diff --git a/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch b/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch index d237f5a3df2..3c4d4a45638 100644 --- a/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch +++ b/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch @@ -297,7 +297,7 @@ index 0000000000000000000000000000000000000000..1b8193587814225c2ef2c5d9e667436e + } +} diff --git a/ca/spottedleaf/moonrise/paper/PaperHooks.java b/ca/spottedleaf/moonrise/paper/PaperHooks.java -index 6f65564f6a6e99d6549de9a23a031b1f4a8a9798..cba09766b9e0c47573aa562872cbe4cfbda4e99a 100644 +index b6730b785e4adf4e1371b34161c7968d84760e02..749f396840439cfb67ff2a6a1946772fcbe4d181 100644 --- a/ca/spottedleaf/moonrise/paper/PaperHooks.java +++ b/ca/spottedleaf/moonrise/paper/PaperHooks.java @@ -13,6 +13,7 @@ import net.minecraft.server.level.ChunkHolder; @@ -4907,10 +4907,10 @@ index 0000000000000000000000000000000000000000..2d24d03bbdb5ee0d862cbfff2219f58a +} diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/client/ClientEntityLookup.java b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/client/ClientEntityLookup.java new file mode 100644 -index 0000000000000000000000000000000000000000..a038215156a163b0b1cbc870ada5b4ac85ed1335 +index 0000000000000000000000000000000000000000..cf929c61d244e3408a7f9cfc0914d140a6c444db --- /dev/null +++ b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/client/ClientEntityLookup.java -@@ -0,0 +1,129 @@ +@@ -0,0 +1,128 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.level.entity.client; + +import ca.spottedleaf.moonrise.common.PlatformHooks; @@ -4958,8 +4958,7 @@ index 0000000000000000000000000000000000000000..a038215156a163b0b1cbc870ada5b4ac + final boolean ticking = this.tickingChunks.contains(CoordinateUtils.getChunkKey(chunkX, chunkZ)); + + final ChunkEntitySlices ret = new ChunkEntitySlices( -+ this.world, chunkX, chunkZ, -+ ticking ? FullChunkStatus.ENTITY_TICKING : FullChunkStatus.FULL, null, ++ this.world, chunkX, chunkZ, ticking ? FullChunkStatus.ENTITY_TICKING : FullChunkStatus.FULL, null, + WorldUtil.getMinSection(this.world), WorldUtil.getMaxSection(this.world) + ); + @@ -5162,10 +5161,10 @@ index 0000000000000000000000000000000000000000..2ff58cf753c60913ee73aae015182e9c +} diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/server/ServerEntityLookup.java b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/server/ServerEntityLookup.java new file mode 100644 -index 0000000000000000000000000000000000000000..26207443b1223119c03db478d7e816d9cdf8e618 +index 0000000000000000000000000000000000000000..5f2deeb5cc01d8bbeb7449bd4e59c466b3dfdf57 --- /dev/null +++ b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/server/ServerEntityLookup.java -@@ -0,0 +1,115 @@ +@@ -0,0 +1,166 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server; + +import ca.spottedleaf.moonrise.common.PlatformHooks; @@ -5175,9 +5174,14 @@ index 0000000000000000000000000000000000000000..26207443b1223119c03db478d7e816d9 +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 ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkHolderManager; ++import ca.spottedleaf.moonrise.patches.chunk_system.ticket.ChunkSystemTicketType; ++import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; ++import net.minecraft.server.level.TicketType; +import net.minecraft.world.entity.Entity; ++import net.minecraft.world.entity.projectile.ThrownEnderpearl; +import net.minecraft.world.level.entity.LevelCallback; + +public final class ServerEntityLookup extends EntityLookup { @@ -5187,9 +5191,18 @@ index 0000000000000000000000000000000000000000..26207443b1223119c03db478d7e816d9 + private final ServerLevel serverWorld; + public final ReferenceList trackerEntities = new ReferenceList<>(EMPTY_ENTITY_ARRAY); // Moonrise - entity tracker + ++ // Vanilla does not increment ticket timeouts if the chunk is progressing in generation. They made this change in 1.21.6 so that the ender pearl ++ // ticket does not expire if the chunk fails to generate before the timeout expires. Rather than blindly adjusting the entire system behavior ++ // to fix this small issue, we instead add non-expirable tickets here to keep ender pearls ticking. This is how the original feature should have ++ // been implemented, but I don't think Vanilla has proper entity add/remove hooks like we do. Fixes MC-297591 ++ private static final TicketType ENDER_PEARL_TICKER = ChunkSystemTicketType.create("chunk_system:ender_pearl_ticker", null); ++ private final Long2IntOpenHashMap enderPearlChunkCount = new Long2IntOpenHashMap(); ++ private final boolean keepEnderPearlsTicking; ++ + public ServerEntityLookup(final ServerLevel world, final LevelCallback worldCallback) { + super(world, worldCallback); + this.serverWorld = world; ++ this.keepEnderPearlsTicking = PlatformHooks.get().addTicketForEnderPearls(world); + } + + @Override @@ -5231,6 +5244,10 @@ index 0000000000000000000000000000000000000000..26207443b1223119c03db478d7e816d9 + if (entity instanceof ServerPlayer player) { + ((ChunkSystemServerLevel)this.serverWorld).moonrise$getNearbyPlayers().tickPlayer(player); + } ++ if (entity instanceof ThrownEnderpearl enderpearl && (oldSectionX != newSectionX || oldSectionZ != newSectionZ)) { ++ this.removeEnderPearl(CoordinateUtils.getChunkKey(oldSectionX, oldSectionZ)); ++ this.addEnderPearl(CoordinateUtils.getChunkKey(newSectionX, newSectionZ)); ++ } + PlatformHooks.get().entityMove( + entity, + CoordinateUtils.getChunkSectionKey(oldSectionX, oldSectionY, oldSectionZ), @@ -5243,6 +5260,9 @@ index 0000000000000000000000000000000000000000..26207443b1223119c03db478d7e816d9 + if (entity instanceof ServerPlayer player) { + ((ChunkSystemServerLevel)this.serverWorld).moonrise$getNearbyPlayers().addPlayer(player); + } ++ if (entity instanceof ThrownEnderpearl enderpearl) { ++ this.addEnderPearl(CoordinateUtils.getChunkKey(enderpearl.chunkPosition())); ++ } + } + + @Override @@ -5250,6 +5270,9 @@ index 0000000000000000000000000000000000000000..26207443b1223119c03db478d7e816d9 + if (entity instanceof ServerPlayer player) { + ((ChunkSystemServerLevel)this.serverWorld).moonrise$getNearbyPlayers().removePlayer(player); + } ++ if (entity instanceof ThrownEnderpearl enderpearl) { ++ this.removeEnderPearl(CoordinateUtils.getChunkKey(enderpearl.chunkPosition())); ++ } + } + + @Override @@ -5280,6 +5303,33 @@ index 0000000000000000000000000000000000000000..26207443b1223119c03db478d7e816d9 + protected boolean screenEntity(final Entity entity, final boolean fromDisk, final boolean event) { + return PlatformHooks.get().screenEntity(this.serverWorld, entity, fromDisk, event); + } ++ ++ private void addEnderPearl(final long coordinate) { ++ if (!this.keepEnderPearlsTicking) { ++ return; ++ } ++ ++ final int oldCount = this.enderPearlChunkCount.addTo(coordinate, 1); ++ if (oldCount != 0) { ++ return; ++ } ++ ((ChunkSystemServerLevel)this.serverWorld).moonrise$getChunkTaskScheduler().chunkHolderManager ++ .addTicketAtLevel(ENDER_PEARL_TICKER, coordinate, ChunkHolderManager.ENTITY_TICKING_TICKET_LEVEL, null); ++ } ++ ++ private void removeEnderPearl(final long coordinate) { ++ if (!this.keepEnderPearlsTicking) { ++ return; ++ } ++ ++ final int oldCount = this.enderPearlChunkCount.addTo(coordinate, -1); ++ if (oldCount != 1) { ++ return; ++ } ++ this.enderPearlChunkCount.remove(coordinate); ++ ((ChunkSystemServerLevel)this.serverWorld).moonrise$getChunkTaskScheduler().chunkHolderManager ++ .removeTicketAtLevel(ENDER_PEARL_TICKER, coordinate, ChunkHolderManager.ENTITY_TICKING_TICKET_LEVEL, null); ++ } +} diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/ChunkSystemPoiManager.java b/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/ChunkSystemPoiManager.java new file mode 100644 diff --git a/paper-server/patches/sources/ca/spottedleaf/moonrise/paper/PaperHooks.java.patch b/paper-server/patches/sources/ca/spottedleaf/moonrise/paper/PaperHooks.java.patch index 2701d3e9a70..fb16e759456 100644 --- a/paper-server/patches/sources/ca/spottedleaf/moonrise/paper/PaperHooks.java.patch +++ b/paper-server/patches/sources/ca/spottedleaf/moonrise/paper/PaperHooks.java.patch @@ -1,6 +1,6 @@ --- /dev/null +++ b/ca/spottedleaf/moonrise/paper/PaperHooks.java -@@ -1,0 +_,250 @@ +@@ -1,0 +_,255 @@ +package ca.spottedleaf.moonrise.paper; + +import ca.spottedleaf.moonrise.common.PlatformHooks; @@ -250,4 +250,9 @@ + public int modifyEntityTrackingRange(final Entity entity, final int currentRange) { + return org.spigotmc.TrackingRange.getEntityTrackingRange(entity, currentRange); + } ++ ++ @Override ++ public boolean addTicketForEnderPearls(final ServerLevel world) { ++ return !world.paperConfig().misc.legacyEnderPearlBehavior; ++ } +} diff --git a/paper-server/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java b/paper-server/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java index 9b879cbc037..279832c201d 100644 --- a/paper-server/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java +++ b/paper-server/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java @@ -102,6 +102,8 @@ public interface PlatformHooks extends ChunkSystemHooks { public int modifyEntityTrackingRange(final Entity entity, final int currentRange); + public boolean addTicketForEnderPearls(final ServerLevel world); + public static final class Holder { private Holder() { } diff --git a/paper-server/src/main/java/ca/spottedleaf/moonrise/common/util/CoordinateUtils.java b/paper-server/src/main/java/ca/spottedleaf/moonrise/common/util/CoordinateUtils.java index 31b92bd4882..bb5b9c9cb0c 100644 --- a/paper-server/src/main/java/ca/spottedleaf/moonrise/common/util/CoordinateUtils.java +++ b/paper-server/src/main/java/ca/spottedleaf/moonrise/common/util/CoordinateUtils.java @@ -16,7 +16,8 @@ public final class CoordinateUtils { } public static long getChunkKey(final Entity entity) { - return ((Mth.lfloor(entity.getZ()) >> 4) << 32) | ((Mth.lfloor(entity.getX()) >> 4) & 0xFFFFFFFFL); + final ChunkPos pos = entity.chunkPosition(); + return ((long)pos.z << 32) | (pos.x & 0xFFFFFFFFL); } public static long getChunkKey(final ChunkPos pos) {