diff --git a/patches/unapplied/server/Attempt-to-recalculate-regionfile-header-if-it-is-co.patch b/patches/server/Attempt-to-recalculate-regionfile-header-if-it-is-co.patch similarity index 97% rename from patches/unapplied/server/Attempt-to-recalculate-regionfile-header-if-it-is-co.patch rename to patches/server/Attempt-to-recalculate-regionfile-header-if-it-is-co.patch index e56d40017e..6cfd78acc2 100644 --- a/patches/unapplied/server/Attempt-to-recalculate-regionfile-header-if-it-is-co.patch +++ b/patches/server/Attempt-to-recalculate-regionfile-header-if-it-is-co.patch @@ -30,7 +30,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end - public static final Codec> BLOCK_STATE_CODEC = PalettedContainer.codecRW(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState(), null); // Paper - Anti-Xray - Add preset block states + public static final Codec> BLOCK_STATE_CODEC = PalettedContainer.codecRW(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState()); private static final Logger LOGGER = LogUtils.getLogger(); @@ -0,0 +0,0 @@ public class ChunkSerializer { nbttagcompound.putInt("xPos", chunkcoordintpair.x); @@ -39,7 +39,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - nbttagcompound.putLong("LastUpdate", asyncsavedata != null ? asyncsavedata.worldTime : world.getGameTime()); // Paper - async chunk unloading + nbttagcompound.putLong("LastUpdate", asyncsavedata != null ? asyncsavedata.worldTime : world.getGameTime()); // Paper - async chunk unloading // Paper - diff on change nbttagcompound.putLong("InhabitedTime", chunk.getInhabitedTime()); - nbttagcompound.putString("Status", chunk.getStatus().getName()); + nbttagcompound.putString("Status", BuiltInRegistries.CHUNK_STATUS.getKey(chunk.getStatus()).toString()); BlendingData blendingdata = chunk.getBlendingData(); diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 @@ -689,11 +689,16 @@ 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 { + public final Long2ObjectLinkedOpenHashMap regionCache = new Long2ObjectLinkedOpenHashMap(); private final Path folder; private final boolean sync; - + private final boolean isChunkData; // Paper -+ + + // Paper start - cache regionfile does not exist state + static final int MAX_NON_EXISTING_CACHE = 1024 * 64; +@@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable { + // Paper end - cache regionfile does not exist state + protected RegionFileStorage(Path directory, boolean dsync) { // Paper - protected constructor + // Paper start - add isChunkData param + this(directory, dsync, false); @@ -705,12 +710,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.sync = dsync; } @@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable { - FileUtil.createDirectoriesSafe(this.folder); + // Paper - only create directory if not existing only - moved down Path path = this.folder; int j = chunkcoordintpair.getRegionX(); - Path path1 = path.resolve("r." + j + "." + chunkcoordintpair.getRegionZ() + ".mca"); + Path path1 = path.resolve("r." + j + "." + chunkcoordintpair.getRegionZ() + ".mca"); // Paper - diff on change - if (existingOnly && !java.nio.file.Files.exists(path1)) return null; // CraftBukkit + if (existingOnly && !java.nio.file.Files.exists(path1)) { // Paper start - cache regionfile does not exist state + this.markNonExisting(regionPos); + return null; // CraftBukkit +@@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable { + } + // Paper end - cache regionfile does not exist state + FileUtil.createDirectoriesSafe(this.folder); // Paper - only create directory if not existing only - moved from above - RegionFile regionfile1 = new RegionFile(path1, this.folder, this.sync); + RegionFile regionfile1 = new RegionFile(path1, this.folder, this.sync, this.isChunkData); // Paper - allow for chunk regionfiles to regen header diff --git a/patches/unapplied/server/Custom-table-implementation-for-blockstate-state-loo.patch b/patches/server/Custom-table-implementation-for-blockstate-state-loo.patch similarity index 99% rename from patches/unapplied/server/Custom-table-implementation-for-blockstate-state-loo.patch rename to patches/server/Custom-table-implementation-for-blockstate-state-loo.patch index 280406878f..dadf8da35d 100644 --- a/patches/unapplied/server/Custom-table-implementation-for-blockstate-state-loo.patch +++ b/patches/server/Custom-table-implementation-for-blockstate-state-loo.patch @@ -217,7 +217,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - Comparable comparable = this.values.get(property); - if (comparable == null) { - throw new IllegalArgumentException("Cannot set property " + property + " as it does not exist in " + this.owner); -- } else if (comparable == value) { +- } else if (comparable.equals(value)) { - return (S)this; - } else { - S object = this.neighbours.get(property, value); diff --git a/patches/unapplied/server/Detail-more-information-in-watchdog-dumps.patch b/patches/server/Detail-more-information-in-watchdog-dumps.patch similarity index 99% rename from patches/unapplied/server/Detail-more-information-in-watchdog-dumps.patch rename to patches/server/Detail-more-information-in-watchdog-dumps.patch index a33d4bc3ac..ae25387d6f 100644 --- a/patches/unapplied/server/Detail-more-information-in-watchdog-dumps.patch +++ b/patches/server/Detail-more-information-in-watchdog-dumps.patch @@ -169,7 +169,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.setPos(this.getX() + movement.x, this.getY() + movement.y, this.getZ() + movement.z); } else { @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { - this.level.getProfiler().pop(); + return false; } } + // Paper start - detailed watchdog information diff --git a/patches/unapplied/server/Execute-chunk-tasks-mid-tick.patch b/patches/server/Execute-chunk-tasks-mid-tick.patch similarity index 98% rename from patches/unapplied/server/Execute-chunk-tasks-mid-tick.patch rename to patches/server/Execute-chunk-tasks-mid-tick.patch index 2204eb204c..b3f0ef04bd 100644 --- a/patches/unapplied/server/Execute-chunk-tasks-mid-tick.patch +++ b/patches/server/Execute-chunk-tasks-mid-tick.patch @@ -110,9 +110,10 @@ 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 { + Collections.shuffle(shuffled); iterator1 = shuffled.iterator(); } - ++ + int chunksTicked = 0; // Paper try { while (iterator1.hasNext()) { @@ -130,9 +131,9 @@ 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 { - private final StructureManager structureManager; private final StructureCheck structureCheck; private final boolean tickTime; + private final RandomSequences randomSequences; + public long lastMidTickExecuteFailure; // Paper - execute chunk tasks mid tick // CraftBukkit start diff --git a/patches/unapplied/server/Manually-inline-methods-in-BlockPosition.patch b/patches/server/Manually-inline-methods-in-BlockPosition.patch similarity index 100% rename from patches/unapplied/server/Manually-inline-methods-in-BlockPosition.patch rename to patches/server/Manually-inline-methods-in-BlockPosition.patch diff --git a/patches/unapplied/server/Optimise-chunk-tick-iteration.patch b/patches/server/Optimise-chunk-tick-iteration.patch similarity index 99% rename from patches/unapplied/server/Optimise-chunk-tick-iteration.patch rename to patches/server/Optimise-chunk-tick-iteration.patch index 61aa1b9543..5e3384dc36 100644 --- a/patches/unapplied/server/Optimise-chunk-tick-iteration.patch +++ b/patches/server/Optimise-chunk-tick-iteration.patch @@ -69,7 +69,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - if (this.hasChangedSections || !this.skyChangedLightSectionFilter.isEmpty() || !this.blockChangedLightSectionFilter.isEmpty()) { + if (this.needsBroadcastChanges()) { // Paper - moved into above, other logic needs to call Level world = chunk.getLevel(); - int i = 0; + List list; diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 @@ -130,7 +130,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper - only shuffle if per-player mob spawning is disabled // Paper - moved natural spawn event up - Iterator iterator1 = list.iterator(); -+ // Paper start - optimise chunk tick iteration + ++ // Paper start - optimise chunk tick iteratio + Iterator iterator1; + if (this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { + iterator1 = this.entityTickingChunks.iterator(); @@ -143,7 +144,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + Collections.shuffle(shuffled); + iterator1 = shuffled.iterator(); + } - + try { while (iterator1.hasNext()) { - ServerChunkCache.ChunkAndHolder chunkproviderserver_a = (ServerChunkCache.ChunkAndHolder) iterator1.next(); diff --git a/patches/unapplied/server/Optimize-anyPlayerCloseEnoughForSpawning-to-use-dist.patch b/patches/server/Optimize-anyPlayerCloseEnoughForSpawning-to-use-dist.patch similarity index 95% rename from patches/unapplied/server/Optimize-anyPlayerCloseEnoughForSpawning-to-use-dist.patch rename to patches/server/Optimize-anyPlayerCloseEnoughForSpawning-to-use-dist.patch index 40ab4c05ab..c7bd8846f7 100644 --- a/patches/unapplied/server/Optimize-anyPlayerCloseEnoughForSpawning-to-use-dist.patch +++ b/patches/server/Optimize-anyPlayerCloseEnoughForSpawning-to-use-dist.patch @@ -38,17 +38,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet playersInChunkTickRange; + // Paper end - optimise anyPlayerCloseEnoughForSpawning + - public ChunkHolder(ChunkPos pos, LevelHeightAccessor world, LevelLightEngine lightingProvider, ChunkHolder.PlayerProvider playersWatchingChunkProvider, io.papermc.paper.chunk.system.scheduling.NewChunkHolder newChunkHolder) { // Paper - rewrite chunk system - this.newChunkHolder = newChunkHolder; // Paper - rewrite chunk system - this.chunkToSaveHistory = null; + // Paper start - replace player chunk loader + private final com.destroystokyo.paper.util.maplist.ReferenceList playersSentChunkTo = new com.destroystokyo.paper.util.maplist.ReferenceList<>(); + diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + // Paper start - distance maps private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>(); - public final io.papermc.paper.chunk.PlayerChunkLoader playerChunkManager = new io.papermc.paper.chunk.PlayerChunkLoader(this, this.pooledLinkedPlayerHashSets); // Paper - replace chunk loader ++ public final io.papermc.paper.chunk.PlayerChunkLoader playerChunkManager = new io.papermc.paper.chunk.PlayerChunkLoader(this, this.pooledLinkedPlayerHashSets); // Paper - replace chunk loader + // Paper start - optimise ChunkMap#anyPlayerCloseEnoughForSpawning + // A note about the naming used here: + // Previously, mojang used a "spawn range" of 8 for controlling both ticking and @@ -62,7 +63,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - optimise ChunkMap#anyPlayerCloseEnoughForSpawning void addPlayerToDistanceMaps(ServerPlayer player) { - this.playerChunkManager.addPlayer(player); // Paper - replace chunk loader + this.level.playerChunkLoader.addPlayer(player); // Paper - replace chunk loader int chunkX = MCUtil.getChunkCoordinate(player.getX()); int chunkZ = MCUtil.getChunkCoordinate(player.getZ()); // Note: players need to be explicitly added to distance maps before they can be updated @@ -72,7 +73,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.playerMobDistanceMap.add(player, chunkX, chunkZ, io.papermc.paper.chunk.system.ChunkSystem.getTickViewDistance(player)); @@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider void removePlayerFromDistanceMaps(ServerPlayer player) { - this.playerChunkManager.removePlayer(player); // Paper - replace chunk loader + this.level.playerChunkLoader.removePlayer(player); // Paper - replace chunk loader + // Paper start - optimise ChunkMap#anyPlayerCloseEnoughForSpawning + this.playerMobSpawnMap.remove(player); @@ -84,7 +85,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider int chunkZ = MCUtil.getChunkCoordinate(player.getZ()); // Note: players need to be explicitly added to distance maps before they can be updated - this.playerChunkManager.updatePlayer(player); // Paper - replace chunk loader + this.level.playerChunkLoader.updatePlayer(player); // Paper - replace chunk loader + this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise ChunkMap#anyPlayerCloseEnoughForSpawning // Paper start - per player mob spawning if (this.playerMobDistanceMap != null) { @@ -213,14 +214,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/level/DistanceManager.java +++ b/src/main/java/net/minecraft/server/level/DistanceManager.java @@ -0,0 +0,0 @@ public abstract class DistanceManager { - private static final int BLOCK_TICKING_LEVEL_THRESHOLD = 33; + private static final int INITIAL_TICKET_LIST_CAPACITY = 4; final Long2ObjectMap> playersPerChunk = new Long2ObjectOpenHashMap(); // Paper - rewrite chunk system - private final DistanceManager.FixedPlayerDistanceChunkTracker naturalSpawnChunkCounter = new DistanceManager.FixedPlayerDistanceChunkTracker(8); + public static final int MOB_SPAWN_RANGE = 8; // private final DistanceManager.FixedPlayerDistanceChunkTracker naturalSpawnChunkCounter = new DistanceManager.FixedPlayerDistanceChunkTracker(8); // Paper - no longer used - //private final TickingTracker tickingTicketsTracker = new TickingTracker(); // Paper - no longer used - //private final DistanceManager.PlayerTicketTracker playerTicketManager = new DistanceManager.PlayerTicketTracker(33); // Paper - no longer used // Paper - rewrite chunk system + private final ChunkMap chunkMap; // Paper + @@ -0,0 +0,0 @@ public abstract class DistanceManager { long i = chunkcoordintpair.toLong(); @@ -337,10 +338,10 @@ 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 String kickLeaveMessage = null; // SPIGOT-3034: Forward leave message to PlayerQuitEvent + public Integer clientViewDistance; // CraftBukkit end public boolean isRealPlayer; // Paper + public double lastEntitySpawnRadiusSquared; // Paper - optimise isOutsideRange, this field is in blocks public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet cachedSingleHashSet; // Paper public PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - + public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - there are a lot of changes to do if we change all methods leading to the event