Re-add legacy getChunkAtAsynchronously to ChunkProviderServer

Apparently some plugins use it
This commit is contained in:
Spottedleaf 2022-09-02 04:41:08 -07:00
parent e8c2c3bfda
commit 09904fd780
19 changed files with 159 additions and 157 deletions

View File

@ -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 {
}
}

View File

@ -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())) {

View File

@ -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;
+ CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> 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<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 {

View File

@ -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() {

View File

@ -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);

View File

@ -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();

View File

@ -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 {

View File

@ -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

View File

@ -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 {

View File

@ -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();

View File

@ -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
}

View File

@ -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() {

View File

@ -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

View File

@ -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)) {

View File

@ -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
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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