From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Sat, 19 Sep 2020 15:29:16 -0700 Subject: [PATCH] Do not allow ticket level changes while unloading playerchunks Sync loading the chunk at this stage would cause it to load older data, as well as screwing our region state. diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java index e106583bbd3268e48b485019e5b6a80f36aa161e..ba7cd04b33fcaea7e7cea43b5929df56e130bf3f 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -296,6 +296,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } // Paper end + boolean unloadingPlayerChunk = false; // Paper - do not allow ticket level changes while unloading chunks public ChunkMap(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureManager structureManager, Executor executor, BlockableEventLoop mainThreadExecutor, LightChunkGetter chunkProvider, ChunkGenerator chunkGenerator, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier persistentStateManagerFactory, int viewDistance, boolean dsync) { super(session.getDimensionPath(world.dimension()).resolve("region"), dataFixer, dsync); this.visibleChunkMap = this.updatingChunkMap.clone(); @@ -690,6 +691,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @Nullable ChunkHolder updateChunkScheduling(long pos, int level, @Nullable ChunkHolder holder, int k) { + if (this.unloadingPlayerChunk) { net.minecraft.server.MinecraftServer.LOGGER.fatal("Cannot tick distance manager while unloading playerchunks", new Throwable()); throw new IllegalStateException("Cannot tick distance manager while unloading playerchunks"); } // Paper if (k > ChunkMap.MAX_CHUNK_DISTANCE && level > ChunkMap.MAX_CHUNK_DISTANCE) { return holder; } else { @@ -908,6 +910,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider if (completablefuture1 != completablefuture) { this.scheduleUnload(pos, holder); } else { + // Paper start - do not allow ticket level changes while unloading chunks + org.spigotmc.AsyncCatcher.catchOp("playerchunk unload"); + boolean unloadingBefore = this.unloadingPlayerChunk; + this.unloadingPlayerChunk = true; + try { + // Paper end - do not allow ticket level changes while unloading chunks // Paper start boolean removed; if ((removed = this.pendingUnloads.remove(pos, holder)) && ichunkaccess != null) { @@ -944,6 +952,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.regionManagers.get(index).removeChunk(holder.pos.x, holder.pos.z); } } // Paper end + } finally { this.unloadingPlayerChunk = unloadingBefore; } // Paper - do not allow ticket level changes while unloading chunks } }; diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java index 804aaa62d9c39bc4340a83a9ed88ab7d04c47059..7dfccd2e72ac5ec8b03b3439b034975ddadd759e 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -820,6 +820,7 @@ public class ServerChunkCache extends ChunkSource { public boolean runDistanceManagerUpdates() { if (distanceManager.delayDistanceManagerTick) return false; // Paper - Chunk priority + if (this.chunkMap.unloadingPlayerChunk) { net.minecraft.server.MinecraftServer.LOGGER.fatal("Cannot tick distance manager while unloading playerchunks", new Throwable()); throw new IllegalStateException("Cannot tick distance manager while unloading playerchunks"); } // Paper boolean flag = this.distanceManager.runAllUpdates(this.chunkMap); boolean flag1 = this.chunkMap.promoteChunkMap();