diff options
Diffstat (limited to 'Spigot-Server-Patches/0385-Configurable-Keep-Spawn-Loaded-range-per-world.patch')
-rw-r--r-- | Spigot-Server-Patches/0385-Configurable-Keep-Spawn-Loaded-range-per-world.patch | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/Spigot-Server-Patches/0385-Configurable-Keep-Spawn-Loaded-range-per-world.patch b/Spigot-Server-Patches/0385-Configurable-Keep-Spawn-Loaded-range-per-world.patch new file mode 100644 index 0000000000..088374345e --- /dev/null +++ b/Spigot-Server-Patches/0385-Configurable-Keep-Spawn-Loaded-range-per-world.patch @@ -0,0 +1,230 @@ +From b4155a3581c39d61d4eab95e5a6103d77924fe37 Mon Sep 17 00:00:00 2001 +From: Aikar <[email protected]> +Date: Sat, 13 Sep 2014 23:14:43 -0400 +Subject: [PATCH] Configurable Keep Spawn Loaded range per world + +This lets you disable it for some worlds and lower it for others. + +diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +index d8bb13693..de11a91af 100644 +--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java ++++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +@@ -483,4 +483,10 @@ public class PaperWorldConfig { + break; + } + } ++ ++ public short keepLoadedRange; ++ private void keepLoadedRange() { ++ keepLoadedRange = (short) (getInt("keep-spawn-loaded-range", Math.min(spigotConfig.viewDistance, 10)) * 16); ++ log( "Keep Spawn Loaded Range: " + (keepLoadedRange/16)); ++ } + } +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index c70ab3caf..c58f6f50d 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -577,6 +577,13 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas + this.forceTicks = true; + // CraftBukkit end + ++ // Paper start - configurable spawn reason ++ int radiusBlocks = worldserver.paperConfig.keepLoadedRange; ++ worldloadlistener.setChunkRadius(radiusBlocks / 16); ++ int totalChunks = ((radiusBlocks / 16) * 2 + 1); ++ totalChunks *= totalChunks; ++ // Paper end ++ + MinecraftServer.LOGGER.info("Preparing start region for dimension '{}'/{}", worldserver.getWorldData().getName(), DimensionManager.a(worldserver.worldProvider.getDimensionManager().getType())); // CraftBukkit + BlockPosition blockposition = worldserver.getSpawn(); + +@@ -585,14 +592,19 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas + + chunkproviderserver.getLightEngine().a(500); + this.nextTick = SystemUtils.getMonotonicMillis(); +- chunkproviderserver.addTicket(TicketType.START, new ChunkCoordIntPair(blockposition), 11, Unit.INSTANCE); ++ // Paper start - Configurable spawn radius ++ if (worldserver.keepSpawnInMemory) { ++ worldserver.addTicketsForSpawn(radiusBlocks, blockposition); ++ } + +- while (chunkproviderserver.b() != 441) { ++ while (worldserver.keepSpawnInMemory && chunkproviderserver.b() != totalChunks) { ++ // Paper end + // CraftBukkit start + // this.nextTick = SystemUtils.getMonotonicMillis() + 10L; + this.executeModerately(); + // CraftBukkit end + } ++ LOGGER.info("Loaded " + chunkproviderserver.b() + " spawn chunks for world " + worldserver.getWorldData().getName()); // Paper + + // CraftBukkit start + // this.nextTick = SystemUtils.getMonotonicMillis() + 10L; +diff --git a/src/main/java/net/minecraft/server/WorldLoadListener.java b/src/main/java/net/minecraft/server/WorldLoadListener.java +index d6762d385..7b6f5b2da 100644 +--- a/src/main/java/net/minecraft/server/WorldLoadListener.java ++++ b/src/main/java/net/minecraft/server/WorldLoadListener.java +@@ -9,4 +9,6 @@ public interface WorldLoadListener { + void a(ChunkCoordIntPair chunkcoordintpair, @Nullable ChunkStatus chunkstatus); + + void b(); ++ ++ void setChunkRadius(int radius); // Paper - allow changing chunk radius + } +diff --git a/src/main/java/net/minecraft/server/WorldLoadListenerLogger.java b/src/main/java/net/minecraft/server/WorldLoadListenerLogger.java +index 3868572ae..ae77805f7 100644 +--- a/src/main/java/net/minecraft/server/WorldLoadListenerLogger.java ++++ b/src/main/java/net/minecraft/server/WorldLoadListenerLogger.java +@@ -7,16 +7,24 @@ import org.apache.logging.log4j.Logger; + public class WorldLoadListenerLogger implements WorldLoadListener { + + private static final Logger LOGGER = LogManager.getLogger(); +- private final int b; ++ private int b; // Paper - remove final + private int c; + private long d; + private long e = Long.MAX_VALUE; + + public WorldLoadListenerLogger(int i) { +- int j = i * 2 + 1; ++ // Paper start - Allow changing radius later for configurable spawn patch ++ this.setChunkRadius(i); // Move to method ++ } ++ ++ @Override ++ public void setChunkRadius(int radius) { ++ // Paper - copied from above ++ int j = radius * 2 + 1; + + this.b = j * j; + } ++ // Paper end + + @Override + public void a(ChunkCoordIntPair chunkcoordintpair) { +diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java +index 0f8f54d8e..8a3124fed 100644 +--- a/src/main/java/net/minecraft/server/WorldServer.java ++++ b/src/main/java/net/minecraft/server/WorldServer.java +@@ -1525,13 +1525,85 @@ public class WorldServer extends World { + return ((PersistentIdCounts) this.getMinecraftServer().getWorldServer(DimensionManager.OVERWORLD).getWorldPersistentData().a(PersistentIdCounts::new, "idcounts")).a(); + } + ++ // Paper start - helper function for configurable spawn radius ++ public void addTicketsForSpawn(int radiusInBlocks, BlockPosition spawn) { ++ // In order to respect vanilla behavior, which is ensuring everything but the spawn border can tick, we add tickets ++ // with level 31 for the non-border spawn chunks ++ ChunkProviderServer chunkproviderserver = this.getChunkProvider(); ++ int tickRadius = radiusInBlocks - 16; ++ ++ // add ticking chunks ++ for (int x = -tickRadius; x <= tickRadius; x += 16) { ++ for (int z = -tickRadius; z <= tickRadius; z += 16) { ++ // radius of 2 will have the current chunk be level 31 ++ chunkproviderserver.addTicket(TicketType.START, new ChunkCoordIntPair(spawn.add(x, 0, z)), 2, Unit.INSTANCE); ++ } ++ } ++ ++ // add border chunks ++ ++ // add border along x axis (including corner chunks) ++ for (int x = -radiusInBlocks; x <= radiusInBlocks; x += 16) { ++ // top ++ chunkproviderserver.addTicket(TicketType.START, new ChunkCoordIntPair(spawn.add(x, 0, radiusInBlocks)), 1, Unit.INSTANCE); // level 32 ++ // bottom ++ chunkproviderserver.addTicket(TicketType.START, new ChunkCoordIntPair(spawn.add(x, 0, -radiusInBlocks)), 1, Unit.INSTANCE); // level 32 ++ } ++ ++ // add border along z axis (excluding corner chunks) ++ for (int z = -radiusInBlocks + 16; z < radiusInBlocks; z += 16) { ++ // right ++ chunkproviderserver.addTicket(TicketType.START, new ChunkCoordIntPair(spawn.add(radiusInBlocks, 0, z)), 1, Unit.INSTANCE); // level 32 ++ // left ++ chunkproviderserver.addTicket(TicketType.START, new ChunkCoordIntPair(spawn.add(-radiusInBlocks, 0, z)), 1, Unit.INSTANCE); // level 32 ++ } ++ } ++ public void removeTicketsForSpawn(int radiusInBlocks, BlockPosition spawn) { ++ // In order to respect vanilla behavior, which is ensuring everything but the spawn border can tick, we added tickets ++ // with level 31 for the non-border spawn chunks ++ ChunkProviderServer chunkproviderserver = this.getChunkProvider(); ++ int tickRadius = radiusInBlocks - 16; ++ ++ // remove ticking chunks ++ for (int x = -tickRadius; x <= tickRadius; x += 16) { ++ for (int z = -tickRadius; z <= tickRadius; z += 16) { ++ // radius of 2 will have the current chunk be level 31 ++ chunkproviderserver.removeTicket(TicketType.START, new ChunkCoordIntPair(spawn.add(x, 0, z)), 2, Unit.INSTANCE); ++ } ++ } ++ ++ // remove border chunks ++ ++ // remove border along x axis (including corner chunks) ++ for (int x = -radiusInBlocks; x <= radiusInBlocks; x += 16) { ++ // top ++ chunkproviderserver.removeTicket(TicketType.START, new ChunkCoordIntPair(spawn.add(x, 0, radiusInBlocks)), 1, Unit.INSTANCE); // level 32 ++ // bottom ++ chunkproviderserver.removeTicket(TicketType.START, new ChunkCoordIntPair(spawn.add(x, 0, -radiusInBlocks)), 1, Unit.INSTANCE); // level 32 ++ } ++ ++ // remove border along z axis (excluding corner chunks) ++ for (int z = -radiusInBlocks + 16; z < radiusInBlocks; z += 16) { ++ // right ++ chunkproviderserver.removeTicket(TicketType.START, new ChunkCoordIntPair(spawn.add(radiusInBlocks, 0, z)), 1, Unit.INSTANCE); // level 32 ++ // left ++ chunkproviderserver.removeTicket(TicketType.START, new ChunkCoordIntPair(spawn.add(-radiusInBlocks, 0, z)), 1, Unit.INSTANCE); // level 32 ++ } ++ } ++ // Paper end ++ + @Override + public void a_(BlockPosition blockposition) { +- ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(new BlockPosition(this.worldData.b(), 0, this.worldData.d())); ++ // Paper - configurable spawn radius ++ BlockPosition prevSpawn = this.getSpawn(); + + super.a_(blockposition); +- this.getChunkProvider().removeTicket(TicketType.START, chunkcoordintpair, 11, Unit.INSTANCE); +- this.getChunkProvider().addTicket(TicketType.START, new ChunkCoordIntPair(blockposition), 11, Unit.INSTANCE); ++ if (this.keepSpawnInMemory) { ++ // if this keepSpawnInMemory is false a plugin has already removed our tickets, do not re-add ++ this.removeTicketsForSpawn(this.paperConfig.keepLoadedRange, prevSpawn); ++ this.addTicketsForSpawn(this.paperConfig.keepLoadedRange, blockposition); ++ } ++ // Paper end + } + + public LongSet getForceLoadedChunks() { +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +index 38939ce81..0c31c349a 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +@@ -1853,15 +1853,21 @@ public class CraftWorld implements World { + + @Override + public void setKeepSpawnInMemory(boolean keepLoaded) { ++ // Paper start - Configurable spawn radius ++ if (keepLoaded == world.keepSpawnInMemory) { ++ // do nothing, nothing has changed ++ return; ++ } + world.keepSpawnInMemory = keepLoaded; + // Grab the worlds spawn chunk +- BlockPosition chunkcoordinates = this.world.getSpawn(); ++ BlockPosition prevSpawn = this.world.getSpawn(); + if (keepLoaded) { +- world.getChunkProvider().addTicket(TicketType.START, new ChunkCoordIntPair(chunkcoordinates), 11, Unit.INSTANCE); ++ world.addTicketsForSpawn(world.paperConfig.keepLoadedRange, prevSpawn); + } else { +- // TODO: doesn't work well if spawn changed.... +- world.getChunkProvider().removeTicket(TicketType.START, new ChunkCoordIntPair(chunkcoordinates), 11, Unit.INSTANCE); ++ // TODO: doesn't work well if spawn changed.... // paper - resolved ++ world.removeTicketsForSpawn(world.paperConfig.keepLoadedRange, prevSpawn); + } ++ // Paper end + } + + @Override +-- +2.23.0 + |