From 7bd22b1835af2611c5ad597aef6470b1ece9b547 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Thu, 11 Jul 2024 09:23:56 -0700 Subject: [PATCH] Optimise entity tracker Patch is ported from Folia --- ... 0991-Moonrise-optimisation-patches.patch} | 744 ++++++++++++++++-- ...993-disable-forced-empty-world-ticks.patch | 4 +- ...item-frames-performance-and-bug-fixe.patch | 4 +- .../1000-Entity-Activation-Range-2.0.patch | 18 +- patches/server/1002-Anti-Xray.patch | 6 +- ...nate-Current-redstone-implementation.patch | 4 +- .../1018-API-for-checking-sent-chunks.patch | 4 +- .../1023-Properly-resend-entities.patch | 6 +- .../1024-Optimise-random-block-ticking.patch | 14 +- ...er-desync-when-new-players-are-added.patch | 4 +- 10 files changed, 724 insertions(+), 84 deletions(-) rename patches/server/{0991-Chunk-System-Starlight-from-Moonrise.patch => 0991-Moonrise-optimisation-patches.patch} (97%) diff --git a/patches/server/0991-Chunk-System-Starlight-from-Moonrise.patch b/patches/server/0991-Moonrise-optimisation-patches.patch similarity index 97% rename from patches/server/0991-Chunk-System-Starlight-from-Moonrise.patch rename to patches/server/0991-Moonrise-optimisation-patches.patch index 06bbfbfbce..de0997769f 100644 --- a/patches/server/0991-Chunk-System-Starlight-from-Moonrise.patch +++ b/patches/server/0991-Moonrise-optimisation-patches.patch @@ -1,7 +1,11 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Fri, 14 Jun 2024 11:57:26 -0700 -Subject: [PATCH] Chunk System + Starlight from Moonrise +Subject: [PATCH] Moonrise optimisation patches + +Currently includes: + - Starlight + Chunk System + - Entity tracker optimisations See https://github.com/Tuinity/Moonrise @@ -2399,6 +2403,221 @@ index 0000000000000000000000000000000000000000..ab2fa1563d5e32a5313dfcc1da411cab + } + } +} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java +new file mode 100644 +index 0000000000000000000000000000000000000000..fdde1f5f988d581db41945916635cdd826a10680 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java +@@ -0,0 +1,209 @@ ++package ca.spottedleaf.moonrise.common.misc; ++ ++import ca.spottedleaf.moonrise.common.list.ReferenceList; ++import ca.spottedleaf.moonrise.common.util.CoordinateUtils; ++import ca.spottedleaf.moonrise.common.util.MoonriseConstants; ++import ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystem; ++import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap; ++import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; ++import net.minecraft.core.BlockPos; ++import net.minecraft.server.level.ServerLevel; ++import net.minecraft.server.level.ServerPlayer; ++import net.minecraft.world.level.ChunkPos; ++ ++public final class NearbyPlayers { ++ ++ public static enum NearbyMapType { ++ GENERAL, ++ GENERAL_SMALL, ++ GENERAL_REALLY_SMALL, ++ TICK_VIEW_DISTANCE, ++ VIEW_DISTANCE, ++ SPAWN_RANGE, ++ } ++ ++ private static final NearbyMapType[] MAP_TYPES = NearbyMapType.values(); ++ public static final int TOTAL_MAP_TYPES = MAP_TYPES.length; ++ ++ private static final int GENERAL_AREA_VIEW_DISTANCE = MoonriseConstants.MAX_VIEW_DISTANCE + 1; ++ private static final int GENERAL_SMALL_VIEW_DISTANCE = 10; ++ private static final int GENERAL_REALLY_SMALL_VIEW_DISTANCE = 3; ++ ++ public static final int GENERAL_AREA_VIEW_DISTANCE_BLOCKS = (GENERAL_AREA_VIEW_DISTANCE << 4); ++ public static final int GENERAL_SMALL_AREA_VIEW_DISTANCE_BLOCKS = (GENERAL_SMALL_VIEW_DISTANCE << 4); ++ public static final int GENERAL_REALLY_SMALL_AREA_VIEW_DISTANCE_BLOCKS = (GENERAL_REALLY_SMALL_VIEW_DISTANCE << 4); ++ ++ private final ServerLevel world; ++ private final Reference2ReferenceOpenHashMap players = new Reference2ReferenceOpenHashMap<>(); ++ private final Long2ReferenceOpenHashMap byChunk = new Long2ReferenceOpenHashMap<>(); ++ ++ public NearbyPlayers(final ServerLevel world) { ++ this.world = world; ++ } ++ ++ public void addPlayer(final ServerPlayer player) { ++ final TrackedPlayer[] newTrackers = new TrackedPlayer[TOTAL_MAP_TYPES]; ++ if (this.players.putIfAbsent(player, newTrackers) != null) { ++ throw new IllegalStateException("Already have player " + player); ++ } ++ ++ final ChunkPos chunk = player.chunkPosition(); ++ ++ for (int i = 0; i < TOTAL_MAP_TYPES; ++i) { ++ // use 0 for default, will be updated by tickPlayer ++ (newTrackers[i] = new TrackedPlayer(player, MAP_TYPES[i])).add(chunk.x, chunk.z, 0); ++ } ++ ++ // update view distances ++ this.tickPlayer(player); ++ } ++ ++ public void removePlayer(final ServerPlayer player) { ++ final TrackedPlayer[] players = this.players.remove(player); ++ if (players == null) { ++ return; // May be called during teleportation before the player is actually placed ++ } ++ ++ for (final TrackedPlayer tracker : players) { ++ tracker.remove(); ++ } ++ } ++ ++ public void tickPlayer(final ServerPlayer player) { ++ final TrackedPlayer[] players = this.players.get(player); ++ if (players == null) { ++ throw new IllegalStateException("Don't have player " + player); ++ } ++ ++ final ChunkPos chunk = player.chunkPosition(); ++ ++ players[NearbyMapType.GENERAL.ordinal()].update(chunk.x, chunk.z, GENERAL_AREA_VIEW_DISTANCE); ++ players[NearbyMapType.GENERAL_SMALL.ordinal()].update(chunk.x, chunk.z, GENERAL_SMALL_VIEW_DISTANCE); ++ players[NearbyMapType.GENERAL_REALLY_SMALL.ordinal()].update(chunk.x, chunk.z, GENERAL_REALLY_SMALL_VIEW_DISTANCE); ++ players[NearbyMapType.TICK_VIEW_DISTANCE.ordinal()].update(chunk.x, chunk.z, ChunkSystem.getTickViewDistance(player)); ++ players[NearbyMapType.VIEW_DISTANCE.ordinal()].update(chunk.x, chunk.z, ChunkSystem.getLoadViewDistance(player)); ++ } ++ ++ public TrackedChunk getChunk(final ChunkPos pos) { ++ return this.byChunk.get(CoordinateUtils.getChunkKey(pos)); ++ } ++ ++ public TrackedChunk getChunk(final BlockPos pos) { ++ return this.byChunk.get(CoordinateUtils.getChunkKey(pos)); ++ } ++ ++ public ReferenceList getPlayers(final BlockPos pos, final NearbyMapType type) { ++ final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(pos)); ++ ++ return chunk == null ? null : chunk.players[type.ordinal()]; ++ } ++ ++ public ReferenceList getPlayers(final ChunkPos pos, final NearbyMapType type) { ++ final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(pos)); ++ ++ return chunk == null ? null : chunk.players[type.ordinal()]; ++ } ++ ++ public ReferenceList getPlayersByChunk(final int chunkX, final int chunkZ, final NearbyMapType type) { ++ final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); ++ ++ return chunk == null ? null : chunk.players[type.ordinal()]; ++ } ++ ++ public ReferenceList getPlayersByBlock(final int blockX, final int blockZ, final NearbyMapType type) { ++ final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(blockX >> 4, blockZ >> 4)); ++ ++ return chunk == null ? null : chunk.players[type.ordinal()]; ++ } ++ ++ public static final class TrackedChunk { ++ ++ private static final ServerPlayer[] EMPTY_PLAYERS_ARRAY = new ServerPlayer[0]; ++ ++ private final ReferenceList[] players = new ReferenceList[TOTAL_MAP_TYPES]; ++ private int nonEmptyLists; ++ private long updateCount; ++ ++ public boolean isEmpty() { ++ return this.nonEmptyLists == 0; ++ } ++ ++ public long getUpdateCount() { ++ return this.updateCount; ++ } ++ ++ public ReferenceList getPlayers(final NearbyMapType type) { ++ return this.players[type.ordinal()]; ++ } ++ ++ public void addPlayer(final ServerPlayer player, final NearbyMapType type) { ++ ++this.updateCount; ++ ++ final int idx = type.ordinal(); ++ final ReferenceList list = this.players[idx]; ++ if (list == null) { ++ ++this.nonEmptyLists; ++ (this.players[idx] = new ReferenceList<>(EMPTY_PLAYERS_ARRAY, 0)).add(player); ++ return; ++ } ++ ++ if (!list.add(player)) { ++ throw new IllegalStateException("Already contains player " + player); ++ } ++ } ++ ++ public void removePlayer(final ServerPlayer player, final NearbyMapType type) { ++ ++this.updateCount; ++ ++ final int idx = type.ordinal(); ++ final ReferenceList list = this.players[idx]; ++ if (list == null) { ++ throw new IllegalStateException("Does not contain player " + player); ++ } ++ ++ if (!list.remove(player)) { ++ throw new IllegalStateException("Does not contain player " + player); ++ } ++ ++ if (list.size() == 0) { ++ this.players[idx] = null; ++ --this.nonEmptyLists; ++ } ++ } ++ } ++ ++ private final class TrackedPlayer extends SingleUserAreaMap { ++ ++ private final NearbyMapType type; ++ ++ public TrackedPlayer(final ServerPlayer player, final NearbyMapType type) { ++ super(player); ++ this.type = type; ++ } ++ ++ @Override ++ protected void addCallback(final ServerPlayer parameter, final int chunkX, final int chunkZ) { ++ final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); ++ ++ NearbyPlayers.this.byChunk.computeIfAbsent(chunkKey, (final long keyInMap) -> { ++ return new TrackedChunk(); ++ }).addPlayer(parameter, this.type); ++ } ++ ++ @Override ++ protected void removeCallback(final ServerPlayer parameter, final int chunkX, final int chunkZ) { ++ final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); ++ ++ final TrackedChunk chunk = NearbyPlayers.this.byChunk.get(chunkKey); ++ if (chunk == null) { ++ throw new IllegalStateException("Chunk should exist at " + new ChunkPos(chunkKey)); ++ } ++ ++ chunk.removePlayer(parameter, this.type); ++ ++ if (chunk.isEmpty()) { ++ NearbyPlayers.this.byChunk.remove(chunkKey); ++ } ++ } ++ } ++} diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/SingleUserAreaMap.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/SingleUserAreaMap.java new file mode 100644 index 0000000000000000000000000000000000000000..61f70247486fd15ed3ffc5b606582dc6a2dd81d3 @@ -4932,13 +5151,14 @@ index 0000000000000000000000000000000000000000..0b58701342d573fa43cdd06681534854 +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemServerLevel.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemServerLevel.java new file mode 100644 -index 0000000000000000000000000000000000000000..6828a3ca7151692a41b5370f680f867958a214fc +index 0000000000000000000000000000000000000000..1a06c2c139e930d2081e605b460ae5403de8c3ea --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemServerLevel.java -@@ -0,0 +1,50 @@ +@@ -0,0 +1,53 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.level; + +import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; ++import ca.spottedleaf.moonrise.common.misc.NearbyPlayers; +import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; +import ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; @@ -4985,6 +5205,8 @@ index 0000000000000000000000000000000000000000..6828a3ca7151692a41b5370f680f8679 + public long moonrise$getLastMidTickFailure(); + + public void moonrise$setLastMidTickFailure(final long time); ++ ++ public NearbyPlayers moonrise$getNearbyPlayers(); +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkSystemChunkHolder.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkSystemChunkHolder.java new file mode 100644 @@ -5905,10 +6127,10 @@ index 0000000000000000000000000000000000000000..997b05167c19472acb98edac32d4548c +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java new file mode 100644 -index 0000000000000000000000000000000000000000..f6a3eb3d1bb070bcc74133818682571d520d9894 +index 0000000000000000000000000000000000000000..a346435abac725b4e024acf4a1589a51caac8d69 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java -@@ -0,0 +1,1044 @@ +@@ -0,0 +1,1077 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.level.entity; + +import ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable; @@ -5984,6 +6206,24 @@ index 0000000000000000000000000000000000000000..f6a3eb3d1bb070bcc74133818682571d + + protected abstract void onEmptySlices(final int chunkX, final int chunkZ); + ++ protected abstract void entitySectionChangeCallback( ++ final Entity entity, ++ final int oldSectionX, final int oldSectionY, final int oldSectionZ, ++ final int newSectionX, final int newSectionY, final int newSectionZ ++ ); ++ ++ protected abstract void addEntityCallback(final Entity entity); ++ ++ protected abstract void removeEntityCallback(final Entity entity); ++ ++ protected abstract void entityStartLoaded(final Entity entity); ++ ++ protected abstract void entityEndLoaded(final Entity entity); ++ ++ protected abstract void entityStartTicking(final Entity entity); ++ ++ protected abstract void entityEndTicking(final Entity entity); ++ + private static Entity maskNonAccessible(final Entity entity) { + if (entity == null) { + return null; @@ -6162,6 +6402,7 @@ index 0000000000000000000000000000000000000000..f6a3eb3d1bb070bcc74133818682571d + if (newVisibility.ordinal() > oldVisibility.ordinal()) { + // status upgrade + if (!oldVisibility.isAccessible() && newVisibility.isAccessible()) { ++ EntityLookup.this.entityStartLoaded(entity); + synchronized (this.accessibleEntities) { + this.accessibleEntities.add(entity); + } @@ -6171,6 +6412,7 @@ index 0000000000000000000000000000000000000000..f6a3eb3d1bb070bcc74133818682571d + } + + if (!oldVisibility.isTicking() && newVisibility.isTicking()) { ++ EntityLookup.this.entityStartTicking(entity); + if (EntityLookup.this.worldCallback != null) { + EntityLookup.this.worldCallback.onTickingStart(entity); + } @@ -6178,12 +6420,14 @@ index 0000000000000000000000000000000000000000..f6a3eb3d1bb070bcc74133818682571d + } else { + // status downgrade + if (oldVisibility.isTicking() && !newVisibility.isTicking()) { ++ EntityLookup.this.entityEndTicking(entity); + if (EntityLookup.this.worldCallback != null) { + EntityLookup.this.worldCallback.onTickingEnd(entity); + } + } + + if (oldVisibility.isAccessible() && !newVisibility.isAccessible()) { ++ EntityLookup.this.entityEndLoaded(entity); + synchronized (this.accessibleEntities) { + this.accessibleEntities.remove(entity); + } @@ -6325,6 +6569,8 @@ index 0000000000000000000000000000000000000000..f6a3eb3d1bb070bcc74133818682571d + + entity.setLevelCallback(new EntityCallback(entity)); + ++ this.addEntityCallback(entity); ++ + this.entityStatusChange(entity, slices, Visibility.HIDDEN, getEntityStatus(entity), false, !fromDisk, false); + + return true; @@ -6432,6 +6678,12 @@ index 0000000000000000000000000000000000000000..f6a3eb3d1bb070bcc74133818682571d + this.onEmptySlices(sectionX, sectionZ); + } + ++ this.entitySectionChangeCallback( ++ entity, ++ sectionX, sectionY, sectionZ, ++ newSectionX, newSectionY, newSectionZ ++ ); ++ + return slices; + } + @@ -6923,6 +7175,7 @@ index 0000000000000000000000000000000000000000..f6a3eb3d1bb070bcc74133818682571d + // no new section, so didn't change sections + return; + } ++ + final Visibility newVisibility = getEntityStatus(entity); + + EntityLookup.this.entityStatusChange(entity, newSlices, oldVisibility, newVisibility, true, false, false); @@ -6938,6 +7191,8 @@ index 0000000000000000000000000000000000000000..f6a3eb3d1bb070bcc74133818682571d + + EntityLookup.this.entityStatusChange(entity, null, tickingState, Visibility.HIDDEN, false, false, reason.shouldDestroy()); + ++ EntityLookup.this.removeEntityCallback(entity); ++ + this.entity.setLevelCallback(NoOpCallback.INSTANCE); + } + } @@ -6956,10 +7211,10 @@ index 0000000000000000000000000000000000000000..f6a3eb3d1bb070bcc74133818682571d \ No newline at end of file diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/client/ClientEntityLookup.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/client/ClientEntityLookup.java new file mode 100644 -index 0000000000000000000000000000000000000000..fc4ea13aa4a21bd3d3f9377418a24b904868c401 +index 0000000000000000000000000000000000000000..77e81414d43826955da8af85ec1bd0009af4e1b9 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/client/ClientEntityLookup.java -@@ -0,0 +1,81 @@ +@@ -0,0 +1,118 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.level.entity.client; + +import ca.spottedleaf.moonrise.common.util.CoordinateUtils; @@ -7021,6 +7276,43 @@ index 0000000000000000000000000000000000000000..fc4ea13aa4a21bd3d3f9377418a24b90 + this.removeChunk(chunkX, chunkZ); + } + ++ @Override ++ protected void entitySectionChangeCallback(final Entity entity, ++ final int oldSectionX, final int oldSectionY, final int oldSectionZ, ++ final int newSectionX, final int newSectionY, final int newSectionZ) { ++ ++ } ++ ++ @Override ++ protected void addEntityCallback(final Entity entity) { ++ ++ } ++ ++ @Override ++ protected void removeEntityCallback(final Entity entity) { ++ ++ } ++ ++ @Override ++ protected void entityStartLoaded(final Entity entity) { ++ ++ } ++ ++ @Override ++ protected void entityEndLoaded(final Entity entity) { ++ ++ } ++ ++ @Override ++ protected void entityStartTicking(final Entity entity) { ++ ++ } ++ ++ @Override ++ protected void entityEndTicking(final Entity entity) { ++ ++ } ++ + public void markTicking(final long pos) { + if (this.tickingChunks.add(pos)) { + final int chunkX = CoordinateUtils.getChunkX(pos); @@ -7043,10 +7335,10 @@ index 0000000000000000000000000000000000000000..fc4ea13aa4a21bd3d3f9377418a24b90 +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/dfl/DefaultEntityLookup.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/dfl/DefaultEntityLookup.java new file mode 100644 -index 0000000000000000000000000000000000000000..a9b0e8e90f433e141f36e47a9331cbdcb9ac9817 +index 0000000000000000000000000000000000000000..4747499e84b05d499364622b0f750fdd66b737e0 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/dfl/DefaultEntityLookup.java -@@ -0,0 +1,72 @@ +@@ -0,0 +1,109 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.level.entity.dfl; + +import ca.spottedleaf.moonrise.common.util.CoordinateUtils; @@ -7095,6 +7387,43 @@ index 0000000000000000000000000000000000000000..a9b0e8e90f433e141f36e47a9331cbdc + this.removeChunk(chunkX, chunkZ); + } + ++ @Override ++ protected void entitySectionChangeCallback(final Entity entity, ++ final int oldSectionX, final int oldSectionY, final int oldSectionZ, ++ final int newSectionX, final int newSectionY, final int newSectionZ) { ++ ++ } ++ ++ @Override ++ protected void addEntityCallback(final Entity entity) { ++ ++ } ++ ++ @Override ++ protected void removeEntityCallback(final Entity entity) { ++ ++ } ++ ++ @Override ++ protected void entityStartLoaded(final Entity entity) { ++ ++ } ++ ++ @Override ++ protected void entityEndLoaded(final Entity entity) { ++ ++ } ++ ++ @Override ++ protected void entityStartTicking(final Entity entity) { ++ ++ } ++ ++ @Override ++ protected void entityEndTicking(final Entity entity) { ++ ++ } ++ + protected static final class DefaultLevelCallback implements LevelCallback { + + @Override @@ -7121,22 +7450,28 @@ index 0000000000000000000000000000000000000000..a9b0e8e90f433e141f36e47a9331cbdc +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/server/ServerEntityLookup.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/server/ServerEntityLookup.java new file mode 100644 -index 0000000000000000000000000000000000000000..5b68279cae5952bdb7bdef3668980385a3a643e0 +index 0000000000000000000000000000000000000000..eb1b0b3594ae6861a05010949ba94a60f73ecc8b --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/server/ServerEntityLookup.java -@@ -0,0 +1,50 @@ +@@ -0,0 +1,106 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server; + ++import ca.spottedleaf.moonrise.common.list.ReferenceList; +import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; +import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices; +import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.EntityLookup; +import net.minecraft.server.level.ServerLevel; ++import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.entity.LevelCallback; + +public final class ServerEntityLookup extends EntityLookup { + ++ private static final Entity[] EMPTY_ENTITY_ARRAY = new Entity[0]; ++ + private final ServerLevel serverWorld; ++ public final ReferenceList trackerEntities = new ReferenceList<>(EMPTY_ENTITY_ARRAY, 0); // Moonrise - entity tracker ++ public final ReferenceList trackerUnloadedEntities = new ReferenceList<>(EMPTY_ENTITY_ARRAY, 0); // Moonrise - entity tracker + + public ServerEntityLookup(final ServerLevel world, final LevelCallback worldCallback) { + super(world, worldCallback); @@ -7174,6 +7509,56 @@ index 0000000000000000000000000000000000000000..5b68279cae5952bdb7bdef3668980385 + protected void onEmptySlices(final int chunkX, final int chunkZ) { + // entity slices unloading is managed by ticket levels in chunk system + } ++ ++ @Override ++ protected void entitySectionChangeCallback(final Entity entity, ++ final int oldSectionX, final int oldSectionY, final int oldSectionZ, ++ final int newSectionX, final int newSectionY, final int newSectionZ) { ++ if (entity instanceof ServerPlayer player) { ++ ((ChunkSystemServerLevel)this.serverWorld).moonrise$getNearbyPlayers().tickPlayer(player); ++ } ++ } ++ ++ @Override ++ protected void addEntityCallback(final Entity entity) { ++ if (entity instanceof ServerPlayer player) { ++ ((ChunkSystemServerLevel)this.serverWorld).moonrise$getNearbyPlayers().addPlayer(player); ++ } ++ } ++ ++ @Override ++ protected void removeEntityCallback(final Entity entity) { ++ if (entity instanceof ServerPlayer player) { ++ ((ChunkSystemServerLevel)this.serverWorld).moonrise$getNearbyPlayers().removePlayer(player); ++ } ++ this.trackerUnloadedEntities.remove(entity); // Moonrise - entity tracker ++ } ++ ++ @Override ++ protected void entityStartLoaded(final Entity entity) { ++ // Moonrise start - entity tracker ++ this.trackerEntities.add(entity); ++ this.trackerUnloadedEntities.remove(entity); ++ // Moonrise end - entity tracker ++ } ++ ++ @Override ++ protected void entityEndLoaded(final Entity entity) { ++ // Moonrise start - entity tracker ++ this.trackerEntities.remove(entity); ++ this.trackerUnloadedEntities.add(entity); ++ // Moonrise end - entity tracker ++ } ++ ++ @Override ++ protected void entityStartTicking(final Entity entity) { ++ ++ } ++ ++ @Override ++ protected void entityEndTicking(final Entity entity) { ++ ++ } +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/ChunkSystemPoiManager.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/ChunkSystemPoiManager.java new file mode 100644 @@ -7483,10 +7868,10 @@ index 0000000000000000000000000000000000000000..003a857e70ead858e8437e3c1bfaf22f +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java new file mode 100644 -index 0000000000000000000000000000000000000000..82e8ce73b77accd6a4210f88c9fccb325ae367d4 +index 0000000000000000000000000000000000000000..f063ab3ff122b920bcc4aa4f5bf9a442a8eb32fd --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java -@@ -0,0 +1,1074 @@ +@@ -0,0 +1,1076 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.player; + +import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; @@ -7688,6 +8073,8 @@ index 0000000000000000000000000000000000000000..82e8ce73b77accd6a4210f88c9fccb32 + final PlayerChunkLoaderData loader = ((ChunkSystemServerPlayer)player).moonrise$getChunkLoader(); + if (loader != null) { + loader.update(); ++ // update view distances for nearby players ++ ((ChunkSystemServerLevel)loader.world).moonrise$getNearbyPlayers().tickPlayer(player); + } + } + @@ -17879,6 +18266,42 @@ index 0000000000000000000000000000000000000000..4b9e2fa963c14f65f15407c1814c543c + public LevelChunk moonrise$getFullChunkIfLoaded(final int chunkX, final int chunkZ); + +} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/entity_tracker/EntityTrackerEntity.java b/src/main/java/ca/spottedleaf/moonrise/patches/entity_tracker/EntityTrackerEntity.java +new file mode 100644 +index 0000000000000000000000000000000000000000..5f5734c00ce8245a1ff69b2d4c3036579d5392e0 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/entity_tracker/EntityTrackerEntity.java +@@ -0,0 +1,11 @@ ++package ca.spottedleaf.moonrise.patches.entity_tracker; ++ ++import net.minecraft.server.level.ChunkMap; ++ ++public interface EntityTrackerEntity { ++ ++ public ChunkMap.TrackedEntity moonrise$getTrackedEntity(); ++ ++ public void moonrise$setTrackedEntity(final ChunkMap.TrackedEntity trackedEntity); ++ ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/entity_tracker/EntityTrackerTrackedEntity.java b/src/main/java/ca/spottedleaf/moonrise/patches/entity_tracker/EntityTrackerTrackedEntity.java +new file mode 100644 +index 0000000000000000000000000000000000000000..1fa07bef57d82c6d5242aaaf66011f0913515231 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/entity_tracker/EntityTrackerTrackedEntity.java +@@ -0,0 +1,13 @@ ++package ca.spottedleaf.moonrise.patches.entity_tracker; ++ ++import ca.spottedleaf.moonrise.common.misc.NearbyPlayers; ++ ++public interface EntityTrackerTrackedEntity { ++ ++ public void moonrise$tick(final NearbyPlayers.TrackedChunk chunk); ++ ++ public void moonrise$removeNonTickThreadPlayers(); ++ ++ public void moonrise$clearPlayers(); ++ ++} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/blockstate/StarlightAbstractBlockState.java b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/blockstate/StarlightAbstractBlockState.java new file mode 100644 index 0000000000000000000000000000000000000000..2bfdf3721db9a45e36538d71cbefcb1d339e6c58 @@ -23805,7 +24228,7 @@ index d9ad32acdf46a43a649334a3b736aeb7b3af21d1..fae17a075d7efaf24d916877dd5968eb public static final int RADIUS_AROUND_FULL_CHUNK = FULL_CHUNK_STEP.accumulatedDependencies().getRadius(); public static final int MAX_LEVEL = 33 + RADIUS_AROUND_FULL_CHUNK; diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index a03385b1b0a2f9b98319137b87d917856d3c632c..1363dda031d1b541d76241812a957a12521cbc05 100644 +index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed18617193568f0d 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -122,10 +122,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -24538,8 +24961,8 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..1363dda031d1b541d76241812a957a12 private static void dropChunk(ServerPlayer player, ChunkPos pos) { - player.connection.chunkSender.dropChunk(player, pos); + // Paper - rewrite chunk system -+ } -+ + } + + // Paper start - rewrite chunk system + @Override + public CompletableFuture> read(final ChunkPos pos) { @@ -24558,8 +24981,8 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..1363dda031d1b541d76241812a957a12 + } + } + return super.read(pos); - } - ++ } ++ + @Override + public CompletableFuture write(final ChunkPos pos, final CompoundTag tag) { + if (!ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.isRegionFileThread()) { @@ -24608,7 +25031,26 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..1363dda031d1b541d76241812a957a12 } } -@@ -1212,71 +822,31 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1176,17 +786,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + } + + public void move(ServerPlayer player) { +- ObjectIterator objectiterator = this.entityMap.values().iterator(); +- +- while (objectiterator.hasNext()) { +- ChunkMap.TrackedEntity playerchunkmap_entitytracker = (ChunkMap.TrackedEntity) objectiterator.next(); +- +- if (playerchunkmap_entitytracker.entity == player) { +- playerchunkmap_entitytracker.updatePlayers(this.level.players()); +- } else { +- playerchunkmap_entitytracker.updatePlayer(player); +- } +- } ++ // Paper - optimise entity tracker + + SectionPos sectionposition = player.getLastSectionPos(); + SectionPos sectionposition1 = SectionPos.of((EntityAccess) player); +@@ -1212,71 +812,31 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.playerMap.unIgnorePlayer(player); } @@ -24691,22 +25133,75 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..1363dda031d1b541d76241812a957a12 } public void addEntity(Entity entity) { -@@ -1347,13 +917,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1304,6 +864,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + + entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker + this.entityMap.put(entity.getId(), playerchunkmap_entitytracker); ++ // Paper start - optimise entity tracker ++ if (((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity)entity).moonrise$getTrackedEntity() != null) { ++ throw new IllegalStateException("Entity is already tracked"); ++ } ++ ((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity)entity).moonrise$setTrackedEntity(playerchunkmap_entitytracker); ++ // Paper end - optimise entity tracker + playerchunkmap_entitytracker.updatePlayers(this.level.players()); + if (entity instanceof ServerPlayer) { + ServerPlayer entityplayer = (ServerPlayer) entity; +@@ -1344,16 +910,49 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + playerchunkmap_entitytracker1.broadcastRemoved(); + } + entity.tracker = null; // Paper - We're no longer tracked ++ ((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity)entity).moonrise$setTrackedEntity(null); // Paper - optimise entity tracker } - protected void tick() { +- protected void tick() { - Iterator iterator = this.playerMap.getAllPlayers().iterator(); -- ++ // Paper start - optimise entity tracker ++ private void newTrackerTick() { ++ final ca.spottedleaf.moonrise.common.misc.NearbyPlayers nearbyPlayers = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getNearbyPlayers(); ++ final ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server.ServerEntityLookup entityLookup = (ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server.ServerEntityLookup)((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getEntityLookup();; + - while (iterator.hasNext()) { - ServerPlayer entityplayer = (ServerPlayer) iterator.next(); -- ++ final ca.spottedleaf.moonrise.common.list.ReferenceList trackerEntities = entityLookup.trackerEntities; ++ final Entity[] trackerEntitiesRaw = trackerEntities.getRawDataUnchecked(); ++ for (int i = 0, len = trackerEntities.size(); i < len; ++i) { ++ final Entity entity = trackerEntitiesRaw[i]; ++ final ChunkMap.TrackedEntity tracker = ((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity)entity).moonrise$getTrackedEntity(); ++ if (tracker == null) { ++ continue; ++ } ++ ((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerTrackedEntity)tracker).moonrise$tick(nearbyPlayers.getChunk(entity.chunkPosition())); ++ tracker.serverEntity.sendChanges(); ++ } ++ ++ // process unloads ++ final ca.spottedleaf.moonrise.common.list.ReferenceList unloadedEntities = entityLookup.trackerUnloadedEntities; ++ final Entity[] unloadedEntitiesRaw = java.util.Arrays.copyOf(unloadedEntities.getRawDataUnchecked(), unloadedEntities.size()); ++ unloadedEntities.clear(); + - this.updateChunkTracking(entityplayer); -- } ++ for (final Entity entity : unloadedEntitiesRaw) { ++ final ChunkMap.TrackedEntity tracker = ((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity)entity).moonrise$getTrackedEntity(); ++ if (tracker == null) { ++ continue; ++ } ++ ((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerTrackedEntity)tracker).moonrise$clearPlayers(); ++ } ++ } ++ // Paper end - optimise entity tracker ++ ++ protected void tick() { ++ // Paper start - optimise entity tracker ++ if (true) { ++ this.newTrackerTick(); ++ return; + } ++ // Paper end - optimise entity tracker + // Paper - rewrite chunk system List list = Lists.newArrayList(); List list1 = this.level.players(); -@@ -1460,27 +1024,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1460,27 +1059,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public void waitForLightBeforeSending(ChunkPos centerPos, int radius) { @@ -24744,6 +25239,100 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..1363dda031d1b541d76241812a957a12 } @Nullable +@@ -1496,7 +1093,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + } + } + +- public class TrackedEntity { ++ public class TrackedEntity implements ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerTrackedEntity { // Paper - optimise entity tracker + + public final ServerEntity serverEntity; + final Entity entity; +@@ -1504,6 +1101,84 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + SectionPos lastSectionPos; + public final Set seenBy = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); // Paper - Perf: optimise map impl + ++ // Paper start - optimise entity tracker ++ private long lastChunkUpdate = -1L; ++ private ca.spottedleaf.moonrise.common.misc.NearbyPlayers.TrackedChunk lastTrackedChunk; ++ ++ @Override ++ public final void moonrise$tick(final ca.spottedleaf.moonrise.common.misc.NearbyPlayers.TrackedChunk chunk) { ++ if (chunk == null) { ++ this.moonrise$clearPlayers(); ++ return; ++ } ++ ++ final ca.spottedleaf.moonrise.common.list.ReferenceList players = chunk.getPlayers(ca.spottedleaf.moonrise.common.misc.NearbyPlayers.NearbyMapType.VIEW_DISTANCE); ++ ++ if (players == null) { ++ this.moonrise$clearPlayers(); ++ return; ++ } ++ ++ final long lastChunkUpdate = this.lastChunkUpdate; ++ final long currChunkUpdate = chunk.getUpdateCount(); ++ final ca.spottedleaf.moonrise.common.misc.NearbyPlayers.TrackedChunk lastTrackedChunk = this.lastTrackedChunk; ++ this.lastChunkUpdate = currChunkUpdate; ++ this.lastTrackedChunk = chunk; ++ ++ final ServerPlayer[] playersRaw = players.getRawDataUnchecked(); ++ ++ for (int i = 0, len = players.size(); i < len; ++i) { ++ final ServerPlayer player = playersRaw[i]; ++ this.updatePlayer(player); ++ } ++ ++ if (lastChunkUpdate != currChunkUpdate || lastTrackedChunk != chunk) { ++ // need to purge any players possible not in the chunk list ++ for (final ServerPlayerConnection conn : new java.util.ArrayList<>(this.seenBy)) { ++ final ServerPlayer player = conn.getPlayer(); ++ if (!players.contains(player)) { ++ this.removePlayer(player); ++ } ++ } ++ } ++ } ++ ++ @Override ++ public final void moonrise$removeNonTickThreadPlayers() { ++ boolean foundToRemove = false; ++ for (final ServerPlayerConnection conn : this.seenBy) { ++ if (!io.papermc.paper.util.TickThread.isTickThreadFor(conn.getPlayer())) { ++ foundToRemove = true; ++ break; ++ } ++ } ++ ++ if (!foundToRemove) { ++ return; ++ } ++ ++ for (final ServerPlayerConnection conn : new java.util.ArrayList<>(this.seenBy)) { ++ ServerPlayer player = conn.getPlayer(); ++ if (!io.papermc.paper.util.TickThread.isTickThreadFor(player)) { ++ this.removePlayer(player); ++ } ++ } ++ } ++ ++ @Override ++ public final void moonrise$clearPlayers() { ++ this.lastChunkUpdate = -1; ++ this.lastTrackedChunk = null; ++ if (this.seenBy.isEmpty()) { ++ return; ++ } ++ for (final ServerPlayerConnection conn : new java.util.ArrayList<>(this.seenBy)) { ++ ServerPlayer player = conn.getPlayer(); ++ this.removePlayer(player); ++ } ++ } ++ // Paper end - optimise entity tracker ++ + public TrackedEntity(final Entity entity, final int i, final int j, final boolean flag) { + this.serverEntity = new ServerEntity(ChunkMap.this.level, entity, j, flag, this::broadcast, this.seenBy); // CraftBukkit + this.entity = entity; diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java index cbabbfbb9967ddf9a56f3be24a88e0fcd4415aa2..71abe25cfb73af3857cbc85980aa32d0201aab62 100644 --- a/src/main/java/net/minecraft/server/level/DistanceManager.java @@ -25887,7 +26476,7 @@ index be9604a0f267558c95125852d86761a2f175732a..67eb2fb32de3555b3afb4b4b7a3a47a1 } } diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..cf33e22ae85cd30b4f5d526dbfececca87d4ee40 100644 +index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..e955bf0c9f76f6e90bd726342f204e999090fee1 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -184,7 +184,7 @@ import org.bukkit.event.weather.LightningStrikeEvent; @@ -25908,7 +26497,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..cf33e22ae85cd30b4f5d526dbfececca private final GameEventDispatcher gameEventDispatcher; public boolean noSave; private final SleepStatus sleepStatus; -@@ -339,6 +339,179 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -339,6 +339,185 @@ public class ServerLevel extends Level implements WorldGenLevel { return player != null && player.level() == this ? player : null; } // Paper end - optimise getPlayerByUUID @@ -25922,6 +26511,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..cf33e22ae85cd30b4f5d526dbfececca + private final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler chunkTaskScheduler; + private long lastMidTickFailure; + private long tickedBlocksOrFluids; ++ private final ca.spottedleaf.moonrise.common.misc.NearbyPlayers nearbyPlayers = new ca.spottedleaf.moonrise.common.misc.NearbyPlayers((ServerLevel)(Object)this); + + @Override + public final LevelChunk moonrise$getFullChunkIfLoaded(final int chunkX, final int chunkZ) { @@ -26084,11 +26674,16 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..cf33e22ae85cd30b4f5d526dbfececca + public final void moonrise$setLastMidTickFailure(final long time) { + this.lastMidTickFailure = time; + } ++ ++ @Override ++ public final ca.spottedleaf.moonrise.common.misc.NearbyPlayers moonrise$getNearbyPlayers() { ++ return this.nearbyPlayers; ++ } + // Paper end - rewrite chunk system // 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) { -@@ -385,14 +558,13 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -385,14 +564,13 @@ public class ServerLevel extends Level implements WorldGenLevel { DataFixer datafixer = minecraftserver.getFixerUpper(); EntityPersistentStorage entitypersistentstorage = new EntityStorage(new SimpleRegionStorage(new RegionStorageInfo(convertable_conversionsession.getLevelId(), resourcekey, "entities"), convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), datafixer, flag2, DataFixTypes.ENTITY_CHUNK), this, minecraftserver); @@ -26106,7 +26701,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..cf33e22ae85cd30b4f5d526dbfececca return minecraftserver.overworld().getDataStorage(); }); this.chunkSource.getGeneratorState().ensureStructuresGenerated(); -@@ -420,6 +592,19 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -420,6 +598,19 @@ public class ServerLevel extends Level implements WorldGenLevel { this.randomSequences = (RandomSequences) Objects.requireNonNullElseGet(randomsequences, () -> { return (RandomSequences) this.getDataStorage().computeIfAbsent(RandomSequences.factory(l), "random_sequences"); }); @@ -26126,7 +26721,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..cf33e22ae85cd30b4f5d526dbfececca this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit } -@@ -553,7 +738,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -553,7 +744,7 @@ public class ServerLevel extends Level implements WorldGenLevel { gameprofilerfiller.push("checkDespawn"); entity.checkDespawn(); gameprofilerfiller.pop(); @@ -26135,7 +26730,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..cf33e22ae85cd30b4f5d526dbfececca Entity entity1 = entity.getVehicle(); if (entity1 != null) { -@@ -578,13 +763,16 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -578,13 +769,16 @@ public class ServerLevel extends Level implements WorldGenLevel { } gameprofilerfiller.push("entityManagement"); @@ -26154,7 +26749,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..cf33e22ae85cd30b4f5d526dbfececca } protected void tickTime() { -@@ -976,6 +1164,11 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -976,6 +1170,11 @@ public class ServerLevel extends Level implements WorldGenLevel { if (fluid1.is(fluid)) { fluid1.tick(this, pos); } @@ -26166,7 +26761,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..cf33e22ae85cd30b4f5d526dbfececca } -@@ -985,6 +1178,11 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -985,6 +1184,11 @@ public class ServerLevel extends Level implements WorldGenLevel { if (iblockdata.is(block)) { iblockdata.tick(this, pos, this.random); } @@ -26178,7 +26773,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..cf33e22ae85cd30b4f5d526dbfececca } -@@ -1061,6 +1259,11 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1061,6 +1265,11 @@ public class ServerLevel extends Level implements WorldGenLevel { } public void save(@Nullable ProgressListener progressListener, boolean flush, boolean savingDisabled) { @@ -26190,7 +26785,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..cf33e22ae85cd30b4f5d526dbfececca ServerChunkCache chunkproviderserver = this.getChunkSource(); if (!savingDisabled) { -@@ -1076,16 +1279,21 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1076,16 +1285,21 @@ public class ServerLevel extends Level implements WorldGenLevel { } timings.worldSaveChunks.startTiming(); // Paper @@ -26218,7 +26813,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..cf33e22ae85cd30b4f5d526dbfececca // CraftBukkit start - moved from MinecraftServer.saveChunks ServerLevel worldserver1 = this; -@@ -1218,7 +1426,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1218,7 +1432,7 @@ public class ServerLevel extends Level implements WorldGenLevel { this.removePlayerImmediately((ServerPlayer) entity, Entity.RemovalReason.DISCARDED); } @@ -26227,7 +26822,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..cf33e22ae85cd30b4f5d526dbfececca } // CraftBukkit start -@@ -1249,7 +1457,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1249,7 +1463,7 @@ public class ServerLevel extends Level implements WorldGenLevel { } // CraftBukkit end @@ -26236,7 +26831,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..cf33e22ae85cd30b4f5d526dbfececca } } -@@ -1260,11 +1468,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1260,11 +1474,7 @@ public class ServerLevel extends Level implements WorldGenLevel { public boolean tryAddFreshEntityWithPassengers(Entity entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) { // CraftBukkit end @@ -26249,7 +26844,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..cf33e22ae85cd30b4f5d526dbfececca return false; } else { this.addFreshEntityWithPassengers(entity, reason); // CraftBukkit -@@ -1850,7 +2054,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1850,7 +2060,7 @@ public class ServerLevel extends Level implements WorldGenLevel { } } @@ -26258,7 +26853,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..cf33e22ae85cd30b4f5d526dbfececca bufferedwriter.write(String.format(Locale.ROOT, "block_entity_tickers: %d\n", this.blockEntityTickers.size())); bufferedwriter.write(String.format(Locale.ROOT, "block_ticks: %d\n", this.getBlockTicks().count())); bufferedwriter.write(String.format(Locale.ROOT, "fluid_ticks: %d\n", this.getFluidTicks().count())); -@@ -1899,7 +2103,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1899,7 +2109,7 @@ public class ServerLevel extends Level implements WorldGenLevel { BufferedWriter bufferedwriter2 = Files.newBufferedWriter(path1); try { @@ -26267,7 +26862,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..cf33e22ae85cd30b4f5d526dbfececca } catch (Throwable throwable4) { if (bufferedwriter2 != null) { try { -@@ -1920,7 +2124,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1920,7 +2130,7 @@ public class ServerLevel extends Level implements WorldGenLevel { BufferedWriter bufferedwriter3 = Files.newBufferedWriter(path2); try { @@ -26276,7 +26871,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..cf33e22ae85cd30b4f5d526dbfececca } catch (Throwable throwable6) { if (bufferedwriter3 != null) { try { -@@ -2062,7 +2266,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2062,7 +2272,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @VisibleForTesting public String getWatchdogStats() { @@ -26285,7 +26880,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..cf33e22ae85cd30b4f5d526dbfececca return BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString(); }), this.blockEntityTickers.size(), ServerLevel.getTypeCount(this.blockEntityTickers, TickingBlockEntity::getType), this.getBlockTicks().count(), this.getFluidTicks().count(), this.gatherChunkSourceStats()); } -@@ -2092,15 +2296,25 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2092,15 +2302,25 @@ public class ServerLevel extends Level implements WorldGenLevel { @Override public LevelEntityGetter getEntities() { org.spigotmc.AsyncCatcher.catchOp("Chunk getEntities call"); // Spigot @@ -26314,7 +26909,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..cf33e22ae85cd30b4f5d526dbfececca } public void startTickingChunk(LevelChunk chunk) { -@@ -2120,34 +2334,47 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2120,34 +2340,47 @@ public class ServerLevel extends Level implements WorldGenLevel { @Override public void close() throws IOException { super.close(); @@ -26369,7 +26964,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..cf33e22ae85cd30b4f5d526dbfececca } @Override -@@ -2173,7 +2400,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2173,7 +2406,7 @@ public class ServerLevel extends Level implements WorldGenLevel { CrashReportCategory crashreportsystemdetails = super.fillReportDetails(report); crashreportsystemdetails.setDetail("Loaded entity count", () -> { @@ -26970,7 +27565,7 @@ index ea72dcb064a35bc6245bc5c94d592efedd8faf41..87ee8e51dfa7657ed7d83fcbceef48bf this.comparator = comparator; if (initialCapacity < 0) { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 2e2101274f3afebbae783fa119f5cae8104de45d..a7deceb2b9caad47f7f641ba4302d622d7127651 100644 +index 2e2101274f3afebbae783fa119f5cae8104de45d..690d3f669092f0a0a39a93a401c2e8a1626650b4 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -167,7 +167,7 @@ import org.bukkit.event.player.PlayerTeleportEvent; @@ -26978,11 +27573,11 @@ index 2e2101274f3afebbae783fa119f5cae8104de45d..a7deceb2b9caad47f7f641ba4302d622 // CraftBukkit end -public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, CommandSource, ScoreHolder { -+public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, CommandSource, ScoreHolder, ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity { // Paper - rewrite chunk system ++public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, CommandSource, ScoreHolder, ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity, ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity { // Paper - rewrite chunk system // Paper - optimise entity tracker // CraftBukkit start private static final int CURRENT_LEVEL = 2; -@@ -456,6 +456,77 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -456,6 +456,97 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return this.dimensions.makeBoundingBox(x, y, z); } // Paper end @@ -27057,10 +27652,55 @@ index 2e2101274f3afebbae783fa119f5cae8104de45d..a7deceb2b9caad47f7f641ba4302d622 + return this.getIndirectPassengersStream().anyMatch((entity) -> entity instanceof Player); + } + // Paper end - rewrite chunk system ++ // Paper start - optimise entity tracker ++ private net.minecraft.server.level.ChunkMap.TrackedEntity trackedEntity; ++ ++ @Override ++ public final net.minecraft.server.level.ChunkMap.TrackedEntity moonrise$getTrackedEntity() { ++ return this.trackedEntity; ++ } ++ ++ @Override ++ public final void moonrise$setTrackedEntity(final net.minecraft.server.level.ChunkMap.TrackedEntity trackedEntity) { ++ this.trackedEntity = trackedEntity; ++ } ++ ++ private static void collectIndirectPassengers(final List into, final List from) { ++ for (final Entity passenger : from) { ++ into.add(passenger); ++ collectIndirectPassengers(into, ((Entity)(Object)passenger).passengers); ++ } ++ } ++ // Paper end - optimise entity tracker public Entity(EntityType type, Level world) { this.id = Entity.ENTITY_COUNTER.incrementAndGet(); -@@ -4397,6 +4468,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4025,14 +4116,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + } + + public Iterable getIndirectPassengers() { +- // Paper start - Optimize indirect passenger iteration +- if (this.passengers.isEmpty()) { return ImmutableList.of(); } +- ImmutableList.Builder indirectPassengers = ImmutableList.builder(); +- for (Entity passenger : this.passengers) { +- indirectPassengers.add(passenger); +- indirectPassengers.addAll(passenger.getIndirectPassengers()); ++ // Paper start - optimise entity tracker ++ final List ret = new ArrayList<>(); ++ ++ if (this.passengers.isEmpty()) { ++ return ret; + } +- return indirectPassengers.build(); ++ ++ collectIndirectPassengers(ret, this.passengers); ++ ++ return ret; ++ // Paper end - optimise entity tracker + } + private Iterable getIndirectPassengers_old() { + // Paper end - Optimize indirect passenger iteration +@@ -4397,6 +4491,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.setPosRaw(x, y, z, false); } public final void setPosRaw(double x, double y, double z, boolean forceBoundingBoxUpdate) { @@ -27076,7 +27716,7 @@ index 2e2101274f3afebbae783fa119f5cae8104de45d..a7deceb2b9caad47f7f641ba4302d622 if (!checkPosition(this, x, y, z)) { return; } -@@ -4528,6 +4608,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4528,6 +4631,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @Override public final void setRemoved(Entity.RemovalReason entity_removalreason, EntityRemoveEvent.Cause cause) { @@ -27089,7 +27729,7 @@ index 2e2101274f3afebbae783fa119f5cae8104de45d..a7deceb2b9caad47f7f641ba4302d622 CraftEventFactory.callEntityRemoveEvent(this, cause); // CraftBukkit end final boolean alreadyRemoved = this.removalReason != null; // Paper - Folia schedulers -@@ -4539,7 +4625,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4539,7 +4648,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.stopRiding(); } @@ -27098,7 +27738,7 @@ index 2e2101274f3afebbae783fa119f5cae8104de45d..a7deceb2b9caad47f7f641ba4302d622 this.levelCallback.onRemove(entity_removalreason); // Paper start - Folia schedulers if (!(this instanceof ServerPlayer) && entity_removalreason != RemovalReason.CHANGED_DIMENSION && !alreadyRemoved) { -@@ -4570,7 +4656,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4570,7 +4679,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @Override public boolean shouldBeSaved() { diff --git a/patches/server/0993-disable-forced-empty-world-ticks.patch b/patches/server/0993-disable-forced-empty-world-ticks.patch index 5dc524cb7c..aa80568a5a 100644 --- a/patches/server/0993-disable-forced-empty-world-ticks.patch +++ b/patches/server/0993-disable-forced-empty-world-ticks.patch @@ -5,10 +5,10 @@ Subject: [PATCH] disable forced empty world ticks diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index cf33e22ae85cd30b4f5d526dbfececca87d4ee40..db30381b3aeab83bcd0d1a341e4056d7c36a6f11 100644 +index e955bf0c9f76f6e90bd726342f204e999090fee1..e5c44d2b02848aca5dcfc86006ab688598244f16 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -713,7 +713,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -719,7 +719,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. this.handlingTick = false; gameprofilerfiller.pop(); diff --git a/patches/server/0995-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch b/patches/server/0995-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch index cb921d96da..5fac9b6575 100644 --- a/patches/server/0995-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch +++ b/patches/server/0995-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch @@ -13,10 +13,10 @@ custom renderers are in use, defaulting to the much simpler Vanilla system. Additionally, numerous issues to player position tracking on maps has been fixed. diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index db30381b3aeab83bcd0d1a341e4056d7c36a6f11..fc011c30628d77d55defe421db6ac194217e8def 100644 +index e5c44d2b02848aca5dcfc86006ab688598244f16..eee9aa0d82c7446f3d32a9655abceb5279ea5226 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -2492,6 +2492,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -2498,6 +2498,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. { if ( iter.next().player == entity ) { diff --git a/patches/server/1000-Entity-Activation-Range-2.0.patch b/patches/server/1000-Entity-Activation-Range-2.0.patch index 154d3a86cd..ddcaef5bad 100644 --- a/patches/server/1000-Entity-Activation-Range-2.0.patch +++ b/patches/server/1000-Entity-Activation-Range-2.0.patch @@ -17,7 +17,7 @@ Adds villagers as separate config public net.minecraft.world.entity.Entity isInsidePortal diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index fc011c30628d77d55defe421db6ac194217e8def..975174a2f20e1597ffd2f9d840c77eec3c353b88 100644 +index eee9aa0d82c7446f3d32a9655abceb5279ea5226..a12864921a35a1fb3b6081d72e6505820a6c64f1 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -2,7 +2,6 @@ package net.minecraft.server.level; @@ -28,7 +28,7 @@ index fc011c30628d77d55defe421db6ac194217e8def..975174a2f20e1597ffd2f9d840c77eec import com.google.common.collect.Lists; import com.mojang.datafixers.DataFixer; import com.mojang.datafixers.util.Pair; -@@ -1190,17 +1189,17 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -1196,17 +1195,17 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. ++TimingHistory.entityTicks; // Paper - timings // Spigot start co.aikar.timings.Timing timer; // Paper @@ -50,7 +50,7 @@ index fc011c30628d77d55defe421db6ac194217e8def..975174a2f20e1597ffd2f9d840c77eec try { // Paper end - timings entity.setOldPosAndRot(); -@@ -1211,9 +1210,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -1217,9 +1216,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. return BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString(); }); gameprofilerfiller.incrementCounter("tickNonPassenger"); @@ -64,7 +64,7 @@ index fc011c30628d77d55defe421db6ac194217e8def..975174a2f20e1597ffd2f9d840c77eec Iterator iterator = entity.getPassengers().iterator(); while (iterator.hasNext()) { -@@ -1221,13 +1224,18 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -1227,13 +1230,18 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. this.tickPassenger(entity, entity1); } @@ -84,7 +84,7 @@ index fc011c30628d77d55defe421db6ac194217e8def..975174a2f20e1597ffd2f9d840c77eec passenger.setOldPosAndRot(); ++passenger.tickCount; ProfilerFiller gameprofilerfiller = this.getProfiler(); -@@ -1236,8 +1244,17 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -1242,8 +1250,17 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. return BuiltInRegistries.ENTITY_TYPE.getKey(passenger.getType()).toString(); }); gameprofilerfiller.incrementCounter("tickPassenger"); @@ -102,7 +102,7 @@ index fc011c30628d77d55defe421db6ac194217e8def..975174a2f20e1597ffd2f9d840c77eec gameprofilerfiller.pop(); Iterator iterator = passenger.getPassengers().iterator(); -@@ -1247,6 +1264,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -1253,6 +1270,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. this.tickPassenger(passenger, entity2); } @@ -111,7 +111,7 @@ index fc011c30628d77d55defe421db6ac194217e8def..975174a2f20e1597ffd2f9d840c77eec } else { passenger.stopRiding(); diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index a7deceb2b9caad47f7f641ba4302d622d7127651..5d7bc6470ab3818b0a189aab18ff26c0180e3912 100644 +index 690d3f669092f0a0a39a93a401c2e8a1626650b4..ffee1fd60e863d1453796ee498fc5a3b13d26de8 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -419,6 +419,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -123,7 +123,7 @@ index a7deceb2b9caad47f7f641ba4302d622d7127651..5d7bc6470ab3818b0a189aab18ff26c0 public boolean spawnedViaMobSpawner; // Paper - Yes this name is similar to above, upstream took the better one // Paper start - Entity origin API @javax.annotation.Nullable -@@ -1039,6 +1041,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1059,6 +1061,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } else { this.wasOnFire = this.isOnFire(); if (movementType == MoverType.PISTON) { @@ -132,7 +132,7 @@ index a7deceb2b9caad47f7f641ba4302d622d7127651..5d7bc6470ab3818b0a189aab18ff26c0 movement = this.limitPistonMovement(movement); if (movement.equals(Vec3.ZERO)) { return; -@@ -1051,6 +1055,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1071,6 +1075,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.stuckSpeedMultiplier = Vec3.ZERO; this.setDeltaMovement(Vec3.ZERO); } diff --git a/patches/server/1002-Anti-Xray.patch b/patches/server/1002-Anti-Xray.patch index ab9a10b557..400053becc 100644 --- a/patches/server/1002-Anti-Xray.patch +++ b/patches/server/1002-Anti-Xray.patch @@ -1104,10 +1104,10 @@ index 183b2191fa1c1b27adedf39593e1b5a223fb1279..8ead66c134688b11dca15f6509147e72 private ClientboundLevelChunkWithLightPacket(RegistryFriendlyByteBuf buf) { diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 975174a2f20e1597ffd2f9d840c77eec3c353b88..8daa490817367391cac5c9852e0755b280fb9054 100644 +index a12864921a35a1fb3b6081d72e6505820a6c64f1..8a3f58e6dfdb0af767be334087748f93c06ec797 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -518,7 +518,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -524,7 +524,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. // Holder holder = worlddimension.type(); // CraftBukkit - decompile error // Objects.requireNonNull(minecraftserver); // CraftBukkit - decompile error @@ -1561,7 +1561,7 @@ index 977bebe8657abc5cb84ede8276d6781cde20e847..6d461849da76894244e6212a75da0c6e // CraftBukkit end diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java -index cce2fed2d4e9d6147ea1854321012c6950eb05cc..2d5c88b80c983eb067ef366c3d9344826fbb0938 100644 +index 33322b57b4c6922f4daad0f584733f0f24083911..45e262308aebafa377a2353661acdd122933b99e 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java @@ -56,7 +56,7 @@ public class CraftChunk implements Chunk { diff --git a/patches/server/1004-Add-Alternate-Current-redstone-implementation.patch b/patches/server/1004-Add-Alternate-Current-redstone-implementation.patch index 261590166f..6554a372c9 100644 --- a/patches/server/1004-Add-Alternate-Current-redstone-implementation.patch +++ b/patches/server/1004-Add-Alternate-Current-redstone-implementation.patch @@ -2009,7 +2009,7 @@ index 0000000000000000000000000000000000000000..33cd90c30c22200a4e1ae64f40a0bf78 + } +} diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 8daa490817367391cac5c9852e0755b280fb9054..2d97ca1f3c625c0206d35b785c57d9587924ed0a 100644 +index 8a3f58e6dfdb0af767be334087748f93c06ec797..7ba34da235ea536b929e1c8bc2cc39e48b33f5aa 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -228,6 +228,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. @@ -2020,7 +2020,7 @@ index 8daa490817367391cac5c9852e0755b280fb9054..2d97ca1f3c625c0206d35b785c57d958 public LevelChunk getChunkIfLoaded(int x, int z) { return this.chunkSource.getChunkAtIfLoadedImmediately(x, z); // Paper - Use getChunkIfLoadedImmediately -@@ -2423,6 +2424,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -2429,6 +2430,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. return crashreportsystemdetails; } diff --git a/patches/server/1018-API-for-checking-sent-chunks.patch b/patches/server/1018-API-for-checking-sent-chunks.patch index 137772f487..5129c9a08a 100644 --- a/patches/server/1018-API-for-checking-sent-chunks.patch +++ b/patches/server/1018-API-for-checking-sent-chunks.patch @@ -5,10 +5,10 @@ Subject: [PATCH] API for checking sent chunks diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java -index 82e8ce73b77accd6a4210f88c9fccb325ae367d4..91c4219b2abf1b5be3dc35f7b8403884e1d36f8d 100644 +index f063ab3ff122b920bcc4aa4f5bf9a442a8eb32fd..95d2d4417591b921d1ddf73025565cff6aabddd7 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java -@@ -1070,5 +1070,10 @@ public final class RegionizedPlayerChunkLoader { +@@ -1072,5 +1072,10 @@ public final class RegionizedPlayerChunkLoader { // now all tickets should be removed, which is all of our external state } diff --git a/patches/server/1023-Properly-resend-entities.patch b/patches/server/1023-Properly-resend-entities.patch index 49917da8c7..02512d7402 100644 --- a/patches/server/1023-Properly-resend-entities.patch +++ b/patches/server/1023-Properly-resend-entities.patch @@ -115,10 +115,10 @@ index 1aa8b914e79c0d48094cc22df60ee9750ec3ccd6..369b3485f452ac157b3ebf88b4f19706 this.sendLevelInfo(player, worldserver1); diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index f1fb4e830c6720d09b22056e3d0b9a08fe2bd472..83f3ffdd8fa901b3de580d2359cdb5ead0d762cb 100644 +index d8a90d7c77536abac6fa5f505338b1b53ef986af..593f371c383d4310f4e8ed81200126b05f585ee6 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -665,13 +665,44 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -685,13 +685,44 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess // CraftBukkit start public void refreshEntityData(ServerPlayer to) { @@ -166,7 +166,7 @@ index f1fb4e830c6720d09b22056e3d0b9a08fe2bd472..83f3ffdd8fa901b3de580d2359cdb5ea public boolean equals(Object object) { return object instanceof Entity ? ((Entity) object).id == this.id : false; diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 6e5af47f5d2775c1afc4914342c3d0ea6569c792..c5ca9fa86b940c6b5a54b05ff1bb3d0a300d60b2 100644 +index c49f71ac5470e7b823af8339e5583e654bc907a0..945da6b82653f05625f054d64bbf605a4ec1cd05 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -3879,6 +3879,11 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/1024-Optimise-random-block-ticking.patch b/patches/server/1024-Optimise-random-block-ticking.patch index 774d250ea6..8f81d5dd83 100644 --- a/patches/server/1024-Optimise-random-block-ticking.patch +++ b/patches/server/1024-Optimise-random-block-ticking.patch @@ -90,10 +90,10 @@ index 0000000000000000000000000000000000000000..7d93652c1abbb6aee6eb7c26cf35d4d0 + } +} diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 2d97ca1f3c625c0206d35b785c57d9587924ed0a..e079f4db4e4738f60a6fdbdbf5e4d1baf593a62f 100644 +index 7ba34da235ea536b929e1c8bc2cc39e48b33f5aa..2a752deb8cc44b49588be37198fe394a9c95683e 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -813,6 +813,10 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -819,6 +819,10 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. entityplayer.stopSleepInBed(false, false); }); } @@ -104,7 +104,7 @@ index 2d97ca1f3c625c0206d35b785c57d9587924ed0a..e079f4db4e4738f60a6fdbdbf5e4d1ba public void tickChunk(LevelChunk chunk, int randomTickSpeed) { ChunkPos chunkcoordintpair = chunk.getPos(); -@@ -822,8 +826,10 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -828,8 +832,10 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. ProfilerFiller gameprofilerfiller = this.getProfiler(); gameprofilerfiller.push("thunder"); @@ -116,7 +116,7 @@ index 2d97ca1f3c625c0206d35b785c57d9587924ed0a..e079f4db4e4738f60a6fdbdbf5e4d1ba if (this.isRainingAt(blockposition)) { DifficultyInstance difficultydamagescaler = this.getCurrentDifficultyAt(blockposition); -@@ -855,7 +861,10 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -861,7 +867,10 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. if (!this.paperConfig().environment.disableIceAndSnow) { // Paper - Option to disable ice and snow for (int l = 0; l < randomTickSpeed; ++l) { if (this.random.nextInt(48) == 0) { @@ -128,7 +128,7 @@ index 2d97ca1f3c625c0206d35b785c57d9587924ed0a..e079f4db4e4738f60a6fdbdbf5e4d1ba } } } // Paper - Option to disable ice and snow -@@ -863,36 +872,37 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -869,36 +878,37 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. gameprofilerfiller.popPush("tickBlocks"); timings.chunkTicksBlocks.startTiming(); // Paper if (randomTickSpeed > 0) { @@ -190,7 +190,7 @@ index 2d97ca1f3c625c0206d35b785c57d9587924ed0a..e079f4db4e4738f60a6fdbdbf5e4d1ba timings.chunkTicksBlocks.stopTiming(); // Paper gameprofilerfiller.pop(); -@@ -900,17 +910,25 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -906,17 +916,25 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. @VisibleForTesting public void tickPrecipitation(BlockPos pos) { @@ -220,7 +220,7 @@ index 2d97ca1f3c625c0206d35b785c57d9587924ed0a..e079f4db4e4738f60a6fdbdbf5e4d1ba if (i > 0 && biomebase.shouldSnow(this, blockposition1)) { BlockState iblockdata = this.getBlockState(blockposition1); -@@ -928,12 +946,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -934,12 +952,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. } } diff --git a/patches/server/1037-Fix-entity-tracker-desync-when-new-players-are-added.patch b/patches/server/1037-Fix-entity-tracker-desync-when-new-players-are-added.patch index 576b74c10c..294794eaea 100644 --- a/patches/server/1037-Fix-entity-tracker-desync-when-new-players-are-added.patch +++ b/patches/server/1037-Fix-entity-tracker-desync-when-new-players-are-added.patch @@ -48,10 +48,10 @@ index 1a5e73fd97781f3903e5ef13aa0352c64fbc2cc1..4126d82e83810126eb4a41b4587dc993 entityTrackerEntry.getLastSentYRot(), entity.getType(), diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index c96740a82eac9101f74edeb44edf4b64d1d633e0..8b6754525fafd1aaac3292cf69a855d6a42b9523 100644 +index 344966d3deb640eb99bc9c9e318e6e6780421907..6df79aab2f0a75bbe347dc92e9ed5d62ceec7983 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1189,6 +1189,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1302,6 +1302,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.serverEntity.addPairing(player); } // Paper end - entity tracking events