diff --git a/patches/removed/1.19.2-legacy-chunksystem/0020-Implement-Chunk-Priority-Urgency-System-for-Chunks.patch b/patches/removed/1.19.2-legacy-chunksystem/0020-Implement-Chunk-Priority-Urgency-System-for-Chunks.patch index 2f6116e043..ec8ccf7a1d 100644 --- a/patches/removed/1.19.2-legacy-chunksystem/0020-Implement-Chunk-Priority-Urgency-System-for-Chunks.patch +++ b/patches/removed/1.19.2-legacy-chunksystem/0020-Implement-Chunk-Priority-Urgency-System-for-Chunks.patch @@ -67,11 +67,95 @@ index af40e473521f408aa0e112953c43bdbce164a48b..68860a3b6db2aa50373d71aec9502c18 } } +diff --git a/src/main/java/net/minecraft/server/ChunkSystem.java b/src/main/java/net/minecraft/server/ChunkSystem.java +index 7f76c304f5eb3c2f27b348918588ab67b795b1ba..1b1bfd5f92f85f46ad9661a0a64a2a1b4c33a80d 100644 +--- a/src/main/java/net/minecraft/server/ChunkSystem.java ++++ b/src/main/java/net/minecraft/server/ChunkSystem.java +@@ -55,6 +55,19 @@ public final class ChunkSystem { + + static final TicketType CHUNK_LOAD = TicketType.create("chunk_load", Long::compareTo); + ++ // Paper start - priority ++ private static int getPriorityBoost(final PrioritisedExecutor.Priority priority) { ++ if (priority.isLowerOrEqualPriority(PrioritisedExecutor.Priority.NORMAL)) { ++ return 0; ++ } ++ ++ int dist = PrioritisedExecutor.Priority.BLOCKING.ordinal() - PrioritisedExecutor.Priority.NORMAL.ordinal(); ++ ++ ++ return (net.minecraft.server.level.DistanceManager.URGENT_PRIORITY * (priority.ordinal() - PrioritisedExecutor.Priority.NORMAL.ordinal())) / dist; ++ } ++ // Paper end - priority ++ + private static long chunkLoadCounter = 0L; + public static void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final ChunkStatus toStatus, + final boolean addTicket, final PrioritisedExecutor.Priority priority, final Consumer onComplete) { +@@ -68,12 +81,19 @@ public final class ChunkSystem { + final int minLevel = 33 + ChunkStatus.getDistance(toStatus); + final Long chunkReference = addTicket ? Long.valueOf(++chunkLoadCounter) : null; + final ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ); ++ final int priorityBoost = getPriorityBoost(priority); + + if (addTicket) { + level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); + } + level.chunkSource.runDistanceManagerUpdates(); + ++ if (priorityBoost == net.minecraft.server.level.DistanceManager.URGENT_PRIORITY) { ++ level.chunkSource.markUrgent(chunkPos); ++ } else if (priorityBoost != 0) { ++ level.chunkSource.markHighPriority(chunkPos, priorityBoost); ++ } ++ + final Consumer loadCallback = (final ChunkAccess chunk) -> { + try { + if (onComplete != null) { +@@ -89,6 +109,11 @@ public final class ChunkSystem { + level.chunkSource.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, minLevel, chunkPos); + level.chunkSource.removeTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); + } ++ if (priorityBoost == net.minecraft.server.level.DistanceManager.URGENT_PRIORITY) { ++ level.chunkSource.clearUrgent(chunkPos); ++ } else if (priorityBoost != 0) { ++ level.chunkSource.clearPriorityTickets(chunkPos); ++ } + } + }; + +@@ -135,12 +160,17 @@ public final class ChunkSystem { + final int radius = toStatus.ordinal() - 1; + final Long chunkReference = addTicket ? Long.valueOf(++chunkLoadCounter) : null; + final ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ); ++ final int priorityBoost = getPriorityBoost(priority); + + if (addTicket) { + level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); + } + level.chunkSource.runDistanceManagerUpdates(); + ++ if (priorityBoost != 0) { ++ level.chunkSource.markAreaHighPriority(chunkPos, priorityBoost, radius); ++ } ++ + final Consumer loadCallback = (final LevelChunk chunk) -> { + try { + if (onComplete != null) { +@@ -156,6 +186,9 @@ public final class ChunkSystem { + level.chunkSource.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, minLevel, chunkPos); + level.chunkSource.removeTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); + } ++ if (priorityBoost != 0) { ++ level.chunkSource.clearAreaPriorityTickets(chunkPos, radius); ++ } + } + }; + diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java -index 4e29c0a983727fc839a4bcde01d3286396b3587d..613988c9ea892ab15516e1c8b4f376d52415ae34 100644 +index 2e56c52e3ee45b0304a9e6a5eab863ef96b2aab0..5eb6ce20ee17d87db0f6c2dcee96d6d0891d6c50 100644 --- a/src/main/java/net/minecraft/server/MCUtil.java +++ b/src/main/java/net/minecraft/server/MCUtil.java -@@ -681,6 +681,7 @@ public final class MCUtil { +@@ -634,6 +634,7 @@ public final class MCUtil { chunkData.addProperty("x", playerChunk.pos.x); chunkData.addProperty("z", playerChunk.pos.z); chunkData.addProperty("ticket-level", playerChunk.getTicketLevel()); @@ -80,7 +164,7 @@ index 4e29c0a983727fc839a4bcde01d3286396b3587d..613988c9ea892ab15516e1c8b4f376d5 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 36a9d52d9af3bc398010c52dc16ab23e53f2702a..ece4cd0de061969d4d2f07560e6cf38e631098b3 100644 +index e30893d6cbe3b42338d04453d0f452babeb61d8a..a52932d665ca45a5e066d7cef0ec0313d1c3f69f 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 +184,7 @@ index 36a9d52d9af3bc398010c52dc16ab23e53f2702a..ece4cd0de061969d4d2f07560e6cf38e boolean isUpdateQueued = false; // Paper private final ChunkMap chunkMap; // Paper -@@ -448,12 +449,18 @@ public class ChunkHolder { +@@ -438,12 +439,18 @@ public class ChunkHolder { }); } @@ -119,7 +203,7 @@ index 36a9d52d9af3bc398010c52dc16ab23e53f2702a..ece4cd0de061969d4d2f07560e6cf38e ChunkStatus chunkstatus = ChunkHolder.getStatus(this.oldTicketLevel); ChunkStatus chunkstatus1 = ChunkHolder.getStatus(this.ticketLevel); boolean flag = this.oldTicketLevel <= ChunkMap.MAX_CHUNK_DISTANCE; -@@ -464,9 +471,22 @@ public class ChunkHolder { +@@ -454,9 +461,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) -> { @@ -143,22 +227,21 @@ index 36a9d52d9af3bc398010c52dc16ab23e53f2702a..ece4cd0de061969d4d2f07560e6cf38e // 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. -@@ -523,12 +543,14 @@ public class ChunkHolder { +@@ -501,11 +521,13 @@ public class ChunkHolder { this.scheduleFullChunkPromotion(chunkStorage, this.fullChunkFuture, executor, ChunkHolder.FullChunkStatus.BORDER); // Paper start - cache ticking ready status this.fullChunkFuture.thenAccept(either -> { + io.papermc.paper.util.TickThread.ensureTickThread("Async full chunk future completion"); // Paper final Optional left = either.left(); if (left.isPresent() && ChunkHolder.this.fullChunkCreateCount == expectCreateCount) { - // note: Here is a very good place to add callbacks to logic waiting on this. LevelChunk fullChunk = either.left().get(); ChunkHolder.this.isFullChunkReady = true; - fullChunk.playerChunk = ChunkHolder.this; -+ this.chunkMap.distanceManager.clearPriorityTickets(pos); + net.minecraft.server.ChunkSystem.onChunkBorder(fullChunk, this); ++ this.chunkMap.distanceManager.clearPriorityTickets(pos); // Paper - chunk priority } }); this.updateChunkToSave(this.fullChunkFuture, "full"); -@@ -549,6 +571,7 @@ public class ChunkHolder { +@@ -531,6 +553,7 @@ public class ChunkHolder { this.scheduleFullChunkPromotion(chunkStorage, this.tickingChunkFuture, executor, ChunkHolder.FullChunkStatus.TICKING); // Paper start - cache ticking ready status this.tickingChunkFuture.thenAccept(either -> { @@ -166,15 +249,15 @@ index 36a9d52d9af3bc398010c52dc16ab23e53f2702a..ece4cd0de061969d4d2f07560e6cf38e either.ifLeft(chunk -> { // note: Here is a very good place to add callbacks to logic waiting on this. ChunkHolder.this.isTickingReady = true; -@@ -584,6 +607,7 @@ public class ChunkHolder { +@@ -563,6 +586,7 @@ public class ChunkHolder { this.scheduleFullChunkPromotion(chunkStorage, this.entityTickingChunkFuture, executor, ChunkHolder.FullChunkStatus.ENTITY_TICKING); // Paper start - cache ticking ready status this.entityTickingChunkFuture.thenAccept(either -> { + io.papermc.paper.util.TickThread.ensureTickThread("Async full chunk future completion"); // Paper either.ifLeft(chunk -> { ChunkHolder.this.isEntityTickingReady = true; - // Paper start - entity ticking chunk set -@@ -610,16 +634,45 @@ public class ChunkHolder { + net.minecraft.server.ChunkSystem.onChunkEntityTicking(chunk, this); +@@ -586,16 +610,45 @@ public class ChunkHolder { this.demoteFullChunk(chunkStorage, playerchunk_state1); } @@ -223,7 +306,7 @@ index 36a9d52d9af3bc398010c52dc16ab23e53f2702a..ece4cd0de061969d4d2f07560e6cf38e }); } }).exceptionally((throwable) -> { -@@ -744,7 +797,134 @@ public class ChunkHolder { +@@ -696,7 +749,134 @@ public class ChunkHolder { }; } @@ -360,10 +443,10 @@ index 36a9d52d9af3bc398010c52dc16ab23e53f2702a..ece4cd0de061969d4d2f07560e6cf38e return this.isEntityTickingReady; } diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index eb74a831fc439c56fe1ac2d4769ebefa1e5759a3..349c311e70758d99ebb4c61ad509a3a975fda04b 100644 +index c3bbaf32373a32417f8b83f386f8cf327c6e0893..46bfaf04867d913c1782d851de101d913376c63a 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -134,6 +134,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -131,6 +131,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider public final ServerLevel level; private final ThreadedLevelLightEngine lightEngine; private final BlockableEventLoop mainThreadExecutor; @@ -371,7 +454,7 @@ index eb74a831fc439c56fe1ac2d4769ebefa1e5759a3..349c311e70758d99ebb4c61ad509a3a9 public ChunkGenerator generator; private RandomState randomState; public final Supplier overworldDataStorage; -@@ -337,6 +338,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -267,6 +268,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } this.mainThreadExecutor = mainThreadExecutor; @@ -387,7 +470,7 @@ index eb74a831fc439c56fe1ac2d4769ebefa1e5759a3..349c311e70758d99ebb4c61ad509a3a9 ProcessorMailbox threadedmailbox = ProcessorMailbox.create(executor, "worldgen"); Objects.requireNonNull(mainThreadExecutor); -@@ -452,6 +462,37 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -309,6 +319,37 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider }); } @@ -422,10 +505,10 @@ index eb74a831fc439c56fe1ac2d4769ebefa1e5759a3..349c311e70758d99ebb4c61ad509a3a9 + } + // Paper end + - // Paper start - public void updatePlayerMobTypeMap(Entity entity) { - if (!this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { -@@ -562,6 +603,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + private static double euclideanDistanceSquared(ChunkPos pos, Entity entity) { + double d0 = (double) SectionPos.sectionToBlockCoord(pos.x, 8); + double d1 = (double) SectionPos.sectionToBlockCoord(pos.z, 8); +@@ -399,6 +440,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider List list1 = new ArrayList(); int j = centerChunk.x; int k = centerChunk.z; @@ -433,7 +516,7 @@ index eb74a831fc439c56fe1ac2d4769ebefa1e5759a3..349c311e70758d99ebb4c61ad509a3a9 for (int l = -margin; l <= margin; ++l) { for (int i1 = -margin; i1 <= margin; ++i1) { -@@ -580,6 +622,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -417,6 +459,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider ChunkStatus chunkstatus = (ChunkStatus) distanceToStatus.apply(j1); CompletableFuture> completablefuture = playerchunk.getOrScheduleFuture(chunkstatus, this); @@ -448,7 +531,7 @@ index eb74a831fc439c56fe1ac2d4769ebefa1e5759a3..349c311e70758d99ebb4c61ad509a3a9 list1.add(playerchunk); list.add(completablefuture); -@@ -937,11 +987,19 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -733,11 +783,19 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider if (requiredStatus == ChunkStatus.EMPTY) { return this.scheduleChunkLoad(chunkcoordintpair); } else { @@ -469,7 +552,7 @@ index eb74a831fc439c56fe1ac2d4769ebefa1e5759a3..349c311e70758d99ebb4c61ad509a3a9 if (optional.isPresent() && ((ChunkAccess) optional.get()).getStatus().isOrAfter(requiredStatus)) { CompletableFuture> completablefuture = requiredStatus.load(this.level, this.structureTemplateManager, this.lightEngine, (ichunkaccess) -> { -@@ -953,6 +1011,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -749,6 +807,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } else { return this.scheduleChunkGeneration(holder, requiredStatus); } @@ -477,7 +560,7 @@ index eb74a831fc439c56fe1ac2d4769ebefa1e5759a3..349c311e70758d99ebb4c61ad509a3a9 } } -@@ -992,14 +1051,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -788,14 +847,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider }; CompletableFuture chunkSaveFuture = this.level.asyncChunkTaskManager.getChunkSaveFuture(pos.x, pos.z); @@ -507,7 +590,7 @@ index eb74a831fc439c56fe1ac2d4769ebefa1e5759a3..349c311e70758d99ebb4c61ad509a3a9 return ret; // Paper end - Async chunk io } -@@ -1078,7 +1147,10 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -874,7 +943,10 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.releaseLightTicket(chunkcoordintpair); return CompletableFuture.completedFuture(Either.right(playerchunk_failure)); }); @@ -519,7 +602,7 @@ index eb74a831fc439c56fe1ac2d4769ebefa1e5759a3..349c311e70758d99ebb4c61ad509a3a9 } protected void releaseLightTicket(ChunkPos pos) { -@@ -1162,7 +1234,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -957,7 +1029,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider long i = chunkHolder.getPos().toLong(); Objects.requireNonNull(chunkHolder); @@ -529,10 +612,10 @@ index eb74a831fc439c56fe1ac2d4769ebefa1e5759a3..349c311e70758d99ebb4c61ad509a3a9 } diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java -index 9bc956068df3baabb9f8e02ee74a6397de2bf587..b2df5e18ce5260a9781052db7afb0b9786fb887c 100644 +index 1d6ab658c48bb765f66624f276ec7b05cf33c1d5..b9b56068cdacd984f873cfb2a06a312e9912893d 100644 --- a/src/main/java/net/minecraft/server/level/DistanceManager.java +++ b/src/main/java/net/minecraft/server/level/DistanceManager.java -@@ -128,6 +128,7 @@ public abstract class DistanceManager { +@@ -114,6 +114,7 @@ public abstract class DistanceManager { } private static int getTicketLevelAt(SortedArraySet> tickets) { @@ -540,15 +623,15 @@ index 9bc956068df3baabb9f8e02ee74a6397de2bf587..b2df5e18ce5260a9781052db7afb0b97 return !tickets.isEmpty() ? ((Ticket) tickets.first()).getTicketLevel() : ChunkMap.MAX_CHUNK_DISTANCE + 1; } -@@ -142,6 +143,7 @@ public abstract class DistanceManager { +@@ -128,6 +129,7 @@ public abstract class DistanceManager { public boolean runAllUpdates(ChunkMap chunkStorage) { - //this.f.a(); // Paper - no longer used + this.naturalSpawnChunkCounter.runAllUpdates(); this.tickingTicketsTracker.runAllUpdates(); + org.spigotmc.AsyncCatcher.catchOp("DistanceManagerTick"); // Paper this.playerTicketManager.runAllUpdates(); int i = Integer.MAX_VALUE - this.ticketTracker.runDistanceUpdates(Integer.MAX_VALUE); boolean flag = i != 0; -@@ -152,11 +154,13 @@ public abstract class DistanceManager { +@@ -138,11 +140,13 @@ public abstract class DistanceManager { // Paper start if (!this.pendingChunkUpdates.isEmpty()) { @@ -562,7 +645,7 @@ index 9bc956068df3baabb9f8e02ee74a6397de2bf587..b2df5e18ce5260a9781052db7afb0b97 // Paper end return true; } else { -@@ -192,8 +196,10 @@ public abstract class DistanceManager { +@@ -178,8 +182,10 @@ public abstract class DistanceManager { return flag; } } @@ -573,7 +656,7 @@ index 9bc956068df3baabb9f8e02ee74a6397de2bf587..b2df5e18ce5260a9781052db7afb0b97 SortedArraySet> arraysetsorted = this.getTickets(i); int j = DistanceManager.getTicketLevelAt(arraysetsorted); Ticket ticket1 = (Ticket) arraysetsorted.addOrGet(ticket); -@@ -207,7 +213,9 @@ public abstract class DistanceManager { +@@ -193,7 +199,9 @@ public abstract class DistanceManager { } boolean removeTicket(long i, Ticket ticket) { // CraftBukkit - void -> boolean @@ -583,7 +666,7 @@ index 9bc956068df3baabb9f8e02ee74a6397de2bf587..b2df5e18ce5260a9781052db7afb0b97 boolean removed = false; // CraftBukkit if (arraysetsorted.remove(ticket)) { -@@ -239,7 +247,12 @@ public abstract class DistanceManager { +@@ -225,7 +233,12 @@ public abstract class DistanceManager { this.tickets.remove(i); } @@ -597,7 +680,7 @@ index 9bc956068df3baabb9f8e02ee74a6397de2bf587..b2df5e18ce5260a9781052db7afb0b97 return removed; // CraftBukkit } -@@ -289,6 +302,112 @@ public abstract class DistanceManager { +@@ -275,6 +288,112 @@ public abstract class DistanceManager { }); } @@ -711,12 +794,12 @@ index 9bc956068df3baabb9f8e02ee74a6397de2bf587..b2df5e18ce5260a9781052db7afb0b97 Ticket ticket = new Ticket<>(TicketType.FORCED, 31, pos); long i = pos.toLong(); diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 585892f19bc0aea89889a358c0407f2975b9efe5..918fda0fbbafa39ce0f421dcaf10f8dcf1e5dabb 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 -@@ -590,6 +590,26 @@ 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) { @@ -737,11 +820,15 @@ index 585892f19bc0aea89889a358c0407f2975b9efe5..918fda0fbbafa39ce0f421dcaf10f8dc + + public void clearPriorityTickets(ChunkPos coords) { + this.distanceManager.clearPriorityTickets(coords); ++ } ++ ++ public void clearUrgent(ChunkPos coords) { ++ this.distanceManager.clearUrgent(coords); + } // Paper end - async chunk io @Nullable -@@ -630,6 +650,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 @@ -750,7 +837,7 @@ index 585892f19bc0aea89889a358c0407f2975b9efe5..918fda0fbbafa39ce0f421dcaf10f8dc 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 -@@ -638,6 +660,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 @@ -759,7 +846,7 @@ index 585892f19bc0aea89889a358c0407f2975b9efe5..918fda0fbbafa39ce0f421dcaf10f8dc } // Paper ichunkaccess = (ChunkAccess) ((Either) completablefuture.join()).map((ichunkaccess1) -> { return ichunkaccess1; -@@ -711,10 +735,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); @@ -772,7 +859,7 @@ index 585892f19bc0aea89889a358c0407f2975b9efe5..918fda0fbbafa39ce0f421dcaf10f8dc this.runDistanceManagerUpdates(); playerchunk = this.getVisibleChunkIfPresent(k); gameprofilerfiller.pop(); -@@ -724,7 +750,13 @@ public class ServerChunkCache extends ChunkSource { +@@ -568,7 +598,13 @@ public class ServerChunkCache extends ChunkSource { } } @@ -787,7 +874,7 @@ index 585892f19bc0aea89889a358c0407f2975b9efe5..918fda0fbbafa39ce0f421dcaf10f8dc } private boolean chunkAbsent(@Nullable ChunkHolder holder, int maxLevel) { -@@ -776,6 +808,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -620,6 +656,7 @@ public class ServerChunkCache extends ChunkSource { } public boolean runDistanceManagerUpdates() { @@ -796,10 +883,10 @@ index 585892f19bc0aea89889a358c0407f2975b9efe5..918fda0fbbafa39ce0f421dcaf10f8dc 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 792ca370a918867e20dc8b020e7ed76535d4742b..63d06fda90816e79026387bc06e88eeb6ad21506 100644 +index 9ab4588e4e512176b881ad4c252e400ff6ea97bd..4adf2d503015cac85b12fbaae833b33eeeb44403 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -192,6 +192,7 @@ public class ServerPlayer extends Player { +@@ -191,6 +191,7 @@ public class ServerPlayer extends Player { private int lastRecordedArmor = Integer.MIN_VALUE; private int lastRecordedLevel = Integer.MIN_VALUE; private int lastRecordedExperience = Integer.MIN_VALUE; @@ -807,9 +894,9 @@ index 792ca370a918867e20dc8b020e7ed76535d4742b..63d06fda90816e79026387bc06e88eeb private float lastSentHealth = -1.0E8F; private int lastSentFood = -99999999; private boolean lastFoodSaturationZero = true; -@@ -336,6 +337,21 @@ public class ServerPlayer extends Player { +@@ -318,6 +319,21 @@ public class ServerPlayer extends Player { + this.bukkitPickUpLoot = true; this.maxHealthCache = this.getMaxHealth(); - this.cachedSingleMobDistanceMap = new com.destroystokyo.paper.util.PooledHashSets.PooledObjectLinkedOpenHashSet<>(this); // Paper } + // Paper start - Chunk priority + public BlockPos getPointInFront(double inFront) { @@ -1099,7 +1186,7 @@ index f1128f0d4a9a0241ac6c9bc18dd13b431c616bb1..2b2b7851d5f68bcdb41d58bcc64740ba protected Ticket(TicketType type, int level, T argument) { this.type = type; diff --git a/src/main/java/net/minecraft/server/level/TicketType.java b/src/main/java/net/minecraft/server/level/TicketType.java -index 8770fe0db46b01e8b608637df4f1a669a3f4cdde..3c1698ba0d3bc412ab957777d9b5211dbc555208 100644 +index 10fa6cec911950f72407ae7f45c8cf48caa9421a..478109526cff7ceb0565cea3b5e97b9a07fbf8d1 100644 --- a/src/main/java/net/minecraft/server/level/TicketType.java +++ b/src/main/java/net/minecraft/server/level/TicketType.java @@ -9,6 +9,8 @@ import net.minecraft.world.level.ChunkPos; @@ -1112,33 +1199,22 @@ index 8770fe0db46b01e8b608637df4f1a669a3f4cdde..3c1698ba0d3bc412ab957777d9b5211d private final String name; private final Comparator comparator; diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 0b301b1f164853bfd23300993288a2958824e287..ec48afe87b5d159b5bdbe035e214ea7c9024fadb 100644 +index 5833cc3d5014dad82607afc4d643b6bed885be64..8e0f73dcef189442450b4518437fb3a1c34b9a47 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -178,6 +178,7 @@ public abstract class PlayerList { +@@ -177,6 +177,7 @@ public abstract class PlayerList { } public void placeNewPlayer(Connection connection, ServerPlayer player) { + player.isRealPlayer = true; // Paper - Chunk priority - ServerPlayer prev = pendingPlayers.put(player.getUUID(), player);// Paper - if (prev != null) { - disconnectPendingPlayer(prev); -@@ -292,8 +293,8 @@ public abstract class PlayerList { - net.minecraft.server.level.ChunkMap playerChunkMap = worldserver1.getChunkSource().chunkMap; - net.minecraft.server.level.DistanceManager distanceManager = playerChunkMap.distanceManager; - distanceManager.addTicket(net.minecraft.server.level.TicketType.LOGIN, pos, 31, pos.toLong()); -- worldserver1.getChunkSource().runDistanceManagerUpdates(); -- worldserver1.getChunkSource().getChunkAtAsynchronously(chunkX, chunkZ, true, true).thenApply(chunk -> { -+ worldserver1.getChunkSource().markAreaHighPriority(pos, 28, 3); // Paper - Chunk priority -+ worldserver1.getChunkSource().getChunkAtAsynchronously(chunkX, chunkZ, true, false).thenApply(chunk -> { // Paper - Chunk priority - net.minecraft.server.level.ChunkHolder updatingChunk = playerChunkMap.getUpdatingChunkIfPresent(pos.toLong()); - if (updatingChunk != null) { - return updatingChunk.getEntityTickingChunkFuture(); + GameProfile gameprofile = player.getGameProfile(); + GameProfileCache usercache = this.server.getProfileCache(); + Optional optional = usercache.get(gameprofile.getId()); diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 173824e96c51c4f1a9f43401cfa3fc79a2432600..c1bf81770f9d00f4e3ba5844260812bb4f6026ca 100644 +index 1a44c98b69398ba5dcb4115f0e8fdcf3f62fd920..9878aded49d0049b066fa608c7eaf25a55fcf12e 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -293,7 +293,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -212,7 +212,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { private BlockPos blockPosition; private ChunkPos chunkPosition; private Vec3 deltaMovement; @@ -1148,10 +1224,10 @@ index 173824e96c51c4f1a9f43401cfa3fc79a2432600..c1bf81770f9d00f4e3ba5844260812bb public float yRotO; public float xRotO; diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -index 797ff36295412ac8429d573e039d870fd85eb569..3591ac3b7823e109e01ebfa54ac70aa4deabd4f6 100644 +index 58a245b2ca6e65d491694142ad04d38236b46434..893051059df51133a127b0870e27ab67461052fa 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -141,7 +141,7 @@ public class LevelChunk extends ChunkAccess { +@@ -134,7 +134,7 @@ public class LevelChunk extends ChunkAccess { return NEIGHBOUR_CACHE_RADIUS; } @@ -1160,7 +1236,7 @@ index 797ff36295412ac8429d573e039d870fd85eb569..3591ac3b7823e109e01ebfa54ac70aa4 private long neighbourChunksLoadedBitset; private final LevelChunk[] loadedNeighbourChunks = new LevelChunk[(NEIGHBOUR_CACHE_RADIUS * 2 + 1) * (NEIGHBOUR_CACHE_RADIUS * 2 + 1)]; -@@ -693,6 +693,7 @@ public class LevelChunk extends ChunkAccess { +@@ -653,6 +653,7 @@ public class LevelChunk extends ChunkAccess { // CraftBukkit start public void loadCallback() { @@ -1168,7 +1244,7 @@ index 797ff36295412ac8429d573e039d870fd85eb569..3591ac3b7823e109e01ebfa54ac70aa4 // Paper start - neighbour cache int chunkX = this.chunkPos.x; int chunkZ = this.chunkPos.z; -@@ -747,6 +748,7 @@ public class LevelChunk extends ChunkAccess { +@@ -707,6 +708,7 @@ public class LevelChunk extends ChunkAccess { } public void unloadCallback() { @@ -1176,41 +1252,3 @@ index 797ff36295412ac8429d573e039d870fd85eb569..3591ac3b7823e109e01ebfa54ac70aa4 org.bukkit.Server server = this.level.getCraftServer(); org.bukkit.event.world.ChunkUnloadEvent unloadEvent = new org.bukkit.event.world.ChunkUnloadEvent(this.bukkitChunk, this.isUnsaved()); server.getPluginManager().callEvent(unloadEvent); -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index b234ba968e82ddf1e8f7c84d3a17659e3beda2b3..af22fa8aa8ddef4d592564b14d0114cc6f903fca 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -2077,6 +2077,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { - return future; - } - -+ // Paper start - Chunk priority -+ if (!urgent) { -+ // If not urgent, at least use a slightly boosted priority -+ world.getChunkSource().markHighPriority(new ChunkPos(x, z), 1); -+ } -+ // Paper end - return this.world.getChunkSource().getChunkAtAsynchronously(x, z, gen, urgent).thenComposeAsync((either) -> { - net.minecraft.world.level.chunk.LevelChunk chunk = (net.minecraft.world.level.chunk.LevelChunk) either.left().orElse(null); - if (chunk != null) addTicket(x, z); // Paper -diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 7ed67bcf9d0afb684e9c070fc1149d5f000aa8da..1b789e43707979a440ec64b3a09db317274abc36 100644 ---- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1039,6 +1039,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player { - throw new UnsupportedOperationException("Cannot set rotation of players. Consider teleporting instead."); - } - -+ // Paper start - Chunk priority -+ @Override -+ public java.util.concurrent.CompletableFuture teleportAsync(Location loc, @javax.annotation.Nonnull PlayerTeleportEvent.TeleportCause cause) { -+ ((CraftWorld)loc.getWorld()).getHandle().getChunkSource().markAreaHighPriority( -+ new net.minecraft.world.level.ChunkPos(net.minecraft.util.Mth.floor(loc.getX()) >> 4, -+ net.minecraft.util.Mth.floor(loc.getZ()) >> 4), 28, 3); // Load area high priority -+ return super.teleportAsync(loc, cause); -+ } -+ // Paper end -+ - @Override - public boolean teleport(Location location, PlayerTeleportEvent.TeleportCause cause) { - Preconditions.checkArgument(location != null, "location"); diff --git a/patches/removed/1.19.2-legacy-chunksystem/0853-Replace-player-chunk-loader-system.patch b/patches/removed/1.19.2-legacy-chunksystem/0853-Replace-player-chunk-loader-system.patch index 9c22222d25..a6d7f180d4 100644 --- a/patches/removed/1.19.2-legacy-chunksystem/0853-Replace-player-chunk-loader-system.patch +++ b/patches/removed/1.19.2-legacy-chunksystem/0853-Replace-player-chunk-loader-system.patch @@ -1218,10 +1218,10 @@ index 0000000000000000000000000000000000000000..b53402903eb6845df361daf6b05a6686 + } +} diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java -index 9549e8ed4b245176b340ab2f22f4bdefdbe28a9e..b65a3626d2e0817cd1e223ec3b10e82fa0339663 100644 +index 66afd752fd7d327e141d49b477f07e1ff3645d02..2a26d03fba2f3b37f176be9e47954ef9a6cd7b3e 100644 --- a/src/main/java/net/minecraft/network/Connection.java +++ b/src/main/java/net/minecraft/network/Connection.java -@@ -104,6 +104,28 @@ public class Connection extends SimpleChannelInboundHandler> { +@@ -100,6 +100,28 @@ public class Connection extends SimpleChannelInboundHandler> { public boolean queueImmunity = false; public ConnectionProtocol protocol; // Paper end @@ -1250,7 +1250,7 @@ index 9549e8ed4b245176b340ab2f22f4bdefdbe28a9e..b65a3626d2e0817cd1e223ec3b10e82f // Paper start - allow controlled flushing volatile boolean canFlush = true; -@@ -479,6 +501,7 @@ public class Connection extends SimpleChannelInboundHandler> { +@@ -488,6 +510,7 @@ public class Connection extends SimpleChannelInboundHandler> { return false; } private boolean processQueue() { @@ -1258,7 +1258,7 @@ index 9549e8ed4b245176b340ab2f22f4bdefdbe28a9e..b65a3626d2e0817cd1e223ec3b10e82f if (this.queue.isEmpty()) return true; // Paper start - make only one flush call per sendPacketQueue() call final boolean needsFlush = this.canFlush; -@@ -510,6 +533,12 @@ public class Connection extends SimpleChannelInboundHandler> { +@@ -519,6 +542,12 @@ public class Connection extends SimpleChannelInboundHandler> { } } return true; @@ -1272,10 +1272,10 @@ index 9549e8ed4b245176b340ab2f22f4bdefdbe28a9e..b65a3626d2e0817cd1e223ec3b10e82f // Paper end diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java -index 1eb71004a19866590a3d27fa6e72842934989177..7034af8ad42940c5af6b9032b9873ce36c55a2a7 100644 +index b575d73ae0ff2e4f09a6a1f6fb061ca3da2cedf1..6939ef9b1fe782980e77c351d8a385a573d6a8e6 100644 --- a/src/main/java/net/minecraft/server/MCUtil.java +++ b/src/main/java/net/minecraft/server/MCUtil.java -@@ -647,7 +647,8 @@ public final class MCUtil { +@@ -636,7 +636,8 @@ public final class MCUtil { }); worldData.addProperty("name", world.getWorld().getName()); @@ -1284,9 +1284,9 @@ index 1eb71004a19866590a3d27fa6e72842934989177..7034af8ad42940c5af6b9032b9873ce3 + worldData.addProperty("tick-view-distance", world.getChunkSource().chunkMap.playerChunkManager.getTargetTickViewDistance()); // Paper - replace chunk loader system worldData.addProperty("keep-spawn-loaded", world.keepSpawnInMemory); worldData.addProperty("keep-spawn-loaded-range", world.paperConfig().spawn.keepSpawnLoadedRange * 16); - worldData.addProperty("visible-chunk-count", visibleChunks.size()); + worldData.addProperty("visible-chunk-count", allChunks.size()); diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java -index 5482be03a667939ff009b6810d5cc90c8601e983..11cd31691307749e925930c4b6e10e3f3b4fad25 100644 +index 73712d6b9c828427d4c066c6d8672534575f3793..a041161dee9a857d43c83fb677dba7e90a6a5d24 100644 --- a/src/main/java/net/minecraft/server/level/ChunkHolder.java +++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java @@ -76,6 +76,17 @@ public class ChunkHolder { @@ -1305,9 +1305,9 @@ index 5482be03a667939ff009b6810d5cc90c8601e983..11cd31691307749e925930c4b6e10e3f + } + // Paper end - no-tick view distance - // Paper start - optimise anyPlayerCloseEnoughForSpawning - // cached here to avoid a map lookup -@@ -268,7 +279,7 @@ public class ChunkHolder { + // Paper start + public void onChunkAdd() { +@@ -273,7 +284,7 @@ public class ChunkHolder { public void blockChanged(BlockPos pos) { if (!pos.isInsideBuildHeightAndWorldBoundsHorizontal(levelHeightAccessor)) return; // Paper - SPIGOT-6086 for all invalid locations; avoid acquiring locks @@ -1316,7 +1316,7 @@ index 5482be03a667939ff009b6810d5cc90c8601e983..11cd31691307749e925930c4b6e10e3f if (chunk != null) { int i = this.levelHeightAccessor.getSectionIndex(pos.getY()); -@@ -284,14 +295,15 @@ public class ChunkHolder { +@@ -289,14 +300,15 @@ public class ChunkHolder { } public void sectionLightChanged(LightLayer lightType, int y) { @@ -1336,7 +1336,7 @@ index 5482be03a667939ff009b6810d5cc90c8601e983..11cd31691307749e925930c4b6e10e3f if (chunk != null) { int j = this.lightEngine.getMinLightSection(); -@@ -394,9 +406,28 @@ public class ChunkHolder { +@@ -399,9 +411,28 @@ public class ChunkHolder { } public void broadcast(Packet packet, boolean onlyOnWatchDistanceEdge) { @@ -1369,10 +1369,10 @@ index 5482be03a667939ff009b6810d5cc90c8601e983..11cd31691307749e925930c4b6e10e3f public CompletableFuture> getOrScheduleFuture(ChunkStatus targetStatus, ChunkMap chunkStorage) { diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 4f6473398edd9987dfbb6cef79ed1bc93c3dd809..d98c489a58c8c2e657a8879b991aa57ef78f5015 100644 +index a5e74d30045a171f5ed66a115fbd429e9ab412af..47657f20652a80f50a2e46207c9c05d1a12111b4 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -221,6 +221,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -218,6 +218,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerMobSpawnMap; // this map is absent from updateMaps since it's controlled at the start of the chunkproviderserver tick public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerChunkTickRangeMap; // Paper end - optimise ChunkMap#anyPlayerCloseEnoughForSpawning @@ -1380,7 +1380,7 @@ index 4f6473398edd9987dfbb6cef79ed1bc93c3dd809..d98c489a58c8c2e657a8879b991aa57e // Paper start - use distance map to optimise tracker public static boolean isLegacyTrackingEntity(Entity entity) { return entity.isLegacyTrackingEntity; -@@ -240,6 +241,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -237,6 +238,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider // Paper end - use distance map to optimise tracker void addPlayerToDistanceMaps(ServerPlayer player) { @@ -1388,7 +1388,7 @@ index 4f6473398edd9987dfbb6cef79ed1bc93c3dd809..d98c489a58c8c2e657a8879b991aa57e int chunkX = MCUtil.getChunkCoordinate(player.getX()); int chunkZ = MCUtil.getChunkCoordinate(player.getZ()); // Paper start - use distance map to optimise entity tracker -@@ -247,7 +249,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -244,7 +246,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider com.destroystokyo.paper.util.misc.PlayerAreaMap trackMap = this.playerEntityTrackerTrackMaps[i]; int trackRange = this.entityTrackerTrackRanges[i]; @@ -1397,7 +1397,7 @@ index 4f6473398edd9987dfbb6cef79ed1bc93c3dd809..d98c489a58c8c2e657a8879b991aa57e } // Paper end - use distance map to optimise entity tracker // Note: players need to be explicitly added to distance maps before they can be updated -@@ -277,6 +279,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -274,6 +276,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.playerMobDistanceMap.remove(player); } // Paper end - per player mob spawning @@ -1405,7 +1405,7 @@ index 4f6473398edd9987dfbb6cef79ed1bc93c3dd809..d98c489a58c8c2e657a8879b991aa57e } void updateMaps(ServerPlayer player) { -@@ -288,7 +291,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -285,7 +288,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider com.destroystokyo.paper.util.misc.PlayerAreaMap trackMap = this.playerEntityTrackerTrackMaps[i]; int trackRange = this.entityTrackerTrackRanges[i]; @@ -1414,7 +1414,7 @@ index 4f6473398edd9987dfbb6cef79ed1bc93c3dd809..d98c489a58c8c2e657a8879b991aa57e } // Paper end - use distance map to optimise entity tracker this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise ChunkMap#anyPlayerCloseEnoughForSpawning -@@ -298,6 +301,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -295,6 +298,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.playerMobDistanceMap.update(player, chunkX, chunkZ, this.distanceManager.getSimulationDistance()); } // Paper end - per player mob spawning @@ -1422,7 +1422,7 @@ index 4f6473398edd9987dfbb6cef79ed1bc93c3dd809..d98c489a58c8c2e657a8879b991aa57e } // Paper end // Paper start -@@ -1452,11 +1456,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1447,11 +1451,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider completablefuture1.thenAcceptAsync((either) -> { either.ifLeft((chunk) -> { this.tickingGenerated.getAndIncrement(); @@ -1435,12 +1435,12 @@ index 4f6473398edd9987dfbb6cef79ed1bc93c3dd809..d98c489a58c8c2e657a8879b991aa57e }); }, (runnable) -> { this.mainThreadMailbox.tell(ChunkTaskPriorityQueueSorter.message(holder, runnable)); -@@ -1625,33 +1625,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1620,33 +1620,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider int k = this.viewDistance; this.viewDistance = j; - this.distanceManager.updatePlayerTickets(this.viewDistance + 1); -- Iterator objectiterator = this.updatingChunks.getVisibleValuesCopy().iterator(); // Paper +- Iterator objectiterator = net.minecraft.server.ChunkSystem.getUpdatingChunkHolders(this.level).iterator(); // Paper - - while (objectiterator.hasNext()) { - ChunkHolder playerchunk = (ChunkHolder) objectiterator.next(); @@ -1478,16 +1478,16 @@ index 4f6473398edd9987dfbb6cef79ed1bc93c3dd809..d98c489a58c8c2e657a8879b991aa57e if (chunk != null) { this.playerLoadedChunk(player, packet, chunk); -@@ -1682,7 +1673,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1677,7 +1668,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider void dumpChunks(Writer writer) throws IOException { CsvOutput csvwriter = CsvOutput.builder().addColumn("x").addColumn("z").addColumn("level").addColumn("in_memory").addColumn("status").addColumn("full_status").addColumn("accessible_ready").addColumn("ticking_ready").addColumn("entity_ticking_ready").addColumn("ticket").addColumn("spawning").addColumn("block_entity_count").addColumn("ticking_ticket").addColumn("ticking_level").addColumn("block_ticks").addColumn("fluid_ticks").build(writer); - TickingTracker tickingtracker = this.distanceManager.tickingTracker(); + // Paper - replace loader system - ObjectBidirectionalIterator objectbidirectionaliterator = this.updatingChunks.getVisibleMap().clone().long2ObjectEntrySet().fastIterator(); // Paper + Iterator objectbidirectionaliterator = net.minecraft.server.ChunkSystem.getVisibleChunkHolders(this.level).iterator(); // Paper while (objectbidirectionaliterator.hasNext()) { -@@ -1698,7 +1689,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1693,7 +1684,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider // CraftBukkit - decompile error csvwriter.writeRow(chunkcoordintpair.x, chunkcoordintpair.z, playerchunk.getTicketLevel(), optional.isPresent(), optional.map(ChunkAccess::getStatus).orElse(null), optional1.map(LevelChunk::getFullStatus).orElse(null), ChunkMap.printFuture(playerchunk.getFullChunkFuture()), ChunkMap.printFuture(playerchunk.getTickingChunkFuture()), ChunkMap.printFuture(playerchunk.getEntityTickingChunkFuture()), this.distanceManager.getTicketDebugString(i), this.anyPlayerCloseEnoughForSpawning(chunkcoordintpair), optional1.map((chunk) -> { return chunk.getBlockEntities().size(); @@ -1496,7 +1496,7 @@ index 4f6473398edd9987dfbb6cef79ed1bc93c3dd809..d98c489a58c8c2e657a8879b991aa57e return chunk.getBlockTicks().count(); }).orElse(0), optional1.map((chunk) -> { return chunk.getFluidTicks().count(); -@@ -1932,15 +1923,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1927,15 +1918,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.removePlayerFromDistanceMaps(player); // Paper - distance maps } @@ -1513,7 +1513,7 @@ index 4f6473398edd9987dfbb6cef79ed1bc93c3dd809..d98c489a58c8c2e657a8879b991aa57e } -@@ -1948,7 +1931,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1943,7 +1926,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider SectionPos sectionposition = SectionPos.of((EntityAccess) player); player.setLastSectionPos(sectionposition); @@ -1522,7 +1522,7 @@ index 4f6473398edd9987dfbb6cef79ed1bc93c3dd809..d98c489a58c8c2e657a8879b991aa57e return sectionposition; } -@@ -1993,65 +1976,40 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1988,65 +1971,40 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider int k1; int l1; @@ -1610,7 +1610,7 @@ index 4f6473398edd9987dfbb6cef79ed1bc93c3dd809..d98c489a58c8c2e657a8879b991aa57e } public void addEntity(Entity entity) { -@@ -2420,7 +2378,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -2415,7 +2373,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider double vec3d_dx = player.getX() - this.entity.getX(); double vec3d_dz = player.getZ() - this.entity.getZ(); // Paper end - remove allocation of Vec3D here @@ -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 96a232f22b1c270b91635ce9c7c6cacc63b026cc..59acbf6249f8f5285504c0ddea448a3433d1d68d 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 -@@ -844,17 +844,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 96a232f22b1c270b91635ce9c7c6cacc63b026cc..59acbf6249f8f5285504c0ddea448a34 } public void save(boolean flush) { -@@ -911,6 +904,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 96a232f22b1c270b91635ce9c7c6cacc63b026cc..59acbf6249f8f5285504c0ddea448a34 this.tickChunks(); this.level.timings.chunks.stopTiming(); // Paper - timings } -@@ -1024,13 +1018,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 96a232f22b1c270b91635ce9c7c6cacc63b026cc..59acbf6249f8f5285504c0ddea448a34 this.level.tickChunk(chunk1, k); if ((chunksTicked++ & 1) == 0) net.minecraft.server.MinecraftServer.getServer().executeMidTickTasks(); // Paper } -@@ -1259,6 +1253,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 @@ -1855,10 +1855,10 @@ index 96a232f22b1c270b91635ce9c7c6cacc63b026cc..59acbf6249f8f5285504c0ddea448a34 return true; } else { diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 01fd17fa845d4f03f3e7e599f42e56f51dd52ff6..b021fc77687cf7f569e5bf6fbb481c486e27e5a6 100644 +index 3bb6dbdd05ed981f70556c8f905d1eeeeade30b8..e71ae32d9827d8a6fb8543abdba7627897ac9f2e 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -676,7 +676,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -682,7 +682,7 @@ public class ServerLevel extends Level implements WorldGenLevel { gameprofilerfiller.push("checkDespawn"); entity.checkDespawn(); gameprofilerfiller.pop(); @@ -1867,7 +1867,7 @@ index 01fd17fa845d4f03f3e7e599f42e56f51dd52ff6..b021fc77687cf7f569e5bf6fbb481c48 Entity entity1 = entity.getVehicle(); if (entity1 != null) { -@@ -709,7 +709,10 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -715,7 +715,10 @@ public class ServerLevel extends Level implements WorldGenLevel { @Override public boolean shouldTickBlocksAt(long chunkPos) { @@ -1879,7 +1879,7 @@ index 01fd17fa845d4f03f3e7e599f42e56f51dd52ff6..b021fc77687cf7f569e5bf6fbb481c48 } protected void tickTime() { -@@ -2453,7 +2456,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2459,7 +2462,7 @@ public class ServerLevel extends Level implements WorldGenLevel { private boolean isPositionTickingWithEntitiesLoaded(long chunkPos) { // Paper start - optimize is ticking ready type functions ChunkHolder chunkHolder = this.chunkSource.chunkMap.getVisibleChunkIfPresent(chunkPos); @@ -1889,10 +1889,10 @@ index 01fd17fa845d4f03f3e7e599f42e56f51dd52ff6..b021fc77687cf7f569e5bf6fbb481c48 } diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index de72b42065d1b24d195e79f3627c7fa2d276fb1e..f5bfd027759a28fd83c244d58e941a24142a3d05 100644 +index b35b36527294dd697d146d2ad817d7911145ae8c..18c3d4aecf498f78040c27336d2ea56fd911d034 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -2495,5 +2495,5 @@ public class ServerPlayer extends Player { +@@ -2475,5 +2475,5 @@ public class ServerPlayer extends Player { } // CraftBukkit end @@ -1900,10 +1900,10 @@ index de72b42065d1b24d195e79f3627c7fa2d276fb1e..f5bfd027759a28fd83c244d58e941a24 + public final int getViewDistance() { throw new UnsupportedOperationException("Use PlayerChunkLoader"); } // Paper - placeholder } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index c0ed1103e649e619c58f59c7bedd6a18a58f71ea..e57636efacedf1c6f1ccd4f01f7e94d6fda2ff4f 100644 +index 67f90c75aa4858bf1575bf7b0a62b8113de7c2ea..b588e14b2826bda5b03b4fc497efcb96b566541a 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -273,7 +273,7 @@ public abstract class PlayerList { +@@ -276,7 +276,7 @@ public abstract class PlayerList { boolean flag1 = gamerules.getBoolean(GameRules.RULE_REDUCEDDEBUGINFO); // Spigot - view distance @@ -1912,7 +1912,7 @@ index c0ed1103e649e619c58f59c7bedd6a18a58f71ea..e57636efacedf1c6f1ccd4f01f7e94d6 player.getBukkitEntity().sendSupportedChannels(); // CraftBukkit playerconnection.send(new ClientboundCustomPayloadPacket(ClientboundCustomPayloadPacket.BRAND, (new FriendlyByteBuf(Unpooled.buffer())).writeUtf(this.getServer().getServerModName()))); playerconnection.send(new ClientboundChangeDifficultyPacket(worlddata.getDifficulty(), worlddata.isDifficultyLocked())); -@@ -942,8 +942,8 @@ public abstract class PlayerList { +@@ -949,8 +949,8 @@ public abstract class PlayerList { // CraftBukkit start LevelData worlddata = worldserver1.getLevelData(); entityplayer1.connection.send(new ClientboundRespawnPacket(worldserver1.dimensionTypeId(), worldserver1.dimension(), BiomeManager.obfuscateSeed(worldserver1.getSeed()), entityplayer1.gameMode.getGameModeForPlayer(), entityplayer1.gameMode.getPreviousGameModeForPlayer(), worldserver1.isDebug(), worldserver1.isFlat(), flag, entityplayer1.getLastDeathLocation())); @@ -1923,7 +1923,7 @@ index c0ed1103e649e619c58f59c7bedd6a18a58f71ea..e57636efacedf1c6f1ccd4f01f7e94d6 entityplayer1.spawnIn(worldserver1); entityplayer1.unsetRemoved(); entityplayer1.connection.teleport(new Location(worldserver1.getWorld(), entityplayer1.getX(), entityplayer1.getY(), entityplayer1.getZ(), entityplayer1.getYRot(), entityplayer1.getXRot())); -@@ -1485,7 +1485,7 @@ public abstract class PlayerList { +@@ -1519,7 +1519,7 @@ public abstract class PlayerList { public void setViewDistance(int viewDistance) { this.viewDistance = viewDistance; @@ -1932,7 +1932,7 @@ index c0ed1103e649e619c58f59c7bedd6a18a58f71ea..e57636efacedf1c6f1ccd4f01f7e94d6 Iterator iterator = this.server.getAllLevels().iterator(); while (iterator.hasNext()) { -@@ -1500,7 +1500,7 @@ public abstract class PlayerList { +@@ -1534,7 +1534,7 @@ public abstract class PlayerList { public void setSimulationDistance(int simulationDistance) { this.simulationDistance = simulationDistance; @@ -1984,10 +1984,10 @@ index 0b3e9e4ed162a6d9e1f3f55b9522b75c94d13254..fa1ff2e79954089552974cefedfcbff2 double deltaZ = soundPos.getZ() - player.getZ(); double distanceSquared = deltaX * deltaX + deltaZ * deltaZ; diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 13c4b7aee9b9802edbaf7e4df9e9355667e727bb..9c036f7be422fd8447726478eee15a77637fdb9c 100644 +index 931de769a3b7c993d151f3ee8e1038d95d3899a3..30140ae5a74a511c9031b8e772e724b25e56de3d 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -628,6 +628,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -627,6 +627,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { if ((i & 2) != 0 && (!this.isClientSide || (i & 4) == 0) && (this.isClientSide || chunk == null || (chunk.getFullStatus() != null && chunk.getFullStatus().isOrAfter(ChunkHolder.FullChunkStatus.TICKING)))) { // allow chunk to be null here as chunk.isReady() is false when we send our notification during block placement this.sendBlockUpdated(blockposition, iblockdata1, iblockdata, i); @@ -2000,7 +2000,7 @@ index 13c4b7aee9b9802edbaf7e4df9e9355667e727bb..9c036f7be422fd8447726478eee15a77 if ((i & 1) != 0) { diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -index 0de0519c01886a39399233b275db44b95e2f3d96..c46cbbf9ac4c5661933b03bc0b2559f7ade8c798 100644 +index d870cefbe5b7485f423817f4f639e3e2a304640c..2292cb0e0c1a3e0ed34b941f028136bfb0bff13e 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -191,6 +191,43 @@ public class LevelChunk extends ChunkAccess { @@ -2079,10 +2079,38 @@ index 0de0519c01886a39399233b275db44b95e2f3d96..c46cbbf9ac4c5661933b03bc0b2559f7 @Nullable diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 6e36b6c722e647fe3672d782447a09030381137e..17b85478749be5be2bec19e49f26e03ebae29852 100644 +index 73e7181655b78f5bff90d07edfe6c5408cc08235..cf6fce4f3bddcbbae59fd128cf661e4506b9d2c5 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -2280,43 +2280,56 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -483,10 +483,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { + ChunkHolder playerChunk = this.world.getChunkSource().chunkMap.getVisibleChunkIfPresent(ChunkPos.asLong(x, z)); + if (playerChunk == null) return false; + +- playerChunk.getTickingChunkFuture().thenAccept(either -> { +- either.left().ifPresent(chunk -> { ++ // Paper start - rewrite player chunk loader ++ net.minecraft.world.level.chunk.LevelChunk chunk = playerChunk.getSendingChunk(); ++ if (chunk == null) { ++ return false; ++ } ++ // Paper end - rewrite player chunk loader + List playersInRange = playerChunk.playerProvider.getPlayers(playerChunk.getPos(), false); +- if (playersInRange.isEmpty()) return; ++ if (playersInRange.isEmpty()) return true; // Paper - rewrite player chunk loader + + // Paper start - Anti-Xray - Bypass + Map refreshPackets = new HashMap<>(); +@@ -499,8 +503,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { + })); + // Paper end + } +- }); +- }); ++ // Paper - rewrite player chunk loader + + return true; + } +@@ -2234,43 +2237,56 @@ public class CraftWorld extends CraftRegionAccessor implements World { // Spigot start @Override public int getViewDistance() { @@ -2148,10 +2176,10 @@ index 6e36b6c722e647fe3672d782447a09030381137e..17b85478749be5be2bec19e49f26e03e // Paper end - view distance api diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 9312484b50949403372ce6441aca4a4bec056b19..58acaaa4925baa0b83b7eda4beec02f13cefaaa7 100644 +index b318842214ede551215fd68af033feb1c8ef6604..4f5760d782bdfeee25839c50b614301eeb8ba42f 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -584,46 +584,80 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -546,45 +546,80 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } } @@ -2236,8 +2264,7 @@ index 9312484b50949403372ce6441aca4a4bec056b19..58acaaa4925baa0b83b7eda4beec02f1 + + data.setTargetSendViewDistance(viewDistance); } -- // Paper end + // Paper end - implement view distances @Override - public void setCompassTarget(Location loc) { + public T getClientOption(com.destroystokyo.paper.ClientOption type) {