48b6bfe2a6
Upstream has released updates that appears to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: c987938a SPIGOT-5180: Add Villager#sleep() and #wakeup() methods CraftBukkit Changes:7f33c6a2
SPIGOT-5196: Restore previous version behaviour regarding cancelled BlockBreakEvent6a5fc902
Improve diff in EntityHangingc98d61bf
SPIGOT-4712: Allow spawning of upwards or downwards facing item framesdb971477
SPIGOT-5199: Fix NPE if setting the book of the ItemMeta of a lecternb0ef3996
SPIGOT-4679 Fix black lines after book paragraphs1215188f
SPIGOT-5180: Add Villager#sleep() and #wakeup() methodsc03b2bef
SPIGOT-4975: NPE on WorldGenStronghold When Using Multiple Worlds65ea162c
Ensure Bukkit data pack is always up to date0b107b8d
MC-157395, SPIGOT-5193: Small armor stands do not drop loot6da0abca
SPIGOT-5195: Player loot table does not drop when keepInventory is on8b09d983
SPIGOT-5190: Superfluous EntityCombustEvent called when using fire aspect sword Spigot Changes: 1981d553 SPIGOT-5198: Catch more bad async operations 6a14ca46 Rebuild patches
231 Zeilen
11 KiB
Diff
231 Zeilen
11 KiB
Diff
From f4ac025c6de88b7e2536490ab7f2c624c2268e96 Mon Sep 17 00:00:00 2001
|
|
From: Aikar <aikar@aikar.co>
|
|
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 200df602a..98c2694a2 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 2a9ceacaf..a98e2613a 100644
|
|
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
|
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
|
@@ -1493,13 +1493,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 273afa972..acf151a25 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
|
@@ -1837,15 +1837,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.22.0
|
|
|