diff --git a/patches/server/0770-Do-not-copy-visible-chunks.patch b/patches/server/0770-Do-not-copy-visible-chunks.patch index f63bf3fee5..06f5dfa56a 100644 --- a/patches/server/0770-Do-not-copy-visible-chunks.patch +++ b/patches/server/0770-Do-not-copy-visible-chunks.patch @@ -21,11 +21,24 @@ index 807bbe54f6516f794bdcb735bb7b8d6812e3ef01..2ef4b4c2ff81d0fa33d4630593266066 if (chunk.getFullChunkUnchecked() == null) { continue; } +diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java +index 379ba589b0423284d63782d951c64770b160cf2d..ee668b989d661e1db1bdfe05b94d7cdadeae6923 100644 +--- a/src/main/java/net/minecraft/server/MCUtil.java ++++ b/src/main/java/net/minecraft/server/MCUtil.java +@@ -614,7 +614,7 @@ public final class MCUtil { + + ServerLevel world = ((org.bukkit.craftbukkit.CraftWorld)bukkitWorld).getHandle(); + ChunkMap chunkMap = world.getChunkSource().chunkMap; +- Long2ObjectLinkedOpenHashMap visibleChunks = chunkMap.visibleChunkMap; ++ Long2ObjectLinkedOpenHashMap visibleChunks = chunkMap.updatingChunks.getVisibleMap(); // Paper + DistanceManager chunkMapDistance = chunkMap.distanceManager; + List allChunks = new ArrayList<>(visibleChunks.values()); + List players = world.players; diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 313a591dda5ef3962b4eab377abdce7c7ad08ec7..364caf495bb8df867885f9df8dfd0c0f1b4673a6 100644 +index 6cf01d98d5d7a41f743527381d496c0d01421928..ff2fbe220da7daf572298a3d65cd11257fcc147c 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -114,6 +114,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -114,9 +114,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider private static final int MIN_VIEW_DISTANCE = 3; public static final int MAX_VIEW_DISTANCE = 33; public static final int MAX_CHUNK_DISTANCE = 33 + ChunkStatus.maxDistance(); @@ -33,9 +46,22 @@ index 313a591dda5ef3962b4eab377abdce7c7ad08ec7..364caf495bb8df867885f9df8dfd0c0f + public final com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object updatingChunks = new com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<>(); + // Paper end - Don't copy public static final int FORCED_TICKET_LEVEL = 31; - public final Long2ObjectLinkedOpenHashMap updatingChunkMap = new Long2ObjectLinkedOpenHashMap(); - public volatile Long2ObjectLinkedOpenHashMap visibleChunkMap; -@@ -676,12 +679,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +- public final Long2ObjectLinkedOpenHashMap updatingChunkMap = new Long2ObjectLinkedOpenHashMap(); +- public volatile Long2ObjectLinkedOpenHashMap visibleChunkMap; ++ // Paper - Don't copy + private final Long2ObjectLinkedOpenHashMap pendingUnloads; + public final LongSet entitiesInLevel; + public final ServerLevel level; +@@ -344,7 +346,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + boolean unloadingPlayerChunk = false; // Paper - do not allow ticket level changes while unloading chunks + public ChunkMap(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureManager structureManager, Executor executor, BlockableEventLoop mainThreadExecutor, LightChunkGetter chunkProvider, ChunkGenerator chunkGenerator, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier persistentStateManagerFactory, int viewDistance, boolean dsync) { + super(new File(session.getDimensionPath(world.dimension()), "region"), dataFixer, dsync); +- this.visibleChunkMap = this.updatingChunkMap.clone(); ++ // Paper - don't copy + this.pendingUnloads = new Long2ObjectLinkedOpenHashMap(); + this.entitiesInLevel = new LongOpenHashSet(); + this.toDrop = new LongOpenHashSet(); +@@ -676,12 +678,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @Nullable public ChunkHolder getUpdatingChunkIfPresent(long pos) { @@ -55,7 +81,7 @@ index 313a591dda5ef3962b4eab377abdce7c7ad08ec7..364caf495bb8df867885f9df8dfd0c0f } protected IntSupplier getChunkQueueLevel(long pos) { -@@ -833,7 +841,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -833,7 +840,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider // Paper end } @@ -64,7 +90,25 @@ index 313a591dda5ef3962b4eab377abdce7c7ad08ec7..364caf495bb8df867885f9df8dfd0c0f this.modified = true; } -@@ -986,7 +994,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -913,7 +920,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + + protected void saveAllChunks(boolean flush) { + if (flush) { +- List list = (List) this.visibleChunkMap.values().stream().filter(ChunkHolder::wasAccessibleSinceLastSave).peek(ChunkHolder::refreshAccessibility).collect(Collectors.toList()); ++ List list = (List) this.updatingChunks.getVisibleValuesCopy().stream().filter(ChunkHolder::wasAccessibleSinceLastSave).peek(ChunkHolder::refreshAccessibility).collect(Collectors.toList()); // Paper + MutableBoolean mutableboolean = new MutableBoolean(); + + do { +@@ -944,7 +951,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + this.level.asyncChunkTaskManager.flush(); // Paper - flush to preserve behavior compat with pre-async behaviour + // this.i(); // Paper - nuke IOWorker + } else { +- this.visibleChunkMap.values().stream().filter(ChunkHolder::wasAccessibleSinceLastSave).forEach((playerchunk) -> { ++ this.updatingChunks.getVisibleValuesCopy().stream().filter(ChunkHolder::wasAccessibleSinceLastSave).forEach((playerchunk) -> { // Paper + ChunkAccess ichunkaccess = (ChunkAccess) playerchunk.getChunkToSave().getNow(null); // CraftBukkit - decompile error + + if (ichunkaccess instanceof ImposterProtoChunk || ichunkaccess instanceof LevelChunk) { +@@ -986,7 +993,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider while (longiterator.hasNext()) { // Spigot long j = longiterator.nextLong(); longiterator.remove(); // Spigot @@ -73,7 +117,7 @@ index 313a591dda5ef3962b4eab377abdce7c7ad08ec7..364caf495bb8df867885f9df8dfd0c0f if (playerchunk != null) { this.pendingUnloads.put(j, playerchunk); -@@ -1121,7 +1129,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1121,7 +1128,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider if (!this.modified) { return false; } else { @@ -87,7 +131,7 @@ index 313a591dda5ef3962b4eab377abdce7c7ad08ec7..364caf495bb8df867885f9df8dfd0c0f this.modified = false; return true; } -@@ -1587,7 +1600,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1587,7 +1599,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public int size() { @@ -96,6 +140,21 @@ index 313a591dda5ef3962b4eab377abdce7c7ad08ec7..364caf495bb8df867885f9df8dfd0c0f } protected DistanceManager getDistanceManager() { +@@ -1595,12 +1607,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + } + + protected Iterable getChunks() { +- return Iterables.unmodifiableIterable(this.visibleChunkMap.values()); ++ return Iterables.unmodifiableIterable(this.updatingChunks.getVisibleValuesCopy()); // Paper + } + + void dumpChunks(Writer writer) throws IOException { + CsvOutput csvwriter = CsvOutput.builder().addColumn("x").addColumn("z").addColumn("level").addColumn("in_memory").addColumn("status").addColumn("full_status").addColumn("accessible_ready").addColumn("ticking_ready").addColumn("entity_ticking_ready").addColumn("ticket").addColumn("spawning").addColumn("block_entity_count").build(writer); +- ObjectBidirectionalIterator objectbidirectionaliterator = this.visibleChunkMap.long2ObjectEntrySet().iterator(); ++ ObjectBidirectionalIterator objectbidirectionaliterator = this.updatingChunks.getVisibleMap().clone().long2ObjectEntrySet().fastIterator(); // Paper + + while (objectbidirectionaliterator.hasNext()) { + Entry entry = (Entry) objectbidirectionaliterator.next(); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java index 6dd6008e3e540d48939f7f3f0c03f7fd920d7d4a..40463344f364618dd2e7330cb0168ff69a5fa58b 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java diff --git a/patches/server/0771-Replace-player-chunk-loader-system.patch b/patches/server/0771-Replace-player-chunk-loader-system.patch index de6d3562e5..b9628ded85 100644 --- a/patches/server/0771-Replace-player-chunk-loader-system.patch +++ b/patches/server/0771-Replace-player-chunk-loader-system.patch @@ -1173,7 +1173,7 @@ index 379ba589b0423284d63782d951c64770b160cf2d..86d1bb22665bf46c7744ef653eda0cae worldData.addProperty("keep-spawn-loaded-range", world.paperConfig.keepLoadedRange); worldData.addProperty("visible-chunk-count", visibleChunks.size()); diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java -index 5c138478fd1bdbf84626dbcca3e8c31729e41a9f..a36f3b37cb36f0bcc3e45ff66e02e30ce5ff0f96 100644 +index 54822e418e319db551bfea3218d00faf0e043f43..de0c6316c9b75a2ecc7d6abf7bcca24e25de0ac0 100644 --- a/src/main/java/net/minecraft/server/level/ChunkHolder.java +++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java @@ -491,7 +491,7 @@ public class ChunkHolder { @@ -1202,10 +1202,10 @@ index 5c138478fd1bdbf84626dbcca3e8c31729e41a9f..a36f3b37cb36f0bcc3e45ff66e02e30c } } diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 364caf495bb8df867885f9df8dfd0c0f1b4673a6..45b668095459c16d2a723870d7533c69463bfde8 100644 +index ff2fbe220da7daf572298a3d65cd11257fcc147c..74a2e70220832257c036c40e0aa8626ab2a4ae7f 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -188,22 +188,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -187,22 +187,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider final CallbackExecutor chunkLoadConversionCallbackExecutor = new CallbackExecutor(); // Paper // Paper start - distance maps private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>(); @@ -1229,7 +1229,7 @@ index 364caf495bb8df867885f9df8dfd0c0f1b4673a6..45b668095459c16d2a723870d7533c69 // Paper start - use distance map to optimise tracker public static boolean isLegacyTrackingEntity(Entity entity) { return entity.isLegacyTrackingEntity; -@@ -242,7 +227,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -241,7 +226,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider com.destroystokyo.paper.util.misc.PlayerAreaMap trackMap = this.playerEntityTrackerTrackMaps[i]; int trackRange = this.entityTrackerTrackRanges[i]; @@ -1238,7 +1238,7 @@ index 364caf495bb8df867885f9df8dfd0c0f1b4673a6..45b668095459c16d2a723870d7533c69 } // Paper end - use distance map to optimise entity tracker // Paper start - optimise PlayerChunkMap#isOutsideRange -@@ -251,19 +236,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -250,19 +235,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider // Paper start - optimise PlayerChunkMap#isOutsideRange this.playerChunkTickRangeMap.add(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper end - optimise PlayerChunkMap#isOutsideRange @@ -1259,7 +1259,7 @@ index 364caf495bb8df867885f9df8dfd0c0f1b4673a6..45b668095459c16d2a723870d7533c69 } void removePlayerFromDistanceMaps(ServerPlayer player) { -@@ -276,11 +249,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -275,11 +248,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.playerMobSpawnMap.remove(player); this.playerChunkTickRangeMap.remove(player); // Paper end - optimise PlayerChunkMap#isOutsideRange @@ -1272,7 +1272,7 @@ index 364caf495bb8df867885f9df8dfd0c0f1b4673a6..45b668095459c16d2a723870d7533c69 } void updateMaps(ServerPlayer player) { -@@ -292,25 +261,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -291,25 +260,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider com.destroystokyo.paper.util.misc.PlayerAreaMap trackMap = this.playerEntityTrackerTrackMaps[i]; int trackRange = this.entityTrackerTrackRanges[i]; @@ -1300,7 +1300,7 @@ index 364caf495bb8df867885f9df8dfd0c0f1b4673a6..45b668095459c16d2a723870d7533c69 } // Paper end // Paper start -@@ -395,43 +352,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -394,43 +351,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.regionManagers.add(this.dataRegionManager); // Paper end // Paper start - no-tick view distance @@ -1345,7 +1345,7 @@ index 364caf495bb8df867885f9df8dfd0c0f1b4673a6..45b668095459c16d2a723870d7533c69 // Paper end - no-tick view distance this.playerMobDistanceMap = this.level.paperConfig.perPlayerMobSpawns ? new com.destroystokyo.paper.util.PlayerMobDistanceMap() : null; // Paper // Paper start - use distance map to optimise entity tracker -@@ -538,6 +459,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -537,6 +458,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public void checkHighPriorityChunks(ServerPlayer player) { @@ -1353,7 +1353,7 @@ index 364caf495bb8df867885f9df8dfd0c0f1b4673a6..45b668095459c16d2a723870d7533c69 int currentTick = MinecraftServer.currentTick; if (currentTick - player.lastHighPriorityChecked < 20 || !player.isRealPlayer) { // weed out fake players return; -@@ -545,7 +467,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -544,7 +466,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider player.lastHighPriorityChecked = currentTick; it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap priorities = new it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap(); @@ -1362,7 +1362,7 @@ index 364caf495bb8df867885f9df8dfd0c0f1b4673a6..45b668095459c16d2a723870d7533c69 net.minecraft.core.BlockPos.MutableBlockPos pos = new net.minecraft.core.BlockPos.MutableBlockPos(); // Prioritize circular near -@@ -611,7 +533,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -610,7 +532,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } private boolean shouldSkipPrioritization(ChunkPos coord) { @@ -1371,7 +1371,7 @@ index 364caf495bb8df867885f9df8dfd0c0f1b4673a6..45b668095459c16d2a723870d7533c69 ChunkHolder chunk = getUpdatingChunkIfPresent(coord.toLong()); return chunk != null && (chunk.isFullChunkReady()); } -@@ -1549,7 +1471,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1548,7 +1470,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider int k = this.viewDistance; this.viewDistance = j; @@ -1380,7 +1380,7 @@ index 364caf495bb8df867885f9df8dfd0c0f1b4673a6..45b668095459c16d2a723870d7533c69 } } -@@ -1557,26 +1479,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1556,26 +1478,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider // Paper start - no-tick view distance public final void setNoTickViewDistance(int viewDistance) { viewDistance = viewDistance == -1 ? -1 : Mth.clamp(viewDistance, 2, 32); @@ -1409,7 +1409,7 @@ index 364caf495bb8df867885f9df8dfd0c0f1b4673a6..45b668095459c16d2a723870d7533c69 if (player.level == this.level) { if (withinViewDistance && !withinMaxWatchDistance) { ChunkHolder playerchunk = this.getVisibleChunkIfPresent(pos.toLong()); -@@ -1905,6 +1812,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1904,6 +1811,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider */ // Paper end - replaced by distance map this.updateMaps(player); // Paper - distance maps @@ -1417,7 +1417,7 @@ index 364caf495bb8df867885f9df8dfd0c0f1b4673a6..45b668095459c16d2a723870d7533c69 } -@@ -1913,7 +1821,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1912,7 +1820,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider // Paper start - per player view distance // there can be potential desync with player's last mapped section and the view distance map, so use the // view distance map here. @@ -1426,7 +1426,7 @@ index 364caf495bb8df867885f9df8dfd0c0f1b4673a6..45b668095459c16d2a723870d7533c69 if (inRange == null) { return Stream.empty(); -@@ -1929,8 +1837,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1928,8 +1836,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider continue; } ServerPlayer player = (ServerPlayer)temp; @@ -1438,7 +1438,7 @@ index 364caf495bb8df867885f9df8dfd0c0f1b4673a6..45b668095459c16d2a723870d7533c69 int distX = Math.abs(MCUtil.getCoordinateX(lastPosition) - chunkPos.x); int distZ = Math.abs(MCUtil.getCoordinateZ(lastPosition) - chunkPos.z); -@@ -1945,6 +1854,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1944,6 +1853,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider continue; } ServerPlayer player = (ServerPlayer)temp; @@ -1446,7 +1446,7 @@ index 364caf495bb8df867885f9df8dfd0c0f1b4673a6..45b668095459c16d2a723870d7533c69 players.add(player); } } -@@ -2358,7 +2268,7 @@ Sections go from 0..16. Now whenever a section is not empty, it can potentially +@@ -2357,7 +2267,7 @@ Sections go from 0..16. Now whenever a section is not empty, it can potentially double vec3d_dy = player.getY() - this.entity.getY(); double vec3d_dz = player.getZ() - this.entity.getZ(); // Paper end - remove allocation of Vec3D here diff --git a/patches/server/0789-Oprimise-map-impl-for-tracked-players.patch b/patches/server/0789-Oprimise-map-impl-for-tracked-players.patch index 3353e126fe..62b0eed04b 100644 --- a/patches/server/0789-Oprimise-map-impl-for-tracked-players.patch +++ b/patches/server/0789-Oprimise-map-impl-for-tracked-players.patch @@ -7,7 +7,7 @@ Reference2BooleanOpenHashMap is going to have better lookups than HashMap. diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 45b668095459c16d2a723870d7533c69463bfde8..b5015f0a59aeb77636e6b1dd4df7381660d0788c 100644 +index 74a2e70220832257c036c40e0aa8626ab2a4ae7f..ab14316375f41a7d7177159d10f1281349b97337 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -103,6 +103,7 @@ import org.apache.logging.log4j.LogManager; @@ -18,7 +18,7 @@ index 45b668095459c16d2a723870d7533c69463bfde8..b5015f0a59aeb77636e6b1dd4df73816 public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider { -@@ -2168,7 +2169,7 @@ Sections go from 0..16. Now whenever a section is not empty, it can potentially +@@ -2167,7 +2168,7 @@ Sections go from 0..16. Now whenever a section is not empty, it can potentially final Entity entity; private final int range; SectionPos lastSectionPos; diff --git a/patches/server/0794-Optimise-nearby-player-lookups.patch b/patches/server/0794-Optimise-nearby-player-lookups.patch index 45b808ae11..f658df2f28 100644 --- a/patches/server/0794-Optimise-nearby-player-lookups.patch +++ b/patches/server/0794-Optimise-nearby-player-lookups.patch @@ -9,7 +9,7 @@ since the penalty of a map lookup could outweigh the benefits of searching less players (as it basically did in the outside range patch). diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java -index 54cb9f909df7d1041cec553e1f54ff8ecff48bbe..82b6b099e3014ab539f4155639efd33ebba88a3e 100644 +index 4588ae8037407b81c99135863eb0c4e97c564c24..2a33071c4b69cb7b5a7e296e8fd903e3a528b210 100644 --- a/src/main/java/net/minecraft/server/level/ChunkHolder.java +++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java @@ -242,6 +242,12 @@ public class ChunkHolder { @@ -26,10 +26,10 @@ index 54cb9f909df7d1041cec553e1f54ff8ecff48bbe..82b6b099e3014ab539f4155639efd33e // Paper end - optimise isOutsideOfRange long lastAutoSaveTime; // Paper - incremental autosave diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index b5015f0a59aeb77636e6b1dd4df7381660d0788c..bc315cc74cfded9f96e55f1d5de8a41334af8017 100644 +index ab14316375f41a7d7177159d10f1281349b97337..daa589cb9441d2255dbbd30583a8c003a325976f 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -218,6 +218,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -217,6 +217,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerMobSpawnMap; // this map is absent from updateMaps since it's controlled at the start of the chunkproviderserver tick public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerChunkTickRangeMap; // Paper end - optimise PlayerChunkMap#isOutsideRange @@ -42,7 +42,7 @@ index b5015f0a59aeb77636e6b1dd4df7381660d0788c..bc315cc74cfded9f96e55f1d5de8a413 void addPlayerToDistanceMaps(ServerPlayer player) { int chunkX = MCUtil.getChunkCoordinate(player.getX()); -@@ -238,6 +244,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -237,6 +243,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.playerChunkTickRangeMap.add(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper end - optimise PlayerChunkMap#isOutsideRange this.playerChunkManager.addPlayer(player); // Paper - replace chunk loader @@ -52,7 +52,7 @@ index b5015f0a59aeb77636e6b1dd4df7381660d0788c..bc315cc74cfded9f96e55f1d5de8a413 } void removePlayerFromDistanceMaps(ServerPlayer player) { -@@ -251,6 +260,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -250,6 +259,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.playerChunkTickRangeMap.remove(player); // Paper end - optimise PlayerChunkMap#isOutsideRange this.playerChunkManager.removePlayer(player); // Paper - replace chunk loader @@ -62,7 +62,7 @@ index b5015f0a59aeb77636e6b1dd4df7381660d0788c..bc315cc74cfded9f96e55f1d5de8a413 } void updateMaps(ServerPlayer player) { -@@ -269,6 +281,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -268,6 +280,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper end - optimise PlayerChunkMap#isOutsideRange this.playerChunkManager.updatePlayer(player); // Paper - replace chunk loader @@ -72,7 +72,7 @@ index b5015f0a59aeb77636e6b1dd4df7381660d0788c..bc315cc74cfded9f96e55f1d5de8a413 } // Paper end // Paper start -@@ -427,6 +442,23 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -426,6 +441,23 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } }); // Paper end - optimise PlayerChunkMap#isOutsideRange @@ -96,7 +96,7 @@ index b5015f0a59aeb77636e6b1dd4df7381660d0788c..bc315cc74cfded9f96e55f1d5de8a413 } // Paper start - Chunk Prioritization -@@ -740,7 +772,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -739,7 +771,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } else { if (holder != null) { holder.setTicketLevel(level); @@ -105,7 +105,7 @@ index b5015f0a59aeb77636e6b1dd4df7381660d0788c..bc315cc74cfded9f96e55f1d5de8a413 } if (holder != null) { -@@ -755,6 +787,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -754,6 +786,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider holder = (ChunkHolder) this.pendingUnloads.remove(pos); if (holder != null) { holder.setTicketLevel(level); diff --git a/patches/server/0796-Optimise-WorldServer-notify.patch b/patches/server/0796-Optimise-WorldServer-notify.patch index 1d0b79025e..ccf01c7964 100644 --- a/patches/server/0796-Optimise-WorldServer-notify.patch +++ b/patches/server/0796-Optimise-WorldServer-notify.patch @@ -8,10 +8,10 @@ Instead, only iterate over navigators in the current region that are eligible for repathing. diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index bc315cc74cfded9f96e55f1d5de8a41334af8017..b556c1ef5d9f4667fa755ae843f4f50719c5013c 100644 +index daa589cb9441d2255dbbd30583a8c003a325976f..4386402e5e55438475c48b023c61bfb2dbe71a8f 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -291,15 +291,81 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -290,15 +290,81 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider public final io.papermc.paper.chunk.SingleThreadChunkRegionManager dataRegionManager; public static final class DataRegionData implements io.papermc.paper.chunk.SingleThreadChunkRegionManager.RegionData { @@ -93,7 +93,7 @@ index bc315cc74cfded9f96e55f1d5de8a41334af8017..b556c1ef5d9f4667fa755ae843f4f507 } @Override -@@ -309,6 +375,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -308,6 +374,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider final DataRegionSectionData sectionData = (DataRegionSectionData)section.sectionData; final DataRegionData oldRegionData = oldRegion == null ? null : (DataRegionData)oldRegion.regionData; final DataRegionData newRegionData = (DataRegionData)newRegion.regionData; diff --git a/patches/server/0802-Use-updatingChunks-for-saving.patch b/patches/server/0802-Use-updatingChunks-for-saving.patch deleted file mode 100644 index a2f3e71bfe..0000000000 --- a/patches/server/0802-Use-updatingChunks-for-saving.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> -Date: Tue, 31 Aug 2021 17:12:01 -0700 -Subject: [PATCH] Use updatingChunks for saving - - -diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index d9f1601c49e7e7fc06a6f9bf0cb13aacd66f190c..730d569bd657049c8165d931ac62bf21c65a3b29 100644 ---- a/src/main/java/net/minecraft/server/level/ChunkMap.java -+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -950,9 +950,18 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - } - // Paper end - -+ // Paper start -+ public Long2ObjectLinkedOpenHashMap getVisibleChunks() { -+ synchronized (this.updatingChunks) { -+ return this.updatingChunks.getVisibleMap().clone(); -+ } -+ } -+ // Paper end -+ - protected void saveAllChunks(boolean flush) { -+ final Long2ObjectLinkedOpenHashMap visibleChunks = this.getVisibleChunks(); // Paper - if (flush) { -- List list = (List) this.visibleChunkMap.values().stream().filter(ChunkHolder::wasAccessibleSinceLastSave).peek(ChunkHolder::refreshAccessibility).collect(Collectors.toList()); -+ List list = visibleChunks.values().stream().filter(ChunkHolder::wasAccessibleSinceLastSave).peek(ChunkHolder::refreshAccessibility).collect(Collectors.toList()); // Paper - MutableBoolean mutableboolean = new MutableBoolean(); - - do { -@@ -983,7 +992,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - this.level.asyncChunkTaskManager.flush(); // Paper - flush to preserve behavior compat with pre-async behaviour - // this.i(); // Paper - nuke IOWorker - } else { -- this.visibleChunkMap.values().stream().filter(ChunkHolder::wasAccessibleSinceLastSave).forEach((playerchunk) -> { -+ visibleChunks.values().stream().filter(ChunkHolder::wasAccessibleSinceLastSave).forEach((playerchunk) -> { // Paper - ChunkAccess ichunkaccess = (ChunkAccess) playerchunk.getChunkToSave().getNow(null); // CraftBukkit - decompile error - - if (ichunkaccess instanceof ImposterProtoChunk || ichunkaccess instanceof LevelChunk) {