diff options
Diffstat (limited to 'Spigot-Server-Patches/0505-Delay-Chunk-Unloads-based-on-Player-Movement.patch')
-rw-r--r-- | Spigot-Server-Patches/0505-Delay-Chunk-Unloads-based-on-Player-Movement.patch | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/Spigot-Server-Patches/0505-Delay-Chunk-Unloads-based-on-Player-Movement.patch b/Spigot-Server-Patches/0505-Delay-Chunk-Unloads-based-on-Player-Movement.patch new file mode 100644 index 0000000000..eaddacca5f --- /dev/null +++ b/Spigot-Server-Patches/0505-Delay-Chunk-Unloads-based-on-Player-Movement.patch @@ -0,0 +1,107 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar <[email protected]> +Date: Sat, 18 Jun 2016 23:22:12 -0400 +Subject: [PATCH] Delay Chunk Unloads based on Player Movement + +When players are moving in the world, doing things such as building or exploring, +they will commonly go back and forth in a small area. This causes a ton of chunk load +and unload activity on the edge chunks of their view distance. + +A simple back and forth movement in 6 blocks could spam a chunk to thrash a +loading and unload cycle over and over again. + +This is very wasteful. This system introduces a delay of inactivity on a chunk +before it actually unloads, which will be handled by the ticket expiry process. + +This allows servers with smaller worlds who do less long distance exploring to stop +wasting cpu cycles on saving/unloading/reloading chunks repeatedly. + +diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +index 5af7e5c815752f2fd2b13c02a905796971401813..6e6534ab25dbebbad5d2ee848edb88ebcae86d03 100644 +--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java ++++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +@@ -634,4 +634,13 @@ public class PaperWorldConfig { + private void viewDistance() { + this.noTickViewDistance = this.getInt("viewdistances.no-tick-view-distance", -1); + } ++ ++ public long delayChunkUnloadsBy; ++ private void delayChunkUnloadsBy() { ++ delayChunkUnloadsBy = PaperConfig.getSeconds(getString("delay-chunk-unloads-by", "10s")); ++ if (delayChunkUnloadsBy > 0) { ++ log("Delaying chunk unloads by " + delayChunkUnloadsBy + " seconds"); ++ delayChunkUnloadsBy *= 20; ++ } ++ } + } +diff --git a/src/main/java/net/minecraft/server/ChunkMapDistance.java b/src/main/java/net/minecraft/server/ChunkMapDistance.java +index 705c6e3a47a76509268075078f95871d313f6b76..eaed04f786b3c1e1a136163b096bd6aeeb571023 100644 +--- a/src/main/java/net/minecraft/server/ChunkMapDistance.java ++++ b/src/main/java/net/minecraft/server/ChunkMapDistance.java +@@ -176,6 +176,27 @@ public abstract class ChunkMapDistance { + boolean removed = false; // CraftBukkit + if (arraysetsorted.remove(ticket)) { + removed = true; // CraftBukkit ++ // Paper start - delay chunk unloads for player tickets ++ long delayChunkUnloadsBy = chunkMap.world.paperConfig.delayChunkUnloadsBy; ++ if (ticket.getTicketType() == TicketType.PLAYER && delayChunkUnloadsBy > 0) { ++ boolean hasPlayer = false; ++ for (Ticket<?> ticket1 : arraysetsorted) { ++ if (ticket1.getTicketType() == TicketType.PLAYER) { ++ hasPlayer = true; ++ break; ++ } ++ } ++ PlayerChunk playerChunk = chunkMap.getUpdatingChunk(i); ++ if (!hasPlayer && playerChunk != null && playerChunk.isFullChunkReady()) { ++ Ticket<Long> delayUnload = new Ticket<Long>(TicketType.DELAY_UNLOAD, 33, i); ++ delayUnload.delayUnloadBy = delayChunkUnloadsBy; ++ delayUnload.setCurrentTick(this.currentTick); ++ arraysetsorted.remove(delayUnload); ++ // refresh ticket ++ arraysetsorted.add(delayUnload); ++ } ++ } ++ // Paper end + } + + if (arraysetsorted.isEmpty()) { +diff --git a/src/main/java/net/minecraft/server/Ticket.java b/src/main/java/net/minecraft/server/Ticket.java +index b5030d6f5d917ba33fb3c40903384fa7a56bc5f1..e41cb8613efc86499dfe3be36c9130ab6dc9b89e 100644 +--- a/src/main/java/net/minecraft/server/Ticket.java ++++ b/src/main/java/net/minecraft/server/Ticket.java +@@ -9,11 +9,13 @@ public final class Ticket<T> implements Comparable<Ticket<?>> { + public final T identifier; public final T getObjectReason() { return this.identifier; } // Paper - OBFHELPER + private long d; public final long getCreationTick() { return this.d; } // Paper - OBFHELPER + public int priority = 0; // Paper ++ public long delayUnloadBy; // Paper + + protected Ticket(TicketType<T> tickettype, int i, T t0) { + this.a = tickettype; + this.b = i; + this.identifier = t0; ++ this.delayUnloadBy = tickettype.loadPeriod; // Paper + } + + public int compareTo(Ticket<?> ticket) { +@@ -63,7 +65,7 @@ public final class Ticket<T> implements Comparable<Ticket<?>> { + } + + protected boolean b(long i) { +- long j = this.a.b(); ++ long j = delayUnloadBy; // Paper + + return j != 0L && i - this.d > j; + } +diff --git a/src/main/java/net/minecraft/server/TicketType.java b/src/main/java/net/minecraft/server/TicketType.java +index 6fd852db6bcfbfbf84ec2acf6d23b08a6051165c..5c789b25f1df2eae8ea8ceb4ba977ba336fe6d5e 100644 +--- a/src/main/java/net/minecraft/server/TicketType.java ++++ b/src/main/java/net/minecraft/server/TicketType.java +@@ -26,6 +26,7 @@ public class TicketType<T> { + public static final TicketType<Long> ASYNC_LOAD = a("async_load", Long::compareTo); // Paper + public static final TicketType<ChunkCoordIntPair> PRIORITY = a("priority", Comparator.comparingLong(ChunkCoordIntPair::pair), 300); // Paper + public static final TicketType<ChunkCoordIntPair> URGENT = a("urgent", Comparator.comparingLong(ChunkCoordIntPair::pair), 300); // Paper ++ public static final TicketType<Long> DELAY_UNLOAD = a("delay_unload", Long::compareTo, 300); // Paper + + public static <T> TicketType<T> a(String s, Comparator<T> comparator) { + return new TicketType<>(s, comparator, 0L); |