aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--paper-server/patches/features/0003-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch6
-rw-r--r--paper-server/patches/features/0007-Anti-Xray.patch10
-rw-r--r--paper-server/patches/features/0021-Moonrise-optimisation-patches.patch30
-rw-r--r--paper-server/patches/features/0023-Lag-compensation-ticks.patch6
-rw-r--r--paper-server/patches/features/0028-Improved-Watchdog-Support.patch22
-rw-r--r--paper-server/patches/features/0032-Incremental-chunk-and-player-saving.patch14
-rw-r--r--paper-server/patches/features/0036-Optimize-Hoppers.patch4
-rw-r--r--paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch219
-rw-r--r--paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch29
-rw-r--r--paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch16
-rw-r--r--paper-server/patches/sources/net/minecraft/server/players/PlayerList.java.patch18
-rw-r--r--paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch6
-rw-r--r--paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java185
13 files changed, 286 insertions, 279 deletions
diff --git a/paper-server/patches/features/0003-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch b/paper-server/patches/features/0003-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch
index 77da1105f4..a547df5f1b 100644
--- a/paper-server/patches/features/0003-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch
+++ b/paper-server/patches/features/0003-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch
@@ -13,7 +13,7 @@ custom renderers are in use, defaulting to the much simpler Vanilla system.
Additionally, numerous issues to player position tracking on maps has been fixed.
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
-index 678b3027e8c53e6021ea49afa69cdbe5f60dcf25..cce78d73e8adafd66d0f3ffb3fabb5e6c025c7df 100644
+index 1f66adcd70aae7eac3d9f9539163905695581631..34a53bf34d10c56e6f53ce9aab2fc2780509f2f1 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -2282,7 +2282,9 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
@@ -28,10 +28,10 @@ index 678b3027e8c53e6021ea49afa69cdbe5f60dcf25..cce78d73e8adafd66d0f3ffb3fabb5e6
}
}
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
-index 68e3282a0aa23bd41ab7c77be287d2b49461e33c..def43c515030412b147afd6049b100a3153733d2 100644
+index 36e0d3f225a71b75ece7bf3fceeba47af948a6df..ff5889f8fed0707a6654d9d21862e32e2ebc866d 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
-@@ -2607,6 +2607,14 @@ public class ServerPlayer extends Player {
+@@ -2594,6 +2594,14 @@ public class ServerPlayer extends Player {
this.awardStat(Stats.DROP);
}
diff --git a/paper-server/patches/features/0007-Anti-Xray.patch b/paper-server/patches/features/0007-Anti-Xray.patch
index bb7e6f43a4..46c23e31dd 100644
--- a/paper-server/patches/features/0007-Anti-Xray.patch
+++ b/paper-server/patches/features/0007-Anti-Xray.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Anti-Xray
diff --git a/io/papermc/paper/FeatureHooks.java b/io/papermc/paper/FeatureHooks.java
-index 1e5d94cdcdffb4d2940f17bacdf0e6a488e84318..d3aebc7f833764351c8e5fe1fad1aa2f8718ca37 100644
+index b97e0a8d4c429776b86def10739faee089e2bc9b..184e6c6fe2ba522d0ea0774604839320c4152371 100644
--- a/io/papermc/paper/FeatureHooks.java
+++ b/io/papermc/paper/FeatureHooks.java
@@ -7,6 +7,7 @@ import it.unimi.dsi.fastutil.longs.LongSets;
@@ -153,7 +153,7 @@ index 3a384175f8e7f204234bbaf3081bdc20c47a0d4b..5699bc15eba92e22433a20cb8326b59f
private ClientboundLevelChunkWithLightPacket(RegistryFriendlyByteBuf buffer) {
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
-index 7702004b68b7735043914f93b54b4413cd21ba41..4d20bda4cba578c47216d450c99389b744a59008 100644
+index a43b8febcf616aa1662ea126ce60f7973799ea46..cdda7f6272cfc48638df4e0e51b496e91ed77ba5 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -348,7 +348,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
@@ -166,7 +166,7 @@ index 7702004b68b7735043914f93b54b4413cd21ba41..4d20bda4cba578c47216d450c99389b7
this.levelStorageAccess = levelStorageAccess;
this.uuid = org.bukkit.craftbukkit.util.WorldUUID.getUUID(levelStorageAccess.levelDirectory.path().toFile());
diff --git a/net/minecraft/server/level/ServerPlayerGameMode.java b/net/minecraft/server/level/ServerPlayerGameMode.java
-index 23d241e98f37979701f80fb6f7b76954bd699ad6..fd7ad2b1bffe3880def0f0c9a7ed8de5088ecd71 100644
+index 1178af2ba50ad71556e0a5cbde3e5dc290396148..bf2a4c03afb73367a6d2530c78ff9f7c06f7f6a6 100644
--- a/net/minecraft/server/level/ServerPlayerGameMode.java
+++ b/net/minecraft/server/level/ServerPlayerGameMode.java
@@ -298,6 +298,7 @@ public class ServerPlayerGameMode {
@@ -196,10 +196,10 @@ index 342bc843c384761e883de861044f4f8930ae8763..14878690a88fd4de3e2c127086607e6c
if (io.papermc.paper.event.packet.PlayerChunkLoadEvent.getHandlerList().getRegisteredListeners().length > 0) {
new io.papermc.paper.event.packet.PlayerChunkLoadEvent(new org.bukkit.craftbukkit.CraftChunk(chunk), packetListener.getPlayer().getBukkitEntity()).callEvent();
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
-index 8a93d1034eb0dab4b4010d52ddbb0caa5697416d..bafeeab3edbc73f6f86474e18ab4a3d96ce17157 100644
+index 0837c732e60d82c36793a5a030f56d9004a5a83f..b0df94fb5f933491af8b024cc8ecf8b98e448f16 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
-@@ -404,7 +404,7 @@ public abstract class PlayerList {
+@@ -403,7 +403,7 @@ public abstract class PlayerList {
.getOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS);
player.connection.send(new net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket(
new net.minecraft.world.level.chunk.EmptyLevelChunk(serverLevel, player.chunkPosition(), plains),
diff --git a/paper-server/patches/features/0021-Moonrise-optimisation-patches.patch b/paper-server/patches/features/0021-Moonrise-optimisation-patches.patch
index 8bdfa4ff3f..4e71dab65e 100644
--- a/paper-server/patches/features/0021-Moonrise-optimisation-patches.patch
+++ b/paper-server/patches/features/0021-Moonrise-optimisation-patches.patch
@@ -23551,7 +23551,7 @@ index 47c62090b421ebea1253ee3f1c896ed84119cea6..e738405e5112584e02e01df2d5ede267
thread1 -> {
DedicatedServer dedicatedServer1 = new DedicatedServer(
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
-index 5649482a8b85056bc009b868e19ca11f21d59fbf..c3318c2fa121d75363c6bc9eadf408dc8040c2bb 100644
+index 768d287be8040797130499b021b2cfd3970f44e5..9c5305b4542483efeeeab19a79eb8eae6d15ef2c 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -173,7 +173,7 @@ import net.minecraft.world.phys.Vec2;
@@ -23641,7 +23641,7 @@ index 5649482a8b85056bc009b868e19ca11f21d59fbf..c3318c2fa121d75363c6bc9eadf408dc
public MinecraftServer(
// CraftBukkit start
joptsimple.OptionSet options,
-@@ -628,7 +699,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -648,7 +719,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.forceDifficulty();
for (ServerLevel serverLevel : this.getAllLevels()) {
this.prepareLevels(serverLevel.getChunkSource().chunkMap.progressListener, serverLevel);
@@ -23650,7 +23650,7 @@ index 5649482a8b85056bc009b868e19ca11f21d59fbf..c3318c2fa121d75363c6bc9eadf408dc
this.server.getPluginManager().callEvent(new org.bukkit.event.world.WorldLoadEvent(serverLevel.getWorld()));
}
-@@ -827,6 +898,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -847,6 +918,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public abstract boolean shouldRconBroadcast();
public boolean saveAllChunks(boolean suppressLog, boolean flush, boolean forced) {
@@ -23662,7 +23662,7 @@ index 5649482a8b85056bc009b868e19ca11f21d59fbf..c3318c2fa121d75363c6bc9eadf408dc
boolean flag = false;
for (ServerLevel serverLevel : this.getAllLevels()) {
-@@ -834,7 +910,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -854,7 +930,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
LOGGER.info("Saving chunks for level '{}'/{}", serverLevel, serverLevel.dimension().location());
}
@@ -23671,7 +23671,7 @@ index 5649482a8b85056bc009b868e19ca11f21d59fbf..c3318c2fa121d75363c6bc9eadf408dc
flag = true;
}
-@@ -925,7 +1001,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -945,7 +1021,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
}
@@ -23680,7 +23680,7 @@ index 5649482a8b85056bc009b868e19ca11f21d59fbf..c3318c2fa121d75363c6bc9eadf408dc
this.nextTickTimeNanos = Util.getNanos() + TimeUtil.NANOSECONDS_PER_MILLISECOND;
for (ServerLevel serverLevelx : this.getAllLevels()) {
-@@ -936,17 +1012,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -956,17 +1032,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.waitUntilNextTick();
}
@@ -23699,7 +23699,7 @@ index 5649482a8b85056bc009b868e19ca11f21d59fbf..c3318c2fa121d75363c6bc9eadf408dc
this.isSaving = false;
this.resources.close();
-@@ -966,6 +1032,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -986,6 +1052,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.getProfileCache().save(false); // Paper - Perf: Async GameProfileCache saving
}
// Spigot end
@@ -23714,7 +23714,7 @@ index 5649482a8b85056bc009b868e19ca11f21d59fbf..c3318c2fa121d75363c6bc9eadf408dc
}
public String getLocalIp() {
-@@ -1130,6 +1204,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -1150,6 +1224,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
profilerFiller.push("tick");
this.tickFrame.start();
this.tickServer(flag ? () -> false : this::haveTime);
@@ -23728,7 +23728,7 @@ index 5649482a8b85056bc009b868e19ca11f21d59fbf..c3318c2fa121d75363c6bc9eadf408dc
this.tickFrame.end();
profilerFiller.popPush("nextTickWait");
this.mayHaveDelayedTasks = true;
-@@ -1302,6 +1383,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -1322,6 +1403,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
private boolean pollTaskInternal() {
if (super.pollTask()) {
@@ -23736,7 +23736,7 @@ index 5649482a8b85056bc009b868e19ca11f21d59fbf..c3318c2fa121d75363c6bc9eadf408dc
return true;
} else {
boolean ret = false; // Paper - force execution of all worlds, do not just bias the first
-@@ -2422,6 +2504,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -2442,6 +2524,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
}
@@ -27495,7 +27495,7 @@ index cdda7f6272cfc48638df4e0e51b496e91ed77ba5..bbb4bb0940765a12c45a99c8234ca82e
}
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
-index 6238729e91ae4fd44a4e0bc73d4f042498c4cb8d..bf4deeac50197eeb83c5b1e458b609aac5ad8a97 100644
+index ff5889f8fed0707a6654d9d21862e32e2ebc866d..e61fe83479f095e8addbd3e8f1d5179c998ae1eb 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -178,7 +178,7 @@ import net.minecraft.world.scores.Team;
@@ -27975,10 +27975,10 @@ index 4eb040006f5d41b47e5ac9df5d9f19c4315d6343..7fa41dea184b01891f45d8e404bc1cba
this.generatingStep = generatingStep;
this.cache = cache;
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
-index bafeeab3edbc73f6f86474e18ab4a3d96ce17157..d322794c0d49daa212b8691f8f60f2276fe25a92 100644
+index b0df94fb5f933491af8b024cc8ecf8b98e448f16..0a2f4af548561144607d24d3bd92270ce630fc95 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
-@@ -1318,7 +1318,7 @@ public abstract class PlayerList {
+@@ -1317,7 +1317,7 @@ public abstract class PlayerList {
public void setViewDistance(int viewDistance) {
this.viewDistance = viewDistance;
@@ -27987,7 +27987,7 @@ index bafeeab3edbc73f6f86474e18ab4a3d96ce17157..d322794c0d49daa212b8691f8f60f227
for (ServerLevel serverLevel : this.server.getAllLevels()) {
if (serverLevel != null) {
-@@ -1329,7 +1329,7 @@ public abstract class PlayerList {
+@@ -1328,7 +1328,7 @@ public abstract class PlayerList {
public void setSimulationDistance(int simulationDistance) {
this.simulationDistance = simulationDistance;
@@ -28371,7 +28371,7 @@ index 8cc5c0716392ba06501542ff5cbe71ee43979e5d..09fd99c9cbd23b5f3c899bfb00c9b896
+ // Paper end - block counting
}
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
-index 069d0d0ddeceb0de2300a3354fed218407d88938..3fd7f6bcdeff271a9843b2f2454f92d92069f539 100644
+index 2b53c5f8ff2ce1097e38ea7cb6f83fbb1d661831..c166a0ec56ff2d4885459d789ddcd5f0ebdfc56a 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -135,7 +135,7 @@ import net.minecraft.world.scores.ScoreHolder;
diff --git a/paper-server/patches/features/0023-Lag-compensation-ticks.patch b/paper-server/patches/features/0023-Lag-compensation-ticks.patch
index c764bdee4a..0e33a6864f 100644
--- a/paper-server/patches/features/0023-Lag-compensation-ticks.patch
+++ b/paper-server/patches/features/0023-Lag-compensation-ticks.patch
@@ -8,7 +8,7 @@ Areas affected by lag comepnsation:
- Eating food items
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
-index 0c35921acebd88f3a9a37676e47e7482dfea6d9c..1ff57c17f7fe3af3fb7fc5fbc5148ca333b5e618 100644
+index 9c5305b4542483efeeeab19a79eb8eae6d15ef2c..ddd23354d68f5cbdc9f72c11246ab26a6c0bbe16 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -301,6 +301,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -19,7 +19,7 @@ index 0c35921acebd88f3a9a37676e47e7482dfea6d9c..1ff57c17f7fe3af3fb7fc5fbc5148ca3
public static <S extends MinecraftServer> S spin(Function<Thread, S> threadFunction) {
ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.init(); // Paper - rewrite data converter system
-@@ -1643,6 +1644,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -1663,6 +1664,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
for (ServerLevel serverLevel : this.getAllLevels()) {
serverLevel.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - BlockPhysicsEvent
serverLevel.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - Add EntityMoveEvent
@@ -28,7 +28,7 @@ index 0c35921acebd88f3a9a37676e47e7482dfea6d9c..1ff57c17f7fe3af3fb7fc5fbc5148ca3
/* Drop global time updates
if (this.tickCount % 20 == 0) {
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
-index ffb5bfdd76a92bac61c7c352fdded4200d13b3ae..651a65aaa37f2cf26d54f75529cbda71e6fc2bc4 100644
+index bbb4bb0940765a12c45a99c8234ca82ef1934903..7dbf6113d79ab826ba5bb9b648b557f625e2b438 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -2678,4 +2678,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
diff --git a/paper-server/patches/features/0028-Improved-Watchdog-Support.patch b/paper-server/patches/features/0028-Improved-Watchdog-Support.patch
index 601c2bb5ea..4a0d417552 100644
--- a/paper-server/patches/features/0028-Improved-Watchdog-Support.patch
+++ b/paper-server/patches/features/0028-Improved-Watchdog-Support.patch
@@ -100,7 +100,7 @@ index e738405e5112584e02e01df2d5ede2676fa1bffb..560d80cb1177297210646b44ce25fd2f
/* CraftBukkit start - Replace everything
OptionParser optionParser = new OptionParser();
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
-index 43306cac3549a03612077df3aacf501051d05a01..d077debf5936050484856e0b84f764967b5d3f5c 100644
+index ddd23354d68f5cbdc9f72c11246ab26a6c0bbe16..3f880bdfd95f7556d1d76e4602a6d24dda78438c 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -298,6 +298,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -119,7 +119,7 @@ index 43306cac3549a03612077df3aacf501051d05a01..d077debf5936050484856e0b84f76496
Runtime.getRuntime().addShutdownHook(new org.bukkit.craftbukkit.util.ServerShutdownThread(this));
// CraftBukkit end
this.paperConfigurations = services.paperConfigurations(); // Paper - add paper configuration files
-@@ -970,6 +972,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -990,6 +992,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.hasStopped = true;
}
if (!hasLoggedStop && isDebugging()) io.papermc.paper.util.TraceUtil.dumpTraceForThread("Server stopped"); // Paper - Debugging
@@ -130,7 +130,7 @@ index 43306cac3549a03612077df3aacf501051d05a01..d077debf5936050484856e0b84f76496
// CraftBukkit end
if (this.metricsRecorder.isRecording()) {
this.cancelRecordingMetrics();
-@@ -1041,6 +1047,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -1061,6 +1067,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
ca.spottedleaf.moonrise.common.util.MoonriseCommon.haltExecutors();
}
// Paper end - rewrite chunk system
@@ -146,7 +146,7 @@ index 43306cac3549a03612077df3aacf501051d05a01..d077debf5936050484856e0b84f76496
}
public String getLocalIp() {
-@@ -1127,6 +1142,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -1147,6 +1162,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
protected void runServer() {
try {
@@ -154,7 +154,7 @@ index 43306cac3549a03612077df3aacf501051d05a01..d077debf5936050484856e0b84f76496
if (!this.initServer()) {
throw new IllegalStateException("Failed to initialize server");
}
-@@ -1137,6 +1153,17 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -1157,6 +1173,17 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.server.spark.enableBeforePlugins(); // Paper - spark
// Spigot start
@@ -172,7 +172,7 @@ index 43306cac3549a03612077df3aacf501051d05a01..d077debf5936050484856e0b84f76496
org.spigotmc.WatchdogThread.hasStarted = true; // Paper
Arrays.fill(this.recentTps, 20);
// Paper start - further improve server tick loop
-@@ -1233,6 +1260,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -1253,6 +1280,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
JvmProfiler.INSTANCE.onServerTick(this.smoothedTickTimeMillis);
}
} catch (Throwable var69) {
@@ -185,7 +185,7 @@ index 43306cac3549a03612077df3aacf501051d05a01..d077debf5936050484856e0b84f76496
LOGGER.error("Encountered an unexpected exception", var69);
CrashReport crashReport = constructOrExtractCrashReport(var69);
this.fillSystemReport(crashReport.getSystemReport());
-@@ -1255,15 +1288,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -1275,15 +1308,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.services.profileCache().clearExecutor();
}
@@ -205,7 +205,7 @@ index 43306cac3549a03612077df3aacf501051d05a01..d077debf5936050484856e0b84f76496
}
}
}
-@@ -1367,6 +1400,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -1387,6 +1420,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@Override
public TickTask wrapRunnable(Runnable runnable) {
@@ -218,7 +218,7 @@ index 43306cac3549a03612077df3aacf501051d05a01..d077debf5936050484856e0b84f76496
return new TickTask(this.tickCount, runnable);
}
-@@ -2164,7 +2203,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -2184,7 +2223,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.resources.managers.updateStaticRegistryTags();
this.resources.managers.getRecipeManager().finalizeRecipeLoading(this.worldData.enabledFeatures());
this.potionBrewing = this.potionBrewing.reload(this.worldData.enabledFeatures()); // Paper - Custom Potion Mixes
@@ -267,10 +267,10 @@ index 55d3f79af2e683b983d4d3f731bb9649dfe76f59..d900469dafd430ec3eba10d6f83bd875
}
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
-index d322794c0d49daa212b8691f8f60f2276fe25a92..e5ae5e1161396280ffea1009f40dafa0398050bb 100644
+index 0a2f4af548561144607d24d3bd92270ce630fc95..42c1f5d0f384e0e4f348e161b4461858a6d84227 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
-@@ -513,7 +513,7 @@ public abstract class PlayerList {
+@@ -512,7 +512,7 @@ public abstract class PlayerList {
this.cserver.getPluginManager().callEvent(playerQuitEvent);
player.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage());
diff --git a/paper-server/patches/features/0032-Incremental-chunk-and-player-saving.patch b/paper-server/patches/features/0032-Incremental-chunk-and-player-saving.patch
index 282b9eb257..964ec03fd8 100644
--- a/paper-server/patches/features/0032-Incremental-chunk-and-player-saving.patch
+++ b/paper-server/patches/features/0032-Incremental-chunk-and-player-saving.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Incremental chunk and player saving
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
-index d077debf5936050484856e0b84f764967b5d3f5c..75efd8f11a42696319c0908b7cf911cf976a31b6 100644
+index 3f880bdfd95f7556d1d76e4602a6d24dda78438c..79d050947960b26ef375c6f1986b617ad2ff081b 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
-@@ -940,7 +940,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -960,7 +960,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
boolean var4;
try {
this.isSaving = true;
@@ -17,7 +17,7 @@ index d077debf5936050484856e0b84f764967b5d3f5c..75efd8f11a42696319c0908b7cf911cf
var4 = this.saveAllChunks(suppressLog, flush, forced);
} finally {
this.isSaving = false;
-@@ -1530,9 +1530,29 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -1550,9 +1550,29 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
this.ticksUntilAutosave--;
@@ -83,7 +83,7 @@ index 9caa06f09409d36abf9e0a770ba004f4049e8e09..fc3b0db0f0a85fb42cb5fa8a1d78d4c4
// Paper start - add close param
this.save(progress, flush, skipSave, false);
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
-index bf4deeac50197eeb83c5b1e458b609aac5ad8a97..a97b0b177a1fb0557af2af4d1f192513d7c0390d 100644
+index e61fe83479f095e8addbd3e8f1d5179c998ae1eb..0a7e5106a1d39150326e7c323030df5d32ecef1e 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -180,6 +180,7 @@ import org.slf4j.Logger;
@@ -95,10 +95,10 @@ index bf4deeac50197eeb83c5b1e458b609aac5ad8a97..a97b0b177a1fb0557af2af4d1f192513
private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10;
private static final int FLY_STAT_RECORDING_SPEED = 25;
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
-index e5ae5e1161396280ffea1009f40dafa0398050bb..d74242a0d25c906d74b018c24d4b21d64415617d 100644
+index 42c1f5d0f384e0e4f348e161b4461858a6d84227..2f7f5f933cf3adb6022664a0ad9b97c8f8bc8fd4 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
-@@ -483,6 +483,7 @@ public abstract class PlayerList {
+@@ -482,6 +482,7 @@ public abstract class PlayerList {
protected void save(ServerPlayer player) {
if (!player.getBukkitEntity().isPersistent()) return; // CraftBukkit
@@ -106,7 +106,7 @@ index e5ae5e1161396280ffea1009f40dafa0398050bb..d74242a0d25c906d74b018c24d4b21d6
this.playerIo.save(player);
ServerStatsCounter serverStatsCounter = player.getStats(); // CraftBukkit
if (serverStatsCounter != null) {
-@@ -1070,9 +1071,23 @@ public abstract class PlayerList {
+@@ -1069,9 +1070,23 @@ public abstract class PlayerList {
}
public void saveAll() {
diff --git a/paper-server/patches/features/0036-Optimize-Hoppers.patch b/paper-server/patches/features/0036-Optimize-Hoppers.patch
index eb195ce201..bb158407dc 100644
--- a/paper-server/patches/features/0036-Optimize-Hoppers.patch
+++ b/paper-server/patches/features/0036-Optimize-Hoppers.patch
@@ -48,10 +48,10 @@ index 0000000000000000000000000000000000000000..24a2090e068ad3c0d08705050944abdf
+ }
+}
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
-index 75efd8f11a42696319c0908b7cf911cf976a31b6..b7bb1b6b2c3c892712c44b4e006d9ceebbd8491a 100644
+index 79d050947960b26ef375c6f1986b617ad2ff081b..12f14284655845d59d44c52c65435fa91e2d7d6f 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
-@@ -1704,6 +1704,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -1724,6 +1724,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
serverLevel.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - BlockPhysicsEvent
serverLevel.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - Add EntityMoveEvent
serverLevel.updateLagCompensationTick(); // Paper - lag compensation
diff --git a/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch b/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch
index ca5ee37782..55497abf8a 100644
--- a/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch
+++ b/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch
@@ -153,7 +153,7 @@
protected abstract boolean initServer() throws IOException;
- protected void loadLevel() {
-+ protected void loadLevel(String s) { // CraftBukkit
++ protected void loadLevel(String levelId) { // CraftBukkit
if (!JvmProfiler.INSTANCE.isRunning()) {
}
@@ -165,11 +165,11 @@
- this.createLevels(chunkProgressListener);
- this.forceDifficulty();
- this.prepareLevels(chunkProgressListener);
-+ this.loadWorld0(s); // CraftBukkit
++ this.loadWorld0(levelId); // CraftBukkit
if (profiledDuration != null) {
profiledDuration.finish(true);
}
-@@ -364,25 +_,245 @@
+@@ -364,25 +_,265 @@
protected void forceDifficulty() {
}
@@ -193,37 +193,39 @@
- this.commandStorage = new CommandStorage(dataStorage);
- WorldBorder worldBorder = serverLevel.getWorldBorder();
+ // CraftBukkit start
-+ private void loadWorld0(String s) {
-+ LevelStorageSource.LevelStorageAccess worldSession = this.storageSource;
-+ RegistryAccess.Frozen iregistrycustom_dimension = this.registries.compositeAccess();
-+ Registry<LevelStem> dimensions = iregistrycustom_dimension.lookupOrThrow(Registries.LEVEL_STEM);
-+ for (LevelStem worldDimension : dimensions) {
-+ ResourceKey<LevelStem> dimensionKey = dimensions.getResourceKey(worldDimension).get();
-+ ServerLevel world;
++ private void loadWorld0(String levelId) {
++ // Mostly modelled off of net.minecraft.server.Main
++ LevelStorageSource.LevelStorageAccess levelStorageAccess = this.storageSource;
++ RegistryAccess.Frozen registryAccess = this.registries.compositeAccess();
++ Registry<LevelStem> levelStemRegistry = registryAccess.lookupOrThrow(Registries.LEVEL_STEM);
++ for (LevelStem levelStem : levelStemRegistry) {
++ ResourceKey<LevelStem> levelStemKey = levelStemRegistry.getResourceKey(levelStem).get();
++ ServerLevel serverLevel;
+ int dimension = 0;
+
-+ if (dimensionKey == LevelStem.NETHER) {
++ if (levelStemKey == LevelStem.NETHER) {
+ if (this.server.getAllowNether()) {
+ dimension = -1;
+ } else {
+ continue;
+ }
-+ } else if (dimensionKey == LevelStem.END) {
++ } else if (levelStemKey == LevelStem.END) {
+ if (this.server.getAllowEnd()) {
+ dimension = 1;
+ } else {
+ continue;
+ }
-+ } else if (dimensionKey != LevelStem.OVERWORLD) {
++ } else if (levelStemKey != LevelStem.OVERWORLD) {
+ dimension = -999;
+ }
+
-+ String worldType = (dimension == -999) ? dimensionKey.location().getNamespace() + "_" + dimensionKey.location().getPath() : org.bukkit.World.Environment.getEnvironment(dimension).toString().toLowerCase(Locale.ROOT);
-+ String name = (dimensionKey == LevelStem.OVERWORLD) ? s : s + "_" + worldType;
++ // Migration of old CB world folders...
++ String worldType = (dimension == -999) ? levelStemKey.location().getNamespace() + "_" + levelStemKey.location().getPath() : org.bukkit.World.Environment.getEnvironment(dimension).toString().toLowerCase(Locale.ROOT);
++ String name = (levelStemKey == LevelStem.OVERWORLD) ? levelId : levelId + "_" + worldType;
+ if (dimension != 0) {
-+ java.io.File newWorld = LevelStorageSource.getStorageFolder(new java.io.File(name).toPath(), dimensionKey).toFile();
-+ java.io.File oldWorld = LevelStorageSource.getStorageFolder(new java.io.File(s).toPath(), dimensionKey).toFile();
-+ java.io.File oldLevelDat = new java.io.File(new java.io.File(s), "level.dat"); // The data folders exist on first run as they are created in the PersistentCollection constructor above, but the level.dat won't
++ java.io.File newWorld = LevelStorageSource.getStorageFolder(new java.io.File(name).toPath(), levelStemKey).toFile();
++ java.io.File oldWorld = LevelStorageSource.getStorageFolder(new java.io.File(levelId).toPath(), levelStemKey).toFile();
++ java.io.File oldLevelDat = new java.io.File(new java.io.File(levelId), "level.dat"); // The data folders exist on first run as they are created in the PersistentCollection constructor above, but the level.dat won't
+
+ if (!newWorld.isDirectory() && oldWorld.isDirectory() && oldLevelDat.isFile()) {
+ MinecraftServer.LOGGER.info("---- Migration of old " + worldType + " folder required ----");
@@ -240,7 +242,7 @@
+ // Migrate world data too.
+ try {
+ com.google.common.io.Files.copy(oldLevelDat, new java.io.File(new java.io.File(name), "level.dat"));
-+ org.apache.commons.io.FileUtils.copyDirectory(new java.io.File(new java.io.File(s), "data"), new java.io.File(new java.io.File(name), "data"));
++ org.apache.commons.io.FileUtils.copyDirectory(new java.io.File(new java.io.File(levelId), "data"), new java.io.File(new java.io.File(name), "data"));
+ } catch (IOException exception) {
+ MinecraftServer.LOGGER.warn("Unable to migrate world data.");
+ }
@@ -256,137 +258,155 @@
+ }
+
+ try {
-+ worldSession = LevelStorageSource.createDefault(this.server.getWorldContainer().toPath()).validateAndCreateAccess(name, dimensionKey);
++ levelStorageAccess = LevelStorageSource.createDefault(this.server.getWorldContainer().toPath()).validateAndCreateAccess(name, levelStemKey);
+ } catch (IOException | net.minecraft.world.level.validation.ContentValidationException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
-+ com.mojang.serialization.Dynamic<?> dynamic;
-+ if (worldSession.hasWorldData()) {
-+ net.minecraft.world.level.storage.LevelSummary worldinfo;
-+
++ com.mojang.serialization.Dynamic<?> dataTag;
++ if (levelStorageAccess.hasWorldData()) {
++ net.minecraft.world.level.storage.LevelSummary summary;
+ try {
-+ dynamic = worldSession.getDataTag();
-+ worldinfo = worldSession.getSummary(dynamic);
-+ } catch (net.minecraft.nbt.NbtException | net.minecraft.nbt.ReportedNbtException | IOException ioexception) {
-+ LevelStorageSource.LevelDirectory convertable_b = worldSession.getLevelDirectory();
-+
-+ MinecraftServer.LOGGER.warn("Failed to load world data from {}", convertable_b.dataFile(), ioexception);
++ dataTag = levelStorageAccess.getDataTag();
++ summary = levelStorageAccess.getSummary(dataTag);
++ } catch (net.minecraft.nbt.NbtException | net.minecraft.nbt.ReportedNbtException | IOException e) {
++ LevelStorageSource.LevelDirectory levelDirectory = levelStorageAccess.getLevelDirectory();
++ MinecraftServer.LOGGER.warn("Failed to load world data from {}", levelDirectory.dataFile(), e);
+ MinecraftServer.LOGGER.info("Attempting to use fallback");
+
+ try {
-+ dynamic = worldSession.getDataTagFallback();
-+ worldinfo = worldSession.getSummary(dynamic);
-+ } catch (net.minecraft.nbt.NbtException | net.minecraft.nbt.ReportedNbtException | IOException ioexception1) {
-+ MinecraftServer.LOGGER.error("Failed to load world data from {}", convertable_b.oldDataFile(), ioexception1);
-+ MinecraftServer.LOGGER.error("Failed to load world data from {} and {}. World files may be corrupted. Shutting down.", convertable_b.dataFile(), convertable_b.oldDataFile());
++ dataTag = levelStorageAccess.getDataTagFallback();
++ summary = levelStorageAccess.getSummary(dataTag);
++ } catch (net.minecraft.nbt.NbtException | net.minecraft.nbt.ReportedNbtException | IOException e1) {
++ MinecraftServer.LOGGER.error("Failed to load world data from {}", levelDirectory.oldDataFile(), e1);
++ MinecraftServer.LOGGER.error(
++ "Failed to load world data from {} and {}. World files may be corrupted. Shutting down.",
++ levelDirectory.dataFile(),
++ levelDirectory.oldDataFile()
++ );
+ return;
+ }
+
-+ worldSession.restoreLevelDataFromOld();
++ levelStorageAccess.restoreLevelDataFromOld();
+ }
+
-+ if (worldinfo.requiresManualConversion()) {
++ if (summary.requiresManualConversion()) {
+ MinecraftServer.LOGGER.info("This world must be opened in an older version (like 1.6.4) to be safely converted");
+ return;
+ }
+
-+ if (!worldinfo.isCompatible()) {
++ if (!summary.isCompatible()) {
+ MinecraftServer.LOGGER.info("This world was created by an incompatible version.");
+ return;
+ }
+ } else {
-+ dynamic = null;
++ dataTag = null;
+ }
+
-+ org.bukkit.generator.ChunkGenerator gen = this.server.getGenerator(name);
++ org.bukkit.generator.ChunkGenerator chunkGenerator = this.server.getGenerator(name);
+ org.bukkit.generator.BiomeProvider biomeProvider = this.server.getBiomeProvider(name);
+
-+ net.minecraft.world.level.storage.PrimaryLevelData worlddata;
-+ WorldLoader.DataLoadContext worldloader_a = this.worldLoader;
-+ Registry<LevelStem> iregistry = worldloader_a.datapackDimensions().lookupOrThrow(Registries.LEVEL_STEM);
-+ if (dynamic != null) {
-+ net.minecraft.world.level.storage.LevelDataAndDimensions leveldataanddimensions = LevelStorageSource.getLevelDataAndDimensions(dynamic, worldloader_a.dataConfiguration(), iregistry, worldloader_a.datapackWorldgen());
-+
-+ worlddata = (net.minecraft.world.level.storage.PrimaryLevelData) leveldataanddimensions.worldData();
++ net.minecraft.world.level.storage.PrimaryLevelData primaryLevelData;
++ WorldLoader.DataLoadContext context = this.worldLoader;
++ Registry<LevelStem> contextLevelStemRegistry = context.datapackDimensions().lookupOrThrow(Registries.LEVEL_STEM);
++ if (dataTag != null) {
++ net.minecraft.world.level.storage.LevelDataAndDimensions levelDataAndDimensions = LevelStorageSource.getLevelDataAndDimensions(
++ dataTag, context.dataConfiguration(), contextLevelStemRegistry, context.datapackWorldgen()
++ );
++ primaryLevelData = (net.minecraft.world.level.storage.PrimaryLevelData) levelDataAndDimensions.worldData();
+ } else {
-+ LevelSettings worldsettings;
-+ WorldOptions worldoptions;
-+ net.minecraft.world.level.levelgen.WorldDimensions worlddimensions;
-+
++ LevelSettings levelSettings;
++ WorldOptions worldOptions;
++ net.minecraft.world.level.levelgen.WorldDimensions worldDimensions;
+ if (this.isDemo()) {
-+ worldsettings = MinecraftServer.DEMO_SETTINGS;
-+ worldoptions = WorldOptions.DEMO_OPTIONS;
-+ worlddimensions = net.minecraft.world.level.levelgen.presets.WorldPresets.createNormalWorldDimensions(worldloader_a.datapackWorldgen());
++ levelSettings = MinecraftServer.DEMO_SETTINGS;
++ worldOptions = WorldOptions.DEMO_OPTIONS;
++ worldDimensions = net.minecraft.world.level.levelgen.presets.WorldPresets.createNormalWorldDimensions(context.datapackWorldgen());
+ } else {
-+ net.minecraft.server.dedicated.DedicatedServerProperties dedicatedserverproperties = ((net.minecraft.server.dedicated.DedicatedServer) this).getProperties();
-+
-+ worldsettings = new LevelSettings(dedicatedserverproperties.levelName, dedicatedserverproperties.gamemode, dedicatedserverproperties.hardcore, dedicatedserverproperties.difficulty, false, new GameRules(worldloader_a.dataConfiguration().enabledFeatures()), worldloader_a.dataConfiguration());
-+ worldoptions = this.options.has("bonusChest") ? dedicatedserverproperties.worldOptions.withBonusChest(true) : dedicatedserverproperties.worldOptions;
-+ worlddimensions = dedicatedserverproperties.createDimensions(worldloader_a.datapackWorldgen());
++ net.minecraft.server.dedicated.DedicatedServerProperties properties = ((net.minecraft.server.dedicated.DedicatedServer) this).getProperties();
++ levelSettings = new LevelSettings(
++ properties.levelName,
++ properties.gamemode,
++ properties.hardcore,
++ properties.difficulty,
++ false,
++ new GameRules(context.dataConfiguration().enabledFeatures()),
++ context.dataConfiguration()
++ );
++ worldOptions = this.options.has("bonusChest") ? properties.worldOptions.withBonusChest(true) : properties.worldOptions; // CraftBukkit
++ worldDimensions = properties.createDimensions(context.datapackWorldgen());
+ }
+
-+ net.minecraft.world.level.levelgen.WorldDimensions.Complete worlddimensions_b = worlddimensions.bake(iregistry);
-+ com.mojang.serialization.Lifecycle lifecycle = worlddimensions_b.lifecycle().add(worldloader_a.datapackWorldgen().allRegistriesLifecycle());
++ net.minecraft.world.level.levelgen.WorldDimensions.Complete complete = worldDimensions.bake(contextLevelStemRegistry);
++ com.mojang.serialization.Lifecycle lifecycle = complete.lifecycle().add(context.datapackWorldgen().allRegistriesLifecycle());
+
-+ worlddata = new net.minecraft.world.level.storage.PrimaryLevelData(worldsettings, worldoptions, worlddimensions_b.specialWorldProperty(), lifecycle);
++ primaryLevelData = new net.minecraft.world.level.storage.PrimaryLevelData(levelSettings, worldOptions, complete.specialWorldProperty(), lifecycle);
+ }
-+ worlddata.checkName(name); // CraftBukkit - Migration did not rewrite the level.dat; This forces 1.8 to take the last loaded world as respawn (in this case the end)
++
++ primaryLevelData.checkName(name); // CraftBukkit - Migration did not rewrite the level.dat; This forces 1.8 to take the last loaded world as respawn (in this case the end)
+ if (this.options.has("forceUpgrade")) {
-+ net.minecraft.server.Main.forceUpgrade(worldSession, net.minecraft.util.datafix.DataFixers.getDataFixer(), this.options.has("eraseCache"), () -> {
-+ return true;
-+ }, iregistrycustom_dimension, this.options.has("recreateRegionFiles"));
++ net.minecraft.server.Main.forceUpgrade(levelStorageAccess, net.minecraft.util.datafix.DataFixers.getDataFixer(), this.options.has("eraseCache"), () -> true, registryAccess, this.options.has("recreateRegionFiles"));
+ }
+
-+ net.minecraft.world.level.storage.PrimaryLevelData iworlddataserver = worlddata;
-+ boolean flag = worlddata.isDebugWorld();
-+ WorldOptions worldoptions = worlddata.worldGenOptions();
-+ long i = worldoptions.seed();
-+ long j = BiomeManager.obfuscateSeed(i);
-+ List<CustomSpawner> list = ImmutableList.of(new PhantomSpawner(), new PatrolSpawner(), new CatSpawner(), new VillageSiege(), new WanderingTraderSpawner(iworlddataserver));
-+ LevelStem worlddimension = (LevelStem) dimensions.getValue(dimensionKey);
-+
-+ org.bukkit.generator.WorldInfo worldInfo = new org.bukkit.craftbukkit.generator.CraftWorldInfo(iworlddataserver, worldSession, org.bukkit.World.Environment.getEnvironment(dimension), worlddimension.type().value(), worlddimension.generator(), this.registryAccess()); // Paper - Expose vanilla BiomeProvider from WorldInfo
-+ if (biomeProvider == null && gen != null) {
-+ biomeProvider = gen.getDefaultBiomeProvider(worldInfo);
++ // Now modelled off the createLevels method
++ net.minecraft.world.level.storage.PrimaryLevelData serverLevelData = primaryLevelData;
++ boolean isDebugWorld = primaryLevelData.isDebugWorld();
++ WorldOptions worldOptions = primaryLevelData.worldGenOptions();
++ long seed = worldOptions.seed();
++ long l = BiomeManager.obfuscateSeed(seed);
++ List<CustomSpawner> list = ImmutableList.of(
++ new PhantomSpawner(), new PatrolSpawner(), new CatSpawner(), new VillageSiege(), new WanderingTraderSpawner(serverLevelData)
++ );
++ LevelStem customStem = levelStemRegistry.getValue(levelStemKey);
++
++ org.bukkit.generator.WorldInfo worldInfo = new org.bukkit.craftbukkit.generator.CraftWorldInfo(serverLevelData, levelStorageAccess, org.bukkit.World.Environment.getEnvironment(dimension), customStem.type().value(), customStem.generator(), this.registryAccess()); // Paper - Expose vanilla BiomeProvider from WorldInfo
++ if (biomeProvider == null && chunkGenerator != null) {
++ biomeProvider = chunkGenerator.getDefaultBiomeProvider(worldInfo);
+ }
+
-+ ResourceKey<Level> worldKey = ResourceKey.create(Registries.DIMENSION, dimensionKey.location());
++ ResourceKey<Level> dimensionKey = ResourceKey.create(Registries.DIMENSION, levelStemKey.location());
+
-+ if (dimensionKey == LevelStem.OVERWORLD) {
-+ this.worldData = worlddata;
++ if (levelStemKey == LevelStem.OVERWORLD) {
++ this.worldData = primaryLevelData;
+ this.worldData.setGameType(((net.minecraft.server.dedicated.DedicatedServer) this).getProperties().gamemode); // From DedicatedServer.init
+
-+ ChunkProgressListener worldloadlistener = this.progressListenerFactory.create(this.worldData.getGameRules().getInt(GameRules.RULE_SPAWN_CHUNK_RADIUS));
++ ChunkProgressListener listener = this.progressListenerFactory.create(this.worldData.getGameRules().getInt(GameRules.RULE_SPAWN_CHUNK_RADIUS));
+
-+ world = new ServerLevel(this, this.executor, worldSession, iworlddataserver, worldKey, worlddimension, worldloadlistener, flag, j, list, true, (RandomSequences) null, org.bukkit.World.Environment.getEnvironment(dimension), gen, biomeProvider);
-+ DimensionDataStorage worldpersistentdata = world.getDataStorage();
-+ this.readScoreboard(worldpersistentdata);
-+ this.server.scoreboardManager = new org.bukkit.craftbukkit.scoreboard.CraftScoreboardManager(this, world.getScoreboard());
-+ this.commandStorage = new CommandStorage(worldpersistentdata);
++ serverLevel = new ServerLevel(
++ this, this.executor, levelStorageAccess, serverLevelData, dimensionKey, customStem, listener, isDebugWorld, l, list, true, null,
++ org.bukkit.World.Environment.getEnvironment(dimension), chunkGenerator, biomeProvider
++ );
++ DimensionDataStorage dataStorage = serverLevel.getDataStorage();
++ this.readScoreboard(dataStorage);
++ this.commandStorage = new CommandStorage(dataStorage);
++ this.server.scoreboardManager = new org.bukkit.craftbukkit.scoreboard.CraftScoreboardManager(this, serverLevel.getScoreboard());
+ } else {
-+ ChunkProgressListener worldloadlistener = this.progressListenerFactory.create(this.worldData.getGameRules().getInt(GameRules.RULE_SPAWN_CHUNK_RADIUS));
++ ChunkProgressListener listener = this.progressListenerFactory.create(this.worldData.getGameRules().getInt(GameRules.RULE_SPAWN_CHUNK_RADIUS));
+ // Paper start - option to use the dimension_type to check if spawners should be added. I imagine mojang will add some datapack-y way of managing this in the future.
+ final List<CustomSpawner> spawners;
-+ if (io.papermc.paper.configuration.GlobalConfiguration.get().misc.useDimensionTypeForCustomSpawners && this.registryAccess().lookupOrThrow(Registries.DIMENSION_TYPE).getResourceKey(worlddimension.type().value()).orElseThrow() == net.minecraft.world.level.dimension.BuiltinDimensionTypes.OVERWORLD) {
++ if (io.papermc.paper.configuration.GlobalConfiguration.get().misc.useDimensionTypeForCustomSpawners && this.registryAccess().lookupOrThrow(Registries.DIMENSION_TYPE).getResourceKey(customStem.type().value()).orElseThrow() == net.minecraft.world.level.dimension.BuiltinDimensionTypes.OVERWORLD) {
+ spawners = list;
+ } else {
+ spawners = Collections.emptyList();
+ }
-+ world = new ServerLevel(this, this.executor, worldSession, iworlddataserver, worldKey, worlddimension, worldloadlistener, flag, j, spawners, true, this.overworld().getRandomSequences(), org.bukkit.World.Environment.getEnvironment(dimension), gen, biomeProvider);
++ serverLevel = new ServerLevel(
++ this, this.executor, levelStorageAccess, serverLevelData, dimensionKey, customStem, listener, isDebugWorld, l, spawners, true, this.overworld().getRandomSequences(),
++ org.bukkit.World.Environment.getEnvironment(dimension), chunkGenerator, biomeProvider
++ );
+ // Paper end - option to use the dimension_type to check if spawners should be added
+ }
+
-+ worlddata.setModdedInfo(this.getServerModName(), this.getModdedStatus().shouldReportAsModified());
-+ this.addLevel(world); // Paper - Put world into worldlist before initing the world; move up
-+ this.initWorld(world, worlddata, this.worldData, worldoptions);
++ // Back to the createLevels method without crazy modifications
++ primaryLevelData.setModdedInfo(this.getServerModName(), this.getModdedStatus().shouldReportAsModified());
++ this.addLevel(serverLevel); // Paper - Put world into worldlist before initing the world; move up
++ this.initWorld(serverLevel, primaryLevelData, this.worldData, worldOptions);
+
+ // Paper - Put world into worldlist before initing the world; move up
-+ this.getPlayerList().addWorldborderListener(world);
++ this.getPlayerList().addWorldborderListener(serverLevel);
+
-+ if (worlddata.getCustomBossEvents() != null) {
-+ this.getCustomBossEvents().load(worlddata.getCustomBossEvents(), this.registryAccess());
++ if (primaryLevelData.getCustomBossEvents() != null) {
++ this.getCustomBossEvents().load(primaryLevelData.getCustomBossEvents(), this.registryAccess());
+ }
+ }
+ this.forceDifficulty();
@@ -1209,15 +1229,6 @@
private ProfilerFiller createProfiler() {
if (this.willStartRecordingMetrics) {
this.metricsRecorder = ActiveMetricsRecorder.createStarted(
-@@ -1941,7 +_,7 @@
- }
-
- public ServerPlayerGameMode createGameModeForPlayer(ServerPlayer player) {
-- return (ServerPlayerGameMode)(this.isDemo() ? new DemoMode(player) : new ServerPlayerGameMode(player));
-+ return (this.isDemo() ? new DemoMode(player) : new ServerPlayerGameMode(player));
- }
-
- @Nullable
@@ -1980,16 +_,22 @@
}
diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch
index ce890ce4a0..7c69b49dd9 100644
--- a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch
+++ b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch
@@ -206,30 +206,17 @@
if (thrownEnderpearl.isRemoved()) {
LOGGER.warn("Trying to save removed ender pearl, skipping");
} else {
-@@ -593,6 +_,29 @@
+@@ -593,6 +_,16 @@
}
}
-+ // CraftBukkit start - World fallback code, either respawn location or global spawn
-+ public void spawnIn(Level world) {
-+ this.setLevel(world);
-+ if (world == null) {
-+ this.unsetRemoved();
-+ Vec3 position = null;
-+ if (this.respawnDimension != null) {
-+ world = this.server.getLevel(this.respawnDimension);
-+ if (world != null && this.getRespawnPosition() != null) {
-+ position = ServerPlayer.findRespawnAndUseSpawnBlock((ServerLevel) world, this.getRespawnPosition(), this.getRespawnAngle(), false, false).map(ServerPlayer.RespawnPosAngle::position).orElse(null);
-+ }
-+ }
-+ if (world == null || position == null) {
-+ world = ((org.bukkit.craftbukkit.CraftWorld) org.bukkit.Bukkit.getServer().getWorlds().get(0)).getHandle();
-+ position = Vec3.atCenterOf(world.getSharedSpawnPos());
-+ }
-+ this.setLevel(world);
-+ this.setPosRaw(position.x(), position.y(), position.z()); // Paper - don't register to chunks yet
++ // CraftBukkit start
++ public void spawnIn(final ServerLevel level) {
++ if (level == null) {
++ throw new IllegalArgumentException("level can't be null");
+ }
-+ this.gameMode.setLevel((ServerLevel) world);
++ this.setLevel(level);
++ this.gameMode.setLevel(level);
+ }
+ // CraftBukkit end
+
@@ -840,7 +827,7 @@
+
+ {
+ {
-+ Either<net.minecraft.world.entity.player.Player.BedSleepingProblem, Unit> either = super.startSleepInBed(at, force).ifRight((unit) -> {
++ Either<net.minecraft.world.entity.player.Player.BedSleepingProblem, Unit> either = super.startSleepInBed(at, force).ifRight(unit -> {
+ // CraftBukkit end
this.awardStat(Stats.SLEEP_IN_BED);
CriteriaTriggers.SLEPT_IN_BED.trigger(this);
diff --git a/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch b/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch
index c53210937f..5c3d9c3714 100644
--- a/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch
+++ b/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch
@@ -808,7 +808,7 @@
d3 = d - this.player.getX();
d4 = d1 - this.player.getY();
if (d4 > -0.5 || d4 < 0.5) {
-@@ -970,20 +_,104 @@
+@@ -970,20 +_,101 @@
d5 = d2 - this.player.getZ();
d7 = d3 * d3 + d4 * d4 + d5 * d5;
@@ -847,11 +847,8 @@
+ teleportBack = false;
+ }
+ }
-+ if (teleportBack) {
++ if (!teleportBack) {
+ // Paper end - Add fail move event
-+ this.internalTeleport(x, y, z, f, f1); // CraftBukkit - SPIGOT-1807: Don't call teleport event, when the client thinks the player is falling, because the chunks are not loaded on the client yet.
-+ this.player.doCheckFallDamage(this.player.getX() - x, this.player.getY() - y, this.player.getZ() - z, packet.isOnGround());
-+ } else {
+ // CraftBukkit start - fire PlayerMoveEvent
+ // Reset to old location first
+ this.player.absMoveTo(prevX, prevY, prevZ, prevYaw, prevPitch);
@@ -922,16 +919,15 @@
this.player.absMoveTo(d, d1, d2, f, f1);
boolean isAutoSpinAttack = this.player.isAutoSpinAttack();
this.clientIsFloating = d4 >= -0.03125
-@@ -1018,9 +_,6 @@
- this.lastGoodX = this.player.getX();
+@@ -1019,7 +_,7 @@
this.lastGoodY = this.player.getY();
this.lastGoodZ = this.player.getZ();
-- } else {
+ } else {
- this.teleport(x, y, z, f, f1);
-- this.player.doCheckFallDamage(this.player.getX() - x, this.player.getY() - y, this.player.getZ() - z, packet.isOnGround());
++ this.internalTeleport(x, y, z, f, f1); // CraftBukkit - SPIGOT-1807: Don't call teleport event, when the client thinks the player is falling, because the chunks are not loaded on the client yet.
+ this.player.doCheckFallDamage(this.player.getX() - x, this.player.getY() - y, this.player.getZ() - z, packet.isOnGround());
}
}
- }
@@ -1053,6 +_,7 @@
this.player.getXRot()
);
diff --git a/paper-server/patches/sources/net/minecraft/server/players/PlayerList.java.patch b/paper-server/patches/sources/net/minecraft/server/players/PlayerList.java.patch
index 8239aa71e1..2ddcf75909 100644
--- a/paper-server/patches/sources/net/minecraft/server/players/PlayerList.java.patch
+++ b/paper-server/patches/sources/net/minecraft/server/players/PlayerList.java.patch
@@ -47,7 +47,7 @@
GameProfile gameProfile = player.getGameProfile();
GameProfileCache profileCache = this.server.getProfileCache();
String string;
-@@ -150,30 +_,94 @@
+@@ -150,30 +_,93 @@
}
Optional<CompoundTag> optional = this.load(player);
@@ -136,7 +136,6 @@
+ serverLevel = ((org.bukkit.craftbukkit.CraftWorld) loc.getWorld()).getHandle();
+
+ player.spawnIn(serverLevel);
-+ player.gameMode.setLevel((ServerLevel) player.level());
+ // Paper start - set raw so we aren't fully joined to the world (not added to chunk or world)
+ player.setPosRaw(loc.getX(), loc.getY(), loc.getZ());
+ player.setRot(loc.getYaw(), loc.getPitch());
@@ -334,7 +333,7 @@
}
@Override
-@@ -309,67 +_,175 @@
+@@ -309,56 +_,162 @@
}
protected void save(ServerPlayer player) {
@@ -469,8 +468,6 @@
- public Component canPlayerLogin(SocketAddress socketAddress, GameProfile gameProfile) {
- if (this.bans.isBanned(gameProfile)) {
- UserBanListEntry userBanListEntry = this.bans.get(gameProfile);
-- MutableComponent mutableComponent = Component.translatable("multiplayer.disconnect.banned.reason", userBanListEntry.getReason());
-- if (userBanListEntry.getExpires() != null) {
+ // CraftBukkit start - Whole method, SocketAddress to LoginListener, added hostname to signature, return EntityPlayer
+ public ServerPlayer canPlayerLogin(net.minecraft.server.network.ServerLoginPacketListenerImpl loginlistener, GameProfile gameProfile) {
+ // if (this.bans.isBanned(gameProfile)) {
@@ -507,14 +504,13 @@
+ org.bukkit.event.player.PlayerLoginEvent event = new org.bukkit.event.player.PlayerLoginEvent(player, loginlistener.connection.hostname, ((java.net.InetSocketAddress) socketAddress).getAddress(), ((java.net.InetSocketAddress) loginlistener.connection.channel.remoteAddress()).getAddress());
+
+ // Paper start - Fix MC-158900
-+ UserBanListEntry gameprofilebanentry;
-+ if (this.bans.isBanned(gameProfile) && (gameprofilebanentry = this.bans.get(gameProfile)) != null) {
++ UserBanListEntry userBanListEntry;
++ if (this.bans.isBanned(gameProfile) && (userBanListEntry = this.bans.get(gameProfile)) != null) {
+ // Paper end - Fix MC-158900
-+ MutableComponent mutableComponent = Component.translatable("multiplayer.disconnect.banned.reason", gameprofilebanentry.getReason());
-+ if (gameprofilebanentry.getExpires() != null) {
+ MutableComponent mutableComponent = Component.translatable("multiplayer.disconnect.banned.reason", userBanListEntry.getReason());
+ if (userBanListEntry.getExpires() != null) {
mutableComponent.append(
-- Component.translatable("multiplayer.disconnect.banned.expiration", BAN_DATE_FORMAT.format(userBanListEntry.getExpires()))
-+ Component.translatable("multiplayer.disconnect.banned.expiration", BAN_DATE_FORMAT.format(gameprofilebanentry.getExpires()))
+@@ -366,10 +_,12 @@
);
}
diff --git a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch
index 6bbcc9ce75..3576351376 100644
--- a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch
+++ b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch
@@ -306,11 +306,10 @@
}
public void onClientRemoval() {
-@@ -367,7 +_,18 @@
+@@ -367,6 +_,17 @@
}
public void setPose(Pose pose) {
-- this.entityData.set(DATA_POSE, pose);
+ if (this.fixedPose) return; // Paper - Expand Pose API
+ // CraftBukkit start
+ if (pose == this.getPose()) {
@@ -322,10 +321,9 @@
+ }
+ // Paper end - Don't fire sync event during generation
+ // CraftBukkit end
-+ this.entityData.set(Entity.DATA_POSE, pose);
+ this.entityData.set(DATA_POSE, pose);
}
- public Pose getPose() {
@@ -390,6 +_,32 @@
}
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 104caaf260..f59b4a6998 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1288,7 +1288,7 @@ public final class CraftServer implements Server {
Preconditions.checkArgument(creator != null, "WorldCreator cannot be null");
String name = creator.name();
- ChunkGenerator generator = creator.generator();
+ ChunkGenerator chunkGenerator = creator.generator();
BiomeProvider biomeProvider = creator.biomeProvider();
File folder = new File(this.getWorldContainer(), name);
World world = this.getWorld(name);
@@ -1307,151 +1307,170 @@ public final class CraftServer implements Server {
Preconditions.checkArgument(folder.isDirectory(), "File (%s) exists and isn't a folder", name);
}
- if (generator == null) {
- generator = this.getGenerator(name);
+ if (chunkGenerator == null) {
+ chunkGenerator = this.getGenerator(name);
}
if (biomeProvider == null) {
biomeProvider = this.getBiomeProvider(name);
}
- ResourceKey<LevelStem> actualDimension;
- switch (creator.environment()) {
- case NORMAL:
- actualDimension = LevelStem.OVERWORLD;
- break;
- case NETHER:
- actualDimension = LevelStem.NETHER;
- break;
- case THE_END:
- actualDimension = LevelStem.END;
- break;
- default:
- throw new IllegalArgumentException("Illegal dimension (" + creator.environment() + ")");
- }
+ ResourceKey<LevelStem> actualDimension = switch (creator.environment()) {
+ case NORMAL -> LevelStem.OVERWORLD;
+ case NETHER -> LevelStem.NETHER;
+ case THE_END -> LevelStem.END;
+ default -> throw new IllegalArgumentException("Illegal dimension (" + creator.environment() + ")");
+ };
- LevelStorageSource.LevelStorageAccess worldSession;
+ LevelStorageSource.LevelStorageAccess levelStorageAccess;
try {
- worldSession = LevelStorageSource.createDefault(this.getWorldContainer().toPath()).validateAndCreateAccess(name, actualDimension);
+ levelStorageAccess = LevelStorageSource.createDefault(this.getWorldContainer().toPath()).validateAndCreateAccess(name, actualDimension);
} catch (IOException | ContentValidationException ex) {
throw new RuntimeException(ex);
}
- Dynamic<?> dynamic;
- if (worldSession.hasWorldData()) {
- net.minecraft.world.level.storage.LevelSummary worldinfo;
-
+ Dynamic<?> dataTag;
+ if (levelStorageAccess.hasWorldData()) {
+ net.minecraft.world.level.storage.LevelSummary summary;
try {
- dynamic = worldSession.getDataTag();
- worldinfo = worldSession.getSummary(dynamic);
- } catch (NbtException | ReportedNbtException | IOException ioexception) {
- LevelStorageSource.LevelDirectory convertable_b = worldSession.getLevelDirectory();
-
- MinecraftServer.LOGGER.warn("Failed to load world data from {}", convertable_b.dataFile(), ioexception);
+ dataTag = levelStorageAccess.getDataTag();
+ summary = levelStorageAccess.getSummary(dataTag);
+ } catch (NbtException | ReportedNbtException | IOException e) {
+ LevelStorageSource.LevelDirectory levelDirectory = levelStorageAccess.getLevelDirectory();
+ MinecraftServer.LOGGER.warn("Failed to load world data from {}", levelDirectory.dataFile(), e);
MinecraftServer.LOGGER.info("Attempting to use fallback");
try {
- dynamic = worldSession.getDataTagFallback();
- worldinfo = worldSession.getSummary(dynamic);
- } catch (NbtException | ReportedNbtException | IOException ioexception1) {
- MinecraftServer.LOGGER.error("Failed to load world data from {}", convertable_b.oldDataFile(), ioexception1);
- MinecraftServer.LOGGER.error("Failed to load world data from {} and {}. World files may be corrupted. Shutting down.", convertable_b.dataFile(), convertable_b.oldDataFile());
+ dataTag = levelStorageAccess.getDataTagFallback();
+ summary = levelStorageAccess.getSummary(dataTag);
+ } catch (NbtException | ReportedNbtException | IOException e1) {
+ MinecraftServer.LOGGER.error("Failed to load world data from {}", levelDirectory.oldDataFile(), e1);
+ MinecraftServer.LOGGER.error(
+ "Failed to load world data from {} and {}. World files may be corrupted. Shutting down.",
+ levelDirectory.dataFile(),
+ levelDirectory.oldDataFile()
+ );
return null;
}
- worldSession.restoreLevelDataFromOld();
+ levelStorageAccess.restoreLevelDataFromOld();
}
- if (worldinfo.requiresManualConversion()) {
+ if (summary.requiresManualConversion()) {
MinecraftServer.LOGGER.info("This world must be opened in an older version (like 1.6.4) to be safely converted");
return null;
}
- if (!worldinfo.isCompatible()) {
+ if (!summary.isCompatible()) {
MinecraftServer.LOGGER.info("This world was created by an incompatible version.");
return null;
}
} else {
- dynamic = null;
+ dataTag = null;
}
boolean hardcore = creator.hardcore();
- PrimaryLevelData worlddata;
- WorldLoader.DataLoadContext worldloader_a = this.console.worldLoader;
- RegistryAccess.Frozen iregistrycustom_dimension = worldloader_a.datapackDimensions();
- net.minecraft.core.Registry<LevelStem> iregistry = iregistrycustom_dimension.lookupOrThrow(Registries.LEVEL_STEM);
- if (dynamic != null) {
- LevelDataAndDimensions leveldataanddimensions = LevelStorageSource.getLevelDataAndDimensions(dynamic, worldloader_a.dataConfiguration(), iregistry, worldloader_a.datapackWorldgen());
-
- worlddata = (PrimaryLevelData) leveldataanddimensions.worldData();
- iregistrycustom_dimension = leveldataanddimensions.dimensions().dimensionsRegistryAccess();
+ PrimaryLevelData primaryLevelData;
+ WorldLoader.DataLoadContext context = this.console.worldLoader;
+ RegistryAccess.Frozen registryAccess = context.datapackDimensions();
+ net.minecraft.core.Registry<LevelStem> contextLevelStemRegistry = registryAccess.lookupOrThrow(Registries.LEVEL_STEM);
+ if (dataTag != null) {
+ LevelDataAndDimensions levelDataAndDimensions = LevelStorageSource.getLevelDataAndDimensions(
+ dataTag, context.dataConfiguration(), contextLevelStemRegistry, context.datapackWorldgen()
+ );
+ primaryLevelData = (PrimaryLevelData) levelDataAndDimensions.worldData();
+ registryAccess = levelDataAndDimensions.dimensions().dimensionsRegistryAccess();
} else {
- LevelSettings worldsettings;
- WorldOptions worldoptions = new WorldOptions(creator.seed(), creator.generateStructures(), false);
- WorldDimensions worlddimensions;
+ LevelSettings levelSettings;
+ WorldOptions worldOptions = new WorldOptions(creator.seed(), creator.generateStructures(), false);
+ WorldDimensions worldDimensions;
DedicatedServerProperties.WorldDimensionData properties = new DedicatedServerProperties.WorldDimensionData(GsonHelper.parse((creator.generatorSettings().isEmpty()) ? "{}" : creator.generatorSettings()), creator.type().name().toLowerCase(Locale.ROOT));
+ levelSettings = new LevelSettings(
+ name,
+ GameType.byId(this.getDefaultGameMode().getValue()),
+ hardcore, Difficulty.EASY,
+ false,
+ new GameRules(context.dataConfiguration().enabledFeatures()),
+ context.dataConfiguration())
+ ;
+ worldDimensions = properties.create(context.datapackWorldgen());
- worldsettings = new LevelSettings(name, GameType.byId(this.getDefaultGameMode().getValue()), hardcore, Difficulty.EASY, false, new GameRules(worldloader_a.dataConfiguration().enabledFeatures()), worldloader_a.dataConfiguration());
- worlddimensions = properties.create(worldloader_a.datapackWorldgen());
-
- WorldDimensions.Complete worlddimensions_b = worlddimensions.bake(iregistry);
- Lifecycle lifecycle = worlddimensions_b.lifecycle().add(worldloader_a.datapackWorldgen().allRegistriesLifecycle());
+ WorldDimensions.Complete complete = worldDimensions.bake(contextLevelStemRegistry);
+ Lifecycle lifecycle = complete.lifecycle().add(context.datapackWorldgen().allRegistriesLifecycle());
- worlddata = new PrimaryLevelData(worldsettings, worldoptions, worlddimensions_b.specialWorldProperty(), lifecycle);
- iregistrycustom_dimension = worlddimensions_b.dimensionsRegistryAccess();
+ primaryLevelData = new PrimaryLevelData(levelSettings, worldOptions, complete.specialWorldProperty(), lifecycle);
+ registryAccess = complete.dimensionsRegistryAccess();
}
- iregistry = iregistrycustom_dimension.lookupOrThrow(Registries.LEVEL_STEM);
- worlddata.customDimensions = iregistry;
- worlddata.checkName(name);
- worlddata.setModdedInfo(this.console.getServerModName(), this.console.getModdedStatus().shouldReportAsModified());
+
+ contextLevelStemRegistry = registryAccess.lookupOrThrow(Registries.LEVEL_STEM);
+ primaryLevelData.customDimensions = contextLevelStemRegistry;
+ primaryLevelData.checkName(name);
+ primaryLevelData.setModdedInfo(this.console.getServerModName(), this.console.getModdedStatus().shouldReportAsModified());
if (this.console.options.has("forceUpgrade")) {
- net.minecraft.server.Main.forceUpgrade(worldSession, DataFixers.getDataFixer(), this.console.options.has("eraseCache"), () -> true, iregistrycustom_dimension, this.console.options.has("recreateRegionFiles"));
+ net.minecraft.server.Main.forceUpgrade(levelStorageAccess, DataFixers.getDataFixer(), this.console.options.has("eraseCache"), () -> true, registryAccess, this.console.options.has("recreateRegionFiles"));
}
- long j = BiomeManager.obfuscateSeed(worlddata.worldGenOptions().seed()); // Paper - use world seed
- List<CustomSpawner> list = ImmutableList.of(new PhantomSpawner(), new PatrolSpawner(), new CatSpawner(), new VillageSiege(), new WanderingTraderSpawner(worlddata));
- LevelStem worlddimension = iregistry.getValue(actualDimension);
+ long i = BiomeManager.obfuscateSeed(primaryLevelData.worldGenOptions().seed());
+ List<CustomSpawner> list = ImmutableList.of(
+ new PhantomSpawner(), new PatrolSpawner(), new CatSpawner(), new VillageSiege(), new WanderingTraderSpawner(primaryLevelData)
+ );
+ LevelStem customStem = contextLevelStemRegistry.getValue(actualDimension);
- WorldInfo worldInfo = new CraftWorldInfo(worlddata, worldSession, creator.environment(), worlddimension.type().value(), worlddimension.generator(), this.getHandle().getServer().registryAccess()); // Paper - Expose vanilla BiomeProvider from WorldInfo
- if (biomeProvider == null && generator != null) {
- biomeProvider = generator.getDefaultBiomeProvider(worldInfo);
+ WorldInfo worldInfo = new CraftWorldInfo(primaryLevelData, levelStorageAccess, creator.environment(), customStem.type().value(), customStem.generator(), this.getHandle().getServer().registryAccess()); // Paper - Expose vanilla BiomeProvider from WorldInfo
+ if (biomeProvider == null && chunkGenerator != null) {
+ biomeProvider = chunkGenerator.getDefaultBiomeProvider(worldInfo);
}
- ResourceKey<net.minecraft.world.level.Level> worldKey;
+ ResourceKey<net.minecraft.world.level.Level> dimensionKey;
String levelName = this.getServer().getProperties().levelName;
if (name.equals(levelName + "_nether")) {
- worldKey = net.minecraft.world.level.Level.NETHER;
+ dimensionKey = net.minecraft.world.level.Level.NETHER;
} else if (name.equals(levelName + "_the_end")) {
- worldKey = net.minecraft.world.level.Level.END;
+ dimensionKey = net.minecraft.world.level.Level.END;
} else {
- worldKey = ResourceKey.create(Registries.DIMENSION, ResourceLocation.fromNamespaceAndPath(creator.key().namespace(), creator.key().value()));
+ dimensionKey = ResourceKey.create(Registries.DIMENSION, ResourceLocation.fromNamespaceAndPath(creator.key().namespace(), creator.key().value()));
}
// If set to not keep spawn in memory (changed from default) then adjust rule accordingly
if (creator.keepSpawnLoaded() == net.kyori.adventure.util.TriState.FALSE) { // Paper
- worlddata.getGameRules().getRule(GameRules.RULE_SPAWN_CHUNK_RADIUS).set(0, null);
- }
- ServerLevel internal = (ServerLevel) new ServerLevel(this.console, this.console.executor, worldSession, worlddata, worldKey, worlddimension, this.getServer().progressListenerFactory.create(worlddata.getGameRules().getInt(GameRules.RULE_SPAWN_CHUNK_RADIUS)),
- worlddata.isDebugWorld(), j, creator.environment() == Environment.NORMAL ? list : ImmutableList.of(), true, this.console.overworld().getRandomSequences(), creator.environment(), generator, biomeProvider);
+ primaryLevelData.getGameRules().getRule(GameRules.RULE_SPAWN_CHUNK_RADIUS).set(0, null);
+ }
+
+ ServerLevel serverLevel = new ServerLevel(
+ this.console,
+ this.console.executor,
+ levelStorageAccess,
+ primaryLevelData,
+ dimensionKey,
+ customStem,
+ this.getServer().progressListenerFactory.create(primaryLevelData.getGameRules().getInt(GameRules.RULE_SPAWN_CHUNK_RADIUS)),
+ primaryLevelData.isDebugWorld(),
+ i,
+ creator.environment() == Environment.NORMAL ? list : ImmutableList.of(),
+ true,
+ this.console.overworld().getRandomSequences(),
+ creator.environment(),
+ chunkGenerator, biomeProvider
+ );
if (!(this.worlds.containsKey(name.toLowerCase(Locale.ROOT)))) {
return null;
}
- this.console.addLevel(internal); // Paper - Put world into worldlist before initing the world; move up
- this.console.initWorld(internal, worlddata, worlddata, worlddata.worldGenOptions());
+ this.console.addLevel(serverLevel); // Paper - Put world into worldlist before initing the world; move up
+ this.console.initWorld(serverLevel, primaryLevelData, primaryLevelData, primaryLevelData.worldGenOptions());
- internal.setSpawnSettings(true);
+ serverLevel.setSpawnSettings(true);
// Paper - Put world into worldlist before initing the world; move up
- this.getServer().prepareLevels(internal.getChunkSource().chunkMap.progressListener, internal);
- io.papermc.paper.FeatureHooks.tickEntityManager(internal); // SPIGOT-6526: Load pending entities so they are available to the API // Paper - chunk system
+ this.getServer().prepareLevels(serverLevel.getChunkSource().chunkMap.progressListener, serverLevel);
+ io.papermc.paper.FeatureHooks.tickEntityManager(serverLevel); // SPIGOT-6526: Load pending entities so they are available to the API // Paper - chunk system
- this.pluginManager.callEvent(new WorldLoadEvent(internal.getWorld()));
- return internal.getWorld();
+ this.pluginManager.callEvent(new WorldLoadEvent(serverLevel.getWorld()));
+ return serverLevel.getWorld();
}
@Override