From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Spottedleaf <spottedleaf@spottedleaf.dev> 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 c9563c0a5f230753dda469530cabde67fdb13f83..5157eac0190c6e1458dedfb1cb2eddee5639407e 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<Runnable> mainThreadExecutor, LightChunkGetter chunkProvider, ChunkGenerator chunkGenerator, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier<DimensionDataStorage> 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 2099769f54b53129f350856a227db4c475b4c903..e13a8e3dc11292aed13ff12ee8e0f9d6a95f0c34 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();