2021-06-11 12:02:28 +00:00
|
|
|
From 0000000000000000000000000000000000000000 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/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
2022-07-23 01:56:50 +00:00
|
|
|
index 86a87ebf18b7f4dd08d85b6bbbc6962d1176a933..c7d06aa55f5cc569890c50acc6c4e6fd9d44fbec 100644
|
2021-06-11 12:02:28 +00:00
|
|
|
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
2022-07-23 01:56:50 +00:00
|
|
|
@@ -727,31 +727,34 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
2021-06-11 12:02:28 +00:00
|
|
|
|
|
|
|
// CraftBukkit start
|
2021-11-24 04:25:34 +00:00
|
|
|
public void prepareLevels(ChunkProgressListener worldloadlistener, ServerLevel worldserver) {
|
2021-06-11 12:02:28 +00:00
|
|
|
+ ServerChunkCache chunkproviderserver = worldserver.getChunkSource(); // Paper
|
2021-11-24 04:25:34 +00:00
|
|
|
// WorldServer worldserver = this.overworld();
|
2021-06-11 12:02:28 +00:00
|
|
|
this.forceTicks = true;
|
|
|
|
// CraftBukkit end
|
|
|
|
+ if (worldserver.getWorld().getKeepSpawnInMemory()) { // Paper
|
|
|
|
|
|
|
|
MinecraftServer.LOGGER.info("Preparing start region for dimension {}", worldserver.dimension().location());
|
2021-06-13 11:40:34 +00:00
|
|
|
BlockPos blockposition = worldserver.getSharedSpawnPos();
|
2021-06-11 12:02:28 +00:00
|
|
|
|
|
|
|
worldloadlistener.updateSpawnPos(new ChunkPos(blockposition));
|
|
|
|
- ServerChunkCache chunkproviderserver = worldserver.getChunkSource();
|
|
|
|
+ //ChunkProviderServer chunkproviderserver = worldserver.getChunkProvider(); // Paper - move up
|
|
|
|
|
|
|
|
chunkproviderserver.getLightEngine().setTaskPerBatch(500);
|
|
|
|
this.nextTickTime = Util.getMillis();
|
2022-03-04 08:33:13 +00:00
|
|
|
- // CraftBukkit start
|
|
|
|
- if (worldserver.getWorld().getKeepSpawnInMemory()) {
|
|
|
|
- chunkproviderserver.addRegionTicket(TicketType.START, new ChunkPos(blockposition), 11, Unit.INSTANCE);
|
2021-06-11 12:02:28 +00:00
|
|
|
-
|
2022-03-04 08:33:13 +00:00
|
|
|
- while (chunkproviderserver.getTickingGenerated() != 441) {
|
|
|
|
- // this.nextTickTime = SystemUtils.getMillis() + 10L;
|
|
|
|
- this.executeModerately();
|
|
|
|
- }
|
2021-06-11 12:02:28 +00:00
|
|
|
- }
|
|
|
|
+ // Paper start - configurable spawn reason
|
2022-06-11 14:58:17 +00:00
|
|
|
+ int radiusBlocks = worldserver.paperConfig().spawn.keepSpawnLoadedRange * 16;
|
2021-06-11 12:02:28 +00:00
|
|
|
+ int radiusChunks = radiusBlocks / 16 + ((radiusBlocks & 15) != 0 ? 1 : 0);
|
|
|
|
+ int totalChunks = ((radiusChunks) * 2 + 1);
|
|
|
|
+ totalChunks *= totalChunks;
|
|
|
|
+ worldloadlistener.setChunkRadius(radiusBlocks / 16);
|
|
|
|
+
|
|
|
|
+ worldserver.addTicketsForSpawn(radiusBlocks, blockposition);
|
|
|
|
+ // Paper end
|
2021-06-13 11:40:34 +00:00
|
|
|
|
2021-11-24 04:25:34 +00:00
|
|
|
// this.nextTickTime = SystemUtils.getMillis() + 10L;
|
2021-06-11 12:02:28 +00:00
|
|
|
this.executeModerately();
|
2021-11-24 04:25:34 +00:00
|
|
|
// Iterator iterator = this.levels.values().iterator();
|
2021-06-11 12:02:28 +00:00
|
|
|
+ }
|
|
|
|
|
|
|
|
if (true) {
|
|
|
|
ServerLevel worldserver1 = worldserver;
|
2022-07-23 01:56:50 +00:00
|
|
|
@@ -774,7 +777,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
2021-11-24 04:25:34 +00:00
|
|
|
// this.nextTickTime = SystemUtils.getMillis() + 10L;
|
2021-06-11 12:02:28 +00:00
|
|
|
this.executeModerately();
|
|
|
|
// CraftBukkit end
|
|
|
|
- worldloadlistener.stop();
|
|
|
|
+ if (worldserver.getWorld().getKeepSpawnInMemory()) worldloadlistener.stop(); // Paper
|
|
|
|
chunkproviderserver.getLightEngine().setTaskPerBatch(5);
|
|
|
|
// CraftBukkit start
|
2021-11-24 04:25:34 +00:00
|
|
|
// this.updateMobSpawningFlags();
|
2021-06-11 12:02:28 +00:00
|
|
|
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
2022-07-03 21:55:56 +00:00
|
|
|
index 65eaf93c135871b3898cd418bfe3aca8368e092e..aa77a3dbbcb77fb6f3ad070b83426042dd284aa0 100644
|
2021-06-11 12:02:28 +00:00
|
|
|
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
2022-03-01 05:43:03 +00:00
|
|
|
@@ -63,6 +63,7 @@ import net.minecraft.network.protocol.game.ClientboundSoundEntityPacket;
|
2021-06-13 11:40:34 +00:00
|
|
|
import net.minecraft.network.protocol.game.ClientboundSoundPacket;
|
2021-06-11 12:02:28 +00:00
|
|
|
import net.minecraft.network.protocol.game.DebugPackets;
|
|
|
|
import net.minecraft.resources.ResourceKey;
|
|
|
|
+import net.minecraft.server.MCUtil;
|
|
|
|
import net.minecraft.server.MinecraftServer;
|
|
|
|
import net.minecraft.server.ServerScoreboard;
|
|
|
|
import net.minecraft.server.level.progress.ChunkProgressListener;
|
2022-06-10 01:20:47 +00:00
|
|
|
@@ -1713,12 +1714,84 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
2021-06-13 11:40:34 +00:00
|
|
|
return ((MapIndex) this.getServer().overworld().getDataStorage().computeIfAbsent(MapIndex::load, MapIndex::new, "idcounts")).getFreeAuxValueForMap();
|
2021-06-11 12:02:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
+ // Paper start - helper function for configurable spawn radius
|
|
|
|
+ public void addTicketsForSpawn(int radiusInBlocks, BlockPos 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
|
|
|
|
+ ServerChunkCache chunkproviderserver = this.getChunkSource();
|
|
|
|
+ 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
|
2021-06-17 17:11:00 +00:00
|
|
|
+ chunkproviderserver.addRegionTicket(TicketType.START, new ChunkPos(spawn.offset(x, 0, z)), 2, Unit.INSTANCE);
|
2021-06-11 12:02:28 +00:00
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // add border chunks
|
|
|
|
+
|
|
|
|
+ // add border along x axis (including corner chunks)
|
|
|
|
+ for (int x = -radiusInBlocks; x <= radiusInBlocks; x += 16) {
|
|
|
|
+ // top
|
2021-06-17 17:11:00 +00:00
|
|
|
+ chunkproviderserver.addRegionTicket(TicketType.START, new ChunkPos(spawn.offset(x, 0, radiusInBlocks)), 1, Unit.INSTANCE); // level 32
|
2021-06-11 12:02:28 +00:00
|
|
|
+ // bottom
|
2021-06-17 17:11:00 +00:00
|
|
|
+ chunkproviderserver.addRegionTicket(TicketType.START, new ChunkPos(spawn.offset(x, 0, -radiusInBlocks)), 1, Unit.INSTANCE); // level 32
|
2021-06-11 12:02:28 +00:00
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // add border along z axis (excluding corner chunks)
|
|
|
|
+ for (int z = -radiusInBlocks + 16; z < radiusInBlocks; z += 16) {
|
|
|
|
+ // right
|
2021-06-17 17:11:00 +00:00
|
|
|
+ chunkproviderserver.addRegionTicket(TicketType.START, new ChunkPos(spawn.offset(radiusInBlocks, 0, z)), 1, Unit.INSTANCE); // level 32
|
2021-06-11 12:02:28 +00:00
|
|
|
+ // left
|
2021-06-17 17:11:00 +00:00
|
|
|
+ chunkproviderserver.addRegionTicket(TicketType.START, new ChunkPos(spawn.offset(-radiusInBlocks, 0, z)), 1, Unit.INSTANCE); // level 32
|
2021-06-11 12:02:28 +00:00
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ public void removeTicketsForSpawn(int radiusInBlocks, BlockPos 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
|
|
|
|
+ ServerChunkCache chunkproviderserver = this.getChunkSource();
|
|
|
|
+ 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
|
2021-06-17 17:11:00 +00:00
|
|
|
+ chunkproviderserver.removeRegionTicket(TicketType.START, new ChunkPos(spawn.offset(x, 0, z)), 2, Unit.INSTANCE);
|
2021-06-11 12:02:28 +00:00
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // remove border chunks
|
|
|
|
+
|
|
|
|
+ // remove border along x axis (including corner chunks)
|
|
|
|
+ for (int x = -radiusInBlocks; x <= radiusInBlocks; x += 16) {
|
|
|
|
+ // top
|
2021-06-17 17:11:00 +00:00
|
|
|
+ chunkproviderserver.removeRegionTicket(TicketType.START, new ChunkPos(spawn.offset(x, 0, radiusInBlocks)), 1, Unit.INSTANCE); // level 32
|
2021-06-11 12:02:28 +00:00
|
|
|
+ // bottom
|
2021-06-17 17:11:00 +00:00
|
|
|
+ chunkproviderserver.removeRegionTicket(TicketType.START, new ChunkPos(spawn.offset(x, 0, -radiusInBlocks)), 1, Unit.INSTANCE); // level 32
|
2021-06-11 12:02:28 +00:00
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // remove border along z axis (excluding corner chunks)
|
|
|
|
+ for (int z = -radiusInBlocks + 16; z < radiusInBlocks; z += 16) {
|
|
|
|
+ // right
|
2021-06-17 17:11:00 +00:00
|
|
|
+ chunkproviderserver.removeRegionTicket(TicketType.START, new ChunkPos(spawn.offset(radiusInBlocks, 0, z)), 1, Unit.INSTANCE); // level 32
|
2021-06-11 12:02:28 +00:00
|
|
|
+ // left
|
2021-06-17 17:11:00 +00:00
|
|
|
+ chunkproviderserver.removeRegionTicket(TicketType.START, new ChunkPos(spawn.offset(-radiusInBlocks, 0, z)), 1, Unit.INSTANCE); // level 32
|
2021-06-11 12:02:28 +00:00
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // Paper end
|
|
|
|
+
|
|
|
|
public void setDefaultSpawnPos(BlockPos pos, float angle) {
|
|
|
|
- ChunkPos chunkcoordintpair = new ChunkPos(new BlockPos(this.levelData.getXSpawn(), 0, this.levelData.getZSpawn()));
|
|
|
|
+ // Paper - configurable spawn radius
|
2021-06-13 12:43:56 +00:00
|
|
|
+ BlockPos prevSpawn = this.getSharedSpawnPos();
|
2021-06-11 12:02:28 +00:00
|
|
|
+ //ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(new BlockPosition(this.worldData.a(), 0, this.worldData.c()));
|
|
|
|
|
|
|
|
this.levelData.setSpawn(pos, angle);
|
|
|
|
- this.getChunkSource().removeRegionTicket(TicketType.START, chunkcoordintpair, 11, Unit.INSTANCE);
|
|
|
|
- this.getChunkSource().addRegionTicket(TicketType.START, new ChunkPos(pos), 11, Unit.INSTANCE);
|
|
|
|
+ if (this.keepSpawnInMemory) {
|
|
|
|
+ // if this keepSpawnInMemory is false a plugin has already removed our tickets, do not re-add
|
2022-06-11 14:58:17 +00:00
|
|
|
+ this.removeTicketsForSpawn(this.paperConfig().spawn.keepSpawnLoadedRange * 16, prevSpawn);
|
|
|
|
+ this.addTicketsForSpawn(this.paperConfig().spawn.keepSpawnLoadedRange * 16, pos);
|
2021-06-11 12:02:28 +00:00
|
|
|
+ }
|
|
|
|
this.getServer().getPlayerList().broadcastAll(new ClientboundSetDefaultSpawnPositionPacket(pos, angle));
|
|
|
|
}
|
|
|
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/level/progress/ChunkProgressListener.java b/src/main/java/net/minecraft/server/level/progress/ChunkProgressListener.java
|
2021-06-13 11:40:34 +00:00
|
|
|
index 1b565b2809c2d367e21971c5154f35c9763995e6..b0f899835ded29aff108d1674bf4a1a6c89693db 100644
|
2021-06-11 12:02:28 +00:00
|
|
|
--- a/src/main/java/net/minecraft/server/level/progress/ChunkProgressListener.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/level/progress/ChunkProgressListener.java
|
2021-06-13 11:40:34 +00:00
|
|
|
@@ -12,4 +12,6 @@ public interface ChunkProgressListener {
|
|
|
|
void start();
|
2021-06-11 12:02:28 +00:00
|
|
|
|
|
|
|
void stop();
|
|
|
|
+
|
|
|
|
+ void setChunkRadius(int radius); // Paper - allow changing chunk radius
|
|
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/level/progress/LoggerChunkProgressListener.java b/src/main/java/net/minecraft/server/level/progress/LoggerChunkProgressListener.java
|
2022-06-08 02:25:49 +00:00
|
|
|
index 4d2348df25410a0b5364eec066880326d6667dad..286aad3205ef8a9e21a47ef07893844fe857556a 100644
|
2021-06-11 12:02:28 +00:00
|
|
|
--- a/src/main/java/net/minecraft/server/level/progress/LoggerChunkProgressListener.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/level/progress/LoggerChunkProgressListener.java
|
2022-03-01 05:43:03 +00:00
|
|
|
@@ -11,12 +11,19 @@ import org.slf4j.Logger;
|
2021-06-11 12:02:28 +00:00
|
|
|
|
2021-06-13 11:40:34 +00:00
|
|
|
public class LoggerChunkProgressListener implements ChunkProgressListener {
|
2022-03-01 05:43:03 +00:00
|
|
|
private static final Logger LOGGER = LogUtils.getLogger();
|
2021-06-11 12:02:28 +00:00
|
|
|
- private final int maxCount;
|
2022-03-01 05:43:03 +00:00
|
|
|
+ private int maxCount;// Paper - remove final
|
2021-06-11 12:02:28 +00:00
|
|
|
private int count;
|
|
|
|
private long startTime;
|
|
|
|
private long nextTickTime = Long.MAX_VALUE;
|
|
|
|
|
|
|
|
public LoggerChunkProgressListener(int radius) {
|
|
|
|
+ // Paper start - Allow changing radius later for configurable spawn patch
|
|
|
|
+ this.setChunkRadius(radius); // Move to method
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void setChunkRadius(int radius) {
|
2021-06-13 11:40:34 +00:00
|
|
|
+ // Paper end
|
|
|
|
int i = radius * 2 + 1;
|
|
|
|
this.maxCount = i * i;
|
2021-06-11 12:02:28 +00:00
|
|
|
}
|
|
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
2022-07-04 14:38:06 +00:00
|
|
|
index 4687bbd141ace6e1ec3f4abf40b1cd559ae10987..2518674a967a5fbf2229a0fdd60447a62cfbf856 100644
|
2021-06-11 12:02:28 +00:00
|
|
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
|
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
2022-07-04 14:38:06 +00:00
|
|
|
@@ -1357,15 +1357,21 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
2021-06-11 12:02:28 +00:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public void setKeepSpawnInMemory(boolean keepLoaded) {
|
2021-06-13 11:40:34 +00:00
|
|
|
- world.keepSpawnInMemory = keepLoaded;
|
2021-06-11 12:02:28 +00:00
|
|
|
+ // Paper start - Configurable spawn radius
|
|
|
|
+ if (keepLoaded == world.keepSpawnInMemory) {
|
|
|
|
+ // do nothing, nothing has changed
|
|
|
|
+ return;
|
|
|
|
+ }
|
2021-06-13 11:40:34 +00:00
|
|
|
+ this.world.keepSpawnInMemory = keepLoaded;
|
2021-06-11 12:02:28 +00:00
|
|
|
// Grab the worlds spawn chunk
|
2021-06-13 11:40:34 +00:00
|
|
|
BlockPos chunkcoordinates = this.world.getSharedSpawnPos();
|
2021-06-11 12:02:28 +00:00
|
|
|
if (keepLoaded) {
|
2021-06-13 11:40:34 +00:00
|
|
|
- this.world.getChunkSource().addRegionTicket(TicketType.START, new ChunkPos(chunkcoordinates), 11, Unit.INSTANCE);
|
2022-06-11 14:58:17 +00:00
|
|
|
+ this.world.addTicketsForSpawn(this.world.paperConfig().spawn.keepSpawnLoadedRange * 16, chunkcoordinates);
|
2021-06-11 12:02:28 +00:00
|
|
|
} else {
|
|
|
|
- // TODO: doesn't work well if spawn changed....
|
2021-06-13 11:40:34 +00:00
|
|
|
- this.world.getChunkSource().removeRegionTicket(TicketType.START, new ChunkPos(chunkcoordinates), 11, Unit.INSTANCE);
|
2021-10-02 17:21:49 +00:00
|
|
|
+ // TODO: doesn't work well if spawn changed.... // Paper - resolved
|
2022-06-11 14:58:17 +00:00
|
|
|
+ this.world.removeTicketsForSpawn(this.world.paperConfig().spawn.keepSpawnLoadedRange * 16, chunkcoordinates);
|
2021-06-11 12:02:28 +00:00
|
|
|
}
|
|
|
|
+ // Paper end
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|