SPIGOT-5228: Entities that are removed during chunk unloads are not
properly removed from the chunk. This could lead to dead entities accumulating in memory over time if the chunk never gets fully unloaded (as it is the case for chunks around the spawn region). The issue is that Minecraft processes the removal of these entities during the next tick, when the chunk has already switched to state INACCESSIBLE and can no longer be retrieved as usual. For the purpose of removing dead entities from their still loaded but no longer accessible chunk, this adds and uses a new method with which a chunk can be accessed without checking its current state first. By: blablubbabc <lukas@wirsindwir.de>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/ChunkProviderServer.java
|
||||
+++ b/net/minecraft/server/ChunkProviderServer.java
|
||||
@@ -54,6 +54,16 @@
|
||||
@@ -54,6 +54,24 @@
|
||||
this.clearCache();
|
||||
}
|
||||
|
||||
@@ -12,12 +12,20 @@
|
||||
+ }
|
||||
+ return chunk.getFullChunk() != null;
|
||||
+ }
|
||||
+
|
||||
+ public Chunk getChunkUnchecked(int chunkX, int chunkZ) {
|
||||
+ PlayerChunk chunk = this.playerChunkMap.getUpdatingChunk(ChunkCoordIntPair.pair(chunkX, chunkZ));
|
||||
+ if (chunk == null) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ return chunk.getFullChunkUnchecked();
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
@Override
|
||||
public LightEngineThreaded getLightEngine() {
|
||||
return this.lightEngine;
|
||||
@@ -98,7 +108,7 @@
|
||||
@@ -98,7 +116,7 @@
|
||||
for (int l = 0; l < 4; ++l) {
|
||||
if (k == this.cachePos[l] && chunkstatus == this.cacheStatus[l]) {
|
||||
ichunkaccess = this.cacheChunk[l];
|
||||
@@ -26,7 +34,7 @@
|
||||
return ichunkaccess;
|
||||
}
|
||||
}
|
||||
@@ -144,12 +154,12 @@
|
||||
@@ -144,12 +162,12 @@
|
||||
if (playerchunk == null) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -41,7 +49,7 @@
|
||||
|
||||
if (ichunkaccess1 != null) {
|
||||
this.a(k, ichunkaccess1, ChunkStatus.FULL);
|
||||
@@ -176,7 +186,15 @@
|
||||
@@ -176,7 +194,15 @@
|
||||
int l = 33 + ChunkStatus.a(chunkstatus);
|
||||
PlayerChunk playerchunk = this.getChunk(k);
|
||||
|
||||
@@ -58,7 +66,7 @@
|
||||
this.chunkMapDistance.a(TicketType.UNKNOWN, chunkcoordintpair, l, chunkcoordintpair);
|
||||
if (this.a(playerchunk, l)) {
|
||||
GameProfilerFiller gameprofilerfiller = this.world.getMethodProfiler();
|
||||
@@ -195,7 +213,7 @@
|
||||
@@ -195,7 +221,7 @@
|
||||
}
|
||||
|
||||
private boolean a(@Nullable PlayerChunk playerchunk, int i) {
|
||||
@@ -67,7 +75,7 @@
|
||||
}
|
||||
|
||||
public boolean isLoaded(int i, int j) {
|
||||
@@ -257,19 +275,19 @@
|
||||
@@ -257,19 +283,19 @@
|
||||
public boolean a(Entity entity) {
|
||||
long i = ChunkCoordIntPair.pair(MathHelper.floor(entity.locX()) >> 4, MathHelper.floor(entity.locZ()) >> 4);
|
||||
|
||||
@@ -90,7 +98,7 @@
|
||||
}
|
||||
|
||||
private boolean a(long i, Function<PlayerChunk, CompletableFuture<Either<Chunk, PlayerChunk.Failure>>> function) {
|
||||
@@ -291,11 +309,31 @@
|
||||
@@ -291,11 +317,31 @@
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
@@ -123,7 +131,7 @@
|
||||
public void tick(BooleanSupplier booleansupplier) {
|
||||
this.world.getMethodProfiler().enter("purge");
|
||||
this.chunkMapDistance.purgeTickets();
|
||||
@@ -315,12 +353,12 @@
|
||||
@@ -315,12 +361,12 @@
|
||||
this.lastTickTime = i;
|
||||
WorldData worlddata = this.world.getWorldData();
|
||||
boolean flag = this.world.isDebugWorld();
|
||||
@@ -138,7 +146,7 @@
|
||||
|
||||
this.world.getMethodProfiler().enter("naturalSpawnCount");
|
||||
int l = this.chunkMapDistance.b();
|
||||
@@ -507,12 +545,18 @@
|
||||
@@ -507,12 +553,18 @@
|
||||
|
||||
@Override
|
||||
protected boolean executeNext() {
|
||||
|
||||
Reference in New Issue
Block a user