diff --git a/Spigot-Server-Patches/Always-tick-falling-blocks.patch b/Spigot-Server-Patches/Always-tick-falling-blocks.patch index 8d6b66b8c6..b2bcd78177 100644 --- a/Spigot-Server-Patches/Always-tick-falling-blocks.patch +++ b/Spigot-Server-Patches/Always-tick-falling-blocks.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Always tick falling blocks diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index a99c0cea0f..a95f93eb76 100644 +index bf35950867..8e1234c246 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -0,0 +0,0 @@ import net.minecraft.server.EntityCreature; @@ -18,7 +18,7 @@ index a99c0cea0f..a95f93eb76 100644 import net.minecraft.server.EntityHuman; @@ -0,0 +0,0 @@ public class ActivationRange || entity instanceof EntityFireball - || entity instanceof EntityWeather + || entity instanceof EntityLightning || entity instanceof EntityTNTPrimed + || entity instanceof EntityFallingBlock // Paper - Always tick falling blocks || entity instanceof EntityEnderCrystal diff --git a/Spigot-Server-Patches/Check-online-mode-before-converting-and-renaming-pla.patch b/Spigot-Server-Patches/Check-online-mode-before-converting-and-renaming-pla.patch index 848f98466e..a8b7bf0c44 100644 --- a/Spigot-Server-Patches/Check-online-mode-before-converting-and-renaming-pla.patch +++ b/Spigot-Server-Patches/Check-online-mode-before-converting-and-renaming-pla.patch @@ -5,11 +5,11 @@ Subject: [PATCH] Check online mode before converting and renaming player data diff --git a/src/main/java/net/minecraft/server/WorldNBTStorage.java b/src/main/java/net/minecraft/server/WorldNBTStorage.java -index 3d5aaf052b..c4173c0aad 100644 +index e9e7d92584..e821dfbaf6 100644 --- a/src/main/java/net/minecraft/server/WorldNBTStorage.java +++ b/src/main/java/net/minecraft/server/WorldNBTStorage.java -@@ -0,0 +0,0 @@ public class WorldNBTStorage implements IDataManager, IPlayerFileData { - File file = new File(this.playerDir, entityhuman.bu() + ".dat"); +@@ -0,0 +0,0 @@ public class WorldNBTStorage implements IPlayerFileData { + File file = new File(this.playerDir, entityhuman.getUniqueIDString() + ".dat"); // Spigot Start boolean usingWrongFile = false; - if ( !file.exists() ) diff --git a/Spigot-Server-Patches/Configurable-end-credits.patch b/Spigot-Server-Patches/Configurable-end-credits.patch index f8722aeffd..1e6fa219af 100644 --- a/Spigot-Server-Patches/Configurable-end-credits.patch +++ b/Spigot-Server-Patches/Configurable-end-credits.patch @@ -5,12 +5,12 @@ 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 59d82fa4fb..012182378a 100644 +index a797a57671..c2b9690a0c 100644 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java @@ -0,0 +0,0 @@ public class PaperWorldConfig { - log("Warning: This feature may help reduce TPS loss from light, but comes at the cost of buggy light data"); - log("We are working to improve this feature."); + } + } } + + public boolean disableEndCredits; @@ -20,24 +20,24 @@ index 59d82fa4fb..012182378a 100644 + } } diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java -index 0902c69f33..c4a55c6a1f 100644 +index e7856b2abe..5548163666 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/EntityPlayer.java @@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { - private long cu = SystemUtils.getMonotonicMillis(); + private long cm = SystemUtils.getMonotonicMillis(); private Entity spectatedEntity; public boolean worldChangeInvuln; -- private boolean cx; -+ private boolean cx; private void setHasSeenCredits(boolean has) { this.cx = has; } // Paper - OBFHELPER +- private boolean cp; ++ private boolean cp; private void setHasSeenCredits(boolean has) { this.cp = has; } // Paper - OBFHELPER private final RecipeBookServer recipeBook; - private Vec3D cz; - private int cA; + private Vec3D cr; + private int cs; @@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { - this.world.kill(this); + this.getWorldServer().removePlayer(this); if (!this.viewingCredits) { this.viewingCredits = true; + if (world.paperConfig.disableEndCredits) this.setHasSeenCredits(true); // Paper - Toggle to always disable end credits - this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(4, this.cx ? 0.0F : 1.0F)); - this.cx = true; + this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(4, this.cp ? 0.0F : 1.0F)); + this.cp = true; } -- \ No newline at end of file diff --git a/Spigot-Server-Patches/Configurable-top-of-nether-void-damage.patch b/Spigot-Server-Patches/Configurable-top-of-nether-void-damage.patch index c967d3d6bc..04ee2a3bc1 100644 --- a/Spigot-Server-Patches/Configurable-top-of-nether-void-damage.patch +++ b/Spigot-Server-Patches/Configurable-top-of-nether-void-damage.patch @@ -29,7 +29,7 @@ index 1ed58f4bba..a797a57671 100644 + } } diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index b4b73dbfd3..ad30cdd824 100644 +index c813b59af5..494c6cb4aa 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java @@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke @@ -40,7 +40,7 @@ index b4b73dbfd3..ad30cdd824 100644 + // Extracted to own function + /* if (this.locY < -64.0D) { - this.aa(); + this.ae(); } + */ + this.performVoidDamage(); @@ -49,7 +49,7 @@ index b4b73dbfd3..ad30cdd824 100644 if (!this.world.isClientSide) { this.setFlag(0, this.fireTicks > 0); @@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - this.world.methodProfiler.exit(); + this.world.getMethodProfiler().exit(); } + // Paper start @@ -70,15 +70,15 @@ index b4b73dbfd3..ad30cdd824 100644 this.fireTicks = 0; } -+ protected final void doVoidDamage() { this.aa(); } // Paper - OBFHELPER - protected void aa() { ++ protected final void doVoidDamage() { this.ae(); } // Paper - OBFHELPER + protected void ae() { this.die(); } diff --git a/src/main/java/net/minecraft/server/EntityMinecartAbstract.java b/src/main/java/net/minecraft/server/EntityMinecartAbstract.java -index 205251bcdd..0f531e7d42 100644 +index 4d2ef9a02b..6fc332dbff 100644 --- a/src/main/java/net/minecraft/server/EntityMinecartAbstract.java +++ b/src/main/java/net/minecraft/server/EntityMinecartAbstract.java -@@ -0,0 +0,0 @@ public abstract class EntityMinecartAbstract extends Entity implements INamableT +@@ -0,0 +0,0 @@ public abstract class EntityMinecartAbstract extends Entity { this.setDamage(this.getDamage() - 1.0F); } @@ -86,12 +86,12 @@ index 205251bcdd..0f531e7d42 100644 + // Extracted to own function + /* if (this.locY < -64.0D) { - this.aa(); + this.ae(); } + */ + this.performVoidDamage(); + // Paper end - int i; - + // this.doPortalTick(); // CraftBukkit - handled in postTick + if (this.world.isClientSide) { -- \ No newline at end of file diff --git a/Spigot-Server-Patches/Entity-Origin-API.patch b/Spigot-Server-Patches/Entity-Origin-API.patch index 1ec0816c28..abad3b4d49 100644 --- a/Spigot-Server-Patches/Entity-Origin-API.patch +++ b/Spigot-Server-Patches/Entity-Origin-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Entity Origin API diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index 2198182ec9..b4b73dbfd3 100644 +index 7191861e81..c813b59af5 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java @@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke @@ -51,7 +51,7 @@ index 2198182ec9..b4b73dbfd3 100644 NBTTagList nbttaglist = new NBTTagList(); double[] adouble1 = adouble; diff --git a/src/main/java/net/minecraft/server/EntityFallingBlock.java b/src/main/java/net/minecraft/server/EntityFallingBlock.java -index a6eae266de..489dd861d2 100644 +index 55591fbe05..90becdfdec 100644 --- a/src/main/java/net/minecraft/server/EntityFallingBlock.java +++ b/src/main/java/net/minecraft/server/EntityFallingBlock.java @@ -0,0 +0,0 @@ public class EntityFallingBlock extends Entity { @@ -70,11 +70,11 @@ index a6eae266de..489dd861d2 100644 public void a(boolean flag) { diff --git a/src/main/java/net/minecraft/server/EntityTNTPrimed.java b/src/main/java/net/minecraft/server/EntityTNTPrimed.java -index 8c19278f37..7f4b68dcc0 100644 +index e3001570f9..e0535604b6 100644 --- a/src/main/java/net/minecraft/server/EntityTNTPrimed.java +++ b/src/main/java/net/minecraft/server/EntityTNTPrimed.java @@ -0,0 +0,0 @@ public class EntityTNTPrimed extends Entity { - + @Override protected void a(NBTTagCompound nbttagcompound) { this.setFuseTicks(nbttagcompound.getShort("Fuse")); + // Paper start - Try and load origin location from the old NBT tags for backwards compatibility @@ -89,36 +89,19 @@ index 8c19278f37..7f4b68dcc0 100644 @Nullable diff --git a/src/main/java/net/minecraft/server/NBTTagList.java b/src/main/java/net/minecraft/server/NBTTagList.java -index 27debcfca9..22027321bd 100644 +index ce510c4867..b7c94fe238 100644 --- a/src/main/java/net/minecraft/server/NBTTagList.java +++ b/src/main/java/net/minecraft/server/NBTTagList.java @@ -0,0 +0,0 @@ public class NBTTagList extends NBTList { return new int[0]; } -+ public final double getDoubleAt(int i) { return this.k(i); } // Paper - OBFHELPER - public double k(int i) { ++ public final double getDoubleAt(int i) { return this.h(i); } // Paper - OBFHELPER + public double h(int i) { if (i >= 0 && i < this.list.size()) { NBTBase nbtbase = (NBTBase) this.list.get(i); -diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 106ad00dc7..470f406227 100644 ---- a/src/main/java/net/minecraft/server/World.java -+++ b/src/main/java/net/minecraft/server/World.java -@@ -0,0 +0,0 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc - int j = MathHelper.floor(entity.locZ / 16.0D); - boolean flag = entity.attachedToPlayer; - -+ // Paper start - Set origin location when the entity is being added to the world -+ if (entity.origin == null) { -+ entity.origin = entity.getBukkitEntity().getLocation(); -+ } -+ // Paper end -+ - if (entity instanceof EntityHuman) { - flag = true; - } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 7edbbb106b..660e59ba15 100644 +index c1ad2626a7..852de0d625 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -0,0 +0,0 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { diff --git a/Spigot-Server-Patches/Fix-lag-from-explosions-processing-dead-entities.patch b/Spigot-Server-Patches/Fix-lag-from-explosions-processing-dead-entities.patch index 56eeaa6e2f..0a19254fde 100644 --- a/Spigot-Server-Patches/Fix-lag-from-explosions-processing-dead-entities.patch +++ b/Spigot-Server-Patches/Fix-lag-from-explosions-processing-dead-entities.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix lag from explosions processing dead entities diff --git a/src/main/java/net/minecraft/server/Explosion.java b/src/main/java/net/minecraft/server/Explosion.java -index 33809baf2e..c4db6367e9 100644 +index 462f8f33a1..e1c628f177 100644 --- a/src/main/java/net/minecraft/server/Explosion.java +++ b/src/main/java/net/minecraft/server/Explosion.java @@ -0,0 +0,0 @@ public class Explosion { @@ -25,7 +25,7 @@ index 33809baf2e..c4db6367e9 100644 for (int l1 = 0; l1 < list.size(); ++l1) { diff --git a/src/main/java/net/minecraft/server/IEntitySelector.java b/src/main/java/net/minecraft/server/IEntitySelector.java -index 8225a82582..bbcbb62325 100644 +index ac44db2543..035d70419d 100644 --- a/src/main/java/net/minecraft/server/IEntitySelector.java +++ b/src/main/java/net/minecraft/server/IEntitySelector.java @@ -0,0 +0,0 @@ public final class IEntitySelector { @@ -34,6 +34,6 @@ index 8225a82582..bbcbb62325 100644 }; + public static Predicate canAITarget() { return e; } // Paper - OBFHELPER public static final Predicate e = (entity) -> { - return !(entity instanceof EntityHuman) || !((EntityHuman) entity).isSpectator() && !((EntityHuman) entity).u(); + return !(entity instanceof EntityHuman) || !entity.t() && !((EntityHuman) entity).isCreative(); }; -- \ No newline at end of file diff --git a/Spigot-Server-Patches/Further-improve-server-tick-loop.patch b/Spigot-Server-Patches/Further-improve-server-tick-loop.patch index f2a17d3d4c..81ce960a99 100644 --- a/Spigot-Server-Patches/Further-improve-server-tick-loop.patch +++ b/Spigot-Server-Patches/Further-improve-server-tick-loop.patch @@ -12,19 +12,19 @@ Previous implementation did not calculate TPS correctly. Switch to a realistic rolling average and factor in std deviation as an extra reporting variable diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index df85f35f37..7ca7b9f3ac 100644 +index 89ad19e59c..7dfe1f0a3c 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati +@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); public int autosavePeriod; -@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati + public File bukkitDataPackFolder; +@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant 2000L && this.nextTick - this.lastOverloadTime >= 15000L) { +- long j = i / 50L; +- +- if (server.getWarnOnOverload()) // CraftBukkit +- MinecraftServer.LOGGER.warn("Can't keep up! Is the server overloaded? Running {}ms or {} ticks behind", i, j); +- this.nextTick += j * 50L; +- this.lastOverloadTime = this.nextTick; ++ curTime = System.nanoTime(); + // Paper start - Further improve server tick loop + wait = TICK_TIME - (curTime - lastTick); + if (wait > 0) { @@ -123,12 +122,8 @@ index df85f35f37..7ca7b9f3ac 100644 + catchupTime = 0; + } + } - if (wait > 0) { - Thread.sleep(wait / 1000000); -- catchupTime = 0; -- continue; -- } else { -- catchupTime = Math.min(1000000000, Math.abs(wait)); ++ if (wait > 0) { ++ Thread.sleep(wait / 1000000); + curTime = System.nanoTime(); + wait = TICK_TIME - (curTime - lastTick); } @@ -137,7 +132,7 @@ index df85f35f37..7ca7b9f3ac 100644 + catchupTime = Math.min(MAX_CATCHUP_BUFFER, catchupTime - wait); + if ( ++MinecraftServer.currentTick % SAMPLE_INTERVAL == 0 ) { -- double currentTps = 1E9 / ( curTime - tickSection ) * SAMPLE_INTERVAL; +- double currentTps = 1E3 / ( curTime - tickSection ) * SAMPLE_INTERVAL; - recentTps[0] = calcTps( recentTps[0], 0.92, currentTps ); // 1/exp(5sec/1min) - recentTps[1] = calcTps( recentTps[1], 0.9835, currentTps ); // 1/exp(5sec/5min) - recentTps[2] = calcTps( recentTps[2], 0.9945, currentTps ); // 1/exp(5sec/15min) @@ -153,15 +148,25 @@ index df85f35f37..7ca7b9f3ac 100644 + // Paper end tickSection = curTime; } - lastTick = curTime; + // Spigot end - MinecraftServer.currentTick = (int) (System.currentTimeMillis() / 50); // CraftBukkit + //MinecraftServer.currentTick = (int) (System.currentTimeMillis() / 50); // CraftBukkit // Paper - don't overwrite current tick time - this.a(this::canSleepForTick); ++ this.a(this::canSleepForTick); this.nextTick += 50L; - // Spigot end + if (this.T) { + this.T = false; +@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant -Date: Wed, 2 Mar 2016 00:52:31 -0600 -Subject: [PATCH] Lighting Queue - -This provides option to queue lighting updates to ensure they do not cause the server lag - -diff --git a/src/main/java/co/aikar/timings/WorldTimingsHandler.java b/src/main/java/co/aikar/timings/WorldTimingsHandler.java -index 145cb274b0..eff9dcf54f 100644 ---- a/src/main/java/co/aikar/timings/WorldTimingsHandler.java -+++ b/src/main/java/co/aikar/timings/WorldTimingsHandler.java -@@ -0,0 +0,0 @@ public class WorldTimingsHandler { - public final Timing worldSaveLevel; - public final Timing chunkSaveData; - -+ public final Timing lightingQueueTimer; -+ - public WorldTimingsHandler(World server) { - String name = server.worldData.getName() +" - "; - -@@ -0,0 +0,0 @@ public class WorldTimingsHandler { - tracker2 = Timings.ofSafe(name + "tracker stage 2"); - doTick = Timings.ofSafe(name + "doTick"); - tickEntities = Timings.ofSafe(name + "tickEntities"); -+ -+ lightingQueueTimer = Timings.ofSafe(name + "Lighting Queue"); - } - - public static Timing getTickList(WorldServer worldserver, String timingsType) { -diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java -index 7691409f6c..cfcc244672 100644 ---- a/src/main/java/com/destroystokyo/paper/PaperConfig.java -+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java -@@ -0,0 +0,0 @@ public class PaperConfig { - return config.getString(path, config.getString(path)); - } - -+ public static int maxTickMsLostLightQueue; -+ private static void lightQueue() { -+ int badSetting = config.getInt("queue-light-updates-max-loss", 10); -+ config.set("queue-light-updates-max-loss", null); -+ maxTickMsLostLightQueue = getInt("settings.queue-light-updates-max-loss", badSetting); -+ } -+ - private static void timings() { - boolean timings = getBoolean("timings.enabled", true); - boolean verboseTimings = getBoolean("timings.verbose", true); -diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index a797a57671..59d82fa4fb 100644 ---- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -@@ -0,0 +0,0 @@ public class PaperWorldConfig { - } - } - } -+ -+ public boolean queueLightUpdates; -+ private void queueLightUpdates() { -+ queueLightUpdates = getBoolean("queue-light-updates", false); -+ log("Lighting Queue enabled: " + queueLightUpdates); -+ log("Warning: This feature may help reduce TPS loss from light, but comes at the cost of buggy light data"); -+ log("We are working to improve this feature."); -+ } - } -diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index e15ed21f67..a9aa13fbf8 100644 ---- a/src/main/java/net/minecraft/server/Chunk.java -+++ b/src/main/java/net/minecraft/server/Chunk.java -@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess { - return removed; - } - } -+ final PaperLightingQueue.LightingQueue lightingQueue = new PaperLightingQueue.LightingQueue(this); - // Paper end - public boolean areNeighborsLoaded(final int radius) { - switch (radius) { -@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess { - - private void g(boolean flag) { - this.world.methodProfiler.enter("recheckGaps"); -- if (this.world.areChunksLoaded(new BlockPosition(this.locX * 16 + 8, 0, this.locZ * 16 + 8), 16)) { -+ if (this.areNeighborsLoaded(1)) { // Paper - for (int i = 0; i < 16; ++i) { - for (int j = 0; j < 16; ++j) { - if (this.g[i + j * 16]) { -@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess { - } - - private void a(int i, int j, int k, int l) { -- if (l > k && this.world.areChunksLoaded(new BlockPosition(i, 0, j), 16)) { -+ if (l > k && this.areNeighborsLoaded(1)) { // Paper - for (int i1 = k; i1 < l; ++i1) { - this.world.c(EnumSkyBlock.SKY, new BlockPosition(i, i1, j)); - } -@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess { - if (flag1) { - this.initLighting(); - } else { -+ this.runOrQueueLightUpdate(() -> { // Paper - Queue light update - int i1 = iblockdata.b(this.world, blockposition); - int j1 = iblockdata1.b(this.world, blockposition); - -@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess { - if (i1 != j1 && (i1 < j1 || this.getBrightness(EnumSkyBlock.SKY, blockposition) > 0 || this.getBrightness(EnumSkyBlock.BLOCK, blockposition) > 0)) { - this.c(i, k); - } -+ }); // Paper - } - - TileEntity tileentity; -@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess { - return this.D == 8; - } - -+ // Paper start -+ public void runOrQueueLightUpdate(Runnable runnable) { -+ if (this.world.paperConfig.queueLightUpdates) { -+ lightingQueue.add(runnable); -+ } else { -+ runnable.run(); -+ } -+ } -+ // Paper end -+ - public static enum EnumTileEntityState { - - IMMEDIATE, QUEUED, CHECK; -diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index eb83e20d50..c2ecc034e8 100644 ---- a/src/main/java/net/minecraft/server/ChunkProviderServer.java -+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java -@@ -0,0 +0,0 @@ public class ChunkProviderServer implements IChunkProvider { - return false; - } - save = event.isSaveChunk(); -+ chunk.lightingQueue.processUnload(); // Paper - - // Update neighbor counts - for (int x = -2; x < 3; x++) { -diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 7ca7b9f3ac..00f1c36e99 100644 ---- a/src/main/java/net/minecraft/server/MinecraftServer.java -+++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati - protected void a(BooleanSupplier booleansupplier) { - co.aikar.timings.TimingsManager.FULL_SERVER_TICK.startTiming(); // Paper - this.slackActivityAccountant.tickStarted(); // Spigot -- long i = SystemUtils.getMonotonicNanos(); -+ long i = SystemUtils.getMonotonicNanos(); long startTime = i; // Paper - - ++this.ticks; - if (this.S) { -@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati - this.methodProfiler.exit(); - this.methodProfiler.exit(); - org.spigotmc.WatchdogThread.tick(); // Spigot -+ PaperLightingQueue.processQueue(startTime); // Paper - this.slackActivityAccountant.tickEnded(l); // Spigot - co.aikar.timings.TimingsManager.FULL_SERVER_TICK.stopTiming(); // Paper - } -diff --git a/src/main/java/net/minecraft/server/PaperLightingQueue.java b/src/main/java/net/minecraft/server/PaperLightingQueue.java -new file mode 100644 -index 0000000000..9783f3a0d9 ---- /dev/null -+++ b/src/main/java/net/minecraft/server/PaperLightingQueue.java -@@ -0,0 +0,0 @@ -+package net.minecraft.server; -+ -+import co.aikar.timings.Timing; -+import com.destroystokyo.paper.PaperConfig; -+import it.unimi.dsi.fastutil.objects.ObjectCollection; -+ -+import java.util.ArrayDeque; -+ -+class PaperLightingQueue { -+ private static final long MAX_TIME = (long) (1000000 * (50 + PaperConfig.maxTickMsLostLightQueue)); -+ -+ static void processQueue(long curTime) { -+ final long startTime = System.nanoTime(); -+ final long maxTickTime = MAX_TIME - (startTime - curTime); -+ -+ if (maxTickTime <= 0) { -+ return; -+ } -+ -+ START: -+ for (World world : MinecraftServer.getServer().getWorlds()) { -+ if (!world.paperConfig.queueLightUpdates) { -+ continue; -+ } -+ -+ ObjectCollection loadedChunks = ((WorldServer) world).getChunkProvider().chunks.values(); -+ for (Chunk chunk : loadedChunks.toArray(new Chunk[0])) { -+ if (chunk.lightingQueue.processQueue(startTime, maxTickTime)) { -+ break START; -+ } -+ } -+ } -+ } -+ -+ static class LightingQueue extends ArrayDeque { -+ final private Chunk chunk; -+ -+ LightingQueue(Chunk chunk) { -+ super(); -+ this.chunk = chunk; -+ } -+ -+ /** -+ * Processes the lighting queue for this chunk -+ * -+ * @param startTime If start Time is 0, we will not limit execution time -+ * @param maxTickTime Maximum time to spend processing lighting updates -+ * @return true to abort processing furthur lighting updates -+ */ -+ private boolean processQueue(long startTime, long maxTickTime) { -+ if (this.isEmpty()) { -+ return false; -+ } -+ if (isOutOfTime(maxTickTime, startTime)) { -+ return true; -+ } -+ try (Timing ignored = chunk.world.timings.lightingQueueTimer.startTiming()) { -+ Runnable lightUpdate; -+ while ((lightUpdate = this.poll()) != null) { -+ lightUpdate.run(); -+ if (isOutOfTime(maxTickTime, startTime)) { -+ return true; -+ } -+ } -+ } -+ -+ return false; -+ } -+ -+ /** -+ * Flushes lighting updates to unload the chunk -+ */ -+ void processUnload() { -+ if (!chunk.world.paperConfig.queueLightUpdates) { -+ return; -+ } -+ processQueue(0, 0); // No timeout -+ -+ final int radius = 1; -+ for (int x = chunk.locX - radius; x <= chunk.locX + radius; ++x) { -+ for (int z = chunk.locZ - radius; z <= chunk.locZ + radius; ++z) { -+ if (x == chunk.locX && z == chunk.locZ) { -+ continue; -+ } -+ -+ Chunk neighbor = chunk.world.getChunkIfLoaded(x, z); -+ if (neighbor != null) { -+ neighbor.lightingQueue.processQueue(0, 0); // No timeout -+ } -+ } -+ } -+ } -+ } -+ -+ private static boolean isOutOfTime(long maxTickTime, long startTime) { -+ return startTime > 0 && System.nanoTime() - startTime > maxTickTime; -+ } -+} -diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index b10e4c409d..f3755fcfbe 100644 ---- a/src/main/java/net/minecraft/server/World.java -+++ b/src/main/java/net/minecraft/server/World.java -@@ -0,0 +0,0 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc - - if (iblockdata2.b(this, blockposition) != iblockdata1.b(this, blockposition) || iblockdata2.e() != iblockdata1.e()) { - this.methodProfiler.enter("checkLight"); -- this.r(blockposition); -+ chunk.runOrQueueLightUpdate(() -> this.r(blockposition)); // Paper - Queue light update - this.methodProfiler.exit(); - } - --- \ No newline at end of file diff --git a/Spigot-Server-Patches/Only-refresh-abilities-if-needed.patch b/Spigot-Server-Patches/Only-refresh-abilities-if-needed.patch index eb57af568d..f19626a1cf 100644 --- a/Spigot-Server-Patches/Only-refresh-abilities-if-needed.patch +++ b/Spigot-Server-Patches/Only-refresh-abilities-if-needed.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Only refresh abilities if needed diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 15c2e1dee7..0ee063bcd3 100644 +index ca65d51d81..6b93cc3a57 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/Spigot-Server-Patches/Optimize-explosions.patch b/Spigot-Server-Patches/Optimize-explosions.patch index fc050a0a62..1d81be44ba 100644 --- a/Spigot-Server-Patches/Optimize-explosions.patch +++ b/Spigot-Server-Patches/Optimize-explosions.patch @@ -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 012182378a..a39451c69a 100644 +index c2b9690a0c..a5ec0bc0e0 100644 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java @@ -0,0 +0,0 @@ public class PaperWorldConfig { @@ -25,32 +25,31 @@ index 012182378a..a39451c69a 100644 + } } diff --git a/src/main/java/net/minecraft/server/Explosion.java b/src/main/java/net/minecraft/server/Explosion.java -index c4db6367e9..3e44b2d549 100644 +index e1c628f177..bcff117619 100644 --- a/src/main/java/net/minecraft/server/Explosion.java +++ b/src/main/java/net/minecraft/server/Explosion.java @@ -0,0 +0,0 @@ public class Explosion { d8 /= d11; d9 /= d11; d10 /= d11; -- double d12 = (double) this.world.a(vec3d, entity.getBoundingBox()); -+ double d12 = this.getBlockDensity(vec3d, entity.getBoundingBox()); // Paper - Optimize explosions +- double d12 = (double) a(vec3d, entity); ++ double d12 = this.getBlockDensity(vec3d, entity); // Paper - Optimize explosions double d13 = (1.0D - d7) * d12; // CraftBukkit start @@ -0,0 +0,0 @@ public class Explosion { - public List getBlocks() { - return this.blocks; + + private Effect() {} } -+ + // Paper start - Optimize explosions -+ private float getBlockDensity(Vec3D vec3d, AxisAlignedBB aabb) { ++ private float getBlockDensity(Vec3D vec3d, Entity entity) { + if (!this.world.paperConfig.optimizeExplosions) { -+ return this.world.a(vec3d, aabb); ++ return a(vec3d, entity); + } -+ CacheKey key = new CacheKey(this, aabb); ++ CacheKey key = new CacheKey(this, entity.getBoundingBox()); + Float blockDensity = this.world.explosionDensityCache.get(key); + if (blockDensity == null) { -+ blockDensity = this.world.a(vec3d, aabb); ++ blockDensity = a(vec3d, entity); + this.world.explosionDensityCache.put(key, blockDensity); + } + @@ -124,11 +123,11 @@ index c4db6367e9..3e44b2d549 100644 + // Paper end } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 00f1c36e99..f488c37f73 100644 +index 7dfe1f0a3c..8704c091d7 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati - worldserver.getTracker().updatePlayers(); +@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant