diff --git a/build-data/paper.at b/build-data/paper.at index cf8a486b80..5fcbdc2590 100644 --- a/build-data/paper.at +++ b/build-data/paper.at @@ -268,3 +268,6 @@ public net.minecraft.world.level.NaturalSpawner SPAWNING_CATEGORIES # Optimize isValidLocation public net.minecraft.world.level.chunk.LevelChunkSection states + +# Player.setPlayerProfile API +public-f net.minecraft.world.entity.player.Player gameProfile diff --git a/patches/server/API-to-get-a-BlockState-without-a-snapshot.patch b/patches/server/API-to-get-a-BlockState-without-a-snapshot.patch index 73d6e33ffa..35814c9512 100644 --- a/patches/server/API-to-get-a-BlockState-without-a-snapshot.patch +++ b/patches/server/API-to-get-a-BlockState-without-a-snapshot.patch @@ -113,13 +113,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java +++ b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java @@ -0,0 +0,0 @@ public final class CraftPersistentDataContainer implements PersistentDataContain - public Map serialize() { return (Map) CraftNBTTagConfigSerializer.serialize(this.toTagCompound()); } -+ + + // Paper start + public void clear() { + this.customDataTags.clear(); + } + // Paper end - } ++ + @FunctionalInterface + public interface Callback { + void onValueChange(); diff --git a/patches/server/Improve-Chunk-Status-Transition-Speed.patch b/patches/server/Improve-Chunk-Status-Transition-Speed.patch index 8606e368f0..e8fdb7f1c6 100644 --- a/patches/server/Improve-Chunk-Status-Transition-Speed.patch +++ b/patches/server/Improve-Chunk-Status-Transition-Speed.patch @@ -40,7 +40,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/level/ChunkHolder.java +++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java @@ -0,0 +0,0 @@ public class ChunkHolder { - // Paper end - optimise isOutsideOfRange + // Paper end - optimise anyPlayerCloseEnoughForSpawning long lastAutoSaveTime; // Paper - incremental autosave long inactiveTimeStart; // Paper - incremental autosave + // Paper start - optimize chunk status progression without jumping through thread pool diff --git a/patches/server/Load-chunk-PDC-if-present.patch b/patches/server/Load-chunk-PDC-if-present.patch deleted file mode 100644 index 19db397a5a..0000000000 --- a/patches/server/Load-chunk-PDC-if-present.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Sun, 28 Nov 2021 12:34:51 -0800 -Subject: [PATCH] Load chunk PDC if present - - -diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -@@ -0,0 +0,0 @@ public class ChunkSerializer { - private static LevelChunk.PostLoadProcessor postLoadChunk(ServerLevel world, CompoundTag nbt) { - ListTag nbttaglist = ChunkSerializer.getListOfCompoundsOrNull(nbt, "entities"); - ListTag nbttaglist1 = ChunkSerializer.getListOfCompoundsOrNull(nbt, "block_entities"); -+ boolean hasPdc = nbt.contains("ChunkBukkitValues", Tag.TAG_COMPOUND); // Paper - -- return nbttaglist == null && nbttaglist1 == null ? null : (chunk) -> { -+ return nbttaglist == null && nbttaglist1 == null && !hasPdc ? null : (chunk) -> { // Paper - if (nbttaglist != null) { - world.addLegacyChunkEntities(EntityType.loadEntitiesRecursive(nbttaglist, world)); - } diff --git a/patches/server/MC-Utils.patch b/patches/server/MC-Utils.patch index 3ffc4133f2..9029495944 100644 --- a/patches/server/MC-Utils.patch +++ b/patches/server/MC-Utils.patch @@ -6531,7 +6531,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 /** @deprecated */ @Nullable @@ -0,0 +0,0 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom - protected final LevelChunkSection[] sections; + // CraftBukkit end public ChunkAccess(ChunkPos pos, UpgradeData upgradeData, LevelHeightAccessor heightLimitView, Registry biome, long inhabitedTime, @Nullable LevelChunkSection[] sectionArrayInitializer, @Nullable BlendingData blendingData) { - this.chunkPos = pos; @@ -6553,7 +6553,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 import net.minecraft.util.profiling.ProfilerFiller; import net.minecraft.world.entity.Entity; @@ -0,0 +0,0 @@ public class LevelChunk extends ChunkAccess { - public final org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer persistentDataContainer = new org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer(LevelChunk.DATA_TYPE_REGISTRY); + // CraftBukkit end + // Paper start diff --git a/patches/server/Optimise-nearby-player-lookups.patch b/patches/server/Optimise-nearby-player-lookups.patch index 99332898a9..77fbca1bd3 100644 --- a/patches/server/Optimise-nearby-player-lookups.patch +++ b/patches/server/Optimise-nearby-player-lookups.patch @@ -23,7 +23,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end - optimise checkDespawn } - // Paper end - optimise isOutsideOfRange + // Paper end - optimise anyPlayerCloseEnoughForSpawning 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 @@ -46,7 +46,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); this.playerChunkTickRangeMap.add(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); - // Paper end - optimise PlayerChunkMap#isOutsideRange + // Paper end - optimise ChunkMap#anyPlayerCloseEnoughForSpawning + this.playerGeneralAreaMap.add(player, chunkX, chunkZ, GENERAL_AREA_MAP_SQUARE_RADIUS); // Paper - optimise checkDespawn } @@ -54,7 +54,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.playerMobSpawnMap.remove(player); this.playerChunkTickRangeMap.remove(player); - // Paper end - optimise PlayerChunkMap#isOutsideRange + // Paper end - optimise ChunkMap#anyPlayerCloseEnoughForSpawning + this.playerGeneralAreaMap.remove(player); // Paper - optimise checkDespawns } @@ -62,7 +62,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } // Paper end - use distance map to optimise entity tracker - this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise PlayerChunkMap#isOutsideRange + this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise ChunkMap#anyPlayerCloseEnoughForSpawning + this.playerGeneralAreaMap.update(player, chunkX, chunkZ, GENERAL_AREA_MAP_SQUARE_RADIUS); // Paper - optimise checkDespawn } // Paper end @@ -70,7 +70,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } }); - // Paper end - optimise PlayerChunkMap#isOutsideRange + // Paper end - optimise ChunkMap#anyPlayerCloseEnoughForSpawning + // Paper start - optimise checkDespawn + this.playerGeneralAreaMap = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets, + (ServerPlayer player, int rangeX, int rangeZ, int currPosX, int currPosZ, int prevPosX, int prevPosZ, diff --git a/patches/server/Optimize-anyPlayerCloseEnoughForSpawning-to-use-dist.patch b/patches/server/Optimize-anyPlayerCloseEnoughForSpawning-to-use-dist.patch index bcc1ae4ba0..72517c4ac8 100644 --- a/patches/server/Optimize-anyPlayerCloseEnoughForSpawning-to-use-dist.patch +++ b/patches/server/Optimize-anyPlayerCloseEnoughForSpawning-to-use-dist.patch @@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 boolean isUpdateQueued = false; // Paper private final ChunkMap chunkMap; // Paper -+ // Paper start - optimise isOutsideOfRange ++ // Paper start - optimise anyPlayerCloseEnoughForSpawning + // cached here to avoid a map lookup + com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet playersInMobSpawnRange; + com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet playersInChunkTickRange; @@ -23,7 +23,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.playersInMobSpawnRange = this.chunkMap.playerMobSpawnMap.getObjectsInRange(key); + this.playersInChunkTickRange = this.chunkMap.playerChunkTickRangeMap.getObjectsInRange(key); + } -+ // Paper end - optimise isOutsideOfRange ++ // Paper end - optimise anyPlayerCloseEnoughForSpawning + public ChunkHolder(ChunkPos pos, int level, LevelHeightAccessor world, LevelLightEngine lightingProvider, ChunkHolder.LevelChangeListener levelUpdateListener, ChunkHolder.PlayerProvider playersWatchingChunkProvider) { this.futures = new AtomicReferenceArray(ChunkHolder.CHUNK_STATUSES.size()); @@ -32,7 +32,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.setTicketLevel(level); this.changedBlocksPerSection = new ShortSet[world.getSectionsCount()]; this.chunkMap = (ChunkMap)playersWatchingChunkProvider; // Paper -+ this.updateRanges(); // Paper - optimise isOutsideOfRange ++ this.updateRanges(); // Paper - optimise anyPlayerCloseEnoughForSpawning } // CraftBukkit start @@ -44,7 +44,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 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<>(); -+ // Paper start - optimise PlayerChunkMap#isOutsideRange ++ // 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 + // mob spawn range. However, spigot makes the spawn range configurable by @@ -54,31 +54,31 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // these maps are named after spigot's uses + 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 ++ // Paper end - optimise ChunkMap#anyPlayerCloseEnoughForSpawning void addPlayerToDistanceMaps(ServerPlayer player) { 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 -+ // Paper start - optimise PlayerChunkMap#isOutsideRange ++ // Paper start - optimise ChunkMap#anyPlayerCloseEnoughForSpawning + this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); + this.playerChunkTickRangeMap.add(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); -+ // Paper end - optimise PlayerChunkMap#isOutsideRange ++ // Paper end - optimise ChunkMap#anyPlayerCloseEnoughForSpawning } void removePlayerFromDistanceMaps(ServerPlayer player) { - -+ // Paper start - optimise PlayerChunkMap#isOutsideRange ++ // Paper start - optimise ChunkMap#anyPlayerCloseEnoughForSpawning + this.playerMobSpawnMap.remove(player); + this.playerChunkTickRangeMap.remove(player); -+ // Paper end - optimise PlayerChunkMap#isOutsideRange ++ // Paper end - optimise ChunkMap#anyPlayerCloseEnoughForSpawning } void updateMaps(ServerPlayer player) { 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 -+ this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise PlayerChunkMap#isOutsideRange ++ this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise ChunkMap#anyPlayerCloseEnoughForSpawning } // Paper end // Paper start @@ -86,7 +86,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.regionManagers.add(this.dataRegionManager); // Paper end this.playerMobDistanceMap = this.level.paperConfig.perPlayerMobSpawns ? new com.destroystokyo.paper.util.PlayerMobDistanceMap() : null; // Paper -+ // Paper start - optimise PlayerChunkMap#isOutsideRange ++ // Paper start - optimise ChunkMap#anyPlayerCloseEnoughForSpawning + this.playerChunkTickRangeMap = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets, + (ServerPlayer player, int rangeX, int rangeZ, int currPosX, int currPosZ, int prevPosX, int prevPosZ, + com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet newState) -> { @@ -117,7 +117,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + playerChunk.playersInMobSpawnRange = newState; + } + }); -+ // Paper end - optimise PlayerChunkMap#isOutsideRange ++ // Paper end - optimise ChunkMap#anyPlayerCloseEnoughForSpawning } protected ChunkGenerator generator() { @@ -125,7 +125,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } else { if (holder != null) { holder.setTicketLevel(level); -+ holder.updateRanges(); // Paper - optimise isOutsideOfRange ++ holder.updateRanges(); // Paper - optimise anyPlayerCloseEnoughForSpawning } if (holder != null) { @@ -143,7 +143,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - double blockRange = 16384.0D; // Paper - // Spigot end - long i = chunkcoordintpair.toLong(); -+ // Paper start - optimise isOutsideOfRange ++ // Paper start - optimise anyPlayerCloseEnoughForSpawning + final boolean anyPlayerCloseEnoughForSpawning(ChunkPos chunkcoordintpair, boolean reducedRange) { + return this.anyPlayerCloseEnoughForSpawning(this.getUpdatingChunkIfPresent(chunkcoordintpair.toLong()), chunkcoordintpair, reducedRange); + } @@ -205,7 +205,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } + // no players in range + return false; -+ // Paper end - optimise isOutsideOfRange ++ // Paper end - optimise anyPlayerCloseEnoughForSpawning } public List getPlayersCloseForSpawning(ChunkPos pos) { @@ -306,7 +306,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + int chunkZ = net.minecraft.server.MCUtil.getChunkCoordinate(player.getZ()); + + playerChunkMap.playerMobSpawnMap.addOrUpdate(player, chunkX, chunkZ, range); -+ player.lastEntitySpawnRadiusSquared = (double)((range << 4) * (range << 4)); // used in isOutsideRange ++ player.lastEntitySpawnRadiusSquared = (double)((range << 4) * (range << 4)); // used in anyPlayerCloseEnoughForSpawning + player.playerNaturallySpawnedEvent = event; + } + // Paper end - optimize isOutisdeRange @@ -335,10 +335,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 ChunkPos chunkcoordintpair = chunk1.getPos(); - if (this.level.isPositionEntityTicking(chunkcoordintpair) && this.chunkMap.anyPlayerCloseEnoughForSpawning(chunkcoordintpair)) { -+ if (this.level.isPositionEntityTicking(chunkcoordintpair) && this.chunkMap.anyPlayerCloseEnoughForSpawning(chunkproviderserver_a.holder, chunkcoordintpair, false)) { // Paper - optimise isOutsideOfRange ++ if (this.level.isPositionEntityTicking(chunkcoordintpair) && this.chunkMap.anyPlayerCloseEnoughForSpawning(chunkproviderserver_a.holder, chunkcoordintpair, false)) { // Paper - optimise anyPlayerCloseEnoughForSpawning chunk1.incrementInhabitedTime(j); -- if (flag2 && (this.spawnEnemies || this.spawnFriendlies) && this.level.getWorldBorder().isWithinBounds(chunkcoordintpair) && !this.chunkMap.anyPlayerCloseEnoughForSpawning(chunkcoordintpair, true)) { // Spigot -+ if (flag2 && (this.spawnEnemies || this.spawnFriendlies) && this.level.getWorldBorder().isWithinBounds(chunkcoordintpair) && this.chunkMap.anyPlayerCloseEnoughForSpawning(chunkproviderserver_a.holder, chunkcoordintpair, true)) { // Spigot // Paper - optimise isOutsideOfRange +- if (flag2 && (this.spawnEnemies || this.spawnFriendlies) && this.level.getWorldBorder().isWithinBounds(chunkcoordintpair) && this.chunkMap.anyPlayerCloseEnoughForSpawning(chunkcoordintpair, true)) { // Spigot ++ if (flag2 && (this.spawnEnemies || this.spawnFriendlies) && this.level.getWorldBorder().isWithinBounds(chunkcoordintpair) && this.chunkMap.anyPlayerCloseEnoughForSpawning(chunkproviderserver_a.holder, chunkcoordintpair, true)) { // Spigot // Paper - optimise anyPlayerCloseEnoughForSpawning NaturalSpawner.spawnForChunk(this.level, chunk1, spawnercreature_d, this.spawnFriendlies, this.spawnEnemies, flag1); } diff --git a/patches/server/Option-to-remove-corrupt-tile-entities.patch b/patches/server/Option-to-remove-corrupt-tile-entities.patch index 5788fcc99d..40087731eb 100644 --- a/patches/server/Option-to-remove-corrupt-tile-entities.patch +++ b/patches/server/Option-to-remove-corrupt-tile-entities.patch @@ -29,8 +29,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - this.unsaved = true; + this.setUnsaved(true); this.needsDecoration = true; // CraftBukkit - } - + // CraftBukkit start + this.persistentDataContainer = protoChunk.persistentDataContainer; // SPIGOT-6814: copy PDC to account for 1.17 to 1.18 chunk upgrading. @@ -0,0 +0,0 @@ public class LevelChunk extends ChunkAccess { "Chunk coordinates: " + (this.chunkPos.x * 16) + "," + (this.chunkPos.z * 16)); e.printStackTrace(); diff --git a/patches/server/Player.setPlayerProfile-API.patch b/patches/server/Player.setPlayerProfile-API.patch index 3dd7b24c08..ad2c45f5f4 100644 --- a/patches/server/Player.setPlayerProfile-API.patch +++ b/patches/server/Player.setPlayerProfile-API.patch @@ -25,19 +25,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 playerName = gameProfile.getName(); uniqueId = gameProfile.getId(); // Paper end -diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/world/entity/player/Player.java -+++ b/src/main/java/net/minecraft/world/entity/player/Player.java -@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity { - protected int enchantmentSeed; - protected final float defaultFlySpeed = 0.02F; - private int lastLevelUpTime; -- private final GameProfile gameProfile; -+ public GameProfile gameProfile; // Paper - private->public - private boolean reducedDebugInfo; - private ItemStack lastItemInMainHand; - private final ItemCooldowns cooldowns; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -51,44 +38,44 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 import net.minecraft.world.level.saveddata.maps.MapDecoration; import net.minecraft.world.level.saveddata.maps.MapItemSavedData; @@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player { - this.hiddenPlayers.put(player.getUniqueId(), hidingPlugins); + this.hiddenEntities.put(entity.getUniqueId(), hidingPlugins); - // Remove this player from the hidden player's EntityTrackerEntry -- ChunkMap tracker = ((ServerLevel) entity.level).getChunkSource().chunkMap; + // Remove this entity from the hidden player's EntityTrackerEntry +- ChunkMap tracker = ((ServerLevel) this.getHandle().level).getChunkSource().chunkMap; + // Paper start - ServerPlayer other = ((CraftPlayer) player).getHandle(); -+ unregisterPlayer(other); + Entity other = ((CraftEntity) entity).getHandle(); ++ unregisterEntity(other); + } -+ private void unregisterPlayer(ServerPlayer other) { -+ ChunkMap tracker = ((ServerLevel) entity.level).getChunkSource().chunkMap; ++ private void unregisterEntity(Entity other) { + // Paper end ++ ChunkMap tracker = ((ServerLevel) this.getHandle().level).getChunkSource().chunkMap; ChunkMap.TrackedEntity entry = tracker.entityMap.get(other.getId()); if (entry != null) { entry.removePlayer(this.getHandle()); @@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } - this.hiddenPlayers.remove(player.getUniqueId()); + this.hiddenEntities.remove(entity.getUniqueId()); -- ChunkMap tracker = ((ServerLevel) entity.level).getChunkSource().chunkMap; +- ChunkMap tracker = ((ServerLevel) this.getHandle().level).getChunkSource().chunkMap; + // Paper start - ServerPlayer other = ((CraftPlayer) player).getHandle(); -+ registerPlayer(other); + Entity other = ((CraftEntity) entity).getHandle(); ++ registerEntity(other); + } -+ private void registerPlayer(ServerPlayer other) { -+ ChunkMap tracker = ((ServerLevel) entity.level).getChunkSource().chunkMap; ++ private void registerEntity(Entity other) { ++ ChunkMap tracker = ((ServerLevel) this.getHandle().level).getChunkSource().chunkMap; + // Paper end - this.getHandle().connection.send(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, other)); - + if (other instanceof ServerPlayer) { + ServerPlayer otherPlayer = (ServerPlayer) other; @@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player { entry.updatePlayer(this.getHandle()); } } + // Paper start + private void reregisterPlayer(ServerPlayer player) { -+ if (!hiddenPlayers.containsKey(player.getUUID())) { -+ unregisterPlayer(player); -+ registerPlayer(player); ++ if (!hiddenEntities.containsKey(player.getUUID())) { ++ unregisterEntity(player); ++ registerEntity(player); + } + } + public void setPlayerProfile(com.destroystokyo.paper.profile.PlayerProfile profile) { @@ -130,4 +117,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end public void removeDisconnectingPlayer(Player player) { - this.hiddenPlayers.remove(player.getUniqueId()); + this.hiddenEntities.remove(player.getUniqueId()); diff --git a/patches/server/Rewrite-the-light-engine.patch b/patches/server/Rewrite-the-light-engine.patch index 6d4b1123c3..cc6c4089c6 100644 --- a/patches/server/Rewrite-the-light-engine.patch +++ b/patches/server/Rewrite-the-light-engine.patch @@ -4801,9 +4801,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java @@ -0,0 +0,0 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom - protected final LevelHeightAccessor levelHeightAccessor; - protected final LevelChunkSection[] sections; - + private static final org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry(); + public org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer persistentDataContainer = new org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer(ChunkAccess.DATA_TYPE_REGISTRY); + // CraftBukkit end + // Paper start - rewrite light engine + private volatile ca.spottedleaf.starlight.common.light.SWMRNibbleArray[] blockNibbles; + @@ -4845,10 +4845,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.blockEmptinessMap = emptinessMap; + } + // Paper end - rewrite light engine -+ + public ChunkAccess(ChunkPos pos, UpgradeData upgradeData, LevelHeightAccessor heightLimitView, Registry biome, long inhabitedTime, @Nullable LevelChunkSection[] sectionArrayInitializer, @Nullable BlendingData blendingData) { this.locX = pos.x; this.locZ = pos.z; // Paper - reduce need for field lookups - this.chunkPos = pos; this.coordinateKey = ChunkPos.asLong(locX, locZ); // Paper - cache long key diff --git a/src/main/java/net/minecraft/world/level/chunk/EmptyLevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/EmptyLevelChunk.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/chunk/EmptyLevelChunk.java diff --git a/patches/server/Setup-Gradle-project.patch b/patches/server/Setup-Gradle-project.patch index 7802f1795e..309e0bcda0 100644 --- a/patches/server/Setup-Gradle-project.patch +++ b/patches/server/Setup-Gradle-project.patch @@ -640,7 +640,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - 3.1.2 - - -- process-classes +- test-compile - - check - diff --git a/patches/server/Timings-v2.patch b/patches/server/Timings-v2.patch index 99597f9da2..49175f7fed 100644 --- a/patches/server/Timings-v2.patch +++ b/patches/server/Timings-v2.patch @@ -1710,8 +1710,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } - world.timings.syncChunkLoadTileEntitiesTimer.stopTiming(); // Spigot - // CraftBukkit start - load chunk persistent data from nbt - net.minecraft.nbt.Tag persistentBase = nbt.get("ChunkBukkitValues"); + }; + } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java diff --git a/patches/server/Use-distance-map-to-optimise-entity-tracker.patch b/patches/server/Use-distance-map-to-optimise-entity-tracker.patch index 9d421a0094..79fae510ff 100644 --- a/patches/server/Use-distance-map-to-optimise-entity-tracker.patch +++ b/patches/server/Use-distance-map-to-optimise-entity-tracker.patch @@ -20,7 +20,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ 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 + // Paper end - optimise ChunkMap#anyPlayerCloseEnoughForSpawning + // Paper start - use distance map to optimise tracker + public static boolean isLegacyTrackingEntity(Entity entity) { + return entity.isLegacyTrackingEntity; @@ -51,7 +51,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end - use distance map to optimise entity tracker // Note: players need to be explicitly added to distance maps before they can be updated - // Paper start - optimise PlayerChunkMap#isOutsideRange + // Paper start - optimise ChunkMap#anyPlayerCloseEnoughForSpawning this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); @@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } @@ -62,7 +62,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.playerEntityTrackerTrackMaps[i].remove(player); + } + // Paper end - use distance map to optimise tracker - // Paper start - optimise PlayerChunkMap#isOutsideRange + // Paper start - optimise ChunkMap#anyPlayerCloseEnoughForSpawning this.playerMobSpawnMap.remove(player); this.playerChunkTickRangeMap.remove(player); @@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -77,7 +77,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + trackMap.update(player, chunkX, chunkZ, Math.min(trackRange, this.getEffectiveViewDistance())); + } + // Paper end - use distance map to optimise entity tracker - this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise PlayerChunkMap#isOutsideRange + this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise ChunkMap#anyPlayerCloseEnoughForSpawning } // Paper end @@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -123,7 +123,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.playerEntityTrackerTrackMaps[ordinal] = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets); + } + // Paper end - use distance map to optimise entity tracker - // Paper start - optimise PlayerChunkMap#isOutsideRange + // Paper start - optimise ChunkMap#anyPlayerCloseEnoughForSpawning this.playerChunkTickRangeMap = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets, (ServerPlayer player, int rangeX, int rangeZ, int currPosX, int currPosZ, int prevPosX, int prevPosZ, @@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider diff --git a/patches/server/incremental-chunk-and-player-saving.patch b/patches/server/incremental-chunk-and-player-saving.patch index 0083f5bab2..75bda2b8ed 100644 --- a/patches/server/incremental-chunk-and-player-saving.patch +++ b/patches/server/incremental-chunk-and-player-saving.patch @@ -104,7 +104,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class ChunkHolder { this.playersInChunkTickRange = this.chunkMap.playerChunkTickRangeMap.getObjectsInRange(key); } - // Paper end - optimise isOutsideOfRange + // Paper end - optimise anyPlayerCloseEnoughForSpawning + long lastAutoSaveTime; // Paper - incremental autosave + long inactiveTimeStart; // Paper - incremental autosave diff --git a/work/Bukkit b/work/Bukkit index c9b35cdb66..810cb078fd 160000 --- a/work/Bukkit +++ b/work/Bukkit @@ -1 +1 @@ -Subproject commit c9b35cdb66761dfbda6f0b860bdb3c2edfda8679 +Subproject commit 810cb078fd22fde8bf94b5a23ed3329f0b1f68db diff --git a/work/CraftBukkit b/work/CraftBukkit index c86a3f7a58..04f8e7e21f 160000 --- a/work/CraftBukkit +++ b/work/CraftBukkit @@ -1 +1 @@ -Subproject commit c86a3f7a5877acb5406147923ac48d91c2f6e7d4 +Subproject commit 04f8e7e21f574311f67a6b0dd3bff1597630fef1 diff --git a/work/Spigot b/work/Spigot index 7514aa374a..b11f318fd2 160000 --- a/work/Spigot +++ b/work/Spigot @@ -1 +1 @@ -Subproject commit 7514aa374a331a548a45673de71e557a96125eda +Subproject commit b11f318fd202a058333afbe406ebcce83037b562