SPIGOT-6980: Since 1.18.2, World#isChunkLoaded returned false for chunks that have just been loaded (e.g. inside ChunkLoadEvent).

Some changes of the 1.18.2 update have been reverted to resolve this regression.

By: blablubbabc <lukas@wirsindwir.de>
This commit is contained in:
CraftBukkit/Spigot 2022-03-27 16:24:06 +11:00
parent fa672ce555
commit 475d10469d
3 changed files with 29 additions and 8 deletions

View file

@ -10,7 +10,7 @@
+ if (chunk == null) {
+ return false;
+ }
+ return chunk.getFullChunk() != null;
+ return chunk.getFullChunkNow() != null;
+ }
+
+ public Chunk getChunkUnchecked(int chunkX, int chunkZ) {
@ -18,7 +18,7 @@
+ if (chunk == null) {
+ return null;
+ }
+ return chunk.getFullChunk();
+ return chunk.getFullChunkNowUnchecked();
+ }
+ // CraftBukkit end
+

View file

@ -25,7 +25,28 @@
this.pos = chunkcoordintpair;
this.levelHeightAccessor = levelheightaccessor;
this.lightEngine = lightengine;
@@ -117,17 +121,17 @@
@@ -92,6 +96,20 @@
this.changedBlocksPerSection = new ShortSet[levelheightaccessor.getSectionsCount()];
}
+ // CraftBukkit start
+ public Chunk getFullChunkNow() {
+ // Note: We use the oldTicketLevel for isLoaded checks.
+ if (!getFullChunkStatus(this.oldTicketLevel).isOrAfter(PlayerChunk.State.BORDER)) return null;
+ return this.getFullChunkNowUnchecked();
+ }
+
+ public Chunk getFullChunkNowUnchecked() {
+ CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> statusFuture = this.getFutureIfPresentUnchecked(ChunkStatus.FULL);
+ Either<IChunkAccess, PlayerChunk.Failure> either = (Either<IChunkAccess, PlayerChunk.Failure>) statusFuture.getNow(null);
+ return (either == null) ? null : (Chunk) either.left().orElse(null);
+ }
+ // CraftBukkit end
+
public CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> getFutureIfPresentUnchecked(ChunkStatus chunkstatus) {
CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> completablefuture = (CompletableFuture) this.futures.get(chunkstatus.getIndex());
@@ -117,17 +135,17 @@
@Nullable
public Chunk getTickingChunk() {
CompletableFuture<Either<Chunk, PlayerChunk.Failure>> completablefuture = this.getTickingChunkFuture();
@ -47,7 +68,7 @@
}
@Nullable
@@ -172,6 +176,7 @@
@@ -172,6 +190,7 @@
if (chunk != null) {
int i = this.levelHeightAccessor.getSectionIndex(blockposition.getY());
@ -55,7 +76,7 @@
if (this.changedBlocksPerSection[i] == null) {
this.hasChangedSections = true;
this.changedBlocksPerSection[i] = new ShortOpenHashSet();
@@ -368,7 +373,7 @@
@@ -368,7 +387,7 @@
this.pendingFullStateConfirmation = completablefuture1;
completablefuture.thenAccept((either) -> {
either.ifLeft((chunk) -> {
@ -64,7 +85,7 @@
});
});
}
@@ -385,6 +390,30 @@
@@ -385,6 +404,30 @@
boolean flag1 = this.ticketLevel <= PlayerChunkMap.MAX_CHUNK_DISTANCE;
PlayerChunk.State playerchunk_state = getFullChunkStatus(this.oldTicketLevel);
PlayerChunk.State playerchunk_state1 = getFullChunkStatus(this.ticketLevel);
@ -95,7 +116,7 @@
if (flag) {
Either<IChunkAccess, PlayerChunk.Failure> either = Either.right(new PlayerChunk.Failure() {
@@ -455,6 +484,26 @@
@@ -455,6 +498,26 @@
this.onLevelChange.onLevelChange(this.pos, this::getQueueLevel, this.ticketLevel, this::setQueueLevel);
this.oldTicketLevel = this.ticketLevel;

View file

@ -231,7 +231,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public Chunk[] getLoadedChunks() {
Long2ObjectLinkedOpenHashMap<PlayerChunk> chunks = world.getChunkSource().chunkMap.visibleChunkMap;
return chunks.values().stream().map(PlayerChunk::getFullChunk).filter(Objects::nonNull).map(net.minecraft.world.level.chunk.Chunk::getBukkitChunk).toArray(Chunk[]::new);
return chunks.values().stream().map(PlayerChunk::getFullChunkNow).filter(Objects::nonNull).map(net.minecraft.world.level.chunk.Chunk::getBukkitChunk).toArray(Chunk[]::new);
}
@Override