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.
This commit is contained in:
blablubbabc 2022-03-27 16:24:06 +11:00 committed by md_5
parent e6cc7c70d7
commit 4ac8fcce8d
No known key found for this signature in database
GPG Key ID: E8E901AC7C617C11
3 changed files with 29 additions and 8 deletions

View File

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

View File

@ -25,7 +25,28 @@
this.pos = chunkcoordintpair; this.pos = chunkcoordintpair;
this.levelHeightAccessor = levelheightaccessor; this.levelHeightAccessor = levelheightaccessor;
this.lightEngine = lightengine; 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 @Nullable
public Chunk getTickingChunk() { public Chunk getTickingChunk() {
CompletableFuture<Either<Chunk, PlayerChunk.Failure>> completablefuture = this.getTickingChunkFuture(); CompletableFuture<Either<Chunk, PlayerChunk.Failure>> completablefuture = this.getTickingChunkFuture();
@ -47,7 +68,7 @@
} }
@Nullable @Nullable
@@ -172,6 +176,7 @@ @@ -172,6 +190,7 @@
if (chunk != null) { if (chunk != null) {
int i = this.levelHeightAccessor.getSectionIndex(blockposition.getY()); int i = this.levelHeightAccessor.getSectionIndex(blockposition.getY());
@ -55,7 +76,7 @@
if (this.changedBlocksPerSection[i] == null) { if (this.changedBlocksPerSection[i] == null) {
this.hasChangedSections = true; this.hasChangedSections = true;
this.changedBlocksPerSection[i] = new ShortOpenHashSet(); this.changedBlocksPerSection[i] = new ShortOpenHashSet();
@@ -368,7 +373,7 @@ @@ -368,7 +387,7 @@
this.pendingFullStateConfirmation = completablefuture1; this.pendingFullStateConfirmation = completablefuture1;
completablefuture.thenAccept((either) -> { completablefuture.thenAccept((either) -> {
either.ifLeft((chunk) -> { either.ifLeft((chunk) -> {
@ -64,7 +85,7 @@
}); });
}); });
} }
@@ -385,6 +390,30 @@ @@ -385,6 +404,30 @@
boolean flag1 = this.ticketLevel <= PlayerChunkMap.MAX_CHUNK_DISTANCE; boolean flag1 = this.ticketLevel <= PlayerChunkMap.MAX_CHUNK_DISTANCE;
PlayerChunk.State playerchunk_state = getFullChunkStatus(this.oldTicketLevel); PlayerChunk.State playerchunk_state = getFullChunkStatus(this.oldTicketLevel);
PlayerChunk.State playerchunk_state1 = getFullChunkStatus(this.ticketLevel); PlayerChunk.State playerchunk_state1 = getFullChunkStatus(this.ticketLevel);
@ -95,7 +116,7 @@
if (flag) { if (flag) {
Either<IChunkAccess, PlayerChunk.Failure> either = Either.right(new PlayerChunk.Failure() { 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.onLevelChange.onLevelChange(this.pos, this::getQueueLevel, this.ticketLevel, this::setQueueLevel);
this.oldTicketLevel = this.ticketLevel; this.oldTicketLevel = this.ticketLevel;

View File

@ -231,7 +231,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override @Override
public Chunk[] getLoadedChunks() { public Chunk[] getLoadedChunks() {
Long2ObjectLinkedOpenHashMap<PlayerChunk> chunks = world.getChunkSource().chunkMap.visibleChunkMap; 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 @Override