aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorSpottedleaf <[email protected]>2022-09-02 04:41:08 -0700
committerSpottedleaf <[email protected]>2022-09-02 04:42:05 -0700
commit09904fd780175821a43adf74cc5a00d363e4a83d (patch)
tree07ea6e4388350a0e17e1a4334cc1eb449522a451
parente8c2c3bfda97143e33dbd35bd9dee528bb51d93c (diff)
downloadPaper-09904fd780175821a43adf74cc5a00d363e4a83d.tar.gz
Paper-09904fd780175821a43adf74cc5a00d363e4a83d.zip
Re-add legacy getChunkAtAsynchronously to ChunkProviderServer
Apparently some plugins use it
-rw-r--r--patches/server/0008-MC-Utils.patch88
-rw-r--r--patches/server/0012-Timings-v2.patch12
-rw-r--r--patches/server/0019-Asynchronous-chunk-IO-and-loading.patch112
-rw-r--r--patches/server/0020-Implement-Chunk-Priority-Urgency-System-for-Chunks.patch18
-rw-r--r--patches/server/0177-PlayerNaturallySpawnCreaturesEvent.patch4
-rw-r--r--patches/server/0361-implement-optional-per-player-mob-spawns.patch4
-rw-r--r--patches/server/0364-Optimise-getChunkAt-calls-for-loaded-chunks.patch6
-rw-r--r--patches/server/0365-Add-debug-for-sync-chunk-loads.patch4
-rw-r--r--patches/server/0398-Fix-Chunk-Post-Processing-deadlock-risk.patch4
-rw-r--r--patches/server/0428-Optimize-anyPlayerCloseEnoughForSpawning-to-use-dist.patch8
-rw-r--r--patches/server/0451-incremental-chunk-and-player-saving.patch4
-rw-r--r--patches/server/0721-Do-not-allow-the-server-to-unload-chunks-at-request-.patch4
-rw-r--r--patches/server/0726-Do-not-allow-ticket-level-changes-while-unloading-pl.patch4
-rw-r--r--patches/server/0730-Prevent-unload-calls-removing-tickets-for-sync-loads.patch8
-rw-r--r--patches/server/0736-Optimise-chunk-tick-iteration.patch8
-rw-r--r--patches/server/0737-Execute-chunk-tasks-mid-tick.patch6
-rw-r--r--patches/server/0742-Distance-manager-tick-timings.patch6
-rw-r--r--patches/server/0748-Consolidate-flush-calls-for-entity-tracker-packets.patch4
-rw-r--r--patches/server/0854-Replace-player-chunk-loader-system.patch10
19 files changed, 158 insertions, 156 deletions
diff --git a/patches/server/0008-MC-Utils.patch b/patches/server/0008-MC-Utils.patch
index 2d9248eb2a..23e7f4e394 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<ChunkStatus> 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<ChunkAccess> 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<ChunkAccess> 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<ChunkAccess> 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<DimensionDataStorage> 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 71da852f12..3795c7882e 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 cf7bd1b0ad..7f5e87c2ae 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<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> getChunkAtAsynchronously(int x, int z, boolean gen, boolean isUrgent) {
-+ if (Thread.currentThread() != this.mainThread) {
-+ CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> future = new CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>>();
-+ this.mainThreadProcessor.execute(() -> {
-+ this.getChunkAtAsynchronously(x, z, gen, isUrgent).whenComplete((chunk, ex) -> {
-+ if (ex != null) {
-+ future.completeExceptionally(ex);
-+ } else {
-+ future.complete(chunk);
-+ }
-+ });
-+ });
-+ return future;
-+ }
-+
-+ 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));
-+ }
-+ }
-+ }
-+
-+ if (gen) {
-+ return this.bringToFullStatusAsync(x, z, chunkPos, isUrgent);
-+ }
++ CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> ret = new CompletableFuture<>();
+
-+ 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);
++ 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;
+ }
+
-+ // 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);
++ 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));
+ }
-+ // bring to full status if required
-+ return this.bringToFullStatusAsync(x, z, chunkPos, isUrgent);
+ });
-+ }
-+
-+ private CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> bringToFullStatusAsync(int x, int z, ChunkPos chunkPos, boolean isUrgent) {
-+ return this.bringToStatusAsync(x, z, chunkPos, ChunkStatus.FULL, isUrgent);
-+ }
-+
-+ private CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> bringToStatusAsync(int x, int z, ChunkPos chunkPos, ChunkStatus status, boolean isUrgent) {
-+ CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> 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<ChunkAccess, ChunkHolder.ChunkLoadingFailure> 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<ChunkHolder.ChunkLoadingFailure> 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<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> 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 0f3896c168..b66f6bfe09 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<ChunkPos> 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 e702a822a8..53ca338ef3 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 804ad3cc57..7aa2416ddc 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 080f8f5b61..2211c9793e 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 4657aa35a9..909d9b70a6 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 91616ec7ae..13219b5e56 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 3923c737df..643380032b 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 e993eebc44..8c38af4a69 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 f8339eb67a..ce98eec585 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 853e534c5c..302867667a 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 5c819b2c69..516b5b8e0c 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<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> 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 13c8c24128..dff38c5fda 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 90d5f94f2f..99a96923d9 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 411ac81671..dd5f5f23b7 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 8ff310e939..5b23522f42 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 84d8c4242a..14f3337119 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