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.
This commit is contained in:
Spottedleaf 2022-10-18 08:11:23 -07:00
parent e1d4b26a62
commit f7da209586
4 changed files with 37 additions and 23 deletions

View File

@ -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 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 new file mode 100644
index 0000000000000000000000000000000000000000..dd9c1d68a2bc42467b4566953aaed028bddf0f74 index 0000000000000000000000000000000000000000..f20faaec3f1fe311b3ac989be5a9148e2e3c59ad
--- /dev/null --- /dev/null
+++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java +++ 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; +package io.papermc.paper.chunk.system.scheduling;
+ +
+import ca.spottedleaf.concurrentutil.completable.Completable; +import ca.spottedleaf.concurrentutil.completable.Completable;
@ -10312,6 +10312,7 @@ index 0000000000000000000000000000000000000000..dd9c1d68a2bc42467b4566953aaed028
+ if (!currState.isOrAfter(ChunkHolder.FullChunkStatus.BORDER) && nextState.isOrAfter(ChunkHolder.FullChunkStatus.BORDER)) { + if (!currState.isOrAfter(ChunkHolder.FullChunkStatus.BORDER) && nextState.isOrAfter(ChunkHolder.FullChunkStatus.BORDER)) {
+ nextState = this.updateCurrentState(ChunkHolder.FullChunkStatus.BORDER); + nextState = this.updateCurrentState(ChunkHolder.FullChunkStatus.BORDER);
+ holderManager.ensureInAutosave(this); + holderManager.ensureInAutosave(this);
+ chunk.pushChunkIntoLoadedMap();
+ this.changeEntityChunkStatus(ChunkHolder.FullChunkStatus.BORDER); + this.changeEntityChunkStatus(ChunkHolder.FullChunkStatus.BORDER);
+ chunk.onChunkLoad(this); + chunk.onChunkLoad(this);
+ this.onFullChunkLoadChange(true, changedFullStatus); + this.onFullChunkLoadChange(true, changedFullStatus);
@ -16670,7 +16671,7 @@ index e6240f891e396d91e31b02fdf3084be77e9d6697..00cb9dafc711607f28529ea9afbcdb49
public int getIndex() { 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 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 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/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 { @@ -183,6 +183,43 @@ public class LevelChunk extends ChunkAccess {
@ -16717,10 +16718,13 @@ index e75ec8f6aa597b5f3048d6269fba45eef057bc71..8b65e8361918b5e6fe936fec99ee63ff
} }
public final boolean isAnyNeighborsLoaded() { 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 + // Paper start - new load callbacks
+ private io.papermc.paper.chunk.system.scheduling.NewChunkHolder chunkHolder; + private io.papermc.paper.chunk.system.scheduling.NewChunkHolder chunkHolder;
+ public io.papermc.paper.chunk.system.scheduling.NewChunkHolder getChunkHolder() { + 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 */ + /* 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 */ + /* 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) { + public void onChunkLoad(io.papermc.paper.chunk.system.scheduling.NewChunkHolder chunkHolder) {
+ // figure out how this should interface with: + // figure out how this should interface with:
@ -16779,21 +16793,21 @@ index e75ec8f6aa597b5f3048d6269fba45eef057bc71..8b65e8361918b5e6fe936fec99ee63ff
+ } + }
+ // Paper end - new load callbacks + // Paper end - new load callbacks
+ +
// CraftBukkit start + // CraftBukkit start
public void loadCallback() { + public void loadCallback() {
+ if (this.loadedTicketLevel) { LOGGER.error("Double calling chunk load!", new Throwable()); } // Paper + if (this.loadedTicketLevel) { LOGGER.error("Double calling chunk load!", new Throwable()); } // Paper
// Paper start - neighbour cache + // Paper - rewrite chunk system - move into separate callback
int chunkX = this.chunkPos.x; this.loadedTicketLevel = true;
int chunkZ = this.chunkPos.z; - // Paper end - neighbour cache
@@ -681,6 +777,7 @@ public class LevelChunk extends ChunkAccess { + // Paper - rewrite chunk system - move into separate callback
// Paper end - neighbour cache
org.bukkit.Server server = this.level.getCraftServer(); 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 + ((ServerLevel)this.level).getChunkSource().chunkMap.playerChunkManager.onChunkLoad(this.chunkPos.x, this.chunkPos.z); // Paper - rewrite player chunk management
if (server != null) { if (server != null) {
/* /*
* If it's a new world, the first few chunks are generated inside * 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. * no way of creating a CraftWorld/CraftServer at that point.
*/ */
server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(this.bukkitChunk, this.needsDecoration)); server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(this.bukkitChunk, this.needsDecoration));
@ -16801,7 +16815,7 @@ index e75ec8f6aa597b5f3048d6269fba45eef057bc71..8b65e8361918b5e6fe936fec99ee63ff
if (this.needsDecoration) { if (this.needsDecoration) {
try (co.aikar.timings.Timing ignored = this.level.timings.chunkLoadPopulate.startTiming()) { // Paper 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() { 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()); org.bukkit.event.world.ChunkUnloadEvent unloadEvent = new org.bukkit.event.world.ChunkUnloadEvent(this.bukkitChunk, this.isUnsaved());
server.getPluginManager().callEvent(unloadEvent); server.getPluginManager().callEvent(unloadEvent);
// note: saving can be prevented, but not forced if no saving is actually required // 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(); ChunkPos chunkcoordintpair = this.getPos();
for (int i = 0; i < this.postProcessing.length; ++i) { 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.pendingBlockEntities.clear();
this.upgradeData.upgrade(this); this.upgradeData.upgrade(this);
@ -16834,7 +16848,7 @@ index e75ec8f6aa597b5f3048d6269fba45eef057bc71..8b65e8361918b5e6fe936fec99ee63ff
} }
@Nullable @Nullable
@@ -891,7 +999,7 @@ public class LevelChunk extends ChunkAccess { @@ -891,7 +1002,7 @@ public class LevelChunk extends ChunkAccess {
} }
public ChunkHolder.FullChunkStatus getFullStatus() { public ChunkHolder.FullChunkStatus getFullStatus() {

View File

@ -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 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 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/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(); gameprofilerfiller.pop();
} catch (Throwable throwable) { } catch (Throwable throwable) {

View File

@ -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 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 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/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 @@ @@ -1,6 +1,7 @@
@ -163,7 +163,7 @@ index a4594b6b28eab545694491bc547f05a971a6ffad..20c9eada6f051ecdd5e45e625d7e6289
// CraftBukkit end // 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 // 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()); 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); net.minecraft.server.MinecraftServer.LOGGER.error(msg, throwable);

View File

@ -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()); 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); 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 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 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/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(); gameprofilerfiller.pop();
} catch (Throwable throwable) { } catch (Throwable throwable) {