From a72d4bb2ab7292da16fff4aee710cffb4c4e04dd Mon Sep 17 00:00:00 2001 From: Aikar Date: Wed, 10 Jun 2020 08:06:34 -0400 Subject: [PATCH] Improve chunk loading speed and prioritization further - Fixes #3530 --- ...k-Priority-Urgency-System-for-Chunks.patch | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/Spigot-Server-Patches/0528-Implement-Chunk-Priority-Urgency-System-for-Chunks.patch b/Spigot-Server-Patches/0528-Implement-Chunk-Priority-Urgency-System-for-Chunks.patch index ec35a4ee2..7045778a7 100644 --- a/Spigot-Server-Patches/0528-Implement-Chunk-Priority-Urgency-System-for-Chunks.patch +++ b/Spigot-Server-Patches/0528-Implement-Chunk-Priority-Urgency-System-for-Chunks.patch @@ -90,7 +90,7 @@ index f617636a22167b06ac8073aa25efd8c7099155f0..0f40793f004639822b9d40521cd21ec5 return new BlockPosition(this.x << 4, 0, this.z << 4); } diff --git a/src/main/java/net/minecraft/server/ChunkMapDistance.java b/src/main/java/net/minecraft/server/ChunkMapDistance.java -index 7702fbefa598bce7e6a2d287f7ec36b78a62bff8..15df19402f2edeb12cc16d61274a1c9d6eaf63ce 100644 +index 7702fbefa598bce7e6a2d287f7ec36b78a62bff8..02d07d3ff5c3b824047402ff1f58aa338a46c254 100644 --- a/src/main/java/net/minecraft/server/ChunkMapDistance.java +++ b/src/main/java/net/minecraft/server/ChunkMapDistance.java @@ -23,6 +23,7 @@ import java.util.concurrent.Executor; @@ -163,7 +163,7 @@ index 7702fbefa598bce7e6a2d287f7ec36b78a62bff8..15df19402f2edeb12cc16d61274a1c9d return removed; // CraftBukkit } -@@ -182,6 +191,112 @@ public abstract class ChunkMapDistance { +@@ -182,6 +191,116 @@ public abstract class ChunkMapDistance { this.addTicketAtLevel(tickettype, chunkcoordintpair, i, t0); } @@ -204,6 +204,10 @@ index 7702fbefa598bce7e6a2d287f7ec36b78a62bff8..15df19402f2edeb12cc16d61274a1c9d + if (chunk != null && chunk.isFullChunkReady()) { + return false; + } ++ if (chunk != null && chunk.getTicketLevel() > 33 && chunkMap.playerViewDistanceNoTickMap.getObjectsInRange(pair) != null) { ++ Ticket ticket = new Ticket<>(TicketType.PLAYER, 33, coords); ++ addTicket(pair, ticket); ++ } + if (getChunkPriority(coords) >= priority) { + return false; + } @@ -276,7 +280,7 @@ index 7702fbefa598bce7e6a2d287f7ec36b78a62bff8..15df19402f2edeb12cc16d61274a1c9d public boolean addTicketAtLevel(TicketType ticketType, ChunkCoordIntPair chunkcoordintpair, int level, T identifier) { return this.addTicket(chunkcoordintpair.pair(), new Ticket<>(ticketType, level, identifier)); // CraftBukkit end -@@ -384,24 +499,25 @@ public abstract class ChunkMapDistance { +@@ -384,24 +503,29 @@ public abstract class ChunkMapDistance { Ticket ticket = new Ticket<>(TicketType.PLAYER, 33, new ChunkCoordIntPair(i)); // Paper - no-tick view distance if (flag1) { @@ -286,7 +290,11 @@ index 7702fbefa598bce7e6a2d287f7ec36b78a62bff8..15df19402f2edeb12cc16d61274a1c9d + // Paper start - smarter ticket delay based on frustum and distance + scheduleChunkLoad(i, MinecraftServer.currentTick, j, (priority) -> { + ChunkMapDistance.this.j.a(ChunkTaskQueueSorter.a(() -> { // CraftBukkit - decompile error -+ if (chunkMap.playerViewDistanceNoTickMap.getObjectsInRange(i) != null && this.c(this.c(i))) { // Copy c(c()) stuff below ++ if (priority < 5 && this.c(this.c(i))) { ++ // Skip throttle for near chunks ++ ChunkMapDistance.this.addTicket(i, ticket); ++ ChunkMapDistance.this.l.add(i); ++ } else if (this.c(this.c(i))) { // Copy c(c()) stuff below + // Paper end ChunkMapDistance.this.addTicket(i, ticket); ChunkMapDistance.this.l.add(i); @@ -309,24 +317,24 @@ index 7702fbefa598bce7e6a2d287f7ec36b78a62bff8..15df19402f2edeb12cc16d61274a1c9d }); }, i, true)); } -@@ -409,6 +525,99 @@ public abstract class ChunkMapDistance { +@@ -409,6 +533,99 @@ public abstract class ChunkMapDistance { } + // Paper start - smart scheduling of player tickets + public void scheduleChunkLoad(long i, long startTick, int initialDistance, java.util.function.Consumer task) { + long elapsed = MinecraftServer.currentTick - startTick; ++ ChunkCoordIntPair chunkPos = new ChunkCoordIntPair(i); + PlayerChunk updatingChunk = chunkMap.getUpdatingChunk(i); -+ if ((updatingChunk != null && updatingChunk.isFullChunkReady()) || !this.c(this.c(i))) { // Copied from above ++ if ((updatingChunk != null && updatingChunk.isFullChunkReady()) || !this.c(this.c(i)) || getChunkPriority(chunkPos) > 0) { // Copied from above + // no longer needed -+ task.accept(initialDistance); ++ task.accept(1); + return; + } + + int desireDelay = 0; + double minDist = Double.MAX_VALUE; + com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet players = chunkMap.playerViewDistanceNoTickMap.getObjectsInRange(i); -+ ChunkCoordIntPair chunkPos = new ChunkCoordIntPair(i); + if (elapsed == 0 && initialDistance <= 4) { + // Aim for no delay on initial 6 chunk radius tickets save on performance of the below code to only > 6 + minDist = initialDistance; @@ -401,7 +409,7 @@ index 7702fbefa598bce7e6a2d287f7ec36b78a62bff8..15df19402f2edeb12cc16d61274a1c9d + if (delay <= 0) { + task.accept((int) minDist); + } else { -+ MCUtil.scheduleTask((int) Math.min(delay, minDist >= 8 ? 60 : 20), () -> scheduleChunkLoad(i, startTick, initialDistance, task), "Player Ticket Delayer"); ++ MCUtil.scheduleTask((int) Math.min(delay, minDist >= 10 ? 40 : (minDist < 6 ? 10 : 20)), () -> scheduleChunkLoad(i, startTick, initialDistance, task), "Player Ticket Delayer"); + } + } + // Paper end