diff --git a/Spigot-Server-Patches/0427-Optimise-TickListServer-by-rewriting-it.patch b/Spigot-Server-Patches/0427-Optimise-TickListServer-by-rewriting-it.patch index 12fce4d284..44aa3f8cb1 100644 --- a/Spigot-Server-Patches/0427-Optimise-TickListServer-by-rewriting-it.patch +++ b/Spigot-Server-Patches/0427-Optimise-TickListServer-by-rewriting-it.patch @@ -42,7 +42,7 @@ sets the excessive tick delay to the specified ticks (defaults to 60 * 20 ticks, aka 60 seconds) diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java -index bf86444c479f346e7d56f10a7c0ebefd62f08f59..8508b3e10e60a4ce36d471b1d3f7ffc836a6ddf7 100644 +index f4a56028c21427d1164c5777285114a284b5643c..ee1a690c1b12f28a5282a61917d28deb3ca08f61 100644 --- a/src/main/java/com/destroystokyo/paper/PaperConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java @@ -349,6 +349,13 @@ public class PaperConfig { @@ -61,10 +61,10 @@ index bf86444c479f346e7d56f10a7c0ebefd62f08f59..8508b3e10e60a4ce36d471b1d3f7ffc8 ConfigurationSection section; diff --git a/src/main/java/com/destroystokyo/paper/server/ticklist/PaperTickList.java b/src/main/java/com/destroystokyo/paper/server/ticklist/PaperTickList.java new file mode 100644 -index 0000000000000000000000000000000000000000..bbb042fec32ce5a4aecf1934ab6bed77c5134a7f +index 0000000000000000000000000000000000000000..e7624948ea4aa1a07d84ed3d295cfe2dd354fd14 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/server/ticklist/PaperTickList.java -@@ -0,0 +1,624 @@ +@@ -0,0 +1,628 @@ +package com.destroystokyo.paper.server.ticklist; + +import net.minecraft.server.MCUtil; @@ -137,7 +137,7 @@ index 0000000000000000000000000000000000000000..bbb042fec32ce5a4aecf1934ab6bed77 + } + private int shortScheduledIndex; + -+ private long nextTick; ++ private long currentTick; + + private static final boolean WARN_ON_EXCESSIVE_DELAY = Boolean.getBoolean("paper.ticklist-warn-on-excessive-delay"); + private static final long EXCESSIVE_DELAY_THRESHOLD = Long.getLong("paper.ticklist-excessive-delay-threshold", 60 * 20).longValue(); // 1 min dfl @@ -163,7 +163,7 @@ index 0000000000000000000000000000000000000000..bbb042fec32ce5a4aecf1934ab6bed77 + this.timingCleanup = co.aikar.timings.WorldTimingsHandler.getTickList(world, timingsType + " - Cleanup"); // Paper + this.timingTicking = co.aikar.timings.WorldTimingsHandler.getTickList(world, timingsType + " - Ticking"); // Paper + this.timingFinished = co.aikar.timings.WorldTimingsHandler.getTickList(world, timingsType + " - Finish"); -+ this.nextTick = this.world.getTime(); ++ this.currentTick = this.world.getTime(); + } + + private void queueEntryForTick(final NextTickListEntry entry, final ChunkProviderServer chunkProvider) { @@ -185,7 +185,7 @@ index 0000000000000000000000000000000000000000..bbb042fec32ce5a4aecf1934ab6bed77 + } + + private void addToSchedule(final NextTickListEntry entry) { -+ long delay = entry.getTargetTick() - this.nextTick; ++ long delay = entry.getTargetTick() - (this.currentTick + 1); + if (delay < SHORT_SCHEDULE_TICK_THRESHOLD) { + if (delay < 0) { + // longScheduled orders by tick time, short scheduled does not @@ -246,7 +246,7 @@ index 0000000000000000000000000000000000000000..bbb042fec32ce5a4aecf1934ab6bed77 + } + } + -+ long delay = entry.getTargetTick() - this.nextTick; ++ long delay = entry.getTargetTick() - (this.currentTick + 1); + if (delay >= SHORT_SCHEDULE_TICK_THRESHOLD) { + this.longScheduled.remove(entry); + } @@ -266,7 +266,7 @@ index 0000000000000000000000000000000000000000..bbb042fec32ce5a4aecf1934ab6bed77 + } + + private void prepare() { -+ final long currentTick = this.nextTick; ++ final long currentTick = this.currentTick; + + final ChunkProviderServer chunkProvider = this.world.getChunkProvider(); + @@ -334,15 +334,19 @@ index 0000000000000000000000000000000000000000..bbb042fec32ce5a4aecf1934ab6bed77 + private boolean warnedAboutDesync; + + @Override -+ public void tick() { -+ ++this.nextTick; -+ if (this.nextTick != this.world.getTime()) { ++ protected void nextTick() { ++ ++this.currentTick; ++ if (this.currentTick != this.world.getTime()) { + if (!this.warnedAboutDesync) { + this.warnedAboutDesync = true; -+ MinecraftServer.LOGGER.error("World tick desync detected! Expected " + this.nextTick + " ticks, but got " + this.world.getTime() + " ticks for world '" + this.world.getWorld().getName() + "'", new Throwable()); ++ MinecraftServer.LOGGER.error("World tick desync detected! Expected " + this.currentTick + " ticks, but got " + this.world.getTime() + " ticks for world '" + this.world.getWorld().getName() + "'", new Throwable()); + MinecraftServer.LOGGER.error("Preventing redstone from breaking by refusing to accept new tick time"); + } + } ++ } ++ ++ @Override ++ public void tick() { + final ChunkProviderServer chunkProvider = this.world.getChunkProvider(); + + this.world.getMethodProfiler().enter("cleaning"); @@ -479,7 +483,7 @@ index 0000000000000000000000000000000000000000..bbb042fec32ce5a4aecf1934ab6bed77 + + @Override + public void schedule(BlockPosition blockPosition, T t, int i, TickListPriority tickListPriority) { -+ this.schedule(blockPosition, t, i + this.nextTick, tickListPriority); ++ this.schedule(blockPosition, t, i + this.currentTick, tickListPriority); + } + + public void schedule(final NextTickListEntry entry) { @@ -493,7 +497,7 @@ index 0000000000000000000000000000000000000000..bbb042fec32ce5a4aecf1934ab6bed77 + } + + if (WARN_ON_EXCESSIVE_DELAY) { -+ final long delay = entry.getTargetTick() - this.nextTick; ++ final long delay = entry.getTargetTick() - this.currentTick; + if (delay >= EXCESSIVE_DELAY_THRESHOLD) { + MinecraftServer.LOGGER.warn("Entry " + entry.toString() + " has been scheduled with an excessive delay of: " + delay, new Throwable()); + } @@ -651,7 +655,7 @@ index 0000000000000000000000000000000000000000..bbb042fec32ce5a4aecf1934ab6bed77 + // start copy from TickListServer // TODO check on update + List> list = this.getEntriesInChunk(chunkcoordintpair, false, true); + -+ return TickListServer.serialize(this.getMinecraftKeyFrom, list, this.nextTick); ++ return TickListServer.serialize(this.getMinecraftKeyFrom, list, this.currentTick); + // end copy from TickListServer + } + @@ -1069,12 +1073,17 @@ index f94234b0a247e378ff9056d6c418464d619a356b..8af1229c3da63a838b0bec1cafde1e41 } diff --git a/src/main/java/net/minecraft/server/TickListServer.java b/src/main/java/net/minecraft/server/TickListServer.java -index 3b8f56c0f0507ebdd9ac20be70688b4c0cfe4cf8..149d2b4f929c11b8baf17163bbd6ff8220a95e86 100644 +index 3b8f56c0f0507ebdd9ac20be70688b4c0cfe4cf8..3e148b7e99554a1abe257dd3c9acafb914e1ebc8 100644 --- a/src/main/java/net/minecraft/server/TickListServer.java +++ b/src/main/java/net/minecraft/server/TickListServer.java -@@ -39,6 +39,11 @@ public class TickListServer implements TickList { +@@ -38,7 +38,16 @@ public class TickListServer implements TickList { + private final co.aikar.timings.Timing timingTicking; // Paper // Paper end ++ // Paper start ++ protected void nextTick() {} ++ // Paper end ++ public void b() { + // Paper start - allow overriding + this.tick(); @@ -1084,7 +1093,7 @@ index 3b8f56c0f0507ebdd9ac20be70688b4c0cfe4cf8..149d2b4f929c11b8baf17163bbd6ff82 int i = this.nextTickList.size(); if (false) { // CraftBukkit -@@ -106,10 +111,20 @@ public class TickListServer implements TickList { +@@ -106,10 +115,20 @@ public class TickListServer implements TickList { @Override public boolean b(BlockPosition blockposition, T t0) { @@ -1105,7 +1114,7 @@ index 3b8f56c0f0507ebdd9ac20be70688b4c0cfe4cf8..149d2b4f929c11b8baf17163bbd6ff82 int i = (chunkcoordintpair.x << 4) - 2; int j = i + 16 + 2; int k = (chunkcoordintpair.z << 4) - 2; -@@ -119,6 +134,11 @@ public class TickListServer implements TickList { +@@ -119,6 +138,11 @@ public class TickListServer implements TickList { } public List> a(StructureBoundingBox structureboundingbox, boolean flag, boolean flag1) { @@ -1117,7 +1126,7 @@ index 3b8f56c0f0507ebdd9ac20be70688b4c0cfe4cf8..149d2b4f929c11b8baf17163bbd6ff82 List> list = this.a((List) null, this.nextTickList, structureboundingbox, flag); if (flag && list != null) { -@@ -158,6 +178,11 @@ public class TickListServer implements TickList { +@@ -158,6 +182,11 @@ public class TickListServer implements TickList { } public void a(StructureBoundingBox structureboundingbox, BlockPosition blockposition) { @@ -1129,7 +1138,7 @@ index 3b8f56c0f0507ebdd9ac20be70688b4c0cfe4cf8..149d2b4f929c11b8baf17163bbd6ff82 List> list = this.a(structureboundingbox, false, false); Iterator iterator = list.iterator(); -@@ -175,11 +200,17 @@ public class TickListServer implements TickList { +@@ -175,11 +204,17 @@ public class TickListServer implements TickList { } public NBTTagList a(ChunkCoordIntPair chunkcoordintpair) { @@ -1147,7 +1156,7 @@ index 3b8f56c0f0507ebdd9ac20be70688b4c0cfe4cf8..149d2b4f929c11b8baf17163bbd6ff82 private static NBTTagList a(Function function, Iterable> iterable, long i) { NBTTagList nbttaglist = new NBTTagList(); Iterator iterator = iterable.iterator(); -@@ -202,11 +233,21 @@ public class TickListServer implements TickList { +@@ -202,11 +237,21 @@ public class TickListServer implements TickList { @Override public boolean a(BlockPosition blockposition, T t0) { @@ -1169,7 +1178,7 @@ index 3b8f56c0f0507ebdd9ac20be70688b4c0cfe4cf8..149d2b4f929c11b8baf17163bbd6ff82 if (!this.a.test(t0)) { this.a(new NextTickListEntry<>(blockposition, t0, (long) i + this.e.getTime(), ticklistpriority)); } -@@ -222,6 +263,11 @@ public class TickListServer implements TickList { +@@ -222,6 +267,11 @@ public class TickListServer implements TickList { } public int a() { @@ -1182,7 +1191,7 @@ index 3b8f56c0f0507ebdd9ac20be70688b4c0cfe4cf8..149d2b4f929c11b8baf17163bbd6ff82 } } diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index d41981a5dc4beb9d63f52abea5653067144be932..a8a843f76e4161bb1afb7b44a6cce933a8104001 100644 +index d41981a5dc4beb9d63f52abea5653067144be932..eebd453bfaeb99b8fdf0d11ee8888f27ad2afff2 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java @@ -181,6 +181,15 @@ public class WorldServer extends World implements GeneratorAccessSeed { @@ -1229,3 +1238,14 @@ index d41981a5dc4beb9d63f52abea5653067144be932..a8a843f76e4161bb1afb7b44a6cce933 this.navigators = Sets.newHashSet(); this.L = new ObjectLinkedOpenHashSet(); this.Q = flag1; +@@ -526,7 +544,9 @@ public class WorldServer extends World implements GeneratorAccessSeed { + if (this.Q) { + long i = this.worldData.getTime() + 1L; + +- this.worldDataServer.setTime(i); ++ this.worldDataServer.setTime(i); // Paper - diff on change, we want the below to be ran right after this ++ this.nextTickListBlock.nextTick(); // Paper ++ this.nextTickListFluid.nextTick(); // Paper + this.worldDataServer.t().a(this.server, i); + if (this.worldData.p().getBoolean(GameRules.DO_DAYLIGHT_CYCLE)) { + this.setDayTime(this.worldData.getDayTime() + 1L); diff --git a/Spigot-Server-Patches/0429-Ensure-Entity-is-never-double-registered.patch b/Spigot-Server-Patches/0429-Ensure-Entity-is-never-double-registered.patch index 92aa5f5288..0211cd80bc 100644 --- a/Spigot-Server-Patches/0429-Ensure-Entity-is-never-double-registered.patch +++ b/Spigot-Server-Patches/0429-Ensure-Entity-is-never-double-registered.patch @@ -23,7 +23,7 @@ index c49d157b8ca25f9811bf64396c207b1c1d6e085d..e895bf811ce5d441541725ade48e3f07 private boolean locked = false; @Override diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index a8a843f76e4161bb1afb7b44a6cce933a8104001..815a668c60e6302940545259cce60e2dbe608464 100644 +index eebd453bfaeb99b8fdf0d11ee8888f27ad2afff2..0e28e829474bea693550b3b2f0e72f97ff9bb10e 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java @@ -530,6 +530,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { @@ -34,7 +34,7 @@ index a8a843f76e4161bb1afb7b44a6cce933a8104001..815a668c60e6302940545259cce60e2d this.registerEntity(entity2); } -@@ -1226,6 +1227,19 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -1228,6 +1229,19 @@ public class WorldServer extends World implements GeneratorAccessSeed { public void unregisterEntity(Entity entity) { org.spigotmc.AsyncCatcher.catchOp("entity unregister"); // Spigot @@ -54,7 +54,7 @@ index a8a843f76e4161bb1afb7b44a6cce933a8104001..815a668c60e6302940545259cce60e2d // Spigot start if ( entity instanceof EntityHuman ) { -@@ -1292,9 +1306,21 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -1294,9 +1308,21 @@ public class WorldServer extends World implements GeneratorAccessSeed { private void registerEntity(Entity entity) { org.spigotmc.AsyncCatcher.catchOp("entity register"); // Spigot diff --git a/Spigot-Server-Patches/0430-Fix-unregistering-entities-from-unloading-chunks.patch b/Spigot-Server-Patches/0430-Fix-unregistering-entities-from-unloading-chunks.patch index a09637ea01..53a29f344c 100644 --- a/Spigot-Server-Patches/0430-Fix-unregistering-entities-from-unloading-chunks.patch +++ b/Spigot-Server-Patches/0430-Fix-unregistering-entities-from-unloading-chunks.patch @@ -15,10 +15,10 @@ Combine that with a buggy detail of the previous implementation of the Dupe UUID patch, then this was the likely source of the "Ghost entities" diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 815a668c60e6302940545259cce60e2dbe608464..26f82291ded548f7d623668d95d74833d5211709 100644 +index 0e28e829474bea693550b3b2f0e72f97ff9bb10e..0038ba4153ce3bb894968ce848f844800361c44a 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -1385,9 +1385,9 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -1387,9 +1387,9 @@ public class WorldServer extends World implements GeneratorAccessSeed { } private void removeEntityFromChunk(Entity entity) { diff --git a/Spigot-Server-Patches/0433-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch b/Spigot-Server-Patches/0433-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch index 3cac76355f..9d5b458f62 100644 --- a/Spigot-Server-Patches/0433-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch +++ b/Spigot-Server-Patches/0433-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch @@ -26,10 +26,10 @@ index 2542b24b0e1919fdc28417df718acd766deefd03..d4207cb622bf17314f77831c604c8ba9 EntityTypes entitytypes = entity.getEntityType(); int i = entitytypes.getChunkRange() * 16; diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 26f82291ded548f7d623668d95d74833d5211709..3ebb6140b248925c53bc8912d4eeaced00d30fe2 100644 +index 0038ba4153ce3bb894968ce848f844800361c44a..1fabe0a99e796f423adf4a6c51811b462745c537 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -1351,7 +1351,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -1353,7 +1353,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { } } @@ -38,7 +38,7 @@ index 26f82291ded548f7d623668d95d74833d5211709..3ebb6140b248925c53bc8912d4eeaced // CraftBukkit start - SPIGOT-5278 if (entity instanceof EntityDrowned) { this.navigators.add(((EntityDrowned) entity).navigationWater); -@@ -1362,6 +1362,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -1364,6 +1364,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { this.navigators.add(((EntityInsentient) entity).getNavigation()); } entity.valid = true; // CraftBukkit diff --git a/Spigot-Server-Patches/0505-Optimize-Light-Engine.patch b/Spigot-Server-Patches/0505-Optimize-Light-Engine.patch index 83d0842530..5ecf8c4b4b 100644 --- a/Spigot-Server-Patches/0505-Optimize-Light-Engine.patch +++ b/Spigot-Server-Patches/0505-Optimize-Light-Engine.patch @@ -1340,10 +1340,10 @@ index 35f4d2d9591e625ab0bbeab7b606761e74965eec..698d82dd736529a8cbfad5c6bed70ab9 this.a.a(t0); this.f(); diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 2b04577c153fc4563e59b67afee12411a5de5314..d048ee2313142ba4b0fae7ef2badb9f80614bb62 100644 +index a54e3ed06a7a1757d3c4ce96b21bed0177e1fa86..63c119072968586fab05ce3990f7c83373736f33 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -707,6 +707,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -709,6 +709,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { } gameprofilerfiller.exit(); timings.chunkTicksBlocks.stopTiming(); // Paper