diff --git a/leaf-api/paper-patches/features/0019-PlayerInventoryOverflowEvent.patch b/leaf-api/paper-patches/features/0018-PlayerInventoryOverflowEvent.patch similarity index 100% rename from leaf-api/paper-patches/features/0019-PlayerInventoryOverflowEvent.patch rename to leaf-api/paper-patches/features/0018-PlayerInventoryOverflowEvent.patch diff --git a/leaf-api/paper-patches/features/0020-Raytrace-AntiXray-SDK-integration.patch b/leaf-api/paper-patches/features/0019-Raytrace-AntiXray-SDK-integration.patch similarity index 100% rename from leaf-api/paper-patches/features/0020-Raytrace-AntiXray-SDK-integration.patch rename to leaf-api/paper-patches/features/0019-Raytrace-AntiXray-SDK-integration.patch diff --git a/leaf-server/minecraft-patches/features/0170-Asynchronous-locator.patch b/leaf-archived-patches/removed/1.21.8/mcserver/0170-Asynchronous-locator.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0170-Asynchronous-locator.patch rename to leaf-archived-patches/removed/1.21.8/mcserver/0170-Asynchronous-locator.patch diff --git a/leaf-archived-patches/removed/1.21.8/mcserver/0191-Cache-supporting-block-check.patch b/leaf-archived-patches/removed/1.21.8/mcserver/0191-Cache-supporting-block-check.patch index 6ae7b61e..be1bee97 100644 --- a/leaf-archived-patches/removed/1.21.8/mcserver/0191-Cache-supporting-block-check.patch +++ b/leaf-archived-patches/removed/1.21.8/mcserver/0191-Cache-supporting-block-check.patch @@ -3,6 +3,7 @@ From: Taiyou06 Date: Sat, 8 Feb 2025 05:32:30 +0100 Subject: [PATCH] Cache supporting block check +Removed since 1.21.8 diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java index e563b636a05a299d860a334987594dbd5c7d3511..428b2114749780770cc617d5e1aedea7f1b28b2d 100644 diff --git a/leaf-api/paper-patches/features/0018-Async-structure-locate-api.patch b/leaf-archived-patches/removed/1.21.8/paperapi/0018-Async-structure-locate-api.patch similarity index 100% rename from leaf-api/paper-patches/features/0018-Async-structure-locate-api.patch rename to leaf-archived-patches/removed/1.21.8/paperapi/0018-Async-structure-locate-api.patch diff --git a/leaf-server/paper-patches/features/0042-Asynchronous-locator.patch b/leaf-archived-patches/removed/1.21.8/paperserver/0042-Asynchronous-locator.patch similarity index 100% rename from leaf-server/paper-patches/features/0042-Asynchronous-locator.patch rename to leaf-archived-patches/removed/1.21.8/paperserver/0042-Asynchronous-locator.patch diff --git a/leaf-server/paper-patches/features/0046-Async-structure-locate-api.patch b/leaf-archived-patches/removed/1.21.8/paperserver/0046-Async-structure-locate-api.patch similarity index 100% rename from leaf-server/paper-patches/features/0046-Async-structure-locate-api.patch rename to leaf-archived-patches/removed/1.21.8/paperserver/0046-Async-structure-locate-api.patch diff --git a/leaf-server/src/main/java/org/dreeam/leaf/async/locate/AsyncLocator.java b/leaf-archived-patches/removed/1.21.8/src/dreeam/leaf/async/locate/AsyncLocator.java similarity index 100% rename from leaf-server/src/main/java/org/dreeam/leaf/async/locate/AsyncLocator.java rename to leaf-archived-patches/removed/1.21.8/src/dreeam/leaf/async/locate/AsyncLocator.java diff --git a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/async/AsyncLocator.java b/leaf-archived-patches/removed/1.21.8/src/dreeam/leaf/config/modules/async/AsyncLocator.java similarity index 100% rename from leaf-server/src/main/java/org/dreeam/leaf/config/modules/async/AsyncLocator.java rename to leaf-archived-patches/removed/1.21.8/src/dreeam/leaf/config/modules/async/AsyncLocator.java diff --git a/leaf-server/minecraft-patches/features/0171-Smart-sort-entities-in-NearestLivingEntitySensor.patch b/leaf-server/minecraft-patches/features/0170-Smart-sort-entities-in-NearestLivingEntitySensor.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0171-Smart-sort-entities-in-NearestLivingEntitySensor.patch rename to leaf-server/minecraft-patches/features/0170-Smart-sort-entities-in-NearestLivingEntitySensor.patch diff --git a/leaf-server/minecraft-patches/features/0172-Further-reduce-memory-footprint-of-CompoundTag.patch b/leaf-server/minecraft-patches/features/0171-Further-reduce-memory-footprint-of-CompoundTag.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0172-Further-reduce-memory-footprint-of-CompoundTag.patch rename to leaf-server/minecraft-patches/features/0171-Further-reduce-memory-footprint-of-CompoundTag.patch diff --git a/leaf-server/minecraft-patches/features/0173-Optimize-Entity-distanceToSqr.patch b/leaf-server/minecraft-patches/features/0172-Optimize-Entity-distanceToSqr.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0173-Optimize-Entity-distanceToSqr.patch rename to leaf-server/minecraft-patches/features/0172-Optimize-Entity-distanceToSqr.patch diff --git a/leaf-server/minecraft-patches/features/0174-EMC-Don-t-use-snapshots-for-TileEntity-getOwner.patch b/leaf-server/minecraft-patches/features/0173-EMC-Don-t-use-snapshots-for-TileEntity-getOwner.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0174-EMC-Don-t-use-snapshots-for-TileEntity-getOwner.patch rename to leaf-server/minecraft-patches/features/0173-EMC-Don-t-use-snapshots-for-TileEntity-getOwner.patch diff --git a/leaf-server/minecraft-patches/features/0175-Cache-tile-entity-position.patch b/leaf-server/minecraft-patches/features/0174-Cache-tile-entity-position.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0175-Cache-tile-entity-position.patch rename to leaf-server/minecraft-patches/features/0174-Cache-tile-entity-position.patch diff --git a/leaf-server/minecraft-patches/features/0176-TT20-Lag-compensation.patch b/leaf-server/minecraft-patches/features/0175-TT20-Lag-compensation.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0176-TT20-Lag-compensation.patch rename to leaf-server/minecraft-patches/features/0175-TT20-Lag-compensation.patch diff --git a/leaf-server/minecraft-patches/features/0177-C2ME-Reduce-Allocations.patch b/leaf-server/minecraft-patches/features/0176-C2ME-Reduce-Allocations.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0177-C2ME-Reduce-Allocations.patch rename to leaf-server/minecraft-patches/features/0176-C2ME-Reduce-Allocations.patch diff --git a/leaf-server/minecraft-patches/features/0178-Lithium-Skip-unnecessary-calculations-if-player-is-n.patch b/leaf-server/minecraft-patches/features/0177-Lithium-Skip-unnecessary-calculations-if-player-is-n.patch similarity index 94% rename from leaf-server/minecraft-patches/features/0178-Lithium-Skip-unnecessary-calculations-if-player-is-n.patch rename to leaf-server/minecraft-patches/features/0177-Lithium-Skip-unnecessary-calculations-if-player-is-n.patch index cfee8e7a..c7a0e442 100644 --- a/leaf-server/minecraft-patches/features/0178-Lithium-Skip-unnecessary-calculations-if-player-is-n.patch +++ b/leaf-server/minecraft-patches/features/0177-Lithium-Skip-unnecessary-calculations-if-player-is-n.patch @@ -12,7 +12,7 @@ As part of: Lithium (https://github.com/CaffeineMC/lithium) Licensed under: LGPL-3.0 (https://www.gnu.org/licenses/lgpl-3.0.html) diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index de4d13e7c6f57d6cc3a78b1b9ca914157820186c..32f754a4c1d7a91bbbbf4995559ac2858ef10e1c 100644 +index 4f0b903945860e518ebf3c858722f28df9394b3d..0a253607733d7f31d0264931b20676c62a289e15 100644 --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java @@ -2825,6 +2825,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin diff --git a/leaf-server/minecraft-patches/features/0179-Lithium-fast-util.patch b/leaf-server/minecraft-patches/features/0178-Lithium-fast-util.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0179-Lithium-fast-util.patch rename to leaf-server/minecraft-patches/features/0178-Lithium-fast-util.patch diff --git a/leaf-server/minecraft-patches/features/0180-Lithium-cached-iterate-outwards.patch b/leaf-server/minecraft-patches/features/0179-Lithium-cached-iterate-outwards.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0180-Lithium-cached-iterate-outwards.patch rename to leaf-server/minecraft-patches/features/0179-Lithium-cached-iterate-outwards.patch diff --git a/leaf-server/minecraft-patches/features/0181-Use-faster-and-thread-safe-ban-list-date-format-pars.patch b/leaf-server/minecraft-patches/features/0180-Use-faster-and-thread-safe-ban-list-date-format-pars.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0181-Use-faster-and-thread-safe-ban-list-date-format-pars.patch rename to leaf-server/minecraft-patches/features/0180-Use-faster-and-thread-safe-ban-list-date-format-pars.patch diff --git a/leaf-server/minecraft-patches/features/0182-C2ME-Optimize-world-gen-math.patch b/leaf-server/minecraft-patches/features/0181-C2ME-Optimize-world-gen-math.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0182-C2ME-Optimize-world-gen-math.patch rename to leaf-server/minecraft-patches/features/0181-C2ME-Optimize-world-gen-math.patch diff --git a/leaf-server/minecraft-patches/features/0183-Cache-chunk-key.patch b/leaf-server/minecraft-patches/features/0182-Cache-chunk-key.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0183-Cache-chunk-key.patch rename to leaf-server/minecraft-patches/features/0182-Cache-chunk-key.patch diff --git a/leaf-server/minecraft-patches/features/0184-Cache-part-of-canHoldFluid-result.patch b/leaf-server/minecraft-patches/features/0183-Cache-part-of-canHoldFluid-result.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0184-Cache-part-of-canHoldFluid-result.patch rename to leaf-server/minecraft-patches/features/0183-Cache-part-of-canHoldFluid-result.patch diff --git a/leaf-server/minecraft-patches/features/0185-Configurable-tripwire-dupe.patch b/leaf-server/minecraft-patches/features/0184-Configurable-tripwire-dupe.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0185-Configurable-tripwire-dupe.patch rename to leaf-server/minecraft-patches/features/0184-Configurable-tripwire-dupe.patch diff --git a/leaf-server/minecraft-patches/features/0186-Paper-PR-Fix-MC-117075-Block-Entities-Unload-Lag-Spi.patch b/leaf-server/minecraft-patches/features/0185-Paper-PR-Fix-MC-117075-Block-Entities-Unload-Lag-Spi.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0186-Paper-PR-Fix-MC-117075-Block-Entities-Unload-Lag-Spi.patch rename to leaf-server/minecraft-patches/features/0185-Paper-PR-Fix-MC-117075-Block-Entities-Unload-Lag-Spi.patch diff --git a/leaf-server/minecraft-patches/features/0187-Sepals-Rearrange-the-attackable-conditions.patch b/leaf-server/minecraft-patches/features/0186-Sepals-Rearrange-the-attackable-conditions.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0187-Sepals-Rearrange-the-attackable-conditions.patch rename to leaf-server/minecraft-patches/features/0186-Sepals-Rearrange-the-attackable-conditions.patch diff --git a/leaf-server/minecraft-patches/features/0188-SparklyPaper-Skip-dirty-stats-copy-when-requesting-p.patch b/leaf-server/minecraft-patches/features/0187-SparklyPaper-Skip-dirty-stats-copy-when-requesting-p.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0188-SparklyPaper-Skip-dirty-stats-copy-when-requesting-p.patch rename to leaf-server/minecraft-patches/features/0187-SparklyPaper-Skip-dirty-stats-copy-when-requesting-p.patch diff --git a/leaf-server/minecraft-patches/features/0189-SparklyPaper-Reset-dirty-flag-when-loading-maps-from.patch b/leaf-server/minecraft-patches/features/0188-SparklyPaper-Reset-dirty-flag-when-loading-maps-from.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0189-SparklyPaper-Reset-dirty-flag-when-loading-maps-from.patch rename to leaf-server/minecraft-patches/features/0188-SparklyPaper-Reset-dirty-flag-when-loading-maps-from.patch diff --git a/leaf-server/minecraft-patches/features/0190-Optimize-checking-nearby-players-for-spawning.patch b/leaf-server/minecraft-patches/features/0189-Optimize-checking-nearby-players-for-spawning.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0190-Optimize-checking-nearby-players-for-spawning.patch rename to leaf-server/minecraft-patches/features/0189-Optimize-checking-nearby-players-for-spawning.patch diff --git a/leaf-server/minecraft-patches/features/0191-Avoid-useless-deque-clear-on-LevelTicks-cleanupAfter.patch b/leaf-server/minecraft-patches/features/0190-Avoid-useless-deque-clear-on-LevelTicks-cleanupAfter.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0191-Avoid-useless-deque-clear-on-LevelTicks-cleanupAfter.patch rename to leaf-server/minecraft-patches/features/0190-Avoid-useless-deque-clear-on-LevelTicks-cleanupAfter.patch diff --git a/leaf-server/minecraft-patches/features/0192-Remove-stream-in-villagers.patch b/leaf-server/minecraft-patches/features/0191-Remove-stream-in-villagers.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0192-Remove-stream-in-villagers.patch rename to leaf-server/minecraft-patches/features/0191-Remove-stream-in-villagers.patch diff --git a/leaf-server/minecraft-patches/features/0193-Optimize-baby-villager-sensor.patch b/leaf-server/minecraft-patches/features/0192-Optimize-baby-villager-sensor.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0193-Optimize-baby-villager-sensor.patch rename to leaf-server/minecraft-patches/features/0192-Optimize-baby-villager-sensor.patch diff --git a/leaf-server/minecraft-patches/features/0194-Only-player-pushable.patch b/leaf-server/minecraft-patches/features/0193-Only-player-pushable.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0194-Only-player-pushable.patch rename to leaf-server/minecraft-patches/features/0193-Only-player-pushable.patch diff --git a/leaf-server/minecraft-patches/features/0195-Remove-iterators-from-Inventory.patch b/leaf-server/minecraft-patches/features/0194-Remove-iterators-from-Inventory.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0195-Remove-iterators-from-Inventory.patch rename to leaf-server/minecraft-patches/features/0194-Remove-iterators-from-Inventory.patch diff --git a/leaf-server/minecraft-patches/features/0196-optimize-mob-despawn.patch b/leaf-server/minecraft-patches/features/0195-optimize-mob-despawn.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0196-optimize-mob-despawn.patch rename to leaf-server/minecraft-patches/features/0195-optimize-mob-despawn.patch diff --git a/leaf-server/minecraft-patches/features/0197-Slightly-optimise-getNearestPlayer.patch b/leaf-server/minecraft-patches/features/0196-Slightly-optimise-getNearestPlayer.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0197-Slightly-optimise-getNearestPlayer.patch rename to leaf-server/minecraft-patches/features/0196-Slightly-optimise-getNearestPlayer.patch diff --git a/leaf-server/minecraft-patches/features/0198-Bulk-writes-to-writeLongArray-during-chunk-loading.patch b/leaf-server/minecraft-patches/features/0197-Bulk-writes-to-writeLongArray-during-chunk-loading.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0198-Bulk-writes-to-writeLongArray-during-chunk-loading.patch rename to leaf-server/minecraft-patches/features/0197-Bulk-writes-to-writeLongArray-during-chunk-loading.patch diff --git a/leaf-server/minecraft-patches/features/0199-Improve-sorting-in-SortedArraySet.patch b/leaf-server/minecraft-patches/features/0198-Improve-sorting-in-SortedArraySet.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0199-Improve-sorting-in-SortedArraySet.patch rename to leaf-server/minecraft-patches/features/0198-Improve-sorting-in-SortedArraySet.patch diff --git a/leaf-server/minecraft-patches/features/0200-Make-removeIf-slightly-faster.patch b/leaf-server/minecraft-patches/features/0199-Make-removeIf-slightly-faster.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0200-Make-removeIf-slightly-faster.patch rename to leaf-server/minecraft-patches/features/0199-Make-removeIf-slightly-faster.patch diff --git a/leaf-server/minecraft-patches/features/0201-Optimize-LinearPalette.patch b/leaf-server/minecraft-patches/features/0200-Optimize-LinearPalette.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0201-Optimize-LinearPalette.patch rename to leaf-server/minecraft-patches/features/0200-Optimize-LinearPalette.patch diff --git a/leaf-server/minecraft-patches/features/0202-Slightly-optimized-VarInt-write.patch b/leaf-server/minecraft-patches/features/0201-Slightly-optimized-VarInt-write.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0202-Slightly-optimized-VarInt-write.patch rename to leaf-server/minecraft-patches/features/0201-Slightly-optimized-VarInt-write.patch diff --git a/leaf-server/minecraft-patches/features/0203-Rewrite-ClientboundLightUpdatePacketData.patch b/leaf-server/minecraft-patches/features/0202-Rewrite-ClientboundLightUpdatePacketData.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0203-Rewrite-ClientboundLightUpdatePacketData.patch rename to leaf-server/minecraft-patches/features/0202-Rewrite-ClientboundLightUpdatePacketData.patch diff --git a/leaf-server/minecraft-patches/features/0204-Async-chunk-sending.patch b/leaf-server/minecraft-patches/features/0203-Async-chunk-sending.patch similarity index 92% rename from leaf-server/minecraft-patches/features/0204-Async-chunk-sending.patch rename to leaf-server/minecraft-patches/features/0203-Async-chunk-sending.patch index 2164ec32..220def8a 100644 --- a/leaf-server/minecraft-patches/features/0204-Async-chunk-sending.patch +++ b/leaf-server/minecraft-patches/features/0203-Async-chunk-sending.patch @@ -173,16 +173,3 @@ index 0376a10ee0544b13e8fd629a7b13f78811e57a30..aa6b900347635857b84460fa8435b81f // Paper end - Anti-Xray // Paper start - PlayerChunkLoadEvent if (io.papermc.paper.event.packet.PlayerChunkLoadEvent.getHandlerList().getRegisteredListeners().length > 0) { -diff --git a/net/minecraft/world/level/chunk/LevelChunkSection.java b/net/minecraft/world/level/chunk/LevelChunkSection.java -index df717c545472006b99532280c38c1fbef12bcf82..7689e005a7de17fa0411a346f595f40b06bb5ca4 100644 ---- a/net/minecraft/world/level/chunk/LevelChunkSection.java -+++ b/net/minecraft/world/level/chunk/LevelChunkSection.java -@@ -18,7 +18,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ - public static final int SECTION_HEIGHT = 16; - public static final int SECTION_SIZE = 4096; - public static final int BIOME_CONTAINER_BITS = 2; -- short nonEmptyBlockCount; // Paper - package private -+ volatile short nonEmptyBlockCount; // Paper - package private // Leaf - Async chunk sending - volatile - private short tickingBlockCount; - private short tickingFluidCount; - public final PalettedContainer states; diff --git a/leaf-server/minecraft-patches/features/0205-Spawner-Configurations.patch b/leaf-server/minecraft-patches/features/0204-Spawner-Configurations.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0205-Spawner-Configurations.patch rename to leaf-server/minecraft-patches/features/0204-Spawner-Configurations.patch diff --git a/leaf-server/minecraft-patches/features/0206-SparklyPaper-Parallel-world-ticking.patch b/leaf-server/minecraft-patches/features/0205-SparklyPaper-Parallel-world-ticking.patch similarity index 99% rename from leaf-server/minecraft-patches/features/0206-SparklyPaper-Parallel-world-ticking.patch rename to leaf-server/minecraft-patches/features/0205-SparklyPaper-Parallel-world-ticking.patch index bf1dcea7..5e967672 100644 --- a/leaf-server/minecraft-patches/features/0206-SparklyPaper-Parallel-world-ticking.patch +++ b/leaf-server/minecraft-patches/features/0205-SparklyPaper-Parallel-world-ticking.patch @@ -411,7 +411,7 @@ index 77f11179836636424927843f5f10c3fd23d2b2d4..9b8d119116b0c3a51d3fe2ff7efb33cc // Gale start - Pufferfish - SIMD support diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java -index 8f41326fda8c5f9f6926038508be6c6529b051bc..f76da1dc0874493ce71fce19e02e68da5f3ff50d 100644 +index eaaa66c4d86d4ebda0acf8f1dbe8ecb55aa28285..3a6c894178829cec8daa08ea9f0294f7f39a8efe 100644 --- a/net/minecraft/server/level/ServerChunkCache.java +++ b/net/minecraft/server/level/ServerChunkCache.java @@ -175,6 +175,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon diff --git a/leaf-server/minecraft-patches/features/0207-SparklyPaper-Track-each-world-MSPT.patch b/leaf-server/minecraft-patches/features/0206-SparklyPaper-Track-each-world-MSPT.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0207-SparklyPaper-Track-each-world-MSPT.patch rename to leaf-server/minecraft-patches/features/0206-SparklyPaper-Track-each-world-MSPT.patch diff --git a/leaf-server/minecraft-patches/features/0208-Paper-PR-Fix-cancelled-Projectile-Events-still-consu.patch b/leaf-server/minecraft-patches/features/0207-Paper-PR-Fix-cancelled-Projectile-Events-still-consu.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0208-Paper-PR-Fix-cancelled-Projectile-Events-still-consu.patch rename to leaf-server/minecraft-patches/features/0207-Paper-PR-Fix-cancelled-Projectile-Events-still-consu.patch diff --git a/leaf-server/minecraft-patches/features/0209-Optimize-SetLookAndInteract-and-NearestVisibleLiving.patch b/leaf-server/minecraft-patches/features/0208-Optimize-SetLookAndInteract-and-NearestVisibleLiving.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0209-Optimize-SetLookAndInteract-and-NearestVisibleLiving.patch rename to leaf-server/minecraft-patches/features/0208-Optimize-SetLookAndInteract-and-NearestVisibleLiving.patch diff --git a/leaf-server/minecraft-patches/features/0210-rewrite-InsideBrownianWalk.patch b/leaf-server/minecraft-patches/features/0209-rewrite-InsideBrownianWalk.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0210-rewrite-InsideBrownianWalk.patch rename to leaf-server/minecraft-patches/features/0209-rewrite-InsideBrownianWalk.patch diff --git a/leaf-server/minecraft-patches/features/0211-Use-BFS-on-getSlopeDistance.patch b/leaf-server/minecraft-patches/features/0210-Use-BFS-on-getSlopeDistance.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0211-Use-BFS-on-getSlopeDistance.patch rename to leaf-server/minecraft-patches/features/0210-Use-BFS-on-getSlopeDistance.patch diff --git a/leaf-server/minecraft-patches/features/0212-Paper-PR-Throttle-failed-spawn-attempts.patch b/leaf-server/minecraft-patches/features/0211-Paper-PR-Throttle-failed-spawn-attempts.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0212-Paper-PR-Throttle-failed-spawn-attempts.patch rename to leaf-server/minecraft-patches/features/0211-Paper-PR-Throttle-failed-spawn-attempts.patch diff --git a/leaf-server/minecraft-patches/features/0213-Improve-BlockEntity-ticking-isRemoved-check.patch b/leaf-server/minecraft-patches/features/0212-Improve-BlockEntity-ticking-isRemoved-check.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0213-Improve-BlockEntity-ticking-isRemoved-check.patch rename to leaf-server/minecraft-patches/features/0212-Improve-BlockEntity-ticking-isRemoved-check.patch diff --git a/leaf-server/minecraft-patches/features/0214-Raytrace-AntiXray-SDK-integration.patch b/leaf-server/minecraft-patches/features/0213-Raytrace-AntiXray-SDK-integration.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0214-Raytrace-AntiXray-SDK-integration.patch rename to leaf-server/minecraft-patches/features/0213-Raytrace-AntiXray-SDK-integration.patch diff --git a/leaf-server/minecraft-patches/features/0215-Optimize-ContextMap.create.patch b/leaf-server/minecraft-patches/features/0214-Optimize-ContextMap.create.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0215-Optimize-ContextMap.create.patch rename to leaf-server/minecraft-patches/features/0214-Optimize-ContextMap.create.patch diff --git a/leaf-server/minecraft-patches/features/0216-Micro-optimizations-for-random-tick.patch b/leaf-server/minecraft-patches/features/0215-Micro-optimizations-for-random-tick.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0216-Micro-optimizations-for-random-tick.patch rename to leaf-server/minecraft-patches/features/0215-Micro-optimizations-for-random-tick.patch diff --git a/leaf-server/minecraft-patches/features/0217-Remove-streams-on-updateConnectedPlayersWithinRange.patch b/leaf-server/minecraft-patches/features/0216-Remove-streams-on-updateConnectedPlayersWithinRange.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0217-Remove-streams-on-updateConnectedPlayersWithinRange.patch rename to leaf-server/minecraft-patches/features/0216-Remove-streams-on-updateConnectedPlayersWithinRange.patch diff --git a/leaf-server/minecraft-patches/features/0218-Remove-streams-on-PlayerDetector.patch b/leaf-server/minecraft-patches/features/0217-Remove-streams-on-PlayerDetector.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0218-Remove-streams-on-PlayerDetector.patch rename to leaf-server/minecraft-patches/features/0217-Remove-streams-on-PlayerDetector.patch diff --git a/leaf-server/minecraft-patches/features/0219-Use-direct-iteration-on-Sensing.tick.patch b/leaf-server/minecraft-patches/features/0218-Use-direct-iteration-on-Sensing.tick.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0219-Use-direct-iteration-on-Sensing.tick.patch rename to leaf-server/minecraft-patches/features/0218-Use-direct-iteration-on-Sensing.tick.patch diff --git a/leaf-server/minecraft-patches/features/0220-Optimise-non-flush-packet-sending.patch b/leaf-server/minecraft-patches/features/0219-Optimise-non-flush-packet-sending.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0220-Optimise-non-flush-packet-sending.patch rename to leaf-server/minecraft-patches/features/0219-Optimise-non-flush-packet-sending.patch diff --git a/leaf-server/minecraft-patches/features/0221-Prevent-double-chunk-retrieving-in-entity-fluid-push.patch b/leaf-server/minecraft-patches/features/0220-Prevent-double-chunk-retrieving-in-entity-fluid-push.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0221-Prevent-double-chunk-retrieving-in-entity-fluid-push.patch rename to leaf-server/minecraft-patches/features/0220-Prevent-double-chunk-retrieving-in-entity-fluid-push.patch diff --git a/leaf-server/minecraft-patches/features/0222-Null-handling-on-MultifaceSpreader.patch b/leaf-server/minecraft-patches/features/0221-Null-handling-on-MultifaceSpreader.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0222-Null-handling-on-MultifaceSpreader.patch rename to leaf-server/minecraft-patches/features/0221-Null-handling-on-MultifaceSpreader.patch diff --git a/leaf-server/minecraft-patches/features/0223-More-virtual-threads.patch b/leaf-server/minecraft-patches/features/0222-More-virtual-threads.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0223-More-virtual-threads.patch rename to leaf-server/minecraft-patches/features/0222-More-virtual-threads.patch diff --git a/leaf-server/minecraft-patches/features/0224-Optimize-ThreadedTicketLevelPropagator.patch b/leaf-server/minecraft-patches/features/0223-Optimize-ThreadedTicketLevelPropagator.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0224-Optimize-ThreadedTicketLevelPropagator.patch rename to leaf-server/minecraft-patches/features/0223-Optimize-ThreadedTicketLevelPropagator.patch diff --git a/leaf-server/minecraft-patches/features/0225-Optimise-MobEffectUtil-getDigSpeedAmplification.patch b/leaf-server/minecraft-patches/features/0224-Optimise-MobEffectUtil-getDigSpeedAmplification.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0225-Optimise-MobEffectUtil-getDigSpeedAmplification.patch rename to leaf-server/minecraft-patches/features/0224-Optimise-MobEffectUtil-getDigSpeedAmplification.patch diff --git a/leaf-server/minecraft-patches/features/0226-Optimise-chunkUnloads.patch b/leaf-server/minecraft-patches/features/0225-Optimise-chunkUnloads.patch similarity index 99% rename from leaf-server/minecraft-patches/features/0226-Optimise-chunkUnloads.patch rename to leaf-server/minecraft-patches/features/0225-Optimise-chunkUnloads.patch index 106ef43f..38194c1c 100644 --- a/leaf-server/minecraft-patches/features/0226-Optimise-chunkUnloads.patch +++ b/leaf-server/minecraft-patches/features/0225-Optimise-chunkUnloads.patch @@ -159,7 +159,7 @@ index 4ca68a903e67606fc4ef0bfa9862a73797121c8b..bed3a64388bb43e47c2ba4e67f7dde5b public static final class SaveState { diff --git a/net/minecraft/world/level/chunk/LevelChunkSection.java b/net/minecraft/world/level/chunk/LevelChunkSection.java -index 7689e005a7de17fa0411a346f595f40b06bb5ca4..5c5d51d5341dac68f89253c5181e1a099c305fac 100644 +index df717c545472006b99532280c38c1fbef12bcf82..abb7c8b4ffc73cedd5e03597fe82c71e51161a1b 100644 --- a/net/minecraft/world/level/chunk/LevelChunkSection.java +++ b/net/minecraft/world/level/chunk/LevelChunkSection.java @@ -23,6 +23,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ diff --git a/leaf-server/minecraft-patches/features/0227-Optimize-BlockEntityType-isValid.patch b/leaf-server/minecraft-patches/features/0226-Optimize-BlockEntityType-isValid.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0227-Optimize-BlockEntityType-isValid.patch rename to leaf-server/minecraft-patches/features/0226-Optimize-BlockEntityType-isValid.patch diff --git a/leaf-server/minecraft-patches/features/0228-Paper-PR-Add-ticket-on-player-join-to-avoid-chunk-lo.patch b/leaf-server/minecraft-patches/features/0227-Paper-PR-Add-ticket-on-player-join-to-avoid-chunk-lo.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0228-Paper-PR-Add-ticket-on-player-join-to-avoid-chunk-lo.patch rename to leaf-server/minecraft-patches/features/0227-Paper-PR-Add-ticket-on-player-join-to-avoid-chunk-lo.patch diff --git a/leaf-server/minecraft-patches/features/0229-Sakura-Optimise-check-inside-blocks-and-traverse-blo.patch b/leaf-server/minecraft-patches/features/0228-Sakura-Optimise-check-inside-blocks-and-traverse-blo.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0229-Sakura-Optimise-check-inside-blocks-and-traverse-blo.patch rename to leaf-server/minecraft-patches/features/0228-Sakura-Optimise-check-inside-blocks-and-traverse-blo.patch diff --git a/leaf-server/minecraft-patches/features/0230-Sakura-copy-EntityList-implementation-to-BasicEntity.patch b/leaf-server/minecraft-patches/features/0229-Sakura-copy-EntityList-implementation-to-BasicEntity.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0230-Sakura-copy-EntityList-implementation-to-BasicEntity.patch rename to leaf-server/minecraft-patches/features/0229-Sakura-copy-EntityList-implementation-to-BasicEntity.patch diff --git a/leaf-server/minecraft-patches/features/0231-Protocol-Core.patch b/leaf-server/minecraft-patches/features/0230-Protocol-Core.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0231-Protocol-Core.patch rename to leaf-server/minecraft-patches/features/0230-Protocol-Core.patch diff --git a/leaf-server/minecraft-patches/features/0232-Async-switch-connection-state.patch b/leaf-server/minecraft-patches/features/0231-Async-switch-connection-state.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0232-Async-switch-connection-state.patch rename to leaf-server/minecraft-patches/features/0231-Async-switch-connection-state.patch diff --git a/leaf-server/minecraft-patches/features/0233-Optimize-BlockEntities-tickersInLevel.patch b/leaf-server/minecraft-patches/features/0232-Optimize-BlockEntities-tickersInLevel.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0233-Optimize-BlockEntities-tickersInLevel.patch rename to leaf-server/minecraft-patches/features/0232-Optimize-BlockEntities-tickersInLevel.patch diff --git a/leaf-server/minecraft-patches/features/0234-Pluto-Check-if-the-cactus-can-even-survive-being-pla.patch b/leaf-server/minecraft-patches/features/0233-Pluto-Check-if-the-cactus-can-even-survive-being-pla.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0234-Pluto-Check-if-the-cactus-can-even-survive-being-pla.patch rename to leaf-server/minecraft-patches/features/0233-Pluto-Check-if-the-cactus-can-even-survive-being-pla.patch diff --git a/leaf-server/minecraft-patches/features/0235-Flush-location-while-knockback.patch b/leaf-server/minecraft-patches/features/0234-Flush-location-while-knockback.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0235-Flush-location-while-knockback.patch rename to leaf-server/minecraft-patches/features/0234-Flush-location-while-knockback.patch diff --git a/leaf-server/minecraft-patches/features/0236-Only-tick-items-at-hand.patch b/leaf-server/minecraft-patches/features/0235-Only-tick-items-at-hand.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0236-Only-tick-items-at-hand.patch rename to leaf-server/minecraft-patches/features/0235-Only-tick-items-at-hand.patch diff --git a/leaf-server/minecraft-patches/features/0237-Smart-sort-items-in-NearestItemSensor.patch b/leaf-server/minecraft-patches/features/0236-Smart-sort-items-in-NearestItemSensor.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0237-Smart-sort-items-in-NearestItemSensor.patch rename to leaf-server/minecraft-patches/features/0236-Smart-sort-items-in-NearestItemSensor.patch diff --git a/leaf-server/minecraft-patches/features/0238-Optimise-player-movement-checks.patch b/leaf-server/minecraft-patches/features/0237-Optimise-player-movement-checks.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0238-Optimise-player-movement-checks.patch rename to leaf-server/minecraft-patches/features/0237-Optimise-player-movement-checks.patch diff --git a/leaf-server/minecraft-patches/features/0239-Remove-streams-in-MobSensor.patch b/leaf-server/minecraft-patches/features/0238-Remove-streams-in-MobSensor.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0239-Remove-streams-in-MobSensor.patch rename to leaf-server/minecraft-patches/features/0238-Remove-streams-in-MobSensor.patch diff --git a/leaf-server/minecraft-patches/features/0240-Remove-streams-in-TemptingSensor.patch b/leaf-server/minecraft-patches/features/0239-Remove-streams-in-TemptingSensor.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0240-Remove-streams-in-TemptingSensor.patch rename to leaf-server/minecraft-patches/features/0239-Remove-streams-in-TemptingSensor.patch diff --git a/leaf-server/minecraft-patches/features/0241-Use-HashedList-on-WeightedList.patch b/leaf-server/minecraft-patches/features/0240-Use-HashedList-on-WeightedList.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0241-Use-HashedList-on-WeightedList.patch rename to leaf-server/minecraft-patches/features/0240-Use-HashedList-on-WeightedList.patch diff --git a/leaf-server/minecraft-patches/features/0242-Add-configurable-death-item-drop-knockback-settings.patch b/leaf-server/minecraft-patches/features/0241-Add-configurable-death-item-drop-knockback-settings.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0242-Add-configurable-death-item-drop-knockback-settings.patch rename to leaf-server/minecraft-patches/features/0241-Add-configurable-death-item-drop-knockback-settings.patch diff --git a/leaf-server/minecraft-patches/features/0243-Optimize-getScaledTrackingDistance.patch b/leaf-server/minecraft-patches/features/0242-Optimize-getScaledTrackingDistance.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0243-Optimize-getScaledTrackingDistance.patch rename to leaf-server/minecraft-patches/features/0242-Optimize-getScaledTrackingDistance.patch diff --git a/leaf-server/minecraft-patches/features/0244-Optimize-SynchedEntityData-packDirty.patch b/leaf-server/minecraft-patches/features/0243-Optimize-SynchedEntityData-packDirty.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0244-Optimize-SynchedEntityData-packDirty.patch rename to leaf-server/minecraft-patches/features/0243-Optimize-SynchedEntityData-packDirty.patch diff --git a/leaf-server/minecraft-patches/features/0245-Optimize-isEyeInFluid.patch b/leaf-server/minecraft-patches/features/0244-Optimize-isEyeInFluid.patch similarity index 74% rename from leaf-server/minecraft-patches/features/0245-Optimize-isEyeInFluid.patch rename to leaf-server/minecraft-patches/features/0244-Optimize-isEyeInFluid.patch index 484722e2..d54e9dda 100644 --- a/leaf-server/minecraft-patches/features/0245-Optimize-isEyeInFluid.patch +++ b/leaf-server/minecraft-patches/features/0244-Optimize-isEyeInFluid.patch @@ -4,80 +4,6 @@ Date: Sat, 17 May 2025 08:25:33 +0800 Subject: [PATCH] Optimize isEyeInFluid -diff --git a/net/minecraft/core/Holder.java b/net/minecraft/core/Holder.java -index 6c7edbbf3935c40ccb78bee680ea75431718b9bd..fd2f79d976c9587b00380f8b8f784b32ca294673 100644 ---- a/net/minecraft/core/Holder.java -+++ b/net/minecraft/core/Holder.java -@@ -29,6 +29,8 @@ public interface Holder { - - Stream> tags(); - -+ TagKey[] tagArray(); // Leaf - Optimize isEyeInFluid -+ - Either, T> unwrap(); - - Optional> unwrapKey(); -@@ -105,6 +107,13 @@ public interface Holder { - public Stream> tags() { - return Stream.of(); - } -+ -+ // Leaf start - Optimize isEyeInFluid -+ @Override -+ public TagKey[] tagArray() { -+ return me.titaniumtown.ArrayConstants.emptyTagKeyArray; -+ } -+ // Leaf end - Optimize isEyeInFluid - } - - public static enum Kind { -@@ -116,6 +125,7 @@ public interface Holder { - private final HolderOwner owner; - @Nullable - private Set> tags; -+ @Nullable private TagKey[] tagArray; // Leaf - Optimize isEyeInFluid - private final Holder.Reference.Type type; - @Nullable - private ResourceKey key; -@@ -173,6 +183,16 @@ public interface Holder { - } - } - -+ // Leaf start - Optimize isEyeInFluid -+ private TagKey[] boundTagArray() { -+ if (this.tags == null || this.tagArray == null) { -+ throw new IllegalStateException("Tags not bound"); -+ } else { -+ return this.tagArray; -+ } -+ } -+ // Leaf end - Optimize isEyeInFluid -+ - @Override - public boolean is(TagKey tagKey) { - return this.boundTags().contains(tagKey); -@@ -231,6 +251,7 @@ public interface Holder { - - void bindTags(Collection> tags) { - this.tags = it.unimi.dsi.fastutil.objects.ReferenceSets.unmodifiable(new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(tags)); // Paper - use reference set because TagKey are interned -+ this.tagArray = this.tags.toArray(new TagKey[0]); // Leaf - Optimize isEyeInFluid - } - - @Override -@@ -238,6 +259,13 @@ public interface Holder { - return this.boundTags().stream(); - } - -+ // Leaf start - Optimize isEyeInFluid -+ @Override -+ public TagKey[] tagArray() { -+ return this.boundTagArray(); -+ } -+ // Leaf end - Optimize isEyeInFluid -+ - @Override - public String toString() { - return "Reference{" + this.key + "=" + this.value + "}"; diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java index f2ec8dafb133999bed21eb48b118ab5d382bc962..a26943a7c70ac8b8eb3be5cd1f9838e4fcc6e04e 100644 --- a/net/minecraft/server/level/ServerPlayer.java @@ -92,7 +18,7 @@ index f2ec8dafb133999bed21eb48b118ab5d382bc962..a26943a7c70ac8b8eb3be5cd1f9838e4 if (rounded > 0) { this.awardStat(Stats.WALK_UNDER_WATER_ONE_CM, rounded); diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index b694c7c1837fd4facb16d6bcf93245da9d18a56d..2f9304c4fc7ac9f42493bc19748ee6c0f57208ee 100644 +index b694c7c1837fd4facb16d6bcf93245da9d18a56d..48c2aeee828c1b79d8d6c5f5fd88fae1ef4befc8 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -288,7 +288,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -122,19 +48,18 @@ index b694c7c1837fd4facb16d6bcf93245da9d18a56d..2f9304c4fc7ac9f42493bc19748ee6c0 double eyeY = this.getEyeY(); if (!( this.getVehicle() instanceof AbstractBoat abstractBoat -@@ -2051,7 +2058,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2051,7 +2058,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess FluidState fluidState = this.level().getFluidState(blockPos); double d = blockPos.getY() + fluidState.getHeight(this.level(), blockPos); if (d > eyeY) { - fluidState.getTags().forEach(this.fluidOnEyes::add); + // Leaf start - Optimize isEyeInFluid -+ TagKey[] tags = fluidState.getTagArray(); -+ this.isInWaterOrLava = tags.length == 0 ? 0 : tags[0] == FluidTags.WATER ? 1 : 2; ++ this.isInWaterOrLava = fluidState.isEmpty() ? 0 : fluidState.is(FluidTags.WATER) ? 1 : 2; + // Leaf end - Optimize isEyeInFluid } } } -@@ -2131,9 +2141,25 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2131,9 +2140,25 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } } @@ -297,20 +222,3 @@ index d947801b616af5b5dcdcc8bb70b36f97d6a69fdd..678badf7622b81e94c973bed2082fbfa } protected int getMaxPassengers() { -diff --git a/net/minecraft/world/level/material/FluidState.java b/net/minecraft/world/level/material/FluidState.java -index 0a5ae623a636923f3bbd3c01974497f39b7c4b62..cc6f2f756c407630aa4e99be329f643c9994af29 100644 ---- a/net/minecraft/world/level/material/FluidState.java -+++ b/net/minecraft/world/level/material/FluidState.java -@@ -167,6 +167,12 @@ public final class FluidState extends StateHolder implements - return this.owner.builtInRegistryHolder().tags(); - } - -+ // Leaf start - Optimize isEyeInFluid -+ public TagKey[] getTagArray() { -+ return this.owner.builtInRegistryHolder().tagArray(); -+ } -+ // Leaf end - Optimize isEyeInFluid -+ - public void entityInside(Level level, BlockPos pos, Entity entity, InsideBlockEffectApplier effectApplier) { - this.getType().entityInside(level, pos, entity, effectApplier); - } diff --git a/leaf-server/minecraft-patches/features/0246-Cache-block-state-tags.patch b/leaf-server/minecraft-patches/features/0245-Cache-block-state-tags.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0246-Cache-block-state-tags.patch rename to leaf-server/minecraft-patches/features/0245-Cache-block-state-tags.patch diff --git a/leaf-server/minecraft-patches/features/0247-optimize-getEntityStatus.patch b/leaf-server/minecraft-patches/features/0246-optimize-getEntityStatus.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0247-optimize-getEntityStatus.patch rename to leaf-server/minecraft-patches/features/0246-optimize-getEntityStatus.patch diff --git a/leaf-server/minecraft-patches/features/0248-Rail-Optimization-optimized-PoweredRailBlock-logic.patch b/leaf-server/minecraft-patches/features/0247-Rail-Optimization-optimized-PoweredRailBlock-logic.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0248-Rail-Optimization-optimized-PoweredRailBlock-logic.patch rename to leaf-server/minecraft-patches/features/0247-Rail-Optimization-optimized-PoweredRailBlock-logic.patch diff --git a/leaf-server/minecraft-patches/features/0249-optimise-ChunkGenerator-getMobsAt.patch b/leaf-server/minecraft-patches/features/0248-optimise-ChunkGenerator-getMobsAt.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0249-optimise-ChunkGenerator-getMobsAt.patch rename to leaf-server/minecraft-patches/features/0248-optimise-ChunkGenerator-getMobsAt.patch diff --git a/leaf-server/minecraft-patches/features/0250-cache-getBiome.patch b/leaf-server/minecraft-patches/features/0249-cache-getBiome.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0250-cache-getBiome.patch rename to leaf-server/minecraft-patches/features/0249-cache-getBiome.patch diff --git a/leaf-server/minecraft-patches/features/0251-optimize-mob-spawning.patch b/leaf-server/minecraft-patches/features/0250-optimize-mob-spawning.patch similarity index 99% rename from leaf-server/minecraft-patches/features/0251-optimize-mob-spawning.patch rename to leaf-server/minecraft-patches/features/0250-optimize-mob-spawning.patch index 3a022492..82da7def 100644 --- a/leaf-server/minecraft-patches/features/0251-optimize-mob-spawning.patch +++ b/leaf-server/minecraft-patches/features/0250-optimize-mob-spawning.patch @@ -26,7 +26,7 @@ index 5c369b3d94e369c3f240821ad90b9d96223f24ca..9803c395fce103cb7bc746f43a017ff9 } // Paper end - Optional per player mob spawns diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java -index f76da1dc0874493ce71fce19e02e68da5f3ff50d..8b9d7129da577d7b613c0e21ee075e68edef7b12 100644 +index 3a6c894178829cec8daa08ea9f0294f7f39a8efe..8bf770fd490634787e794efec9f0d6a10d97e42f 100644 --- a/net/minecraft/server/level/ServerChunkCache.java +++ b/net/minecraft/server/level/ServerChunkCache.java @@ -70,11 +70,11 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon diff --git a/leaf-server/minecraft-patches/features/0252-optimize-structure-map.patch b/leaf-server/minecraft-patches/features/0251-optimize-structure-map.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0252-optimize-structure-map.patch rename to leaf-server/minecraft-patches/features/0251-optimize-structure-map.patch diff --git a/leaf-server/minecraft-patches/features/0253-throttle-mob-spawning.patch b/leaf-server/minecraft-patches/features/0252-throttle-mob-spawning.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0253-throttle-mob-spawning.patch rename to leaf-server/minecraft-patches/features/0252-throttle-mob-spawning.patch diff --git a/leaf-server/minecraft-patches/features/0254-Add-BlockExplosionHitEvent.patch b/leaf-server/minecraft-patches/features/0253-Add-BlockExplosionHitEvent.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0254-Add-BlockExplosionHitEvent.patch rename to leaf-server/minecraft-patches/features/0253-Add-BlockExplosionHitEvent.patch diff --git a/leaf-server/minecraft-patches/features/0255-Old-Blast-Protection-explosion-knockback.patch b/leaf-server/minecraft-patches/features/0254-Old-Blast-Protection-explosion-knockback.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0255-Old-Blast-Protection-explosion-knockback.patch rename to leaf-server/minecraft-patches/features/0254-Old-Blast-Protection-explosion-knockback.patch diff --git a/leaf-server/minecraft-patches/features/0256-Use-UUID-for-cure-reputation.patch b/leaf-server/minecraft-patches/features/0255-Use-UUID-for-cure-reputation.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0256-Use-UUID-for-cure-reputation.patch rename to leaf-server/minecraft-patches/features/0255-Use-UUID-for-cure-reputation.patch diff --git a/leaf-server/minecraft-patches/features/0257-Fix-crash-during-parsing-unknown-command-message.patch b/leaf-server/minecraft-patches/features/0256-Fix-crash-during-parsing-unknown-command-message.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0257-Fix-crash-during-parsing-unknown-command-message.patch rename to leaf-server/minecraft-patches/features/0256-Fix-crash-during-parsing-unknown-command-message.patch diff --git a/leaf-server/minecraft-patches/features/0258-optimize-random-tick.patch b/leaf-server/minecraft-patches/features/0257-optimize-random-tick.patch similarity index 97% rename from leaf-server/minecraft-patches/features/0258-optimize-random-tick.patch rename to leaf-server/minecraft-patches/features/0257-optimize-random-tick.patch index af53b5ca..c8a0a6dd 100644 --- a/leaf-server/minecraft-patches/features/0258-optimize-random-tick.patch +++ b/leaf-server/minecraft-patches/features/0257-optimize-random-tick.patch @@ -5,7 +5,7 @@ Subject: [PATCH] optimize random tick diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java -index 8b9d7129da577d7b613c0e21ee075e68edef7b12..8d074d2adf36827bc7c38a5f4efe4771453631b8 100644 +index 8bf770fd490634787e794efec9f0d6a10d97e42f..7e84b94a4602801e8cc713b28d0d93052589fd5e 100644 --- a/net/minecraft/server/level/ServerChunkCache.java +++ b/net/minecraft/server/level/ServerChunkCache.java @@ -666,7 +666,13 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon diff --git a/leaf-server/minecraft-patches/features/0259-do-not-log-invalid-flatten-text-component-parse.patch b/leaf-server/minecraft-patches/features/0258-do-not-log-invalid-flatten-text-component-parse.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0259-do-not-log-invalid-flatten-text-component-parse.patch rename to leaf-server/minecraft-patches/features/0258-do-not-log-invalid-flatten-text-component-parse.patch diff --git a/leaf-server/minecraft-patches/features/0260-Fast-BiomeManager-seed-obfuscation.patch b/leaf-server/minecraft-patches/features/0259-Fast-BiomeManager-seed-obfuscation.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0260-Fast-BiomeManager-seed-obfuscation.patch rename to leaf-server/minecraft-patches/features/0259-Fast-BiomeManager-seed-obfuscation.patch diff --git a/leaf-server/minecraft-patches/features/0261-Replace-EntitySelectorOptions-map-with-optimized-col.patch b/leaf-server/minecraft-patches/features/0260-Replace-EntitySelectorOptions-map-with-optimized-col.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0261-Replace-EntitySelectorOptions-map-with-optimized-col.patch rename to leaf-server/minecraft-patches/features/0260-Replace-EntitySelectorOptions-map-with-optimized-col.patch diff --git a/leaf-server/minecraft-patches/features/0262-optimize-no-action-time.patch b/leaf-server/minecraft-patches/features/0261-optimize-no-action-time.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0262-optimize-no-action-time.patch rename to leaf-server/minecraft-patches/features/0261-optimize-no-action-time.patch diff --git a/leaf-server/minecraft-patches/features/0263-optimize-waypoint.patch b/leaf-server/minecraft-patches/features/0262-optimize-waypoint.patch similarity index 65% rename from leaf-server/minecraft-patches/features/0263-optimize-waypoint.patch rename to leaf-server/minecraft-patches/features/0262-optimize-waypoint.patch index f4794064..600334f1 100644 --- a/leaf-server/minecraft-patches/features/0263-optimize-waypoint.patch +++ b/leaf-server/minecraft-patches/features/0262-optimize-waypoint.patch @@ -5,28 +5,20 @@ Subject: [PATCH] optimize waypoint diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 2f9304c4fc7ac9f42493bc19748ee6c0f57208ee..5d4350dbe1d4189e17de77586a342c4ed0087c13 100644 +index 48c2aeee828c1b79d8d6c5f5fd88fae1ef4befc8..b71acd053b38d9b59720e35e664f957df6626b27 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -5112,6 +5112,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - return; - } - // Paper end - Block invalid positions and bounding box -+ boolean blockUpdated; // Leaf - optimize waypoint - if (this.position.x != x || this.position.y != y || this.position.z != z) { - synchronized (this.posLock) { // Paper - detailed watchdog information - this.position = new Vec3(x, y, z); -@@ -5119,7 +5120,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -5118,7 +5118,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess int floor = Mth.floor(x); int floor1 = Mth.floor(y); int floor2 = Mth.floor(z); - if (floor != this.blockPosition.getX() || floor1 != this.blockPosition.getY() || floor2 != this.blockPosition.getZ()) { -+ blockUpdated = floor != this.blockPosition.getX() || floor1 != this.blockPosition.getY() || floor2 != this.blockPosition.getZ(); // Leaf - optimize waypoint ++ boolean blockUpdated = floor != this.blockPosition.getX() || floor1 != this.blockPosition.getY() || floor2 != this.blockPosition.getZ(); // Leaf - optimize waypoint + if (blockUpdated) { // Leaf - optimize waypoint this.blockPosition = new BlockPos(floor, floor1, floor2); this.inBlockState = null; if (SectionPos.blockToSectionCoord(floor) != this.chunkPosition.x || SectionPos.blockToSectionCoord(floor2) != this.chunkPosition.z) { -@@ -5128,7 +5130,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -5127,7 +5128,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } this.levelCallback.onMove(); diff --git a/leaf-server/minecraft-patches/features/0264-Paw-optimization.patch b/leaf-server/minecraft-patches/features/0263-Paw-optimization.patch similarity index 99% rename from leaf-server/minecraft-patches/features/0264-Paw-optimization.patch rename to leaf-server/minecraft-patches/features/0263-Paw-optimization.patch index 4d12e179..b1144bc4 100644 --- a/leaf-server/minecraft-patches/features/0264-Paw-optimization.patch +++ b/leaf-server/minecraft-patches/features/0263-Paw-optimization.patch @@ -132,7 +132,7 @@ index a16bd45a3fd9a8937a7624c8f7838367e7e087bd..2712a9bf21731a1cf575dcb4ece19e6f private void tickPassenger(Entity ridingEntity, Entity passengerEntity, final boolean isActive) { // Paper - EAR 2 diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 5d4350dbe1d4189e17de77586a342c4ed0087c13..c1344b1313ff0999d6cb4ef7ca32ccc2715a7cde 100644 +index b71acd053b38d9b59720e35e664f957df6626b27..2d26a7a0b85c85830694e7947f2c4f29483bb99a 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -1138,16 +1138,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -183,7 +183,7 @@ index 5d4350dbe1d4189e17de77586a342c4ed0087c13..c1344b1313ff0999d6cb4ef7ca32ccc2 } private void applyMovementEmissionAndPlaySound(Entity.MovementEmission movementEmission, Vec3 movement, BlockPos pos, BlockState state) { -@@ -5013,9 +4987,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -5012,9 +4986,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public void setDeltaMovement(Vec3 deltaMovement) { @@ -193,9 +193,9 @@ index 5d4350dbe1d4189e17de77586a342c4ed0087c13..c1344b1313ff0999d6cb4ef7ca32ccc2 } public void addDeltaMovement(Vec3 addend) { -@@ -5114,9 +5086,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -5112,9 +5084,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + } // Paper end - Block invalid positions and bounding box - boolean blockUpdated; // Leaf - optimize waypoint if (this.position.x != x || this.position.y != y || this.position.z != z) { - synchronized (this.posLock) { // Paper - detailed watchdog information this.position = new Vec3(x, y, z); diff --git a/leaf-server/minecraft-patches/features/0265-Fix-Paper-config-fixClimbingBypassingCrammingRule.patch b/leaf-server/minecraft-patches/features/0264-Fix-Paper-config-fixClimbingBypassingCrammingRule.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0265-Fix-Paper-config-fixClimbingBypassingCrammingRule.patch rename to leaf-server/minecraft-patches/features/0264-Fix-Paper-config-fixClimbingBypassingCrammingRule.patch diff --git a/leaf-server/minecraft-patches/features/0266-Skip-inactive-entity-for-execute.patch b/leaf-server/minecraft-patches/features/0265-Skip-inactive-entity-for-execute.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0266-Skip-inactive-entity-for-execute.patch rename to leaf-server/minecraft-patches/features/0265-Skip-inactive-entity-for-execute.patch diff --git a/leaf-server/minecraft-patches/features/0267-Optimise-getEntities.patch b/leaf-server/minecraft-patches/features/0266-Optimise-getEntities.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0267-Optimise-getEntities.patch rename to leaf-server/minecraft-patches/features/0266-Optimise-getEntities.patch diff --git a/leaf-server/minecraft-patches/features/0268-fix-MC-298464.patch b/leaf-server/minecraft-patches/features/0267-fix-MC-298464.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0268-fix-MC-298464.patch rename to leaf-server/minecraft-patches/features/0267-fix-MC-298464.patch diff --git a/leaf-server/minecraft-patches/features/0269-Re-route-SetClosestHomeAsWalkTarget-s-poi-finding-to.patch b/leaf-server/minecraft-patches/features/0268-Re-route-SetClosestHomeAsWalkTarget-s-poi-finding-to.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0269-Re-route-SetClosestHomeAsWalkTarget-s-poi-finding-to.patch rename to leaf-server/minecraft-patches/features/0268-Re-route-SetClosestHomeAsWalkTarget-s-poi-finding-to.patch diff --git a/leaf-server/minecraft-patches/features/0270-optimize-checkInsideBlocks-calls.patch b/leaf-server/minecraft-patches/features/0269-optimize-checkInsideBlocks-calls.patch similarity index 99% rename from leaf-server/minecraft-patches/features/0270-optimize-checkInsideBlocks-calls.patch rename to leaf-server/minecraft-patches/features/0269-optimize-checkInsideBlocks-calls.patch index 8610dcb8..ee202da8 100644 --- a/leaf-server/minecraft-patches/features/0270-optimize-checkInsideBlocks-calls.patch +++ b/leaf-server/minecraft-patches/features/0269-optimize-checkInsideBlocks-calls.patch @@ -11,7 +11,7 @@ Subject: [PATCH] optimize checkInsideBlocks calls License: LGPL-3.0 (https://www.gnu.org/licenses/lgpl-3.0.html) diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index c1344b1313ff0999d6cb4ef7ca32ccc2715a7cde..6a0b44311d0b27cb7ae4a799eccb607e43d59f48 100644 +index 2d26a7a0b85c85830694e7947f2c4f29483bb99a..d61761dc1683e439af4ebfc393bc8c70de23340f 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -1701,8 +1701,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/leaf-server/minecraft-patches/features/0271-Op-lock.patch b/leaf-server/minecraft-patches/features/0270-Op-lock.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0271-Op-lock.patch rename to leaf-server/minecraft-patches/features/0270-Op-lock.patch diff --git a/leaf-server/minecraft-patches/features/0272-Custom-NonNullList.patch b/leaf-server/minecraft-patches/features/0271-Custom-NonNullList.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0272-Custom-NonNullList.patch rename to leaf-server/minecraft-patches/features/0271-Custom-NonNullList.patch diff --git a/leaf-server/minecraft-patches/features/0273-Optimise-TextColor.patch b/leaf-server/minecraft-patches/features/0272-Optimise-TextColor.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0273-Optimise-TextColor.patch rename to leaf-server/minecraft-patches/features/0272-Optimise-TextColor.patch diff --git a/leaf-server/minecraft-patches/features/0274-Do-not-create-fire-if-explosion-was-cancelled.patch b/leaf-server/minecraft-patches/features/0273-Do-not-create-fire-if-explosion-was-cancelled.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0274-Do-not-create-fire-if-explosion-was-cancelled.patch rename to leaf-server/minecraft-patches/features/0273-Do-not-create-fire-if-explosion-was-cancelled.patch diff --git a/leaf-server/minecraft-patches/features/0275-Skip-BlockPhysicsEvent-if-no-listeners.patch b/leaf-server/minecraft-patches/features/0274-Skip-BlockPhysicsEvent-if-no-listeners.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0275-Skip-BlockPhysicsEvent-if-no-listeners.patch rename to leaf-server/minecraft-patches/features/0274-Skip-BlockPhysicsEvent-if-no-listeners.patch diff --git a/leaf-server/minecraft-patches/features/0276-Lithium-equipment-tracking.patch b/leaf-server/minecraft-patches/features/0275-Lithium-equipment-tracking.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0276-Lithium-equipment-tracking.patch rename to leaf-server/minecraft-patches/features/0275-Lithium-equipment-tracking.patch diff --git a/leaf-server/minecraft-patches/features/0277-fix-purpur-attribute-base-patch.patch b/leaf-server/minecraft-patches/features/0276-fix-purpur-attribute-base-patch.patch similarity index 99% rename from leaf-server/minecraft-patches/features/0277-fix-purpur-attribute-base-patch.patch rename to leaf-server/minecraft-patches/features/0276-fix-purpur-attribute-base-patch.patch index ee6d9430..4c26be32 100644 --- a/leaf-server/minecraft-patches/features/0277-fix-purpur-attribute-base-patch.patch +++ b/leaf-server/minecraft-patches/features/0276-fix-purpur-attribute-base-patch.patch @@ -147,7 +147,7 @@ index b2fa170b14bc3037e5c143d320d0a1ef24738f1c..aaa710ca8629235fc3395a3f96df21f6 // Purpur end - Configurable entity base attributes diff --git a/net/minecraft/world/entity/animal/Dolphin.java b/net/minecraft/world/entity/animal/Dolphin.java -index c4fda92e078c9ba745b2548ecaaffffff97fb0fd..c683455e7500b18a99f3e88d1d4b57924eea12a3 100644 +index 23696a5e2871ea07f34d4b4f6a20e2896ac3f5bd..cb539644232ba9e949c1c6fb25dfcc54e096e4fd 100644 --- a/net/minecraft/world/entity/animal/Dolphin.java +++ b/net/minecraft/world/entity/animal/Dolphin.java @@ -154,8 +154,8 @@ public class Dolphin extends AgeableWaterCreature { diff --git a/leaf-server/minecraft-patches/features/0278-Bump-netty-to-4.2.x.patch b/leaf-server/minecraft-patches/features/0277-Bump-netty-to-4.2.x.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0278-Bump-netty-to-4.2.x.patch rename to leaf-server/minecraft-patches/features/0277-Bump-netty-to-4.2.x.patch diff --git a/leaf-server/minecraft-patches/features/0279-Paper-PR-Optimise-temptation-lookups.patch b/leaf-server/minecraft-patches/features/0278-Paper-PR-Optimise-temptation-lookups.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0279-Paper-PR-Optimise-temptation-lookups.patch rename to leaf-server/minecraft-patches/features/0278-Paper-PR-Optimise-temptation-lookups.patch diff --git a/leaf-server/minecraft-patches/features/0280-fix-temptation-lookups.patch b/leaf-server/minecraft-patches/features/0279-fix-temptation-lookups.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0280-fix-temptation-lookups.patch rename to leaf-server/minecraft-patches/features/0279-fix-temptation-lookups.patch diff --git a/leaf-server/minecraft-patches/features/0281-Lithium-combined-heightmap-update.patch b/leaf-server/minecraft-patches/features/0280-Lithium-combined-heightmap-update.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0281-Lithium-combined-heightmap-update.patch rename to leaf-server/minecraft-patches/features/0280-Lithium-combined-heightmap-update.patch diff --git a/leaf-server/minecraft-patches/features/0281-thread-unsafe-chunk-map.patch b/leaf-server/minecraft-patches/features/0281-thread-unsafe-chunk-map.patch new file mode 100644 index 00000000..19c7ff3e --- /dev/null +++ b/leaf-server/minecraft-patches/features/0281-thread-unsafe-chunk-map.patch @@ -0,0 +1,214 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: hayanesuru +Date: Sat, 9 Aug 2025 14:52:44 +0900 +Subject: [PATCH] thread unsafe chunk map + + +diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java +index 36ce2be30478d734d8326eeeb004ba7dc61e0642..df60c94a8755df2c2ca71a27022291587fb21af0 100644 +--- a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java ++++ b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java +@@ -78,6 +78,7 @@ public final class ChunkHolderManager { + final ChunkUnloadQueue unloadQueue; + + private final ConcurrentLong2ReferenceChainedHashTable chunkHolders = ConcurrentLong2ReferenceChainedHashTable.createWithCapacity(16384, 0.25f); ++ public final org.dreeam.leaf.world.ChunkCache chunkHoldersNoSync; // Leaf - thread unsafe chunk map + private final ServerLevel world; + private final ChunkTaskScheduler taskScheduler; + private long currentTick; +@@ -112,6 +113,7 @@ public final class ChunkHolderManager { + this.taskScheduler = taskScheduler; + this.ticketLockArea = new ReentrantAreaLock(taskScheduler.getChunkSystemLockShift()); + this.unloadQueue = new ChunkUnloadQueue(((ChunkSystemServerLevel)world).moonrise$getRegionChunkShift()); ++ this.chunkHoldersNoSync = new org.dreeam.leaf.world.ChunkCache<>(world.getChunkSource().mainThread); // Leaf - thread unsafe chunk map + } + + public boolean processTicketUpdates(final int chunkX, final int chunkZ) { +@@ -374,6 +376,7 @@ public final class ChunkHolderManager { + if (current == null) { + // must create + current = ChunkHolderManager.this.createChunkHolder(key); ++ ChunkHolderManager.this.chunkHoldersNoSync.put(key, current); // Leaf - thread unsafe chunk map + ChunkHolderManager.this.chunkHolders.put(key, current); + current.updateTicketLevel(newLevel); + } else { +@@ -923,11 +926,24 @@ public final class ChunkHolderManager { + } + + public NewChunkHolder getChunkHolder(final int chunkX, final int chunkZ) { +- return this.chunkHolders.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); ++ // Leaf start - thread unsafe chunk map ++ final long position = CoordinateUtils.getChunkKey(chunkX, chunkZ); ++ if (this.chunkHoldersNoSync.isSameThread()) { ++ return this.chunkHoldersNoSync.get(position); ++ } else { ++ return this.chunkHolders.get(position); ++ } ++ // Leaf end - thread unsafe chunk map + } + + public NewChunkHolder getChunkHolder(final long position) { +- return this.chunkHolders.get(position); ++ // Leaf start - thread unsafe chunk map ++ if (this.chunkHoldersNoSync.isSameThread()) { ++ return this.chunkHoldersNoSync.get(position); ++ } else { ++ return this.chunkHolders.get(position); ++ } ++ // Leaf end - thread unsafe chunk map + } + + public void raisePriority(final int x, final int z, final Priority priority) { +@@ -986,6 +1002,7 @@ public final class ChunkHolderManager { + } + + current = this.createChunkHolder(position); ++ this.chunkHoldersNoSync.put(position, current); // Leaf - thread unsafe chunk map + this.chunkHolders.put(position, current); + + +@@ -1158,7 +1175,11 @@ public final class ChunkHolderManager { + holder.onUnload(); + this.autoSaveQueue.remove(holder); + PlatformHooks.get().onChunkHolderDelete(this.world, holder.vanillaChunkHolder); +- this.chunkHolders.remove(CoordinateUtils.getChunkKey(holder.chunkX, holder.chunkZ)); ++ // Leaf start - thread unsafe chunk map ++ long position = CoordinateUtils.getChunkKey(holder.chunkX, holder.chunkZ); ++ this.chunkHoldersNoSync.remove(position); ++ this.chunkHolders.remove(position); ++ // Leaf end - thread unsafe chunk map + } + + // note: never call while inside the chunk system, this will absolutely break everything +diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java +index f31a643b9fcfdafb2c1c6069b44b736527960787..7f231d95db5d33fccd923cc53466e67de75babc0 100644 +--- a/net/minecraft/server/MinecraftServer.java ++++ b/net/minecraft/server/MinecraftServer.java +@@ -1769,6 +1769,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { ++ serverLevel.getChunkSource().fullChunksNonSync.setThread(); // Leaf - thread unsafe chunk map ++ serverLevel.moonrise$getChunkTaskScheduler().chunkHolderManager.chunkHoldersNoSync.setThread(); // Leaf - thread unsafe chunk map + ca.spottedleaf.moonrise.common.util.TickThread.ServerLevelTickThread currentThread = (ca.spottedleaf.moonrise.common.util.TickThread.ServerLevelTickThread) Thread.currentThread(); + currentThread.currentlyTickingServerLevel = serverLevel; + +@@ -1787,7 +1789,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop fullChunks = new ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable<>(); ++ public final org.dreeam.leaf.world.ChunkCache fullChunksNonSync; // Leaf - thread unsafe chunk map + public int getFullChunksCount() { + return this.fullChunks.size(); + } +@@ -87,16 +88,27 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon + @Override + public final void moonrise$setFullChunk(final int chunkX, final int chunkZ, final LevelChunk chunk) { + final long key = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(chunkX, chunkZ); ++ // Leaf start - thread unsafe chunk map + if (chunk == null) { ++ this.fullChunksNonSync.remove(key); + this.fullChunks.remove(key); + } else { ++ this.fullChunksNonSync.put(key,chunk); + this.fullChunks.put(key, chunk); + } ++ // Leaf end - thread unsafe chunk map + } + + @Override + public final LevelChunk moonrise$getFullChunkIfLoaded(final int chunkX, final int chunkZ) { +- return this.fullChunks.get(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(chunkX, chunkZ)); ++ // Leaf start - thread unsafe chunk map ++ long key = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(chunkX, chunkZ); ++ if (this.fullChunksNonSync.isSameThread()) { ++ return this.fullChunksNonSync.get(key); ++ } else { ++ return this.fullChunks.get(key); ++ } ++ // Leaf end - thread unsafe chunk map + } + + private ChunkAccess syncLoad(final int chunkX, final int chunkZ, final ChunkStatus toStatus) { +@@ -204,6 +216,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon + this.mainThreadProcessor = new ServerChunkCache.MainThreadExecutor(level); + this.mainThread = Thread.currentThread(); + Path path = levelStorageAccess.getDimensionPath(level.dimension()).resolve("data"); ++ this.fullChunksNonSync = new org.dreeam.leaf.world.ChunkCache<>(mainThread); // Leaf - thread unsafe chunk map + + try { + FileUtil.createDirectoriesSafe(path); +@@ -283,7 +296,14 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon + + @Nullable + public LevelChunk getChunkAtIfLoadedImmediately(int x, int z) { +- return this.fullChunks.get(ChunkPos.asLong(x, z)); ++ // Leaf start - thread unsafe chunk map ++ long key = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(x, z); ++ if (this.fullChunksNonSync.isSameThread()) { ++ return this.fullChunksNonSync.get(key); ++ } else { ++ return this.fullChunks.get(key); ++ } ++ // Leaf end - thread unsafe chunk map + } + // Paper end + +@@ -318,7 +338,8 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon + public ChunkAccess getChunk(int x, int z, ChunkStatus chunkStatus, boolean requireChunk) { + // Paper start - rewrite chunk system + if (chunkStatus == ChunkStatus.FULL) { +- final LevelChunk ret = this.fullChunks.get(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(x, z)); ++ long key = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(x, z); // Leaf - thread unsafe chunk map ++ final LevelChunk ret = this.fullChunksNonSync.isSameThread() ? this.fullChunksNonSync.get(key) : this.fullChunks.get(key); // Leaf - thread unsafe chunk map + + if (ret != null) { + return ret; +@@ -335,7 +356,8 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon + @Override + public LevelChunk getChunkNow(int chunkX, int chunkZ) { + // Paper start - rewrite chunk system +- final LevelChunk ret = this.fullChunks.get(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(chunkX, chunkZ)); ++ long key = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(chunkX, chunkZ); // Leaf - thread unsafe chunk map ++ final LevelChunk ret = this.fullChunksNonSync.isSameThread() ? this.fullChunksNonSync.get(key) : this.fullChunks.get(key); // Leaf - thread unsafe chunk map + if (!ca.spottedleaf.moonrise.common.PlatformHooks.get().hasCurrentlyLoadingChunk()) { + return ret; + } +diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java +index afebf43067f13493d06e6c0620058c135eb9b880..4e1748020c31b80b52f6f52fe90eb0f7099651d9 100644 +--- a/net/minecraft/world/level/Level.java ++++ b/net/minecraft/world/level/Level.java +@@ -1063,6 +1063,18 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl + // Paper end - Perf: make sure loaded chunks get the inlined variant of this function + } + ++ // Leaf start - thread unsafe chunk map ++ @Nullable ++ public final LevelChunk getChunkAtIfLoadedUnchecked(int x, int z) { ++ return ((ServerLevel) this).chunkSource.fullChunksNonSync.get(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(x, z)); ++ } ++ ++ @Nullable ++ public final BlockState getBlockStateIfLoadedUnchecked(int x, int y, int z) { ++ LevelChunk chunk = ((ServerLevel) this).chunkSource.fullChunksNonSync.get(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(x >> 4, z >> 4)); ++ return chunk == null ? null : chunk.getBlockStateFinal(x, y, z); ++ } ++ // Leaf end - thread unsafe chunk map + // Paper start - if loaded + @Nullable + @Override diff --git a/leaf-server/minecraft-patches/features/0283-optimize-SimpleBitStorage-object-layout.patch b/leaf-server/minecraft-patches/features/0283-optimize-SimpleBitStorage-object-layout.patch new file mode 100644 index 00000000..78ef18c7 --- /dev/null +++ b/leaf-server/minecraft-patches/features/0283-optimize-SimpleBitStorage-object-layout.patch @@ -0,0 +1,41 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: hayanesuru +Date: Sat, 9 Aug 2025 14:55:00 +0900 +Subject: [PATCH] optimize SimpleBitStorage object layout + + +diff --git a/net/minecraft/util/SimpleBitStorage.java b/net/minecraft/util/SimpleBitStorage.java +index 8091f0c0a536047ead4966e70785962e87faad9a..8aec073db74a4d0a21c8a423586d108c6add9ad5 100644 +--- a/net/minecraft/util/SimpleBitStorage.java ++++ b/net/minecraft/util/SimpleBitStorage.java +@@ -204,8 +204,8 @@ public class SimpleBitStorage implements BitStorage { + private final long mask; + private final int size; + private final int valuesPerLong; +- private final int divideMul; private final long divideMulUnsigned; // Paper - Perf: Optimize SimpleBitStorage; referenced in b(int) with 2 Integer.toUnsignedLong calls +- private final int divideAdd; private final long divideAddUnsigned; // Paper - Perf: Optimize SimpleBitStorage ++ private final int divideMul; /*private final long divideMulUnsigned;*/ // Paper - Perf: Optimize SimpleBitStorage; referenced in b(int) with 2 Integer.toUnsignedLong calls // Leaf - optimize SimpleBitStorage object layout ++ private final int divideAdd; /*private final long divideAddUnsigned;*/ // Paper - Perf: Optimize SimpleBitStorage // Leaf - optimize SimpleBitStorage object layout + private final int divideShift; + + // Paper start - optimise bitstorage read/write operations +@@ -262,8 +262,8 @@ public class SimpleBitStorage implements BitStorage { + this.mask = (1L << bits) - 1L; + this.valuesPerLong = (char)(64 / bits); + int i = 3 * (this.valuesPerLong - 1); +- this.divideMul = MAGIC[i + 0]; this.divideMulUnsigned = Integer.toUnsignedLong(this.divideMul); // Paper - Perf: Optimize SimpleBitStorage +- this.divideAdd = MAGIC[i + 1]; this.divideAddUnsigned = Integer.toUnsignedLong(this.divideAdd); // Paper - Perf: Optimize SimpleBitStorage ++ this.divideMul = MAGIC[i + 0]; /*this.divideMulUnsigned = Integer.toUnsignedLong(this.divideMul);*/ // Paper - Perf: Optimize SimpleBitStorage // Leaf - optimize SimpleBitStorage object layout ++ this.divideAdd = MAGIC[i + 1]; /*this.divideAddUnsigned = Integer.toUnsignedLong(this.divideAdd);*/ // Paper - Perf: Optimize SimpleBitStorage // Leaf - optimize SimpleBitStorage object layout + this.divideShift = MAGIC[i + 2]; + int i1 = (size + this.valuesPerLong - 1) / this.valuesPerLong; + if (data != null) { +@@ -285,7 +285,7 @@ public class SimpleBitStorage implements BitStorage { + } + + private int cellIndex(int index) { +- return (int)(index * this.divideMulUnsigned + this.divideAddUnsigned >> 32 >> this.divideShift); // Paper - Perf: Optimize SimpleBitStorage ++ return (int)(index * Integer.toUnsignedLong(this.divideMul) + Integer.toUnsignedLong(this.divideAdd) >> 32 >> this.divideShift); // Paper - Perf: Optimize SimpleBitStorage // Leaf - optimize SimpleBitStorage object layout + } + + @Override diff --git a/leaf-server/minecraft-patches/features/0284-optimize-get-chunk.patch b/leaf-server/minecraft-patches/features/0284-optimize-get-chunk.patch new file mode 100644 index 00000000..0d63a29a --- /dev/null +++ b/leaf-server/minecraft-patches/features/0284-optimize-get-chunk.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: hayanesuru +Date: Sat, 9 Aug 2025 14:55:37 +0900 +Subject: [PATCH] optimize get chunk + + +diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java +index 4e1748020c31b80b52f6f52fe90eb0f7099651d9..28fdc5b85c22fd03bc2e4b4c6ae3e3524fd039f6 100644 +--- a/net/minecraft/world/level/Level.java ++++ b/net/minecraft/world/level/Level.java +@@ -1409,12 +1409,17 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl + } + } + // CraftBukkit end +- if (this.isOutsideBuildHeight(pos)) { ++ // Leaf start - optimize get chunk ++ int x = pos.getX(); ++ int y = pos.getY(); ++ int z = pos.getZ(); ++ if (this.isOutsideBuildHeight(y)) { + return Blocks.VOID_AIR.defaultBlockState(); + } else { +- ChunkAccess chunk = this.getChunk(pos.getX() >> 4, pos.getZ() >> 4, ChunkStatus.FULL, true); // Paper - manually inline to reduce hops and avoid unnecessary null check to reduce total byte code size, this should never return null and if it does we will see it the next line but the real stack trace will matter in the chunk engine +- return chunk.getBlockState(pos); ++ ChunkAccess chunk = this.getChunk(x >> 4, z >> 4, ChunkStatus.FULL, true); // Paper - manually inline to reduce hops and avoid unnecessary null check to reduce total byte code size, this should never return null and if it does we will see it the next line but the real stack trace will matter in the chunk engine ++ return chunk.getBlockState(x, y, z); + } ++ // Leaf end - optimize get chunk + } + + @Override diff --git a/leaf-server/minecraft-patches/features/0285-remove-shouldTickBlocksAt-check.patch b/leaf-server/minecraft-patches/features/0285-remove-shouldTickBlocksAt-check.patch new file mode 100644 index 00000000..f6bed46a --- /dev/null +++ b/leaf-server/minecraft-patches/features/0285-remove-shouldTickBlocksAt-check.patch @@ -0,0 +1,19 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: hayanesuru +Date: Sat, 9 Aug 2025 14:56:22 +0900 +Subject: [PATCH] remove shouldTickBlocksAt check + + +diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java +index 28fdc5b85c22fd03bc2e4b4c6ae3e3524fd039f6..498a9c1590ec3bc4a2b3d5bead899aeb37b56cdf 100644 +--- a/net/minecraft/world/level/Level.java ++++ b/net/minecraft/world/level/Level.java +@@ -1539,7 +1539,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl + // Spigot end + if (tickingBlockEntity.isRemoved()) { + ((org.dreeam.leaf.util.list.BlockEntityTickersList) this.blockEntityTickers).markAsRemoved(this.tileTickPosition); // toRemove.add(tickingBlockEntity); // SparklyPaper - optimize block entity removals // Paper - Fix MC-117075; use removeAll +- } else if (runsNormally && this.shouldTickBlocksAt(tickingBlockEntity.getPos())) { ++ } else if (runsNormally /*&& this.shouldTickBlocksAt(tickingBlockEntity.getPos())*/) { // Leaf - remove shouldTickBlocksAt check - duplicate at BoundTickingBlockEntity#tick + tickingBlockEntity.tick(); + // Paper start - rewrite chunk system + // Leaf start - SparklyPaper - parallel world ticking (only run mid-tick at the end of each tick / fixes concurrency bugs related to executeMidTickTasks) - do not bother with condition work / make configurable diff --git a/leaf-server/minecraft-patches/features/0286-optimize-PalettedContainer-get.patch b/leaf-server/minecraft-patches/features/0286-optimize-PalettedContainer-get.patch new file mode 100644 index 00000000..cbf9168e --- /dev/null +++ b/leaf-server/minecraft-patches/features/0286-optimize-PalettedContainer-get.patch @@ -0,0 +1,47 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: hayanesuru +Date: Sat, 9 Aug 2025 14:59:34 +0900 +Subject: [PATCH] optimize PalettedContainer#get + + +diff --git a/net/minecraft/world/level/chunk/PalettedContainer.java b/net/minecraft/world/level/chunk/PalettedContainer.java +index 49220967392331dd9928a539da6e6052b007e318..9319ccc4ee8e44ea8c1f32e623f2d3c7ceed1f4f 100644 +--- a/net/minecraft/world/level/chunk/PalettedContainer.java ++++ b/net/minecraft/world/level/chunk/PalettedContainer.java +@@ -48,6 +48,18 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + private final PalettedContainer.Strategy strategy; + //private final ThreadingDetector threadingDetector = new ThreadingDetector("PalettedContainer"); // Paper - unused + ++ // Leaf start - optimize PalettedContainer#get ++ private static final java.lang.invoke.VarHandle DATA_HANDLE; ++ static { ++ try { ++ DATA_HANDLE = java.lang.invoke.MethodHandles.lookup() ++ .findVarHandle(PalettedContainer.class, "data", PalettedContainer.Data.class); ++ } catch (ReflectiveOperationException e) { ++ throw new ExceptionInInitializerError(e); ++ } ++ } ++ // Leaf end - optimize PalettedContainer#get ++ + public void acquire() { + // this.threadingDetector.checkAndLock(); // Paper - disable this - use proper synchronization + } +@@ -104,7 +116,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + } + + private T readPalette(final PalettedContainer.Data data, final int paletteIdx) { +- final T[] palette = ((ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData)(Object)data).moonrise$getPalette(); ++ final T[] palette = data.moonrise$getPalette(); // Leaf - optimize PalettedContainer#get - remove type cast + if (palette == null) { + return this.readPaletteSlow(data, paletteIdx); + } +@@ -268,7 +280,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + + public T get(int index) { // Paper - public + // Paper start - optimise palette reads +- final PalettedContainer.Data data = this.data; ++ final PalettedContainer.Data data = (PalettedContainer.Data) DATA_HANDLE.getAcquire(this); // Leaf - optimize get chunk + return this.readPalette(data, data.storage.get(index)); + // Paper end - optimise palette reads + } diff --git a/leaf-server/minecraft-patches/features/0287-optimize-LevelChunk-getBlockStateFinal.patch b/leaf-server/minecraft-patches/features/0287-optimize-LevelChunk-getBlockStateFinal.patch new file mode 100644 index 00000000..e2be03f6 --- /dev/null +++ b/leaf-server/minecraft-patches/features/0287-optimize-LevelChunk-getBlockStateFinal.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: hayanesuru +Date: Sat, 9 Aug 2025 15:00:20 +0900 +Subject: [PATCH] optimize LevelChunk#getBlockStateFinal + + +diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java +index e429932a044647f931443c6761d1b39e4eb7665c..6a70665e9b8bc767ba316ada542178634e090afa 100644 +--- a/net/minecraft/world/level/chunk/LevelChunk.java ++++ b/net/minecraft/world/level/chunk/LevelChunk.java +@@ -316,12 +316,18 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p + + public BlockState getBlockStateFinal(final int x, final int y, final int z) { + // Copied and modified from below +- final int sectionIndex = this.getSectionIndex(y); +- if (sectionIndex < 0 || sectionIndex >= this.sections.length +- || this.sections[sectionIndex].nonEmptyBlockCount == 0) { +- return Blocks.AIR.defaultBlockState(); ++ // Leaf start - optimize LevelChunk#getBlockStateFinal ++ final int sectionIndex = (y >> 4) - this.minSection; ++ if (sectionIndex < 0 || sectionIndex >= this.sections.length) { ++ return AIR_BLOCKSTATE; ++ } else { ++ LevelChunkSection section = this.sections[sectionIndex]; ++ if (section.nonEmptyBlockCount == 0) { ++ return AIR_BLOCKSTATE; ++ } ++ return section.states.get((y & 15) << 8 | (z & 15) << 4 | x & 15); + } +- return this.sections[sectionIndex].states.get((y & 15) << 8 | (z & 15) << 4 | x & 15); ++ // Leaf end - optimize LevelChunk#getBlockStateFinal + } + + @Override diff --git a/leaf-server/minecraft-patches/features/0288-optimize-FluidState-is-TagKey.patch b/leaf-server/minecraft-patches/features/0288-optimize-FluidState-is-TagKey.patch new file mode 100644 index 00000000..722cb11f --- /dev/null +++ b/leaf-server/minecraft-patches/features/0288-optimize-FluidState-is-TagKey.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: hayanesuru +Date: Sat, 9 Aug 2025 15:00:57 +0900 +Subject: [PATCH] optimize FluidState#is(TagKey) + + +diff --git a/net/minecraft/world/level/material/FluidState.java b/net/minecraft/world/level/material/FluidState.java +index 0a5ae623a636923f3bbd3c01974497f39b7c4b62..0e7c4469275fa992b614b50df7e4b76670ebd121 100644 +--- a/net/minecraft/world/level/material/FluidState.java ++++ b/net/minecraft/world/level/material/FluidState.java +@@ -131,7 +131,16 @@ public final class FluidState extends StateHolder implements + } + + public boolean is(TagKey tag) { +- return this.getType().builtInRegistryHolder().is(tag); ++ // Leaf start - optimize FluidState#is(TagKey) ++ Fluid fluid = this.getType(); ++ if (fluid == Fluids.WATER || fluid == Fluids.FLOWING_WATER) { ++ return tag == net.minecraft.tags.FluidTags.WATER; ++ } else if (fluid == Fluids.LAVA || fluid == Fluids.FLOWING_LAVA) { ++ return tag == net.minecraft.tags.FluidTags.LAVA; ++ } else { ++ return false; ++ } ++ // Leaf end - optimize FluidState#is(TagKey) + } + + public boolean is(HolderSet fluids) { diff --git a/leaf-server/minecraft-patches/features/0289-optimize-fluid.patch b/leaf-server/minecraft-patches/features/0289-optimize-fluid.patch new file mode 100644 index 00000000..42b7f341 --- /dev/null +++ b/leaf-server/minecraft-patches/features/0289-optimize-fluid.patch @@ -0,0 +1,154 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: hayanesuru +Date: Sat, 9 Aug 2025 15:12:14 +0900 +Subject: [PATCH] optimize fluid + + +diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java +index 498a9c1590ec3bc4a2b3d5bead899aeb37b56cdf..27a02bbabdb8ddc750a2aeb3901bd6783cbb873a 100644 +--- a/net/minecraft/world/level/Level.java ++++ b/net/minecraft/world/level/Level.java +@@ -1432,6 +1432,14 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl + } + } + ++ // Leaf start ++ @Nullable ++ public final FluidState getFluidStateIfLoadedUnchecked(final int x, final int y, final int z) { ++ LevelChunk chunkAt = ((ServerLevel) this).chunkSource.fullChunksNonSync.get(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(x >> 4, z >> 4)); ++ return chunkAt == null ? null : chunkAt.getFluidStateFinal(x, y, z); ++ } ++ // Leaf end ++ + public boolean isBrightOutside() { + return !this.dimensionType().hasFixedTime() && this.skyDarken < 4; + } +diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java +index 6a70665e9b8bc767ba316ada542178634e090afa..0ee94459c1995ddd7e8b469088827b873dab3fe0 100644 +--- a/net/minecraft/world/level/chunk/LevelChunk.java ++++ b/net/minecraft/world/level/chunk/LevelChunk.java +@@ -330,6 +330,21 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p + // Leaf end - optimize LevelChunk#getBlockStateFinal + } + ++ // Leaf start ++ public FluidState getFluidStateFinal(final int x, final int y, final int z) { ++ final int sectionIndex = (y >> 4) - this.minSection; ++ if (sectionIndex < 0 || sectionIndex >= this.sections.length) { ++ return AIR_FLUIDSTATE; ++ } else { ++ LevelChunkSection section = this.sections[sectionIndex]; ++ if (section.waterFluidCount == 0 && section.lavaFluidCount == 0) { ++ return AIR_FLUIDSTATE; ++ } ++ return section.states.get((y & 15) << 8 | (z & 15) << 4 | x & 15).getFluidState(); ++ } ++ } ++ // Leaf end ++ + @Override + public BlockState getBlockState(BlockPos pos) { + if (true) { +diff --git a/net/minecraft/world/level/chunk/LevelChunkSection.java b/net/minecraft/world/level/chunk/LevelChunkSection.java +index abb7c8b4ffc73cedd5e03597fe82c71e51161a1b..315cd21ac80b1bbaef96a039b9567c48ce098027 100644 +--- a/net/minecraft/world/level/chunk/LevelChunkSection.java ++++ b/net/minecraft/world/level/chunk/LevelChunkSection.java +@@ -21,6 +21,8 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ + short nonEmptyBlockCount; // Paper - package private + private short tickingBlockCount; + private short tickingFluidCount; ++ public short waterFluidCount; // Leaf ++ public short lavaFluidCount; // Leaf + public final PalettedContainer states; + private PalettedContainer> biomes; // CraftBukkit - read/write + private boolean modified = false; // Leaf - Optimize chunkUnload +@@ -53,6 +55,8 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ + this.nonEmptyBlockCount = section.nonEmptyBlockCount; + this.tickingBlockCount = section.tickingBlockCount; + this.tickingFluidCount = section.tickingFluidCount; ++ this.waterFluidCount = section.waterFluidCount; // Leaf ++ this.lavaFluidCount = section.lavaFluidCount; // Leaf + this.states = section.states.copy(); + this.biomes = section.biomes.copy(); + } +@@ -149,6 +153,15 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ + if (blockState.isRandomlyTicking()) { + this.tickingBlockCount--; + } ++ // Leaf start ++ final int flags = blockState.tagFlag; ++ if ((flags & org.dreeam.leaf.util.BlockMasks.WATER) != 0) { ++ this.waterFluidCount--; ++ } ++ if ((flags & org.dreeam.leaf.util.BlockMasks.LAVA) != 0) { ++ this.lavaFluidCount--; ++ } ++ // Leaf end + } + + if (!!fluidState.isRandomlyTicking()) { // Paper - block counting +@@ -160,6 +173,15 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ + if (state.isRandomlyTicking()) { + this.tickingBlockCount++; + } ++ // Leaf start ++ final int flags = blockState.tagFlag; ++ if ((flags & org.dreeam.leaf.util.BlockMasks.WATER) != 0) { ++ this.waterFluidCount++; ++ } ++ if ((flags & org.dreeam.leaf.util.BlockMasks.LAVA) != 0) { ++ this.lavaFluidCount++; ++ } ++ // Leaf end + } + + if (!!fluidState1.isRandomlyTicking()) { // Paper - block counting +@@ -193,6 +215,8 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ + this.nonEmptyBlockCount = (short)0; + this.tickingBlockCount = (short)0; + this.tickingFluidCount = (short)0; ++ this.waterFluidCount = (short)0; // Leaf ++ this.lavaFluidCount = (short)0; // Leaf + this.specialCollidingBlocks = (short)0; + this.tickingBlocks.clear(); + +@@ -240,6 +264,15 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ + tickingBlocks.add(raw[i]); + } + } ++ // Leaf start ++ final int flags = state.tagFlag; ++ if ((flags & org.dreeam.leaf.util.BlockMasks.WATER) != 0) { ++ this.waterFluidCount += (short)paletteCount; ++ } ++ if ((flags & org.dreeam.leaf.util.BlockMasks.LAVA) != 0) { ++ this.lavaFluidCount += (short)paletteCount; ++ } ++ // Leaf end + + final FluidState fluid = state.getFluidState(); + +@@ -326,11 +359,13 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ + } + + // Leaf start - Optimize chunkUnload +- private LevelChunkSection(short nonEmptyBlockCount, short tickingBlockCount, short tickingFluidCount, ++ private LevelChunkSection(short nonEmptyBlockCount, short tickingBlockCount, short tickingFluidCount, short waterFluidCount, short lavaFluidCount, // Leaf + PalettedContainer states, PalettedContainer> biomes) { + this.nonEmptyBlockCount = nonEmptyBlockCount; + this.tickingBlockCount = tickingBlockCount; + this.tickingFluidCount = tickingFluidCount; ++ this.waterFluidCount = waterFluidCount; // Leaf ++ this.lavaFluidCount = lavaFluidCount; // Leaf + this.states = states; + this.biomes = biomes; + } +@@ -345,6 +380,8 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ + this.nonEmptyBlockCount, + this.tickingBlockCount, + this.tickingFluidCount, ++ this.waterFluidCount, // Leaf ++ this.lavaFluidCount, // Leaf + this.states, // Share reference instead of copying + this.biomes // Share reference instead of copying + ); diff --git a/leaf-server/minecraft-patches/features/0290-optimize-SpreadingSnowyDirtBlock-randomTick.patch b/leaf-server/minecraft-patches/features/0290-optimize-SpreadingSnowyDirtBlock-randomTick.patch new file mode 100644 index 00000000..8b21fb25 --- /dev/null +++ b/leaf-server/minecraft-patches/features/0290-optimize-SpreadingSnowyDirtBlock-randomTick.patch @@ -0,0 +1,19 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: hayanesuru +Date: Sat, 9 Aug 2025 15:39:09 +0900 +Subject: [PATCH] optimize SpreadingSnowyDirtBlock#randomTick + + +diff --git a/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java b/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java +index f8cc3f870d88715386bb4de0da81a74fa04fd216..07eb777ac9657318831b5bf00e4a4c9e8aca76db 100644 +--- a/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java ++++ b/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java +@@ -52,7 +52,7 @@ public abstract class SpreadingSnowyDirtBlock extends SnowyDirtBlock { + protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { + if (this instanceof GrassBlock && level.paperConfig().tickRates.grassSpread != 1 && (level.paperConfig().tickRates.grassSpread < 1 || (net.minecraft.server.MinecraftServer.currentTick + pos.hashCode()) % level.paperConfig().tickRates.grassSpread != 0)) { return; } // Paper - Configurable random tick rates for blocks + // Paper start - Perf: optimize dirt and snow spreading +- final net.minecraft.world.level.chunk.ChunkAccess cachedBlockChunk = level.getChunkIfLoaded(pos); ++ final net.minecraft.world.level.chunk.ChunkAccess cachedBlockChunk = level.getChunkAtIfLoadedUnchecked(pos.getX() >> 4, pos.getZ() >> 4); // Leaf - optimize get chunk + if (cachedBlockChunk == null) { // Is this needed? + return; + } diff --git a/leaf-server/minecraft-patches/features/0291-optimize-onClimbable.patch b/leaf-server/minecraft-patches/features/0291-optimize-onClimbable.patch new file mode 100644 index 00000000..cb1b024b --- /dev/null +++ b/leaf-server/minecraft-patches/features/0291-optimize-onClimbable.patch @@ -0,0 +1,91 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: hayanesuru +Date: Sat, 9 Aug 2025 15:42:48 +0900 +Subject: [PATCH] optimize onClimbable + + +diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java +index d61761dc1683e439af4ebfc393bc8c70de23340f..85789dfd30fe4f3b1108634e84b10f168bf6f64e 100644 +--- a/net/minecraft/world/entity/Entity.java ++++ b/net/minecraft/world/entity/Entity.java +@@ -4992,7 +4992,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + // Gale start - don't load chunks to activate climbing entities + public @Nullable BlockState getInBlockStateIfLoaded() { + if (this.inBlockState == null) { +- this.inBlockState = this.level.getBlockStateIfLoaded(this.blockPosition()); ++ BlockPos pos = this.blockPosition(); // Leaf - optimize onClimbable ++ this.inBlockState = this.level.getBlockStateIfLoadedUnchecked(pos.getX(), pos.getY(), pos.getZ()); // Leaf - optimize onClimbable + } + + return this.inBlockState; +diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java +index 5b8fbc73b4d165b56c7133ed4a0156570ecb58a1..f0a0a19e2adff03e73e75c3db831dbf74ebf3861 100644 +--- a/net/minecraft/world/entity/LivingEntity.java ++++ b/net/minecraft/world/entity/LivingEntity.java +@@ -2217,10 +2217,10 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin + public boolean onClimbableCached() { + if (!this.blockPosition().equals(this.lastClimbingPosition)) { + // Gale start - don't load chunks to activate climbing entities +- Boolean onClimbableIfLoaded = this.onClimbable(this.level().galeConfig().smallOptimizations.loadChunks.toActivateClimbingEntities); ++ int onClimbableIfLoaded = this.onClimbable1(this.level().galeConfig().smallOptimizations.loadChunks.toActivateClimbingEntities); // Leaf - optimize onClimbable + +- if (onClimbableIfLoaded != null) { +- this.cachedOnClimbable = onClimbableIfLoaded; ++ if (onClimbableIfLoaded != 2) { // Leaf - optimize onClimbable ++ this.cachedOnClimbable = onClimbableIfLoaded == 1; // Leaf - optimize onClimbable + this.lastClimbingPosition = this.blockPosition(); + } else { + this.cachedOnClimbable = false; +@@ -2235,35 +2235,39 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin + + public boolean onClimbable() { + // Gale start - don't load chunks to activate climbing entities +- return onClimbable(true); ++ return onClimbable1(true) == 1; // Leaf - optimize onClimbable + } + +- public Boolean onClimbable(boolean loadChunk) { ++ // Leaf start - optimize onClimbable ++ public int onClimbable1(boolean loadChunk) { + // Gale end - don't load chunks to activate climbing entities + if (this.isSpectator()) { +- return false; ++ return 0; + } else { + BlockPos blockPos = this.blockPosition(); + // Gale start - don't load chunks to activate climbing +- BlockState inBlockState; ++ BlockState inBlockState = this.getInBlockStateIfLoaded(); + if (loadChunk) { +- inBlockState = this.getInBlockState(); +- } else { +- inBlockState = this.getInBlockStateIfLoaded(); +- if (inBlockState == null) return null; ++ if (inBlockState == null) { ++ inBlockState = this.getInBlockState(); ++ } ++ } else if (inBlockState == null) { ++ return 2; + } + // Gale end - don't load chunks to activate climbing entities +- if (inBlockState.is(BlockTags.CLIMBABLE)) { ++ final int flags = inBlockState.tagFlag; ++ if ((flags & org.dreeam.leaf.util.BlockMasks.CLIMBABLE_TAG) != 0) { + this.lastClimbablePos = Optional.of(blockPos); +- return true; +- } else if (inBlockState.getBlock() instanceof TrapDoorBlock && this.trapdoorUsableAsLadder(blockPos, inBlockState)) { ++ return 1; ++ } else if ((flags & org.dreeam.leaf.util.BlockMasks.TRAP_DOOR_CL) != 0 && this.trapdoorUsableAsLadder(blockPos, inBlockState)) { + this.lastClimbablePos = Optional.of(blockPos); +- return true; ++ return 1; + } else { +- return false; ++ return 0; + } + } + } ++ // Leaf end - optimize onClimbable + + private boolean trapdoorUsableAsLadder(BlockPos pos, BlockState state) { + if (!state.getValue(TrapDoorBlock.OPEN)) { diff --git a/leaf-server/minecraft-patches/features/0292-optimize-applyMovementEmissionAndPlaySound.patch b/leaf-server/minecraft-patches/features/0292-optimize-applyMovementEmissionAndPlaySound.patch new file mode 100644 index 00000000..937d2328 --- /dev/null +++ b/leaf-server/minecraft-patches/features/0292-optimize-applyMovementEmissionAndPlaySound.patch @@ -0,0 +1,20 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: hayanesuru +Date: Sat, 9 Aug 2025 15:43:00 +0900 +Subject: [PATCH] optimize applyMovementEmissionAndPlaySound + + +diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java +index 85789dfd30fe4f3b1108634e84b10f168bf6f64e..0bd4bc2d3d3edf6f7ea5e41d4049b2e0a3b3151e 100644 +--- a/net/minecraft/world/entity/Entity.java ++++ b/net/minecraft/world/entity/Entity.java +@@ -1276,7 +1276,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + float f1 = (float)(movement.length() * 0.6F); + float f2 = (float)(movement.horizontalDistance() * 0.6F); + BlockPos onPos = this.getOnPos(); +- BlockState blockState = this.level().getBlockState(onPos); ++ BlockState blockState = this.level.getBlockStateIfLoadedUnchecked(onPos.getX(), onPos.getY(), onPos.getZ()); ++ if (blockState == null) { blockState = this.level.getBlockState(onPos); } + boolean isStateClimbable = this.isStateClimbable(blockState); + this.moveDist += isStateClimbable ? f1 : f2; + this.flyDist += f1; diff --git a/leaf-server/minecraft-patches/features/0293-optimize-isStateClimbable.patch b/leaf-server/minecraft-patches/features/0293-optimize-isStateClimbable.patch new file mode 100644 index 00000000..f4a248a1 --- /dev/null +++ b/leaf-server/minecraft-patches/features/0293-optimize-isStateClimbable.patch @@ -0,0 +1,20 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: hayanesuru +Date: Sat, 9 Aug 2025 15:43:06 +0900 +Subject: [PATCH] optimize isStateClimbable + + +diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java +index 0bd4bc2d3d3edf6f7ea5e41d4049b2e0a3b3151e..3aec52d72cd5ffd2ef61b1f6c37c6b7f1203d06f 100644 +--- a/net/minecraft/world/entity/Entity.java ++++ b/net/minecraft/world/entity/Entity.java +@@ -1376,7 +1376,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + } + + private boolean isStateClimbable(BlockState state) { +- return state.is(BlockTags.CLIMBABLE) || state.is(Blocks.POWDER_SNOW); ++ final int flags = state.tagFlag; ++ return (flags & (org.dreeam.leaf.util.BlockMasks.CLIMBABLE_TAG | org.dreeam.leaf.util.BlockMasks.POWDER_SNOW_CL)) != 0; + } + + private boolean vibrationAndSoundEffectsFromBlock(BlockPos pos, BlockState state, boolean playStepSound, boolean broadcastGameEvent, Vec3 entityPos) { diff --git a/leaf-server/minecraft-patches/features/0294-optimize-getOnPos.patch b/leaf-server/minecraft-patches/features/0294-optimize-getOnPos.patch new file mode 100644 index 00000000..e497fc8a --- /dev/null +++ b/leaf-server/minecraft-patches/features/0294-optimize-getOnPos.patch @@ -0,0 +1,350 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: hayanesuru +Date: Sat, 9 Aug 2025 15:43:17 +0900 +Subject: [PATCH] optimize getOnPos + + +diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java +index 3aec52d72cd5ffd2ef61b1f6c37c6b7f1203d06f..8c01317e1aa5cc588eb2d9e4d47de1da93d5146a 100644 +--- a/net/minecraft/world/entity/Entity.java ++++ b/net/minecraft/world/entity/Entity.java +@@ -895,6 +895,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + // CraftBukkit end + + public void baseTick() { ++ this.leaf$onBlockState = null; // Leaf ++ this.leaf$cacheOnBlock = true; // Leaf + if (firstTick && this instanceof net.minecraft.world.entity.NeutralMob neutralMob) neutralMob.tickInitialPersistentAnger(level); // Paper - Prevent entity loading causing async lookups + this.inBlockState = null; + if (this.isPassenger() && this.getVehicle().isRemoved()) { +@@ -954,6 +956,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + if (this.level() instanceof ServerLevel serverLevelx && this instanceof Leashable) { + Leashable.tickLeash(serverLevelx, (Entity & Leashable)this); + } ++ this.leaf$cacheOnBlock = false; // Leaf + } + + public void setSharedFlagOnFire(boolean isOnFire) { +@@ -1118,11 +1121,19 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + AABB aabb = new AABB(boundingBox.minX, boundingBox.minY - 1.0E-6, boundingBox.minZ, boundingBox.maxX, boundingBox.minY, boundingBox.maxZ); + Optional optional = this.level.findSupportingBlock(this, aabb); + if (optional.isPresent() || this.onGroundNoBlocks) { +- this.mainSupportingBlockPos = optional; ++ // Leaf start ++ if (mainSupportingBlockPos.isEmpty() || optional.isEmpty() || !mainSupportingBlockPos.get().equals(optional.get())) { ++ this.mainSupportingBlockPos = optional; ++ } ++ // Leaf end + } else if (movement != null) { + AABB aabb1 = aabb.move(-movement.x, 0.0, -movement.z); + optional = this.level.findSupportingBlock(this, aabb1); +- this.mainSupportingBlockPos = optional; ++ // Leaf start ++ if (mainSupportingBlockPos.isEmpty() || optional.isEmpty() || !mainSupportingBlockPos.get().equals(optional.get())) { ++ this.mainSupportingBlockPos = optional; ++ } ++ // Leaf end + } + + this.onGroundNoBlocks = optional.isEmpty(); +@@ -1207,8 +1218,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + this.minorHorizontalCollision = false; + } + +- BlockPos onPosLegacy = this.getOnPosLegacy(); +- BlockState blockState = this.level().getBlockState(onPosLegacy); ++ BlockState blockState = this.leaf$getOnBlockLegacy(); // Leaf ++ BlockPos onPosLegacy = this.leaf$getOnBlockPos(); // Leaf + if (this.isLocalInstanceAuthoritative()) { + this.checkFallDamage(vec3.y, this.onGround(), blockState, onPosLegacy); + } +@@ -1275,9 +1286,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + float f = 0.6F; + float f1 = (float)(movement.length() * 0.6F); + float f2 = (float)(movement.horizontalDistance() * 0.6F); +- BlockPos onPos = this.getOnPos(); +- BlockState blockState = this.level.getBlockStateIfLoadedUnchecked(onPos.getX(), onPos.getY(), onPos.getZ()); +- if (blockState == null) { blockState = this.level.getBlockState(onPos); } ++ BlockState blockState = this.leaf$getOnBlock0(); // Leaf ++ BlockPos onPos = this.leaf$getOnBlockPos(); // Leaf + boolean isStateClimbable = this.isStateClimbable(blockState); + this.moveDist += isStateClimbable ? f1 : f2; + this.flyDist += f1; +@@ -1346,8 +1356,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + private void applyEffectsFromBlocks(List movements) { + if (this.isAffectedByBlocks()) { + if (this.onGround()) { +- BlockPos onPosLegacy = this.getOnPosLegacy(); +- BlockState blockState = this.level().getBlockState(onPosLegacy); ++ BlockState blockState = this.leaf$getOnBlockLegacy(); // Leaf ++ BlockPos onPosLegacy = this.leaf$getOnBlockPos(); // Leaf + blockState.getBlock().stepOn(this.level(), onPosLegacy, blockState, this); + } + +@@ -1443,34 +1453,124 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + return this.getOnPos(0.2F); + } + ++ // Leaf start ++ @Deprecated ++ public BlockState leaf$getOnBlockLegacy() { ++ return this.leaf$getOnBlock(0.2F); ++ } ++ // Leaf end ++ + public BlockPos getBlockPosBelowThatAffectsMyMovement() { + return this.getOnPos(0.500001F); + } + ++ // Leaf start ++ public net.minecraft.world.level.block.state.BlockState leaf$getBlockBelow() { ++ return this.leaf$getOnBlock(0.500001F); ++ } ++ // Leaf end ++ + public BlockPos getOnPos() { + return this.getOnPos(1.0E-5F); + } + ++ // Leaf start ++ public BlockState leaf$getOnBlock0() { ++ return this.leaf$getOnBlock(1.0E-5F); ++ } ++ // Leaf end ++ + protected BlockPos getOnPos(float yOffset) { +- if (this.mainSupportingBlockPos.isPresent() && this.level().getChunkIfLoadedImmediately(this.mainSupportingBlockPos.get()) != null) { // Paper - ensure no loads ++ // Leaf start - optimize get chunk ++ if (this.mainSupportingBlockPos.isPresent()) { + BlockPos blockPos = this.mainSupportingBlockPos.get(); ++ int x = blockPos.getX(); ++ int y = blockPos.getY(); ++ int z = blockPos.getZ(); ++ net.minecraft.world.level.chunk.LevelChunk chunk = this.level.getChunkAtIfLoadedUnchecked(x >> 4, z >> 4); ++ if (chunk == null) { chunk = this.level.getChunk(x >> 4, z >> 4); } ++ BlockState blockState = chunk.getBlockStateFinal(x, y, z); + if (!(yOffset > 1.0E-5F)) { + return blockPos; +- } else { +- BlockState blockState = this.level().getBlockState(blockPos); +- return (!(yOffset <= 0.5) || !blockState.is(BlockTags.FENCES)) +- && !blockState.is(BlockTags.WALLS) +- && !(blockState.getBlock() instanceof FenceGateBlock) +- ? blockPos.atY(Mth.floor(this.position.y - yOffset)) +- : blockPos; + } ++ final int flags = blockState.tagFlag; ++ return (!(yOffset <= 0.5) || ((flags & org.dreeam.leaf.util.BlockMasks.FENCE_TAG) == 0)) ++ && ((flags & org.dreeam.leaf.util.BlockMasks.WALL_TAG) == 0) ++ && ((flags & org.dreeam.leaf.util.BlockMasks.FENCE_GATE_CL) == 0) ++ ? blockPos.atY(Mth.floor(this.position.y - yOffset)) ++ : blockPos; + } else { + int floor = Mth.floor(this.position.x); + int floor1 = Mth.floor(this.position.y - yOffset); + int floor2 = Mth.floor(this.position.z); + return new BlockPos(floor, floor1, floor2); + } ++ // Leaf end - optimize get chunk ++ } ++ ++ // Leaf start ++ @Nullable private BlockState leaf$onBlockState = null; ++ private BlockPos leaf$onBlockPos = BlockPos.ZERO; ++ public boolean leaf$cacheOnBlock = false; ++ ++ protected final BlockPos leaf$getOnBlockPos() { ++ return leaf$onBlockPos; ++ } ++ ++ protected final BlockState leaf$getOnBlock(float yOffset) { ++ if (this.mainSupportingBlockPos.isPresent()) { ++ BlockPos blockPos = this.mainSupportingBlockPos.get(); ++ int x = blockPos.getX(); ++ int y = blockPos.getY(); ++ int z = blockPos.getZ(); ++ net.minecraft.world.level.chunk.LevelChunk chunk = null; ++ if (leaf$onBlockPos != blockPos || leaf$onBlockState == null || !leaf$cacheOnBlock) { ++ chunk = this.level.getChunkAtIfLoadedUnchecked(x >> 4, z >> 4); ++ if (chunk == null) { ++ chunk = this.level.getChunk(x >> 4, z >> 4); ++ } ++ leaf$onBlockState = chunk.getBlockStateFinal(x, y, z); ++ leaf$onBlockPos = blockPos; ++ } ++ if (!(yOffset > 1.0E-5F)) { ++ return leaf$onBlockState; ++ } ++ final int flags = leaf$onBlockState.tagFlag; ++ if ((!(yOffset <= 0.5) || ((flags & org.dreeam.leaf.util.BlockMasks.FENCE_TAG) == 0)) ++ && ((flags & org.dreeam.leaf.util.BlockMasks.WALL_TAG) == 0) ++ && ((flags & org.dreeam.leaf.util.BlockMasks.FENCE_GATE_CL) == 0)) { ++ int y1 = Mth.floor(this.position.y - yOffset); ++ if (y1 != y) { ++ if (chunk == null) { ++ chunk = this.level.getChunk(x >> 4, z >> 4); ++ } ++ leaf$onBlockPos = new BlockPos(x, y1, z); ++ return leaf$onBlockState = chunk.getBlockStateFinal(x, y1, z); ++ } else { ++ return leaf$onBlockState; ++ } ++ } else { ++ return leaf$onBlockState; ++ } ++ } else { ++ int x = Mth.floor(this.position.x); ++ int y = Mth.floor(this.position.y - yOffset); ++ int z = Mth.floor(this.position.z); ++ boolean flag = leaf$onBlockPos.getX() != x || leaf$onBlockPos.getY() != y || leaf$onBlockPos.getZ() != z; ++ if (flag) { ++ leaf$onBlockPos = new BlockPos(x, y, z); ++ } ++ if (flag || leaf$onBlockState == null || !leaf$cacheOnBlock) { ++ net.minecraft.world.level.chunk.LevelChunk chunk = this.level.getChunkAtIfLoadedUnchecked(x >> 4, z >> 4); ++ if (chunk == null) { ++ chunk = this.level.getChunk(x >> 4, z >> 4); ++ } ++ leaf$onBlockState = chunk.getBlockStateFinal(x, y, z); ++ } ++ return leaf$onBlockState; ++ } + } ++ // Leaf end + + protected float getBlockJumpFactor() { + float jumpFactor = this.level().getBlockState(this.blockPosition()).getBlock().getJumpFactor(); +@@ -1482,7 +1582,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + BlockState blockState = this.level().getBlockState(this.blockPosition()); + float speedFactor = blockState.getBlock().getSpeedFactor(); + if (!blockState.is(Blocks.WATER) && !blockState.is(Blocks.BUBBLE_COLUMN)) { +- return speedFactor == 1.0 ? this.level().getBlockState(this.getBlockPosBelowThatAffectsMyMovement()).getBlock().getSpeedFactor() : speedFactor; ++ return speedFactor == 1.0 ? this.leaf$getBlockBelow().getBlock().getSpeedFactor() : speedFactor; // Leaf + } else { + return speedFactor; + } +@@ -2104,7 +2204,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + + @Deprecated + protected BlockState getBlockStateOnLegacy() { +- return this.level().getBlockState(this.getOnPosLegacy()); ++ return this.leaf$getOnBlockLegacy(); // Leaf + } + + public BlockState getBlockStateOn() { +@@ -2116,8 +2216,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + } + + protected void spawnSprintParticle() { +- BlockPos onPosLegacy = this.getOnPosLegacy(); +- BlockState blockState = this.level().getBlockState(onPosLegacy); ++ BlockState blockState = this.leaf$getOnBlockLegacy(); // Leaf ++ BlockPos onPosLegacy = this.leaf$getOnBlockPos(); // Leaf + if (blockState.getRenderShape() != RenderShape.INVISIBLE) { + Vec3 deltaMovement = this.getDeltaMovement(); + BlockPos blockPos = this.blockPosition(); +diff --git a/net/minecraft/world/entity/ExperienceOrb.java b/net/minecraft/world/entity/ExperienceOrb.java +index 3ee788b172240ccf38cb31385dff13364ccc4142..f61ccef92c46b13bbe53df1fca8a3b4798b006e4 100644 +--- a/net/minecraft/world/entity/ExperienceOrb.java ++++ b/net/minecraft/world/entity/ExperienceOrb.java +@@ -243,6 +243,13 @@ public class ExperienceOrb extends Entity { + return this.getOnPos(0.999999F); + } + ++ // Leaf start ++ @Override ++ public net.minecraft.world.level.block.state.BlockState leaf$getBlockBelow() { ++ return this.leaf$getOnBlock(0.999999F); ++ } ++ // Leaf end ++ + private void scanForMerges() { + if (this.level() instanceof ServerLevel) { + for (ExperienceOrb experienceOrb : this.level() +diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java +index f0a0a19e2adff03e73e75c3db831dbf74ebf3861..eb408f9318ce406b22c6dbb575f08329fb286ee0 100644 +--- a/net/minecraft/world/entity/LivingEntity.java ++++ b/net/minecraft/world/entity/LivingEntity.java +@@ -3087,7 +3087,11 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin + } + + public void travel(Vec3 travelVector) { +- FluidState fluidState = this.level().getFluidState(this.blockPosition()); ++ // Leaf start ++ BlockPos blockPos = this.blockPosition(); ++ FluidState fluidState = this.level().getFluidStateIfLoadedUnchecked(blockPos.getX(), blockPos.getY(), blockPos.getZ()); ++ if (fluidState == null) { this.level().getFluidState(blockPos); } ++ // Leaf end + if ((this.isInWater() || this.isInLava()) && this.isAffectedByFluids() && !this.canStandOnFluid(fluidState)) { + this.travelInFluid(travelVector); + } else if (this.isFallFlying()) { +@@ -3115,7 +3119,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin + if (this.getRider() != null && this.isControllable()) { + float friction = 0.91F; + if (this.onGround()) { +- friction = this.level().getBlockState(this.getBlockPosBelowThatAffectsMyMovement()).getBlock().getFriction() * 0.91F; ++ friction = this.leaf$getBlockBelow().getBlock().getFriction() * 0.91F; // Leaf + } + + float frictionCompensation = 0.16277137F / (friction * friction * friction); +@@ -3133,15 +3137,14 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin + } + + private void travelInAir(Vec3 travelVector) { +- BlockPos blockPosBelowThatAffectsMyMovement = this.getBlockPosBelowThatAffectsMyMovement(); +- float f = this.onGround() ? this.level().getBlockState(blockPosBelowThatAffectsMyMovement).getBlock().getFriction() : 1.0F; ++ float f = this.onGround() ? leaf$getBlockBelow().getBlock().getFriction() : 1.0F; // Leaf + float f1 = f * 0.91F; + Vec3 vec3 = this.handleRelativeFrictionAndCalculateMovement(travelVector, f); + double d = vec3.y; + MobEffectInstance effect = this.getEffect(MobEffects.LEVITATION); + if (effect != null) { + d += (0.05 * (effect.getAmplifier() + 1) - vec3.y) * 0.2; +- } else if (!this.level().isClientSide || this.level().hasChunkAt(blockPosBelowThatAffectsMyMovement)) { ++ } else if (!this.level().isClientSide) { // Leaf + d -= this.getEffectiveGravity(); + } else if (this.getY() > this.level().getMinY()) { + d = -0.1; +@@ -3682,6 +3685,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin + this.resetFallDistance(); + } + ++ this.leaf$cacheOnBlock = true; // Leaf + if (this.getControllingPassenger() instanceof Player player && this.isAlive()) { + this.travelRidden(player, vec3); + } else if (this.canSimulateMovement() && this.isEffectiveAi()) { +@@ -3691,6 +3695,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin + if (!this.level().isClientSide() || this.isLocalInstanceAuthoritative()) { + this.applyEffectsFromBlocks(); + } ++ this.leaf$cacheOnBlock = false; // Leaf + + if (this.level().isClientSide()) { + this.calculateEntityAnimation(this instanceof FlyingAnimal); +diff --git a/net/minecraft/world/entity/item/ItemEntity.java b/net/minecraft/world/entity/item/ItemEntity.java +index 52314a8fe4188689431f9a1261226859b967f5f1..e93cf31ddb1affcfcdaab380a6614c118a96eaa1 100644 +--- a/net/minecraft/world/entity/item/ItemEntity.java ++++ b/net/minecraft/world/entity/item/ItemEntity.java +@@ -204,7 +204,7 @@ public class ItemEntity extends Entity implements TraceableEntity { + f = 1F; + } else if (this.onGround()) { + // Paper end - Friction API +- f = this.level().getBlockState(this.getBlockPosBelowThatAffectsMyMovement()).getBlock().getFriction() * 0.98F; ++ f = this.leaf$getBlockBelow().getBlock().getFriction() * 0.98F; // Leaf + } + + this.setDeltaMovement(this.getDeltaMovement().multiply(f, 0.98, f)); +@@ -279,6 +279,13 @@ public class ItemEntity extends Entity implements TraceableEntity { + return this.getOnPos(0.999999F); + } + ++ // Leaf start ++ @Override ++ public net.minecraft.world.level.block.state.BlockState leaf$getBlockBelow() { ++ return this.leaf$getOnBlock(0.999999F); ++ } ++ // Leaf end ++ + private void setUnderwaterMovement() { + this.setFluidMovement(0.99F); + } diff --git a/leaf-server/minecraft-patches/features/0295-optimize-get-eye-block-position.patch b/leaf-server/minecraft-patches/features/0295-optimize-get-eye-block-position.patch new file mode 100644 index 00000000..7712d199 --- /dev/null +++ b/leaf-server/minecraft-patches/features/0295-optimize-get-eye-block-position.patch @@ -0,0 +1,122 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: hayanesuru +Date: Sat, 9 Aug 2025 15:43:24 +0900 +Subject: [PATCH] optimize get eye block position + + +diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java +index 8c01317e1aa5cc588eb2d9e4d47de1da93d5146a..11a0fcf040053f9e84db21b3890cdfdc330755f0 100644 +--- a/net/minecraft/world/entity/Entity.java ++++ b/net/minecraft/world/entity/Entity.java +@@ -553,20 +553,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + + // Leaf start - Fix Pufferfish and Purpur patches + // Gale start - JettPack - optimize sun burn tick - cache eye blockpos +- private BlockPos cached_eye_blockpos; +- private net.minecraft.world.phys.Vec3 cached_position; ++ private BlockPos leaf$cached_eye_blockpos = BlockPos.ZERO; ++ @Nullable private BlockPos leaf$cached_position = null; + // Gale end - JettPack - optimize sun burn tick - cache eye blockpos + // Purpur start - copied from Mob - API for any mob to burn daylight + public boolean isSunBurnTick() { + if (this.level().isBrightOutside() && !this.level().isClientSide) { + // Gale start - JettPack - optimize sun burn tick - optimizations and cache eye blockpos +- if (this.cached_position != this.position) { +- this.cached_eye_blockpos = BlockPos.containing(this.getX(), this.getEyeY(), this.getZ()); +- this.cached_position = this.position; +- } +- +- float lightLevelDependentMagicValue = this.getLightLevelDependentMagicValue(cached_eye_blockpos); // Pass BlockPos to getBrightness +- ++ float lightLevelDependentMagicValue = this.getLightLevelDependentMagicValue(); + // Check brightness first + if (lightLevelDependentMagicValue <= 0.5F) return false; + if (this.random.nextFloat() * 30.0F >= (lightLevelDependentMagicValue - 0.4F) * 2.0F) return false; +@@ -574,11 +568,22 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + + boolean flag = this.isInWaterOrRain() || this.isInPowderSnow || this.wasInPowderSnow; + +- return !flag && this.level().canSeeSky(this.cached_eye_blockpos); // Gale - JettPack - optimize sun burn tick - optimizations and cache eye blockpos ++ return !flag && this.level().canSeeSky(this.leaf$getEyeBlockPos()); // Gale - JettPack - optimize sun burn tick - optimizations and cache eye blockpos + } + + return false; // Gale - JettPack - optimize sun burn tick - optimizations and cache eye blockpos - diff on change + } ++ ++ // Leaf start ++ public BlockPos leaf$getEyeBlockPos() { ++ if (this.leaf$cached_position != this.blockPosition) { ++ this.leaf$cached_eye_blockpos = this.blockPosition.atY(Mth.floor(this.getEyeY())); ++ this.leaf$cached_position = this.blockPosition; ++ } ++ return this.leaf$cached_eye_blockpos; ++ } ++ // Leaf end ++ + // Purpur end - copied from Mob - API for any mob to burn daylight + // Leaf end - Fix Pufferfish and Purpur patches + +@@ -2152,8 +2157,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + && abstractBoat.getBoundingBox().maxY >= eyeY + && abstractBoat.getBoundingBox().minY <= eyeY + )) { +- BlockPos blockPos = BlockPos.containing(this.getX(), eyeY, this.getZ()); +- FluidState fluidState = this.level().getFluidState(blockPos); ++ BlockPos blockPos = leaf$getEyeBlockPos(); // Leaf ++ FluidState fluidState = this.level().getFluidStateIfLoadedUnchecked(blockPos.getX(), blockPos.getY(), blockPos.getZ()); // Leaf ++ if (fluidState == null) { fluidState = this.level().getFluidState(blockPos); } // Leaf + double d = blockPos.getY() + fluidState.getHeight(this.level(), blockPos); + if (d > eyeY) { + // Leaf start - Optimize isEyeInFluid +@@ -2281,20 +2287,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + + @Deprecated + public float getLightLevelDependentMagicValue() { +- return this.getLightLevelDependentMagicValue(BlockPos.containing(this.getX(), this.getEyeY(), this.getZ())); // Gale - JettPack - optimize sun burn tick - allow passing BlockPos to getLightLevelDependentMagicValue +- } +- +- // Gale start - JettPack - optimize sun burn tick - allow passing BlockPos to getLightLevelDependentMagicValue +- /** +- * @deprecated +- */ +- @Deprecated +- public float getLightLevelDependentMagicValue(BlockPos pos) { +- return this.level().hasChunkAt(this.getBlockX(), this.getBlockZ()) +- ? this.level.getLightLevelDependentMagicValue(pos) ++ return this.level.hasChunkAt(this.getBlockX(), this.getBlockZ()) // Leaf ++ ? this.level.getLightLevelDependentMagicValue(leaf$getEyeBlockPos()) // Leaf + : 0.0F; + } +- // Gale end - JettPack - optimize sun burn tick - allow passing BlockPos to getLightLevelDependentMagicValue + + public void absSnapTo(double x, double y, double z, float yRot, float xRot) { + this.absSnapTo(x, y, z); +@@ -4532,6 +4528,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + EntityDimensions dimensions = this.getDimensions(pose); + this.dimensions = dimensions; + this.eyeHeight = dimensions.eyeHeight(); ++ this.leaf$cached_position = null; // Leaf + } + + public void refreshDimensions() { +@@ -4540,6 +4537,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + EntityDimensions dimensions = this.getDimensions(pose); + this.dimensions = dimensions; + this.eyeHeight = dimensions.eyeHeight(); ++ this.leaf$cached_position = null; // Leaf + this.reapplyPosition(); + boolean flag = dimensions.width() <= 4.0F && dimensions.height() <= 4.0F; + if (!this.level.isClientSide +diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java +index eb408f9318ce406b22c6dbb575f08329fb286ee0..04e7bcf4cc004b4323a23dadf5d9d347ba5aa881 100644 +--- a/net/minecraft/world/entity/LivingEntity.java ++++ b/net/minecraft/world/entity/LivingEntity.java +@@ -464,7 +464,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin + } + + if (this.isEyeInWater() // Leaf - Optimize isEyeInFluid +- && !serverLevel1.getBlockState(BlockPos.containing(this.getX(), this.getEyeY(), this.getZ())).is(Blocks.BUBBLE_COLUMN)) { ++ && !serverLevel1.getBlockState(leaf$getEyeBlockPos()).is(Blocks.BUBBLE_COLUMN)) { // Leaf + boolean flag1 = !this.canBreatheUnderwater() + && !MobEffectUtil.hasWaterBreathing(this) + && (!flag || !((Player)this).getAbilities().invulnerable); diff --git a/leaf-server/minecraft-patches/features/0296-optimize-updateFluidHeightAndDoFluidPushing.patch b/leaf-server/minecraft-patches/features/0296-optimize-updateFluidHeightAndDoFluidPushing.patch new file mode 100644 index 00000000..77796944 --- /dev/null +++ b/leaf-server/minecraft-patches/features/0296-optimize-updateFluidHeightAndDoFluidPushing.patch @@ -0,0 +1,43 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: hayanesuru +Date: Sat, 9 Aug 2025 15:44:06 +0900 +Subject: [PATCH] optimize updateFluidHeightAndDoFluidPushing + + +diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java +index 11a0fcf040053f9e84db21b3890cdfdc330755f0..ae8154b4dea055c219797f00f357e56c74bcdace 100644 +--- a/net/minecraft/world/entity/Entity.java ++++ b/net/minecraft/world/entity/Entity.java +@@ -4933,12 +4933,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + final int minChunkZ = minBlockZ >> 4; + final int maxChunkZ = maxBlockZ >> 4; + +- final net.minecraft.world.level.chunk.ChunkSource chunkSource = world.getChunkSource(); ++ final net.minecraft.server.level.ServerChunkCache chunkSource = ((ServerLevel) world).chunkSource; // Leaf - optimize get chunk + + for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) { + for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) { + // Leaf start - Prevent double chunk retrieving in entity fluid pushing check and fluid height updating +- final net.minecraft.world.level.chunk.ChunkAccess chunk = chunkSource.getChunk(currChunkX, currChunkZ, net.minecraft.world.level.chunk.status.ChunkStatus.FULL, false); ++ final net.minecraft.world.level.chunk.LevelChunk chunk = chunkSource.fullChunksNonSync.get(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(currChunkX, currChunkZ)); + if (chunk == null) continue; + final net.minecraft.world.level.chunk.LevelChunkSection[] sections = chunk.getSections(); + // Leaf end - Prevent double chunk retrieving in entity fluid pushing check and fluid height updating +@@ -4950,7 +4950,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + continue; + } + final net.minecraft.world.level.chunk.LevelChunkSection section = sections[sectionIdx]; +- if (section.hasOnlyAir()) { ++ if (section.hasOnlyAir() || (fluid == FluidTags.WATER && section.waterFluidCount == 0) || (fluid == FluidTags.LAVA && section.lavaFluidCount == 0)) { + // empty + continue; + } +@@ -5007,7 +5007,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + + this.fluidHeight.put(fluid, maxHeightDiff); + +- if (pushVector.lengthSqr() == 0.0) { ++ if (pushVector == Vec3.ZERO || pushVector.lengthSqr() == 0.0) { + return inFluid; + } + diff --git a/leaf-server/minecraft-patches/features/0297-optimize-checkInsideBlocks.patch b/leaf-server/minecraft-patches/features/0297-optimize-checkInsideBlocks.patch new file mode 100644 index 00000000..b99db894 --- /dev/null +++ b/leaf-server/minecraft-patches/features/0297-optimize-checkInsideBlocks.patch @@ -0,0 +1,289 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: hayanesuru +Date: Sat, 9 Aug 2025 18:12:11 +0900 +Subject: [PATCH] optimize checkInsideBlocks + + +diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java +index ae8154b4dea055c219797f00f357e56c74bcdace..8a43dfcb5b8c041a80bd01611bdc8865a754e8cd 100644 +--- a/net/minecraft/world/entity/Entity.java ++++ b/net/minecraft/world/entity/Entity.java +@@ -1812,72 +1812,57 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + private void checkInsideBlocks(Vec3 vec3, Vec3 vec31, InsideBlockEffectApplier.StepBasedCollector stepBasedCollector, LongSet set) { + final Level level = this.level(); + AABB aabb = this.getBoundingBox().move(vec31.subtract(this.position())).deflate(1.0E-5F); +- final net.minecraft.world.level.chunk.ChunkAccess[] cachedChunk = { null }; +- final long[] cachedChunkPos = { Long.MIN_VALUE }; + +- BlockGetter.forEachBlockIntersectedBetween( ++ BlockGetter.leaf$forEachBlockIntersectedBetween( ++ set, + vec3, + vec31, + aabb, + (pos, index) -> { ++ final int posX = pos.getX(); ++ final int posY = pos.getY(); ++ final int posZ = pos.getZ(); ++ BlockState blockState = level.getBlockStateIfLoadedUnchecked(posX, posY, posZ); ++ if (blockState == null) { ++ blockState = level.getBlockState(pos); ++ } ++ if (blockState.isAir()) { ++ this.debugBlockIntersection(pos, false, false); ++ return true; ++ } + if (!this.isAlive()) { + return false; +- } else { +- final int chunkX = pos.getX() >> 4; +- final int chunkZ = pos.getZ() >> 4; +- final long currentChunkPos = ChunkPos.asLong(chunkX, chunkZ); +- BlockState blockState; +- +- if (cachedChunkPos[0] != currentChunkPos) {cachedChunk[0] = level.getChunkIfLoaded(chunkX, chunkZ);cachedChunkPos[0] = currentChunkPos;} +- +- if (cachedChunk[0] != null) {blockState = cachedChunk[0].getBlockState(pos); +- } else { +- blockState = level.getBlockStateIfLoaded(pos); +- if (blockState == null) {blockState = Blocks.AIR.defaultBlockState();} ++ } ++ VoxelShape entityInsideCollisionShape = blockState.getEntityInsideCollisionShape(level, pos, this); ++ boolean flag = entityInsideCollisionShape == Shapes.block() ++ || this.collidedWithShapeMovingFrom(vec3, vec31, entityInsideCollisionShape.move(new Vec3(pos)).toAabbs()); ++ if (flag) { ++ try { ++ stepBasedCollector.advanceStep(index, pos); // Paper - track position inside effect was triggered on ++ blockState.entityInside(level, pos, this, stepBasedCollector); ++ this.onInsideBlock(blockState); ++ } catch (Throwable var14) { ++ CrashReport crashReport = CrashReport.forThrowable(var14, "Colliding entity with block"); ++ CrashReportCategory crashReportCategory = crashReport.addCategory("Block being collided with"); ++ CrashReportCategory.populateBlockDetails(crashReportCategory, level, pos, blockState); ++ CrashReportCategory crashReportCategory1 = crashReport.addCategory("Entity being checked for collision"); ++ this.fillCrashReportCategory(crashReportCategory1); ++ throw new ReportedException(crashReport); + } ++ } + +- final long posLong = pos.asLong(); +- if (blockState.isAir()) { +- this.debugBlockIntersection(pos, false, false); +- return true; +- } else if (!set.add(posLong)) { +- return true; +- } else { +- VoxelShape entityInsideCollisionShape = blockState.getEntityInsideCollisionShape(level, pos, this); +- boolean flag = entityInsideCollisionShape == Shapes.block() +- || this.collidedWithShapeMovingFrom(vec3, vec31, entityInsideCollisionShape.move(new Vec3(pos)).toAabbs()); +- +- if (flag) { +- try { +- stepBasedCollector.advanceStep(index, pos); // Paper - track position inside effect was triggered on +- blockState.entityInside(level, pos, this, stepBasedCollector); +- this.onInsideBlock(blockState); +- } catch (Throwable var14) { +- CrashReport crashReport = CrashReport.forThrowable(var14, "Colliding entity with block"); +- CrashReportCategory crashReportCategory = crashReport.addCategory("Block being collided with"); +- CrashReportCategory.populateBlockDetails(crashReportCategory, level, pos, blockState); +- CrashReportCategory crashReportCategory1 = crashReport.addCategory("Entity being checked for collision"); +- this.fillCrashReportCategory(crashReportCategory1); +- throw new ReportedException(crashReport); +- } +- } +- +- final FluidState fluidState = blockState.getFluidState(); +- boolean flag1 = !fluidState.isEmpty() && this.collidedWithFluid(fluidState, pos, vec3, vec31); +- +- if (flag1) { +- stepBasedCollector.advanceStep(index, pos); // Paper - track position inside effect was triggered on +- fluidState.entityInside(level, pos, this, stepBasedCollector); +- } +- +- this.debugBlockIntersection(pos, flag, flag1); +- return true; +- } ++ boolean flag1 = (blockState.tagFlag & org.dreeam.leaf.util.BlockMasks.FLUID) != 0 ++ && this.collidedWithFluid(blockState.getFluidState(), pos, vec3, vec31); ++ if (flag1) { ++ stepBasedCollector.advanceStep(index, pos); // Paper - track position inside effect was triggered on ++ blockState.getFluidState().entityInside(level, pos, this, stepBasedCollector); + } ++ this.debugBlockIntersection(pos, flag, flag1); ++ return true; + } + ); + } +-// Leaf end - optimize checkInsideBlocks calls ++ // Leaf end - optimize checkInsideBlocks calls + + private void debugBlockIntersection(BlockPos blockPos, boolean flag, boolean flag1) { + } +diff --git a/net/minecraft/world/entity/InsideBlockEffectApplier.java b/net/minecraft/world/entity/InsideBlockEffectApplier.java +index 92b9c324cb6aab415abe2e77c5844b74c251a42f..eba3896b73c70f29732388373e89bf7ce3a07c92 100644 +--- a/net/minecraft/world/entity/InsideBlockEffectApplier.java ++++ b/net/minecraft/world/entity/InsideBlockEffectApplier.java +@@ -33,6 +33,7 @@ public interface InsideBlockEffectApplier { + // Leaf start - optimize checkInsideBlocks calls + private static final InsideBlockEffectType[] APPLY_ORDER = InsideBlockEffectType.values(); + private static final int NO_STEP = -1; ++ private int flags = 0; + + private final Consumer[] effectsInStep = new Consumer[APPLY_ORDER.length]; + private final List>[] beforeEffectsInStep = new List[APPLY_ORDER.length]; +@@ -40,13 +41,13 @@ public interface InsideBlockEffectApplier { + + private static final List> EMPTY_LIST = List.of(); + +- private final List> finalEffects = new ArrayList<>(); ++ private final List> finalEffects = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(); + private int lastStep = -1; + + public StepBasedCollector() { + for (int i = 0; i < APPLY_ORDER.length; i++) { +- beforeEffectsInStep[i] = new ArrayList<>(2); +- afterEffectsInStep[i] = new ArrayList<>(2); ++ beforeEffectsInStep[i] = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(2); ++ afterEffectsInStep[i] = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(2); + } + } + +@@ -100,6 +101,10 @@ public interface InsideBlockEffectApplier { + } + + private void flushStep() { ++ final int flags = this.flags; ++ if (flags == 0) { ++ return; ++ } + final int len = APPLY_ORDER.length; + final List>[] beforeArr = this.beforeEffectsInStep; + final Consumer[] effectArr = this.effectsInStep; +@@ -107,6 +112,9 @@ public interface InsideBlockEffectApplier { + final List> finalList = this.finalEffects; + + for (int i = 0; i < len; i++) { ++ if (((1 << i) & flags) == 0) { ++ continue; ++ } + // Process before effects + List> beforeList = beforeArr[i]; + if (!beforeList.isEmpty()) { +@@ -128,21 +136,28 @@ public interface InsideBlockEffectApplier { + afterList.clear(); + } + } ++ this.flags = 0; + } + + @Override + public void apply(InsideBlockEffectType type) { +- effectsInStep[type.ordinal()] = recorded(type); ++ int i = type.ordinal(); ++ effectsInStep[i] = recorded(type); ++ this.flags |= 1 << i; + } + + @Override + public void runBefore(InsideBlockEffectType type, Consumer effect) { +- beforeEffectsInStep[type.ordinal()].add(effect); ++ int i = type.ordinal(); ++ beforeEffectsInStep[i].add(effect); ++ this.flags |= 1 << i; + } + + @Override + public void runAfter(InsideBlockEffectType type, Consumer effect) { +- afterEffectsInStep[type.ordinal()].add(effect); ++ int i = type.ordinal(); ++ afterEffectsInStep[i].add(effect); ++ this.flags |= 1 << i; + } + + // Paper start - track position inside effect was triggered on +diff --git a/net/minecraft/world/level/BlockGetter.java b/net/minecraft/world/level/BlockGetter.java +index eeddffbe6a47dc1a42c07f286bfec0cbde33fc17..b0da274c944fcef6aaae39b43f05a79110e4bb16 100644 +--- a/net/minecraft/world/level/BlockGetter.java ++++ b/net/minecraft/world/level/BlockGetter.java +@@ -255,6 +255,81 @@ public interface BlockGetter extends LevelHeightAccessor { + } + } + ++ // Leaf start ++ static boolean leaf$forEachBlockIntersectedBetween(it.unimi.dsi.fastutil.longs.LongSet set, Vec3 from, Vec3 to, AABB boundingBox, BlockGetter.BlockStepVisitor visitor) { ++ Vec3 vec3 = to.subtract(from); ++ BlockPos.MutableBlockPos cursor = new BlockPos.MutableBlockPos(); ++ if (vec3.lengthSqr() < Mth.square(0.99999F)) { ++ int pos1x = Mth.floor(boundingBox.minX); ++ int pos1y = Mth.floor(boundingBox.minY); ++ int pos1z = Mth.floor(boundingBox.minZ); ++ int pos2x = Mth.floor(boundingBox.maxX); ++ int pos2y = Mth.floor(boundingBox.maxY); ++ int pos2z = Mth.floor(boundingBox.maxZ); ++ int x1 = Math.min(pos1x, pos2x); ++ int y1 = Math.min(pos1y, pos2y); ++ int z1 = Math.min(pos1z, pos2z); ++ int i = Math.max(pos1x, pos2x) - x1 + 1; ++ int i1 = Math.max(pos1y, pos2y) - y1 + 1; ++ int i2 = Math.max(pos1z, pos2z) - z1 + 1; ++ int i3 = i * i1 * i2; ++ int index = 0; ++ while (index != i3) { ++ int i4 = index % i; ++ int i5 = index / i; ++ int i6 = i5 % i1; ++ int i7 = i5 / i1; ++ index++; ++ int x0 = x1 + i4; ++ int y0 = y1 + i6; ++ int z0 = z1 + i7; ++ if (set.add(BlockPos.asLong(x0, y0, z0)) && !visitor.visit(cursor.set(x0, y0, z0), 0)) { ++ return false; ++ } ++ } ++ ++ return true; ++ } else { ++ Vec3 minPosition = boundingBox.getMinPosition(); ++ Vec3 vec31 = minPosition.subtract(vec3); ++ int i = addCollisionsAlongTravel(set, vec31, minPosition, boundingBox, visitor); ++ if (i < 0) { ++ return false; ++ } else { ++ int pos1x = Mth.floor(boundingBox.minX); ++ int pos1y = Mth.floor(boundingBox.minY); ++ int pos1z = Mth.floor(boundingBox.minZ); ++ int pos2x = Mth.floor(boundingBox.maxX); ++ int pos2y = Mth.floor(boundingBox.maxY); ++ int pos2z = Mth.floor(boundingBox.maxZ); ++ int x1 = Math.min(pos1x, pos2x); ++ int y1 = Math.min(pos1y, pos2y); ++ int z1 = Math.min(pos1z, pos2z); ++ int j = Math.max(pos1x, pos2x) - x1 + 1; ++ int i1 = Math.max(pos1y, pos2y) - y1 + 1; ++ int i2 = Math.max(pos1z, pos2z) - z1 + 1; ++ int i3 = j * i1 * i2; ++ int index = 0; ++ while (index != i3) { ++ int i4 = index % j; ++ int i5 = index / j; ++ int i6 = i5 % i1; ++ int i7 = i5 / i1; ++ index++; ++ int x0 = x1 + i4; ++ int y0 = y1 + i6; ++ int z0 = z1 + i7; ++ if (set.add(BlockPos.asLong(x0, y0, z0)) && !visitor.visit(cursor.set(x0, y0, z0), i + 1)) { ++ return false; ++ } ++ } ++ ++ return true; ++ } ++ } ++ } ++ // Leaf end ++ + private static int addCollisionsAlongTravel(LongSet output, Vec3 from, Vec3 to, AABB boundingBox, BlockGetter.BlockStepVisitor stepVisitor) { + Vec3 vec3 = to.subtract(from); + int floor = Mth.floor(from.x); diff --git a/leaf-server/minecraft-patches/features/0298-Replace-fluid-height-map.patch b/leaf-server/minecraft-patches/features/0298-Replace-fluid-height-map.patch new file mode 100644 index 00000000..421d35a5 --- /dev/null +++ b/leaf-server/minecraft-patches/features/0298-Replace-fluid-height-map.patch @@ -0,0 +1,19 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: hayanesuru +Date: Sun, 10 Aug 2025 16:14:07 +0900 +Subject: [PATCH] Replace fluid height map + + +diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java +index 8a43dfcb5b8c041a80bd01611bdc8865a754e8cd..7dda8c5db2bbbfe04db07b1a053489b4d19f3f09 100644 +--- a/net/minecraft/world/entity/Entity.java ++++ b/net/minecraft/world/entity/Entity.java +@@ -286,7 +286,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + public int tickCount; + private int remainingFireTicks; + public boolean wasTouchingWater; +- protected Object2DoubleMap> fluidHeight = new Object2DoubleArrayMap<>(2); ++ protected Object2DoubleMap> fluidHeight = new org.dreeam.leaf.util.map.FluidHeightMap(); // Leaf - Replace fluid height map + protected boolean wasEyeInWater; + // Leaf start - Optimize isEyeInFluid + // Remove original field since plugin should not direct access to it, and able to diff --git a/leaf-server/minecraft-patches/features/0299-optimize-collision-shape.patch b/leaf-server/minecraft-patches/features/0299-optimize-collision-shape.patch new file mode 100644 index 00000000..5a26b822 --- /dev/null +++ b/leaf-server/minecraft-patches/features/0299-optimize-collision-shape.patch @@ -0,0 +1,24 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: hayanesuru +Date: Mon, 11 Aug 2025 02:19:41 +0900 +Subject: [PATCH] optimize collision shape + + +diff --git a/net/minecraft/world/level/block/state/BlockBehaviour.java b/net/minecraft/world/level/block/state/BlockBehaviour.java +index 9caac78f0dbadc838753e2db7b757b70cea2fae8..782b5e58bc7a528d896a5b182476ba6fa3f8abc4 100644 +--- a/net/minecraft/world/level/block/state/BlockBehaviour.java ++++ b/net/minecraft/world/level/block/state/BlockBehaviour.java +@@ -623,6 +623,13 @@ public abstract class BlockBehaviour implements FeatureElement { + this.emptyConstantCollisionShape = this.constantCollisionShape != null && this.constantCollisionShape.isEmpty(); + // init caches + initCaches(collisionShape, true); ++ // Leaf start ++ switch (getBlock()) { ++ case net.minecraft.world.level.block.FireBlock fireBlock -> {} ++ case net.minecraft.world.level.block.LiquidBlock liquidBlock -> {} ++ default -> this.constantCollisionShape = collisionShape; ++ } ++ // Leaf end + if (this.constantCollisionShape != null) { + initCaches(this.constantCollisionShape, true); + } diff --git a/leaf-server/minecraft-patches/features/0300-cache-collision-list.patch b/leaf-server/minecraft-patches/features/0300-cache-collision-list.patch new file mode 100644 index 00000000..8bba5402 --- /dev/null +++ b/leaf-server/minecraft-patches/features/0300-cache-collision-list.patch @@ -0,0 +1,82 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: hayanesuru +Date: Mon, 11 Aug 2025 02:19:59 +0900 +Subject: [PATCH] cache collision list + + +diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java +index ba9efafd8e58e1dee7d871892906f85b4cbdf89a..4599332ae1fd488c29e1f9332f557d3ee417ce47 100644 +--- a/net/minecraft/server/level/ServerLevel.java ++++ b/net/minecraft/server/level/ServerLevel.java +@@ -1095,6 +1095,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + public final org.dreeam.leaf.world.DespawnMap despawnMap = new org.dreeam.leaf.world.DespawnMap(paperConfig()); // Leaf - optimize despawn + public final org.dreeam.leaf.world.NatureSpawnChunkMap natureSpawnChunkMap = new org.dreeam.leaf.world.NatureSpawnChunkMap(); // Leaf - optimize mob spawning + public final org.dreeam.leaf.world.RandomTickSystem randomTickSystem = new org.dreeam.leaf.world.RandomTickSystem(); // Leaf - optimize random tick ++ public final org.dreeam.leaf.world.EntityCollisionCache entityCollisionCache = new org.dreeam.leaf.world.EntityCollisionCache(); // Leaf ++ + public void tickChunk(LevelChunk chunk, int randomTickSpeed) { + final net.minecraft.world.level.levelgen.BitRandomSource simpleRandom = this.simpleRandom; // Paper - optimise random ticking // Leaf - Faster random generator - upcasting + ChunkPos pos = chunk.getPos(); +diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java +index 7dda8c5db2bbbfe04db07b1a053489b4d19f3f09..2b0c5d5920a3df8c4d6076c45d3191976f7abfec 100644 +--- a/net/minecraft/world/entity/Entity.java ++++ b/net/minecraft/world/entity/Entity.java +@@ -1641,8 +1641,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + + final AABB currentBox = this.getBoundingBox(); + +- final List potentialCollisionsVoxel = new ArrayList<>(); +- final List potentialCollisionsBB = new ArrayList<>(); ++ // final List potentialCollisionsVoxel = new ArrayList<>(); // Leaf ++ // final List potentialCollisionsBB = new ArrayList<>(); // Leaf + + final AABB initialCollisionBox; + if (xZero & zZero) { +@@ -1654,17 +1654,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + initialCollisionBox = currentBox.expandTowards(movement); + } + +- final List entityAABBs = new ArrayList<>(); ++ org.dreeam.leaf.world.EntityCollisionCache entityCollisionCache = ((ServerLevel) this.level).entityCollisionCache; // Leaf + ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.getEntityHardCollisions( +- this.level, (Entity)(Object)this, initialCollisionBox, entityAABBs, 0, null ++ this.level, (Entity)(Object)this, initialCollisionBox, entityCollisionCache.entityAABBs(), 0, null // Leaf + ); + + ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.getCollisionsForBlocksOrWorldBorder( +- this.level, (Entity)(Object)this, initialCollisionBox, potentialCollisionsVoxel, potentialCollisionsBB, ++ this.level, (Entity)(Object)this, initialCollisionBox, entityCollisionCache.potentialCollisionsVoxel(), entityCollisionCache.potentialCollisionsBB(), + ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_FLAG_CHECK_BORDER, null + ); +- potentialCollisionsBB.addAll(entityAABBs); +- final Vec3 collided = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performCollisions(movement, currentBox, potentialCollisionsVoxel, potentialCollisionsBB); ++ entityCollisionCache.potentialCollisionsBB().addAll(entityCollisionCache.entityAABBs()); // Leaf ++ final Vec3 collided = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performCollisions(movement, currentBox, entityCollisionCache.potentialCollisionsVoxel(), entityCollisionCache.potentialCollisionsBB()); // Leaf + + final boolean collidedX = collided.x != movement.x; + final boolean collidedY = collided.y != movement.y; +@@ -1675,6 +1675,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + final double stepHeight; + + if ((!collidedDownwards && !this.onGround) || (!collidedX && !collidedZ) || (stepHeight = (double)this.maxUpStep()) <= 0.0) { ++ entityCollisionCache.clear(); // Leaf + return collided; + } + +@@ -1685,7 +1686,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + } + + final List stepVoxels = new ArrayList<>(); +- final List stepAABBs = entityAABBs; ++ final List stepAABBs = entityCollisionCache.entityAABBs(); // Leaf + + ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.getCollisionsForBlocksOrWorldBorder( + this.level, (Entity)(Object)this, stepRetrievalBox, stepVoxels, stepAABBs, +@@ -1699,6 +1700,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + } + } + ++ entityCollisionCache.clear(); // Leaf + return collided; + // Paper end - optimise collisions + } diff --git a/leaf-server/paper-patches/features/0043-EMC-Don-t-use-snapshots-for-acquiring-blockstate.patch b/leaf-server/paper-patches/features/0042-EMC-Don-t-use-snapshots-for-acquiring-blockstate.patch similarity index 100% rename from leaf-server/paper-patches/features/0043-EMC-Don-t-use-snapshots-for-acquiring-blockstate.patch rename to leaf-server/paper-patches/features/0042-EMC-Don-t-use-snapshots-for-acquiring-blockstate.patch diff --git a/leaf-server/paper-patches/features/0044-Faster-CraftServer-getworlds-list-creation.patch b/leaf-server/paper-patches/features/0043-Faster-CraftServer-getworlds-list-creation.patch similarity index 100% rename from leaf-server/paper-patches/features/0044-Faster-CraftServer-getworlds-list-creation.patch rename to leaf-server/paper-patches/features/0043-Faster-CraftServer-getworlds-list-creation.patch diff --git a/leaf-server/paper-patches/features/0045-Cache-chunk-key.patch b/leaf-server/paper-patches/features/0044-Cache-chunk-key.patch similarity index 100% rename from leaf-server/paper-patches/features/0045-Cache-chunk-key.patch rename to leaf-server/paper-patches/features/0044-Cache-chunk-key.patch diff --git a/leaf-server/paper-patches/features/0047-PlayerInventoryOverflowEvent.patch b/leaf-server/paper-patches/features/0045-PlayerInventoryOverflowEvent.patch similarity index 100% rename from leaf-server/paper-patches/features/0047-PlayerInventoryOverflowEvent.patch rename to leaf-server/paper-patches/features/0045-PlayerInventoryOverflowEvent.patch diff --git a/leaf-server/paper-patches/features/0048-Paper-PR-Fix-MC-117075-Block-Entities-Unload-Lag-Spi.patch b/leaf-server/paper-patches/features/0046-Paper-PR-Fix-MC-117075-Block-Entities-Unload-Lag-Spi.patch similarity index 100% rename from leaf-server/paper-patches/features/0048-Paper-PR-Fix-MC-117075-Block-Entities-Unload-Lag-Spi.patch rename to leaf-server/paper-patches/features/0046-Paper-PR-Fix-MC-117075-Block-Entities-Unload-Lag-Spi.patch diff --git a/leaf-server/paper-patches/features/0049-SparklyPaper-Parallel-world-ticking.patch b/leaf-server/paper-patches/features/0047-SparklyPaper-Parallel-world-ticking.patch similarity index 99% rename from leaf-server/paper-patches/features/0049-SparklyPaper-Parallel-world-ticking.patch rename to leaf-server/paper-patches/features/0047-SparklyPaper-Parallel-world-ticking.patch index 73650ae5..5d81a87c 100644 --- a/leaf-server/paper-patches/features/0049-SparklyPaper-Parallel-world-ticking.patch +++ b/leaf-server/paper-patches/features/0047-SparklyPaper-Parallel-world-ticking.patch @@ -6,7 +6,7 @@ Subject: [PATCH] SparklyPaper: Parallel world ticking Original project: https://github.com/SparklyPower/SparklyPaper diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java -index a4aa2615823d77920ff55b8aa0bcc27a54b8c3e1..e1bf7dfdb3be8f92ef2cb86d7f15a613b4ccadff 100644 +index 69cdd304d255d52c9b7dc9b6a33ffdb630b79abe..09dfab1ace05ee62df5cf6e292f8be0146e85a36 100644 --- a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java +++ b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java @@ -14,6 +14,7 @@ import java.util.concurrent.atomic.AtomicInteger; @@ -164,7 +164,7 @@ index a4aa2615823d77920ff55b8aa0bcc27a54b8c3e1..e1bf7dfdb3be8f92ef2cb86d7f15a613 public final int id; /* We don't override getId as the spec requires that it be unique (with respect to all other threads) */ private static final AtomicInteger ID_GENERATOR = new AtomicInteger(); -@@ -133,46 +200,74 @@ public class TickThread extends Thread { +@@ -127,46 +194,74 @@ public class TickThread extends Thread { } public static boolean isTickThreadFor(final Level world, final BlockPos pos) { @@ -251,7 +251,7 @@ index a4aa2615823d77920ff55b8aa0bcc27a54b8c3e1..e1bf7dfdb3be8f92ef2cb86d7f15a613 + // SparklyPaper end - parallel world ticking } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 8c597b54491521f759e2983329a522ba065c647f..10a1f9cf6a558037be7b91e7dfa102a4a5f3c104 100644 +index 61121d2efd0df2fcafdc4c272e1cd1b986f42e24..ee5f342995a335593932a497c2bafd36d34cecb2 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -480,7 +480,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -327,7 +327,7 @@ index 8c597b54491521f759e2983329a522ba065c647f..10a1f9cf6a558037be7b91e7dfa102a4 if (this.world.hasChunkAt(pos)) { net.minecraft.world.level.chunk.LevelChunk chunk = this.world.getChunkAt(pos); -@@ -2358,6 +2378,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -2319,6 +2339,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void sendGameEvent(Entity sourceEntity, org.bukkit.GameEvent gameEvent, Vector position) { diff --git a/leaf-server/paper-patches/features/0050-Paper-PR-Throttle-failed-spawn-attempts.patch b/leaf-server/paper-patches/features/0048-Paper-PR-Throttle-failed-spawn-attempts.patch similarity index 100% rename from leaf-server/paper-patches/features/0050-Paper-PR-Throttle-failed-spawn-attempts.patch rename to leaf-server/paper-patches/features/0048-Paper-PR-Throttle-failed-spawn-attempts.patch diff --git a/leaf-server/paper-patches/features/0051-Async-playerdata-saving.patch b/leaf-server/paper-patches/features/0049-Async-playerdata-saving.patch similarity index 100% rename from leaf-server/paper-patches/features/0051-Async-playerdata-saving.patch rename to leaf-server/paper-patches/features/0049-Async-playerdata-saving.patch diff --git a/leaf-server/paper-patches/features/0052-Async-chunk-sending.patch b/leaf-server/paper-patches/features/0050-Async-chunk-sending.patch similarity index 100% rename from leaf-server/paper-patches/features/0052-Async-chunk-sending.patch rename to leaf-server/paper-patches/features/0050-Async-chunk-sending.patch diff --git a/leaf-server/paper-patches/features/0053-Optimise-player-movement-checks.patch b/leaf-server/paper-patches/features/0051-Optimise-player-movement-checks.patch similarity index 100% rename from leaf-server/paper-patches/features/0053-Optimise-player-movement-checks.patch rename to leaf-server/paper-patches/features/0051-Optimise-player-movement-checks.patch diff --git a/leaf-server/paper-patches/features/0054-optimise-ReferenceList.patch b/leaf-server/paper-patches/features/0052-optimise-ReferenceList.patch similarity index 100% rename from leaf-server/paper-patches/features/0054-optimise-ReferenceList.patch rename to leaf-server/paper-patches/features/0052-optimise-ReferenceList.patch diff --git a/leaf-server/paper-patches/features/0055-cache-getBiome.patch b/leaf-server/paper-patches/features/0053-cache-getBiome.patch similarity index 100% rename from leaf-server/paper-patches/features/0055-cache-getBiome.patch rename to leaf-server/paper-patches/features/0053-cache-getBiome.patch diff --git a/leaf-server/paper-patches/features/0056-dump-pwt-thread.patch b/leaf-server/paper-patches/features/0054-dump-pwt-thread.patch similarity index 100% rename from leaf-server/paper-patches/features/0056-dump-pwt-thread.patch rename to leaf-server/paper-patches/features/0054-dump-pwt-thread.patch diff --git a/leaf-server/paper-patches/features/0057-Paw-optimization.patch b/leaf-server/paper-patches/features/0055-Paw-optimization.patch similarity index 100% rename from leaf-server/paper-patches/features/0057-Paw-optimization.patch rename to leaf-server/paper-patches/features/0055-Paw-optimization.patch diff --git a/leaf-server/paper-patches/features/0058-optimize-despawn.patch b/leaf-server/paper-patches/features/0056-optimize-despawn.patch similarity index 100% rename from leaf-server/paper-patches/features/0058-optimize-despawn.patch rename to leaf-server/paper-patches/features/0056-optimize-despawn.patch diff --git a/leaf-server/paper-patches/features/0059-optimize-mob-spawning.patch b/leaf-server/paper-patches/features/0057-optimize-mob-spawning.patch similarity index 100% rename from leaf-server/paper-patches/features/0059-optimize-mob-spawning.patch rename to leaf-server/paper-patches/features/0057-optimize-mob-spawning.patch diff --git a/leaf-server/paper-patches/features/0060-Toggleable-async-catcher.patch b/leaf-server/paper-patches/features/0058-Toggleable-async-catcher.patch similarity index 100% rename from leaf-server/paper-patches/features/0060-Toggleable-async-catcher.patch rename to leaf-server/paper-patches/features/0058-Toggleable-async-catcher.patch diff --git a/leaf-server/paper-patches/features/0061-Op-lock.patch b/leaf-server/paper-patches/features/0059-Op-lock.patch similarity index 100% rename from leaf-server/paper-patches/features/0061-Op-lock.patch rename to leaf-server/paper-patches/features/0059-Op-lock.patch diff --git a/leaf-server/paper-patches/features/0062-cache-profile-data.patch b/leaf-server/paper-patches/features/0060-cache-profile-data.patch similarity index 100% rename from leaf-server/paper-patches/features/0062-cache-profile-data.patch rename to leaf-server/paper-patches/features/0060-cache-profile-data.patch diff --git a/leaf-server/paper-patches/features/0063-Bump-netty-to-4.2.x.patch b/leaf-server/paper-patches/features/0061-Bump-netty-to-4.2.x.patch similarity index 100% rename from leaf-server/paper-patches/features/0063-Bump-netty-to-4.2.x.patch rename to leaf-server/paper-patches/features/0061-Bump-netty-to-4.2.x.patch diff --git a/leaf-server/src/main/java/org/dreeam/leaf/async/ShutdownExecutors.java b/leaf-server/src/main/java/org/dreeam/leaf/async/ShutdownExecutors.java index 10d97215..501d135a 100644 --- a/leaf-server/src/main/java/org/dreeam/leaf/async/ShutdownExecutors.java +++ b/leaf-server/src/main/java/org/dreeam/leaf/async/ShutdownExecutors.java @@ -3,7 +3,6 @@ package org.dreeam.leaf.async; import net.minecraft.server.MinecraftServer; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.dreeam.leaf.async.locate.AsyncLocator; import org.dreeam.leaf.async.path.AsyncPathProcessor; import org.dreeam.leaf.async.tracker.AsyncTracker; @@ -48,14 +47,5 @@ public class ShutdownExecutors { } catch (InterruptedException ignored) { } } - - if (AsyncLocator.LOCATING_EXECUTOR_SERVICE != null) { - LOGGER.info("Waiting for structure locating executor to shutdown..."); - AsyncLocator.LOCATING_EXECUTOR_SERVICE.shutdown(); - try { - AsyncLocator.LOCATING_EXECUTOR_SERVICE.awaitTermination(60L, TimeUnit.SECONDS); - } catch (InterruptedException ignored) { - } - } } } diff --git a/leaf-server/src/main/java/org/dreeam/leaf/util/map/FluidHeightMap.java b/leaf-server/src/main/java/org/dreeam/leaf/util/map/FluidHeightMap.java new file mode 100644 index 00000000..00688538 --- /dev/null +++ b/leaf-server/src/main/java/org/dreeam/leaf/util/map/FluidHeightMap.java @@ -0,0 +1,162 @@ +package org.dreeam.leaf.util.map; + +import it.unimi.dsi.fastutil.objects.AbstractObject2DoubleMap; +import it.unimi.dsi.fastutil.objects.AbstractObjectSet; +import it.unimi.dsi.fastutil.objects.ObjectIterator; +import it.unimi.dsi.fastutil.objects.ObjectSet; +import net.minecraft.tags.FluidTags; +import net.minecraft.tags.TagKey; +import net.minecraft.world.level.material.Fluid; + +import java.util.NoSuchElementException; + +public final class FluidHeightMap extends AbstractObject2DoubleMap> { + private double water = 0.0; + private double lava = 0.0; + + @Override + public int size() { + return 2; + } + + @Override + public ObjectSet>> object2DoubleEntrySet() { + return new EntrySet(); + } + + @Override + public double getDouble(Object k) { + return k == FluidTags.WATER ? water : k == FluidTags.LAVA ? lava : 0.0; + } + + @Override + public double put(TagKey k, double v) { + if (k == FluidTags.WATER) { + double prev = this.water; + this.water = v; + return prev; + } else if (k == FluidTags.LAVA) { + double prev = this.lava; + this.lava = v; + return prev; + } + return 0.0; + } + + @Override + public void clear() { + this.water = 0.0; + this.lava = 0.0; + } + + private final class EntrySet extends AbstractObjectSet>> { + @Override + public ObjectIterator>> iterator() { + return new EntryIterator(); + } + + @Override + public int size() { + return 2; + } + + @Override + public boolean contains(Object o) { + if (!(o instanceof Entry entry)) { + return false; + } + Object key = entry.getKey(); + if (key == FluidTags.WATER) { + return entry.getDoubleValue() == water; + } else if (key == FluidTags.LAVA) { + return entry.getDoubleValue() == lava; + } + return false; + } + + @Override + public boolean remove(final Object o) { + if (!(o instanceof Entry entry)) { + return false; + } + Object key = entry.getKey(); + if (key == FluidTags.WATER) { + water = 0.0; + return true; + } else if (key == FluidTags.LAVA) { + lava = 0.0; + return true; + } + return false; + } + } + + private final class EntryIterator implements ObjectIterator>> { + private int index = 0; + private Entry> entry = null; + + @Override + public boolean hasNext() { + return index < 2; + } + + @Override + public Entry> next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + if (index == 0) { + index++; + return entry = new DoubleEntry(FluidTags.WATER); + } else { + index++; + return entry = new DoubleEntry(FluidTags.LAVA); + } + } + + @Override + public void remove() { + if (entry == null) { + throw new IllegalStateException(); + } + TagKey key = entry.getKey(); + if (key == FluidTags.WATER) { + water = 0.0; + } else if (key == FluidTags.LAVA) { + lava = 0.0; + } + entry = null; + } + } + + private final class DoubleEntry implements Entry> { + private final TagKey key; + + public DoubleEntry(TagKey key) { + this.key = key; + } + + @Override + public TagKey getKey() { + return key; + } + + @Override + public double getDoubleValue() { + return key == FluidTags.WATER ? water : lava; + } + + @Override + public double setValue(double value) { + double prev; + if (key == FluidTags.WATER) { + prev = water; + water = value; + } else { + prev = lava; + lava = value; + } + return prev; + } + } +} diff --git a/leaf-server/src/main/java/org/dreeam/leaf/world/ChunkCache.java b/leaf-server/src/main/java/org/dreeam/leaf/world/ChunkCache.java new file mode 100644 index 00000000..ef4a869c --- /dev/null +++ b/leaf-server/src/main/java/org/dreeam/leaf/world/ChunkCache.java @@ -0,0 +1,304 @@ +package org.dreeam.leaf.world; + +import ca.spottedleaf.moonrise.common.util.TickThread; +import it.unimi.dsi.fastutil.HashCommon; +import net.minecraft.server.level.ServerLevel; + +import java.util.Arrays; +import java.util.concurrent.Future; + +/// Optimized chunk map for main thread. +/// - Single-entry cache: Maintains a fast-access entry cache for the most recently accessed item +/// - Thread safety: Enforces single-threaded access with runtime checks +/// +/// This map is designed to be accessed from a single thread at a time. +/// All mutating operations will throw [IllegalStateException] +/// if the current thread is not the owning thread. +/// +/// @see it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap +public final class ChunkCache { + private static final long EMPTY_KEY = Long.MIN_VALUE; + private static final float FACTOR = 0.5F; + private static final int MIN_N = HashCommon.arraySize(1024, FACTOR); + + private long k1 = EMPTY_KEY; + private V v1 = null; + private Thread thread; + + private transient long[] key; + private transient V[] value; + private transient int mask; + private transient boolean containsNullKey; + private transient int n; + private transient int maxFill; + private int size; + + public ChunkCache(Thread thread) { + n = MIN_N; + mask = n - 1; + maxFill = HashCommon.maxFill(n, FACTOR); + key = new long[n + 1]; + //noinspection unchecked + value = (V[]) new Object[n + 1]; + this.thread = thread; + } + + /// Retrieves the value associated with the specified key. + /// + /// This method implements a single-entry cache optimization: + /// + /// If the requested key matches the most recently accessed key, + /// the cached value is returned immediately without a hash map lookup. + /// + /// This method does not perform thread checks for performance reasons. + /// + /// # Safety + /// + /// The caller must ensure that the current thread is the owning thread. + /// + /// @param k The key whose associated value is to be returned + /// @return The value associated with the key, or `null` if no mapping exists + /// @implNote This method updates the single-entry cache on successful lookups + /// @see #isSameThread() + public V get(long k) { + long k1 = this.k1; + V v1 = this.v1; + if (k1 == k && v1 != null) { + return v1; + } + if (k == 0L) { + if (this.containsNullKey) { + this.k1 = k; + return this.v1 = this.value[this.n]; + } else { + return null; + } + } else { + long curr; + final long[] key = this.key; + int pos; + if ((curr = key[pos = (int) HashCommon.mix(k) & this.mask]) == 0) { + return null; + } else if (k == curr) { + this.k1 = k; + return this.v1 = this.value[pos]; + } else { + while (true) { + if ((curr = key[pos = pos + 1 & this.mask]) == 0) { + return null; + } + if (k == curr) { + this.k1 = k; + return this.v1 = this.value[pos]; + } + } + } + } + } + + /// Removes the mapping for the specified key from this map. + /// + /// If the removed key matches the cached key, the single-entry cache is invalidated. + /// + /// @param k The key whose mapping is to be removed + /// @return The previous value associated with the key, or `null` if no mapping existed + /// @throws IllegalStateException If the current thread is not the owning thread + public V remove(long k) { + // Safety: throws IllegalStateException for all non-owning threads + ensureSameThread(); + if (k == k1) { + v1 = null; + k1 = EMPTY_KEY; + } + if (((k) == (0))) { + if (containsNullKey) return removeNullEntry(); + return null; + } + long curr; + final long[] key = this.key; + int pos; + if (((curr = key[pos = (int) HashCommon.mix((k)) & mask]) == (0))) return null; + if (((k) == (curr))) return removeEntry(pos); + while (true) { + if (((curr = key[pos = (pos + 1) & mask]) == (0))) return null; + if (((k) == (curr))) return removeEntry(pos); + } + } + + /// Associates the specified entry in this map. + /// + /// If the key matches the cached key, the single-entry cache is invalidated. + /// + /// @param k The key with which the specified value is to be associated + /// @param levelChunk The value to be associated with the specified key + /// @return The previous value associated with the key, or null if no mapping existed + /// @throws IllegalStateException If the current thread is not the owning thread + public V put(long k, V levelChunk) { + // Safety: throws IllegalStateException for all non-owning threads + ensureSameThread(); + if (k == k1) { + v1 = null; + k1 = EMPTY_KEY; + } + final int pos = find(k); + if (pos < 0) { + insert(-pos - 1, k, levelChunk); + return null; + } + final V oldValue = value[pos]; + value[pos] = levelChunk; + return oldValue; + } + + /// Removes all elements from this map. + /// + /// This method also clears the single-entry cache. + /// + /// @throws IllegalStateException If the current thread is not the owning thread + public void clear() { + // Safety: throws IllegalStateException for all non-owning threads + ensureSameThread(); + v1 = null; + k1 = EMPTY_KEY; + if (size == 0) return; + size = 0; + containsNullKey = false; + Arrays.fill(key, (0)); + Arrays.fill(value, null); + } + + /// Changes the owning thread of this map to the current thread. + /// + /// # Safety + /// + /// The caller must ensure proper happens before relationships + /// when transferring ownership between threads. + /// + /// This should be done through proper synchronization mechanisms like + /// [Thread#join()] or [Future#get()]. + /// + /// @implNote This method does not perform synchronization + public void setThread() { + this.thread = Thread.currentThread(); + } + + /// Checks if the current thread is the same as the owning thread. + /// + /// @return The current thread owns this map + public boolean isSameThread() { + return Thread.currentThread() == this.thread; + } + + public boolean isSameThreadFor(ServerLevel serverLevel, int chunkX, int chunkZ) { + return Thread.currentThread() == this.thread && TickThread.isTickThreadFor(serverLevel, chunkX, chunkZ); + } + + /// Ensure that the current thread is the owning thread. + /// + /// @throws IllegalStateException If the current thread is not the owning thread + /// @see #isSameThread() + /// @see #setThread() + public void ensureSameThread() { + if (!isSameThread()) { + throw new IllegalStateException("Thread failed main thread check: Cannot update chunk status asynchronously, context=thread=" + Thread.currentThread().getName()); + } + } + + // from fastutil + private V removeEntry(final int pos) { + final V oldValue = value[pos]; + value[pos] = null; + size--; + shiftKeys(pos); + if (n > MIN_N && size < maxFill / 4 && n > it.unimi.dsi.fastutil.Hash.DEFAULT_INITIAL_SIZE) { + rehash(n / 2); + } + return oldValue; + } + + // from fastutil + private void shiftKeys(int pos) { + int last, slot; + long curr; + final long[] key = this.key; + final V[] value = this.value; + for (;;) { + pos = ((last = pos) + 1) & mask; + for (;;) { + if (((curr = key[pos]) == (0))) { + key[last] = (0); + value[last] = null; + return; + } + slot = (int) HashCommon.mix((curr)) & mask; + if (last <= pos ? last >= slot || slot > pos : last >= slot && slot > pos) break; + pos = (pos + 1) & mask; + } + key[last] = curr; + value[last] = value[pos]; + } + } + + // from fastutil + private V removeNullEntry() { + containsNullKey = false; + final V oldValue = value[n]; + value[n] = null; + size--; + if (n > MIN_N && size < maxFill / 4 && n > it.unimi.dsi.fastutil.Hash.DEFAULT_INITIAL_SIZE) rehash(n / 2); + return oldValue; + } + + // from fastutil + private void rehash(final int newN) { + final long[] key = this.key; + final V[] value = this.value; + final int mask = newN - 1; + final long[] newKey = new long[newN + 1]; + //noinspection unchecked + final V[] newValue = (V[])new Object[newN + 1]; + int i = n, pos; + for (int j = realSize(); j-- != 0;) { + //noinspection StatementWithEmptyBody + while (((key[--i]) == (0))); + if (!((newKey[pos = (int) HashCommon.mix((key[i])) & mask]) == (0))) + //noinspection StatementWithEmptyBody + while (!((newKey[pos = (pos + 1) & mask]) == (0))); + newKey[pos] = key[i]; + newValue[pos] = value[i]; + } + newValue[newN] = value[n]; + n = newN; + this.mask = mask; + maxFill = HashCommon.maxFill(n, FACTOR); + this.key = newKey; + this.value = newValue; + } + + // from fastutil + private int realSize() { + return containsNullKey ? size - 1 : size; + } + + // from fastutil + private int find(final long k) { + if (((k) == (0))) return containsNullKey ? n : -(n + 1); + long curr; + final long[] key = this.key; + int pos; + if (((curr = key[pos = (int) HashCommon.mix((k)) & mask]) == (0))) return -(pos + 1); + if (((k) == (curr))) return pos; + while (true) { + if (((curr = key[pos = (pos + 1) & mask]) == (0))) return -(pos + 1); + if (((k) == (curr))) return pos; + } + } + + // from fastutil + private void insert(final int pos, final long k, final V v) { + if (pos == n) containsNullKey = true; + key[pos] = k; + value[pos] = v; + if (size++ >= maxFill) rehash(HashCommon.arraySize(size + 1, FACTOR)); + } +} diff --git a/leaf-server/src/main/java/org/dreeam/leaf/world/EntityCollisionCache.java b/leaf-server/src/main/java/org/dreeam/leaf/world/EntityCollisionCache.java new file mode 100644 index 00000000..975a1543 --- /dev/null +++ b/leaf-server/src/main/java/org/dreeam/leaf/world/EntityCollisionCache.java @@ -0,0 +1,21 @@ +package org.dreeam.leaf.world; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.shapes.VoxelShape; + +public record EntityCollisionCache( + ObjectArrayList potentialCollisionsVoxel, + ObjectArrayList potentialCollisionsBB, + ObjectArrayList entityAABBs +) { + public EntityCollisionCache() { + this(new ObjectArrayList<>(), new ObjectArrayList<>(), new ObjectArrayList<>()); + } + + public void clear() { + potentialCollisionsVoxel.clear(); + potentialCollisionsBB.clear(); + entityAABBs.clear(); + } +}