aboutsummaryrefslogtreecommitdiffhomepage
path: root/Spigot-Server-Patches/0505-Delay-Chunk-Unloads-based-on-Player-Movement.patch
diff options
context:
space:
mode:
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.patch107
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);