From 3fd3544a368246784462d4cbc632c6f02dff3ae4 Mon Sep 17 00:00:00 2001 From: Byteflux Date: Thu, 24 Mar 2016 23:38:38 -0700 Subject: [PATCH] Add Lighting Queue The lighting queue spreads out the processing of light updates across multiple ticks based on how much free time the server has left at the end of the tick. --- ...031-Configurable-async-light-updates.patch | 242 ------------------ .../0031-Lighting-Queue.patch | 233 +++++++++++++++++ .../0033-Configurable-end-credits.patch | 8 +- .../0036-Optimize-explosions.patch | 30 +-- .../0051-Disable-spigot-tick-limiters.patch | 8 +- ...port-to-tab-completers-vanilla-featu.patch | 10 +- .../0064-Optimize-getBlockData.patch | 8 +- ...opper-searches-if-there-are-no-items.patch | 29 ++- ...entation-of-tile-entity-removal-list.patch | 25 +- .../0075-Add-exception-reporting-event.patch | 22 +- .../0092-Add-World-Util-Methods.patch | 12 +- .../0100-Optimize-Chunk-Unload-Queue.patch | 32 +-- .../0105-Optimize-Chunk-Access.patch | 20 +- ...ptimize-isValidLocation-for-inlining.patch | 24 +- 14 files changed, 350 insertions(+), 353 deletions(-) delete mode 100644 Spigot-Server-Patches/0031-Configurable-async-light-updates.patch create mode 100644 Spigot-Server-Patches/0031-Lighting-Queue.patch diff --git a/Spigot-Server-Patches/0031-Configurable-async-light-updates.patch b/Spigot-Server-Patches/0031-Configurable-async-light-updates.patch deleted file mode 100644 index 3d4e250c6..000000000 --- a/Spigot-Server-Patches/0031-Configurable-async-light-updates.patch +++ /dev/null @@ -1,242 +0,0 @@ -From 3139fa5792642d1ac35a315ca8a40acf0c057bf7 Mon Sep 17 00:00:00 2001 -From: Byteflux -Date: Wed, 2 Mar 2016 00:52:31 -0600 -Subject: [PATCH] Configurable async light updates - - -diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index facb98c..9991a4a 100644 ---- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -@@ -166,4 +166,9 @@ public class PaperWorldConfig { - - } - -+ public boolean useAsyncLighting; -+ private void useAsyncLighting() { -+ useAsyncLighting = false; //getBoolean( "use-async-lighting", false ); -+ log("World async lighting: " + useAsyncLighting); -+ } - } -diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index cde4124..5df38be 100644 ---- a/src/main/java/net/minecraft/server/Chunk.java -+++ b/src/main/java/net/minecraft/server/Chunk.java -@@ -11,6 +11,8 @@ import java.util.Map; - import java.util.Random; - import java.util.concurrent.Callable; - import java.util.concurrent.ConcurrentLinkedQueue; -+import java.util.concurrent.atomic.AtomicInteger; // Paper -+ - import org.apache.logging.log4j.LogManager; - import org.apache.logging.log4j.Logger; - -@@ -44,6 +46,10 @@ public class Chunk { - private int w; - private ConcurrentLinkedQueue x; - protected gnu.trove.map.hash.TObjectIntHashMap entityCount = new gnu.trove.map.hash.TObjectIntHashMap(); // Spigot -+ // Paper start - Asynchronous light updates -+ public AtomicInteger pendingLightUpdates = new AtomicInteger(); -+ public long lightUpdateTime; -+ // Paper end - - // CraftBukkit start - Neighbor loaded cache for chunk lighting and entity ticking - private int neighbors = 0x1 << 12; -@@ -278,7 +284,7 @@ public class Chunk { - private void a(int i, int j, int k, int l) { - if (l > k && this.world.areChunksLoaded(new BlockPosition(i, 0, j), 16)) { - for (int i1 = k; i1 < l; ++i1) { -- this.world.c(EnumSkyBlock.SKY, new BlockPosition(i, i1, j)); -+ this.world.updateLight(EnumSkyBlock.SKY, new BlockPosition(i, i1, j)); - } - - this.r = true; -@@ -991,7 +997,7 @@ public class Chunk { - - public void b(boolean flag) { - if (this.l && !this.world.worldProvider.m() && !flag) { -- this.h(this.world.isClientSide); -+ this.recheckGaps(this.world.isClientSide); // Paper - Asynchronous lighting updates - } - - this.q = true; -@@ -1012,6 +1018,23 @@ public class Chunk { - - } - -+ /** -+ * Paper- Recheck gaps asynchronously -+ */ -+ public void recheckGaps(final boolean isClientSide) { -+ if (!world.paperConfig.useAsyncLighting) { -+ this.h(this.world.isClientSide); -+ return; -+ } -+ -+ world.lightingExecutor.submit(new Runnable() { -+ @Override -+ public void run() { -+ Chunk.this.h(isClientSide); -+ } -+ }); -+ } -+ - public boolean isReady() { - // Spigot Start - /* -diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index 83857a6..49288c9 100644 ---- a/src/main/java/net/minecraft/server/ChunkProviderServer.java -+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java -@@ -46,6 +46,12 @@ public class ChunkProviderServer implements IChunkProvider { - } - - public void queueUnload(int i, int j) { -+ // Paper start - Asynchronous lighting updates -+ Chunk chunk = chunks.get(LongHash.toLong(i, j)); -+ if (chunk != null && chunk.world.paperConfig.useAsyncLighting && (chunk.pendingLightUpdates.get() > 0 || chunk.world.getTime() - chunk.lightUpdateTime < 20)) { -+ return; -+ } -+ // Paper end - if (this.world.worldProvider.c(i, j)) { - // CraftBukkit start - this.unloadQueue.add(i, j); -diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index c5ce0c3..fae23ae 100644 ---- a/src/main/java/net/minecraft/server/World.java -+++ b/src/main/java/net/minecraft/server/World.java -@@ -29,6 +29,12 @@ import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; - import org.bukkit.generator.ChunkGenerator; - // CraftBukkit end - -+// Paper start -+import java.util.concurrent.ExecutorService; -+import java.util.concurrent.Executors; -+import com.google.common.util.concurrent.ThreadFactoryBuilder; -+// Paper end -+ - public abstract class World implements IBlockAccess { - - private int a = 63; -@@ -134,6 +140,7 @@ public abstract class World implements IBlockAccess { - private org.spigotmc.TickLimiter entityLimiter; - private org.spigotmc.TickLimiter tileLimiter; - private int tileTickPosition; -+ public ExecutorService lightingExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("Paper - Lighting Thread").build()); // Paper - Asynchronous lighting updates - - public CraftWorld getWorld() { - return this.world; -@@ -476,7 +483,7 @@ public abstract class World implements IBlockAccess { - - if (!this.worldProvider.m()) { - for (i1 = k; i1 <= l; ++i1) { -- this.c(EnumSkyBlock.SKY, new BlockPosition(i, i1, j)); -+ this.updateLight(EnumSkyBlock.SKY, new BlockPosition(i, i1, j)); // Paper - Asynchronous lighting updates - } - } - -@@ -2245,10 +2252,10 @@ public abstract class World implements IBlockAccess { - boolean flag = false; - - if (!this.worldProvider.m()) { -- flag |= this.c(EnumSkyBlock.SKY, blockposition); -+ flag |= this.updateLight(EnumSkyBlock.SKY, blockposition); // Paper - Asynchronous lighting updates - } - -- flag |= this.c(EnumSkyBlock.BLOCK, blockposition); -+ flag |= this.updateLight(EnumSkyBlock.BLOCK, blockposition); // Paper - Asynchronous lighting updates - return flag; - } - -@@ -2298,10 +2305,15 @@ public abstract class World implements IBlockAccess { - } - } - -+ // Paper start - Asynchronous lighting updates - public boolean c(EnumSkyBlock enumskyblock, BlockPosition blockposition) { -+ return this.c(enumskyblock, blockposition, null, null); -+ } -+ -+ public boolean c(EnumSkyBlock enumskyblock, BlockPosition blockposition, Chunk chunk, List neighbors) { // Paper - // CraftBukkit start - Use neighbor cache instead of looking up -- Chunk chunk = this.getChunkIfLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4); -- if (chunk == null || !chunk.areNeighborsLoaded(1) /*!this.areChunksLoaded(blockposition, 17, false)*/) { -+ //Chunk chunk = this.getChunkIfLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4); -+ if (chunk == null /*|| !chunk.areNeighborsLoaded(1)*/ /*!this.areChunksLoaded(blockposition, 17, false)*/) { - // CraftBukkit end - return false; - } else { -@@ -2372,6 +2384,17 @@ public abstract class World implements IBlockAccess { - i = 0; - } - -+ // Paper start - Asynchronous light updates -+ if (chunk.world.paperConfig.useAsyncLighting) { -+ chunk.pendingLightUpdates.decrementAndGet(); -+ if (neighbors != null) { -+ for (Chunk neighbor : neighbors) { -+ neighbor.pendingLightUpdates.decrementAndGet(); -+ } -+ } -+ } -+ // Paper end -+ - this.methodProfiler.b(); - this.methodProfiler.a("checkedPosition < toCheckCount"); - -@@ -2426,6 +2449,52 @@ public abstract class World implements IBlockAccess { - } - } - -+ /** -+ * Paper - Asynchronous lighting updates -+ */ -+ public boolean updateLight(final EnumSkyBlock enumskyblock, final BlockPosition position) { -+ int x = position.getX(); -+ int z = position.getZ(); -+ final Chunk chunk = this.getChunkIfLoaded(x >> 4, z >> 4); -+ if (chunk == null || !chunk.areNeighborsLoaded(1)) { -+ return false; -+ } -+ -+ if (!chunk.world.paperConfig.useAsyncLighting) { -+ return this.c(enumskyblock, position, chunk, null); -+ } -+ -+ chunk.pendingLightUpdates.incrementAndGet(); -+ chunk.lightUpdateTime = chunk.world.getTime(); -+ -+ final List neighbors = new ArrayList(); -+ -+ for (int cx = (x >> 4) - 1; cx <= (x >> 4) + 1; ++cx) { -+ for (int cz = (z >> 4) - 1; cz <= (z >> 4) + 1; ++cz) { -+ if (cx != x >> 4 && cz != z >> 4) { -+ Chunk neighbor = this.getChunkIfLoaded(cx, cz); -+ if (neighbor != null) { -+ neighbor.pendingLightUpdates.incrementAndGet(); -+ neighbor.lightUpdateTime = chunk.world.getTime(); -+ neighbors.add(neighbor); -+ } -+ } -+ } -+ } -+ -+ if (!Bukkit.isPrimaryThread()) { -+ return this.c(enumskyblock, position, chunk, neighbors); -+ } -+ -+ lightingExecutor.submit(new Runnable() { -+ @Override -+ public void run() { -+ World.this.c(enumskyblock, position, chunk, neighbors); -+ } -+ }); -+ return true; -+ } -+ - public boolean a(boolean flag) { - return false; - } --- -2.7.1.windows.2 - diff --git a/Spigot-Server-Patches/0031-Lighting-Queue.patch b/Spigot-Server-Patches/0031-Lighting-Queue.patch new file mode 100644 index 000000000..125642905 --- /dev/null +++ b/Spigot-Server-Patches/0031-Lighting-Queue.patch @@ -0,0 +1,233 @@ +From 73b3ea1a73387e5a5a24366959c1c35caf7387e9 Mon Sep 17 00:00:00 2001 +From: Byteflux +Date: Wed, 2 Mar 2016 00:52:31 -0600 +Subject: [PATCH] Lighting Queue + + +diff --git a/src/main/java/co/aikar/timings/SpigotTimings.java b/src/main/java/co/aikar/timings/SpigotTimings.java +index 3f4271c..5fdf051 100644 +--- a/src/main/java/co/aikar/timings/SpigotTimings.java ++++ b/src/main/java/co/aikar/timings/SpigotTimings.java +@@ -17,6 +17,7 @@ public final class SpigotTimings { + public static final Timing timeUpdateTimer = Timings.ofSafe("Time Update"); + public static final Timing serverCommandTimer = Timings.ofSafe("Server Command"); + public static final Timing worldSaveTimer = Timings.ofSafe("World Save"); ++ public static final Timing lightingQueueTimer = Timings.ofSafe("Lighting Queue"); + + public static final Timing tickEntityTimer = Timings.ofSafe("## tickEntity"); + public static final Timing tickTileEntityTimer = Timings.ofSafe("## tickTileEntity"); +diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +index facb98c..e0e9a65 100644 +--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java ++++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +@@ -166,4 +166,9 @@ public class PaperWorldConfig { + + } + ++ public boolean queueLightUpdates; ++ private void queueLightUpdates() { ++ queueLightUpdates = getBoolean("queue-light-updates", false); ++ log("Lighting Queue enabled: " + queueLightUpdates); ++ } + } +diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java +index cde4124..9020b1b 100644 +--- a/src/main/java/net/minecraft/server/Chunk.java ++++ b/src/main/java/net/minecraft/server/Chunk.java +@@ -44,6 +44,7 @@ public class Chunk { + private int w; + private ConcurrentLinkedQueue x; + protected gnu.trove.map.hash.TObjectIntHashMap entityCount = new gnu.trove.map.hash.TObjectIntHashMap(); // Spigot ++ public int lightUpdates; // Paper - Number of queued light updates for this chunk + + // CraftBukkit start - Neighbor loaded cache for chunk lighting and entity ticking + private int neighbors = 0x1 << 12; +@@ -226,6 +227,22 @@ public class Chunk { + private void h(boolean flag) { + this.world.methodProfiler.a("recheckGaps"); + if (this.world.areChunksLoaded(new BlockPosition(this.locX * 16 + 8, 0, this.locZ * 16 + 8), 16)) { ++ // Paper start - Queue light update ++ if (!world.paperConfig.queueLightUpdates) { ++ recheckGaps(flag); ++ } else { ++ ++lightUpdates; ++ world.getServer().getServer().lightingQueue.add(() -> { ++ recheckGaps(flag); ++ --lightUpdates; ++ }); ++ } ++ } ++ } ++ ++ private void recheckGaps(boolean flag) { ++ if (true) { ++ // Paper end + for (int i = 0; i < 16; ++i) { + for (int j = 0; j < 16; ++j) { + if (this.h[i + j * 16]) { +@@ -476,7 +493,7 @@ public class Chunk { + } else { + if (flag) { + this.initLighting(); +- } else { ++ } else if (!world.paperConfig.queueLightUpdates) { // Paper + int j1 = iblockdata.c(); + int k1 = iblockdata1.c(); + +@@ -491,6 +508,28 @@ public class Chunk { + if (j1 != k1 && (j1 < k1 || this.getBrightness(EnumSkyBlock.SKY, blockposition) > 0 || this.getBrightness(EnumSkyBlock.BLOCK, blockposition) > 0)) { + this.d(i, k); + } ++ // Paper start - Queue light update ++ } else { ++ int j1 = iblockdata.c(); ++ int k1 = iblockdata1.c(); ++ ++ ++lightUpdates; ++ world.getServer().getServer().lightingQueue.add(() -> { ++ if (j1 > 0) { ++ if (j >= i1) { ++ this.c(i, j + 1, k); ++ } ++ } else if (j == i1 - 1) { ++ this.c(i, j, k); ++ } ++ ++ if (j1 != k1 && (j1 < k1 || this.getBrightness(EnumSkyBlock.SKY, blockposition) > 0 || this.getBrightness(EnumSkyBlock.BLOCK, blockposition) > 0)) { ++ this.d(i, k); ++ } ++ ++ --lightUpdates; ++ }); ++ // Paper end + } + + TileEntity tileentity; +@@ -1314,4 +1353,29 @@ public class Chunk { + + private EnumTileEntityState() {} + } ++ ++ // Paper start ++ public boolean hasLightUpdates() { ++ if (world.paperConfig.queueLightUpdates) { ++ if (lightUpdates > 0) { ++ return true; ++ } ++ ++ for (int x = locX - 2; x <= locX + 2; ++x) { ++ for (int z = locZ - 2; z <= locZ + 2; ++z) { ++ if ((x == 0 && z == 0) || (x == locX && z == locZ)) { ++ continue; ++ } ++ ++ Chunk chunk = world.getChunkIfLoaded(x, z); ++ if (chunk != null && chunk.lightUpdates > 0) { ++ return true; ++ } ++ } ++ } ++ } ++ ++ return false; ++ } ++ // Paper end + } +diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java +index 83857a6..4dd672a 100644 +--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java ++++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java +@@ -284,6 +284,7 @@ public class ChunkProviderServer implements IChunkProvider { + long chunkcoordinates = this.unloadQueue.popFirst(); + Chunk chunk = this.chunks.get(chunkcoordinates); + if (chunk == null) continue; ++ if (chunk.hasLightUpdates()) continue; // Paper - Don't unload chunks with pending light updates. + + ChunkUnloadEvent event = new ChunkUnloadEvent(chunk.bukkitChunk); + server.getPluginManager().callEvent(event); +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index 6ae06a5..aa337cc 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -47,6 +47,11 @@ import org.bukkit.craftbukkit.CraftServer; + // CraftBukkit end + import co.aikar.timings.SpigotTimings; // Paper + ++// Paper start ++import java.util.LinkedList; ++import java.util.Queue; ++// Paper end ++ + public abstract class MinecraftServer implements Runnable, ICommandListener, IAsyncTaskHandler, IMojangStatistics { + + public static final Logger LOGGER = LogManager.getLogger(); +@@ -113,6 +118,7 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs + public final Thread primaryThread; + public java.util.Queue processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); + public int autosavePeriod; ++ public final Queue lightingQueue = new LinkedList(); // Paper - Queued light updates + // CraftBukkit end + + public MinecraftServer(OptionSet options, Proxy proxy, DataConverterManager dataconvertermanager, YggdrasilAuthenticationService yggdrasilauthenticationservice, MinecraftSessionService minecraftsessionservice, GameProfileRepository gameprofilerepository, UserCache usercache) { +@@ -759,6 +765,35 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs + + this.methodProfiler.b(); + this.methodProfiler.b(); ++ ++ // Paper start - Flush light updates ++ if (!lightingQueue.isEmpty()) { ++ SpigotTimings.lightingQueueTimer.startTiming(); ++ ++ int updatesThisTick = 0; ++ long cachedTime = System.currentTimeMillis(); ++ long startTime = cachedTime - (this.h[this.ticks % 100] / 1000000); ++ int maxTickTimeCap = MathHelper.floor((TICK_TIME / 1000000) * 0.8); ++ int maxTickTime = Math.max(0, (int) (maxTickTimeCap - (cachedTime - startTime))); ++ Runnable lightUpdate; ++ ++ while (maxTickTime > 0 && (lightUpdate = lightingQueue.poll()) != null) { ++ lightUpdate.run(); ++ if (++updatesThisTick % 10 == 0) { ++ long currentTime = System.currentTimeMillis(); ++ if (currentTime - cachedTime > maxTickTime) { ++ break; ++ } ++ ++ cachedTime = currentTime; ++ maxTickTime = Math.max(0, (int) (maxTickTimeCap - (currentTime - startTime))); ++ } ++ } ++ ++ SpigotTimings.lightingQueueTimer.stopTiming(); ++ } ++ // Paper end ++ + org.spigotmc.WatchdogThread.tick(); // Spigot + co.aikar.timings.TimingsManager.FULL_SERVER_TICK.stopTiming(); // Paper + } +diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java +index c5ce0c3..a1d8bc5 100644 +--- a/src/main/java/net/minecraft/server/World.java ++++ b/src/main/java/net/minecraft/server/World.java +@@ -378,7 +378,17 @@ public abstract class World implements IBlockAccess { + } else { + if (iblockdata.c() != iblockdata1.c() || iblockdata.d() != iblockdata1.d()) { + this.methodProfiler.a("checkLight"); +- this.w(blockposition); ++ // Paper start - Queue light update ++ if (!paperConfig.queueLightUpdates) { ++ this.w(blockposition); ++ } else { ++ ++chunk.lightUpdates; ++ getMinecraftServer().lightingQueue.add(() -> { ++ this.w(blockposition); ++ --chunk.lightUpdates; ++ }); ++ } ++ // Paper end + this.methodProfiler.b(); + } + +-- +2.7.1.windows.2 + diff --git a/Spigot-Server-Patches/0033-Configurable-end-credits.patch b/Spigot-Server-Patches/0033-Configurable-end-credits.patch index eec179101..cdedb4bb9 100644 --- a/Spigot-Server-Patches/0033-Configurable-end-credits.patch +++ b/Spigot-Server-Patches/0033-Configurable-end-credits.patch @@ -1,16 +1,16 @@ -From cbfc14ef58ca1f52834aaeb230f7f034efd0bf45 Mon Sep 17 00:00:00 2001 +From a0fe380f5153cbc63cf9c9243bc64b2d1542bfa0 Mon Sep 17 00:00:00 2001 From: DoctorDark Date: Wed, 16 Mar 2016 02:21:39 -0500 Subject: [PATCH] Configurable end credits diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index 9991a4a..1b88731 100644 +index e0e9a65..3a57c8e 100644 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java @@ -171,4 +171,10 @@ public class PaperWorldConfig { - useAsyncLighting = false; //getBoolean( "use-async-lighting", false ); - log("World async lighting: " + useAsyncLighting); + queueLightUpdates = getBoolean("queue-light-updates", false); + log("Lighting Queue enabled: " + queueLightUpdates); } + + public boolean disableEndCredits; diff --git a/Spigot-Server-Patches/0036-Optimize-explosions.patch b/Spigot-Server-Patches/0036-Optimize-explosions.patch index 385805c1e..951b72ecc 100644 --- a/Spigot-Server-Patches/0036-Optimize-explosions.patch +++ b/Spigot-Server-Patches/0036-Optimize-explosions.patch @@ -1,4 +1,4 @@ -From 40287dea24fbe1f8d97a10d6580beb13dc7037c7 Mon Sep 17 00:00:00 2001 +From abf2b31e23d05c3fb8ec5b85f739356b48047979 Mon Sep 17 00:00:00 2001 From: Byteflux Date: Wed, 2 Mar 2016 11:59:48 -0600 Subject: [PATCH] Optimize explosions @@ -10,7 +10,7 @@ This patch adds a per-tick cache that is used for storing and retrieving an entity's exposure during an explosion. diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index 7154d31..2be15d2 100644 +index 66deccb..09b9867 100644 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java @@ -201,4 +201,10 @@ public class PaperWorldConfig { @@ -124,10 +124,10 @@ index 8ce1b23..5bb2510 100644 + // Paper end } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 6ae06a5..92b98a0 100644 +index aa337cc..a30b019 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -865,6 +865,7 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs +@@ -900,6 +900,7 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs worldserver.timings.tracker.stopTiming(); // Spigot this.methodProfiler.b(); this.methodProfiler.b(); @@ -136,22 +136,22 @@ index 6ae06a5..92b98a0 100644 // this.i[i][this.ticks % 100] = System.nanoTime() - j; // CraftBukkit diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index fae23ae..b6d8e1b 100644 +index a1d8bc5..3fe987f 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -32,6 +32,7 @@ import org.bukkit.generator.ChunkGenerator; - // Paper start - import java.util.concurrent.ExecutorService; - import java.util.concurrent.Executors; -+import java.util.HashMap; - import com.google.common.util.concurrent.ThreadFactoryBuilder; - // Paper end +@@ -15,6 +15,7 @@ import java.util.concurrent.Callable; -@@ -141,6 +142,7 @@ public abstract class World implements IBlockAccess { + // CraftBukkit start + import com.google.common.collect.Maps; ++import java.util.HashMap; // Paper + import java.util.Map; + import org.bukkit.Bukkit; + import org.bukkit.block.BlockState; +@@ -134,6 +135,7 @@ public abstract class World implements IBlockAccess { + private org.spigotmc.TickLimiter entityLimiter; private org.spigotmc.TickLimiter tileLimiter; private int tileTickPosition; - public ExecutorService lightingExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("Paper - Lighting Thread").build()); // Paper - Asynchronous lighting updates -+ public final Map explosionDensityCache = new HashMap(); // Paper - Optimize explosions ++ public final Map explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions public CraftWorld getWorld() { return this.world; diff --git a/Spigot-Server-Patches/0051-Disable-spigot-tick-limiters.patch b/Spigot-Server-Patches/0051-Disable-spigot-tick-limiters.patch index 895b4b1fd..9fa7914d7 100644 --- a/Spigot-Server-Patches/0051-Disable-spigot-tick-limiters.patch +++ b/Spigot-Server-Patches/0051-Disable-spigot-tick-limiters.patch @@ -1,14 +1,14 @@ -From 6afc533c9e295094848e44abbfa76c9283454215 Mon Sep 17 00:00:00 2001 +From cf6fcfa594a8512abf3b7821edcebe478fc13df0 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Wed, 2 Mar 2016 23:45:17 -0600 Subject: [PATCH] Disable spigot tick limiters diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index b6d8e1b..66293f7 100644 +index 3fe987f..c93af22 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -1412,10 +1412,10 @@ public abstract class World implements IBlockAccess { +@@ -1415,10 +1415,10 @@ public abstract class World implements IBlockAccess { // CraftBukkit start - Use field for loop variable co.aikar.timings.TimingHistory.entityTicks += this.entityList.size(); // Paper int entitiesThisCycle = 0; @@ -23,7 +23,7 @@ index b6d8e1b..66293f7 100644 tickPosition = (tickPosition < entityList.size()) ? tickPosition : 0; entity = (Entity) this.entityList.get(this.tickPosition); // CraftBukkit end -@@ -1480,9 +1480,7 @@ public abstract class World implements IBlockAccess { +@@ -1483,9 +1483,7 @@ public abstract class World implements IBlockAccess { // Spigot start // Iterator iterator = this.tileEntityListTick.iterator(); int tilesThisCycle = 0; diff --git a/Spigot-Server-Patches/0061-Add-Location-support-to-tab-completers-vanilla-featu.patch b/Spigot-Server-Patches/0061-Add-Location-support-to-tab-completers-vanilla-featu.patch index e7f27e968..76abad2cc 100644 --- a/Spigot-Server-Patches/0061-Add-Location-support-to-tab-completers-vanilla-featu.patch +++ b/Spigot-Server-Patches/0061-Add-Location-support-to-tab-completers-vanilla-featu.patch @@ -1,4 +1,4 @@ -From 94e78ae772b6c0b96a39f28b088331772b5157d3 Mon Sep 17 00:00:00 2001 +From f5d0f96c004c8bbae8fc9a036da32ffd36db3dad Mon Sep 17 00:00:00 2001 From: DemonWav Date: Thu, 3 Mar 2016 01:44:39 -0600 Subject: [PATCH] Add Location support to tab completers (vanilla feature @@ -6,7 +6,7 @@ Subject: [PATCH] Add Location support to tab completers (vanilla feature diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index 8ec65af..fd9aa5c 100644 +index 1f97e59..ca11cd7 100644 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java @@ -262,4 +262,9 @@ public class PaperWorldConfig { @@ -20,10 +20,10 @@ index 8ec65af..fd9aa5c 100644 + } } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 92b98a0..4c0b0ba 100644 +index a30b019..6aaba5e 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1151,7 +1151,7 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs +@@ -1186,7 +1186,7 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs return arraylist; } */ @@ -151,5 +151,5 @@ index 100d84a..a40218c 100644 public static CommandSender lastSender = null; // Nasty :( -- -2.7.3 +2.7.1.windows.2 diff --git a/Spigot-Server-Patches/0064-Optimize-getBlockData.patch b/Spigot-Server-Patches/0064-Optimize-getBlockData.patch index 2799dd6fe..cbe3d6bd4 100644 --- a/Spigot-Server-Patches/0064-Optimize-getBlockData.patch +++ b/Spigot-Server-Patches/0064-Optimize-getBlockData.patch @@ -1,4 +1,4 @@ -From 1605c01b00947016970a88f124e76ee1a93fa1ae Mon Sep 17 00:00:00 2001 +From 913ffd56eaf018ef08a5581bdb34cf4e98d9327e Mon Sep 17 00:00:00 2001 From: Aikar Date: Thu, 3 Mar 2016 02:07:55 -0600 Subject: [PATCH] Optimize getBlockData @@ -6,10 +6,10 @@ Subject: [PATCH] Optimize getBlockData Hot method, so reduce # of instructions for the method. diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index 5df38be..19788ed 100644 +index 9020b1b..f233c13 100644 --- a/src/main/java/net/minecraft/server/Chunk.java +++ b/src/main/java/net/minecraft/server/Chunk.java -@@ -392,8 +392,15 @@ public class Chunk { +@@ -403,8 +403,15 @@ public class Chunk { return this.a(i, j, k).c(); } @@ -27,5 +27,5 @@ index 5df38be..19788ed 100644 public IBlockData a(final int i, final int j, final int k) { -- -2.7.2 +2.7.1.windows.2 diff --git a/Spigot-Server-Patches/0065-Avoid-hopper-searches-if-there-are-no-items.patch b/Spigot-Server-Patches/0065-Avoid-hopper-searches-if-there-are-no-items.patch index 2f3bb4423..693ed846e 100644 --- a/Spigot-Server-Patches/0065-Avoid-hopper-searches-if-there-are-no-items.patch +++ b/Spigot-Server-Patches/0065-Avoid-hopper-searches-if-there-are-no-items.patch @@ -1,4 +1,4 @@ -From f10417f375c81cec510a68204309474063d79aff Mon Sep 17 00:00:00 2001 +From 2a296ac64bd3bd678edd258287d058ed28e9c186 Mon Sep 17 00:00:00 2001 From: CullanP Date: Thu, 3 Mar 2016 02:13:38 -0600 Subject: [PATCH] Avoid hopper searches if there are no items @@ -14,21 +14,24 @@ And since minecart hoppers are used _very_ rarely near we can avoid alot of sear Combined, this adds up a lot. diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index 19788ed..6d148d7 100644 +index f233c13..d8c0347 100644 --- a/src/main/java/net/minecraft/server/Chunk.java +++ b/src/main/java/net/minecraft/server/Chunk.java -@@ -49,6 +49,10 @@ public class Chunk { - // Paper start - Asynchronous light updates - public AtomicInteger pendingLightUpdates = new AtomicInteger(); - public long lightUpdateTime; +@@ -46,6 +46,13 @@ public class Chunk { + protected gnu.trove.map.hash.TObjectIntHashMap entityCount = new gnu.trove.map.hash.TObjectIntHashMap(); // Spigot + public int lightUpdates; // Paper - Number of queued light updates for this chunk + ++ // Paper start + // Track the number of minecarts and items + // Keep this synced with entitySlices.add() and entitySlices.remove() + private final int[] itemCounts = new int[16]; + private final int[] inventoryEntityCounts = new int[16]; - // Paper end - ++ // Paper end ++ // CraftBukkit start - Neighbor loaded cache for chunk lighting and entity ticking -@@ -620,6 +624,13 @@ public class Chunk { + private int neighbors = 0x1 << 12; + +@@ -653,6 +660,13 @@ public class Chunk { entity.ac = k; entity.ad = this.locZ; this.entitySlices[k].add(entity); @@ -42,7 +45,7 @@ index 19788ed..6d148d7 100644 // Spigot start - increment creature type count // Keep this synced up with World.a(Class) if (entity instanceof EntityInsentient) { -@@ -652,6 +663,13 @@ public class Chunk { +@@ -685,6 +699,13 @@ public class Chunk { } this.entitySlices[i].remove(entity); @@ -56,7 +59,7 @@ index 19788ed..6d148d7 100644 // Spigot start - decrement creature type count // Keep this synced up with World.a(Class) if (entity instanceof EntityInsentient) { -@@ -841,6 +859,15 @@ public class Chunk { +@@ -874,6 +895,15 @@ public class Chunk { if (!this.entitySlices[k].isEmpty()) { Iterator iterator = this.entitySlices[k].iterator(); @@ -72,7 +75,7 @@ index 19788ed..6d148d7 100644 while (iterator.hasNext()) { Entity entity1 = (Entity) iterator.next(); -@@ -873,7 +900,18 @@ public class Chunk { +@@ -906,7 +936,18 @@ public class Chunk { i = MathHelper.clamp(i, 0, this.entitySlices.length - 1); j = MathHelper.clamp(j, 0, this.entitySlices.length - 1); @@ -92,5 +95,5 @@ index 19788ed..6d148d7 100644 while (iterator.hasNext()) { -- -2.7.2 +2.7.1.windows.2 diff --git a/Spigot-Server-Patches/0071-Change-implementation-of-tile-entity-removal-list.patch b/Spigot-Server-Patches/0071-Change-implementation-of-tile-entity-removal-list.patch index d99487adb..7173f4e44 100644 --- a/Spigot-Server-Patches/0071-Change-implementation-of-tile-entity-removal-list.patch +++ b/Spigot-Server-Patches/0071-Change-implementation-of-tile-entity-removal-list.patch @@ -1,23 +1,26 @@ -From 84b6a774a12374f05c0d1d02f2ca5e07f0fe40f3 Mon Sep 17 00:00:00 2001 +From 5d2b01e642cb5ef8b70cdf786376be1610e2e2a2 Mon Sep 17 00:00:00 2001 From: Joseph Hirschfeld Date: Thu, 3 Mar 2016 02:39:54 -0600 Subject: [PATCH] Change implementation of (tile)entity removal list diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 21b0986..2919415 100644 +index c93af22..6cfd38c 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -33,6 +33,8 @@ import org.bukkit.generator.ChunkGenerator; - import java.util.concurrent.ExecutorService; - import java.util.concurrent.Executors; - import java.util.HashMap; +@@ -30,6 +30,11 @@ import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; + import org.bukkit.generator.ChunkGenerator; + // CraftBukkit end + ++// Paper start +import java.util.Set; +import com.google.common.collect.Sets; - import com.google.common.util.concurrent.ThreadFactoryBuilder; - // Paper end ++// Paper end ++ + public abstract class World implements IBlockAccess { -@@ -66,11 +68,11 @@ public abstract class World implements IBlockAccess { + private int a = 63; +@@ -60,11 +65,11 @@ public abstract class World implements IBlockAccess { } }; // Spigot end @@ -31,7 +34,7 @@ index 21b0986..2919415 100644 public final List players = Lists.newArrayList(); public final List j = Lists.newArrayList(); protected final IntHashMap entitiesById = new IntHashMap(); -@@ -1384,19 +1386,20 @@ public abstract class World implements IBlockAccess { +@@ -1387,19 +1392,20 @@ public abstract class World implements IBlockAccess { int j; @@ -61,5 +64,5 @@ index 21b0986..2919415 100644 this.f.clear(); this.l(); -- -2.7.2 +2.7.1.windows.2 diff --git a/Spigot-Server-Patches/0075-Add-exception-reporting-event.patch b/Spigot-Server-Patches/0075-Add-exception-reporting-event.patch index 88d1f635b..1e24f5eaf 100644 --- a/Spigot-Server-Patches/0075-Add-exception-reporting-event.patch +++ b/Spigot-Server-Patches/0075-Add-exception-reporting-event.patch @@ -1,4 +1,4 @@ -From 74ef9d7784479d8a035466d41dcb1c86996fc120 Mon Sep 17 00:00:00 2001 +From fabc3a2adbde966e8248772fadf3f9930b2b1101 Mon Sep 17 00:00:00 2001 From: Joseph Hirschfeld Date: Thu, 3 Mar 2016 03:15:41 -0600 Subject: [PATCH] Add exception reporting event @@ -50,7 +50,7 @@ index 0000000..9339718 +} \ No newline at end of file diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index 6d148d7..b6d84d7 100644 +index d8c0347..d42a8d2 100644 --- a/src/main/java/net/minecraft/server/Chunk.java +++ b/src/main/java/net/minecraft/server/Chunk.java @@ -1,5 +1,6 @@ @@ -60,7 +60,7 @@ index 6d148d7..b6d84d7 100644 import com.google.common.base.Predicate; import com.google.common.collect.Maps; import com.google.common.collect.Queues; -@@ -18,6 +19,7 @@ import org.apache.logging.log4j.Logger; +@@ -16,6 +17,7 @@ import org.apache.logging.log4j.Logger; import com.google.common.collect.Lists; // CraftBukkit import org.bukkit.Bukkit; // CraftBukkit @@ -68,7 +68,7 @@ index 6d148d7..b6d84d7 100644 public class Chunk { -@@ -753,10 +755,15 @@ public class Chunk { +@@ -789,10 +791,15 @@ public class Chunk { this.tileEntities.remove(blockposition); // Paper end } else { @@ -89,7 +89,7 @@ index 6d148d7..b6d84d7 100644 } } diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index 49288c9..9ef6246 100644 +index 4dd672a..450bf9b 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java @@ -4,6 +4,7 @@ import java.io.IOException; @@ -100,7 +100,7 @@ index 49288c9..9ef6246 100644 import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -@@ -226,7 +227,11 @@ public class ChunkProviderServer implements IChunkProvider { +@@ -220,7 +221,11 @@ public class ChunkProviderServer implements IChunkProvider { return chunk; } catch (Exception exception) { @@ -113,7 +113,7 @@ index 49288c9..9ef6246 100644 return null; } } -@@ -235,7 +240,11 @@ public class ChunkProviderServer implements IChunkProvider { +@@ -229,7 +234,11 @@ public class ChunkProviderServer implements IChunkProvider { try { this.chunkLoader.b(this.world, chunk); } catch (Exception exception) { @@ -126,7 +126,7 @@ index 49288c9..9ef6246 100644 } } -@@ -245,9 +254,14 @@ public class ChunkProviderServer implements IChunkProvider { +@@ -239,9 +248,14 @@ public class ChunkProviderServer implements IChunkProvider { chunk.setLastSaved(this.world.getTime()); this.chunkLoader.a(this.world, chunk); } catch (IOException ioexception) { @@ -292,7 +292,7 @@ index 320e52e..d40257f 100644 } diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index ee36486..6fb0230 100644 +index 6cfd38c..614cabe 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java @@ -1,5 +1,7 @@ @@ -303,7 +303,7 @@ index ee36486..6fb0230 100644 import com.google.common.base.Function; import com.google.common.base.Objects; import com.google.common.base.Predicate; -@@ -1441,8 +1443,10 @@ public abstract class World implements IBlockAccess { +@@ -1447,8 +1449,10 @@ public abstract class World implements IBlockAccess { } catch (Throwable throwable1) { entity.tickTimer.stopTiming(); // Paper start - Prevent tile entity and entity crashes @@ -315,7 +315,7 @@ index ee36486..6fb0230 100644 entity.dead = true; continue; // Paper end -@@ -1506,8 +1510,10 @@ public abstract class World implements IBlockAccess { +@@ -1512,8 +1516,10 @@ public abstract class World implements IBlockAccess { this.methodProfiler.b(); } catch (Throwable throwable2) { // Paper start - Prevent tile entity and entity crashes diff --git a/Spigot-Server-Patches/0092-Add-World-Util-Methods.patch b/Spigot-Server-Patches/0092-Add-World-Util-Methods.patch index 8bdad61a7..81840c890 100644 --- a/Spigot-Server-Patches/0092-Add-World-Util-Methods.patch +++ b/Spigot-Server-Patches/0092-Add-World-Util-Methods.patch @@ -1,4 +1,4 @@ -From 712fbf766b9e252fa208226bce6b7941327fefbe Mon Sep 17 00:00:00 2001 +From 5eafc0a2293770a3558d1e30c46f72f8a20d4e78 Mon Sep 17 00:00:00 2001 From: Aikar Date: Fri, 18 Mar 2016 20:16:03 -0400 Subject: [PATCH] Add World Util Methods @@ -6,10 +6,10 @@ Subject: [PATCH] Add World Util Methods Methods that can be used for other patches to help improve logic. diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index b356aa6..a6c8e53 100644 +index 614cabe..2283536 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -156,6 +156,12 @@ public abstract class World implements IBlockAccess { +@@ -152,6 +152,12 @@ public abstract class World implements IBlockAccess { return (CraftServer) Bukkit.getServer(); } @@ -22,7 +22,7 @@ index b356aa6..a6c8e53 100644 public Chunk getChunkIfLoaded(int x, int z) { return ((ChunkProviderServer) this.chunkProvider).getChunkIfLoaded(x, z); } -@@ -628,6 +634,41 @@ public abstract class World implements IBlockAccess { +@@ -634,6 +640,41 @@ public abstract class World implements IBlockAccess { } } @@ -64,7 +64,7 @@ index b356aa6..a6c8e53 100644 public int getLightLevel(BlockPosition blockposition) { return this.c(blockposition, true); } -@@ -742,6 +783,27 @@ public abstract class World implements IBlockAccess { +@@ -748,6 +789,27 @@ public abstract class World implements IBlockAccess { return this.worldProvider.n()[this.getLightLevel(blockposition)]; } @@ -93,5 +93,5 @@ index b356aa6..a6c8e53 100644 // CraftBukkit start - tree generation if (captureTreeGeneration) { -- -2.7.4 +2.7.1.windows.2 diff --git a/Spigot-Server-Patches/0100-Optimize-Chunk-Unload-Queue.patch b/Spigot-Server-Patches/0100-Optimize-Chunk-Unload-Queue.patch index f5b939d3b..b77c465ec 100644 --- a/Spigot-Server-Patches/0100-Optimize-Chunk-Unload-Queue.patch +++ b/Spigot-Server-Patches/0100-Optimize-Chunk-Unload-Queue.patch @@ -1,4 +1,4 @@ -From db83f7f21876709f4d9a58499435fb7ecad82d0b Mon Sep 17 00:00:00 2001 +From f3a9dd01aab3b666d2b5e76346c58afef11ed3b1 Mon Sep 17 00:00:00 2001 From: Aikar Date: Fri, 18 Mar 2016 17:57:25 -0400 Subject: [PATCH] Optimize Chunk Unload Queue @@ -23,10 +23,10 @@ it will skip it and move to next. Also optimize EAR to use these methods. diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index b6d84d7..7ba45c8 100644 +index d42a8d2..05417a7 100644 --- a/src/main/java/net/minecraft/server/Chunk.java +++ b/src/main/java/net/minecraft/server/Chunk.java -@@ -55,6 +55,8 @@ public class Chunk { +@@ -53,6 +53,8 @@ public class Chunk { // Keep this synced with entitySlices.add() and entitySlices.remove() private final int[] itemCounts = new int[16]; private final int[] inventoryEntityCounts = new int[16]; @@ -36,7 +36,7 @@ index b6d84d7..7ba45c8 100644 // CraftBukkit start - Neighbor loaded cache for chunk lighting and entity ticking diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index 9ef6246..f9375eb 100644 +index 450bf9b..f5a2580 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java @@ -21,7 +21,7 @@ import org.bukkit.event.world.ChunkUnloadEvent; @@ -48,7 +48,7 @@ index 9ef6246..f9375eb 100644 public final ChunkGenerator chunkGenerator; // CraftBukkit - public private final IChunkLoader chunkLoader; public LongObjectHashMap chunks = new LongObjectHashMap(); // CraftBukkit -@@ -83,14 +83,24 @@ public class ChunkProviderServer implements IChunkProvider { +@@ -77,14 +77,24 @@ public class ChunkProviderServer implements IChunkProvider { return (chunk == null) ? getChunkAt(x, z) : chunk; } @@ -76,7 +76,7 @@ index 9ef6246..f9375eb 100644 return chunk; } -@@ -118,6 +128,7 @@ public class ChunkProviderServer implements IChunkProvider { +@@ -112,6 +122,7 @@ public class ChunkProviderServer implements IChunkProvider { // CraftBukkit end } @@ -84,7 +84,7 @@ index 9ef6246..f9375eb 100644 return chunk; } -@@ -126,7 +137,7 @@ public class ChunkProviderServer implements IChunkProvider { +@@ -120,7 +131,7 @@ public class ChunkProviderServer implements IChunkProvider { } public Chunk getChunkAt(int i, int j, Runnable runnable) { @@ -93,7 +93,7 @@ index 9ef6246..f9375eb 100644 Chunk chunk = chunks.get(LongHash.toLong(i, j)); ChunkRegionLoader loader = null; -@@ -150,12 +161,13 @@ public class ChunkProviderServer implements IChunkProvider { +@@ -144,12 +155,13 @@ public class ChunkProviderServer implements IChunkProvider { if (runnable != null) { runnable.run(); } @@ -108,7 +108,7 @@ index 9ef6246..f9375eb 100644 Chunk chunk = this.chunks.get(LongHash.toLong(i, j)); boolean newChunk = false; // CraftBukkit end -@@ -201,7 +213,7 @@ public class ChunkProviderServer implements IChunkProvider { +@@ -195,7 +207,7 @@ public class ChunkProviderServer implements IChunkProvider { continue; } @@ -117,7 +117,7 @@ index 9ef6246..f9375eb 100644 if (neighbor != null) { neighbor.setNeighborLoaded(-x, -z); chunk.setNeighborLoaded(x, z); -@@ -212,6 +224,7 @@ public class ChunkProviderServer implements IChunkProvider { +@@ -206,6 +218,7 @@ public class ChunkProviderServer implements IChunkProvider { chunk.loadNearby(this, this.chunkGenerator); world.timings.syncChunkLoadTimer.stopTiming(); // Spigot } @@ -125,7 +125,7 @@ index 9ef6246..f9375eb 100644 return chunk; } -@@ -300,10 +313,17 @@ public class ChunkProviderServer implements IChunkProvider { +@@ -294,10 +307,17 @@ public class ChunkProviderServer implements IChunkProvider { if (!this.world.savingDisabled) { // CraftBukkit start Server server = this.world.getServer(); @@ -144,10 +144,10 @@ index 9ef6246..f9375eb 100644 + continue; + } + // Paper end + if (chunk.hasLightUpdates()) continue; // Paper - Don't unload chunks with pending light updates. ChunkUnloadEvent event = new ChunkUnloadEvent(chunk.bukkitChunk); - server.getPluginManager().callEvent(event); -@@ -325,7 +345,7 @@ public class ChunkProviderServer implements IChunkProvider { +@@ -320,7 +340,7 @@ public class ChunkProviderServer implements IChunkProvider { continue; } @@ -156,7 +156,7 @@ index 9ef6246..f9375eb 100644 if (neighbor != null) { neighbor.setNeighborUnloaded(-x, -z); chunk.setNeighborUnloaded(x, z); -@@ -367,4 +387,69 @@ public class ChunkProviderServer implements IChunkProvider { +@@ -362,4 +382,69 @@ public class ChunkProviderServer implements IChunkProvider { public boolean e(int i, int j) { return this.chunks.containsKey(LongHash.toLong(i, j)); // CraftBukkit } @@ -240,10 +240,10 @@ index 63e118d..721bcae 100644 i += server.getChunkAt( x, z ).entityCount.get( oClass ); } diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index f261e01..22c87eb 100644 +index 2283536..406bdaa 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -163,9 +163,15 @@ public abstract class World implements IBlockAccess { +@@ -159,9 +159,15 @@ public abstract class World implements IBlockAccess { // Paper end public Chunk getChunkIfLoaded(int x, int z) { diff --git a/Spigot-Server-Patches/0105-Optimize-Chunk-Access.patch b/Spigot-Server-Patches/0105-Optimize-Chunk-Access.patch index a3a8da9ad..cc119efb0 100644 --- a/Spigot-Server-Patches/0105-Optimize-Chunk-Access.patch +++ b/Spigot-Server-Patches/0105-Optimize-Chunk-Access.patch @@ -1,4 +1,4 @@ -From 1f1ba7ebcc4d5a51914decb47c0537ff3a5ae1da Mon Sep 17 00:00:00 2001 +From 03ee6c4a13460987076f859841235e5460bc2661 Mon Sep 17 00:00:00 2001 From: Aikar Date: Thu, 27 Aug 2015 01:15:02 -0400 Subject: [PATCH] Optimize Chunk Access @@ -9,10 +9,10 @@ getChunkAt is called for the same chunk multiple times in a row, often from getT Optimize this look up by using a Last Access cache. diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index 7ba45c8..fd65117 100644 +index 05417a7..c4b3461 100644 --- a/src/main/java/net/minecraft/server/Chunk.java +++ b/src/main/java/net/minecraft/server/Chunk.java -@@ -32,6 +32,7 @@ public class Chunk { +@@ -30,6 +30,7 @@ public class Chunk { private boolean i; public final World world; public final int[] heightMap; @@ -20,7 +20,7 @@ index 7ba45c8..fd65117 100644 public final int locX; public final int locZ; private boolean l; -@@ -99,6 +100,7 @@ public class Chunk { +@@ -97,6 +98,7 @@ public class Chunk { this.world = world; this.locX = i; this.locZ = j; @@ -29,7 +29,7 @@ index 7ba45c8..fd65117 100644 for (int k = 0; k < this.entitySlices.length; ++k) { diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index f9375eb..90348d5 100644 +index f5a2580..f31ffe2 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java @@ -24,7 +24,18 @@ public class ChunkProviderServer implements IChunkProvider { @@ -52,7 +52,7 @@ index f9375eb..90348d5 100644 // private final LongHashMap chunks = new LongHashMap(); // private final List chunkList = Lists.newArrayList(); public final WorldServer world; -@@ -59,6 +70,7 @@ public class ChunkProviderServer implements IChunkProvider { +@@ -53,6 +64,7 @@ public class ChunkProviderServer implements IChunkProvider { Chunk c = chunks.get(LongHash.toLong(i, j)); if (c != null) { @@ -60,7 +60,7 @@ index f9375eb..90348d5 100644 c.mustSave = true; } // CraftBukkit end -@@ -333,6 +345,7 @@ public class ChunkProviderServer implements IChunkProvider { +@@ -328,6 +340,7 @@ public class ChunkProviderServer implements IChunkProvider { chunk.removeEntities(); this.saveChunk(chunk); this.saveChunkNOP(chunk); @@ -69,10 +69,10 @@ index f9375eb..90348d5 100644 } diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index d8bd36c..d21076b 100644 +index 406bdaa..0419eb4 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -160,6 +160,12 @@ public abstract class World implements IBlockAccess { +@@ -156,6 +156,12 @@ public abstract class World implements IBlockAccess { public Chunk getChunkIfLoaded(BlockPosition blockposition) { return this.chunkProvider.getLoadedChunkAt(blockposition.getX() >> 4, blockposition.getZ() >> 4); } @@ -110,5 +110,5 @@ index caa5e62..c69e070 100644 // Update neighbor counts for (int xx = -2; xx < 3; xx++) { -- -2.7.4.windows.1 +2.7.1.windows.2 diff --git a/Spigot-Server-Patches/0107-Optimize-isValidLocation-for-inlining.patch b/Spigot-Server-Patches/0107-Optimize-isValidLocation-for-inlining.patch index 8e026f843..91941b580 100644 --- a/Spigot-Server-Patches/0107-Optimize-isValidLocation-for-inlining.patch +++ b/Spigot-Server-Patches/0107-Optimize-isValidLocation-for-inlining.patch @@ -1,4 +1,4 @@ -From 64e71e5b3e3539cf102becf3e3c95c10c3856db6 Mon Sep 17 00:00:00 2001 +From 8eb1640efd765ee190b892daaf1be6c45ba1488f Mon Sep 17 00:00:00 2001 From: Aikar Date: Tue, 22 Mar 2016 23:41:34 -0400 Subject: [PATCH] Optimize isValidLocation for inlining @@ -22,10 +22,10 @@ index f0908a2..d1688e1 100644 public BaseBlockPosition(int i, int j, int k) { diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index dcce296..edfb4cd 100644 +index 0419eb4..90b4367 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -288,8 +288,8 @@ public abstract class World implements IBlockAccess { +@@ -284,8 +284,8 @@ public abstract class World implements IBlockAccess { return this.getType(blockposition1); } @@ -36,7 +36,7 @@ index dcce296..edfb4cd 100644 } public boolean isEmpty(BlockPosition blockposition) { -@@ -301,7 +301,7 @@ public abstract class World implements IBlockAccess { +@@ -297,7 +297,7 @@ public abstract class World implements IBlockAccess { } public boolean a(BlockPosition blockposition, boolean flag) { @@ -45,7 +45,7 @@ index dcce296..edfb4cd 100644 } public boolean areChunksLoaded(BlockPosition blockposition, int i) { -@@ -381,7 +381,7 @@ public abstract class World implements IBlockAccess { +@@ -377,7 +377,7 @@ public abstract class World implements IBlockAccess { return true; } // CraftBukkit end @@ -54,7 +54,7 @@ index dcce296..edfb4cd 100644 return false; } else if (!this.isClientSide && this.worldData.getType() == WorldType.DEBUG_ALL_BLOCK_STATES) { return false; -@@ -649,7 +649,7 @@ public abstract class World implements IBlockAccess { +@@ -655,7 +655,7 @@ public abstract class World implements IBlockAccess { // Paper start - test if meets light level, return faster // logic copied from below public boolean isLightLevel(BlockPosition blockposition, int level) { @@ -63,7 +63,7 @@ index dcce296..edfb4cd 100644 if (this.getType(blockposition).f()) { if (this.c(blockposition.up(), false) >= level) { return true; -@@ -762,7 +762,7 @@ public abstract class World implements IBlockAccess { +@@ -768,7 +768,7 @@ public abstract class World implements IBlockAccess { blockposition = new BlockPosition(blockposition.getX(), 0, blockposition.getZ()); } @@ -72,7 +72,7 @@ index dcce296..edfb4cd 100644 return enumskyblock.c; } else if (!this.isLoaded(blockposition)) { return enumskyblock.c; -@@ -774,7 +774,7 @@ public abstract class World implements IBlockAccess { +@@ -780,7 +780,7 @@ public abstract class World implements IBlockAccess { } public void a(EnumSkyBlock enumskyblock, BlockPosition blockposition, int i) { @@ -81,7 +81,7 @@ index dcce296..edfb4cd 100644 if (this.isLoaded(blockposition)) { Chunk chunk = this.getChunkAtWorldCoords(blockposition); -@@ -810,7 +810,7 @@ public abstract class World implements IBlockAccess { +@@ -816,7 +816,7 @@ public abstract class World implements IBlockAccess { // CraftBukkit end Chunk chunk = this.getChunkIfLoaded(blockposition); if (chunk != null) { @@ -90,7 +90,7 @@ index dcce296..edfb4cd 100644 } return null; } -@@ -828,7 +828,7 @@ public abstract class World implements IBlockAccess { +@@ -834,7 +834,7 @@ public abstract class World implements IBlockAccess { } } // CraftBukkit end @@ -99,7 +99,7 @@ index dcce296..edfb4cd 100644 return Blocks.AIR.getBlockData(); } else { Chunk chunk = this.getChunkAtWorldCoords(blockposition); -@@ -2044,7 +2044,7 @@ public abstract class World implements IBlockAccess { +@@ -2050,7 +2050,7 @@ public abstract class World implements IBlockAccess { public Map capturedTileEntities = Maps.newHashMap(); public TileEntity getTileEntity(BlockPosition blockposition) { @@ -108,7 +108,7 @@ index dcce296..edfb4cd 100644 return null; } else { // CraftBukkit start -@@ -2147,7 +2147,7 @@ public abstract class World implements IBlockAccess { +@@ -2153,7 +2153,7 @@ public abstract class World implements IBlockAccess { } public boolean d(BlockPosition blockposition, boolean flag) {