diff --git a/Spigot-Server-Patches/0011-Player-Exhaustion-Multipliers.patch b/Spigot-Server-Patches/0011-Player-Exhaustion-Multipliers.patch index fe211c4562a..555dbff9ce8 100644 --- a/Spigot-Server-Patches/0011-Player-Exhaustion-Multipliers.patch +++ b/Spigot-Server-Patches/0011-Player-Exhaustion-Multipliers.patch @@ -1,4 +1,4 @@ -From 044e45972d2ced451ccd807d63e04b33a2b93af3 Mon Sep 17 00:00:00 2001 +From 62db989dcad63f99430f472ddcbc0384da81bd9b Mon Sep 17 00:00:00 2001 From: gsand Date: Tue, 1 Mar 2016 13:43:16 -0600 Subject: [PATCH] Player Exhaustion Multipliers @@ -36,10 +36,10 @@ index 1d2f580..bed5577 100644 ItemStack itemstack1 = this.u(iblockdata); diff --git a/src/main/java/net/minecraft/server/EntityHuman.java b/src/main/java/net/minecraft/server/EntityHuman.java -index 11fdee8..d195ef0 100644 +index 6e40e60..b602c5d 100644 --- a/src/main/java/net/minecraft/server/EntityHuman.java +++ b/src/main/java/net/minecraft/server/EntityHuman.java -@@ -1447,13 +1447,13 @@ public abstract class EntityHuman extends EntityLiving { +@@ -1449,13 +1449,13 @@ public abstract class EntityHuman extends EntityLiving { i = Math.round(MathHelper.sqrt(d0 * d0 + d1 * d1 + d2 * d2) * 100.0F); if (i > 0) { this.a(StatisticList.q, i); @@ -56,5 +56,5 @@ index 11fdee8..d195ef0 100644 } else if (this.n_()) { if (d1 > 0.0D) { -- -2.7.2.windows.1 +2.7.2 diff --git a/Spigot-Server-Patches/0017-Player-affects-spawning-API.patch b/Spigot-Server-Patches/0017-Player-affects-spawning-API.patch index 62084ef99ce..9588b3b2fa5 100644 --- a/Spigot-Server-Patches/0017-Player-affects-spawning-API.patch +++ b/Spigot-Server-Patches/0017-Player-affects-spawning-API.patch @@ -1,14 +1,14 @@ -From 35e02674a6ff73cbeb7fa49e7048f74baeef5be8 Mon Sep 17 00:00:00 2001 +From 0b152c9f505a0e6136da7b1b9f810656a1540a75 Mon Sep 17 00:00:00 2001 From: Jedediah Smith Date: Tue, 1 Mar 2016 14:47:52 -0600 Subject: [PATCH] Player affects spawning API diff --git a/src/main/java/net/minecraft/server/EntityHuman.java b/src/main/java/net/minecraft/server/EntityHuman.java -index 7b7025f..9534bf9 100644 +index b602c5d..6c202c5 100644 --- a/src/main/java/net/minecraft/server/EntityHuman.java +++ b/src/main/java/net/minecraft/server/EntityHuman.java -@@ -63,6 +63,7 @@ public abstract class EntityHuman extends EntityLiving { +@@ -64,6 +64,7 @@ public abstract class EntityHuman extends EntityLiving { private ItemStack bT = null; private final ItemCooldown bU = this.l(); public EntityFishingHook hookedFish; @@ -17,7 +17,7 @@ index 7b7025f..9534bf9 100644 // CraftBukkit start public boolean fauxSleeping; diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java -index c0215e2..2df5f15 100644 +index fdda1ae..6ad5279 100644 --- a/src/main/java/net/minecraft/server/EntityInsentient.java +++ b/src/main/java/net/minecraft/server/EntityInsentient.java @@ -593,7 +593,7 @@ public abstract class EntityInsentient extends EntityLiving { @@ -65,7 +65,7 @@ index 9e19dfd..b724586 100644 biomebase_biomemeta = worldserver.a(enumcreaturetype, (BlockPosition) blockposition_mutableblockposition); if (biomebase_biomemeta == null) { diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 39afaae..f8737ef 100644 +index 2653853..19f79fd 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java @@ -2679,6 +2679,53 @@ public abstract class World implements IBlockAccess { diff --git a/Spigot-Server-Patches/0040-Disable-explosion-knockback.patch b/Spigot-Server-Patches/0040-Disable-explosion-knockback.patch index 7eade4d1aae..c1270c748e1 100644 --- a/Spigot-Server-Patches/0040-Disable-explosion-knockback.patch +++ b/Spigot-Server-Patches/0040-Disable-explosion-knockback.patch @@ -1,4 +1,4 @@ -From 20711d38315229d4506eb215fb101d4d413a20ca Mon Sep 17 00:00:00 2001 +From 6fd6995aefe3c21191c4b2ac3f08200871ae5773 Mon Sep 17 00:00:00 2001 From: Sudzzy Date: Wed, 2 Mar 2016 14:48:03 -0600 Subject: [PATCH] Disable explosion knockback @@ -19,10 +19,10 @@ index 1c8e310..694b448 100644 + } } diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java -index 0248a9e..2e671fd 100644 +index 89b2eb0..8c8fc38 100644 --- a/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java -@@ -852,12 +852,14 @@ public abstract class EntityLiving extends Entity { +@@ -853,12 +853,14 @@ public abstract class EntityLiving extends Entity { } } @@ -37,7 +37,7 @@ index 0248a9e..2e671fd 100644 this.world.broadcastEntityEffect(this, (byte) 2); } -@@ -881,6 +883,8 @@ public abstract class EntityLiving extends Entity { +@@ -882,6 +884,8 @@ public abstract class EntityLiving extends Entity { } } diff --git a/Spigot-Server-Patches/0057-Timings-v2.patch b/Spigot-Server-Patches/0057-Timings-v2.patch index 836680d8e48..f2284a6eb92 100644 --- a/Spigot-Server-Patches/0057-Timings-v2.patch +++ b/Spigot-Server-Patches/0057-Timings-v2.patch @@ -1,4 +1,4 @@ -From c6260f9606fba3d561cb6d4662e211cd6d9c95c6 Mon Sep 17 00:00:00 2001 +From cb7de95e68ead99f11e3bc71d3bf43415be8b1b8 Mon Sep 17 00:00:00 2001 From: Aikar Date: Thu, 3 Mar 2016 04:00:11 -0600 Subject: [PATCH] Timings v2 @@ -329,10 +329,10 @@ index a6c1136..c2771e7 100644 public void recalcPosition() { diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java -index 2e671fd..b10475f 100644 +index 8c8fc38..03bc598 100644 --- a/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java -@@ -23,7 +23,7 @@ import org.bukkit.event.entity.EntityRegainHealthEvent; +@@ -24,7 +24,7 @@ import org.bukkit.event.entity.EntityRegainHealthEvent; import org.bukkit.event.player.PlayerItemConsumeEvent; // CraftBukkit end @@ -341,7 +341,7 @@ index 2e671fd..b10475f 100644 public abstract class EntityLiving extends Entity { -@@ -1686,7 +1686,6 @@ public abstract class EntityLiving extends Entity { +@@ -1688,7 +1688,6 @@ public abstract class EntityLiving extends Entity { } public void m() { @@ -349,7 +349,7 @@ index 2e671fd..b10475f 100644 super.m(); this.cu(); if (!this.world.isClientSide) { -@@ -1759,9 +1758,7 @@ public abstract class EntityLiving extends Entity { +@@ -1761,9 +1760,7 @@ public abstract class EntityLiving extends Entity { } } @@ -359,7 +359,7 @@ index 2e671fd..b10475f 100644 double d0 = this.locX - this.lastX; double d1 = this.locZ - this.lastZ; float f = (float) (d0 * d0 + d1 * d1); -@@ -1830,8 +1827,6 @@ public abstract class EntityLiving extends Entity { +@@ -1832,8 +1829,6 @@ public abstract class EntityLiving extends Entity { } else { this.bo = 0; } @@ -368,7 +368,7 @@ index 2e671fd..b10475f 100644 } protected float h(float f, float f1) { -@@ -1896,7 +1891,6 @@ public abstract class EntityLiving extends Entity { +@@ -1898,7 +1893,6 @@ public abstract class EntityLiving extends Entity { } this.world.methodProfiler.a("ai"); @@ -376,7 +376,7 @@ index 2e671fd..b10475f 100644 if (this.cf()) { this.bc = false; this.bd = 0.0F; -@@ -1907,7 +1901,6 @@ public abstract class EntityLiving extends Entity { +@@ -1909,7 +1903,6 @@ public abstract class EntityLiving extends Entity { this.doTick(); this.world.methodProfiler.b(); } @@ -384,7 +384,7 @@ index 2e671fd..b10475f 100644 this.world.methodProfiler.b(); this.world.methodProfiler.a("jump"); -@@ -1930,14 +1923,10 @@ public abstract class EntityLiving extends Entity { +@@ -1932,14 +1925,10 @@ public abstract class EntityLiving extends Entity { this.be *= 0.98F; this.bf *= 0.9F; this.r(); @@ -461,7 +461,7 @@ index 733f8e7..92b98a0 100644 // Run tasks that are waiting on processing SpigotTimings.processQueueTimer.startTiming(); // Spigot diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java -index 4795c44..2ebe52b 100644 +index 9e5a037..5795804 100644 --- a/src/main/java/net/minecraft/server/PlayerConnection.java +++ b/src/main/java/net/minecraft/server/PlayerConnection.java @@ -57,6 +57,7 @@ import org.bukkit.inventory.CraftingInventory; @@ -529,7 +529,7 @@ index d898428..f579d28 100644 private static Map> f = Maps.newHashMap(); private static Map, String> g = Maps.newHashMap(); diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index c816b4d..938c05b 100644 +index 1815f79..21b0986 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java @@ -18,11 +18,11 @@ import com.google.common.collect.Maps; diff --git a/Spigot-Server-Patches/0080-Add-methods-for-working-with-arrows-stuck-in-living-.patch b/Spigot-Server-Patches/0080-Add-methods-for-working-with-arrows-stuck-in-living-.patch index c142a4e54ba..de579dbd364 100644 --- a/Spigot-Server-Patches/0080-Add-methods-for-working-with-arrows-stuck-in-living-.patch +++ b/Spigot-Server-Patches/0080-Add-methods-for-working-with-arrows-stuck-in-living-.patch @@ -1,14 +1,14 @@ -From 63947a2a46bc67cc097163e3958b80ea7eb74bd3 Mon Sep 17 00:00:00 2001 +From 8afe21b2c6cf6f93d4e275410e893a88d243688e Mon Sep 17 00:00:00 2001 From: mrapple Date: Sun, 25 Nov 2012 13:43:39 -0600 Subject: [PATCH] Add methods for working with arrows stuck in living entities diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java -index 015caa7..946c925 100644 +index 03bc598..b262dc8 100644 --- a/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java -@@ -1264,10 +1264,12 @@ public abstract class EntityLiving extends Entity { +@@ -1265,10 +1265,12 @@ public abstract class EntityLiving extends Entity { return (float) this.getAttributeInstance(GenericAttributes.maxHealth).getValue(); } @@ -22,10 +22,10 @@ index 015caa7..946c925 100644 this.datawatcher.set(EntityLiving.h, Integer.valueOf(i)); } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index 5e1aec2..95965fd 100644 +index 6f25d18..693d5cb 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -521,4 +521,16 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -531,4 +531,16 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { public AttributeInstance getAttribute(Attribute attribute) { return getHandle().craftAttributes.getAttribute(attribute); } diff --git a/Spigot-Server-Patches/0083-Chunk-save-queue-improvements.patch b/Spigot-Server-Patches/0083-Chunk-save-queue-improvements.patch new file mode 100644 index 00000000000..9d8e694e7fb --- /dev/null +++ b/Spigot-Server-Patches/0083-Chunk-save-queue-improvements.patch @@ -0,0 +1,169 @@ +From fc24c303721e53eba7a36079e7b937bd3b7a692e Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Fri, 4 Mar 2016 18:18:37 -0600 +Subject: [PATCH] Chunk save queue improvements + +For some unknown reason, Minecraft is sleeping 10ms between every single chunk being saved to disk. +Under high chunk load/unload activity (lots of movement / teleporting), this causes the chunk unload queue +to build up in size. + +This has multiple impacts: +1) Performance of the unload queue itself - The save thread is pretty ineffecient for how it accesses it + By letting the queue get larger, checking and popping work off the queue can get less performant. +2) Performance of chunk loading - As with #1, chunk loads also have to check this queue when loading + chunk data so that it doesn't load stale data if new data is pending write to disk. +3) Memory Usage - The entire chunk has been serialized to NBT, and now sits in this queue. This leads to + elevated memory usage, and then the objects used in the serialization sit around longer than needed, + resulting in promotion to Old Generation instead of dying young. + +If there is work to do, then the thread should be doing its work, and only sleep when it is done. + +Additionally, optimize the ChunkRegionLoader queue to reduce lock contention (issue with 1.9) + +diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java +index 62f4631..ed49d83 100644 +--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java ++++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java +@@ -164,4 +164,10 @@ public class PaperConfig { + } + return time; + } ++ ++ public static boolean enableFileIOThreadSleep; ++ private static void enableFileIOThreadSleep() { ++ enableFileIOThreadSleep = getBoolean("settings.sleep-between-chunk-saves", false); ++ if (enableFileIOThreadSleep) Bukkit.getLogger().info("Enabled sleeping between chunk saves, beware of memory issues"); ++ } + } +diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java +index 5bd6ce0..336e780 100644 +--- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java ++++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java +@@ -11,14 +11,17 @@ import java.util.List; + import java.util.Map; + import java.util.Set; + import java.util.concurrent.ConcurrentHashMap; ++import java.util.concurrent.ConcurrentLinkedQueue; // Paper + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + + public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { + ++ private ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue(); // Paper - Chunk queue improvements ++ private final Object lock = new Object(); // Paper - Chunk queue improvements + private static final Logger a = LogManager.getLogger(); + private Map b = new ConcurrentHashMap(); +- private Set c = Collections.newSetFromMap(new ConcurrentHashMap()); ++ //private Set c = Collections.newSetFromMap(new ConcurrentHashMap()); // Paper - Chunk queue improvements + private final File d; + private final DataConverterManager e; + private boolean f = false; +@@ -32,11 +35,11 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { + public boolean chunkExists(World world, int i, int j) { + ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i, j); + +- if (this.c.contains(chunkcoordintpair)) { ++ //if (this.c.contains(chunkcoordintpair)) { // Paper - Chunk queue improvements + if (this.b.containsKey(chunkcoordintpair)) { + return true; + } +- } ++ //} // Paper - Chunk queue improvements + + // Paper start - Don't create region files when checking that they exist + final RegionFile region = RegionFileCache.a(this.d, i, j, false); +@@ -139,28 +142,32 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { + } + + protected void a(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) { +- if (!this.c.contains(chunkcoordintpair)) { ++ synchronized (lock) { // Paper - Chunk queue improvements + this.b.put(chunkcoordintpair, nbttagcompound); + } ++ queue.add(new QueuedChunk(chunkcoordintpair, nbttagcompound)); // Paper - Chunk queue improvements + + FileIOThread.a().a(this); + } + + public boolean c() { +- if (this.b.isEmpty()) { ++ // Paper start - Chunk queue improvements ++ QueuedChunk chunk = queue.poll(); ++ if (chunk == null) { ++ // Paper - end + if (this.f) { + ChunkRegionLoader.a.info("ThreadedAnvilChunkStorage ({}): All chunks are saved", new Object[] { this.d.getName()}); + } + + return false; + } else { +- ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) this.b.keySet().iterator().next(); ++ ChunkCoordIntPair chunkcoordintpair = chunk.coords; // Paper - Chunk queue improvements + + boolean flag; + + try { +- this.c.add(chunkcoordintpair); +- NBTTagCompound nbttagcompound = (NBTTagCompound) this.b.remove(chunkcoordintpair); ++ //this.c.add(chunkcoordintpair); ++ NBTTagCompound nbttagcompound = chunk.compound; // Paper - Chunk queue improvements + + if (nbttagcompound != null) { + try { +@@ -169,10 +176,11 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { + ChunkRegionLoader.a.error("Failed to save chunk", exception); + } + } ++ synchronized (lock) { if (this.b.get(chunkcoordintpair) == nbttagcompound) { this.b.remove(chunkcoordintpair); } }// Paper - This will not equal if a newer version is still pending + + flag = true; + } finally { +- this.c.remove(chunkcoordintpair); ++ //this.c.remove(chunkcoordintpair); // Paper + } + + return flag; +@@ -503,4 +511,16 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { + return entity; + } + } ++ ++ // Paper start - Chunk queue improvements ++ private static class QueuedChunk { ++ public ChunkCoordIntPair coords; ++ public NBTTagCompound compound; ++ ++ public QueuedChunk(ChunkCoordIntPair coords, NBTTagCompound compound) { ++ this.coords = coords; ++ this.compound = compound; ++ } ++ } ++ // Paper end + } +diff --git a/src/main/java/net/minecraft/server/FileIOThread.java b/src/main/java/net/minecraft/server/FileIOThread.java +index 198b00f..d997dd4 100644 +--- a/src/main/java/net/minecraft/server/FileIOThread.java ++++ b/src/main/java/net/minecraft/server/FileIOThread.java +@@ -39,11 +39,15 @@ public class FileIOThread implements Runnable { + ++this.d; + } + +- try { +- Thread.sleep(this.e ? 0L : 10L); +- } catch (InterruptedException interruptedexception) { +- interruptedexception.printStackTrace(); ++ // Paper start - Add toggle ++ if (com.destroystokyo.paper.PaperConfig.enableFileIOThreadSleep) { ++ try { ++ Thread.sleep(this.e ? 0L : 10L); ++ } catch (InterruptedException interruptedexception) { ++ interruptedexception.printStackTrace(); ++ } + } ++ // Paper end + } + + if (this.b.isEmpty()) { +-- +2.7.2 +