diff --git a/nms-patches/ChunkProviderServer.patch b/nms-patches/ChunkProviderServer.patch index 1309bf5263..5111274053 100644 --- a/nms-patches/ChunkProviderServer.patch +++ b/nms-patches/ChunkProviderServer.patch @@ -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() { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java index 5318dfd2b5..831048f83a 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -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);