diff --git a/patches/server/Add-Alternate-Current-redstone-implementation.patch b/patches/server/Add-Alternate-Current-redstone-implementation.patch index 045a4205d5..6922035420 100644 --- a/patches/server/Add-Alternate-Current-redstone-implementation.patch +++ b/patches/server/Add-Alternate-Current-redstone-implementation.patch @@ -2038,9 +2038,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - } + return ret; } - // Paper end - notify observers even if grow failed + // Paper end + // Paper start - optimize redstone (Alternate Current) + public alternate.current.wire.WireHandler getWireHandler() { + // This method is overridden in ServerLevel. diff --git a/patches/server/Add-Early-Warning-Feature-to-WatchDog.patch b/patches/server/Add-Early-Warning-Feature-to-WatchDog.patch index 71512c8e16..3bc11b7d80 100644 --- a/patches/server/Add-Early-Warning-Feature-to-WatchDog.patch +++ b/patches/server/Add-Early-Warning-Feature-to-WatchDog.patch @@ -69,7 +69,7 @@ diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/ index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/spigotmc/WatchdogThread.java +++ b/src/main/java/org/spigotmc/WatchdogThread.java -@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa +@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread private static WatchdogThread instance; private long timeoutTime; private boolean restart; @@ -80,7 +80,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private volatile long lastTick; private volatile boolean stopping; -@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa +@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread super( "Paper Watchdog Thread" ); this.timeoutTime = timeoutTime; this.restart = restart; @@ -89,7 +89,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } private static long monotonicMillis() -@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa +@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread while ( !this.stopping ) { // @@ -110,10 +110,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 log.log( Level.SEVERE, "------------------------------" ); log.log( Level.SEVERE, "The server has stopped responding! This is (probably) not a Paper bug." ); // Paper log.log( Level.SEVERE, "If you see a plugin in the Server thread dump below, then please report it to that author" ); -@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa - } +@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread + log.log( Level.SEVERE, "near " + net.minecraft.world.level.Level.lastPhysicsProblem ); } - // Paper end + // ++ // Paper start - Warn in watchdog if an excessive velocity was ever set ++ if (org.bukkit.craftbukkit.CraftServer.excessiveVelEx != null) { ++ log.log( Level.SEVERE, "------------------------------" ); ++ log.log( Level.SEVERE, "During the run of the server, a plugin set an excessive velocity on an entity" ); ++ log.log( Level.SEVERE, "This may be the cause of the issue, or it may be entirely unrelated" ); ++ log.log( Level.SEVERE, org.bukkit.craftbukkit.CraftServer.excessiveVelEx.getMessage()); ++ for (StackTraceElement stack : org.bukkit.craftbukkit.CraftServer.excessiveVelEx.getStackTrace()) { ++ log.log(Level.SEVERE, "\t\t" + stack); ++ } ++ } ++ // Paper end + } else + { + log.log(Level.SEVERE, "--- DO NOT REPORT THIS TO PAPER - THIS IS NOT A BUG OR A CRASH - " + Bukkit.getServer().getVersion() + " ---"); @@ -122,7 +133,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - Different message for short timeout log.log( Level.SEVERE, "------------------------------" ); log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper - io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.dumpAllChunkLoadInfo(isLongTimeout); // Paper // Paper - rewrite chunk system WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log ); log.log( Level.SEVERE, "------------------------------" ); // diff --git a/patches/server/Add-debug-for-sync-chunk-loads.patch b/patches/server/Add-debug-for-sync-chunk-loads.patch index 170cd5a535..5c67baf5e9 100644 --- a/patches/server/Add-debug-for-sync-chunk-loads.patch +++ b/patches/server/Add-debug-for-sync-chunk-loads.patch @@ -198,10 +198,10 @@ 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("version"), new VersionCommand()); commands.put(Set.of("dumpplugins"), new DumpPluginsCommand()); commands.put(Set.of("fixlight"), new FixLightCommand()); - commands.put(Set.of("debug", "chunkinfo", "holderinfo"), new ChunkDebugCommand()); -+ commands.put(Set.of("syncloadinfo"), new SyncLoadInfoCommand()); ++ commands.put(Set.of("debug", "chunkinfo", "holderinfo"), new ChunkDebugCommand()); return commands.entrySet().stream() .flatMap(entry -> entry.getKey().stream().map(s -> Map.entry(s, entry.getValue()))) @@ -304,19 +304,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource { - // Paper start - async chunk io/loading - io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.pushChunkWait(this.level, x1, z1); // Paper - rewrite chunk system - // Paper end -+ com.destroystokyo.paper.io.SyncLoadFinder.logSyncLoad(this.level, x1, z1); // Paper - Add debug for sync chunk loads + + Objects.requireNonNull(completablefuture); + if (!completablefuture.isDone()) { // Paper ++ com.destroystokyo.paper.io.SyncLoadFinder.logSyncLoad(this.level, x, z); // Paper - Add debug for sync chunk loads this.level.timings.syncChunkLoad.startTiming(); // Paper chunkproviderserver_b.managedBlock(completablefuture::isDone); - io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.popChunkWait(); // Paper - async chunk debug // Paper - rewrite chunk system + this.level.timings.syncChunkLoad.stopTiming(); // Paper diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel { - this.entityLookup = new io.papermc.paper.chunk.system.entity.EntityLookup(this, new EntityCallbacks()); // Paper - rewrite chunk system + this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit } + // Paper start diff --git a/patches/server/Add-paper-dumplisteners-command.patch b/patches/server/Add-paper-dumplisteners-command.patch index 125268c076..aa9c1abf4a 100644 --- a/patches/server/Add-paper-dumplisteners-command.patch +++ b/patches/server/Add-paper-dumplisteners-command.patch @@ -10,7 +10,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("syncloadinfo"), new SyncLoadInfoCommand()); + commands.put(Set.of("debug", "chunkinfo", "holderinfo"), new ChunkDebugCommand()); // commands.put(Set.of("dumpitem"), new DumpItemCommand()); commands.put(Set.of("mobcaps", "playermobcaps"), new MobcapsCommand()); + commands.put(Set.of("dumplisteners"), new DumpListenersCommand()); diff --git a/patches/server/Add-paper-mobcaps-and-paper-playermobcaps.patch b/patches/server/Add-paper-mobcaps-and-paper-playermobcaps.patch index fb01b3c2dd..54886b1b0a 100644 --- a/patches/server/Add-paper-mobcaps-and-paper-playermobcaps.patch +++ b/patches/server/Add-paper-mobcaps-and-paper-playermobcaps.patch @@ -14,8 +14,8 @@ 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("debug", "chunkinfo", "holderinfo"), new ChunkDebugCommand()); - commands.put(Set.of("syncloadinfo"), new SyncLoadInfoCommand()); + commands.put(Set.of("fixlight"), new FixLightCommand()); + commands.put(Set.of("debug", "chunkinfo", "holderinfo"), new ChunkDebugCommand()); // commands.put(Set.of("dumpitem"), new DumpItemCommand()); + commands.put(Set.of("mobcaps", "playermobcaps"), new MobcapsCommand()); diff --git a/patches/server/Add-velocity-warnings.patch b/patches/server/Add-velocity-warnings.patch index db3130fa20..6148537c6c 100644 --- a/patches/server/Add-velocity-warnings.patch +++ b/patches/server/Add-velocity-warnings.patch @@ -65,24 +65,21 @@ diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/ index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/spigotmc/WatchdogThread.java +++ b/src/main/java/org/spigotmc/WatchdogThread.java -@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa - log.log( Level.SEVERE, "During the run of the server, a physics stackoverflow was supressed" ); - log.log( Level.SEVERE, "near " + net.minecraft.world.level.Level.lastPhysicsProblem ); - } -- // -+ // Paper start - Warn in watchdog if an excessive velocity was ever set -+ if ( org.bukkit.craftbukkit.CraftServer.excessiveVelEx != null ) -+ { -+ log.log( Level.SEVERE, "------------------------------" ); -+ log.log( Level.SEVERE, "During the run of the server, a plugin set an excessive velocity on an entity" ); -+ log.log( Level.SEVERE, "This may be the cause of the issue, or it may be entirely unrelated" ); -+ log.log( Level.SEVERE, org.bukkit.craftbukkit.CraftServer.excessiveVelEx.getMessage()); -+ for ( StackTraceElement stack : org.bukkit.craftbukkit.CraftServer.excessiveVelEx.getStackTrace() ) -+ { -+ log.log( Level.SEVERE, "\t\t" + stack ); -+ } -+ } -+ // Paper end - log.log( Level.SEVERE, "------------------------------" ); - log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper - io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.dumpAllChunkLoadInfo(isLongTimeout); // Paper // Paper - rewrite chunk system +@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread + } + log.log( Level.SEVERE, "\tStack:" ); + // ++ // Paper start - Warn in watchdog if an excessive velocity was ever set ++ if (org.bukkit.craftbukkit.CraftServer.excessiveVelEx != null) { ++ log.log(Level.SEVERE, "------------------------------"); ++ log.log(Level.SEVERE, "During the run of the server, a plugin set an excessive velocity on an entity"); ++ log.log(Level.SEVERE, "This may be the cause of the issue, or it may be entirely unrelated"); ++ log.log(Level.SEVERE, org.bukkit.craftbukkit.CraftServer.excessiveVelEx.getMessage()); ++ for (StackTraceElement stack : org.bukkit.craftbukkit.CraftServer.excessiveVelEx.getStackTrace()) { ++ log.log( Level.SEVERE, "\t\t" + stack ); ++ } ++ } ++ // Paper end + for ( StackTraceElement stack : thread.getStackTrace() ) + { + log.log( Level.SEVERE, "\t\t" + stack ); diff --git a/patches/server/Async-GameProfileCache-saving.patch b/patches/server/Async-GameProfileCache-saving.patch index c0fbb3d199..dd381f4251 100644 --- a/patches/server/Async-GameProfileCache-saving.patch +++ b/patches/server/Async-GameProfileCache-saving.patch @@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.getProfileCache().save(false); // Paper - Perf: Async GameProfileCache saving } // Spigot end - io.papermc.paper.chunk.system.io.RegionFileIOThread.close(true); // Paper // Paper - rewrite chunk system + 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/AsyncTabCompleteEvent.patch b/patches/server/AsyncTabCompleteEvent.patch index de3a841b62..21970c4342 100644 --- a/patches/server/AsyncTabCompleteEvent.patch +++ b/patches/server/AsyncTabCompleteEvent.patch @@ -37,10 +37,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam"))); // Paper - AsyncTabCompleteEvent return; } - // Paper start -@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - } - // Paper end // CraftBukkit end + // Paper start - AsyncTabCompleteEvent + TAB_COMPLETE_EXECUTOR.execute(() -> { diff --git a/patches/server/Basic-PlayerProfile-API.patch b/patches/server/Basic-PlayerProfile-API.patch index 52f3127f38..66d2a760dc 100644 --- a/patches/server/Basic-PlayerProfile-API.patch +++ b/patches/server/Basic-PlayerProfile-API.patch @@ -557,8 +557,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 import com.google.common.util.concurrent.ThreadFactoryBuilder; import io.papermc.paper.math.BlockPosition; import io.papermc.paper.math.FinePosition; -@@ -0,0 +0,0 @@ import net.minecraft.world.level.chunk.ChunkAccess; - import net.minecraft.world.level.chunk.ChunkStatus; +@@ -0,0 +0,0 @@ import net.minecraft.world.level.ClipContext; + import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; import org.apache.commons.lang.exception.ExceptionUtils; +import com.mojang.authlib.GameProfile; diff --git a/patches/server/Chunk-Save-Reattempt.patch b/patches/server/Chunk-Save-Reattempt.patch index 68bcd76d14..8fbc14825d 100644 --- a/patches/server/Chunk-Save-Reattempt.patch +++ b/patches/server/Chunk-Save-Reattempt.patch @@ -23,10 +23,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java @@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable { - } - // Paper end - rewrite chunk system - try { // Paper -+ int attempts = 0; Exception laste = null; while (attempts++ < 5) { try { // Paper - Chunk save reattempt + + protected void write(ChunkPos pos, @Nullable CompoundTag nbt) throws IOException { + RegionFile regionfile = this.getRegionFile(pos, false); // CraftBukkit ++ // Paper start - Chunk save reattempt ++ int attempts = 0; ++ Exception lastException = null; ++ while (attempts++ < 5) { ++ try { ++ // Paper end - Chunk save reattempt if (nbt == null) { regionfile.clear(pos); @@ -35,17 +40,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } } + // Paper start - Chunk save reattempt -+ return; -+ } catch (Exception ex) { -+ laste = ex; -+ } ++ return; ++ } catch (Exception ex) { ++ lastException = ex; ++ } + } -+ if (laste != null) { -+ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(laste); -+ net.minecraft.server.MinecraftServer.LOGGER.error("Failed to save chunk " + pos, laste); ++ if (lastException != null) { ++ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(lastException); ++ net.minecraft.server.MinecraftServer.LOGGER.error("Failed to save chunk {}", pos, lastException); + } + // Paper end - Chunk save reattempt - } finally { // Paper start - regionfile.fileLock.unlock(); - } // Paper end + } + + public void close() throws IOException { diff --git a/patches/server/Deobfuscate-stacktraces-in-log-messages-crash-report.patch b/patches/server/Deobfuscate-stacktraces-in-log-messages-crash-report.patch index 196722f5f4..189edde2cb 100644 --- a/patches/server/Deobfuscate-stacktraces-in-log-messages-crash-report.patch +++ b/patches/server/Deobfuscate-stacktraces-in-log-messages-crash-report.patch @@ -641,19 +641,25 @@ diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/ index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/spigotmc/WatchdogThread.java +++ b/src/main/java/org/spigotmc/WatchdogThread.java -@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa +@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread log.log( Level.SEVERE, "During the run of the server, a plugin set an excessive velocity on an entity" ); log.log( Level.SEVERE, "This may be the cause of the issue, or it may be entirely unrelated" ); log.log( Level.SEVERE, org.bukkit.craftbukkit.CraftServer.excessiveVelEx.getMessage()); -- for ( StackTraceElement stack : org.bukkit.craftbukkit.CraftServer.excessiveVelEx.getStackTrace() ) -+ for ( StackTraceElement stack : io.papermc.paper.util.StacktraceDeobfuscator.INSTANCE.deobfuscateStacktrace(org.bukkit.craftbukkit.CraftServer.excessiveVelEx.getStackTrace()) ) // Paper - { - log.log( Level.SEVERE, "\t\t" + stack ); +- for (StackTraceElement stack : org.bukkit.craftbukkit.CraftServer.excessiveVelEx.getStackTrace()) { ++ for (StackTraceElement stack : io.papermc.paper.util.StacktraceDeobfuscator.INSTANCE.deobfuscateStacktrace(org.bukkit.craftbukkit.CraftServer.excessiveVelEx.getStackTrace())) { // Paper + log.log(Level.SEVERE, "\t\t" + stack); } -@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa + } +@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread + log.log(Level.SEVERE, "During the run of the server, a plugin set an excessive velocity on an entity"); + log.log(Level.SEVERE, "This may be the cause of the issue, or it may be entirely unrelated"); + log.log(Level.SEVERE, org.bukkit.craftbukkit.CraftServer.excessiveVelEx.getMessage()); +- for (StackTraceElement stack : org.bukkit.craftbukkit.CraftServer.excessiveVelEx.getStackTrace()) { ++ for (StackTraceElement stack : io.papermc.paper.util.StacktraceDeobfuscator.INSTANCE.deobfuscateStacktrace(org.bukkit.craftbukkit.CraftServer.excessiveVelEx.getStackTrace())) { // Paper + log.log( Level.SEVERE, "\t\t" + stack ); + } } - log.log( Level.SEVERE, "\tStack:" ); - // + // Paper end - for ( StackTraceElement stack : thread.getStackTrace() ) + for ( StackTraceElement stack : io.papermc.paper.util.StacktraceDeobfuscator.INSTANCE.deobfuscateStacktrace(thread.getStackTrace()) ) // Paper { diff --git a/patches/server/Detail-more-information-in-watchdog-dumps.patch b/patches/server/Detail-more-information-in-watchdog-dumps.patch index 8a8285f980..11dcba3c16 100644 --- a/patches/server/Detail-more-information-in-watchdog-dumps.patch +++ b/patches/server/Detail-more-information-in-watchdog-dumps.patch @@ -289,7 +289,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa log.log( Level.SEVERE, "------------------------------" ); log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper - io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.dumpAllChunkLoadInfo(isLongTimeout); // Paper // Paper - rewrite chunk system + io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.dumpAllChunkLoadInfo(isLongTimeout); // Paper - rewrite chunk system + this.dumpTickingInfo(); // Paper - log detailed tick information WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log ); log.log( Level.SEVERE, "------------------------------" ); 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 70c2e0cc2b..00925563c4 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,7 +13,7 @@ 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 { - InProgressChunkHolder holder = loadChunk(world, poiStorage, chunkPos, nbt, true); + InProgressChunkHolder holder = readInProgressChunkHolder(world, poiStorage, chunkPos, nbt); return holder.protoChunk; } + // Paper start - Do not let the server load chunks from newer versions @@ -21,15 +21,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + private static final boolean JUST_CORRUPT_IT = Boolean.getBoolean("Paper.ignoreWorldDataVersion"); + // Paper end - Do not let the server load chunks from newer versions - public static InProgressChunkHolder loadChunk(ServerLevel world, PoiManager poiStorage, ChunkPos chunkPos, CompoundTag nbt, boolean distinguish) { + public static InProgressChunkHolder readInProgressChunkHolder(ServerLevel world, PoiManager poiStorage, ChunkPos chunkPos, CompoundTag nbt) { + // Paper end - rewrite chunk system + // Paper start - Do not let the server load chunks from newer versions + if (nbt.contains("DataVersion", net.minecraft.nbt.Tag.TAG_ANY_NUMERIC)) { -+ int dataVersion = nbt.getInt("DataVersion"); ++ final int dataVersion = nbt.getInt("DataVersion"); + if (!JUST_CORRUPT_IT && dataVersion > CURRENT_DATA_VERSION) { + new RuntimeException("Server attempted to load chunk saved with newer version of minecraft! " + dataVersion + " > " + CURRENT_DATA_VERSION).printStackTrace(); + System.exit(1); + } + } - // Paper end ++ // Paper end - Do not let the server load chunks from newer versions ChunkPos chunkcoordintpair1 = new ChunkPos(nbt.getInt("xPos"), nbt.getInt("zPos")); // Paper - guard against serializing mismatching coordinates; diff on change, see ChunkSerializer#getChunkCoordinate + if (!Objects.equals(chunkPos, chunkcoordintpair1)) { diff --git a/patches/server/Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch b/patches/server/Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch index 4fac73d4f3..df0d48d9bd 100644 --- a/patches/server/Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch +++ b/patches/server/Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch @@ -20,4 +20,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (objectset == null || objectset.isEmpty()) { // Paper this.playersPerChunk.remove(i); this.naturalSpawnChunkCounter.update(i, Integer.MAX_VALUE, false); - //this.playerTicketManager.update(i, Integer.MAX_VALUE, false); // Paper - no longer used + this.playerTicketManager.update(i, Integer.MAX_VALUE, false); diff --git a/patches/server/Duplicate-UUID-Resolve-Option.patch b/patches/server/Duplicate-UUID-Resolve-Option.patch index 97cf4268eb..d1136adc18 100644 --- a/patches/server/Duplicate-UUID-Resolve-Option.patch +++ b/patches/server/Duplicate-UUID-Resolve-Option.patch @@ -42,10 +42,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } + checkDupeUUID(world, entity); // Paper - duplicate uuid resolving return !needsRemoval; - }), position); // Paper - rewrite chunk system + })); // CraftBukkit end @@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - throw new UnsupportedOperationException(); // Paper - rewrite chunk system + }); } + // Paper start - duplicate uuid resolving @@ -88,5 +88,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end - duplicate uuid resolving public CompletableFuture> prepareTickingChunk(ChunkHolder holder) { - throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } + CompletableFuture, ChunkHolder.ChunkLoadingFailure>> completablefuture = this.getChunkRangeFuture(holder, 1, (i) -> { + return ChunkStatus.FULL; diff --git a/patches/server/Ensure-Entity-position-and-AABB-are-never-invalid.patch b/patches/server/Ensure-Entity-position-and-AABB-are-never-invalid.patch index 4bde5c4148..e802d11f8d 100644 --- a/patches/server/Ensure-Entity-position-and-AABB-are-never-invalid.patch +++ b/patches/server/Ensure-Entity-position-and-AABB-are-never-invalid.patch @@ -47,9 +47,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return; + } + // Paper end - Block invalid positions and bounding box - // Paper start - rewrite chunk system - if (this.updatingSectionStatus) { - LOGGER.error("Refusing to update position for entity " + this + " to position " + new Vec3(x, y, z) + " since it is processing a section status update", new Throwable()); + if (this.position.x != x || this.position.y != y || this.position.z != z) { + this.position = new Vec3(x, y, z); + int i = Mth.floor(x); @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S this.levelCallback.onMove(); } diff --git a/patches/server/Fix-global-sound-handling.patch b/patches/server/Fix-global-sound-handling.patch index 5cd082c680..512167cf42 100644 --- a/patches/server/Fix-global-sound-handling.patch +++ b/patches/server/Fix-global-sound-handling.patch @@ -85,10 +85,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - return ret; + + private ExplosionInteraction() {} } - // Paper end -+ + // Paper start - respect global sound events gamerule + public List getPlayersForGlobalSoundGamerule() { + return this.getGameRules().getBoolean(GameRules.RULE_GLOBAL_SOUND_EVENTS) ? ((ServerLevel) this).getServer().getPlayerList().players : ((ServerLevel) this).players(); diff --git a/patches/server/Guard-against-serializing-mismatching-chunk-coordina.patch b/patches/server/Guard-against-serializing-mismatching-chunk-coordina.patch index 0e3ec75d56..04f949512e 100644 --- a/patches/server/Guard-against-serializing-mismatching-chunk-coordina.patch +++ b/patches/server/Guard-against-serializing-mismatching-chunk-coordina.patch @@ -15,7 +15,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start - guard against serializing mismatching coordinates + // TODO Note: This needs to be re-checked each update -+ public static ChunkPos getChunkCoordinate(CompoundTag chunkData) { ++ public static ChunkPos getChunkCoordinate(final CompoundTag chunkData) { + final int dataVersion = ChunkStorage.getVersion(chunkData); + if (dataVersion < 2842) { // Level tag is removed after this version + final CompoundTag levelData = chunkData.getCompound("Level"); @@ -25,13 +25,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + } + // Paper end - guard against serializing mismatching coordinates - // Paper start - public static final class InProgressChunkHolder { - -@@ -0,0 +0,0 @@ public class ChunkSerializer { - - public static InProgressChunkHolder loadChunk(ServerLevel world, PoiManager poiStorage, ChunkPos chunkPos, CompoundTag nbt, boolean distinguish) { - // Paper end + public static ProtoChunk read(ServerLevel world, PoiManager poiStorage, ChunkPos chunkPos, CompoundTag nbt) { - ChunkPos chunkcoordintpair1 = new ChunkPos(nbt.getInt("xPos"), nbt.getInt("zPos")); + ChunkPos chunkcoordintpair1 = new ChunkPos(nbt.getInt("xPos"), nbt.getInt("zPos")); // Paper - guard against serializing mismatching coordinates; diff on change, see ChunkSerializer#getChunkCoordinate @@ -42,16 +36,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java @@ -0,0 +0,0 @@ public class ChunkStorage implements AutoCloseable { + } - // Paper start - async chunk io - public void write(ChunkPos chunkPos, CompoundTag nbt) throws IOException { + public void write(ChunkPos chunkPos, CompoundTag nbt) { + // Paper start - guard against serializing mismatching coordinates + if (nbt != null && !chunkPos.equals(ChunkSerializer.getChunkCoordinate(nbt))) { -+ String world = (this instanceof net.minecraft.server.level.ChunkMap) ? ((net.minecraft.server.level.ChunkMap)this).level.getWorld().getName() : null; -+ throw new IllegalArgumentException("Chunk coordinate and serialized data do not have matching coordinates, trying to serialize coordinate " + chunkPos.toString() -+ + " but compound says coordinate is " + ChunkSerializer.getChunkCoordinate(nbt).toString() + (world == null ? " for an unknown world" : (" for world: " + world))); ++ final String world = (this instanceof net.minecraft.server.level.ChunkMap) ? ((net.minecraft.server.level.ChunkMap) this).level.getWorld().getName() : null; ++ throw new IllegalArgumentException("Chunk coordinate and serialized data do not have matching coordinates, trying to serialize coordinate " + chunkPos ++ + " but compound says coordinate is " + ChunkSerializer.getChunkCoordinate(nbt) + (world == null ? " for an unknown world" : (" for world: " + world))); + } + // Paper end - guard against serializing mismatching coordinates - this.regionFileCache.write(chunkPos, nbt); - // Paper end - Async chunk loading + this.worker.store(chunkPos, nbt); if (this.legacyStructureHandler != null) { + this.legacyStructureHandler.removeIndex(chunkPos.toLong()); diff --git a/patches/server/Only-capture-actual-tree-growth.patch b/patches/server/Only-capture-actual-tree-growth.patch index cf47deabea..8fb4959f40 100644 --- a/patches/server/Only-capture-actual-tree-growth.patch +++ b/patches/server/Only-capture-actual-tree-growth.patch @@ -46,7 +46,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + } + // Paper end - notify observers even if grow failed - } + // Paper start + //protected final io.papermc.paper.world.EntitySliceManager entitySliceManager; // Paper - rewrite chunk system + diff --git a/src/main/java/net/minecraft/world/level/block/SaplingBlock.java b/src/main/java/net/minecraft/world/level/block/SaplingBlock.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/block/SaplingBlock.java diff --git a/patches/server/Only-write-chunk-data-to-disk-if-it-serializes-witho.patch b/patches/server/Only-write-chunk-data-to-disk-if-it-serializes-witho.patch index e6b20d86bd..496622a480 100644 --- a/patches/server/Only-write-chunk-data-to-disk-if-it-serializes-witho.patch +++ b/patches/server/Only-write-chunk-data-to-disk-if-it-serializes-witho.patch @@ -77,7 +77,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper - don't write garbage data to disk if writing serialization fails; move into try block to only write if successfully serialized } // Paper start - Chunk save reattempt - return; + return; @@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable { } diff --git a/patches/server/Optimise-EntityGetter-getPlayerByUUID.patch b/patches/server/Optimise-EntityGetter-getPlayerByUUID.patch index 06f4450882..0cd4ca038c 100644 --- a/patches/server/Optimise-EntityGetter-getPlayerByUUID.patch +++ b/patches/server/Optimise-EntityGetter-getPlayerByUUID.patch @@ -10,8 +10,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel { - }); } + // Paper end + // Paper start - optimise getPlayerByUUID + @Nullable diff --git a/patches/server/Optimise-getChunkAt-calls-for-loaded-chunks.patch b/patches/server/Optimise-getChunkAt-calls-for-loaded-chunks.patch index aaf37435af..b90e61c4f6 100644 --- a/patches/server/Optimise-getChunkAt-calls-for-loaded-chunks.patch +++ b/patches/server/Optimise-getChunkAt-calls-for-loaded-chunks.patch @@ -24,7 +24,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 gameprofilerfiller.incrementCounter("getChunk"); @@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource { - if (!io.papermc.paper.util.TickThread.isTickThread()) { // Paper - rewrite chunk system + if (Thread.currentThread() != this.mainThread) { return null; } else { - this.level.getProfiler().incrementCounter("getChunkNow"); diff --git a/patches/server/Optimize-Captured-BlockEntity-Lookup.patch b/patches/server/Optimize-Captured-BlockEntity-Lookup.patch index 5c6d361a54..8f91ba3745 100644 --- a/patches/server/Optimize-Captured-BlockEntity-Lookup.patch +++ b/patches/server/Optimize-Captured-BlockEntity-Lookup.patch @@ -26,5 +26,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } + // Paper end - Perf: Optimize capturedTileEntities lookup // CraftBukkit end - return this.isOutsideBuildHeight(blockposition) ? null : (!this.isClientSide && !io.papermc.paper.util.TickThread.isTickThread() ? null : this.getChunkAt(blockposition).getBlockEntity(blockposition, LevelChunk.EntityCreationType.IMMEDIATE)); // Paper - rewrite chunk system + return this.isOutsideBuildHeight(blockposition) ? null : (!this.isClientSide && Thread.currentThread() != this.thread ? null : this.getChunkAt(blockposition).getBlockEntity(blockposition, LevelChunk.EntityCreationType.IMMEDIATE)); } diff --git a/patches/server/Paper-dumpitem-command.patch b/patches/server/Paper-dumpitem-command.patch index 8608deff59..ebb6ba6e64 100644 --- a/patches/server/Paper-dumpitem-command.patch +++ b/patches/server/Paper-dumpitem-command.patch @@ -10,9 +10,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("dumpplugins"), new DumpPluginsCommand()); commands.put(Set.of("fixlight"), new FixLightCommand()); commands.put(Set.of("debug", "chunkinfo", "holderinfo"), new ChunkDebugCommand()); - commands.put(Set.of("syncloadinfo"), new SyncLoadInfoCommand()); + commands.put(Set.of("dumpitem"), new DumpItemCommand()); return commands.entrySet().stream() diff --git a/patches/server/PlayerNaturallySpawnCreaturesEvent.patch b/patches/server/PlayerNaturallySpawnCreaturesEvent.patch index 4a900da4b1..60569ce201 100644 --- a/patches/server/PlayerNaturallySpawnCreaturesEvent.patch +++ b/patches/server/PlayerNaturallySpawnCreaturesEvent.patch @@ -69,5 +69,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet cachedSingleHashSet; // Paper + public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent - // Paper start - replace player chunk loader - private final java.util.concurrent.atomic.AtomicReference viewDistances = new java.util.concurrent.atomic.AtomicReference<>(new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances(-1, -1, -1)); + public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile, ClientInformation clientOptions) { + super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile); diff --git a/patches/server/Rewrite-chunk-system.patch b/patches/server/Rewrite-chunk-system.patch index e75bc7d922..3f9766ec7c 100644 --- a/patches/server/Rewrite-chunk-system.patch +++ b/patches/server/Rewrite-chunk-system.patch @@ -8509,8 +8509,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + chunkPos, this.world + ); + // deserialize -+ final ChunkSerializer.InProgressChunkHolder chunkHolder = ChunkSerializer.loadChunk( -+ this.world, chunkMap.getPoiManager(), chunkPos, converted, true ++ final ChunkSerializer.InProgressChunkHolder chunkHolder = ChunkSerializer.readInProgressChunkHolder( ++ this.world, chunkMap.getPoiManager(), chunkPos, converted + ); + + return new TaskResult<>(chunkHolder.protoChunk, null); @@ -15289,10 +15289,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 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("debug", "chunkinfo", "holderinfo"), new ChunkDebugCommand()); +- commands.put(Set.of("debug", "chunkinfo", "holderinfo"), new ChunkDebugCommand()); ++ commands.put(Set.of("debug", "chunkinfo", "holderinfo"), new ChunkDebugCommand()); // + commands.put(Set.of("dumpitem"), new DumpItemCommand()); return commands.entrySet().stream() - .flatMap(entry -> entry.getKey().stream().map(s -> Map.entry(s, entry.getValue()))) diff --git a/src/main/java/io/papermc/paper/command/subcommands/ChunkDebugCommand.java b/src/main/java/io/papermc/paper/command/subcommands/ChunkDebugCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 @@ -15760,7 +15761,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import net.minecraft.world.level.chunk.ChunkStatus; import net.minecraft.world.phys.Vec3; import org.apache.commons.lang.exception.ExceptionUtils; - import org.bukkit.Location; + import com.mojang.authlib.GameProfile; @@ -0,0 +0,0 @@ import org.spigotmc.AsyncCatcher; import javax.annotation.Nonnull; @@ -16753,7 +16754,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.isSaving = false; this.resources.close(); @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { @@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - needsRemoval = true; } + checkDupeUUID(world, entity); // Paper - duplicate uuid resolving return !needsRemoval; - })); + }), position); // Paper - rewrite chunk system @@ -18222,6 +18223,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + throw new UnsupportedOperationException(); // Paper - rewrite chunk system } + // Paper start - duplicate uuid resolving +@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + } + // Paper end - duplicate uuid resolving public CompletableFuture> prepareTickingChunk(ChunkHolder holder) { - CompletableFuture, ChunkHolder.ChunkLoadingFailure>> completablefuture = this.getChunkRangeFuture(holder, 1, (i) -> { - return ChunkStatus.FULL; @@ -18912,7 +18917,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public void removePlayer(SectionPos pos, ServerPlayer player) { @@ -0,0 +0,0 @@ public abstract class DistanceManager { - if (objectset.isEmpty()) { + if (objectset == null || objectset.isEmpty()) { // Paper this.playersPerChunk.remove(i); this.naturalSpawnChunkCounter.update(i, Integer.MAX_VALUE, false); - this.playerTicketManager.update(i, Integer.MAX_VALUE, false); @@ -19295,12 +19300,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 Objects.requireNonNull(completablefuture); if (!completablefuture.isDone()) { // Paper -+ // Paper start - async chunk io/loading + io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.pushChunkWait(this.level, x1, z1); // Paper - rewrite chunk system -+ // Paper end + com.destroystokyo.paper.io.SyncLoadFinder.logSyncLoad(this.level, x, z); // Paper - Add debug for sync chunk loads this.level.timings.syncChunkLoad.startTiming(); // Paper chunkproviderserver_b.managedBlock(completablefuture::isDone); -+ io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.popChunkWait(); // Paper - async chunk debug // Paper - rewrite chunk system ++ io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.popChunkWait(); // Paper - rewrite chunk system this.level.timings.syncChunkLoad.stopTiming(); // Paper } // Paper ichunkaccess = (ChunkAccess) ((Either) completablefuture.join()).map((ichunkaccess1) -> { @@ -19312,7 +19316,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (!io.papermc.paper.util.TickThread.isTickThread()) { // Paper - rewrite chunk system return null; } else { - this.level.getProfiler().incrementCounter("getChunkNow"); + return this.getChunkAtIfLoadedMainThread(chunkX, chunkZ); // Paper - Perf: Optimise getChunkAt calls for loaded chunks @@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource { } @@ -19649,10 +19653,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 io.papermc.paper.chunk.system.ChunkSystem.scheduleChunkLoad( - this, cx, cz, net.minecraft.world.level.chunk.ChunkStatus.FULL, true, priority, consumer + this, cx, cz, chunkStatus, true, priority, consumer -+ ); -+ } -+ } -+ } + ); + } + } + } +- // Paper end + + public final void loadChunksForMoveAsync(AABB axisalignedbb, ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority, + java.util.function.Consumer> onLoad) { @@ -19742,8 +19747,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + throw new IllegalArgumentException( + "Entity chunk coordinate and serialized data do not have matching coordinates, trying to serialize coordinate " + pos.toString() + + " but compound says coordinate is " + nbtPos + " for world: " + this - ); - } ++ ); ++ } + super.write(pos, nbt); + } + } @@ -19841,9 +19846,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (this.viewDistances.compareAndSet(curr, update.apply(curr))) { + return; + } - } - } -- // Paper end ++ } ++ } + + public void setTickViewDistance(final int distance) { + if ((distance < io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.MIN_VIEW_DISTANCE || distance > io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.MAX_VIEW_DISTANCE)) { @@ -19872,8 +19876,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + }); + } - // Add env and gen to constructor, IWorldDataServer -> WorldDataServer - public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List list, boolean flag1, @Nullable RandomSequences randomsequences, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) { + // Paper start - optimise getPlayerByUUID + @Nullable @@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel { // CraftBukkit end boolean flag2 = minecraftserver.forceSynchronousWrites(); @@ -19905,7 +19909,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.entityLookup = new io.papermc.paper.chunk.system.entity.EntityLookup(this, new EntityCallbacks()); // Paper - rewrite chunk system } - /** @deprecated */ + // Paper start @@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel { gameprofilerfiller.push("checkDespawn"); entity.checkDespawn(); @@ -19935,7 +19939,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 protected void tickTime() { @@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel { - } + // Paper end - Incremental chunk and player saving public void save(@Nullable ProgressListener progressListener, boolean flush, boolean savingDisabled) { + // Paper start - rewrite chunk system - add close param @@ -20127,8 +20131,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -0,0 +0,0 @@ public class ServerPlayer extends Player { - public boolean isRealPlayer; // Paper public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet cachedSingleHashSet; // Paper + public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent + // Paper start - replace player chunk loader + private final java.util.concurrent.atomic.AtomicReference viewDistances = new java.util.concurrent.atomic.AtomicReference<>(new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances(-1, -1, -1)); @@ -20498,7 +20502,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - this.disconnect(Component.translatable("disconnect.spam")); + server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam"))); // Paper - AsyncTabCompleteEvent return; } + // Paper start @@ -20509,8 +20513,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end // CraftBukkit end - StringReader stringreader = new StringReader(packet.getCommand()); - + // Paper start - AsyncTabCompleteEvent + TAB_COMPLETE_EXECUTOR.execute(() -> { diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java @@ -20757,12 +20761,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return this.countPlayerPassengers() == 1; } @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S - } - - public final void setPosRaw(double x, double y, double z) { + return; + } + // Paper end - Block invalid positions and bounding box + // Paper start - rewrite chunk system + if (this.updatingSectionStatus) { -+ LOGGER.error("Refusing to update position for entity " + this + " to position " + new Vec3(x, y, z) + " since it is processing a section status update", new Throwable()); ++ LOGGER.error("Refusing to update position for entity {} to position {} since it is processing a section status update", this, new Vec3(x, y, z), new Throwable()); + return; + } + // Paper end - rewrite chunk system @@ -21092,8 +21096,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if ((i & 1) != 0) { @@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - return this.capturedTileEntities.get(blockposition); } + // Paper end - Perf: Optimize capturedTileEntities lookup // CraftBukkit end - return this.isOutsideBuildHeight(blockposition) ? null : (!this.isClientSide && Thread.currentThread() != this.thread ? null : this.getChunkAt(blockposition).getBlockEntity(blockposition, LevelChunk.EntityCreationType.IMMEDIATE)); + return this.isOutsideBuildHeight(blockposition) ? null : (!this.isClientSide && !io.papermc.paper.util.TickThread.isTickThread() ? null : this.getChunkAt(blockposition).getBlockEntity(blockposition, LevelChunk.EntityCreationType.IMMEDIATE)); // Paper - rewrite chunk system @@ -21180,9 +21184,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Nullable @@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - - private ExplosionInteraction() {} + return range <= 0 ? 64.0 * 64.0 : range * range; // 64 is taken from default in ServerLevel#levelEvent } + // Paper end - respect global sound events gamerule + // Paper start + //protected final io.papermc.paper.world.EntitySliceManager entitySliceManager; // Paper - rewrite chunk system + @@ -21524,10 +21528,10 @@ 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 ChunkSerializer() {} - -+ // Paper start + } + } + // Paper end - guard against serializing mismatching coordinates ++ // Paper start - rewrite chunk system + public static final class InProgressChunkHolder { + + public final ProtoChunk protoChunk; @@ -21538,17 +21542,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.protoChunk = protoChunk; + } + } -+ // Paper end -+ public static ProtoChunk read(ServerLevel world, PoiManager poiStorage, ChunkPos chunkPos, CompoundTag nbt) { -+ // Paper start - add variant for async calls -+ InProgressChunkHolder holder = loadChunk(world, poiStorage, chunkPos, nbt, true); ++ InProgressChunkHolder holder = readInProgressChunkHolder(world, poiStorage, chunkPos, nbt); + return holder.protoChunk; + } + -+ public static InProgressChunkHolder loadChunk(ServerLevel world, PoiManager poiStorage, ChunkPos chunkPos, CompoundTag nbt, boolean distinguish) { -+ // Paper end - ChunkPos chunkcoordintpair1 = new ChunkPos(nbt.getInt("xPos"), nbt.getInt("zPos")); ++ public static InProgressChunkHolder readInProgressChunkHolder(ServerLevel world, PoiManager poiStorage, ChunkPos chunkPos, CompoundTag nbt) { ++ // Paper end - rewrite chunk system + ChunkPos chunkcoordintpair1 = new ChunkPos(nbt.getInt("xPos"), nbt.getInt("zPos")); // Paper - guard against serializing mismatching coordinates; diff on change, see ChunkSerializer#getChunkCoordinate if (!Objects.equals(chunkPos, chunkcoordintpair1)) { @@ -0,0 +0,0 @@ public class ChunkSerializer { @@ -21768,15 +21769,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - async chunk io - public void write(ChunkPos chunkPos, CompoundTag nbt) { ++ public void write(ChunkPos chunkPos, CompoundTag nbt) throws IOException { // Paper - rewrite chunk system; async chunk io + // Paper start - guard against serializing mismatching coordinates + if (nbt != null && !chunkPos.equals(ChunkSerializer.getChunkCoordinate(nbt))) { + final String world = (this instanceof net.minecraft.server.level.ChunkMap) ? ((net.minecraft.server.level.ChunkMap) this).level.getWorld().getName() : null; +@@ -0,0 +0,0 @@ public class ChunkStorage implements AutoCloseable { + + " but compound says coordinate is " + ChunkSerializer.getChunkCoordinate(nbt) + (world == null ? " for an unknown world" : (" for world: " + world))); + } + // Paper end - guard against serializing mismatching coordinates - this.worker.store(chunkPos, nbt); -+ // Paper start - async chunk io -+ public void write(ChunkPos chunkPos, CompoundTag nbt) throws IOException { -+ this.regionFileCache.write(chunkPos, nbt); -+ // Paper end - Async chunk loading ++ this.regionFileCache.write(chunkPos, nbt); // Paper - rewrite chunk system; async chunk io if (this.legacyStructureHandler != null) { -+ synchronized (this.persistentDataLock) { // Paper - Async chunk loading ++ synchronized (this.persistentDataLock) { // Paper - rewrite chunk system; async chunk io this.legacyStructureHandler.removeIndex(chunkPos.toLong()); -+ } // Paper - Async chunk loading ++ } // Paper - rewrite chunk system; async chunk io } } @@ -22084,7 +22090,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return null; + } + // Paper end - cache regionfile does not exist state - if (this.regionCache.size() >= 256) { + if (this.regionCache.size() >= io.papermc.paper.configuration.GlobalConfiguration.get().misc.regionFileCacheSize) { // Paper - Sanitise RegionFileCache and make configurable ((RegionFile) this.regionCache.removeLast()).close(); } @@ -22143,22 +22149,28 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 protected void write(ChunkPos pos, @Nullable CompoundTag nbt) throws IOException { - RegionFile regionfile = this.getRegionFile(pos, false); // CraftBukkit -+ RegionFile regionfile = this.getRegionFile(pos, nbt == null, true); // CraftBukkit // Paper // Paper start - rewrite chunk system ++ // Paper start - rewrite chunk system ++ RegionFile regionfile = this.getRegionFile(pos, nbt == null, true); // CraftBukkit + if (nbt == null && regionfile == null) { + return; + } + // Paper end - rewrite chunk system -+ try { // Paper - - if (nbt == null) { - regionfile.clear(pos); + // Paper start - Chunk save reattempt + int attempts = 0; + Exception lastException = null; @@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable { + return; + } catch (Exception ex) { + lastException = ex; ++ // Paper start - rewrite chunk system ++ } finally { ++ regionfile.fileLock.unlock(); ++ // Paper end - rewrite chunk system } } -+ } finally { // Paper start -+ regionfile.fileLock.unlock(); -+ } // Paper end +@@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable { + // Paper end - Chunk save reattempt } - public void close() throws IOException { @@ -23004,10 +23016,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private static WatchdogThread instance; @@ -0,0 +0,0 @@ public class WatchdogThread extends Thread - // + // Paper end - Different message for short timeout log.log( Level.SEVERE, "------------------------------" ); - log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Spigot!):" ); -+ io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.dumpAllChunkLoadInfo(isLongTimeout); // Paper // Paper - rewrite chunk system + log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper ++ io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.dumpAllChunkLoadInfo(isLongTimeout); // Paper - rewrite chunk system WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log ); log.log( Level.SEVERE, "------------------------------" ); // diff --git a/patches/server/Sanitise-RegionFileCache-and-make-configurable.patch b/patches/server/Sanitise-RegionFileCache-and-make-configurable.patch index 0d96af8f1e..2e96ad8b88 100644 --- a/patches/server/Sanitise-RegionFileCache-and-make-configurable.patch +++ b/patches/server/Sanitise-RegionFileCache-and-make-configurable.patch @@ -15,11 +15,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java @@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable { - return null; - } - // Paper end - cache regionfile does not exist state + if (regionfile != null) { + return regionfile; + } else { - if (this.regionCache.size() >= 256) { -+ if (this.regionCache.size() >= io.papermc.paper.configuration.GlobalConfiguration.get().misc.regionFileCacheSize) { // Paper - Sanitise RegionFileCache and make configurable. ++ if (this.regionCache.size() >= io.papermc.paper.configuration.GlobalConfiguration.get().misc.regionFileCacheSize) { // Paper - Sanitise RegionFileCache and make configurable ((RegionFile) this.regionCache.removeLast()).close(); } diff --git a/patches/server/Show-Paper-in-client-crashes-server-lists-and-Mojang.patch b/patches/server/Show-Paper-in-client-crashes-server-lists-and-Mojang.patch index af1d3afd5a..490ee13e88 100644 --- a/patches/server/Show-Paper-in-client-crashes-server-lists-and-Mojang.patch +++ b/patches/server/Show-Paper-in-client-crashes-server-lists-and-Mojang.patch @@ -66,7 +66,7 @@ diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/ index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/spigotmc/WatchdogThread.java +++ b/src/main/java/org/spigotmc/WatchdogThread.java -@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa +@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread private WatchdogThread(long timeoutTime, boolean restart) { @@ -75,7 +75,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.timeoutTime = timeoutTime; this.restart = restart; } -@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa +@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread { Logger log = Bukkit.getServer().getLogger(); log.log( Level.SEVERE, "------------------------------" ); @@ -93,12 +93,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // if ( net.minecraft.world.level.Level.lastPhysicsProblem != null ) { -@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa +@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread } // log.log( Level.SEVERE, "------------------------------" ); - log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Spigot!):" ); + log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper - io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.dumpAllChunkLoadInfo(isLongTimeout); // Paper // Paper - rewrite chunk system WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log ); log.log( Level.SEVERE, "------------------------------" ); + // diff --git a/patches/server/System-property-for-disabling-watchdoge.patch b/patches/server/System-property-for-disabling-watchdoge.patch index 8b145e16e3..c5213c8c5a 100644 --- a/patches/server/System-property-for-disabling-watchdoge.patch +++ b/patches/server/System-property-for-disabling-watchdoge.patch @@ -8,7 +8,7 @@ diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/ index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/spigotmc/WatchdogThread.java +++ b/src/main/java/org/spigotmc/WatchdogThread.java -@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa +@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread while ( !this.stopping ) { // diff --git a/patches/server/Use-a-Queue-for-Queueing-Commands.patch b/patches/server/Use-a-Queue-for-Queueing-Commands.patch index 6912b5b510..637c1a6922 100644 --- a/patches/server/Use-a-Queue-for-Queueing-Commands.patch +++ b/patches/server/Use-a-Queue-for-Queueing-Commands.patch @@ -19,9 +19,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private QueryThreadGs4 queryThreadGs4; // private final RemoteControlCommandListener rconConsoleSource; // CraftBukkit - remove field @@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface - return; - } - // Paper end - rewrite chunk system + } + + public void handleConsoleInput(String command, CommandSourceStack commandSource) { - this.consoleInput.add(new ConsoleInput(command, commandSource)); + this.serverCommandQueue.add(new ConsoleInput(command, commandSource)); // Paper - Perf: use proper queue } diff --git a/patches/server/incremental-chunk-and-player-saving.patch b/patches/server/incremental-chunk-and-player-saving.patch index 105200bc08..cf1f4fe2c8 100644 --- a/patches/server/incremental-chunk-and-player-saving.patch +++ b/patches/server/incremental-chunk-and-player-saving.patch @@ -115,8 +115,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - Incremental chunk and player saving + public void save(@Nullable ProgressListener progressListener, boolean flush, boolean savingDisabled) { - // Paper start - rewrite chunk system - add close param - this.save(progressListener, flush, savingDisabled, false); + ServerChunkCache chunkproviderserver = this.getChunkSource(); + diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java diff --git a/scripts/moveback.py b/scripts/moveback.py index 6dec9e0759..6135e33d8b 100644 --- a/scripts/moveback.py +++ b/scripts/moveback.py @@ -2,8 +2,8 @@ import os import sys # Use inside of server patch dir -# py ../../scripts/moveback.py '' -patch_target = 100 # TODO: Update this +# py ../../scripts/moveback.py 'Rewrite chunk system' +patch_target = 400 # TODO: Update this def increment_number(filename):