From 09904fd780175821a43adf74cc5a00d363e4a83d Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Fri, 2 Sep 2022 04:41:08 -0700 Subject: [PATCH] Re-add legacy getChunkAtAsynchronously to ChunkProviderServer Apparently some plugins use it --- patches/server/0008-MC-Utils.patch | 88 +++++++++++++- patches/server/0012-Timings-v2.patch | 12 +- ...19-Asynchronous-chunk-IO-and-loading.patch | 114 +++--------------- ...k-Priority-Urgency-System-for-Chunks.patch | 18 +-- ...7-PlayerNaturallySpawnCreaturesEvent.patch | 4 +- ...ement-optional-per-player-mob-spawns.patch | 4 +- ...e-getChunkAt-calls-for-loaded-chunks.patch | 6 +- .../0365-Add-debug-for-sync-chunk-loads.patch | 4 +- ...-Chunk-Post-Processing-deadlock-risk.patch | 4 +- ...erCloseEnoughForSpawning-to-use-dist.patch | 8 +- ...-incremental-chunk-and-player-saving.patch | 4 +- ...-server-to-unload-chunks-at-request-.patch | 4 +- ...ket-level-changes-while-unloading-pl.patch | 4 +- ...alls-removing-tickets-for-sync-loads.patch | 8 +- .../0736-Optimise-chunk-tick-iteration.patch | 8 +- .../0737-Execute-chunk-tasks-mid-tick.patch | 6 +- .../0742-Distance-manager-tick-timings.patch | 6 +- ...ush-calls-for-entity-tracker-packets.patch | 4 +- ...4-Replace-player-chunk-loader-system.patch | 10 +- 19 files changed, 159 insertions(+), 157 deletions(-) diff --git a/patches/server/0008-MC-Utils.patch b/patches/server/0008-MC-Utils.patch index 2d9248eb2..23e7f4e39 100644 --- a/patches/server/0008-MC-Utils.patch +++ b/patches/server/0008-MC-Utils.patch @@ -5914,7 +5914,7 @@ index 6c98676827ceb6999f340fa2b06a0b3e1cb4cae2..f08089b8672454acf8c2309e850466b3 while (objectiterator.hasNext()) { diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index ce88976db29b9e9524dbe45b16721ef90afb692b..96323a83d917516edf4b6951d1e881d2f5513bd0 100644 +index ce88976db29b9e9524dbe45b16721ef90afb692b..1a8c5ce3ecce9cbbc8496ea3882b18c297964e33 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -50,6 +50,7 @@ import net.minecraft.world.level.storage.LevelStorageSource; @@ -5925,7 +5925,7 @@ index ce88976db29b9e9524dbe45b16721ef90afb692b..96323a83d917516edf4b6951d1e881d2 public static final List CHUNK_STATUSES = ChunkStatus.getStatusList(); private final DistanceManager distanceManager; final ServerLevel level; -@@ -68,6 +69,151 @@ public class ServerChunkCache extends ChunkSource { +@@ -68,6 +69,231 @@ public class ServerChunkCache extends ChunkSource { @Nullable @VisibleForDebug private NaturalSpawner.SpawnState lastSpawnState; @@ -6022,6 +6022,86 @@ index ce88976db29b9e9524dbe45b16721ef90afb692b..96323a83d917516edf4b6951d1e881d2 + ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.NORMAL, onLoad + ); + } ++ ++ void chunkLoadAccept(int chunkX, int chunkZ, ChunkAccess chunk, java.util.function.Consumer consumer) { ++ try { ++ consumer.accept(chunk); ++ } catch (Throwable throwable) { ++ if (throwable instanceof ThreadDeath) { ++ throw (ThreadDeath)throwable; ++ } ++ LOGGER.error("Load callback for chunk " + chunkX + "," + chunkZ + " in world '" + this.level.getWorld().getName() + "' threw an exception", throwable); ++ } ++ } ++ ++ void getChunkAtAsynchronously(int chunkX, int chunkZ, int ticketLevel, ++ java.util.function.Consumer consumer) { ++ if (ticketLevel <= 33) { ++ this.getFullChunkAsync(chunkX, chunkZ, (java.util.function.Consumer)consumer); ++ return; ++ } ++ ++ net.minecraft.server.ChunkSystem.scheduleChunkLoad( ++ this.level, chunkX, chunkZ, ChunkHolder.getStatus(ticketLevel), true, ++ ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.NORMAL, consumer ++ ); ++ } ++ ++ ++ public final void getChunkAtAsynchronously(int chunkX, int chunkZ, ChunkStatus status, boolean gen, boolean allowSubTicketLevel, java.util.function.Consumer onLoad) { ++ // try to fire sync ++ int chunkStatusTicketLevel = 33 + ChunkStatus.getDistance(status); ++ ChunkHolder playerChunk = this.chunkMap.getUpdatingChunkIfPresent(io.papermc.paper.util.CoordinateUtils.getChunkKey(chunkX, chunkZ)); ++ if (playerChunk != null) { ++ ChunkStatus holderStatus = playerChunk.getChunkHolderStatus(); ++ ChunkAccess immediate = playerChunk.getAvailableChunkNow(); ++ if (immediate != null) { ++ if (allowSubTicketLevel ? immediate.getStatus().isOrAfter(status) : (playerChunk.getTicketLevel() <= chunkStatusTicketLevel && holderStatus != null && holderStatus.isOrAfter(status))) { ++ this.chunkLoadAccept(chunkX, chunkZ, immediate, onLoad); ++ return; ++ } else { ++ if (gen || (!allowSubTicketLevel && immediate.getStatus().isOrAfter(status))) { ++ this.getChunkAtAsynchronously(chunkX, chunkZ, chunkStatusTicketLevel, onLoad); ++ return; ++ } else { ++ this.chunkLoadAccept(chunkX, chunkZ, null, onLoad); ++ return; ++ } ++ } ++ } ++ } ++ ++ // need to fire async ++ ++ if (gen && !allowSubTicketLevel) { ++ this.getChunkAtAsynchronously(chunkX, chunkZ, chunkStatusTicketLevel, onLoad); ++ return; ++ } ++ ++ this.getChunkAtAsynchronously(chunkX, chunkZ, net.minecraft.server.MCUtil.getTicketLevelFor(ChunkStatus.EMPTY), (ChunkAccess chunk) -> { ++ if (chunk == null) { ++ throw new IllegalStateException("Chunk cannot be null"); ++ } ++ ++ if (!chunk.getStatus().isOrAfter(status)) { ++ if (gen) { ++ this.getChunkAtAsynchronously(chunkX, chunkZ, chunkStatusTicketLevel, onLoad); ++ return; ++ } else { ++ ServerChunkCache.this.chunkLoadAccept(chunkX, chunkZ, null, onLoad); ++ return; ++ } ++ } else { ++ if (allowSubTicketLevel) { ++ ServerChunkCache.this.chunkLoadAccept(chunkX, chunkZ, chunk, onLoad); ++ return; ++ } else { ++ this.getChunkAtAsynchronously(chunkX, chunkZ, chunkStatusTicketLevel, onLoad); ++ return; ++ } ++ } ++ }); ++ } + // Paper end + + // Paper start @@ -6077,7 +6157,7 @@ index ce88976db29b9e9524dbe45b16721ef90afb692b..96323a83d917516edf4b6951d1e881d2 public ServerChunkCache(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor workerExecutor, ChunkGenerator chunkGenerator, int viewDistance, int simulationDistance, boolean dsync, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier persistentStateManagerFactory) { this.level = world; -@@ -120,6 +266,49 @@ public class ServerChunkCache extends ChunkSource { +@@ -120,6 +346,49 @@ public class ServerChunkCache extends ChunkSource { this.lastChunk[0] = chunk; } @@ -6127,7 +6207,7 @@ index ce88976db29b9e9524dbe45b16721ef90afb692b..96323a83d917516edf4b6951d1e881d2 @Nullable @Override public ChunkAccess getChunk(int x, int z, ChunkStatus leastStatus, boolean create) { -@@ -327,6 +516,12 @@ public class ServerChunkCache extends ChunkSource { +@@ -327,6 +596,12 @@ public class ServerChunkCache extends ChunkSource { } } diff --git a/patches/server/0012-Timings-v2.patch b/patches/server/0012-Timings-v2.patch index 71da852f1..3795c7882 100644 --- a/patches/server/0012-Timings-v2.patch +++ b/patches/server/0012-Timings-v2.patch @@ -1054,10 +1054,10 @@ index 1fbe1b6de925f71763f79fe3d2371b70a8650f25..2a9e5fb8164f79b0f9c1cb5497216e51 } diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 96323a83d917516edf4b6951d1e881d2f5513bd0..514111ed7fe8aec0d5f15f7a8f157d5872a56e4f 100644 +index 1a8c5ce3ecce9cbbc8496ea3882b18c297964e33..8c99e9d1cc1abf5a425846eb4edd52bf38aa2f75 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -334,13 +334,15 @@ public class ServerChunkCache extends ChunkSource { +@@ -414,13 +414,15 @@ public class ServerChunkCache extends ChunkSource { } gameprofilerfiller.incrementCounter("getChunkCacheMiss"); @@ -1075,7 +1075,7 @@ index 96323a83d917516edf4b6951d1e881d2f5513bd0..514111ed7fe8aec0d5f15f7a8f157d58 ichunkaccess = (ChunkAccess) ((Either) completablefuture.join()).map((ichunkaccess1) -> { return ichunkaccess1; }, (playerchunk_failure) -> { -@@ -538,7 +540,9 @@ public class ServerChunkCache extends ChunkSource { +@@ -618,7 +620,9 @@ public class ServerChunkCache extends ChunkSource { public void save(boolean flush) { this.runDistanceManagerUpdates(); @@ -1085,7 +1085,7 @@ index 96323a83d917516edf4b6951d1e881d2f5513bd0..514111ed7fe8aec0d5f15f7a8f157d58 } @Override -@@ -577,7 +581,9 @@ public class ServerChunkCache extends ChunkSource { +@@ -657,7 +661,9 @@ public class ServerChunkCache extends ChunkSource { this.level.timings.doChunkMap.stopTiming(); // Spigot this.level.getProfiler().popPush("chunks"); if (tickChunks) { @@ -1095,7 +1095,7 @@ index 96323a83d917516edf4b6951d1e881d2f5513bd0..514111ed7fe8aec0d5f15f7a8f157d58 } this.level.timings.doChunkUnload.startTiming(); // Spigot -@@ -606,13 +612,16 @@ public class ServerChunkCache extends ChunkSource { +@@ -686,13 +692,16 @@ public class ServerChunkCache extends ChunkSource { boolean flag1 = level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) != 0L && worlddata.getGameTime() % level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) == 0L; // CraftBukkit gameprofilerfiller.push("naturalSpawnCount"); @@ -1112,7 +1112,7 @@ index 96323a83d917516edf4b6951d1e881d2f5513bd0..514111ed7fe8aec0d5f15f7a8f157d58 while (iterator.hasNext()) { ChunkHolder playerchunk = (ChunkHolder) iterator.next(); -@@ -641,27 +650,27 @@ public class ServerChunkCache extends ChunkSource { +@@ -721,27 +730,27 @@ public class ServerChunkCache extends ChunkSource { } if (this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) { diff --git a/patches/server/0019-Asynchronous-chunk-IO-and-loading.patch b/patches/server/0019-Asynchronous-chunk-IO-and-loading.patch index cf7bd1b0a..7f5e87c2a 100644 --- a/patches/server/0019-Asynchronous-chunk-IO-and-loading.patch +++ b/patches/server/0019-Asynchronous-chunk-IO-and-loading.patch @@ -2579,111 +2579,33 @@ index aaf6344d3187ceada947ce6ee0fbba91ca0271a3..1d6ab658c48bb765f66624f276ec7b05 while (objectiterator.hasNext()) { diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 514111ed7fe8aec0d5f15f7a8f157d5872a56e4f..3ff5e35e45a71dc03552dedb65c7338317e9d0a9 100644 +index 8c99e9d1cc1abf5a425846eb4edd52bf38aa2f75..07671ac54f598872dba2b22ec8f82db3dd037d7f 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -308,10 +308,111 @@ public class ServerChunkCache extends ChunkSource { +@@ -388,10 +388,33 @@ public class ServerChunkCache extends ChunkSource { return ret; } // Paper end + // Paper start - async chunk io -+ private long asyncLoadSeqCounter; -+ + public CompletableFuture> getChunkAtAsynchronously(int x, int z, boolean gen, boolean isUrgent) { -+ if (Thread.currentThread() != this.mainThread) { -+ CompletableFuture> future = new CompletableFuture>(); -+ this.mainThreadProcessor.execute(() -> { -+ this.getChunkAtAsynchronously(x, z, gen, isUrgent).whenComplete((chunk, ex) -> { -+ if (ex != null) { -+ future.completeExceptionally(ex); -+ } else { -+ future.complete(chunk); -+ } -+ }); -+ }); -+ return future; ++ CompletableFuture> ret = new CompletableFuture<>(); ++ ++ ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority; ++ if (isUrgent) { ++ priority = ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.HIGHER; ++ } else { ++ priority = ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.NORMAL; + } + -+ long k = ChunkPos.asLong(x, z); -+ ChunkPos chunkPos = new ChunkPos(x, z); -+ -+ ChunkAccess ichunkaccess; -+ -+ // try cache -+ for (int l = 0; l < 4; ++l) { -+ if (k == this.lastChunkPos[l] && ChunkStatus.FULL == this.lastChunkStatus[l]) { -+ ichunkaccess = this.lastChunk[l]; -+ if (ichunkaccess != null) { // CraftBukkit - the chunk can become accessible in the meantime TODO for non-null chunks it might also make sense to check that the chunk's state hasn't changed in the meantime -+ -+ // move to first in cache -+ -+ for (int i1 = 3; i1 > 0; --i1) { -+ this.lastChunkPos[i1] = this.lastChunkPos[i1 - 1]; -+ this.lastChunkStatus[i1] = this.lastChunkStatus[i1 - 1]; -+ this.lastChunk[i1] = this.lastChunk[i1 - 1]; -+ } -+ -+ this.lastChunkPos[0] = k; -+ this.lastChunkStatus[0] = ChunkStatus.FULL; -+ this.lastChunk[0] = ichunkaccess; -+ -+ return CompletableFuture.completedFuture(Either.left(ichunkaccess)); -+ } ++ net.minecraft.server.ChunkSystem.scheduleChunkLoad(this.level, x, z, gen, ChunkStatus.FULL, true, priority, (chunk) -> { ++ if (chunk == null) { ++ ret.complete(ChunkHolder.UNLOADED_CHUNK); ++ } else { ++ ret.complete(Either.left(chunk)); + } -+ } -+ -+ if (gen) { -+ return this.bringToFullStatusAsync(x, z, chunkPos, isUrgent); -+ } -+ -+ ChunkAccess current = this.getChunkAtImmediately(x, z); // we want to bypass ticket restrictions -+ if (current != null) { -+ if (!(current instanceof net.minecraft.world.level.chunk.ImposterProtoChunk) && !(current instanceof LevelChunk)) { -+ return CompletableFuture.completedFuture(ChunkHolder.UNLOADED_CHUNK); -+ } -+ // we know the chunk is at full status here (either in read-only mode or the real thing) -+ return this.bringToFullStatusAsync(x, z, chunkPos, isUrgent); -+ } -+ -+ // here we don't know what status it is and we're not supposed to generate -+ // so we asynchronously load empty status -+ return this.bringToStatusAsync(x, z, chunkPos, ChunkStatus.EMPTY, isUrgent).thenCompose((either) -> { -+ ChunkAccess chunk = either.left().orElse(null); -+ if (!(chunk instanceof net.minecraft.world.level.chunk.ImposterProtoChunk) && !(chunk instanceof LevelChunk)) { -+ // the chunk on disk was not a full status chunk -+ return CompletableFuture.completedFuture(ChunkHolder.UNLOADED_CHUNK); -+ } -+ // bring to full status if required -+ return this.bringToFullStatusAsync(x, z, chunkPos, isUrgent); + }); -+ } + -+ private CompletableFuture> bringToFullStatusAsync(int x, int z, ChunkPos chunkPos, boolean isUrgent) { -+ return this.bringToStatusAsync(x, z, chunkPos, ChunkStatus.FULL, isUrgent); -+ } -+ -+ private CompletableFuture> bringToStatusAsync(int x, int z, ChunkPos chunkPos, ChunkStatus status, boolean isUrgent) { -+ CompletableFuture> future = this.getChunkFutureMainThread(x, z, status, true, isUrgent); -+ Long identifier = Long.valueOf(this.asyncLoadSeqCounter++); -+ int ticketLevel = net.minecraft.server.MCUtil.getTicketLevelFor(status); -+ this.addTicketAtLevel(TicketType.ASYNC_LOAD, chunkPos, ticketLevel, identifier); -+ -+ return future.thenComposeAsync((Either either) -> { -+ // either left -> success -+ // either right -> failure -+ -+ this.removeTicketAtLevel(TicketType.ASYNC_LOAD, chunkPos, ticketLevel, identifier); -+ this.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, ticketLevel, chunkPos); // allow unloading -+ -+ Optional failure = either.right(); -+ -+ if (failure.isPresent()) { -+ // failure -+ throw new IllegalStateException("Chunk failed to load: " + failure.get().toString()); -+ } -+ -+ return CompletableFuture.completedFuture(either); -+ }, this.mainThreadProcessor); ++ return ret; + } + // Paper end - async chunk io @@ -2694,7 +2616,7 @@ index 514111ed7fe8aec0d5f15f7a8f157d5872a56e4f..3ff5e35e45a71dc03552dedb65c73383 if (Thread.currentThread() != this.mainThread) { return (ChunkAccess) CompletableFuture.supplyAsync(() -> { return this.getChunk(x, z, leastStatus, create); -@@ -334,13 +435,18 @@ public class ServerChunkCache extends ChunkSource { +@@ -414,13 +437,18 @@ public class ServerChunkCache extends ChunkSource { } gameprofilerfiller.incrementCounter("getChunkCacheMiss"); @@ -2714,7 +2636,7 @@ index 514111ed7fe8aec0d5f15f7a8f157d5872a56e4f..3ff5e35e45a71dc03552dedb65c73383 this.level.timings.syncChunkLoad.stopTiming(); // Paper } // Paper ichunkaccess = (ChunkAccess) ((Either) completablefuture.join()).map((ichunkaccess1) -> { -@@ -427,6 +533,11 @@ public class ServerChunkCache extends ChunkSource { +@@ -507,6 +535,11 @@ public class ServerChunkCache extends ChunkSource { } private CompletableFuture> getChunkFutureMainThread(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) { @@ -2726,7 +2648,7 @@ index 514111ed7fe8aec0d5f15f7a8f157d5872a56e4f..3ff5e35e45a71dc03552dedb65c73383 ChunkPos chunkcoordintpair = new ChunkPos(chunkX, chunkZ); long k = chunkcoordintpair.toLong(); int l = 33 + ChunkStatus.getDistance(leastStatus); -@@ -841,11 +952,12 @@ public class ServerChunkCache extends ChunkSource { +@@ -921,11 +954,12 @@ public class ServerChunkCache extends ChunkSource { // CraftBukkit start - process pending Chunk loadCallback() and unloadCallback() after each run task public boolean pollTask() { try { diff --git a/patches/server/0020-Implement-Chunk-Priority-Urgency-System-for-Chunks.patch b/patches/server/0020-Implement-Chunk-Priority-Urgency-System-for-Chunks.patch index 0f3896c16..b66f6bfe0 100644 --- a/patches/server/0020-Implement-Chunk-Priority-Urgency-System-for-Chunks.patch +++ b/patches/server/0020-Implement-Chunk-Priority-Urgency-System-for-Chunks.patch @@ -794,12 +794,12 @@ index 1d6ab658c48bb765f66624f276ec7b05cf33c1d5..b9b56068cdacd984f873cfb2a06a312e Ticket ticket = new Ticket<>(TicketType.FORCED, 31, pos); long i = pos.toLong(); diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 3ff5e35e45a71dc03552dedb65c7338317e9d0a9..2400212e65c72d3ce6604b3cf200db0ae7032f2a 100644 +index 07671ac54f598872dba2b22ec8f82db3dd037d7f..5057053bcd3fc205e62edd9519a9545c16ce60c7 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -407,6 +407,30 @@ public class ServerChunkCache extends ChunkSource { - return CompletableFuture.completedFuture(either); - }, this.mainThreadProcessor); +@@ -409,6 +409,30 @@ public class ServerChunkCache extends ChunkSource { + + return ret; } + + public boolean markUrgent(ChunkPos coords) { @@ -828,7 +828,7 @@ index 3ff5e35e45a71dc03552dedb65c7338317e9d0a9..2400212e65c72d3ce6604b3cf200db0a // Paper end - async chunk io @Nullable -@@ -441,6 +465,8 @@ public class ServerChunkCache extends ChunkSource { +@@ -443,6 +467,8 @@ public class ServerChunkCache extends ChunkSource { Objects.requireNonNull(completablefuture); if (!completablefuture.isDone()) { // Paper // Paper start - async chunk io/loading @@ -837,7 +837,7 @@ index 3ff5e35e45a71dc03552dedb65c7338317e9d0a9..2400212e65c72d3ce6604b3cf200db0a this.level.asyncChunkTaskManager.raisePriority(x1, z1, com.destroystokyo.paper.io.PrioritizedTaskQueue.HIGHEST_PRIORITY); com.destroystokyo.paper.io.chunk.ChunkTaskManager.pushChunkWait(this.level, x1, z1); // Paper end -@@ -448,6 +474,8 @@ public class ServerChunkCache extends ChunkSource { +@@ -450,6 +476,8 @@ public class ServerChunkCache extends ChunkSource { chunkproviderserver_b.managedBlock(completablefuture::isDone); com.destroystokyo.paper.io.chunk.ChunkTaskManager.popChunkWait(); // Paper - async chunk debug this.level.timings.syncChunkLoad.stopTiming(); // Paper @@ -846,7 +846,7 @@ index 3ff5e35e45a71dc03552dedb65c7338317e9d0a9..2400212e65c72d3ce6604b3cf200db0a } // Paper ichunkaccess = (ChunkAccess) ((Either) completablefuture.join()).map((ichunkaccess1) -> { return ichunkaccess1; -@@ -553,10 +581,12 @@ public class ServerChunkCache extends ChunkSource { +@@ -555,10 +583,12 @@ public class ServerChunkCache extends ChunkSource { if (create && !currentlyUnloading) { // CraftBukkit end this.distanceManager.addTicket(TicketType.UNKNOWN, chunkcoordintpair, l, chunkcoordintpair); @@ -859,7 +859,7 @@ index 3ff5e35e45a71dc03552dedb65c7338317e9d0a9..2400212e65c72d3ce6604b3cf200db0a this.runDistanceManagerUpdates(); playerchunk = this.getVisibleChunkIfPresent(k); gameprofilerfiller.pop(); -@@ -566,7 +596,13 @@ public class ServerChunkCache extends ChunkSource { +@@ -568,7 +598,13 @@ public class ServerChunkCache extends ChunkSource { } } @@ -874,7 +874,7 @@ index 3ff5e35e45a71dc03552dedb65c7338317e9d0a9..2400212e65c72d3ce6604b3cf200db0a } private boolean chunkAbsent(@Nullable ChunkHolder holder, int maxLevel) { -@@ -618,6 +654,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -620,6 +656,7 @@ public class ServerChunkCache extends ChunkSource { } public boolean runDistanceManagerUpdates() { diff --git a/patches/server/0177-PlayerNaturallySpawnCreaturesEvent.patch b/patches/server/0177-PlayerNaturallySpawnCreaturesEvent.patch index e702a822a..53ca338ef 100644 --- a/patches/server/0177-PlayerNaturallySpawnCreaturesEvent.patch +++ b/patches/server/0177-PlayerNaturallySpawnCreaturesEvent.patch @@ -40,10 +40,10 @@ index e086135936e4f6c109cd09a4e4df350702b3510a..09a2680162ed9f1d82830778fea6b05a return true; diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 2400212e65c72d3ce6604b3cf200db0ae7032f2a..f2775bc2c9137b7b81080f3113340923469bb46d 100644 +index 5057053bcd3fc205e62edd9519a9545c16ce60c7..d1fa959b6e872565b689ee6b4f1bed9ad9e4077e 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -784,6 +784,15 @@ public class ServerChunkCache extends ChunkSource { +@@ -786,6 +786,15 @@ public class ServerChunkCache extends ChunkSource { boolean flag2 = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.players().isEmpty(); // CraftBukkit Collections.shuffle(list); diff --git a/patches/server/0361-implement-optional-per-player-mob-spawns.patch b/patches/server/0361-implement-optional-per-player-mob-spawns.patch index 804ad3cc5..7aa2416dd 100644 --- a/patches/server/0361-implement-optional-per-player-mob-spawns.patch +++ b/patches/server/0361-implement-optional-per-player-mob-spawns.patch @@ -352,10 +352,10 @@ index b9b56068cdacd984f873cfb2a06a312e9912893d..9309ea89a440606be3e56ef634f5048a this.naturalSpawnChunkCounter.runAllUpdates(); return this.naturalSpawnChunkCounter.chunks.size(); diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index f2775bc2c9137b7b81080f3113340923469bb46d..cd3de4cd1a38c5092f6a88de4fa33d6dda7f3445 100644 +index d1fa959b6e872565b689ee6b4f1bed9ad9e4077e..f982241898c4aeaf50854e67fe188478f2f2b186 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -762,7 +762,18 @@ public class ServerChunkCache extends ChunkSource { +@@ -764,7 +764,18 @@ public class ServerChunkCache extends ChunkSource { gameprofilerfiller.push("naturalSpawnCount"); this.level.timings.countNaturalMobs.startTiming(); // Paper - timings int l = this.distanceManager.getNaturalSpawnChunkCount(); diff --git a/patches/server/0364-Optimise-getChunkAt-calls-for-loaded-chunks.patch b/patches/server/0364-Optimise-getChunkAt-calls-for-loaded-chunks.patch index 080f8f5b6..2211c9793 100644 --- a/patches/server/0364-Optimise-getChunkAt-calls-for-loaded-chunks.patch +++ b/patches/server/0364-Optimise-getChunkAt-calls-for-loaded-chunks.patch @@ -7,10 +7,10 @@ bypass the need to get a player chunk, then get the either, then unwrap it... diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index cd3de4cd1a38c5092f6a88de4fa33d6dda7f3445..9ef4a8dee2af8d76e5d2c27ff3490a394b9afd59 100644 +index f982241898c4aeaf50854e67fe188478f2f2b186..38788e0ab7e881102d38bae53ba9d2d4f62b99d4 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -442,6 +442,12 @@ public class ServerChunkCache extends ChunkSource { +@@ -444,6 +444,12 @@ public class ServerChunkCache extends ChunkSource { return this.getChunk(x, z, leastStatus, create); }, this.mainThreadProcessor).join(); } else { @@ -23,7 +23,7 @@ index cd3de4cd1a38c5092f6a88de4fa33d6dda7f3445..9ef4a8dee2af8d76e5d2c27ff3490a39 ProfilerFiller gameprofilerfiller = this.level.getProfiler(); gameprofilerfiller.incrementCounter("getChunk"); -@@ -497,39 +503,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -499,39 +505,7 @@ public class ServerChunkCache extends ChunkSource { if (Thread.currentThread() != this.mainThread) { return null; } else { diff --git a/patches/server/0365-Add-debug-for-sync-chunk-loads.patch b/patches/server/0365-Add-debug-for-sync-chunk-loads.patch index 4657aa35a..909d9b70a 100644 --- a/patches/server/0365-Add-debug-for-sync-chunk-loads.patch +++ b/patches/server/0365-Add-debug-for-sync-chunk-loads.patch @@ -298,10 +298,10 @@ index 0000000000000000000000000000000000000000..1120aef5b0dd983c467167f77245884e + } +} diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 9ef4a8dee2af8d76e5d2c27ff3490a394b9afd59..d97b50a7a71b8bb8dcaab35ae5f03314ad6acf7e 100644 +index 38788e0ab7e881102d38bae53ba9d2d4f62b99d4..471cc00c677b6581ba84c8cac25d2246c2a14bc9 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -476,6 +476,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -478,6 +478,7 @@ public class ServerChunkCache extends ChunkSource { this.level.asyncChunkTaskManager.raisePriority(x1, z1, com.destroystokyo.paper.io.PrioritizedTaskQueue.HIGHEST_PRIORITY); com.destroystokyo.paper.io.chunk.ChunkTaskManager.pushChunkWait(this.level, x1, z1); // Paper end diff --git a/patches/server/0398-Fix-Chunk-Post-Processing-deadlock-risk.patch b/patches/server/0398-Fix-Chunk-Post-Processing-deadlock-risk.patch index 91616ec7a..13219b5e5 100644 --- a/patches/server/0398-Fix-Chunk-Post-Processing-deadlock-risk.patch +++ b/patches/server/0398-Fix-Chunk-Post-Processing-deadlock-risk.patch @@ -60,10 +60,10 @@ index fcc9dd6e1c54e4ca16102150aa4c12ecc7de06df..aed3da6ef2d498d3f1c9c64177bf1ba6 completablefuture1.thenAcceptAsync((either) -> { either.ifLeft((chunk) -> { diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index d97b50a7a71b8bb8dcaab35ae5f03314ad6acf7e..a986051dead41f1a9f70e5e00572255e9939c4a9 100644 +index 471cc00c677b6581ba84c8cac25d2246c2a14bc9..497827822a64eeff2a4901f0e7c62f0f2c359b48 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -992,6 +992,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -994,6 +994,7 @@ public class ServerChunkCache extends ChunkSource { return super.pollTask() || execChunkTask; // Paper } } finally { diff --git a/patches/server/0428-Optimize-anyPlayerCloseEnoughForSpawning-to-use-dist.patch b/patches/server/0428-Optimize-anyPlayerCloseEnoughForSpawning-to-use-dist.patch index 3923c737d..643380032 100644 --- a/patches/server/0428-Optimize-anyPlayerCloseEnoughForSpawning-to-use-dist.patch +++ b/patches/server/0428-Optimize-anyPlayerCloseEnoughForSpawning-to-use-dist.patch @@ -268,10 +268,10 @@ index f456ba4bf699e1f6bd15726a037a0047b6ca7380..b2df5e18ce5260a9781052db7afb0b97 public String getDebugStatus() { diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index a986051dead41f1a9f70e5e00572255e9939c4a9..70c5e151d47217d417b91105ac63f17a2eb957bf 100644 +index 497827822a64eeff2a4901f0e7c62f0f2c359b48..a59782d6f3640262c377a676e2b2ef5ec82563db 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -727,6 +727,37 @@ public class ServerChunkCache extends ChunkSource { +@@ -729,6 +729,37 @@ public class ServerChunkCache extends ChunkSource { if (flag) { this.chunkMap.tick(); } else { @@ -309,7 +309,7 @@ index a986051dead41f1a9f70e5e00572255e9939c4a9..70c5e151d47217d417b91105ac63f17a LevelData worlddata = this.level.getLevelData(); ProfilerFiller gameprofilerfiller = this.level.getProfiler(); -@@ -770,15 +801,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -772,15 +803,7 @@ public class ServerChunkCache extends ChunkSource { boolean flag2 = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.players().isEmpty(); // CraftBukkit Collections.shuffle(list); @@ -326,7 +326,7 @@ index a986051dead41f1a9f70e5e00572255e9939c4a9..70c5e151d47217d417b91105ac63f17a Iterator iterator1 = list.iterator(); while (iterator1.hasNext()) { -@@ -786,9 +809,9 @@ public class ServerChunkCache extends ChunkSource { +@@ -788,9 +811,9 @@ public class ServerChunkCache extends ChunkSource { LevelChunk chunk1 = chunkproviderserver_a.chunk; ChunkPos chunkcoordintpair = chunk1.getPos(); diff --git a/patches/server/0451-incremental-chunk-and-player-saving.patch b/patches/server/0451-incremental-chunk-and-player-saving.patch index e993eebc4..8c38af4a6 100644 --- a/patches/server/0451-incremental-chunk-and-player-saving.patch +++ b/patches/server/0451-incremental-chunk-and-player-saving.patch @@ -235,10 +235,10 @@ index b0e0f85e04438affb8d8e0f75055ea83d0c03bcd..7493da0f1c3f8ab0ebc517347ef23fbe ChunkPos chunkcoordintpair = chunk.getPos(); diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 70c5e151d47217d417b91105ac63f17a2eb957bf..15b275ee91451478d1c55eae0d20e0e8f36f3a0f 100644 +index a59782d6f3640262c377a676e2b2ef5ec82563db..b5f46703e536f8138ff4e6769485c45b35941f9f 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -668,6 +668,15 @@ public class ServerChunkCache extends ChunkSource { +@@ -670,6 +670,15 @@ public class ServerChunkCache extends ChunkSource { } // Paper - Timings } diff --git a/patches/server/0721-Do-not-allow-the-server-to-unload-chunks-at-request-.patch b/patches/server/0721-Do-not-allow-the-server-to-unload-chunks-at-request-.patch index f8339eb67..ce98eec58 100644 --- a/patches/server/0721-Do-not-allow-the-server-to-unload-chunks-at-request-.patch +++ b/patches/server/0721-Do-not-allow-the-server-to-unload-chunks-at-request-.patch @@ -10,10 +10,10 @@ to be unloaded will simply be unloaded next tick, rather than immediately. diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 15b275ee91451478d1c55eae0d20e0e8f36f3a0f..dd4656f0b9d7740ab449ede2588df64e647fab40 100644 +index b5f46703e536f8138ff4e6769485c45b35941f9f..f3ab1691948c46477888776d28791ce24e7aa93d 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -694,6 +694,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -696,6 +696,7 @@ public class ServerChunkCache extends ChunkSource { // CraftBukkit start - modelled on below public void purgeUnload() { diff --git a/patches/server/0726-Do-not-allow-ticket-level-changes-while-unloading-pl.patch b/patches/server/0726-Do-not-allow-ticket-level-changes-while-unloading-pl.patch index 853e534c5..302867667 100644 --- a/patches/server/0726-Do-not-allow-ticket-level-changes-while-unloading-pl.patch +++ b/patches/server/0726-Do-not-allow-ticket-level-changes-while-unloading-pl.patch @@ -49,10 +49,10 @@ index a3fceb2608b3be80941dfe2570999b270429e0c6..b34c90497a5492c289839ba74df9f2f2 } }; diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index dd4656f0b9d7740ab449ede2588df64e647fab40..3e45d0c1a95cf8124d15ff4851ea1dcf063f440d 100644 +index f3ab1691948c46477888776d28791ce24e7aa93d..29ba8971ceffbac68290f6063a69c98065e9bcba 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -630,6 +630,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -632,6 +632,7 @@ public class ServerChunkCache extends ChunkSource { public boolean runDistanceManagerUpdates() { if (distanceManager.delayDistanceManagerTick) return false; // Paper - Chunk priority diff --git a/patches/server/0730-Prevent-unload-calls-removing-tickets-for-sync-loads.patch b/patches/server/0730-Prevent-unload-calls-removing-tickets-for-sync-loads.patch index 5c819b2c6..516b5b8e0 100644 --- a/patches/server/0730-Prevent-unload-calls-removing-tickets-for-sync-loads.patch +++ b/patches/server/0730-Prevent-unload-calls-removing-tickets-for-sync-loads.patch @@ -18,10 +18,10 @@ index b2df5e18ce5260a9781052db7afb0b9786fb887c..537d34a0325a985948c744929b90144a while (objectiterator.hasNext()) { diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 3e45d0c1a95cf8124d15ff4851ea1dcf063f440d..9f7ec687e6cf971bb9699e9f4ad7ebe37a3ef882 100644 +index 29ba8971ceffbac68290f6063a69c98065e9bcba..2390fcbc1b21653b1753a58da33f936cec43d0cb 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -535,6 +535,8 @@ public class ServerChunkCache extends ChunkSource { +@@ -537,6 +537,8 @@ public class ServerChunkCache extends ChunkSource { return completablefuture; } @@ -30,7 +30,7 @@ index 3e45d0c1a95cf8124d15ff4851ea1dcf063f440d..9f7ec687e6cf971bb9699e9f4ad7ebe3 private CompletableFuture> getChunkFutureMainThread(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) { // Paper start - add isUrgent - old sig left in place for dirty nms plugins return getChunkFutureMainThread(chunkX, chunkZ, leastStatus, create, false); -@@ -553,9 +555,12 @@ public class ServerChunkCache extends ChunkSource { +@@ -555,9 +557,12 @@ public class ServerChunkCache extends ChunkSource { ChunkHolder.FullChunkStatus currentChunkState = ChunkHolder.getFullChunkStatus(playerchunk.getTicketLevel()); currentlyUnloading = (oldChunkState.isOrAfter(ChunkHolder.FullChunkStatus.BORDER) && !currentChunkState.isOrAfter(ChunkHolder.FullChunkStatus.BORDER)); } @@ -43,7 +43,7 @@ index 3e45d0c1a95cf8124d15ff4851ea1dcf063f440d..9f7ec687e6cf971bb9699e9f4ad7ebe3 if (isUrgent) this.distanceManager.markUrgent(chunkcoordintpair); // Paper - Chunk priority if (this.chunkAbsent(playerchunk, l)) { ProfilerFiller gameprofilerfiller = this.level.getProfiler(); -@@ -566,13 +571,21 @@ public class ServerChunkCache extends ChunkSource { +@@ -568,13 +573,21 @@ public class ServerChunkCache extends ChunkSource { playerchunk = this.getVisibleChunkIfPresent(k); gameprofilerfiller.pop(); if (this.chunkAbsent(playerchunk, l)) { diff --git a/patches/server/0736-Optimise-chunk-tick-iteration.patch b/patches/server/0736-Optimise-chunk-tick-iteration.patch index 13c8c2412..dff38c5fd 100644 --- a/patches/server/0736-Optimise-chunk-tick-iteration.patch +++ b/patches/server/0736-Optimise-chunk-tick-iteration.patch @@ -84,7 +84,7 @@ index b34c90497a5492c289839ba74df9f2f27e29370e..e811c7d617b8c9cc684bc0a58a98d5ec // CraftBukkit start - recursion-safe executor for Chunk loadCallback() and unloadCallback() public final CallbackExecutor callbackExecutor = new CallbackExecutor(); diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 9f7ec687e6cf971bb9699e9f4ad7ebe37a3ef882..e585d0047f1dbafeb2bcacf19bd38f3d4b9ab53e 100644 +index 2390fcbc1b21653b1753a58da33f936cec43d0cb..7b1279256ed7963ba4e225b15592816087ab16b4 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -47,6 +47,7 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemp @@ -95,7 +95,7 @@ index 9f7ec687e6cf971bb9699e9f4ad7ebe37a3ef882..e585d0047f1dbafeb2bcacf19bd38f3d public class ServerChunkCache extends ChunkSource { -@@ -808,34 +809,42 @@ public class ServerChunkCache extends ChunkSource { +@@ -810,34 +811,42 @@ public class ServerChunkCache extends ChunkSource { this.lastSpawnState = spawnercreature_d; gameprofilerfiller.popPush("filteringLoadedChunks"); @@ -154,7 +154,7 @@ index 9f7ec687e6cf971bb9699e9f4ad7ebe37a3ef882..e585d0047f1dbafeb2bcacf19bd38f3d NaturalSpawner.spawnForChunk(this.level, chunk1, spawnercreature_d, this.spawnFriendlies, this.spawnEnemies, flag1); } -@@ -843,7 +852,16 @@ public class ServerChunkCache extends ChunkSource { +@@ -845,7 +854,16 @@ public class ServerChunkCache extends ChunkSource { this.level.tickChunk(chunk1, k); } } @@ -171,7 +171,7 @@ index 9f7ec687e6cf971bb9699e9f4ad7ebe37a3ef882..e585d0047f1dbafeb2bcacf19bd38f3d this.level.timings.chunkTicks.stopTiming(); // Paper gameprofilerfiller.popPush("customSpawners"); if (flag2) { -@@ -851,15 +869,24 @@ public class ServerChunkCache extends ChunkSource { +@@ -853,15 +871,24 @@ public class ServerChunkCache extends ChunkSource { this.level.tickCustomSpawners(this.spawnEnemies, this.spawnFriendlies); } // Paper - timings } diff --git a/patches/server/0737-Execute-chunk-tasks-mid-tick.patch b/patches/server/0737-Execute-chunk-tasks-mid-tick.patch index 90d5f94f2..99a96923d 100644 --- a/patches/server/0737-Execute-chunk-tasks-mid-tick.patch +++ b/patches/server/0737-Execute-chunk-tasks-mid-tick.patch @@ -106,10 +106,10 @@ index 98fe4165d291b47a39ce741884353c87dd0a4789..99073ea2757cd1c15b098d7cfaf86817 + // Paper end - execute chunk tasks mid tick } diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index e585d0047f1dbafeb2bcacf19bd38f3d4b9ab53e..5ef0ddad4a129b53e3102f177f31f28d5f4cf455 100644 +index 7b1279256ed7963ba4e225b15592816087ab16b4..1510e1fcfbbb2ccbaf57dd274bed05afc85eeeb0 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -833,6 +833,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -835,6 +835,7 @@ public class ServerChunkCache extends ChunkSource { iterator1 = shuffled.iterator(); } @@ -117,7 +117,7 @@ index e585d0047f1dbafeb2bcacf19bd38f3d4b9ab53e..5ef0ddad4a129b53e3102f177f31f28d try { while (iterator1.hasNext()) { LevelChunk chunk1 = iterator1.next(); -@@ -850,6 +851,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -852,6 +853,7 @@ public class ServerChunkCache extends ChunkSource { if (this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) { this.level.tickChunk(chunk1, k); diff --git a/patches/server/0742-Distance-manager-tick-timings.patch b/patches/server/0742-Distance-manager-tick-timings.patch index 411ac8167..dd5f5f23b 100644 --- a/patches/server/0742-Distance-manager-tick-timings.patch +++ b/patches/server/0742-Distance-manager-tick-timings.patch @@ -19,10 +19,10 @@ index 5ec241d49ff5e3a161a39006f05823a5de847c5e..435b3b6d05e00803386d123c66f961c9 public static final Timing midTickChunkTasks = Timings.ofSafe("Mid Tick Chunk Tasks"); diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 5ef0ddad4a129b53e3102f177f31f28d5f4cf455..5aa5e951f7827e81d370825f0ac8afd78f482955 100644 +index 1510e1fcfbbb2ccbaf57dd274bed05afc85eeeb0..98e279e5330b45d0587d1afebddaf876e9802e33 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -645,6 +645,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -647,6 +647,7 @@ public class ServerChunkCache extends ChunkSource { public boolean runDistanceManagerUpdates() { if (distanceManager.delayDistanceManagerTick) return false; // Paper - Chunk priority if (this.chunkMap.unloadingPlayerChunk) { LOGGER.error("Cannot tick distance manager while unloading playerchunks", new Throwable()); throw new IllegalStateException("Cannot tick distance manager while unloading playerchunks"); } // Paper @@ -30,7 +30,7 @@ index 5ef0ddad4a129b53e3102f177f31f28d5f4cf455..5aa5e951f7827e81d370825f0ac8afd7 boolean flag = this.distanceManager.runAllUpdates(this.chunkMap); boolean flag1 = this.chunkMap.promoteChunkMap(); -@@ -654,6 +655,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -656,6 +657,7 @@ public class ServerChunkCache extends ChunkSource { this.clearCache(); return true; } diff --git a/patches/server/0748-Consolidate-flush-calls-for-entity-tracker-packets.patch b/patches/server/0748-Consolidate-flush-calls-for-entity-tracker-packets.patch index 8ff310e93..5b23522f4 100644 --- a/patches/server/0748-Consolidate-flush-calls-for-entity-tracker-packets.patch +++ b/patches/server/0748-Consolidate-flush-calls-for-entity-tracker-packets.patch @@ -22,10 +22,10 @@ With this change I could get all 200 on at 0ms ping. So in general this patch should reduce Netty I/O thread load. diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 5aa5e951f7827e81d370825f0ac8afd78f482955..3b549ac6d07484a09dc6521cb4f3ab3b3cc979e9 100644 +index 98e279e5330b45d0587d1afebddaf876e9802e33..4c82f17313e18c9dfd9b28653715b8a3242b826c 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -891,7 +891,24 @@ public class ServerChunkCache extends ChunkSource { +@@ -893,7 +893,24 @@ public class ServerChunkCache extends ChunkSource { this.level.timings.broadcastChunkUpdates.stopTiming(); // Paper - timing gameprofilerfiller.pop(); // Paper end - use set of chunks requiring updates, rather than iterating every single one loaded diff --git a/patches/server/0854-Replace-player-chunk-loader-system.patch b/patches/server/0854-Replace-player-chunk-loader-system.patch index 84d8c4242..14f333711 100644 --- a/patches/server/0854-Replace-player-chunk-loader-system.patch +++ b/patches/server/0854-Replace-player-chunk-loader-system.patch @@ -1797,10 +1797,10 @@ index f581a9f79b2357118d912a15344ff94df3b0c50e..d1b5c25b7455174e908cd6ed66789fa7 + */ // Paper - replace old loader system } diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 3b549ac6d07484a09dc6521cb4f3ab3b3cc979e9..ea1b8f4fd49678f39b1036ae6be880bacc6997f8 100644 +index 4c82f17313e18c9dfd9b28653715b8a3242b826c..efcb80efc69a1e5ffc81b579bf535fd94e8144d7 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -665,17 +665,10 @@ public class ServerChunkCache extends ChunkSource { +@@ -667,17 +667,10 @@ public class ServerChunkCache extends ChunkSource { // Paper end public boolean isPositionTicking(long pos) { @@ -1822,7 +1822,7 @@ index 3b549ac6d07484a09dc6521cb4f3ab3b3cc979e9..ea1b8f4fd49678f39b1036ae6be880ba } public void save(boolean flush) { -@@ -732,6 +725,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -734,6 +727,7 @@ public class ServerChunkCache extends ChunkSource { this.level.getProfiler().popPush("chunks"); if (tickChunks) { this.level.timings.chunks.startTiming(); // Paper - timings @@ -1830,7 +1830,7 @@ index 3b549ac6d07484a09dc6521cb4f3ab3b3cc979e9..ea1b8f4fd49678f39b1036ae6be880ba this.tickChunks(); this.level.timings.chunks.stopTiming(); // Paper - timings } -@@ -845,13 +839,13 @@ public class ServerChunkCache extends ChunkSource { +@@ -847,13 +841,13 @@ public class ServerChunkCache extends ChunkSource { // Paper end - optimise chunk tick iteration ChunkPos chunkcoordintpair = chunk1.getPos(); @@ -1846,7 +1846,7 @@ index 3b549ac6d07484a09dc6521cb4f3ab3b3cc979e9..ea1b8f4fd49678f39b1036ae6be880ba this.level.tickChunk(chunk1, k); if ((chunksTicked++ & 1) == 0) net.minecraft.server.MinecraftServer.getServer().executeMidTickTasks(); // Paper } -@@ -1080,6 +1074,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -1082,6 +1076,7 @@ public class ServerChunkCache extends ChunkSource { public boolean pollTask() { try { boolean execChunkTask = com.destroystokyo.paper.io.chunk.ChunkTaskManager.pollChunkWaitQueue() || ServerChunkCache.this.level.asyncChunkTaskManager.pollNextChunkTask(); // Paper