diff --git a/patches/server/Add-Early-Warning-Feature-to-WatchDog.patch b/patches/server/Add-Early-Warning-Feature-to-WatchDog.patch index 26c4bb494c..738f90532d 100644 --- a/patches/server/Add-Early-Warning-Feature-to-WatchDog.patch +++ b/patches/server/Add-Early-Warning-Feature-to-WatchDog.patch @@ -18,8 +18,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // Spigot start + org.spigotmc.WatchdogThread.hasStarted = true; // Paper Arrays.fill( this.recentTps, 20 ); - long tickSection = Util.getMillis(), tickCount = 1; - while (this.running) { + // Paper start - further improve server tick loop + long tickSection = Util.getNanos(); diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java diff --git a/patches/server/Add-Raw-Byte-Entity-Serialization.patch b/patches/server/Add-Raw-Byte-Entity-Serialization.patch index d733ea533d..6a4f37fe48 100644 --- a/patches/server/Add-Raw-Byte-Entity-Serialization.patch +++ b/patches/server/Add-Raw-Byte-Entity-Serialization.patch @@ -51,7 +51,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -0,0 +0,0 @@ public final class CraftMagicNumbers implements UnsafeValues { - return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.of(ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.ITEM_STACK, compound, dataVersion, getDataVersion()))); + return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.of(compound)); } + @Override @@ -71,8 +71,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + CompoundTag compound = deserializeNbtFromBytes(data); + int dataVersion = compound.getInt("DataVersion"); -+ compound = ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.ENTITY, compound, dataVersion, getDataVersion()); -+ if (!preserveUUID) compound.remove("UUID"); // Generate a new UUID so we don't have to worry about deserializing the same entity twice ++ compound = (CompoundTag) MinecraftServer.getServer().fixerUpper.update(References.ENTITY, new Dynamic<>(NbtOps.INSTANCE, compound), dataVersion, this.getDataVersion()).getValue(); ++ if (!preserveUUID) { ++ // Generate a new UUID so we don't have to worry about deserializing the same entity twice ++ compound.remove("UUID"); ++ } + return net.minecraft.world.entity.EntityType.create(compound, ((org.bukkit.craftbukkit.CraftWorld) world).getHandle()) + .orElseThrow(() -> new IllegalArgumentException("An ID was not found for the data. Did you downgrade?")).getBukkitEntity(); + } diff --git a/patches/server/Add-Raw-Byte-ItemStack-Serialization.patch b/patches/server/Add-Raw-Byte-ItemStack-Serialization.patch index 5c3ea19fb3..1da0e69865 100644 --- a/patches/server/Add-Raw-Byte-ItemStack-Serialization.patch +++ b/patches/server/Add-Raw-Byte-ItemStack-Serialization.patch @@ -28,8 +28,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + Preconditions.checkArgument(data.length > 0, "cannot deserialize nothing"); + + CompoundTag compound = deserializeNbtFromBytes(data); -+ int dataVersion = compound.getInt("DataVersion"); -+ return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.of(ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.ITEM_STACK, compound, dataVersion, getDataVersion()))); ++ final int dataVersion = compound.getInt("DataVersion"); ++ compound = (CompoundTag) MinecraftServer.getServer().fixerUpper.update(References.ITEM_STACK, new Dynamic<>(NbtOps.INSTANCE, compound), dataVersion, this.getDataVersion()).getValue(); ++ return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.of(compound)); + } + + private byte[] serializeNbtToBytes(CompoundTag compound) { diff --git a/patches/server/Add-debug-for-sync-chunk-loads.patch b/patches/server/Add-debug-for-sync-chunk-loads.patch index 60ffec6c04..ecef4523f2 100644 --- a/patches/server/Add-debug-for-sync-chunk-loads.patch +++ b/patches/server/Add-debug-for-sync-chunk-loads.patch @@ -198,9 +198,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/io/papermc/paper/command/PaperCommand.java +++ b/src/main/java/io/papermc/paper/command/PaperCommand.java @@ -0,0 +0,0 @@ public final class PaperCommand extends Command { + commands.put(Set.of("reload"), new ReloadCommand()); commands.put(Set.of("version"), new VersionCommand()); commands.put(Set.of("dumpplugins"), new DumpPluginsCommand()); - commands.put(Set.of("fixlight"), new FixLightCommand()); + commands.put(Set.of("syncloadinfo"), new SyncLoadInfoCommand()); return commands.entrySet().stream() diff --git a/patches/server/Add-paper-mobcaps-and-paper-playermobcaps.patch b/patches/server/Add-paper-mobcaps-and-paper-playermobcaps.patch index b244006d98..0f94565192 100644 --- a/patches/server/Add-paper-mobcaps-and-paper-playermobcaps.patch +++ b/patches/server/Add-paper-mobcaps-and-paper-playermobcaps.patch @@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/io/papermc/paper/command/PaperCommand.java +++ b/src/main/java/io/papermc/paper/command/PaperCommand.java @@ -0,0 +0,0 @@ public final class PaperCommand extends Command { - commands.put(Set.of("fixlight"), new FixLightCommand()); + commands.put(Set.of("dumpplugins"), new DumpPluginsCommand()); commands.put(Set.of("syncloadinfo"), new SyncLoadInfoCommand()); commands.put(Set.of("dumpitem"), new DumpItemCommand()); + commands.put(Set.of("mobcaps", "playermobcaps"), new MobcapsCommand()); diff --git a/patches/server/Do-not-let-the-server-load-chunks-from-newer-version.patch b/patches/server/Do-not-let-the-server-load-chunks-from-newer-version.patch index c210d96d72..4a4f4e3d90 100644 --- a/patches/server/Do-not-let-the-server-load-chunks-from-newer-version.patch +++ b/patches/server/Do-not-let-the-server-load-chunks-from-newer-version.patch @@ -13,16 +13,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java @@ -0,0 +0,0 @@ public class ChunkSerializer { - private static final String SKYLIGHT_STATE_TAG = "starlight.skylight_state"; - private static final String STARLIGHT_VERSION_TAG = "starlight.light_version"; - // Paper end - replace light engine impl + public static final String BLOCK_LIGHT_TAG = "BlockLight"; + public static final String SKY_LIGHT_TAG = "SkyLight"; + + // Paper start - Do not let the server load chunks from newer versions + private static final int CURRENT_DATA_VERSION = net.minecraft.SharedConstants.getCurrentVersion().getDataVersion().getVersion(); + private static final boolean JUST_CORRUPT_IT = Boolean.getBoolean("Paper.ignoreWorldDataVersion"); + // Paper end - Do not let the server load chunks from newer versions - public ChunkSerializer() {} + // Paper start - guard against serializing mismatching coordinates @@ -0,0 +0,0 @@ public class ChunkSerializer { } // Paper end - guard against serializing mismatching coordinates diff --git a/patches/server/Further-improve-server-tick-loop.patch b/patches/server/Further-improve-server-tick-loop.patch index 3a2c595c30..cf31d1e148 100644 --- a/patches/server/Further-improve-server-tick-loop.patch +++ b/patches/server/Further-improve-server-tick-loop.patch @@ -16,11 +16,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); public int autosavePeriod; public Commands vanillaCommandDispatcher; @@ -29,7 +29,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public static final int TPS = 20; public static final int TICK_TIME = 1000000000 / MinecraftServer.TPS; - private static final int SAMPLE_INTERVAL = 100; -+ private static final int SAMPLE_INTERVAL = 20; // Paper ++ private static final int SAMPLE_INTERVAL = 20; // Paper - improve server tick loop ++ @Deprecated(forRemoval = true) // Paper public final double[] recentTps = new double[ 3 ]; // Spigot end public final io.papermc.paper.configuration.PaperConfigurations paperConfigurations; // Paper - add paper configuration files @@ -90,43 +91,47 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end // Spigot End - public static volatile RuntimeException chunkSystemCrash; // Paper - rewrite chunk system + protected void runServer() { @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop> future = chunkStatus.generate( + Runnable::run, + serverLevel, @@ -75,21 +67,34 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } } -- if (chunk != null) { -- refreshChunk(x, z); +- final long chunkKey = ChunkCoordIntPair.pair(x, z); +- world.getChunkProvider().unloadQueue.remove(chunkKey); + for (final BlockPos blockPos : BlockPos.betweenClosed(chunkPos.getMinBlockX(), serverLevel.getMinBuildHeight(), chunkPos.getMinBlockZ(), chunkPos.getMaxBlockX(), serverLevel.getMaxBuildHeight() - 1, chunkPos.getMaxBlockZ())) { + serverChunkCache.blockChanged(blockPos); - } ++ } -- return chunk != null; -- */ +- net.minecraft.server.Chunk chunk = world.getChunkProvider().generateChunk(x, z); +- PlayerChunk playerChunk = world.getPlayerChunkMap().getChunk(x, z); +- if (playerChunk != null) { +- playerChunk.chunk = chunk; + final Set chunksToRelight = new HashSet<>(9); + for (int chunkX = chunkPos.x - 1; chunkX <= chunkPos.x + 1 ; chunkX++) { + for (int chunkZ = chunkPos.z - 1; chunkZ <= chunkPos.z + 1 ; chunkZ++) { + chunksToRelight.add(new ChunkPos(chunkX, chunkZ)); + } -+ } -+ serverChunkCache.getLightEngine().relight(chunksToRelight, pos -> {}, relit -> {}); + } + +- if (chunk != null) { +- refreshChunk(x, z); ++ for (final ChunkPos pos : chunksToRelight) { ++ final ChunkAccess chunk = serverChunkCache.getChunk(pos.x, pos.z, false); ++ if (chunk != null) { ++ serverChunkCache.getLightEngine().lightChunk(chunk, false); ++ } + } + +- return chunk != null; +- */ + return true; + // Paper end - implement regenerate chunk method } diff --git a/patches/server/Improved-Watchdog-Support.patch b/patches/server/Improved-Watchdog-Support.patch index 9d62d24b48..77961cf5aa 100644 --- a/patches/server/Improved-Watchdog-Support.patch +++ b/patches/server/Improved-Watchdog-Support.patch @@ -169,7 +169,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + org.spigotmc.WatchdogThread.tick(); // Paper org.spigotmc.WatchdogThread.hasStarted = true; // Paper Arrays.fill( this.recentTps, 20 ); - long tickSection = Util.getMillis(), tickCount = 1; + // Paper start - further improve server tick loop @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop(NbtOps.INSTANCE, compound), dataVersion, this.getDataVersion()).getValue(); +- return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.of(compound)); ++ return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.of(ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.ITEM_STACK, compound, dataVersion, this.getDataVersion()))); // Paper - rewrite dataconverter + } + + @Override +@@ -0,0 +0,0 @@ public final class CraftMagicNumbers implements UnsafeValues { + + CompoundTag compound = deserializeNbtFromBytes(data); + int dataVersion = compound.getInt("DataVersion"); +- compound = (CompoundTag) MinecraftServer.getServer().fixerUpper.update(References.ENTITY, new Dynamic<>(NbtOps.INSTANCE, compound), dataVersion, this.getDataVersion()).getValue(); ++ compound = ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.ENTITY, compound, dataVersion, getDataVersion()); // Paper - rewrite dataconverter + if (!preserveUUID) { + // Generate a new UUID so we don't have to worry about deserializing the same entity twice + compound.remove("UUID"); diff --git a/patches/server/Starlight.patch b/patches/server/Starlight.patch index eb09402336..a04aeffea8 100644 --- a/patches/server/Starlight.patch +++ b/patches/server/Starlight.patch @@ -7,7 +7,6 @@ See https://github.com/PaperMC/Starlight == AT == public net.minecraft.server.level.ChunkHolder broadcast(Lnet/minecraft/network/protocol/Packet;Z)V -public net.minecraft.world.level.chunk.LevelChunkSection states diff --git a/src/main/java/ca/spottedleaf/starlight/common/light/BlockStarLightEngine.java b/src/main/java/ca/spottedleaf/starlight/common/light/BlockStarLightEngine.java new file mode 100644 @@ -4351,9 +4350,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/io/papermc/paper/command/PaperCommand.java +++ b/src/main/java/io/papermc/paper/command/PaperCommand.java @@ -0,0 +0,0 @@ public final class PaperCommand extends Command { - commands.put(Set.of("reload"), new ReloadCommand()); - commands.put(Set.of("version"), new VersionCommand()); - commands.put(Set.of("dumpplugins"), new DumpPluginsCommand()); + commands.put(Set.of("dumpitem"), new DumpItemCommand()); + commands.put(Set.of("mobcaps", "playermobcaps"), new MobcapsCommand()); + commands.put(Set.of("dumplisteners"), new DumpListenersCommand()); + commands.put(Set.of("fixlight"), new FixLightCommand()); return commands.entrySet().stream() @@ -4892,8 +4891,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.replaceable = blockbase_info.replaceable; + this.conditionallyFullOpaque = this.canOcclude & this.useShapeForLightOcclusion; // Paper } - - private boolean calculateSolid() { + // Paper start - Perf: impl cached craft block data, lazy load to fix issue with loading at the wrong time + private org.bukkit.craftbukkit.block.data.CraftBlockData cachedCraftBlockData; @@ -0,0 +0,0 @@ public abstract class BlockBehaviour implements FeatureElement { return this.shapeExceedsCube; } @@ -5200,9 +5199,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java @@ -0,0 +0,0 @@ public class ChunkSerializer { - public static final String BLOCK_LIGHT_TAG = "BlockLight"; - public static final String SKY_LIGHT_TAG = "SkyLight"; - + private static final int CURRENT_DATA_VERSION = net.minecraft.SharedConstants.getCurrentVersion().getDataVersion().getVersion(); + private static final boolean JUST_CORRUPT_IT = Boolean.getBoolean("Paper.ignoreWorldDataVersion"); + // Paper end - Do not let the server load chunks from newer versions + // Paper start - replace light engine impl + private static final int STARLIGHT_LIGHT_VERSION = 9; + @@ -5213,7 +5212,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public ChunkSerializer() {} - public static ProtoChunk read(ServerLevel world, PoiManager poiStorage, ChunkPos chunkPos, CompoundTag nbt) { + // Paper start - guard against serializing mismatching coordinates @@ -0,0 +0,0 @@ public class ChunkSerializer { } @@ -5403,3 +5402,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public static ChunkStatus.ChunkType getChunkTypeFromTag(@Nullable CompoundTag nbt) { return nbt != null ? ChunkStatus.byName(nbt.getString("Status")).getChunkType() : ChunkStatus.ChunkType.PROTOCHUNK; } +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World { + } + } + +- for (final ChunkPos pos : chunksToRelight) { +- final ChunkAccess chunk = serverChunkCache.getChunk(pos.x, pos.z, false); +- if (chunk != null) { +- serverChunkCache.getLightEngine().lightChunk(chunk, false); +- } +- } ++ serverChunkCache.getLightEngine().relight(chunksToRelight, pos -> {}, relit -> {}); // Paper - Starlight + + return true; + // Paper end - implement regenerate chunk method diff --git a/patches/server/Use-TerminalConsoleAppender-for-console-improvements.patch b/patches/server/Use-TerminalConsoleAppender-for-console-improvements.patch index 8fc6a6f1f8..d63e991299 100644 --- a/patches/server/Use-TerminalConsoleAppender-for-console-improvements.patch +++ b/patches/server/Use-TerminalConsoleAppender-for-console-improvements.patch @@ -267,7 +267,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public OptionSet options; public org.bukkit.command.ConsoleCommandSender console; - public ConsoleReader reader; - public static int currentTick = (int) (System.currentTimeMillis() / 50); + public static int currentTick; // Paper - improve tick loop public java.util.Queue processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); public int autosavePeriod; @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop