Ensure priority updates are determined by current level, not deferred level (#6507)
* Ensure priority updates are determined by current level, not deferred level Deferral could cause an infinite loop to occur. Also, re-add the light engine priority logic. * Rebase Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>
Dieser Commit ist enthalten in:
Ursprung
159112ef41
Commit
1c4f87a258
@ -80,7 +80,7 @@ index 2d5b8e35d52b0dfd075af81a3a936d8a21053b31..9ddedd310eb0323a5a09f51a61bfb7b3
|
||||
chunkData.addProperty("queued-for-unload", chunkMap.toDrop.contains(playerChunk.pos.longKey));
|
||||
chunkData.addProperty("status", status == null ? "unloaded" : status.toString());
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
index 8245e07f6ecfd9dd997c8525b52c6eadd392e6f1..a0334dde56829fd895323f4cab2ab55d5d5ecf30 100644
|
||||
index 8245e07f6ecfd9dd997c8525b52c6eadd392e6f1..75fbcc3d9b3aca2738df0c7ce8c1a0b157ff375a 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
@@ -60,7 +60,7 @@ public class ChunkHolder {
|
||||
@ -100,7 +100,7 @@ index 8245e07f6ecfd9dd997c8525b52c6eadd392e6f1..a0334dde56829fd895323f4cab2ab55d
|
||||
// Paper start - no-tick view distance
|
||||
public final LevelChunk getSendingChunk() {
|
||||
// it's important that we use getChunkAtIfLoadedImmediately to mirror the chunk sending logic used
|
||||
@@ -100,6 +101,134 @@ public class ChunkHolder {
|
||||
@@ -100,6 +101,136 @@ public class ChunkHolder {
|
||||
}
|
||||
// Paper end
|
||||
|
||||
@ -109,6 +109,7 @@ index 8245e07f6ecfd9dd997c8525b52c6eadd392e6f1..a0334dde56829fd895323f4cab2ab55d
|
||||
+ volatile int priorityBoost = 0;
|
||||
+ public final java.util.concurrent.ConcurrentHashMap<ChunkHolder, ChunkStatus> neighbors = new java.util.concurrent.ConcurrentHashMap<>();
|
||||
+ public final it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<Integer> neighborPriorities = new it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<>();
|
||||
+ int requestedPriority = ChunkMap.MAX_CHUNK_DISTANCE + 1; // this priority is possible pending, but is used to ensure needless updates are not queued
|
||||
+
|
||||
+ private int getDemandedPriority() {
|
||||
+ int priority = neighborPriority; // if we have a neighbor priority, use it
|
||||
@ -170,8 +171,9 @@ index 8245e07f6ecfd9dd997c8525b52c6eadd392e6f1..a0334dde56829fd895323f4cab2ab55d
|
||||
+
|
||||
+ private void setNeighborPriority(ChunkHolder requester, int priority) {
|
||||
+ synchronized (neighborPriorities) {
|
||||
+ neighborPriorities.put(requester.pos.toLong(), Integer.valueOf(priority));
|
||||
+ recalcNeighborPriority();
|
||||
+ if (!Integer.valueOf(priority).equals(neighborPriorities.put(requester.pos.toLong(), Integer.valueOf(priority)))) {
|
||||
+ recalcNeighborPriority();
|
||||
+ }
|
||||
+ }
|
||||
+ checkPriority();
|
||||
+ }
|
||||
@ -189,7 +191,7 @@ index 8245e07f6ecfd9dd997c8525b52c6eadd392e6f1..a0334dde56829fd895323f4cab2ab55d
|
||||
+ }
|
||||
+ }
|
||||
+ private void checkPriority() {
|
||||
+ if (queueLevel != getDemandedPriority()) this.chunkMap.queueHolderUpdate(this);
|
||||
+ if (this.requestedPriority != getDemandedPriority()) this.chunkMap.queueHolderUpdate(this);
|
||||
+ }
|
||||
+
|
||||
+ public final double getDistance(ServerPlayer player) {
|
||||
@ -235,7 +237,7 @@ index 8245e07f6ecfd9dd997c8525b52c6eadd392e6f1..a0334dde56829fd895323f4cab2ab55d
|
||||
// Paper start - optimise isOutsideOfRange
|
||||
// cached here to avoid a map lookup
|
||||
com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> playersInMobSpawnRange;
|
||||
@@ -470,12 +599,25 @@ public class ChunkHolder {
|
||||
@@ -470,12 +601,25 @@ public class ChunkHolder {
|
||||
});
|
||||
}
|
||||
|
||||
@ -261,7 +263,7 @@ index 8245e07f6ecfd9dd997c8525b52c6eadd392e6f1..a0334dde56829fd895323f4cab2ab55d
|
||||
ChunkStatus chunkstatus = ChunkHolder.getStatus(this.oldTicketLevel);
|
||||
ChunkStatus chunkstatus1 = ChunkHolder.getStatus(this.ticketLevel);
|
||||
boolean flag = this.oldTicketLevel <= ChunkMap.MAX_CHUNK_DISTANCE;
|
||||
@@ -486,9 +628,22 @@ public class ChunkHolder {
|
||||
@@ -486,9 +630,22 @@ public class ChunkHolder {
|
||||
// ChunkUnloadEvent: Called before the chunk is unloaded: isChunkLoaded is still true and chunk can still be modified by plugins.
|
||||
if (playerchunk_state.isOrAfter(ChunkHolder.FullChunkStatus.BORDER) && !playerchunk_state1.isOrAfter(ChunkHolder.FullChunkStatus.BORDER)) {
|
||||
this.getFutureIfPresentUnchecked(ChunkStatus.FULL).thenAccept((either) -> {
|
||||
@ -285,7 +287,7 @@ index 8245e07f6ecfd9dd997c8525b52c6eadd392e6f1..a0334dde56829fd895323f4cab2ab55d
|
||||
// Minecraft will apply the chunks tick lists to the world once the chunk got loaded, and then store the tick
|
||||
// lists again inside the chunk once the chunk becomes inaccessible and set the chunk's needsSaving flag.
|
||||
// These actions may however happen deferred, so we manually set the needsSaving flag already here.
|
||||
@@ -545,12 +700,14 @@ public class ChunkHolder {
|
||||
@@ -545,12 +702,14 @@ public class ChunkHolder {
|
||||
this.scheduleFullChunkPromotion(chunkStorage, this.fullChunkFuture, executor, ChunkHolder.FullChunkStatus.BORDER);
|
||||
// Paper start - cache ticking ready status
|
||||
this.fullChunkFuture.thenAccept(either -> {
|
||||
@ -300,7 +302,7 @@ index 8245e07f6ecfd9dd997c8525b52c6eadd392e6f1..a0334dde56829fd895323f4cab2ab55d
|
||||
}
|
||||
});
|
||||
this.updateChunkToSave(this.fullChunkFuture, "full");
|
||||
@@ -575,6 +732,7 @@ public class ChunkHolder {
|
||||
@@ -575,6 +734,7 @@ public class ChunkHolder {
|
||||
this.scheduleFullChunkPromotion(chunkStorage, this.tickingChunkFuture, executor, ChunkHolder.FullChunkStatus.TICKING);
|
||||
// Paper start - cache ticking ready status
|
||||
this.tickingChunkFuture.thenAccept(either -> {
|
||||
@ -308,7 +310,7 @@ index 8245e07f6ecfd9dd997c8525b52c6eadd392e6f1..a0334dde56829fd895323f4cab2ab55d
|
||||
either.ifLeft(chunk -> {
|
||||
// note: Here is a very good place to add callbacks to logic waiting on this.
|
||||
ChunkHolder.this.isTickingReady = true;
|
||||
@@ -607,6 +765,7 @@ public class ChunkHolder {
|
||||
@@ -607,6 +767,7 @@ public class ChunkHolder {
|
||||
this.scheduleFullChunkPromotion(chunkStorage, this.entityTickingChunkFuture, executor, ChunkHolder.FullChunkStatus.ENTITY_TICKING);
|
||||
// Paper start - cache ticking ready status
|
||||
this.entityTickingChunkFuture.thenAccept(either -> {
|
||||
@ -316,7 +318,7 @@ index 8245e07f6ecfd9dd997c8525b52c6eadd392e6f1..a0334dde56829fd895323f4cab2ab55d
|
||||
either.ifLeft(chunk -> {
|
||||
ChunkHolder.this.isEntityTickingReady = true;
|
||||
});
|
||||
@@ -624,16 +783,42 @@ public class ChunkHolder {
|
||||
@@ -624,16 +785,44 @@ public class ChunkHolder {
|
||||
this.demoteFullChunk(chunkStorage, playerchunk_state1);
|
||||
}
|
||||
|
||||
@ -324,7 +326,9 @@ index 8245e07f6ecfd9dd997c8525b52c6eadd392e6f1..a0334dde56829fd895323f4cab2ab55d
|
||||
+ //this.onLevelChange.onLevelChange(this.pos, this::getQueueLevel, this.ticketLevel, this::setQueueLevel);
|
||||
+ // Paper start - raise IO/load priority if priority changes, use our preferred priority
|
||||
+ priorityBoost = chunkMap.distanceManager.getChunkPriority(pos);
|
||||
+ int currRequestedPriority = this.requestedPriority;
|
||||
+ int priority = getDemandedPriority();
|
||||
+ int newRequestedPriority = this.requestedPriority = priority;
|
||||
+ if (this.queueLevel > priority) {
|
||||
+ int ioPriority = com.destroystokyo.paper.io.PrioritizedTaskQueue.NORMAL_PRIORITY;
|
||||
+ if (priority <= 10) {
|
||||
@ -334,7 +338,7 @@ index 8245e07f6ecfd9dd997c8525b52c6eadd392e6f1..a0334dde56829fd895323f4cab2ab55d
|
||||
+ }
|
||||
+ chunkMap.level.asyncChunkTaskManager.raisePriority(pos.x, pos.z, ioPriority);
|
||||
+ }
|
||||
+ if (this.queueLevel != priority) {
|
||||
+ if (currRequestedPriority != newRequestedPriority) {
|
||||
+ this.onLevelChange.onLevelChange(this.pos, () -> this.queueLevel, priority, p -> this.queueLevel = p); // use preferred priority
|
||||
+ int neighborsPriority = getNeighborsPriority();
|
||||
+ this.neighbors.forEach((neighbor, neighborDesired) -> neighbor.setNeighborPriority(this, neighborsPriority));
|
||||
@ -363,7 +367,7 @@ index 8245e07f6ecfd9dd997c8525b52c6eadd392e6f1..a0334dde56829fd895323f4cab2ab55d
|
||||
}
|
||||
}).exceptionally((throwable) -> {
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index 12f9f512dc8b9e094dab2caec7b6ddaf2a378ee9..5b1b91ab4d351f47a05a73cf65539b0bc92df13b 100644
|
||||
index 12f9f512dc8b9e094dab2caec7b6ddaf2a378ee9..11b743acfad319f536798204d525cda0813e8987 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -149,6 +149,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
@ -589,7 +593,7 @@ index 12f9f512dc8b9e094dab2caec7b6ddaf2a378ee9..5b1b91ab4d351f47a05a73cf65539b0b
|
||||
CompletableFuture<CompoundTag> chunkSaveFuture = this.level.asyncChunkTaskManager.getChunkSaveFuture(pos.x, pos.z);
|
||||
+ // Paper start
|
||||
+ ChunkHolder playerChunk = getUpdatingChunkIfPresent(pos.toLong());
|
||||
+ int chunkPriority = playerChunk != null ? playerChunk.queueLevel : 33;
|
||||
+ int chunkPriority = playerChunk != null ? playerChunk.requestedPriority : 33;
|
||||
+ int priority = com.destroystokyo.paper.io.PrioritizedTaskQueue.NORMAL_PRIORITY;
|
||||
+
|
||||
+ if (chunkPriority <= 10) {
|
||||
@ -1103,7 +1107,7 @@ index 6d947343b6ff2f86a23ea669e371d5ecd9e903c0..d6f0c82b503a0fa73f6589fc4c331d27
|
||||
boolean flag1 = this.chunkMap.promoteChunkMap();
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index cf09bd17b9d2be04f79edef6debdd815b5f7f86c..6cf83d9b1e43ade17cb67843dbdc11937eda1e08 100644
|
||||
index 009b6fe428db1a6e69403d8df32325f78e6b4461..1da049b171e26ac422fa0e56d8772577d5c768fa 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -189,6 +189,14 @@ public class ServerPlayer extends Player {
|
||||
|
@ -36,10 +36,10 @@ scenario / path:
|
||||
Previously would have hopped to SERVER around 12+ times there extra.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
index a0334dde56829fd895323f4cab2ab55d5d5ecf30..81696d822c00e506ba2128590e95341994ff93f6 100644
|
||||
index 75fbcc3d9b3aca2738df0c7ce8c1a0b157ff375a..0c6d513b6bcbd518fe4beee7acd7b96ce801c78e 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
@@ -242,6 +242,13 @@ public class ChunkHolder {
|
||||
@@ -244,6 +244,13 @@ public class ChunkHolder {
|
||||
// Paper end - optimise isOutsideOfRange
|
||||
long lastAutoSaveTime; // Paper - incremental autosave
|
||||
long inactiveTimeStart; // Paper - incremental autosave
|
||||
@ -54,7 +54,7 @@ index a0334dde56829fd895323f4cab2ab55d5d5ecf30..81696d822c00e506ba2128590e953419
|
||||
public ChunkHolder(ChunkPos pos, int level, LevelHeightAccessor world, LevelLightEngine lightingProvider, ChunkHolder.LevelChangeListener levelUpdateListener, ChunkHolder.PlayerProvider playersWatchingChunkProvider) {
|
||||
this.futures = new AtomicReferenceArray(ChunkHolder.CHUNK_STATUSES.size());
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index 5b1b91ab4d351f47a05a73cf65539b0bc92df13b..d470fdcbc79c4a491e9a078930b54e8d8949d68c 100644
|
||||
index 11b743acfad319f536798204d525cda0813e8987..1de84204656d60e4dc91cc37661cb7c1573a22d2 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -827,7 +827,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
@ -25,19 +25,19 @@ Massive update to light to improve performance and chunk loading/generation.
|
||||
8) Fix NPE risk that crashes server in getting nibble data
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
index 81696d822c00e506ba2128590e95341994ff93f6..c6c4894427e5e98dccc1506d9d20157e1acbbd21 100644
|
||||
index 0c6d513b6bcbd518fe4beee7acd7b96ce801c78e..e6cc5da2fd58bcc2809baeffee01040d0370a92c 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
@@ -810,6 +810,7 @@ public class ChunkHolder {
|
||||
@@ -806,6 +806,7 @@ public class ChunkHolder {
|
||||
ioPriority = com.destroystokyo.paper.io.PrioritizedTaskQueue.HIGH_PRIORITY;
|
||||
}
|
||||
chunkMap.level.asyncChunkTaskManager.raisePriority(pos.x, pos.z, ioPriority);
|
||||
+ chunkMap.level.getChunkSource().getLightEngine().queue.changePriority(pos.toLong(), this.queueLevel, priority); // Paper // Restore this in chunk priority later?
|
||||
}
|
||||
// Paper end
|
||||
this.oldTicketLevel = this.ticketLevel;
|
||||
+ //chunkMap.level.getChunkSource().getLightEngine().queue.changePriority(pos.toLong(), this.queueLevel, priority); // Paper // Restore this in chunk priority later?
|
||||
// CraftBukkit start
|
||||
// ChunkLoadEvent: Called after the chunk is loaded: isChunkLoaded returns true and chunk is ready to be modified by plugins.
|
||||
if (!playerchunk_state.isOrAfter(ChunkHolder.FullChunkStatus.BORDER) && playerchunk_state1.isOrAfter(ChunkHolder.FullChunkStatus.BORDER)) {
|
||||
if (currRequestedPriority != newRequestedPriority) {
|
||||
this.onLevelChange.onLevelChange(this.pos, () -> this.queueLevel, priority, p -> this.queueLevel = p); // use preferred priority
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index d470fdcbc79c4a491e9a078930b54e8d8949d68c..1c662deee2a3184c7612cf7de5f798753fbd7381 100644
|
||||
index 1de84204656d60e4dc91cc37661cb7c1573a22d2..97bf5120d680ab47778c65e28e2ea2954daac031 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -97,6 +97,7 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureMana
|
||||
|
@ -5,10 +5,10 @@ Subject: [PATCH] Don't mark dirty in invalid locations (SPIGOT-6086)
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
index 6333a310fe32c631be95889f7438414d4a2c03bd..2e983077143a0a7ce6857d5796c9e4f7a4629caf 100644
|
||||
index e6cc5da2fd58bcc2809baeffee01040d0370a92c..8d59d735b2862ecc12cbfebc57a02ebbfd1e125e 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
@@ -379,6 +379,7 @@ public class ChunkHolder {
|
||||
@@ -381,6 +381,7 @@ public class ChunkHolder {
|
||||
}
|
||||
|
||||
public void blockChanged(BlockPos pos) {
|
||||
|
@ -8,10 +8,10 @@ cause a recursive call which would handle the increase but then
|
||||
the caller would think the chunk would be unloaded.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
index e844ac574e4b94580a14027c130374f1287f7324..844a0e1ac3a6480c8d7b49debaada2c698432405 100644
|
||||
index 8d59d735b2862ecc12cbfebc57a02ebbfd1e125e..ee71e8678e58441287a9cd6cf00d5635daddc60f 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
@@ -624,8 +624,10 @@ public class ChunkHolder {
|
||||
@@ -626,8 +626,10 @@ public class ChunkHolder {
|
||||
playerchunkmap.onFullChunkStatusChange(this.pos, playerchunk_state);
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ index e844ac574e4b94580a14027c130374f1287f7324..844a0e1ac3a6480c8d7b49debaada2c6
|
||||
ChunkStatus chunkstatus = ChunkHolder.getStatus(this.oldTicketLevel);
|
||||
ChunkStatus chunkstatus1 = ChunkHolder.getStatus(this.ticketLevel);
|
||||
boolean flag = this.oldTicketLevel <= ChunkMap.MAX_CHUNK_DISTANCE;
|
||||
@@ -667,6 +669,12 @@ public class ChunkHolder {
|
||||
@@ -669,6 +671,12 @@ public class ChunkHolder {
|
||||
|
||||
// Run callback right away if the future was already done
|
||||
chunkStorage.callbackExecutor.run();
|
||||
|
@ -8,10 +8,10 @@ This WILL cause state corruption if it happens. So, don't
|
||||
allow it.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
index 844a0e1ac3a6480c8d7b49debaada2c698432405..660ec9359cb9fe9cdb54d7ef6139bbbccb91ba16 100644
|
||||
index ee71e8678e58441287a9cd6cf00d5635daddc60f..7c0d404e5ac6819326276fb6424e33949c4ee08b 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
@@ -597,7 +597,13 @@ public class ChunkHolder {
|
||||
@@ -599,7 +599,13 @@ public class ChunkHolder {
|
||||
CompletableFuture<Void> completablefuture1 = new CompletableFuture();
|
||||
|
||||
completablefuture1.thenRunAsync(() -> {
|
||||
@ -25,7 +25,7 @@ index 844a0e1ac3a6480c8d7b49debaada2c698432405..660ec9359cb9fe9cdb54d7ef6139bbbc
|
||||
}, executor);
|
||||
this.pendingFullStateConfirmation = completablefuture1;
|
||||
completablefuture.thenAccept((either) -> {
|
||||
@@ -621,7 +627,12 @@ public class ChunkHolder {
|
||||
@@ -623,7 +629,12 @@ public class ChunkHolder {
|
||||
|
||||
private void demoteFullChunk(ChunkMap playerchunkmap, ChunkHolder.FullChunkStatus playerchunk_state) {
|
||||
this.pendingFullStateConfirmation.cancel(false);
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren