From f7da209586b12d169719e38b3dfa2664b6474a67 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Tue, 18 Oct 2022 08:11:23 -0700 Subject: [PATCH] Fix inconsistent isChunkLoaded calls When we update the chunk state to border, it should be the case that isChunkLoaded returns true and that getChunkIfLoadedImmediately returns a non-null value. Now add the chunk to the loaded map before making any callbacks after updating to border state. --- .../server/0016-Rewrite-chunk-system.patch | 48 ++++++++++++------- ...event-tile-entity-and-entity-crashes.patch | 4 +- .../0059-Add-exception-reporting-event.patch | 4 +- .../0378-Improved-Watchdog-Support.patch | 4 +- 4 files changed, 37 insertions(+), 23 deletions(-) diff --git a/patches/server/0016-Rewrite-chunk-system.patch b/patches/server/0016-Rewrite-chunk-system.patch index 08dbd33a4..1df2fdeeb 100644 --- a/patches/server/0016-Rewrite-chunk-system.patch +++ b/patches/server/0016-Rewrite-chunk-system.patch @@ -9000,10 +9000,10 @@ index 0000000000000000000000000000000000000000..396d72c00e47cf1669ae20dc839c1c96 +} diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java new file mode 100644 -index 0000000000000000000000000000000000000000..dd9c1d68a2bc42467b4566953aaed028bddf0f74 +index 0000000000000000000000000000000000000000..f20faaec3f1fe311b3ac989be5a9148e2e3c59ad --- /dev/null +++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java -@@ -0,0 +1,2071 @@ +@@ -0,0 +1,2072 @@ +package io.papermc.paper.chunk.system.scheduling; + +import ca.spottedleaf.concurrentutil.completable.Completable; @@ -10312,6 +10312,7 @@ index 0000000000000000000000000000000000000000..dd9c1d68a2bc42467b4566953aaed028 + if (!currState.isOrAfter(ChunkHolder.FullChunkStatus.BORDER) && nextState.isOrAfter(ChunkHolder.FullChunkStatus.BORDER)) { + nextState = this.updateCurrentState(ChunkHolder.FullChunkStatus.BORDER); + holderManager.ensureInAutosave(this); ++ chunk.pushChunkIntoLoadedMap(); + this.changeEntityChunkStatus(ChunkHolder.FullChunkStatus.BORDER); + chunk.onChunkLoad(this); + this.onFullChunkLoadChange(true, changedFullStatus); @@ -16670,7 +16671,7 @@ index e6240f891e396d91e31b02fdf3084be77e9d6697..00cb9dafc711607f28529ea9afbcdb49 public int getIndex() { diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -index e75ec8f6aa597b5f3048d6269fba45eef057bc71..8b65e8361918b5e6fe936fec99ee63ff9eef66f0 100644 +index e75ec8f6aa597b5f3048d6269fba45eef057bc71..6a84e7524a246e234116a37349f30e01411e6787 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -183,6 +183,43 @@ public class LevelChunk extends ChunkAccess { @@ -16717,10 +16718,13 @@ index e75ec8f6aa597b5f3048d6269fba45eef057bc71..8b65e8361918b5e6fe936fec99ee63ff } public final boolean isAnyNeighborsLoaded() { -@@ -660,8 +697,67 @@ public class LevelChunk extends ChunkAccess { +@@ -660,9 +697,26 @@ public class LevelChunk extends ChunkAccess { } +- // CraftBukkit start +- public void loadCallback() { +- // Paper start - neighbour cache + // Paper start - new load callbacks + private io.papermc.paper.chunk.system.scheduling.NewChunkHolder chunkHolder; + public io.papermc.paper.chunk.system.scheduling.NewChunkHolder getChunkHolder() { @@ -16740,6 +16744,16 @@ index e75ec8f6aa597b5f3048d6269fba45eef057bc71..8b65e8361918b5e6fe936fec99ee63ff + + /* Note: We skip the light neighbour chunk loading done for the vanilla full chunk */ + /* Starlight does not need these chunks for lighting purposes because of edge checks */ ++ public void pushChunkIntoLoadedMap() { + int chunkX = this.chunkPos.x; + int chunkZ = this.chunkPos.z; + ServerChunkCache chunkProvider = this.level.getChunkSource(); +@@ -677,10 +731,56 @@ public class LevelChunk extends ChunkAccess { + } + } + this.setNeighbourLoaded(0, 0, this); ++ this.level.getChunkSource().addLoadedChunk(this); ++ } + + public void onChunkLoad(io.papermc.paper.chunk.system.scheduling.NewChunkHolder chunkHolder) { + // figure out how this should interface with: @@ -16779,21 +16793,21 @@ index e75ec8f6aa597b5f3048d6269fba45eef057bc71..8b65e8361918b5e6fe936fec99ee63ff + } + // Paper end - new load callbacks + - // CraftBukkit start - public void loadCallback() { ++ // CraftBukkit start ++ public void loadCallback() { + if (this.loadedTicketLevel) { LOGGER.error("Double calling chunk load!", new Throwable()); } // Paper - // Paper start - neighbour cache - int chunkX = this.chunkPos.x; - int chunkZ = this.chunkPos.z; -@@ -681,6 +777,7 @@ public class LevelChunk extends ChunkAccess { - // Paper end - neighbour cache ++ // Paper - rewrite chunk system - move into separate callback + this.loadedTicketLevel = true; +- // Paper end - neighbour cache ++ // Paper - rewrite chunk system - move into separate callback org.bukkit.Server server = this.level.getCraftServer(); - this.level.getChunkSource().addLoadedChunk(this); // Paper +- this.level.getChunkSource().addLoadedChunk(this); // Paper ++ // Paper - rewrite chunk system - move into separate callback + ((ServerLevel)this.level).getChunkSource().chunkMap.playerChunkManager.onChunkLoad(this.chunkPos.x, this.chunkPos.z); // Paper - rewrite player chunk management if (server != null) { /* * If it's a new world, the first few chunks are generated inside -@@ -688,6 +785,7 @@ public class LevelChunk extends ChunkAccess { +@@ -688,6 +788,7 @@ public class LevelChunk extends ChunkAccess { * no way of creating a CraftWorld/CraftServer at that point. */ server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(this.bukkitChunk, this.needsDecoration)); @@ -16801,7 +16815,7 @@ index e75ec8f6aa597b5f3048d6269fba45eef057bc71..8b65e8361918b5e6fe936fec99ee63ff if (this.needsDecoration) { try (co.aikar.timings.Timing ignored = this.level.timings.chunkLoadPopulate.startTiming()) { // Paper -@@ -716,7 +814,9 @@ public class LevelChunk extends ChunkAccess { +@@ -716,7 +817,9 @@ public class LevelChunk extends ChunkAccess { } public void unloadCallback() { @@ -16811,7 +16825,7 @@ index e75ec8f6aa597b5f3048d6269fba45eef057bc71..8b65e8361918b5e6fe936fec99ee63ff org.bukkit.event.world.ChunkUnloadEvent unloadEvent = new org.bukkit.event.world.ChunkUnloadEvent(this.bukkitChunk, this.isUnsaved()); server.getPluginManager().callEvent(unloadEvent); // note: saving can be prevented, but not forced if no saving is actually required -@@ -804,7 +904,10 @@ public class LevelChunk extends ChunkAccess { +@@ -804,7 +907,10 @@ public class LevelChunk extends ChunkAccess { }); } @@ -16822,7 +16836,7 @@ index e75ec8f6aa597b5f3048d6269fba45eef057bc71..8b65e8361918b5e6fe936fec99ee63ff ChunkPos chunkcoordintpair = this.getPos(); for (int i = 0; i < this.postProcessing.length; ++i) { -@@ -842,6 +945,11 @@ public class LevelChunk extends ChunkAccess { +@@ -842,6 +948,11 @@ public class LevelChunk extends ChunkAccess { this.pendingBlockEntities.clear(); this.upgradeData.upgrade(this); @@ -16834,7 +16848,7 @@ index e75ec8f6aa597b5f3048d6269fba45eef057bc71..8b65e8361918b5e6fe936fec99ee63ff } @Nullable -@@ -891,7 +999,7 @@ public class LevelChunk extends ChunkAccess { +@@ -891,7 +1002,7 @@ public class LevelChunk extends ChunkAccess { } public ChunkHolder.FullChunkStatus getFullStatus() { diff --git a/patches/server/0032-Prevent-tile-entity-and-entity-crashes.patch b/patches/server/0032-Prevent-tile-entity-and-entity-crashes.patch index ce3f080af..ac5edf52f 100644 --- a/patches/server/0032-Prevent-tile-entity-and-entity-crashes.patch +++ b/patches/server/0032-Prevent-tile-entity-and-entity-crashes.patch @@ -44,10 +44,10 @@ index be08224c8107aab3e9a3645a20977dd14bfff782..c518704386f14cd033307dd976455c35 } } diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -index 8b65e8361918b5e6fe936fec99ee63ff9eef66f0..a4594b6b28eab545694491bc547f05a971a6ffad 100644 +index 6a84e7524a246e234116a37349f30e01411e6787..5127da6855ca58c8703d3aa85abcbcef345b37e6 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -1166,11 +1166,11 @@ public class LevelChunk extends ChunkAccess { +@@ -1169,11 +1169,11 @@ public class LevelChunk extends ChunkAccess { gameprofilerfiller.pop(); } catch (Throwable throwable) { diff --git a/patches/server/0059-Add-exception-reporting-event.patch b/patches/server/0059-Add-exception-reporting-event.patch index 975103897..48cc76714 100644 --- a/patches/server/0059-Add-exception-reporting-event.patch +++ b/patches/server/0059-Add-exception-reporting-event.patch @@ -131,7 +131,7 @@ index 992b1eb2e4151863ba7900c3f7eaa8e56c0de7fa..c6ba7427b53398ddc8f0c942a810fad6 } diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -index a4594b6b28eab545694491bc547f05a971a6ffad..20c9eada6f051ecdd5e45e625d7e6289d406a2f8 100644 +index 5127da6855ca58c8703d3aa85abcbcef345b37e6..6aea5dd821b213772f9dbf9f6d134fc28c7dfd05 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -1,6 +1,7 @@ @@ -163,7 +163,7 @@ index a4594b6b28eab545694491bc547f05a971a6ffad..20c9eada6f051ecdd5e45e625d7e6289 // CraftBukkit end } } -@@ -1169,6 +1176,7 @@ public class LevelChunk extends ChunkAccess { +@@ -1172,6 +1179,7 @@ public class LevelChunk extends ChunkAccess { // Paper start - Prevent tile entity and entity crashes final String msg = String.format("BlockEntity threw exception at %s:%s,%s,%s", LevelChunk.this.getLevel().getWorld().getName(), this.getPos().getX(), this.getPos().getY(), this.getPos().getZ()); net.minecraft.server.MinecraftServer.LOGGER.error(msg, throwable); diff --git a/patches/server/0378-Improved-Watchdog-Support.patch b/patches/server/0378-Improved-Watchdog-Support.patch index 96f8055ba..4666f3be7 100644 --- a/patches/server/0378-Improved-Watchdog-Support.patch +++ b/patches/server/0378-Improved-Watchdog-Support.patch @@ -306,10 +306,10 @@ index 0dd6ccc5b281ea46d2d12eb99c28335bdbe66d7e..426fe552d2444a4977a3e261d7e60fbd final String msg = String.format("Entity threw exception at %s:%s,%s,%s", entity.level.getWorld().getName(), entity.getX(), entity.getY(), entity.getZ()); MinecraftServer.LOGGER.error(msg, throwable); diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -index bd1c957a9405ccf18f110c7976cf8e0af922cf78..b0f53c99a89b900ffe49bdd277329829b44775d4 100644 +index ab9c7b2d68ef34f1fb8f5acaaf88401d789e3475..941bd6c43d3de9e5c947c2b7a3f42388c3fea25a 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -1200,6 +1200,7 @@ public class LevelChunk extends ChunkAccess { +@@ -1203,6 +1203,7 @@ public class LevelChunk extends ChunkAccess { gameprofilerfiller.pop(); } catch (Throwable throwable) {