aboutsummaryrefslogtreecommitdiffhomepage
path: root/Spigot-Server-Patches/0506-Add-Plugin-Tickets-to-API-Chunk-Methods.patch
diff options
context:
space:
mode:
Diffstat (limited to 'Spigot-Server-Patches/0506-Add-Plugin-Tickets-to-API-Chunk-Methods.patch')
-rw-r--r--Spigot-Server-Patches/0506-Add-Plugin-Tickets-to-API-Chunk-Methods.patch122
1 files changed, 122 insertions, 0 deletions
diff --git a/Spigot-Server-Patches/0506-Add-Plugin-Tickets-to-API-Chunk-Methods.patch b/Spigot-Server-Patches/0506-Add-Plugin-Tickets-to-API-Chunk-Methods.patch
new file mode 100644
index 0000000000..8f47b0edce
--- /dev/null
+++ b/Spigot-Server-Patches/0506-Add-Plugin-Tickets-to-API-Chunk-Methods.patch
@@ -0,0 +1,122 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Aikar <[email protected]>
+Date: Tue, 9 Jun 2020 03:33:03 -0400
+Subject: [PATCH] Add Plugin Tickets to API Chunk Methods
+
+Like previous versions, plugins loading chunks kept them loaded until
+they garbage collected to avoid constant spamming of chunk loads
+
+This adds tickets to a few more places so that they can be unloaded.
+
+Additionally, this drops their ticket level to BORDER so they wont be ticking
+so they will just sit inactive instead.
+
+Using .loadChunk to keep a chunk ticking was a horrible idea for upstream
+when we have TWO methods that are able to do that already in the API.
+
+Also reduce their collection count down to a maximum of 1 second. Barely
+anyone knows what chunk-gc is in bukkit.yml as its less relevant now, and
+since this wasn't spigot behavior, this is safe to mostly ignore (unless someone
+wants it to collect even faster, they can restore that setting back to 1 instead of 20+)
+
+Not adding it to .getType() though to keep behavior consistent with vanilla for performance reasons.
+
+diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+index 11c9b740b6b1ff30bd33c188c03f2b77b12faf7b..506e76eecd4be892bdc70367c0ee4d9764569ca7 100644
+--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
++++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+@@ -346,7 +346,7 @@ public final class CraftServer implements Server {
+ ambientSpawn = configuration.getInt("spawn-limits.ambient");
+ console.autosavePeriod = configuration.getInt("ticks-per.autosave");
+ warningState = WarningState.value(configuration.getString("settings.deprecated-verbose"));
+- TicketType.PLUGIN.loadPeriod = configuration.getInt("chunk-gc.period-in-ticks");
++ TicketType.PLUGIN.loadPeriod = Math.min(20, configuration.getInt("chunk-gc.period-in-ticks")); // Paper - cap plugin loads to 1 second
+ minimumAPI = configuration.getString("settings.minimum-api");
+ loadIcon();
+ }
+@@ -829,7 +829,7 @@ public final class CraftServer implements Server {
+ waterAmbientSpawn = configuration.getInt("spawn-limits.water-ambient");
+ ambientSpawn = configuration.getInt("spawn-limits.ambient");
+ warningState = WarningState.value(configuration.getString("settings.deprecated-verbose"));
+- TicketType.PLUGIN.loadPeriod = configuration.getInt("chunk-gc.period-in-ticks");
++ TicketType.PLUGIN.loadPeriod = Math.min(20, configuration.getInt("chunk-gc.period-in-ticks")); // Paper - cap plugin loads to 1 second
+ minimumAPI = configuration.getString("settings.minimum-api");
+ printSaveWarning = false;
+ console.autosavePeriod = configuration.getInt("ticks-per.autosave");
+diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+index cc7c6204b6dcce766a0d3834f2963304b26107c6..06d8ab61f3636a2c76531356f3d7fd6f6be34225 100644
+--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
++++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+@@ -402,9 +402,22 @@ public class CraftWorld implements World {
+
+ @Override
+ public Chunk getChunkAt(int x, int z) {
+- return this.world.getChunkProvider().getChunkAt(x, z, true).bukkitChunk;
++ // Paper start - add ticket to hold chunk for a little while longer if plugin accesses it
++ net.minecraft.server.Chunk chunk = world.getChunkProvider().getChunkAtIfLoadedImmediately(x, z);
++ if (chunk == null) {
++ addTicket(x, z);
++ chunk = this.world.getChunkProvider().getChunkAt(x, z, true);
++ }
++ return chunk.bukkitChunk;
++ // Paper end
+ }
+
++ // Paper start
++ private void addTicket(int x, int z) {
++ MCUtil.MAIN_EXECUTOR.execute(() -> world.getChunkProvider().addTicket(TicketType.PLUGIN, new ChunkCoordIntPair(x, z), 0, Unit.INSTANCE)); // Paper
++ }
++ // Paper end
++
+ @Override
+ public Chunk getChunkAt(Block block) {
+ Preconditions.checkArgument(block != null, "null block");
+@@ -478,7 +491,7 @@ public class CraftWorld implements World {
+ public boolean unloadChunkRequest(int x, int z) {
+ org.spigotmc.AsyncCatcher.catchOp("chunk unload"); // Spigot
+ if (isChunkLoaded(x, z)) {
+- world.getChunkProvider().removeTicket(TicketType.PLUGIN, new ChunkCoordIntPair(x, z), 1, Unit.INSTANCE);
++ world.getChunkProvider().removeTicket(TicketType.PLUGIN, new ChunkCoordIntPair(x, z), 0, Unit.INSTANCE); // Paper
+ }
+
+ return true;
+@@ -555,10 +568,12 @@ public class CraftWorld implements World {
+ org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot
+ // Paper start - Optimize this method
+ ChunkCoordIntPair chunkPos = new ChunkCoordIntPair(x, z);
++ IChunkAccess immediate = world.getChunkProvider().getChunkAtIfLoadedImmediately(x, z); // Paper
++ if (immediate != null) return true; // Paper
+
+ if (!generate) {
+
+- IChunkAccess immediate = world.getChunkProvider().getChunkAtImmediately(x, z);
++ //IChunkAccess immediate = world.getChunkProvider().getChunkAtImmediately(x, z); // Paper
+ if (immediate == null) {
+ immediate = world.getChunkProvider().playerChunkMap.getUnloadingChunk(x, z);
+ }
+@@ -566,7 +581,7 @@ public class CraftWorld implements World {
+ if (!(immediate instanceof ProtoChunkExtension) && !(immediate instanceof net.minecraft.server.Chunk)) {
+ return false; // not full status
+ }
+- world.getChunkProvider().addTicket(TicketType.PLUGIN, chunkPos, 1, Unit.INSTANCE);
++ world.getChunkProvider().addTicket(TicketType.PLUGIN, chunkPos, 0, Unit.INSTANCE); // Paper
+ world.getChunkAt(x, z); // make sure we're at ticket level 32 or lower
+ return true;
+ }
+@@ -593,7 +608,7 @@ public class CraftWorld implements World {
+ // we do this so we do not re-read the chunk data on disk
+ }
+
+- world.getChunkProvider().addTicket(TicketType.PLUGIN, chunkPos, 1, Unit.INSTANCE);
++ world.getChunkProvider().addTicket(TicketType.PLUGIN, chunkPos, 0, Unit.INSTANCE); // Paper
+ world.getChunkProvider().getChunkAt(x, z, ChunkStatus.FULL, true);
+ return true;
+ // Paper end
+@@ -2526,6 +2541,7 @@ public class CraftWorld implements World {
+ }
+ return this.world.getChunkProvider().getChunkAtAsynchronously(x, z, gen, urgent).thenComposeAsync((either) -> {
+ net.minecraft.server.Chunk chunk = (net.minecraft.server.Chunk) either.left().orElse(null);
++ if (chunk != null) addTicket(x, z); // Paper
+ return CompletableFuture.completedFuture(chunk == null ? null : chunk.getBukkitChunk());
+ }, MinecraftServer.getServer());
+ }