From 0d5ec65372cd40b6df39771ecbe6e5843789b3b0 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Thu, 28 May 2020 16:34:58 -0700 Subject: [PATCH] Cleanup async chunks (#3456) Co-authored-by: Spottedleaf --- ...90-Asynchronous-chunk-IO-and-loading.patch | 159 +++--------------- .../0426-Tracking-Range-Improvements.patch | 4 +- ...-PlayerChunkMap-adds-crashing-server.patch | 4 +- ...hunkMap-memory-use-for-visibleChunks.patch | 4 +- .../0467-Improved-Watchdog-Support.patch | 11 +- ...g-Broken-behavior-of-PlayerJoinEvent.patch | 4 +- ...tance-map-to-optimise-entity-tracker.patch | 16 +- ...-isOutsideRange-to-use-distance-maps.patch | 4 +- ...No-Tick-view-distance-implementation.patch | 22 +-- ...llocation-of-Vec3D-by-entity-tracker.patch | 4 +- ...ound-for-Client-Lag-Spikes-MC-162253.patch | 4 +- 11 files changed, 61 insertions(+), 175 deletions(-) diff --git a/Spigot-Server-Patches/0390-Asynchronous-chunk-IO-and-loading.patch b/Spigot-Server-Patches/0390-Asynchronous-chunk-IO-and-loading.patch index f4ac9b7441..7ecad1f0ff 100644 --- a/Spigot-Server-Patches/0390-Asynchronous-chunk-IO-and-loading.patch +++ b/Spigot-Server-Patches/0390-Asynchronous-chunk-IO-and-loading.patch @@ -334,10 +334,10 @@ index 0000000000000000000000000000000000000000..5af0ac3d9e87c06053e65433060f1577 +} diff --git a/src/main/java/com/destroystokyo/paper/io/PaperFileIOThread.java b/src/main/java/com/destroystokyo/paper/io/PaperFileIOThread.java new file mode 100644 -index 0000000000000000000000000000000000000000..4f10a8311ea931026079c85bb59e223b0122a4a9 +index 0000000000000000000000000000000000000000..a6434b4e28a73ecab4350862c5747b7494761ba0 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/PaperFileIOThread.java -@@ -0,0 +1,661 @@ +@@ -0,0 +1,607 @@ +package com.destroystokyo.paper.io; + +import net.minecraft.server.ChunkCoordIntPair; @@ -447,48 +447,6 @@ index 0000000000000000000000000000000000000000..4f10a8311ea931026079c85bb59e223b + } + } + -+ // Hack start -+ /** -+ * if {@code waitForRead} is true, then this task will wait on an available read task, else it will wait on an available -+ * write task -+ * if {@code poiTask} is true, then this task will wait on a poi task, else it will wait on chunk data task -+ * @deprecated API is garbage and will only work for main thread queueing of tasks (which is vanilla), plugins messing -+ * around asynchronously will give unexpected results -+ * @return whether the task succeeded, or {@code null} if there is no task -+ */ -+ @Deprecated -+ public Boolean waitForIOToComplete(final WorldServer world, final int chunkX, final int chunkZ, final boolean waitForRead, -+ final boolean poiTask) { -+ final ChunkDataTask task; -+ -+ final Long key = IOUtil.getCoordinateKey(chunkX, chunkZ); -+ if (poiTask) { -+ task = world.poiDataController.tasks.get(key); -+ } else { -+ task = world.chunkDataController.tasks.get(key); -+ } -+ -+ if (task == null) { -+ return null; -+ } -+ -+ if (waitForRead) { -+ ChunkDataController.InProgressRead read = task.inProgressRead; -+ if (read == null) { -+ return null; -+ } -+ return Boolean.valueOf(read.readFuture.join() != PaperFileIOThread.FAILURE_VALUE); -+ } -+ -+ // wait for write -+ ChunkDataController.InProgressWrite write = task.inProgressWrite; -+ if (write == null) { -+ return null; -+ } -+ return Boolean.valueOf(write.wrote.join() != PaperFileIOThread.FAILURE_VALUE); -+ } -+ // Hack end -+ + public NBTTagCompound getPendingWrite(final WorldServer world, final int chunkX, final int chunkZ, final boolean poiData) { + final ChunkDataController taskController = poiData ? world.poiDataController : world.chunkDataController; + @@ -826,11 +784,6 @@ index 0000000000000000000000000000000000000000..4f10a8311ea931026079c85bb59e223b + public static final class InProgressWrite { + public long writeCounter; + public NBTTagCompound data; -+ -+ // Hack start -+ @Deprecated -+ public CompletableFuture wrote = new CompletableFuture<>(); -+ // Hack end + } + + public static final class InProgressRead { @@ -883,7 +836,6 @@ index 0000000000000000000000000000000000000000..4f10a8311ea931026079c85bb59e223b + void reschedule(final int priority) { + // priority is checked before this stage // TODO what + this.queue.lazySet(null); -+ this.inProgressWrite.wrote = new CompletableFuture<>(); // Hack + this.priority.lazySet(priority); + PaperFileIOThread.Holder.INSTANCE.queueTask(this); + } @@ -936,7 +888,6 @@ index 0000000000000000000000000000000000000000..4f10a8311ea931026079c85bb59e223b + LOGGER.fatal("Couldn't save chunk; already in use by another instance of Minecraft?", ex); + // we don't need to set the write counter to -1 as we know at this stage there's no point in re-scheduling + // writes since they'll fail anyways. -+ write.wrote.complete(PaperFileIOThread.FAILURE_VALUE); // Hack - However we need to fail the write + return; + } + @@ -966,19 +917,14 @@ index 0000000000000000000000000000000000000000..4f10a8311ea931026079c85bb59e223b + + ChunkDataTask inMap = this.taskController.tasks.compute(chunkKey, (final Long keyInMap, final ChunkDataTask valueInMap) -> { + if (valueInMap == null) { -+ ChunkDataTask.this.inProgressWrite.wrote.complete(PaperFileIOThread.FAILURE_VALUE); // Hack + throw new IllegalStateException("Write completed concurrently, expected this task: " + ChunkDataTask.this.toString() + ", report this!"); + } + if (valueInMap != ChunkDataTask.this) { -+ ChunkDataTask.this.inProgressWrite.wrote.complete(PaperFileIOThread.FAILURE_VALUE); // Hack + throw new IllegalStateException("Chunk task mismatch, expected this task: " + ChunkDataTask.this.toString() + ", got: " + valueInMap.toString() + ", report this!"); + } + if (valueInMap.inProgressWrite.writeCounter == writeCounter) { + if (finalFailWrite) { + valueInMap.inProgressWrite.writeCounter = -1L; -+ valueInMap.inProgressWrite.wrote.complete(PaperFileIOThread.FAILURE_VALUE); -+ } else { -+ valueInMap.inProgressWrite.wrote.complete(data); + } + + return null; @@ -3107,7 +3053,7 @@ index 52ea4f05a0c7f29f62f31bb032a5ceb905107e60..0f1576effe10795bcb8ed3b519f4dbaf completablefuture = (CompletableFuture) this.statusFutures.get(i); if (completablefuture != null) { diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..71ab7537313bbaf29f13ba3fae45bfb8a501429a 100644 +index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..6552bbf06637b08626cbf0fb352123c3e381cb5a 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -63,7 +63,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { @@ -3308,21 +3254,21 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..71ab7537313bbaf29f13ba3fae45bfb8 - - if (nbttagcompound != null) {try (Timing ignored2 = this.world.timings.chunkLoadLevelTimer.startTimingIfSync()) { // Paper start - timings - boolean flag = nbttagcompound.hasKeyOfType("Level", 10) && nbttagcompound.getCompound("Level").hasKeyOfType("Status", 8); -- -- if (flag) { -- ProtoChunk protochunk = ChunkRegionLoader.loadChunk(this.world, this.definedStructureManager, this.m, chunkcoordintpair, nbttagcompound); + if (ioThrowable != null) { + com.destroystokyo.paper.io.IOUtil.rethrow(ioThrowable); + } -- protochunk.setLastSaved(this.world.getTime()); -- return Either.left(protochunk); -- } +- if (flag) { +- ProtoChunk protochunk = ChunkRegionLoader.loadChunk(this.world, this.definedStructureManager, this.m, chunkcoordintpair, nbttagcompound); + this.getVillagePlace().loadInData(chunkcoordintpair, chunkHolder.poiData); + chunkHolder.tasks.forEach(Runnable::run); + // Paper - async load completes this + // Paper end +- protochunk.setLastSaved(this.world.getTime()); +- return Either.left(protochunk); +- } +- - PlayerChunkMap.LOGGER.error("Chunk file at {} is missing level data, skipping", chunkcoordintpair); - }} // Paper + // Paper start - This is done async @@ -3368,44 +3314,12 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..71ab7537313bbaf29f13ba3fae45bfb8 } private CompletableFuture> b(PlayerChunk playerchunk, ChunkStatus chunkstatus) { -@@ -823,18 +921,43 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - return this.u.get(); +@@ -824,17 +922,12 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } -+ // Paper start - async chunk io -+ private boolean writeDataAsync(ChunkCoordIntPair chunkPos, NBTTagCompound poiData, NBTTagCompound chunkData, boolean async) { -+ com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.scheduleSave(this.world, chunkPos.x, chunkPos.z, -+ poiData, chunkData, !async ? com.destroystokyo.paper.io.PrioritizedTaskQueue.HIGHEST_PRIORITY : com.destroystokyo.paper.io.PrioritizedTaskQueue.LOW_PRIORITY); -+ -+ if (async) { -+ return true; -+ } -+ -+ try (co.aikar.timings.Timing ignored = this.world.timings.chunkSaveIOWait.startTiming()) { // Paper -+ Boolean successPoi = com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.waitForIOToComplete(this.world, chunkPos.x, chunkPos.z, true, true); -+ Boolean successChunk = com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.waitForIOToComplete(this.world, chunkPos.x, chunkPos.z, true, false); -+ -+ if (successPoi == Boolean.FALSE || successChunk == Boolean.FALSE) { -+ return false; -+ } -+ -+ // null indicates no task existed, which means our write completed before we waited on it -+ -+ return true; -+ } // Paper -+ } -+ // Paper end -+ public boolean saveChunk(IChunkAccess ichunkaccess) { -- this.m.a(ichunkaccess.getPos()); -+ // Paper start - async param -+ return this.saveChunk(ichunkaccess, true); -+ } -+ public boolean saveChunk(IChunkAccess ichunkaccess, boolean async) { -+ try (co.aikar.timings.Timing ignored = this.world.timings.chunkSave.startTiming()) { -+ NBTTagCompound poiData = this.getVillagePlace().getData(ichunkaccess.getPos()); // Paper -+ //this.m.a(ichunkaccess.getPos()); // Delay -+ // Paper end ++ try (co.aikar.timings.Timing ignored = this.world.timings.chunkSave.startTiming()) { // Paper + this.m.a(ichunkaccess.getPos()); if (!ichunkaccess.isNeedsSaving()) { return false; } else { @@ -3420,7 +3334,7 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..71ab7537313bbaf29f13ba3fae45bfb8 ichunkaccess.setLastSaved(this.world.getTime()); ichunkaccess.setNeedsSaving(false); -@@ -845,28 +968,35 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -845,6 +938,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { NBTTagCompound nbttagcompound; if (chunkstatus.getType() != ChunkStatus.Type.LEVELCHUNK) { @@ -3428,29 +3342,24 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..71ab7537313bbaf29f13ba3fae45bfb8 // Paper start - Optimize save by using status cache ChunkStatus statusOnDisk = this.getChunkStatusOnDisk(chunkcoordintpair); if (statusOnDisk != null && statusOnDisk.getType() == ChunkStatus.Type.LEVELCHUNK) { - // Paper end -+ this.writeDataAsync(ichunkaccess.getPos(), poiData, null, async); // Paper - Async chunk io - return false; - } - - if (chunkstatus == ChunkStatus.EMPTY && ichunkaccess.h().values().stream().noneMatch(StructureStart::e)) { -+ this.writeDataAsync(ichunkaccess.getPos(), poiData, null, async); // Paper - Async chunk io - return false; +@@ -857,9 +951,15 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } } - this.world.getMethodProfiler().c("chunkSave"); + } // Paper + this.world.getMethodProfiler().c("chunkSave"); + try (co.aikar.timings.Timing ignored1 = this.world.timings.chunkSaveDataSerialization.startTiming()) { // Paper nbttagcompound = ChunkRegionLoader.saveChunk(this.world, ichunkaccess); - this.a(chunkcoordintpair, nbttagcompound); -- return true; + } // Paper -+ return this.writeDataAsync(ichunkaccess.getPos(), poiData, nbttagcompound, async); // Paper - Async chunk io -+ //return true; // Paper ++ // Paper start - async chunk io ++ com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.scheduleSave(this.world, chunkcoordintpair.x, chunkcoordintpair.z, ++ null, nbttagcompound, com.destroystokyo.paper.io.PrioritizedTaskQueue.NORMAL_PRIORITY); ++ // Paper end - async chunk io + return true; } catch (Exception exception) { PlayerChunkMap.LOGGER.error("Failed to save chunk {},{}", chunkcoordintpair.x, chunkcoordintpair.z, exception); - com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(exception); // Paper +@@ -867,6 +967,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { return false; } } @@ -3458,7 +3367,7 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..71ab7537313bbaf29f13ba3fae45bfb8 } protected void setViewDistance(int i) { -@@ -970,6 +1100,42 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -970,6 +1071,35 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } } @@ -3485,13 +3394,6 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..71ab7537313bbaf29f13ba3fae45bfb8 + com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.scheduleSave( + this.world, chunkcoordintpair.x, chunkcoordintpair.z, null, nbttagcompound, + com.destroystokyo.paper.io.IOUtil.getPriorityForCurrentThread()); -+ -+ Boolean ret = com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.waitForIOToComplete(this.world, -+ chunkcoordintpair.x, chunkcoordintpair.z, true, false); -+ -+ if (ret == Boolean.FALSE) { -+ throw new IOException("See logs for further detail"); -+ } + return; + } + super.write(chunkcoordintpair, nbttagcompound); @@ -3501,7 +3403,7 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..71ab7537313bbaf29f13ba3fae45bfb8 @Nullable public NBTTagCompound readChunkData(ChunkCoordIntPair chunkcoordintpair) throws IOException { // Paper - private -> public NBTTagCompound nbttagcompound = this.read(chunkcoordintpair); -@@ -992,33 +1158,55 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -992,33 +1122,55 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { // Paper start - chunk status cache "api" public ChunkStatus getChunkStatusOnDiskIfCached(ChunkCoordIntPair chunkPos) { @@ -3568,7 +3470,7 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..71ab7537313bbaf29f13ba3fae45bfb8 } public IChunkAccess getUnloadingChunk(int chunkX, int chunkZ) { -@@ -1027,6 +1215,39 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1027,6 +1179,39 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } // Paper end @@ -3608,7 +3510,7 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..71ab7537313bbaf29f13ba3fae45bfb8 boolean isOutsideOfRange(ChunkCoordIntPair chunkcoordintpair) { // Spigot start return isOutsideOfRange(chunkcoordintpair, false); -@@ -1374,6 +1595,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1374,6 +1559,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } @@ -3954,7 +3856,7 @@ index 75ab9f185b3231113dfa387c956a707b403bb2db..8055f5998213ab1c6c10d03d88d2b14d public static TicketType a(String s, Comparator comparator) { return new TicketType<>(s, comparator, 0L); diff --git a/src/main/java/net/minecraft/server/VillagePlace.java b/src/main/java/net/minecraft/server/VillagePlace.java -index c999f8c9bf8a59e19b3d6d1b7ad8b5fb6e48b928..b59ef1a63338aa150d39e8014e12b2275da26d50 100644 +index c999f8c9bf8a59e19b3d6d1b7ad8b5fb6e48b928..1a5ec6152c15a6ece227d4bac00c3b02bd9c5c95 100644 --- a/src/main/java/net/minecraft/server/VillagePlace.java +++ b/src/main/java/net/minecraft/server/VillagePlace.java @@ -24,8 +24,16 @@ public class VillagePlace extends RegionFileSection { @@ -3999,7 +3901,7 @@ index c999f8c9bf8a59e19b3d6d1b7ad8b5fb6e48b928..b59ef1a63338aa150d39e8014e12b227 this.a.a(); } -@@ -229,6 +253,42 @@ public class VillagePlace extends RegionFileSection { +@@ -229,6 +253,35 @@ public class VillagePlace extends RegionFileSection { } } @@ -4026,13 +3928,6 @@ index c999f8c9bf8a59e19b3d6d1b7ad8b5fb6e48b928..b59ef1a63338aa150d39e8014e12b227 + com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.scheduleSave( + this.world, chunkcoordintpair.x, chunkcoordintpair.z, nbttagcompound, null, + com.destroystokyo.paper.io.IOUtil.getPriorityForCurrentThread()); -+ -+ Boolean ret = com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.waitForIOToComplete(this.world, -+ chunkcoordintpair.x, chunkcoordintpair.z, true, true); -+ -+ if (ret == Boolean.FALSE) { -+ throw new java.io.IOException("See logs for further detail"); -+ } + return; + } + super.write(chunkcoordintpair, nbttagcompound); diff --git a/Spigot-Server-Patches/0426-Tracking-Range-Improvements.patch b/Spigot-Server-Patches/0426-Tracking-Range-Improvements.patch index 1aedc62ffd..64610ac9d0 100644 --- a/Spigot-Server-Patches/0426-Tracking-Range-Improvements.patch +++ b/Spigot-Server-Patches/0426-Tracking-Range-Improvements.patch @@ -8,10 +8,10 @@ Sets tracking range of watermobs to animals instead of misc and simplifies code Also ignores Enderdragon, defaulting it to Mojang's setting diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 7984dedfde6ba41db873f2de99ba01b6622ea6c7..b1f1372a76167a29f63917cedd1d6bfc99a97eba 100644 +index c20acd86beb8f28345d1359d0a2b68b7d8e0e410..4ba661c5a89bebe29c8802387bc93c10094b7606 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java -@@ -1738,6 +1738,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1702,6 +1702,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { while (iterator.hasNext()) { Entity entity = (Entity) iterator.next(); int j = entity.getEntityType().getChunkRange() * 16; diff --git a/Spigot-Server-Patches/0452-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch b/Spigot-Server-Patches/0452-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch index 3545dcd716..e75822ae24 100644 --- a/Spigot-Server-Patches/0452-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch +++ b/Spigot-Server-Patches/0452-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch @@ -7,10 +7,10 @@ Suspected case would be around the technique used in .stopRiding Stack will identify any causer of this and warn instead of crashing. diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index b1f1372a76167a29f63917cedd1d6bfc99a97eba..c900bfb9edf957ebdbd83cc44280440648288250 100644 +index 4ba661c5a89bebe29c8802387bc93c10094b7606..6a2cf0c6f649e7a74b58fc292f57a08c0663b0a4 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java -@@ -1447,6 +1447,14 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1411,6 +1411,14 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { protected void addEntity(Entity entity) { org.spigotmc.AsyncCatcher.catchOp("entity track"); // Spigot diff --git a/Spigot-Server-Patches/0456-Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch b/Spigot-Server-Patches/0456-Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch index fa9468009e..246d9a783c 100644 --- a/Spigot-Server-Patches/0456-Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch +++ b/Spigot-Server-Patches/0456-Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch @@ -83,7 +83,7 @@ index 9f8c0e10e42d233a8b74ee5a71fb8fb6ea8e7480..0d1065688b19ceca9440bc8bf2bf6591 List allChunks = new ArrayList<>(visibleChunks.values()); List players = world.players; diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index c900bfb9edf957ebdbd83cc44280440648288250..8cd77117cdb81e3fbd196415f8ac82d3aeddcb12 100644 +index 6a2cf0c6f649e7a74b58fc292f57a08c0663b0a4..ea6b310e8e4741c8bb301e5bc586faca8bea5e06 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -55,8 +55,33 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { @@ -227,7 +227,7 @@ index c900bfb9edf957ebdbd83cc44280440648288250..8cd77117cdb81e3fbd196415f8ac82d3 this.updatingChunksModified = false; return true; } -@@ -1077,12 +1159,12 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1048,12 +1130,12 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } protected Iterable f() { diff --git a/Spigot-Server-Patches/0467-Improved-Watchdog-Support.patch b/Spigot-Server-Patches/0467-Improved-Watchdog-Support.patch index 9dadee5b8d..6d6a1c49d3 100644 --- a/Spigot-Server-Patches/0467-Improved-Watchdog-Support.patch +++ b/Spigot-Server-Patches/0467-Improved-Watchdog-Support.patch @@ -225,7 +225,7 @@ index b701db638370c0d07d5be0f61c6cbf19168cde8e..4ea3468614df36e1c148a44bb15d2201 } diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 8cd77117cdb81e3fbd196415f8ac82d3aeddcb12..00ad80bb74bd581e3fa1bf82356ee5b7bc656bfe 100644 +index ea6b310e8e4741c8bb301e5bc586faca8bea5e06..6bdaaf8daef15cd7c11943254e412e0e2d2898fb 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -485,6 +485,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { @@ -236,15 +236,6 @@ index 8cd77117cdb81e3fbd196415f8ac82d3aeddcb12..00ad80bb74bd581e3fa1bf82356ee5b7 mutableboolean.setFalse(); list.stream().map((playerchunk) -> { CompletableFuture completablefuture; -@@ -497,7 +498,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - return (IChunkAccess) completablefuture.join(); - }).filter((ichunkaccess) -> { - return ichunkaccess instanceof ProtoChunkExtension || ichunkaccess instanceof Chunk; -- }).filter(this::saveChunk).forEach((ichunkaccess) -> { -+ }).filter(ichunkaccess1 -> saveChunk(ichunkaccess1, !isShuttingDown)).forEach((ichunkaccess) -> { // Paper - dont save async during shutdown - mutableboolean.setTrue(); - }); - } while (mutableboolean.isTrue()); diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java index ab2831830ad3a4cec0671d189e0534c843b47f5e..78040e83899f1ef1a6d5c456beb9d13959307c18 100644 --- a/src/main/java/net/minecraft/server/PlayerList.java diff --git a/Spigot-Server-Patches/0484-Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch b/Spigot-Server-Patches/0484-Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch index 0bba69bd8a..5d3432d74c 100644 --- a/Spigot-Server-Patches/0484-Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch +++ b/Spigot-Server-Patches/0484-Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch @@ -40,10 +40,10 @@ index 64e00275edf38739fe6e2d79dbcb93243e765678..a87aa07b17205b52e85f7d082fa4d516 // CraftBukkit end public PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 9e2998f2214d6129e38acc0cbb59ce19f4c38759..50375629186e5cbe9fd6a36cae348f018cdac9d5 100644 +index 48f858388029e77f710365e73905f8570f1103f5..2caa53a7e143aae32918ecbefc1bdadcab8d61ed 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java -@@ -1539,6 +1539,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1503,6 +1503,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { .printStackTrace(); return; } diff --git a/Spigot-Server-Patches/0502-Use-distance-map-to-optimise-entity-tracker.patch b/Spigot-Server-Patches/0502-Use-distance-map-to-optimise-entity-tracker.patch index f73e48ac1e..c349243a11 100644 --- a/Spigot-Server-Patches/0502-Use-distance-map-to-optimise-entity-tracker.patch +++ b/Spigot-Server-Patches/0502-Use-distance-map-to-optimise-entity-tracker.patch @@ -44,7 +44,7 @@ index 3a88c9a67062eb73ad8257ea786efca7e7e99f65..6d3b34ead9cc95dcc1152dffa8c6c4a8 List list = this.tracker.getPassengers(); diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index a28158d7abb9465f4bd8e6f5c1a789d0a4dad125..7e0e9b74327a76c79658e0bcc61fac721a684ab5 100644 +index 3f1a5e48676d1b4b01fbbc25fc9c9cf556cbf0eb..f09bb1329cf993034661fb8cfbf87571fe5f1ebe 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -143,21 +143,51 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { @@ -145,7 +145,7 @@ index a28158d7abb9465f4bd8e6f5c1a789d0a4dad125..7e0e9b74327a76c79658e0bcc61fac72 } public void updatePlayerMobTypeMap(Entity entity) { -@@ -1436,17 +1504,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1400,17 +1468,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } public void movePlayer(EntityPlayer entityplayer) { @@ -164,7 +164,7 @@ index a28158d7abb9465f4bd8e6f5c1a789d0a4dad125..7e0e9b74327a76c79658e0bcc61fac72 int i = MathHelper.floor(entityplayer.locX()) >> 4; int j = MathHelper.floor(entityplayer.locZ()) >> 4; -@@ -1563,7 +1621,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1527,7 +1585,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker this.trackedEntities.put(entity.getId(), playerchunkmap_entitytracker); @@ -173,7 +173,7 @@ index a28158d7abb9465f4bd8e6f5c1a789d0a4dad125..7e0e9b74327a76c79658e0bcc61fac72 if (entity instanceof EntityPlayer) { EntityPlayer entityplayer = (EntityPlayer) entity; -@@ -1607,7 +1665,37 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1571,7 +1629,37 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { entity.tracker = null; // Paper - We're no longer tracked } @@ -211,7 +211,7 @@ index a28158d7abb9465f4bd8e6f5c1a789d0a4dad125..7e0e9b74327a76c79658e0bcc61fac72 List list = Lists.newArrayList(); List list1 = this.world.getPlayers(); -@@ -1675,23 +1763,31 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1639,23 +1727,31 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { PacketDebug.a(this.world, chunk.getPos()); List list = Lists.newArrayList(); List list1 = Lists.newArrayList(); @@ -255,7 +255,7 @@ index a28158d7abb9465f4bd8e6f5c1a789d0a4dad125..7e0e9b74327a76c79658e0bcc61fac72 Iterator iterator; Entity entity1; -@@ -1729,7 +1825,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1693,7 +1789,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { public class EntityTracker { @@ -264,7 +264,7 @@ index a28158d7abb9465f4bd8e6f5c1a789d0a4dad125..7e0e9b74327a76c79658e0bcc61fac72 private final Entity tracker; private final int trackingDistance; private SectionPosition e; -@@ -1746,6 +1842,42 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1710,6 +1806,42 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { this.e = SectionPosition.a(entity); } @@ -307,7 +307,7 @@ index a28158d7abb9465f4bd8e6f5c1a789d0a4dad125..7e0e9b74327a76c79658e0bcc61fac72 public boolean equals(Object object) { return object instanceof PlayerChunkMap.EntityTracker ? ((PlayerChunkMap.EntityTracker) object).tracker.getId() == this.tracker.getId() : false; } -@@ -1842,7 +1974,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1806,7 +1938,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { int j = entity.getEntityType().getChunkRange() * 16; j = org.spigotmc.TrackingRange.getEntityTrackingRange(entity, j); // Paper diff --git a/Spigot-Server-Patches/0503-Optimize-isOutsideRange-to-use-distance-maps.patch b/Spigot-Server-Patches/0503-Optimize-isOutsideRange-to-use-distance-maps.patch index 9a3bcd082a..6c8f9282ab 100644 --- a/Spigot-Server-Patches/0503-Optimize-isOutsideRange-to-use-distance-maps.patch +++ b/Spigot-Server-Patches/0503-Optimize-isOutsideRange-to-use-distance-maps.patch @@ -192,7 +192,7 @@ index afc92dd031cdaf725b85c0b301d5a5a21da54720..6980d19f36c18cdbed6679dbdf04afd6 // Paper start diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 7e0e9b74327a76c79658e0bcc61fac721a684ab5..7380270ae89f3fe134ec76a265f8074b6406f558 100644 +index f09bb1329cf993034661fb8cfbf87571fe5f1ebe..74b868d7cec0260a10ca7718f48308f4ec54d56b 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -153,6 +153,17 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { @@ -308,7 +308,7 @@ index 7e0e9b74327a76c79658e0bcc61fac721a684ab5..7380270ae89f3fe134ec76a265f8074b } if (playerchunk != null) { -@@ -1433,30 +1488,53 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1397,30 +1452,53 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { return isOutsideOfRange(chunkcoordintpair, false); } diff --git a/Spigot-Server-Patches/0505-No-Tick-view-distance-implementation.patch b/Spigot-Server-Patches/0505-No-Tick-view-distance-implementation.patch index c1ad1c8a6d..73aeb9d39e 100644 --- a/Spigot-Server-Patches/0505-No-Tick-view-distance-implementation.patch +++ b/Spigot-Server-Patches/0505-No-Tick-view-distance-implementation.patch @@ -207,7 +207,7 @@ index 6980d19f36c18cdbed6679dbdf04afd694e078b6..03fb688fe4bdc19b4bc36b1f1d5b40c6 public CompletableFuture> a(ChunkStatus chunkstatus, PlayerChunkMap playerchunkmap) { diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 7380270ae89f3fe134ec76a265f8074b6406f558..e90c5e1048b0564cd0d703d550a3ae414275164a 100644 +index 74b868d7cec0260a10ca7718f48308f4ec54d56b..f832e7cdfc6741a932787f02754f145202ff7887 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -94,7 +94,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { @@ -358,7 +358,7 @@ index 7380270ae89f3fe134ec76a265f8074b6406f558..e90c5e1048b0564cd0d703d550a3ae41 }); return completablefuture1; } -@@ -1234,32 +1316,38 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1205,32 +1287,38 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } // Paper } @@ -412,7 +412,7 @@ index 7380270ae89f3fe134ec76a265f8074b6406f558..e90c5e1048b0564cd0d703d550a3ae41 protected void sendChunk(EntityPlayer entityplayer, ChunkCoordIntPair chunkcoordintpair, Packet[] apacket, boolean flag, boolean flag1) { if (entityplayer.world == this.world) { -@@ -1267,7 +1355,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1238,7 +1326,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { PlayerChunk playerchunk = this.getVisibleChunk(chunkcoordintpair.pair()); if (playerchunk != null) { @@ -421,7 +421,7 @@ index 7380270ae89f3fe134ec76a265f8074b6406f558..e90c5e1048b0564cd0d703d550a3ae41 if (chunk != null) { this.a(entityplayer, apacket, chunk); -@@ -1536,6 +1624,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1500,6 +1588,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } // Paper end - optimise isOutsideOfRange @@ -429,7 +429,7 @@ index 7380270ae89f3fe134ec76a265f8074b6406f558..e90c5e1048b0564cd0d703d550a3ae41 private boolean b(EntityPlayer entityplayer) { return entityplayer.isSpectator() && !this.world.getGameRules().getBoolean(GameRules.SPECTATORS_GENERATE_CHUNKS); } -@@ -1563,13 +1652,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1527,13 +1616,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { this.removePlayerFromDistanceMaps(entityplayer); // Paper - distance maps } @@ -444,7 +444,7 @@ index 7380270ae89f3fe134ec76a265f8074b6406f558..e90c5e1048b0564cd0d703d550a3ae41 } -@@ -1577,7 +1660,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1541,7 +1624,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { SectionPosition sectionposition = SectionPosition.a((Entity) entityplayer); entityplayer.a(sectionposition); @@ -453,7 +453,7 @@ index 7380270ae89f3fe134ec76a265f8074b6406f558..e90c5e1048b0564cd0d703d550a3ae41 return sectionposition; } -@@ -1622,6 +1705,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1586,6 +1669,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { int k1; int l1; @@ -461,7 +461,7 @@ index 7380270ae89f3fe134ec76a265f8074b6406f558..e90c5e1048b0564cd0d703d550a3ae41 if (Math.abs(i1 - i) <= this.viewDistance * 2 && Math.abs(j1 - j) <= this.viewDistance * 2) { k1 = Math.min(i, i1) - this.viewDistance; l1 = Math.min(j, j1) - this.viewDistance; -@@ -1659,7 +1743,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1623,7 +1707,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { this.sendChunk(entityplayer, chunkcoordintpair1, new Packet[2], false, true); } } @@ -470,7 +470,7 @@ index 7380270ae89f3fe134ec76a265f8074b6406f558..e90c5e1048b0564cd0d703d550a3ae41 this.updateMaps(entityplayer); // Paper - distance maps -@@ -1667,11 +1751,46 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1631,11 +1715,46 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { @Override public Stream a(ChunkCoordIntPair chunkcoordintpair, boolean flag) { @@ -521,7 +521,7 @@ index 7380270ae89f3fe134ec76a265f8074b6406f558..e90c5e1048b0564cd0d703d550a3ae41 } protected void addEntity(Entity entity) { -@@ -1831,6 +1950,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1795,6 +1914,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } @@ -529,7 +529,7 @@ index 7380270ae89f3fe134ec76a265f8074b6406f558..e90c5e1048b0564cd0d703d550a3ae41 private void a(EntityPlayer entityplayer, Packet[] apacket, Chunk chunk) { if (apacket[0] == null) { apacket[0] = new PacketPlayOutMapChunk(chunk, 65535); -@@ -2016,7 +2136,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1980,7 +2100,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(this.tracker.chunkX, this.tracker.chunkZ); PlayerChunk playerchunk = PlayerChunkMap.this.getVisibleChunk(chunkcoordintpair.pair()); diff --git a/Spigot-Server-Patches/0524-Reduce-allocation-of-Vec3D-by-entity-tracker.patch b/Spigot-Server-Patches/0524-Reduce-allocation-of-Vec3D-by-entity-tracker.patch index 4dc08c86ae..45ed81a066 100644 --- a/Spigot-Server-Patches/0524-Reduce-allocation-of-Vec3D-by-entity-tracker.patch +++ b/Spigot-Server-Patches/0524-Reduce-allocation-of-Vec3D-by-entity-tracker.patch @@ -39,10 +39,10 @@ index 6d3b34ead9cc95dcc1152dffa8c6c4a8c7f1d58b..5cc89c0cf9e9e632212a9653391437cb if (!flag4 && this.o <= 400 && !this.q && this.r == this.tracker.onGround) { diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 1c3526dda5c20264e21d079fd1aff1a735a9e496..2dd7999b6a540efd1e2e974f33ed87a6d0a8e8f1 100644 +index f361939b9ae451bdccf7922e9cca09344c6152b5..68dd9220bb360c75057919fed0598b415b947e4d 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java -@@ -2132,9 +2132,14 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -2096,9 +2096,14 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { public void updatePlayer(EntityPlayer entityplayer) { org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot if (entityplayer != this.tracker) { diff --git a/Spigot-Server-Patches/0528-Workaround-for-Client-Lag-Spikes-MC-162253.patch b/Spigot-Server-Patches/0528-Workaround-for-Client-Lag-Spikes-MC-162253.patch index 253e7bbbd0..380f142f14 100644 --- a/Spigot-Server-Patches/0528-Workaround-for-Client-Lag-Spikes-MC-162253.patch +++ b/Spigot-Server-Patches/0528-Workaround-for-Client-Lag-Spikes-MC-162253.patch @@ -37,7 +37,7 @@ index b7b06e082e59f8518be2036637385c7710d524ea..71da9f00b8a969e84414066fb1852cec return chunksection == Chunk.a || chunksection.c(); } diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 2dd7999b6a540efd1e2e974f33ed87a6d0a8e8f1..4a9d6f0c193c6d8a65d548ac1dd1461e7056f0a4 100644 +index 68dd9220bb360c75057919fed0598b415b947e4d..0aa14bfca6e1845eb6e9f5bd4e0e36335fa7f532 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -402,7 +402,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { @@ -49,7 +49,7 @@ index 2dd7999b6a540efd1e2e974f33ed87a6d0a8e8f1..4a9d6f0c193c6d8a65d548ac1dd1461e }, (EntityPlayer player, int rangeX, int rangeZ, int currPosX, int currPosZ, int prevPosX, int prevPosZ, com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet newState) -> { -@@ -1957,12 +1957,112 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1921,12 +1921,112 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { }