#673: Fix Craftworld#isChunkLoaded

The flag for getChunkAt(int, int, ChunkStatus, boolean)
is actually a flag for whether to bring the underlying
PlayerChunk up to the required ticket level to load the
chunk. So, if the chunk is already at the required level,
but has not yet loaded, the call will actually either
start the load if it has not already been started and
block until completion.

This behaviour is not suitable for just
checking if the chunk is loaded.
This commit is contained in:
Spottedleaf 2020-06-06 19:23:46 +10:00 committed by md_5
parent 8637ec008d
commit fad2494af1
2 changed files with 30 additions and 15 deletions

View file

@ -1,6 +1,23 @@
--- a/net/minecraft/server/ChunkProviderServer.java
+++ b/net/minecraft/server/ChunkProviderServer.java
@@ -95,7 +95,7 @@
@@ -51,6 +51,16 @@
this.clearCache();
}
+ // CraftBukkit start - properly implement isChunkLoaded
+ public boolean isChunkLoaded(int chunkX, int chunkZ) {
+ PlayerChunk chunk = this.playerChunkMap.getUpdatingChunk(ChunkCoordIntPair.pair(chunkX, chunkZ));
+ if (chunk == null) {
+ return false;
+ }
+ return chunk.getFullChunk() != null;
+ }
+ // CraftBukkit end
+
@Override
public LightEngineThreaded getLightEngine() {
return this.lightEngine;
@@ -95,7 +105,7 @@
for (int l = 0; l < 4; ++l) {
if (k == this.cachePos[l] && chunkstatus == this.cacheStatus[l]) {
ichunkaccess = this.cacheChunk[l];
@ -9,7 +26,7 @@
return ichunkaccess;
}
}
@@ -141,12 +141,12 @@
@@ -141,12 +151,12 @@
if (playerchunk == null) {
return null;
} else {
@ -24,7 +41,7 @@
if (ichunkaccess1 != null) {
this.a(k, ichunkaccess1, ChunkStatus.FULL);
@@ -173,7 +173,15 @@
@@ -173,7 +183,15 @@
int l = 33 + ChunkStatus.a(chunkstatus);
PlayerChunk playerchunk = this.getChunk(k);
@ -41,7 +58,7 @@
this.chunkMapDistance.a(TicketType.UNKNOWN, chunkcoordintpair, l, chunkcoordintpair);
if (this.a(playerchunk, l)) {
GameProfilerFiller gameprofilerfiller = this.world.getMethodProfiler();
@@ -192,7 +200,7 @@
@@ -192,7 +210,7 @@
}
private boolean a(@Nullable PlayerChunk playerchunk, int i) {
@ -50,7 +67,7 @@
}
public boolean isLoaded(int i, int j) {
@@ -294,11 +302,31 @@
@@ -294,11 +312,31 @@
@Override
public void close() throws IOException {
@ -83,7 +100,7 @@
public void tick(BooleanSupplier booleansupplier) {
this.world.getMethodProfiler().enter("purge");
this.chunkMapDistance.purgeTickets();
@@ -318,13 +346,19 @@
@@ -318,13 +356,19 @@
this.lastTickTime = i;
WorldData worlddata = this.world.getWorldData();
boolean flag = worlddata.getType() == WorldType.DEBUG_ALL_BLOCK_STATES;
@ -105,7 +122,7 @@
this.world.getMethodProfiler().enter("naturalSpawnCount");
int l = this.chunkMapDistance.b();
@@ -353,8 +387,35 @@
@@ -353,8 +397,35 @@
for (int j1 = 0; j1 < i1; ++j1) {
EnumCreatureType enumcreaturetype = aenumcreaturetype1[j1];
@ -142,7 +159,7 @@
if (object2intmap.getInt(enumcreaturetype) <= k1) {
SpawnerCreature.a(enumcreaturetype, this.world, chunk, blockposition);
@@ -507,12 +568,18 @@
@@ -507,12 +578,18 @@
@Override
protected boolean executeNext() {

View file

@ -340,8 +340,7 @@ public class CraftWorld implements World {
@Override
public boolean isChunkLoaded(int x, int z) {
net.minecraft.server.Chunk chunk = world.getChunkProvider().getChunkAt(x, z, false);
return chunk != null;
return world.getChunkProvider().isChunkLoaded(x, z);
}
@Override
@ -381,19 +380,18 @@ public class CraftWorld implements World {
@Override
public boolean unloadChunkRequest(int x, int z) {
net.minecraft.server.IChunkAccess chunk = world.getChunkProvider().getChunkAt(x, z, ChunkStatus.FULL, false);
if (chunk != null) {
world.getChunkProvider().removeTicket(TicketType.PLUGIN, chunk.getPos(), 1, Unit.INSTANCE);
if (isChunkLoaded(x, z)) {
world.getChunkProvider().removeTicket(TicketType.PLUGIN, new ChunkCoordIntPair(x, z), 1, Unit.INSTANCE);
}
return true;
}
private boolean unloadChunk0(int x, int z, boolean save) {
net.minecraft.server.Chunk chunk = (net.minecraft.server.Chunk) world.getChunkProvider().getChunkAt(x, z, ChunkStatus.FULL, false);
if (chunk == null) {
if (!isChunkLoaded(x, z)) {
return true;
}
net.minecraft.server.Chunk chunk = world.getChunkAt(x, z);
chunk.mustNotSave = !save;
unloadChunkRequest(x, z);