diff options
Diffstat (limited to 'patches/server/0450-Add-Plugin-Tickets-to-API-Chunk-Methods.patch')
-rw-r--r-- | patches/server/0450-Add-Plugin-Tickets-to-API-Chunk-Methods.patch | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/patches/server/0450-Add-Plugin-Tickets-to-API-Chunk-Methods.patch b/patches/server/0450-Add-Plugin-Tickets-to-API-Chunk-Methods.patch new file mode 100644 index 0000000000..506018715e --- /dev/null +++ b/patches/server/0450-Add-Plugin-Tickets-to-API-Chunk-Methods.patch @@ -0,0 +1,121 @@ +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 99a9bf12f2e3e6ac5457da53f6f12118efce5d82..58f361ad664ba45c496ab0817c7ab5e1a017b807 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +@@ -360,7 +360,7 @@ public final class CraftServer implements Server { + this.overrideSpawnLimits(); + console.autosavePeriod = this.configuration.getInt("ticks-per.autosave"); + this.warningState = WarningState.value(this.configuration.getString("settings.deprecated-verbose")); +- TicketType.PLUGIN.timeout = this.configuration.getInt("chunk-gc.period-in-ticks"); ++ TicketType.PLUGIN.timeout = Math.min(20, this.configuration.getInt("chunk-gc.period-in-ticks")); // Paper - cap plugin loads to 1 second + this.minimumAPI = this.configuration.getString("settings.minimum-api"); + this.loadIcon(); + +@@ -931,7 +931,7 @@ public final class CraftServer implements Server { + this.console.setMotd(config.motd); + this.overrideSpawnLimits(); + this.warningState = WarningState.value(this.configuration.getString("settings.deprecated-verbose")); +- TicketType.PLUGIN.timeout = this.configuration.getInt("chunk-gc.period-in-ticks"); ++ TicketType.PLUGIN.timeout = Math.min(20, configuration.getInt("chunk-gc.period-in-ticks")); // Paper - cap plugin loads to 1 second + this.minimumAPI = this.configuration.getString("settings.minimum-api"); + this.printSaveWarning = false; + console.autosavePeriod = this.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 a8ab324bfbaaf946af5998402588244465dd7286..710270775cd47e8df1146ad0636648568d45ac75 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +@@ -282,8 +282,21 @@ public class CraftWorld extends CraftRegionAccessor implements World { + + @Override + public Chunk getChunkAt(int x, int z) { +- return this.world.getChunkSource().getChunk(x, z, true).bukkitChunk; ++ // Paper start - add ticket to hold chunk for a little while longer if plugin accesses it ++ net.minecraft.world.level.chunk.LevelChunk chunk = world.getChunkSource().getChunkAtIfLoadedImmediately(x, z); ++ if (chunk == null) { ++ addTicket(x, z); ++ chunk = this.world.getChunkSource().getChunk(x, z, true); ++ } ++ return chunk.bukkitChunk; ++ // Paper end ++ } ++ ++ // Paper start ++ private void addTicket(int x, int z) { ++ net.minecraft.server.MCUtil.MAIN_EXECUTOR.execute(() -> world.getChunkSource().addRegionTicket(TicketType.PLUGIN, new ChunkPos(x, z), 0, Unit.INSTANCE)); // Paper + } ++ // Paper end + + @Override + public Chunk getChunkAt(Block block) { +@@ -350,7 +363,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { + public boolean unloadChunkRequest(int x, int z) { + org.spigotmc.AsyncCatcher.catchOp("chunk unload"); // Spigot + if (this.isChunkLoaded(x, z)) { +- this.world.getChunkSource().removeRegionTicket(TicketType.PLUGIN, new ChunkPos(x, z), 1, Unit.INSTANCE); ++ this.world.getChunkSource().removeRegionTicket(TicketType.PLUGIN, new ChunkPos(x, z), 0, Unit.INSTANCE); // Paper + } + + return true; +@@ -433,9 +446,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { + org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot + // Paper start - Optimize this method + ChunkPos chunkPos = new ChunkPos(x, z); ++ ChunkAccess immediate = world.getChunkSource().getChunkAtIfLoadedImmediately(x, z); // Paper ++ if (immediate != null) return true; // Paper + + if (!generate) { +- ChunkAccess immediate = world.getChunkSource().getChunkAtImmediately(x, z); ++ ++ //IChunkAccess immediate = world.getChunkProvider().getChunkAtImmediately(x, z); // Paper + if (immediate == null) { + immediate = world.getChunkSource().chunkMap.getUnloadingChunk(x, z); + } +@@ -443,7 +459,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { + if (!(immediate instanceof ImposterProtoChunk) && !(immediate instanceof net.minecraft.world.level.chunk.LevelChunk)) { + return false; // not full status + } +- world.getChunkSource().addRegionTicket(TicketType.PLUGIN, chunkPos, 1, Unit.INSTANCE); ++ world.getChunkSource().addRegionTicket(TicketType.PLUGIN, chunkPos, 0, Unit.INSTANCE); // Paper + world.getChunk(x, z); // make sure we're at ticket level 32 or lower + return true; + } +@@ -469,7 +485,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { + // we do this so we do not re-read the chunk data on disk + } + +- world.getChunkSource().addRegionTicket(TicketType.PLUGIN, chunkPos, 1, Unit.INSTANCE); ++ world.getChunkSource().addRegionTicket(TicketType.PLUGIN, chunkPos, 0, Unit.INSTANCE); // Paper + world.getChunkSource().getChunk(x, z, ChunkStatus.FULL, true); + return true; + // Paper end +@@ -2150,6 +2166,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { + net.minecraft.server.ChunkSystem.scheduleChunkLoad(this.getHandle(), x, z, gen, ChunkStatus.FULL, true, priority, (c) -> { + net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(() -> { + net.minecraft.world.level.chunk.LevelChunk chunk = (net.minecraft.world.level.chunk.LevelChunk)c; ++ if (chunk != null) addTicket(x, z); // Paper + ret.complete(chunk == null ? null : chunk.getBukkitChunk()); + }); + }); |