diff --git a/.github/workflows/build-1214.yml b/.github/workflows/build-1214.yml index 1289b100..062617db 100644 --- a/.github/workflows/build-1214.yml +++ b/.github/workflows/build-1214.yml @@ -97,7 +97,7 @@ jobs: path: ./leaf-1.21.4-${{ env.BUILD_NUMBER }}.jar - name: Release Leaf - uses: softprops/action-gh-release@master + uses: softprops/action-gh-release@v2.2.2 # Temp fix with: name: "Leaf 1.21.4" tag_name: "ver-1.21.4" diff --git a/.gitignore b/.gitignore index 44a9d442..a16f5ea7 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ # IntelliJ *.iml .idea +!.idea/icon.svg # Gradle !gradle/wrapper/gradle-wrapper.jar diff --git a/.idea/icon.svg b/.idea/icon.svg new file mode 100644 index 00000000..e4563310 --- /dev/null +++ b/.idea/icon.svg @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/LICENSE.md b/LICENSE.md index be435f08..dce2fa9d 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,5 +1,10 @@ # Leaf license +Leaf inherits licenses from upstream projects. + Paperweight files are licensed under [MIT](https://opensource.org/licenses/MIT) (included in `license/MIT.txt`). -Patches are licensed under MIT, unless indicated differently in their header (some patches are licensed under [GPL-3.0](https://www.gnu.org/licenses/gpl-3.0.html) (included in `license/GPL-3.0.txt`) or [LGPL-3.0](https://www.gnu.org/licenses/lgpl-3.0.html) (included in `license/LGPL-3.0.txt`)). +Patches are licensed under MIT, unless indicated differently in their header (some patches are licensed under [GPL-3.0](https://www.gnu.org/licenses/gpl-3.0.html) (included in `license/GPL-3.0.txt`), [LGPL-3.0](https://www.gnu.org/licenses/lgpl-3.0.html) (included in `license/LGPL-3.0.txt`), or [Apache-2.0](https://www.apache.org/licenses/) (included in `license/Apache-2.0.txt`)). +Certain patches are derived from other projects and retain the original licenses, as noted in the patch header. Binaries are licensed under GPL-3.0. + +Also see [PaperMC/Paper](https://github.com/PaperMC/Paper), [PaperMC/paperweight](https://github.com/PaperMC/paperweight), and the repositories of other dependencies used by this project for their respective licenses. diff --git a/README.md b/README.md index 08609ec3..6d21354f 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ ## 🍃 Features - **Based on [Gale](https://github.com/Dreeam-qwq/Gale)** for better performance - **Async** pathfinding, mob spawning and entity tracker -- **Various optimizations** blending from [other forks](https://github.com/Winds-Studio/Leaf#-credits) and our own +- **Various optimizations** blending from [other forks](#-credits) and our own - **Fully compatible** with Spigot and Paper plugins - **Latest dependencies**, keeping all dependencies up-to-date - **Allows all characters in usernames**, including Chinese and other characters @@ -87,11 +87,9 @@ java { ``` ## ⚖️ License -Paperweight files are licensed under [MIT](licenses/MIT.txt). -Patches are licensed under [MIT](licenses/MIT.txt), unless indicated differently in their header. -Binaries are licensed under [GPL-3.0](licenses/GPL-3.0.txt). +Leaf is licensed under multiple open source licenses depending on upstream projects and other materials, -Also see [PaperMC/Paper](https://github.com/PaperMC/Paper) and [PaperMC/paperweight](https://github.com/PaperMC/paperweight) for the licenses of some materials used by this project. +see [LICENSE.md](LICENSE.md) for full license information. ## 📜 Credits Thanks to these projects below. Leaf includes some patches taken from them.
diff --git a/leaf-archived-patches/removed/hardfork/server/0074-Airplane-Remove-stream-in-PoiCompetitorScan.patch b/leaf-archived-patches/removed/hardfork/server/0074-Airplane-Remove-stream-in-PoiCompetitorScan.patch index 4264fe76..7e8ae181 100644 --- a/leaf-archived-patches/removed/hardfork/server/0074-Airplane-Remove-stream-in-PoiCompetitorScan.patch +++ b/leaf-archived-patches/removed/hardfork/server/0074-Airplane-Remove-stream-in-PoiCompetitorScan.patch @@ -28,7 +28,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with this program. If not, see . +along with this program. If not, see . diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/PoiCompetitorScan.java b/src/main/java/net/minecraft/world/entity/ai/behavior/PoiCompetitorScan.java index 7302d397d39d8400527ab2da4adaf8d792256749..faeb1d42d8361c02b63e33059edaeff78e719c71 100644 diff --git a/leaf-server/minecraft-patches/features/0101-Collect-then-startEachNonRunningBehavior-in-Brain.patch b/leaf-archived-patches/removed/hardfork/server/0101-Collect-then-startEachNonRunningBehavior-in-Brain.patch similarity index 96% rename from leaf-server/minecraft-patches/features/0101-Collect-then-startEachNonRunningBehavior-in-Brain.patch rename to leaf-archived-patches/removed/hardfork/server/0101-Collect-then-startEachNonRunningBehavior-in-Brain.patch index c4960779..5909a99d 100644 --- a/leaf-server/minecraft-patches/features/0101-Collect-then-startEachNonRunningBehavior-in-Brain.patch +++ b/leaf-archived-patches/removed/hardfork/server/0101-Collect-then-startEachNonRunningBehavior-in-Brain.patch @@ -3,6 +3,7 @@ From: Taiyou06 Date: Tue, 9 Nov 2077 00:00:00 +0800 Subject: [PATCH] Collect then startEachNonRunningBehavior in Brain +Removed since Leaf 1.21.4, replaced by Cache potential behaviors in Brain patch diff --git a/net/minecraft/world/entity/ai/Brain.java b/net/minecraft/world/entity/ai/Brain.java index c561b749fb9b76ba9b1e9689089b743248c65d50..ea6c8e85ccff67b1c24109732f74f1e8199cad07 100644 diff --git a/leaf-server/minecraft-patches/features/0185-preload-mob-spawning-position.patch b/leaf-archived-patches/removed/hardfork/server/0184-preload-mob-spawning-position.patch similarity index 81% rename from leaf-server/minecraft-patches/features/0185-preload-mob-spawning-position.patch rename to leaf-archived-patches/removed/hardfork/server/0184-preload-mob-spawning-position.patch index a48c0781..19db2558 100644 --- a/leaf-server/minecraft-patches/features/0185-preload-mob-spawning-position.patch +++ b/leaf-archived-patches/removed/hardfork/server/0184-preload-mob-spawning-position.patch @@ -3,19 +3,20 @@ From: hayanesuru Date: Wed, 4 Jun 2025 20:54:32 +0900 Subject: [PATCH] preload mob spawning position +No need diff --git a/net/minecraft/world/level/NaturalSpawner.java b/net/minecraft/world/level/NaturalSpawner.java -index 762bdf1fe19546f89d34b9efdad66b00dab80006..0443df34de4f940f64e563ea76453493cadf200b 100644 +index 458b17dca84c87591b030679c5aac6259c0f8308..c69922ac2b831d8af35c9e98a34825e6b8a268da 100644 --- a/net/minecraft/world/level/NaturalSpawner.java +++ b/net/minecraft/world/level/NaturalSpawner.java -@@ -257,9 +257,56 @@ public final class NaturalSpawner { +@@ -257,9 +257,57 @@ public final class NaturalSpawner { // Paper end - Optional per player mob spawns - // Leaf start + // Leaf start - optimize mob spawning BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(); - mutableRandomPosWithin(pos, level, chunk); - if (pos.getY() < level.getMinY() + 1) { - return 0; -+ // Leaf start ++ // Leaf start - preload mob spawning position + if (org.dreeam.leaf.config.modules.opt.PreloadNaturalMobSpawning.enabled) { + if (chunk.cacheSpawnPosIndex == 16 || chunk.cacheSpawnPosIndex == -1) { + if (chunk.cacheSpawnPos == null) { @@ -65,44 +66,45 @@ index 762bdf1fe19546f89d34b9efdad66b00dab80006..0443df34de4f940f64e563ea76453493 + if (bs == null || bs.isRedstoneConductor(level, pos)) { + return 0; + } ++ // Leaf end - preload mob spawning position } return spawnCategoryForPosition(category, level, chunk, pos, filter, callback, maxSpawns, trackEntity, false); // Paper - Optional per player mob spawns // Paper - throttle failed spawn attempts - // Leaf end -@@ -284,7 +331,12 @@ public final class NaturalSpawner { + // Leaf end - optimize mob spawning +@@ -284,7 +332,12 @@ public final class NaturalSpawner { MobCategory category, ServerLevel level, ChunkAccess chunk, BlockPos pos, NaturalSpawner.SpawnPredicate filter, NaturalSpawner.AfterSpawnCallback callback, final int maxSpawns, final @Nullable Consumer trackEntity // Paper start - throttle failed spawn attempts ) { - spawnCategoryForPosition(category, level, chunk, pos, filter, callback, maxSpawns, trackEntity, false); -+ // Leaf start ++ // Leaf start - preload mob spawning position + BlockState blockState = level.getBlockStateIfLoadedAndInBounds(pos); + if (blockState != null && !blockState.isRedstoneConductor(chunk, pos)) { + spawnCategoryForPosition(category, level, chunk, pos, filter, callback, maxSpawns, trackEntity, false); + } -+ // Leaf end ++ // Leaf end - preload mob spawning position } public static int spawnCategoryForPosition( MobCategory category, ServerLevel level, ChunkAccess chunk, BlockPos pos, NaturalSpawner.SpawnPredicate filter, NaturalSpawner.AfterSpawnCallback callback, final int maxSpawns, final @Nullable Consumer trackEntity, final boolean nothing -@@ -297,8 +349,8 @@ public final class NaturalSpawner { - int posX = pos.getX(); // Leaf - int posZ = pos.getZ(); // Leaf +@@ -297,8 +350,8 @@ public final class NaturalSpawner { + int posX = pos.getX(); // Leaf - optimize mob spawning + int posZ = pos.getZ(); // Leaf - optimize mob spawning int i = 0; // Paper - throttle failed spawn attempts - BlockState blockState = level.getBlockStateIfLoadedAndInBounds(pos); // Paper - don't load chunks for mob spawn - if (blockState != null && !blockState.isRedstoneConductor(chunk, pos)) { // Paper - don't load chunks for mob spawn -+ // BlockState blockState = level.getBlockStateIfLoadedAndInBounds(pos); // Paper - don't load chunks for mob spawn // Leaf -+ if (true /*blockState != null && !blockState.isRedstoneConductor(chunk, pos)*/) { // Paper - don't load chunks for mob spawn // Leaf - BlockPos.MutableBlockPos mutableBlockPos = pos instanceof BlockPos.MutableBlockPos pos2 ? pos2 : new BlockPos.MutableBlockPos(); // Leaf ++ //BlockState blockState = level.getBlockStateIfLoadedAndInBounds(pos); // Paper - don't load chunks for mob spawn // Leaf - preload mob spawning position ++ if (true /*blockState != null && !blockState.isRedstoneConductor(chunk, pos)*/) { // Paper - don't load chunks for mob spawn // Leaf - preload mob spawning position + BlockPos.MutableBlockPos mutableBlockPos = pos instanceof BlockPos.MutableBlockPos pos2 ? pos2 : new BlockPos.MutableBlockPos(); // Leaf - optimize mob spawning //int i = 0; // Paper - throttle failed spawn attempts - move up diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java -index e6eab6929b08503c49debbbd25497ffedad438e1..624a177695580510c0a49d4503dee72da7fd7114 100644 +index a90bf0d80ae4dac9b19b8e467b402917cc19a271..804f2118167b1607c50ca8378119254e8760427a 100644 --- a/net/minecraft/world/level/chunk/LevelChunk.java +++ b/net/minecraft/world/level/chunk/LevelChunk.java @@ -106,6 +106,8 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p // Paper start - rewrite chunk system private boolean postProcessingDone; private net.minecraft.server.level.ServerChunkCache.ChunkAndHolder chunkAndHolder; -+ public long[] cacheSpawnPos = null; // Leaf -+ public int cacheSpawnPosIndex = -1; // Leaf ++ public long[] cacheSpawnPos = null; // Leaf - preload mob spawning position ++ public int cacheSpawnPosIndex = -1; // Leaf - preload mob spawning position @Override public final boolean moonrise$isPostProcessingDone() { diff --git a/leaf-server/minecraft-patches/features/0005-Pufferfish-Dynamic-Activation-of-Brain.patch b/leaf-server/minecraft-patches/features/0005-Pufferfish-Dynamic-Activation-of-Brain.patch index 515b5091..5bba7a99 100644 --- a/leaf-server/minecraft-patches/features/0005-Pufferfish-Dynamic-Activation-of-Brain.patch +++ b/leaf-server/minecraft-patches/features/0005-Pufferfish-Dynamic-Activation-of-Brain.patch @@ -29,7 +29,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with this program. If not, see . +along with this program. If not, see . diff --git a/io/papermc/paper/entity/activation/ActivationRange.java b/io/papermc/paper/entity/activation/ActivationRange.java index 6db99585fa47fe2d2ae6eff8efe16190dd756511..a9269356de964585028e69a3713ca64f67ba02bf 100644 diff --git a/leaf-server/minecraft-patches/features/0048-Cache-player-profileResult.patch b/leaf-server/minecraft-patches/features/0048-Cache-player-profileResult.patch index 36ccec15..5b903ec9 100644 --- a/leaf-server/minecraft-patches/features/0048-Cache-player-profileResult.patch +++ b/leaf-server/minecraft-patches/features/0048-Cache-player-profileResult.patch @@ -3,6 +3,23 @@ From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com> Date: Thu, 28 Mar 2024 13:36:09 -0400 Subject: [PATCH] Cache player profileResult +This patch includes code that references the Caffeine caching library, +which is licensed under the Apache License, Version 2.0. + +Caffeine (https://github.com/ben-manes/caffeine) +Copyright (c) Ben Manes + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/net/minecraft/server/network/ServerLoginPacketListenerImpl.java index 069477e524a28b20a0289221858bdc802704a890..114b25f933c6a1b011523581a5a02a5a2c1e827e 100644 diff --git a/leaf-server/minecraft-patches/features/0070-Replace-brain-maps-with-optimized-collection.patch b/leaf-server/minecraft-patches/features/0070-Replace-brain-maps-with-optimized-collection.patch index 653864fd..1e725029 100644 --- a/leaf-server/minecraft-patches/features/0070-Replace-brain-maps-with-optimized-collection.patch +++ b/leaf-server/minecraft-patches/features/0070-Replace-brain-maps-with-optimized-collection.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Replace brain maps with optimized collection diff --git a/net/minecraft/world/entity/ai/Brain.java b/net/minecraft/world/entity/ai/Brain.java -index 083eb9a7a0bc14d30db944f356d98ca552fa1784..778e3b99a7f941a53b87cbec510db8deed5d77c8 100644 +index 083eb9a7a0bc14d30db944f356d98ca552fa1784..10986e50bd3307f81074c4cb371eb4d7defc9cfc 100644 --- a/net/minecraft/world/entity/ai/Brain.java +++ b/net/minecraft/world/entity/ai/Brain.java @@ -45,14 +45,18 @@ public class Brain { @@ -14,11 +14,10 @@ index 083eb9a7a0bc14d30db944f356d98ca552fa1784..778e3b99a7f941a53b87cbec510db8de private static final int SCHEDULE_UPDATE_DELAY = 20; - private final Map, Optional>> memories = Maps.newHashMap(); - private final Map>, Sensor> sensors = Maps.newLinkedHashMap(); -- private final Map>>> availableBehaviorsByPriority = Maps.newTreeMap(); + // Leaf start - Replace brain maps with optimized collection + private final Map, Optional>> memories = new it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap<>(); + private final Map>, Sensor> sensors = new it.unimi.dsi.fastutil.objects.Reference2ReferenceLinkedOpenHashMap<>(); -+ private final Map>>> availableBehaviorsByPriority = new it.unimi.dsi.fastutil.objects.Object2ObjectRBTreeMap<>(); + private final Map>>> availableBehaviorsByPriority = Maps.newTreeMap(); + // Leaf end - Replace brain maps with optimized collection private Schedule schedule = Schedule.EMPTY; - private final Map, MemoryStatus>>> activityRequirements = Maps.newHashMap(); diff --git a/leaf-server/minecraft-patches/features/0072-Use-caffeine-cache-for-kickPermission-instead-of-usi.patch b/leaf-server/minecraft-patches/features/0072-Use-caffeine-cache-for-kickPermission-instead-of-usi.patch index 775ac9f6..fbcb9faa 100644 --- a/leaf-server/minecraft-patches/features/0072-Use-caffeine-cache-for-kickPermission-instead-of-usi.patch +++ b/leaf-server/minecraft-patches/features/0072-Use-caffeine-cache-for-kickPermission-instead-of-usi.patch @@ -4,6 +4,23 @@ Date: Sun, 23 Jun 2024 11:26:20 +0800 Subject: [PATCH] Use caffeine cache for kickPermission instead of using google.common.cache +This patch includes code that references the Caffeine caching library, +which is licensed under the Apache License, Version 2.0. + +Caffeine (https://github.com/ben-manes/caffeine) +Copyright (c) Ben Manes + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java index 24aca7ba2cc3ec5f05bb4ea7d373feb730d8dd90..c30e017e6cffa6aa828b0f6e8889885dbaaa4680 100644 diff --git a/leaf-server/minecraft-patches/features/0102-Lithium-equipment-tracking.patch b/leaf-server/minecraft-patches/features/0101-Lithium-equipment-tracking.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0102-Lithium-equipment-tracking.patch rename to leaf-server/minecraft-patches/features/0101-Lithium-equipment-tracking.patch diff --git a/leaf-server/minecraft-patches/features/0103-C2ME-Optimize-world-gen-math.patch b/leaf-server/minecraft-patches/features/0102-C2ME-Optimize-world-gen-math.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0103-C2ME-Optimize-world-gen-math.patch rename to leaf-server/minecraft-patches/features/0102-C2ME-Optimize-world-gen-math.patch diff --git a/leaf-server/minecraft-patches/features/0104-Cache-chunk-key.patch b/leaf-server/minecraft-patches/features/0103-Cache-chunk-key.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0104-Cache-chunk-key.patch rename to leaf-server/minecraft-patches/features/0103-Cache-chunk-key.patch diff --git a/leaf-server/minecraft-patches/features/0105-Cache-random-tick-block-status.patch b/leaf-server/minecraft-patches/features/0104-Cache-random-tick-block-status.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0105-Cache-random-tick-block-status.patch rename to leaf-server/minecraft-patches/features/0104-Cache-random-tick-block-status.patch diff --git a/leaf-server/minecraft-patches/features/0106-Cache-part-of-canHoldFluid-result.patch b/leaf-server/minecraft-patches/features/0105-Cache-part-of-canHoldFluid-result.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0106-Cache-part-of-canHoldFluid-result.patch rename to leaf-server/minecraft-patches/features/0105-Cache-part-of-canHoldFluid-result.patch diff --git a/leaf-server/minecraft-patches/features/0107-Configurable-tripwire-dupe.patch b/leaf-server/minecraft-patches/features/0106-Configurable-tripwire-dupe.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0107-Configurable-tripwire-dupe.patch rename to leaf-server/minecraft-patches/features/0106-Configurable-tripwire-dupe.patch diff --git a/leaf-server/minecraft-patches/features/0108-PaperPR-Fix-MC-117075-Block-Entities-Unload-Lag-Spik.patch b/leaf-server/minecraft-patches/features/0107-PaperPR-Fix-MC-117075-Block-Entities-Unload-Lag-Spik.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0108-PaperPR-Fix-MC-117075-Block-Entities-Unload-Lag-Spik.patch rename to leaf-server/minecraft-patches/features/0107-PaperPR-Fix-MC-117075-Block-Entities-Unload-Lag-Spik.patch diff --git a/leaf-server/minecraft-patches/features/0109-Sepals-Rearrange-the-attackable-conditions.patch b/leaf-server/minecraft-patches/features/0108-Sepals-Rearrange-the-attackable-conditions.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0109-Sepals-Rearrange-the-attackable-conditions.patch rename to leaf-server/minecraft-patches/features/0108-Sepals-Rearrange-the-attackable-conditions.patch diff --git a/leaf-server/minecraft-patches/features/0110-SparklyPaper-Skip-dirty-stats-copy-when-requesting-p.patch b/leaf-server/minecraft-patches/features/0109-SparklyPaper-Skip-dirty-stats-copy-when-requesting-p.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0110-SparklyPaper-Skip-dirty-stats-copy-when-requesting-p.patch rename to leaf-server/minecraft-patches/features/0109-SparklyPaper-Skip-dirty-stats-copy-when-requesting-p.patch diff --git a/leaf-server/minecraft-patches/features/0111-SparklyPaper-Reset-dirty-flag-when-loading-maps-from.patch b/leaf-server/minecraft-patches/features/0110-SparklyPaper-Reset-dirty-flag-when-loading-maps-from.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0111-SparklyPaper-Reset-dirty-flag-when-loading-maps-from.patch rename to leaf-server/minecraft-patches/features/0110-SparklyPaper-Reset-dirty-flag-when-loading-maps-from.patch diff --git a/leaf-server/minecraft-patches/features/0112-Optimize-checking-nearby-players-for-spawning.patch b/leaf-server/minecraft-patches/features/0111-Optimize-checking-nearby-players-for-spawning.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0112-Optimize-checking-nearby-players-for-spawning.patch rename to leaf-server/minecraft-patches/features/0111-Optimize-checking-nearby-players-for-spawning.patch diff --git a/leaf-server/minecraft-patches/features/0113-Cache-supporting-block-check.patch b/leaf-server/minecraft-patches/features/0112-Cache-supporting-block-check.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0113-Cache-supporting-block-check.patch rename to leaf-server/minecraft-patches/features/0112-Cache-supporting-block-check.patch diff --git a/leaf-server/minecraft-patches/features/0114-Avoid-useless-deque-clear-on-LevelTicks-cleanupAfter.patch b/leaf-server/minecraft-patches/features/0113-Avoid-useless-deque-clear-on-LevelTicks-cleanupAfter.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0114-Avoid-useless-deque-clear-on-LevelTicks-cleanupAfter.patch rename to leaf-server/minecraft-patches/features/0113-Avoid-useless-deque-clear-on-LevelTicks-cleanupAfter.patch diff --git a/leaf-server/minecraft-patches/features/0115-Replace-brain-activity-maps-with-optimized-collectio.patch b/leaf-server/minecraft-patches/features/0114-Replace-brain-activity-maps-with-optimized-collectio.patch similarity index 92% rename from leaf-server/minecraft-patches/features/0115-Replace-brain-activity-maps-with-optimized-collectio.patch rename to leaf-server/minecraft-patches/features/0114-Replace-brain-activity-maps-with-optimized-collectio.patch index dbdcd2c0..880b8ae0 100644 --- a/leaf-server/minecraft-patches/features/0115-Replace-brain-activity-maps-with-optimized-collectio.patch +++ b/leaf-server/minecraft-patches/features/0114-Replace-brain-activity-maps-with-optimized-collectio.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Replace brain activity maps with optimized collection diff --git a/net/minecraft/world/entity/ai/Brain.java b/net/minecraft/world/entity/ai/Brain.java -index ea6c8e85ccff67b1c24109732f74f1e8199cad07..e27284f9897923f67985e3d60c3438bd00cc4a51 100644 +index 778e3b99a7f941a53b87cbec510db8deed5d77c8..4dde1642a33349335f374f17123a700dde1079d7 100644 --- a/net/minecraft/world/entity/ai/Brain.java +++ b/net/minecraft/world/entity/ai/Brain.java @@ -390,8 +390,8 @@ public class Brain { diff --git a/leaf-server/minecraft-patches/features/0116-Remove-stream-in-villagers.patch b/leaf-server/minecraft-patches/features/0115-Remove-stream-in-villagers.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0116-Remove-stream-in-villagers.patch rename to leaf-server/minecraft-patches/features/0115-Remove-stream-in-villagers.patch diff --git a/leaf-server/minecraft-patches/features/0117-Optimize-baby-villager-sensor.patch b/leaf-server/minecraft-patches/features/0116-Optimize-baby-villager-sensor.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0117-Optimize-baby-villager-sensor.patch rename to leaf-server/minecraft-patches/features/0116-Optimize-baby-villager-sensor.patch diff --git a/leaf-server/minecraft-patches/features/0118-Only-player-pushable.patch b/leaf-server/minecraft-patches/features/0117-Only-player-pushable.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0118-Only-player-pushable.patch rename to leaf-server/minecraft-patches/features/0117-Only-player-pushable.patch diff --git a/leaf-server/minecraft-patches/features/0119-Remove-iterators-from-Inventory-contains.patch b/leaf-server/minecraft-patches/features/0118-Remove-iterators-from-Inventory-contains.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0119-Remove-iterators-from-Inventory-contains.patch rename to leaf-server/minecraft-patches/features/0118-Remove-iterators-from-Inventory-contains.patch diff --git a/leaf-server/minecraft-patches/features/0120-Cache-eligible-players-for-despawn-checks.patch b/leaf-server/minecraft-patches/features/0119-Cache-eligible-players-for-despawn-checks.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0120-Cache-eligible-players-for-despawn-checks.patch rename to leaf-server/minecraft-patches/features/0119-Cache-eligible-players-for-despawn-checks.patch diff --git a/leaf-server/minecraft-patches/features/0121-Slightly-optimise-getNearestPlayer.patch b/leaf-server/minecraft-patches/features/0120-Slightly-optimise-getNearestPlayer.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0121-Slightly-optimise-getNearestPlayer.patch rename to leaf-server/minecraft-patches/features/0120-Slightly-optimise-getNearestPlayer.patch diff --git a/leaf-server/minecraft-patches/features/0122-Use-ensureCapacity-to-pre-populate-the-size-of-ticki.patch b/leaf-server/minecraft-patches/features/0121-Use-ensureCapacity-to-pre-populate-the-size-of-ticki.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0122-Use-ensureCapacity-to-pre-populate-the-size-of-ticki.patch rename to leaf-server/minecraft-patches/features/0121-Use-ensureCapacity-to-pre-populate-the-size-of-ticki.patch diff --git a/leaf-server/minecraft-patches/features/0123-Directly-use-the-pre-filtered-ticking-chunks-list-as.patch b/leaf-server/minecraft-patches/features/0122-Directly-use-the-pre-filtered-ticking-chunks-list-as.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0123-Directly-use-the-pre-filtered-ticking-chunks-list-as.patch rename to leaf-server/minecraft-patches/features/0122-Directly-use-the-pre-filtered-ticking-chunks-list-as.patch diff --git a/leaf-server/minecraft-patches/features/0124-Bulk-writes-to-writeLongArray-during-chunk-loading.patch b/leaf-server/minecraft-patches/features/0123-Bulk-writes-to-writeLongArray-during-chunk-loading.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0124-Bulk-writes-to-writeLongArray-during-chunk-loading.patch rename to leaf-server/minecraft-patches/features/0123-Bulk-writes-to-writeLongArray-during-chunk-loading.patch diff --git a/leaf-server/minecraft-patches/features/0125-Improve-sorting-in-SortedArraySet.patch b/leaf-server/minecraft-patches/features/0124-Improve-sorting-in-SortedArraySet.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0125-Improve-sorting-in-SortedArraySet.patch rename to leaf-server/minecraft-patches/features/0124-Improve-sorting-in-SortedArraySet.patch diff --git a/leaf-server/minecraft-patches/features/0126-Make-removeIf-slightly-faster.patch b/leaf-server/minecraft-patches/features/0125-Make-removeIf-slightly-faster.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0126-Make-removeIf-slightly-faster.patch rename to leaf-server/minecraft-patches/features/0125-Make-removeIf-slightly-faster.patch diff --git a/leaf-server/minecraft-patches/features/0127-Optimize-LinearPalette.patch b/leaf-server/minecraft-patches/features/0126-Optimize-LinearPalette.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0127-Optimize-LinearPalette.patch rename to leaf-server/minecraft-patches/features/0126-Optimize-LinearPalette.patch diff --git a/leaf-server/minecraft-patches/features/0128-Slightly-optimized-VarInt-write.patch b/leaf-server/minecraft-patches/features/0127-Slightly-optimized-VarInt-write.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0128-Slightly-optimized-VarInt-write.patch rename to leaf-server/minecraft-patches/features/0127-Slightly-optimized-VarInt-write.patch diff --git a/leaf-server/minecraft-patches/features/0129-Rewrite-ClientboundLightUpdatePacketData.patch b/leaf-server/minecraft-patches/features/0128-Rewrite-ClientboundLightUpdatePacketData.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0129-Rewrite-ClientboundLightUpdatePacketData.patch rename to leaf-server/minecraft-patches/features/0128-Rewrite-ClientboundLightUpdatePacketData.patch diff --git a/leaf-server/minecraft-patches/features/0130-Async-chunk-send.patch b/leaf-server/minecraft-patches/features/0129-Async-chunk-send.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0130-Async-chunk-send.patch rename to leaf-server/minecraft-patches/features/0129-Async-chunk-send.patch diff --git a/leaf-server/minecraft-patches/features/0131-Spawner-Configurations.patch b/leaf-server/minecraft-patches/features/0130-Spawner-Configurations.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0131-Spawner-Configurations.patch rename to leaf-server/minecraft-patches/features/0130-Spawner-Configurations.patch diff --git a/leaf-server/minecraft-patches/features/0132-SparklyPaper-Parallel-world-ticking.patch b/leaf-server/minecraft-patches/features/0131-SparklyPaper-Parallel-world-ticking.patch similarity index 99% rename from leaf-server/minecraft-patches/features/0132-SparklyPaper-Parallel-world-ticking.patch rename to leaf-server/minecraft-patches/features/0131-SparklyPaper-Parallel-world-ticking.patch index 9f02149e..f38d95f9 100644 --- a/leaf-server/minecraft-patches/features/0132-SparklyPaper-Parallel-world-ticking.patch +++ b/leaf-server/minecraft-patches/features/0131-SparklyPaper-Parallel-world-ticking.patch @@ -42,10 +42,10 @@ index be820c6093dd2ae7642b9bee11edf65e3a8d7242..06ac3537f5655d048d770bb004243f20 boolean ret = false; final boolean canProcessFullUpdates = processFullUpdates & isTickThread; diff --git a/io/papermc/paper/redstone/RedstoneWireTurbo.java b/io/papermc/paper/redstone/RedstoneWireTurbo.java -index ff747a1ecdf3c888bca0d69de4f85dcd810b6139..62ecbbf7c167beaa3b67fc4c30e901c5d359d6b8 100644 +index ff747a1ecdf3c888bca0d69de4f85dcd810b6139..b288d57d9f7bd0ccf1877cf9920bd67288ff22f7 100644 --- a/io/papermc/paper/redstone/RedstoneWireTurbo.java +++ b/io/papermc/paper/redstone/RedstoneWireTurbo.java -@@ -829,14 +829,8 @@ public final class RedstoneWireTurbo { +@@ -829,14 +829,10 @@ public final class RedstoneWireTurbo { j = getMaxCurrentStrength(upd, j); int l = 0; @@ -57,8 +57,10 @@ index ff747a1ecdf3c888bca0d69de4f85dcd810b6139..62ecbbf7c167beaa3b67fc4c30e901c5 - // is consistency to what this call returns, we may be able to cache it. - final int k = worldIn.getBestNeighborSignal(upd.self); - wire.shouldSignal = true; ++ // Leaf start - SparklyPaper - parallel world ticking + // This now correctly calls the (conditionally) thread-safe method in RedStoneWireBlock + final int k = wire.getBlockSignal(worldIn, upd.self); ++ // Leaf end - SparklyPaper - parallel world ticking // The variable 'k' holds the maximum redstone power value of any adjacent blocks. // If 'k' has the highest level of all neighbors, then the power level of this @@ -1361,7 +1363,7 @@ index 904369f4d7db41026183f2de7c96c2f0f4dc204d..afd952ddc8942818ec01d1c750413776 return true; } else { diff --git a/net/minecraft/world/level/block/RedStoneWireBlock.java b/net/minecraft/world/level/block/RedStoneWireBlock.java -index 12c9d60314c99fb65e640d255a2d0c6b7790ad4d..5a60c5e4fe122d37a0aed1269128aa5e6e5e87b8 100644 +index 12c9d60314c99fb65e640d255a2d0c6b7790ad4d..9d655558e8a15e4861a66e545b0991968e747b58 100644 --- a/net/minecraft/world/level/block/RedStoneWireBlock.java +++ b/net/minecraft/world/level/block/RedStoneWireBlock.java @@ -91,7 +91,10 @@ public class RedStoneWireBlock extends Block { @@ -1427,7 +1429,7 @@ index 12c9d60314c99fb65e640d255a2d0c6b7790ad4d..5a60c5e4fe122d37a0aed1269128aa5e } private void checkCornerChangeAt(Level level, BlockPos pos) { -@@ -450,24 +472,34 @@ public class RedStoneWireBlock extends Block { +@@ -450,12 +472,21 @@ public class RedStoneWireBlock extends Block { @Override protected int getDirectSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) { @@ -1451,13 +1453,7 @@ index 12c9d60314c99fb65e640d255a2d0c6b7790ad4d..5a60c5e4fe122d37a0aed1269128aa5e int powerValue = blockState.getValue(POWER); if (powerValue == 0) { return 0; - } else { - return side != Direction.UP -- && !this.getConnectionState(blockAccess, blockState, pos).getValue(PROPERTY_BY_DIRECTION.get(side.getOpposite())).isConnected() -+ && !this.getConnectionState(blockAccess, blockState, pos).getValue(PROPERTY_BY_DIRECTION.get(side.getOpposite())).isConnected() - ? 0 - : powerValue; - } +@@ -468,6 +499,7 @@ public class RedStoneWireBlock extends Block { } else { return 0; } diff --git a/leaf-server/minecraft-patches/features/0133-SparklyPaper-Track-each-world-MSPT.patch b/leaf-server/minecraft-patches/features/0132-SparklyPaper-Track-each-world-MSPT.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0133-SparklyPaper-Track-each-world-MSPT.patch rename to leaf-server/minecraft-patches/features/0132-SparklyPaper-Track-each-world-MSPT.patch diff --git a/leaf-server/minecraft-patches/features/0134-PaperPR-Fix-cancelled-Projectile-Events-still-consum.patch b/leaf-server/minecraft-patches/features/0133-PaperPR-Fix-cancelled-Projectile-Events-still-consum.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0134-PaperPR-Fix-cancelled-Projectile-Events-still-consum.patch rename to leaf-server/minecraft-patches/features/0133-PaperPR-Fix-cancelled-Projectile-Events-still-consum.patch diff --git a/leaf-server/minecraft-patches/features/0135-Optimize-SetLookAndInteract-and-NearestVisibleLiving.patch b/leaf-server/minecraft-patches/features/0134-Optimize-SetLookAndInteract-and-NearestVisibleLiving.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0135-Optimize-SetLookAndInteract-and-NearestVisibleLiving.patch rename to leaf-server/minecraft-patches/features/0134-Optimize-SetLookAndInteract-and-NearestVisibleLiving.patch diff --git a/leaf-server/minecraft-patches/features/0136-Remove-streams-on-InsideBrownianWalk.patch b/leaf-server/minecraft-patches/features/0135-Remove-streams-on-InsideBrownianWalk.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0136-Remove-streams-on-InsideBrownianWalk.patch rename to leaf-server/minecraft-patches/features/0135-Remove-streams-on-InsideBrownianWalk.patch diff --git a/leaf-server/minecraft-patches/features/0137-Use-BFS-on-getSlopeDistance.patch b/leaf-server/minecraft-patches/features/0136-Use-BFS-on-getSlopeDistance.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0137-Use-BFS-on-getSlopeDistance.patch rename to leaf-server/minecraft-patches/features/0136-Use-BFS-on-getSlopeDistance.patch diff --git a/leaf-server/minecraft-patches/features/0138-Paper-PR-Throttle-failed-spawn-attempts.patch b/leaf-server/minecraft-patches/features/0137-Paper-PR-Throttle-failed-spawn-attempts.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0138-Paper-PR-Throttle-failed-spawn-attempts.patch rename to leaf-server/minecraft-patches/features/0137-Paper-PR-Throttle-failed-spawn-attempts.patch diff --git a/leaf-server/minecraft-patches/features/0139-Improve-BlockEntity-ticking-isRemoved-check.patch b/leaf-server/minecraft-patches/features/0138-Improve-BlockEntity-ticking-isRemoved-check.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0139-Improve-BlockEntity-ticking-isRemoved-check.patch rename to leaf-server/minecraft-patches/features/0138-Improve-BlockEntity-ticking-isRemoved-check.patch diff --git a/leaf-server/minecraft-patches/features/0140-Raytrace-AntiXray-SDK-integration.patch b/leaf-server/minecraft-patches/features/0139-Raytrace-AntiXray-SDK-integration.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0140-Raytrace-AntiXray-SDK-integration.patch rename to leaf-server/minecraft-patches/features/0139-Raytrace-AntiXray-SDK-integration.patch diff --git a/leaf-server/minecraft-patches/features/0141-Optimize-addOrUpdateTransientModifier.patch b/leaf-server/minecraft-patches/features/0140-Optimize-addOrUpdateTransientModifier.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0141-Optimize-addOrUpdateTransientModifier.patch rename to leaf-server/minecraft-patches/features/0140-Optimize-addOrUpdateTransientModifier.patch diff --git a/leaf-server/minecraft-patches/features/0142-Optimize-ContextMap.create.patch b/leaf-server/minecraft-patches/features/0141-Optimize-ContextMap.create.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0142-Optimize-ContextMap.create.patch rename to leaf-server/minecraft-patches/features/0141-Optimize-ContextMap.create.patch diff --git a/leaf-server/minecraft-patches/features/0143-Micro-optimizations-for-random-tick.patch b/leaf-server/minecraft-patches/features/0142-Micro-optimizations-for-random-tick.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0143-Micro-optimizations-for-random-tick.patch rename to leaf-server/minecraft-patches/features/0142-Micro-optimizations-for-random-tick.patch diff --git a/leaf-server/minecraft-patches/features/0144-Remove-streams-on-updateConnectedPlayersWithinRange.patch b/leaf-server/minecraft-patches/features/0143-Remove-streams-on-updateConnectedPlayersWithinRange.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0144-Remove-streams-on-updateConnectedPlayersWithinRange.patch rename to leaf-server/minecraft-patches/features/0143-Remove-streams-on-updateConnectedPlayersWithinRange.patch diff --git a/leaf-server/minecraft-patches/features/0145-Remove-streams-on-PlayerDetector.patch b/leaf-server/minecraft-patches/features/0144-Remove-streams-on-PlayerDetector.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0145-Remove-streams-on-PlayerDetector.patch rename to leaf-server/minecraft-patches/features/0144-Remove-streams-on-PlayerDetector.patch diff --git a/leaf-server/minecraft-patches/features/0146-Use-direct-iteration-on-Sensing.tick.patch b/leaf-server/minecraft-patches/features/0145-Use-direct-iteration-on-Sensing.tick.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0146-Use-direct-iteration-on-Sensing.tick.patch rename to leaf-server/minecraft-patches/features/0145-Use-direct-iteration-on-Sensing.tick.patch diff --git a/leaf-server/minecraft-patches/features/0147-Optimise-non-flush-packet-sending.patch b/leaf-server/minecraft-patches/features/0146-Optimise-non-flush-packet-sending.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0147-Optimise-non-flush-packet-sending.patch rename to leaf-server/minecraft-patches/features/0146-Optimise-non-flush-packet-sending.patch diff --git a/leaf-server/minecraft-patches/features/0148-Prevent-double-chunk-retrieving-in-entity-fluid-push.patch b/leaf-server/minecraft-patches/features/0147-Prevent-double-chunk-retrieving-in-entity-fluid-push.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0148-Prevent-double-chunk-retrieving-in-entity-fluid-push.patch rename to leaf-server/minecraft-patches/features/0147-Prevent-double-chunk-retrieving-in-entity-fluid-push.patch diff --git a/leaf-server/minecraft-patches/features/0149-Null-handling-on-MultifaceSpreader.patch b/leaf-server/minecraft-patches/features/0148-Null-handling-on-MultifaceSpreader.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0149-Null-handling-on-MultifaceSpreader.patch rename to leaf-server/minecraft-patches/features/0148-Null-handling-on-MultifaceSpreader.patch diff --git a/leaf-server/minecraft-patches/features/0150-More-virtual-threads.patch b/leaf-server/minecraft-patches/features/0149-More-virtual-threads.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0150-More-virtual-threads.patch rename to leaf-server/minecraft-patches/features/0149-More-virtual-threads.patch diff --git a/leaf-server/minecraft-patches/features/0151-Async-target-finding.patch b/leaf-server/minecraft-patches/features/0150-Async-target-finding.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0151-Async-target-finding.patch rename to leaf-server/minecraft-patches/features/0150-Async-target-finding.patch diff --git a/leaf-server/minecraft-patches/features/0152-Optimize-ThreadedTicketLevelPropagator.patch b/leaf-server/minecraft-patches/features/0151-Optimize-ThreadedTicketLevelPropagator.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0152-Optimize-ThreadedTicketLevelPropagator.patch rename to leaf-server/minecraft-patches/features/0151-Optimize-ThreadedTicketLevelPropagator.patch diff --git a/leaf-server/minecraft-patches/features/0153-Optimise-MobEffectUtil-getDigSpeedAmplification.patch b/leaf-server/minecraft-patches/features/0152-Optimise-MobEffectUtil-getDigSpeedAmplification.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0153-Optimise-MobEffectUtil-getDigSpeedAmplification.patch rename to leaf-server/minecraft-patches/features/0152-Optimise-MobEffectUtil-getDigSpeedAmplification.patch diff --git a/leaf-server/minecraft-patches/features/0154-Optimise-chunkUnloads.patch b/leaf-server/minecraft-patches/features/0153-Optimise-chunkUnloads.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0154-Optimise-chunkUnloads.patch rename to leaf-server/minecraft-patches/features/0153-Optimise-chunkUnloads.patch diff --git a/leaf-server/minecraft-patches/features/0155-Optimize-BlockEntityType-isValid.patch b/leaf-server/minecraft-patches/features/0154-Optimize-BlockEntityType-isValid.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0155-Optimize-BlockEntityType-isValid.patch rename to leaf-server/minecraft-patches/features/0154-Optimize-BlockEntityType-isValid.patch diff --git a/leaf-server/minecraft-patches/features/0156-PaperPR-Add-ticket-on-player-join-to-avoid-chunk-loa.patch b/leaf-server/minecraft-patches/features/0155-PaperPR-Add-ticket-on-player-join-to-avoid-chunk-loa.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0156-PaperPR-Add-ticket-on-player-join-to-avoid-chunk-loa.patch rename to leaf-server/minecraft-patches/features/0155-PaperPR-Add-ticket-on-player-join-to-avoid-chunk-loa.patch diff --git a/leaf-server/minecraft-patches/features/0157-PaperPR-Fix-save-load-NaN-Entity-Motion.patch b/leaf-server/minecraft-patches/features/0156-PaperPR-Fix-save-load-NaN-Entity-Motion.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0157-PaperPR-Fix-save-load-NaN-Entity-Motion.patch rename to leaf-server/minecraft-patches/features/0156-PaperPR-Fix-save-load-NaN-Entity-Motion.patch diff --git a/leaf-server/minecraft-patches/features/0158-PaperPR-Fix-unnecessary-map-data-saves.patch b/leaf-server/minecraft-patches/features/0157-PaperPR-Fix-unnecessary-map-data-saves.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0158-PaperPR-Fix-unnecessary-map-data-saves.patch rename to leaf-server/minecraft-patches/features/0157-PaperPR-Fix-unnecessary-map-data-saves.patch diff --git a/leaf-server/minecraft-patches/features/0159-Sakura-Optimise-check-inside-blocks-and-traverse-blo.patch b/leaf-server/minecraft-patches/features/0158-Sakura-Optimise-check-inside-blocks-and-traverse-blo.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0159-Sakura-Optimise-check-inside-blocks-and-traverse-blo.patch rename to leaf-server/minecraft-patches/features/0158-Sakura-Optimise-check-inside-blocks-and-traverse-blo.patch diff --git a/leaf-server/minecraft-patches/features/0160-Sakura-copy-EntityList-implementation-to-BasicEntity.patch b/leaf-server/minecraft-patches/features/0159-Sakura-copy-EntityList-implementation-to-BasicEntity.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0160-Sakura-copy-EntityList-implementation-to-BasicEntity.patch rename to leaf-server/minecraft-patches/features/0159-Sakura-copy-EntityList-implementation-to-BasicEntity.patch diff --git a/leaf-server/minecraft-patches/features/0161-Protocol-Core.patch b/leaf-server/minecraft-patches/features/0160-Protocol-Core.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0161-Protocol-Core.patch rename to leaf-server/minecraft-patches/features/0160-Protocol-Core.patch diff --git a/leaf-server/minecraft-patches/features/0162-Reduce-PlayerChunk-Updates.patch b/leaf-server/minecraft-patches/features/0161-Reduce-PlayerChunk-Updates.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0162-Reduce-PlayerChunk-Updates.patch rename to leaf-server/minecraft-patches/features/0161-Reduce-PlayerChunk-Updates.patch diff --git a/leaf-server/minecraft-patches/features/0163-Async-switch-connection-state.patch b/leaf-server/minecraft-patches/features/0162-Async-switch-connection-state.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0163-Async-switch-connection-state.patch rename to leaf-server/minecraft-patches/features/0162-Async-switch-connection-state.patch diff --git a/leaf-server/minecraft-patches/features/0164-Optimise-BlockEntities-tickersInLevel.patch b/leaf-server/minecraft-patches/features/0163-Optimize-BlockEntities-tickersInLevel.patch similarity index 81% rename from leaf-server/minecraft-patches/features/0164-Optimise-BlockEntities-tickersInLevel.patch rename to leaf-server/minecraft-patches/features/0163-Optimize-BlockEntities-tickersInLevel.patch index 1ad19b8d..ae5d6817 100644 --- a/leaf-server/minecraft-patches/features/0164-Optimise-BlockEntities-tickersInLevel.patch +++ b/leaf-server/minecraft-patches/features/0163-Optimize-BlockEntities-tickersInLevel.patch @@ -1,11 +1,11 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Taiyou06 Date: Thu, 8 May 2025 13:30:07 +0200 -Subject: [PATCH] Optimise BlockEntities tickersInLevel +Subject: [PATCH] Optimize BlockEntities tickersInLevel diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java -index 546fb78339c005ed71142cb3c894f816b8c72d08..e6eab6929b08503c49debbbd25497ffedad438e1 100644 +index 546fb78339c005ed71142cb3c894f816b8c72d08..a90bf0d80ae4dac9b19b8e467b402917cc19a271 100644 --- a/net/minecraft/world/level/chunk/LevelChunk.java +++ b/net/minecraft/world/level/chunk/LevelChunk.java @@ -72,7 +72,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p @@ -13,7 +13,7 @@ index 546fb78339c005ed71142cb3c894f816b8c72d08..e6eab6929b08503c49debbbd25497ffe } }; - private final Map tickersInLevel = Maps.newHashMap(); -+ private final Map tickersInLevel = org.dreeam.leaf.config.modules.opt.OptimiseBlockEntities.enabled ? new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>() : Maps.newHashMap(); // Leaf - Optimise BlockEntities tickersInLevel ++ private final Map tickersInLevel = org.dreeam.leaf.config.modules.opt.OptimizeBlockEntities.enabled ? new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>() : Maps.newHashMap(); // Leaf - Optimise BlockEntities tickersInLevel public boolean loaded; public final ServerLevel level; // CraftBukkit - type @Nullable diff --git a/leaf-server/minecraft-patches/features/0165-Pluto-Check-if-the-cactus-can-even-survive-being-pla.patch b/leaf-server/minecraft-patches/features/0164-Pluto-Check-if-the-cactus-can-even-survive-being-pla.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0165-Pluto-Check-if-the-cactus-can-even-survive-being-pla.patch rename to leaf-server/minecraft-patches/features/0164-Pluto-Check-if-the-cactus-can-even-survive-being-pla.patch diff --git a/leaf-server/minecraft-patches/features/0166-Flush-location-while-knockback.patch b/leaf-server/minecraft-patches/features/0165-Flush-location-while-knockback.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0166-Flush-location-while-knockback.patch rename to leaf-server/minecraft-patches/features/0165-Flush-location-while-knockback.patch diff --git a/leaf-server/minecraft-patches/features/0167-Only-tick-items-at-hand.patch b/leaf-server/minecraft-patches/features/0166-Only-tick-items-at-hand.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0167-Only-tick-items-at-hand.patch rename to leaf-server/minecraft-patches/features/0166-Only-tick-items-at-hand.patch diff --git a/leaf-server/minecraft-patches/features/0168-Smart-sort-items-in-NearestItemSensor.patch b/leaf-server/minecraft-patches/features/0167-Smart-sort-items-in-NearestItemSensor.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0168-Smart-sort-items-in-NearestItemSensor.patch rename to leaf-server/minecraft-patches/features/0167-Smart-sort-items-in-NearestItemSensor.patch diff --git a/leaf-server/minecraft-patches/features/0169-Optimise-player-movement-checks.patch b/leaf-server/minecraft-patches/features/0168-Optimise-player-movement-checks.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0169-Optimise-player-movement-checks.patch rename to leaf-server/minecraft-patches/features/0168-Optimise-player-movement-checks.patch diff --git a/leaf-server/minecraft-patches/features/0170-Remove-streams-in-MobSensor.patch b/leaf-server/minecraft-patches/features/0169-Remove-streams-in-MobSensor.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0170-Remove-streams-in-MobSensor.patch rename to leaf-server/minecraft-patches/features/0169-Remove-streams-in-MobSensor.patch diff --git a/leaf-server/minecraft-patches/features/0171-Remove-streams-in-TemptingSensor.patch b/leaf-server/minecraft-patches/features/0170-Remove-streams-in-TemptingSensor.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0171-Remove-streams-in-TemptingSensor.patch rename to leaf-server/minecraft-patches/features/0170-Remove-streams-in-TemptingSensor.patch diff --git a/leaf-server/minecraft-patches/features/0172-Use-HashedList-on-WeightedRandomList.patch b/leaf-server/minecraft-patches/features/0171-Use-HashedList-on-WeightedRandomList.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0172-Use-HashedList-on-WeightedRandomList.patch rename to leaf-server/minecraft-patches/features/0171-Use-HashedList-on-WeightedRandomList.patch diff --git a/leaf-server/minecraft-patches/features/0173-Add-configurable-death-item-drop-knockback-settings.patch b/leaf-server/minecraft-patches/features/0172-Add-configurable-death-item-drop-knockback-settings.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0173-Add-configurable-death-item-drop-knockback-settings.patch rename to leaf-server/minecraft-patches/features/0172-Add-configurable-death-item-drop-knockback-settings.patch diff --git a/leaf-server/minecraft-patches/features/0174-Optimize-getScaledTrackingDistance.patch b/leaf-server/minecraft-patches/features/0173-Optimize-getScaledTrackingDistance.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0174-Optimize-getScaledTrackingDistance.patch rename to leaf-server/minecraft-patches/features/0173-Optimize-getScaledTrackingDistance.patch diff --git a/leaf-server/minecraft-patches/features/0175-Optimize-SynchedEntityData-packDirty.patch b/leaf-server/minecraft-patches/features/0174-Optimize-SynchedEntityData-packDirty.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0175-Optimize-SynchedEntityData-packDirty.patch rename to leaf-server/minecraft-patches/features/0174-Optimize-SynchedEntityData-packDirty.patch diff --git a/leaf-server/minecraft-patches/features/0176-Optimize-isEyeInFluid.patch b/leaf-server/minecraft-patches/features/0175-Optimize-isEyeInFluid.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0176-Optimize-isEyeInFluid.patch rename to leaf-server/minecraft-patches/features/0175-Optimize-isEyeInFluid.patch diff --git a/leaf-server/minecraft-patches/features/0177-Cache-block-path-type.patch b/leaf-server/minecraft-patches/features/0176-Cache-block-path-type.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0177-Cache-block-path-type.patch rename to leaf-server/minecraft-patches/features/0176-Cache-block-path-type.patch diff --git a/leaf-server/minecraft-patches/features/0178-optimize-getEntityStatus.patch b/leaf-server/minecraft-patches/features/0177-optimize-getEntityStatus.patch similarity index 59% rename from leaf-server/minecraft-patches/features/0178-optimize-getEntityStatus.patch rename to leaf-server/minecraft-patches/features/0177-optimize-getEntityStatus.patch index 58447a60..463a0268 100644 --- a/leaf-server/minecraft-patches/features/0178-optimize-getEntityStatus.patch +++ b/leaf-server/minecraft-patches/features/0177-optimize-getEntityStatus.patch @@ -5,7 +5,7 @@ Subject: [PATCH] optimize getEntityStatus diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java -index 7554c109c35397bc1a43dd80e87764fd78645bbf..151476fd036839a416c226599279d0d8bf79717b 100644 +index 7554c109c35397bc1a43dd80e87764fd78645bbf..8ae35834bb35ace0bf0ad2c79a80500cbcb19cad 100644 --- a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java +++ b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java @@ -93,8 +93,14 @@ public abstract class EntityLookup implements LevelEntityGetter { @@ -14,14 +14,14 @@ index 7554c109c35397bc1a43dd80e87764fd78645bbf..151476fd036839a416c226599279d0d8 } - final Visibility visibility = EntityLookup.getEntityStatus(entity); - return visibility.isAccessible() ? entity : null; -+ // Leaf start ++ // Leaf start - optimize getEntityStatus + final FullChunkStatus entityStatus = ((ChunkSystemEntity) entity).moonrise$getChunkStatus(); + return switch (entityStatus) { + case INACCESSIBLE -> null; + case FULL, BLOCK_TICKING, ENTITY_TICKING -> entity; + case null -> null; + }; -+ // Leaf end ++ // Leaf end - optimize getEntityStatus } @Override @@ -30,34 +30,14 @@ index 7554c109c35397bc1a43dd80e87764fd78645bbf..151476fd036839a416c226599279d0d8 } final FullChunkStatus entityStatus = ((ChunkSystemEntity)entity).moonrise$getChunkStatus(); - return Visibility.fromFullChunkStatus(entityStatus == null ? FullChunkStatus.INACCESSIBLE : entityStatus); -+ // Leaf start ++ // Leaf start - optimize getEntityStatus + return switch (entityStatus) { + case INACCESSIBLE -> Visibility.HIDDEN; + case FULL, BLOCK_TICKING -> Visibility.TRACKED; + case ENTITY_TICKING -> Visibility.TICKING; + case null -> Visibility.HIDDEN; + }; -+ // Leaf end ++ // Leaf end - optimize getEntityStatus } protected boolean addEntity(final Entity entity, final boolean fromDisk, final boolean event) { -diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 64f24d3e0ecb91e0b4df6229354aeac549234f1b..80baa2dff5c1034a72271fc727fdb2acc1b69488 100644 ---- a/net/minecraft/world/entity/Entity.java -+++ b/net/minecraft/world/entity/Entity.java -@@ -381,6 +381,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - // Paper end - // Paper start - rewrite chunk system - private final boolean isHardColliding = this.moonrise$isHardCollidingUncached(); -+ @org.jetbrains.annotations.Nullable // Leaf - private net.minecraft.server.level.FullChunkStatus chunkStatus; - private ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData chunkData; - private int sectionX = Integer.MIN_VALUE; -@@ -394,6 +395,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - } - - @Override -+ @org.jetbrains.annotations.Nullable // Leaf - public final net.minecraft.server.level.FullChunkStatus moonrise$getChunkStatus() { - return this.chunkStatus; - } diff --git a/leaf-server/minecraft-patches/features/0179-Rail-Optimization-optimized-PoweredRailBlock-logic.patch b/leaf-server/minecraft-patches/features/0178-Rail-Optimization-optimized-PoweredRailBlock-logic.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0179-Rail-Optimization-optimized-PoweredRailBlock-logic.patch rename to leaf-server/minecraft-patches/features/0178-Rail-Optimization-optimized-PoweredRailBlock-logic.patch diff --git a/leaf-server/minecraft-patches/features/0180-optimise-ChunkGenerator-getMobsAt.patch b/leaf-server/minecraft-patches/features/0179-optimise-ChunkGenerator-getMobsAt.patch similarity index 87% rename from leaf-server/minecraft-patches/features/0180-optimise-ChunkGenerator-getMobsAt.patch rename to leaf-server/minecraft-patches/features/0179-optimise-ChunkGenerator-getMobsAt.patch index a7facb01..ac024cc6 100644 --- a/leaf-server/minecraft-patches/features/0180-optimise-ChunkGenerator-getMobsAt.patch +++ b/leaf-server/minecraft-patches/features/0179-optimise-ChunkGenerator-getMobsAt.patch @@ -6,7 +6,7 @@ Subject: [PATCH] optimise ChunkGenerator#getMobsAt inline fillStartsForStructure diff --git a/net/minecraft/world/level/StructureManager.java b/net/minecraft/world/level/StructureManager.java -index 8bc6a6c86cd8db53feefba7508b6031ba67e242e..20a2bc31a8082afd4f758bd7e91691bbc58ba16e 100644 +index 8bc6a6c86cd8db53feefba7508b6031ba67e242e..90397f237c0cb79da03b3f9ca7445676324ebd11 100644 --- a/net/minecraft/world/level/StructureManager.java +++ b/net/minecraft/world/level/StructureManager.java @@ -78,7 +78,7 @@ public class StructureManager { @@ -14,7 +14,7 @@ index 8bc6a6c86cd8db53feefba7508b6031ba67e242e..20a2bc31a8082afd4f758bd7e91691bb public void fillStartsForStructure(Structure structure, LongSet structureRefs, Consumer startConsumer) { for (long l : structureRefs) { - SectionPos sectionPos = SectionPos.of(new ChunkPos(l), this.level.getMinSectionY()); -+ SectionPos sectionPos = SectionPos.of(ChunkPos.getX(l), this.level.getMinSectionY(), ChunkPos.getZ(l)); // Leaf ++ SectionPos sectionPos = SectionPos.of(ChunkPos.getX(l), this.level.getMinSectionY(), ChunkPos.getZ(l)); // Leaf - optimise ChunkGenerator#getMobsAt StructureStart startForStructure = this.getStartForStructure( sectionPos, structure, this.level.getChunk(sectionPos.x(), sectionPos.z(), ChunkStatus.STRUCTURE_STARTS) ); @@ -24,13 +24,13 @@ index 8bc6a6c86cd8db53feefba7508b6031ba67e242e..20a2bc31a8082afd4f758bd7e91691bb public Map getAllStructuresAt(BlockPos pos) { - SectionPos sectionPos = SectionPos.of(pos); - return this.level.getChunk(sectionPos.x(), sectionPos.z(), ChunkStatus.STRUCTURE_REFERENCES).getAllReferences(); -+ // SectionPos sectionPos = SectionPos.of(pos); // Leaf -+ return this.level.getChunk(pos.getX() >> 4, pos.getZ() >> 4, ChunkStatus.STRUCTURE_REFERENCES).getAllReferences(); // Leaf ++ //SectionPos sectionPos = SectionPos.of(pos); // Leaf - optimise ChunkGenerator#getMobsAt ++ return this.level.getChunk(pos.getX() >> 4, pos.getZ() >> 4, ChunkStatus.STRUCTURE_REFERENCES).getAllReferences(); // Leaf - optimise ChunkGenerator#getMobsAt } public StructureCheckResult checkStructurePresence(ChunkPos chunkPos, Structure structure, StructurePlacement placement, boolean skipKnownStructures) { diff --git a/net/minecraft/world/level/chunk/ChunkGenerator.java b/net/minecraft/world/level/chunk/ChunkGenerator.java -index 176adfcaa0fc458043d4bc05ead1861864b63606..87df3cd0981e94c28b816eb231942499c266a8da 100644 +index 176adfcaa0fc458043d4bc05ead1861864b63606..755e635a2ece6ab6d3b166cb437e48b527041160 100644 --- a/net/minecraft/world/level/chunk/ChunkGenerator.java +++ b/net/minecraft/world/level/chunk/ChunkGenerator.java @@ -501,18 +501,20 @@ public abstract class ChunkGenerator { @@ -44,7 +44,7 @@ index 176adfcaa0fc458043d4bc05ead1861864b63606..87df3cd0981e94c28b816eb231942499 - structureManager.fillStartsForStructure(structure, entry.getValue(), structureStart -> { - if (mutableBoolean.isFalse() && predicate.test(structureStart)) { - mutableBoolean.setTrue(); -+ // Leaf start ++ // Leaf start - optimise ChunkGenerator#getMobsAt + for (long l : entry.getValue()) { + StructureStart startForStructure = structureManager.getStartForStructure( + null, structure, structureManager.level.getChunk(ChunkPos.getX(l), ChunkPos.getZ(l), ChunkStatus.STRUCTURE_STARTS) @@ -60,7 +60,7 @@ index 176adfcaa0fc458043d4bc05ead1861864b63606..87df3cd0981e94c28b816eb231942499 - if (mutableBoolean.isTrue()) { - return structureSpawnOverride.spawns(); } -+ // Leaf end ++ // Leaf end - optimise ChunkGenerator#getMobsAt } } diff --git a/leaf-server/minecraft-patches/features/0181-optimise-getBiome.patch b/leaf-server/minecraft-patches/features/0180-optimise-getBiome.patch similarity index 95% rename from leaf-server/minecraft-patches/features/0181-optimise-getBiome.patch rename to leaf-server/minecraft-patches/features/0180-optimise-getBiome.patch index bd1a671c..98211eac 100644 --- a/leaf-server/minecraft-patches/features/0181-optimise-getBiome.patch +++ b/leaf-server/minecraft-patches/features/0180-optimise-getBiome.patch @@ -57,7 +57,7 @@ index ce2621a87dec1befb016b3437ceb2d02ed6d0b75..9b37b763c6555705f3e256010f508b5a public static boolean isInNetherFortressBounds(BlockPos pos, ServerLevel level, MobCategory category, StructureManager structureManager) { diff --git a/net/minecraft/world/level/biome/BiomeManager.java b/net/minecraft/world/level/biome/BiomeManager.java -index a48175a7ebb1788ace46395621ed78d910178a53..cb6b99dd4504681bdf2f7dbd7e3d2218304f891a 100644 +index a48175a7ebb1788ace46395621ed78d910178a53..00122472991ba0c1a0ea77053aad71cdfa92a7bd 100644 --- a/net/minecraft/world/level/biome/BiomeManager.java +++ b/net/minecraft/world/level/biome/BiomeManager.java @@ -15,10 +15,23 @@ public class BiomeManager { @@ -129,7 +129,7 @@ index a48175a7ebb1788ace46395621ed78d910178a53..cb6b99dd4504681bdf2f7dbd7e3d2218 return Mth.square(zNoise + fiddle2) + Mth.square(yNoise + fiddle1) + Mth.square(xNoise + fiddle); } -+ // Leaf start ++ // Leaf start - optimise getBiome + private static final double[] FIDDLE_TABLE = new double[1024]; + static { + for (int i = 0; i < 1024; i++) { @@ -139,9 +139,9 @@ index a48175a7ebb1788ace46395621ed78d910178a53..cb6b99dd4504681bdf2f7dbd7e3d2218 private static double getFiddle(long seed) { - return (double)(((seed >> 24) & (1024 - 1)) - (1024/2)) * (0.9 / 1024.0); // Paper - avoid floorMod, fp division, and fp subtraction + return FIDDLE_TABLE[(int)(seed >>> 24) & 1023]; -+ // return (double)(((seed >> 24) & (1024 - 1)) - (1024/2)) * (0.9 / 1024.0); // Paper - avoid floorMod, fp division, and fp subtraction ++ //return (double)(((seed >> 24) & (1024 - 1)) - (1024/2)) * (0.9 / 1024.0); // Paper - avoid floorMod, fp division, and fp subtraction } -+ // Leaf end ++ // Leaf end - optimise getBiome public interface NoiseBiomeSource { Holder getNoiseBiome(int x, int y, int z); diff --git a/leaf-server/minecraft-patches/features/0182-optimize-mob-spawning.patch b/leaf-server/minecraft-patches/features/0181-optimize-mob-spawning.patch similarity index 85% rename from leaf-server/minecraft-patches/features/0182-optimize-mob-spawning.patch rename to leaf-server/minecraft-patches/features/0181-optimize-mob-spawning.patch index 80ec7715..d606a09a 100644 --- a/leaf-server/minecraft-patches/features/0182-optimize-mob-spawning.patch +++ b/leaf-server/minecraft-patches/features/0181-optimize-mob-spawning.patch @@ -5,7 +5,7 @@ Subject: [PATCH] optimize mob spawning diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java -index f57f8e610dac80b8095bfc0c7e4b22ff5ad6b13c..55f20122732e88037d24be311469b6cab72c37ad 100644 +index f57f8e610dac80b8095bfc0c7e4b22ff5ad6b13c..c1efd558cfbfd2200295ef5755aa496e95deb7d7 100644 --- a/net/minecraft/server/level/ServerChunkCache.java +++ b/net/minecraft/server/level/ServerChunkCache.java @@ -70,7 +70,9 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon @@ -13,9 +13,9 @@ index f57f8e610dac80b8095bfc0c7e4b22ff5ad6b13c..55f20122732e88037d24be311469b6ca @Nullable @VisibleForDebug - private NaturalSpawner.SpawnState lastSpawnState; -+ private volatile NaturalSpawner.SpawnState lastSpawnState; // Leaf -+ private long delayTimeInhabited = 0L; // Leaf -+ private long delaySpawn = -1L; // Leaf ++ private volatile NaturalSpawner.SpawnState lastSpawnState; // Leaf - optimize mob spawning ++ private long delayTimeInhabited = 0L; // Leaf - optimize mob spawning ++ private long delaySpawn = -1L; // Leaf - optimize mob spawning // Paper start public final ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable fullChunks = new ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable<>(); public int getFullChunksCount() { @@ -28,7 +28,7 @@ index f57f8e610dac80b8095bfc0c7e4b22ff5ad6b13c..55f20122732e88037d24be311469b6ca - levelChunk.incrementInhabitedTime(timeInhabited); - if (!filteredSpawningCategories.isEmpty() && this.level.getWorldBorder().isWithinBounds(pos) && lastSpawnState != null && (!org.dreeam.leaf.config.modules.async.AsyncMobSpawning.enabled || _pufferfish_spawnCountsReady.get()) && this.chunkMap.anyPlayerCloseEnoughForSpawning(pos, true)) { // Spigot // Pufferfish // Leaf - Don't spawn if lastSpawnState is null - NaturalSpawner.spawnForChunk(this.level, levelChunk, lastSpawnState, filteredSpawningCategories); // Pufferfish -+ // Leaf start ++ // Leaf start - optimize mob spawning + var lastSpawnState1 = this.lastSpawnState; + if (lastSpawnState1 != null && (!org.dreeam.leaf.config.modules.async.AsyncMobSpawning.enabled || _pufferfish_spawnCountsReady.get())) { + long sumTimeInhabited = timeInhabited + delayTimeInhabited; @@ -56,27 +56,27 @@ index f57f8e610dac80b8095bfc0c7e4b22ff5ad6b13c..55f20122732e88037d24be311469b6ca + delayTimeInhabited += timeInhabited; + delaySpawn = level.getGameTime(); + } -+ // Leaf end ++ // Leaf end - optimize mob spawning -+ for (LevelChunk levelChunk : chunks) { // Leaf - split to 2 loop ++ for (LevelChunk levelChunk : chunks) { // Leaf - optimize mob spawning - split to 2 loop if (true) { // Paper - rewrite chunk system this.level.tickChunk(levelChunk, _int); } diff --git a/net/minecraft/world/level/NaturalSpawner.java b/net/minecraft/world/level/NaturalSpawner.java -index 9b37b763c6555705f3e256010f508b5a0c2cdb66..7bfc636fb442036f742903c4e69a8a9fcd0e6fc2 100644 +index 9b37b763c6555705f3e256010f508b5a0c2cdb66..bde7008e14a3b4c0a37a94a4890e2f7fa1ce2466 100644 --- a/net/minecraft/world/level/NaturalSpawner.java +++ b/net/minecraft/world/level/NaturalSpawner.java @@ -155,7 +155,13 @@ public final class NaturalSpawner { return list; } -+ @Deprecated(forRemoval = true) // Leaf ++ @Deprecated(forRemoval = true) // Leaf - optimize mob spawning public static void spawnForChunk(ServerLevel level, LevelChunk chunk, NaturalSpawner.SpawnState spawnState, List categories) { -+ // Leaf start ++ // Leaf start - optimize mob spawning + spawnForChunk(level, chunk, spawnState, categories, level.getGameTime()); + } + public static void spawnForChunk(ServerLevel level, LevelChunk chunk, NaturalSpawner.SpawnState spawnState, List categories, long gameTime) { -+ // Leaf end ++ // Leaf end - optimize mob spawning for (MobCategory mobCategory : categories) { // Paper start - Optional per player mob spawns final boolean canSpawn; @@ -85,7 +85,7 @@ index 9b37b763c6555705f3e256010f508b5a0c2cdb66..7bfc636fb442036f742903c4e69a8a9f // Paper end - throttle failed spawn attempts if (CraftSpawnCategory.isValidForLimits(spawnCategory)) { - spawnThisTick = ticksPerSpawnTmp != 0 && level.getGameTime() % ticksPerSpawn == 0; // Paper - throttle failed spawn attempts -+ spawnThisTick = ticksPerSpawnTmp != 0 && gameTime % ticksPerSpawn == 0; // Paper - throttle failed spawn attempts // Leaf ++ spawnThisTick = ticksPerSpawnTmp != 0 && gameTime % ticksPerSpawn == 0; // Paper - throttle failed spawn attempts // Leaf - optimize mob spawning limit = level.getWorld().getSpawnLimit(spawnCategory); } @@ -96,7 +96,7 @@ index 9b37b763c6555705f3e256010f508b5a0c2cdb66..7bfc636fb442036f742903c4e69a8a9f - BlockPos randomPosWithin = getRandomPosWithin(level, chunk); - if (randomPosWithin.getY() >= level.getMinY() + 1) { - return spawnCategoryForPosition(category, level, chunk, randomPosWithin, filter, callback, maxSpawns, trackEntity, false); // Paper - Optional per player mob spawns // Paper - throttle failed spawn attempts -+ // Leaf start ++ // Leaf start - optimize mob spawning + BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(); + mutableRandomPosWithin(pos, level, chunk); + if (pos.getY() < level.getMinY() + 1) { @@ -105,7 +105,7 @@ index 9b37b763c6555705f3e256010f508b5a0c2cdb66..7bfc636fb442036f742903c4e69a8a9f - - return 0; // Paper - throttle failed spawn attempts + return spawnCategoryForPosition(category, level, chunk, pos, filter, callback, maxSpawns, trackEntity, false); // Paper - Optional per player mob spawns // Paper - throttle failed spawn attempts -+ // Leaf end ++ // Leaf end - optimize mob spawning } @VisibleForDebug @@ -113,16 +113,16 @@ index 9b37b763c6555705f3e256010f508b5a0c2cdb66..7bfc636fb442036f742903c4e69a8a9f StructureManager structureManager = level.structureManager(); ChunkGenerator generator = level.getChunkSource().getGenerator(); int y = pos.getY(); -+ int posX = pos.getX(); // Leaf -+ int posZ = pos.getZ(); // Leaf ++ int posX = pos.getX(); // Leaf - optimize mob spawning ++ int posZ = pos.getZ(); // Leaf - optimize mob spawning int i = 0; // Paper - throttle failed spawn attempts BlockState blockState = level.getBlockStateIfLoadedAndInBounds(pos); // Paper - don't load chunks for mob spawn if (blockState != null && !blockState.isRedstoneConductor(chunk, pos)) { // Paper - don't load chunks for mob spawn - BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos(); -+ BlockPos.MutableBlockPos mutableBlockPos = pos instanceof BlockPos.MutableBlockPos pos2 ? pos2 : new BlockPos.MutableBlockPos(); // Leaf ++ BlockPos.MutableBlockPos mutableBlockPos = pos instanceof BlockPos.MutableBlockPos pos2 ? pos2 : new BlockPos.MutableBlockPos(); // Leaf - optimize mob spawning //int i = 0; // Paper - throttle failed spawn attempts - move up -+ // Leaf start ++ // Leaf start - optimize mob spawning + long rand = level.random.nextLong(); + int bits = 0; for (int i1 = 0; i1 < 3; i1++) { @@ -161,7 +161,7 @@ index 9b37b763c6555705f3e256010f508b5a0c2cdb66..7bfc636fb442036f742903c4e69a8a9f + } + x += rand1 - rand2; + z += rand3 - rand4; -+ // Leaf end ++ // Leaf end - optimize mob spawning mutableBlockPos.set(x, y, z); double d = x + 0.5; double d1 = z + 0.5; @@ -169,7 +169,7 @@ index 9b37b763c6555705f3e256010f508b5a0c2cdb66..7bfc636fb442036f742903c4e69a8a9f if (nearestPlayer != null) { double d2 = nearestPlayer.distanceToSqr(d, y, d1); - if (level.isLoadedAndInBounds(mutableBlockPos) && isRightDistanceToPlayerAndSpawnPoint(level, chunk, mutableBlockPos, d2)) { // Paper - don't load chunks for mob spawn -+ if (level.getWorldBorder().isWithinBounds(mutableBlockPos) && (chunk.getPos().longKey == ChunkPos.asLong(mutableBlockPos) || level.getChunkIfLoadedImmediately(mutableBlockPos.getX() >> 4, mutableBlockPos.getZ() >> 4) != null) && isRightDistanceToPlayerAndSpawnPoint(level, chunk, mutableBlockPos, d2)) { // Paper - don't load chunks for mob spawn // Leaf ++ if (level.getWorldBorder().isWithinBounds(mutableBlockPos) && (chunk.getPos().longKey == ChunkPos.asLong(mutableBlockPos) || level.getChunkIfLoadedImmediately(mutableBlockPos.getX() >> 4, mutableBlockPos.getZ() >> 4) != null) && isRightDistanceToPlayerAndSpawnPoint(level, chunk, mutableBlockPos, d2)) { // Paper - don't load chunks for mob spawn // Leaf - optimize mob spawning if (spawnerData == null) { Optional randomSpawnMobAt = getRandomSpawnMobAt( level, structureManager, generator, category, level.random, mutableBlockPos @@ -179,8 +179,8 @@ index 9b37b763c6555705f3e256010f508b5a0c2cdb66..7bfc636fb442036f742903c4e69a8a9f return !(distance <= 576.0) - && !level.getSharedSpawnPos().closerToCenterThan(new Vec3(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5), 24.0) - && (Objects.equals(new ChunkPos(pos), chunk.getPos()) || level.isNaturalSpawningAllowed(pos)); -+ && !(level.getSharedSpawnPos().distToCenterSqr(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5) < 576.0) // Leaf -+ && (ChunkPos.asLong(pos) == chunk.getPos().longKey || level.isNaturalSpawningAllowed(pos)); // Leaf ++ && !(level.getSharedSpawnPos().distToCenterSqr(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5) < 576.0) // Leaf - optimize mob spawning ++ && (ChunkPos.asLong(pos) == chunk.getPos().longKey || level.isNaturalSpawningAllowed(pos)); // Leaf - optimize mob spawning } // Paper start - PreCreatureSpawnEvent @@ -188,16 +188,16 @@ index 9b37b763c6555705f3e256010f508b5a0c2cdb66..7bfc636fb442036f742903c4e69a8a9f } } -+ // Leaf start ++ // Leaf start - optimize mob spawning + private static void mutableRandomPosWithin(BlockPos.MutableBlockPos pos1, Level level, LevelChunk chunk) { + ChunkPos pos = chunk.getPos(); -+ int i = pos.getMinBlockX() + level.random.nextInt(16); -+ int i1 = pos.getMinBlockZ() + level.random.nextInt(16); -+ int i2 = chunk.getHeight(Heightmap.Types.WORLD_SURFACE, i, i1) + 1; -+ int i3 = Mth.randomBetweenInclusive(level.random, level.getMinY(), i2); -+ pos1.set(i, i3, i1); ++ int randomX = pos.getMinBlockX() + level.random.nextInt(16); ++ int randomZ = pos.getMinBlockZ() + level.random.nextInt(16); ++ int surfaceY = chunk.getHeight(Heightmap.Types.WORLD_SURFACE, randomX, randomZ) + 1; ++ int randomY = Mth.randomBetweenInclusive(level.random, level.getMinY(), surfaceY); ++ pos1.set(randomX, randomY, randomZ); + } -+ // Leaf end ++ // Leaf end - optimize mob spawning + private static BlockPos getRandomPosWithin(Level level, LevelChunk chunk) { ChunkPos pos = chunk.getPos(); diff --git a/leaf-server/minecraft-patches/features/0183-optimize-structure-map.patch b/leaf-server/minecraft-patches/features/0182-optimize-structure-map.patch similarity index 87% rename from leaf-server/minecraft-patches/features/0183-optimize-structure-map.patch rename to leaf-server/minecraft-patches/features/0182-optimize-structure-map.patch index 34592250..de32ab83 100644 --- a/leaf-server/minecraft-patches/features/0183-optimize-structure-map.patch +++ b/leaf-server/minecraft-patches/features/0182-optimize-structure-map.patch @@ -5,7 +5,7 @@ Subject: [PATCH] optimize structure map diff --git a/net/minecraft/world/level/chunk/ChunkAccess.java b/net/minecraft/world/level/chunk/ChunkAccess.java -index 50a9903367f49ece2a267d10944b1515c7b93859..ceabb277bef2633de8f55e16431dbb4d0869817b 100644 +index 50a9903367f49ece2a267d10944b1515c7b93859..5117671a4391690c90e7577a2518d0298e4b8c74 100644 --- a/net/minecraft/world/level/chunk/ChunkAccess.java +++ b/net/minecraft/world/level/chunk/ChunkAccess.java @@ -76,8 +76,8 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh @@ -14,8 +14,8 @@ index 50a9903367f49ece2a267d10944b1515c7b93859..ceabb277bef2633de8f55e16431dbb4d // Paper - rewrite chunk system - private final Map structureStarts = Maps.newHashMap(); - private final Map structuresRefences = Maps.newHashMap(); -+ private final Map structureStarts = new it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap<>(); // Leaf -+ private final Map structuresRefences = new it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap<>(); // Leaf ++ private final Map structureStarts = new it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap<>(); // Leaf - optimize structure map ++ private final Map structuresRefences = new it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap<>(); // Leaf - optimize structure map protected final Map pendingBlockEntities = Maps.newHashMap(); public final Map blockEntities = new Object2ObjectOpenHashMap<>(); protected final LevelHeightAccessor levelHeightAccessor; @@ -24,7 +24,7 @@ index 50a9903367f49ece2a267d10944b1515c7b93859..ceabb277bef2633de8f55e16431dbb4d public Map getAllStarts() { - return Collections.unmodifiableMap(this.structureStarts); -+ return this.structureStarts; // Leaf ++ return this.structureStarts; // Leaf - optimize structure map } public void setAllStarts(Map structureStarts) { @@ -33,14 +33,14 @@ index 50a9903367f49ece2a267d10944b1515c7b93859..ceabb277bef2633de8f55e16431dbb4d @Override public void addReferenceForStructure(Structure structure, long reference) { - this.structuresRefences.computeIfAbsent(structure, key -> new LongOpenHashSet()).add(reference); -+ this.structuresRefences.computeIfAbsent(structure, key -> new it.unimi.dsi.fastutil.longs.LongArraySet()).add(reference); // Leaf ++ this.structuresRefences.computeIfAbsent(structure, key -> new it.unimi.dsi.fastutil.longs.LongArraySet()).add(reference); // Leaf - optimize structure map this.markUnsaved(); } @Override public Map getAllReferences() { - return Collections.unmodifiableMap(this.structuresRefences); -+ return this.structuresRefences; // Leaf ++ return this.structuresRefences; // Leaf - optimize structure map } @Override diff --git a/leaf-server/minecraft-patches/features/0184-throttle-mob-spawning.patch b/leaf-server/minecraft-patches/features/0183-throttle-mob-spawning.patch similarity index 88% rename from leaf-server/minecraft-patches/features/0184-throttle-mob-spawning.patch rename to leaf-server/minecraft-patches/features/0183-throttle-mob-spawning.patch index d4079d19..3f0377fd 100644 --- a/leaf-server/minecraft-patches/features/0184-throttle-mob-spawning.patch +++ b/leaf-server/minecraft-patches/features/0183-throttle-mob-spawning.patch @@ -5,14 +5,14 @@ Subject: [PATCH] throttle mob spawning diff --git a/net/minecraft/world/level/NaturalSpawner.java b/net/minecraft/world/level/NaturalSpawner.java -index 7bfc636fb442036f742903c4e69a8a9fcd0e6fc2..762bdf1fe19546f89d34b9efdad66b00dab80006 100644 +index bde7008e14a3b4c0a37a94a4890e2f7fa1ce2466..458b17dca84c87591b030679c5aac6259c0f8308 100644 --- a/net/minecraft/world/level/NaturalSpawner.java +++ b/net/minecraft/world/level/NaturalSpawner.java @@ -166,6 +166,17 @@ public final class NaturalSpawner { // Paper start - Optional per player mob spawns final boolean canSpawn; int maxSpawns = Integer.MAX_VALUE; -+ // Leaf start ++ // Leaf start - throttle mob spawning + if (org.dreeam.leaf.config.modules.opt.ThrottleNaturalMobSpawning.enabled) { + int spawnChance = org.dreeam.leaf.config.modules.opt.ThrottleNaturalMobSpawning.spawnChance[mobCategory.ordinal()]; + long failedAttempt = org.dreeam.leaf.config.modules.opt.ThrottleNaturalMobSpawning.failedAttempts[mobCategory.ordinal()]; @@ -22,7 +22,7 @@ index 7bfc636fb442036f742903c4e69a8a9fcd0e6fc2..762bdf1fe19546f89d34b9efdad66b00 + continue; + } + } -+ // Leaf end ++ // Leaf end - throttle mob spawning if (level.paperConfig().entities.spawning.perPlayerMobSpawns) { // Copied from getFilteredSpawningCategories int limit = mobCategory.getMaxInstancesPerChunk(); diff --git a/leaf-server/minecraft-patches/features/0186-Add-BlockExplosionHitEvent.patch b/leaf-server/minecraft-patches/features/0184-Add-BlockExplosionHitEvent.patch similarity index 68% rename from leaf-server/minecraft-patches/features/0186-Add-BlockExplosionHitEvent.patch rename to leaf-server/minecraft-patches/features/0184-Add-BlockExplosionHitEvent.patch index 92843555..7f6f6b67 100644 --- a/leaf-server/minecraft-patches/features/0186-Add-BlockExplosionHitEvent.patch +++ b/leaf-server/minecraft-patches/features/0184-Add-BlockExplosionHitEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add BlockExplosionHitEvent diff --git a/net/minecraft/world/level/ServerExplosion.java b/net/minecraft/world/level/ServerExplosion.java -index 6030c4eefd77969a1a9251de76d4291dcb0a2092..ea9c641fe9a9685307b6de2999ea4ff5342269b7 100644 +index 6030c4eefd77969a1a9251de76d4291dcb0a2092..f76ec9520f6a2ee42ed3ba65068c01f4b9bc8746 100644 --- a/net/minecraft/world/level/ServerExplosion.java +++ b/net/minecraft/world/level/ServerExplosion.java @@ -623,9 +623,13 @@ public class ServerExplosion implements Explosion { @@ -15,13 +15,13 @@ index 6030c4eefd77969a1a9251de76d4291dcb0a2092..ea9c641fe9a9685307b6de2999ea4ff5 - this.level - .getBlockState(blockPos) - .onExplosionHit(this.level, blockPos, this, (itemStack, blockPos1) -> addOrAppendStack(list, itemStack, blockPos1)); -+ // Leaf start - BlockExplosionHitEvent -+ if(new org.dreeam.leaf.event.BlockExplosionHitEvent(CraftLocation.toBukkit(blockPos, bworld).getBlock(), this.source == null ? null : this.source.getBukkitEntity(), org.bukkit.craftbukkit.CraftExplosionResult.toBukkit(this.blockInteraction)).callEvent()) { ++ // Leaf start - Add BlockExplosionHitEvent ++ if (new org.dreeam.leaf.event.BlockExplosionHitEvent(CraftLocation.toBukkit(blockPos, bworld).getBlock(), this.source == null ? null : this.source.getBukkitEntity(), org.bukkit.craftbukkit.CraftExplosionResult.toBukkit(this.blockInteraction)).callEvent()) { + this.level + .getBlockState(blockPos) + .onExplosionHit(this.level, blockPos, this, (itemStack, blockPos1) -> addOrAppendStack(list, itemStack, blockPos1)); + } -+ // Leaf end ++ // Leaf end - Add BlockExplosionHitEvent } for (ServerExplosion.StackCollector stackCollector : list) { diff --git a/leaf-server/minecraft-patches/features/0187-Old-Blast-Protection-explosion-knockback.patch b/leaf-server/minecraft-patches/features/0185-Old-Blast-Protection-explosion-knockback.patch similarity index 98% rename from leaf-server/minecraft-patches/features/0187-Old-Blast-Protection-explosion-knockback.patch rename to leaf-server/minecraft-patches/features/0185-Old-Blast-Protection-explosion-knockback.patch index 60d58d15..09ef9a74 100644 --- a/leaf-server/minecraft-patches/features/0187-Old-Blast-Protection-explosion-knockback.patch +++ b/leaf-server/minecraft-patches/features/0185-Old-Blast-Protection-explosion-knockback.patch @@ -17,7 +17,7 @@ index 0a5611b1ece4dbe2887e7fbdef45f58e7f4d53ad..9f6fc274525f2fe4e4e35e0feaa410bf public static final StringRepresentable.EnumCodec CODEC = StringRepresentable.fromEnum(EquipmentSlot::values); public static final StreamCodec STREAM_CODEC = ByteBufCodecs.idMapper(BY_ID, equipmentSlot -> equipmentSlot.id); diff --git a/net/minecraft/world/level/ServerExplosion.java b/net/minecraft/world/level/ServerExplosion.java -index ea9c641fe9a9685307b6de2999ea4ff5342269b7..ae0dab1f8470cf53031a2ba776fa70d8ae074a87 100644 +index f76ec9520f6a2ee42ed3ba65068c01f4b9bc8746..18f11006f0f4b3214c311f2db193df11736cd75c 100644 --- a/net/minecraft/world/level/ServerExplosion.java +++ b/net/minecraft/world/level/ServerExplosion.java @@ -532,7 +532,7 @@ public class ServerExplosion implements Explosion { diff --git a/leaf-server/minecraft-patches/features/0188-Paw-optimization.patch b/leaf-server/minecraft-patches/features/0186-Paw-optimization.patch similarity index 98% rename from leaf-server/minecraft-patches/features/0188-Paw-optimization.patch rename to leaf-server/minecraft-patches/features/0186-Paw-optimization.patch index 5c1e1b4b..a735ae35 100644 --- a/leaf-server/minecraft-patches/features/0188-Paw-optimization.patch +++ b/leaf-server/minecraft-patches/features/0186-Paw-optimization.patch @@ -100,7 +100,7 @@ index 4535858701b2bb232b9d2feb2af6551526232ddc..e65c62dbe4c1560ae153e4c4344e9194 - // Paper end - detailed watchdog information } diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java -index 55f20122732e88037d24be311469b6cab72c37ad..2f927b422c2c4f2f65d822befe3cbfd9e3bb3708 100644 +index c1efd558cfbfd2200295ef5755aa496e95deb7d7..15bbd1f7f2a90b4b5427026d622764bb1c92d465 100644 --- a/net/minecraft/server/level/ServerChunkCache.java +++ b/net/minecraft/server/level/ServerChunkCache.java @@ -506,9 +506,10 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon @@ -149,10 +149,10 @@ index 7955a8fa9c4de139b24c9d53018b055ff4008e02..eb849c57992658005e0f514c6f7923f8 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 80baa2dff5c1034a72271fc727fdb2acc1b69488..9f581d5bdc3f658694bbd8c80abbce4e27e568d3 100644 +index 64f24d3e0ecb91e0b4df6229354aeac549234f1b..df23d80d6b18e900414aa02e5c1812f0a10f0fb7 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -1147,31 +1147,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1145,31 +1145,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return this.onGround; } @@ -184,7 +184,7 @@ index 80baa2dff5c1034a72271fc727fdb2acc1b69488..9f581d5bdc3f658694bbd8c80abbce4e public void move(MoverType type, Vec3 movement) { // Gale start - VMP - skip entity move if movement is zero if (!this.boundingBoxChanged && movement.equals(Vec3.ZERO)) { -@@ -1179,16 +1154,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1177,16 +1152,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } // Gale end - VMP - skip entity move if movement is zero final Vec3 originalMovement = movement; // Paper - Expose pre-collision velocity @@ -201,7 +201,7 @@ index 80baa2dff5c1034a72271fc727fdb2acc1b69488..9f581d5bdc3f658694bbd8c80abbce4e if (this.noPhysics) { this.setPos(this.getX() + movement.x, this.getY() + movement.y, this.getZ() + movement.z); } else { -@@ -1309,13 +1275,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1307,13 +1273,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess // Gale end - skip negligible planar movement multiplication } } @@ -215,7 +215,7 @@ index 80baa2dff5c1034a72271fc727fdb2acc1b69488..9f581d5bdc3f658694bbd8c80abbce4e } private void applyMovementEmissionAndPlaySound(Entity.MovementEmission movementEmission, Vec3 movement, BlockPos pos, BlockState state) { -@@ -4881,9 +4840,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4879,9 +4838,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public void setDeltaMovement(Vec3 deltaMovement) { @@ -225,7 +225,7 @@ index 80baa2dff5c1034a72271fc727fdb2acc1b69488..9f581d5bdc3f658694bbd8c80abbce4e } public void addDeltaMovement(Vec3 addend) { -@@ -4989,9 +4946,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4987,9 +4944,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } // Paper end - Fix MC-4 if (this.position.x != x || this.position.y != y || this.position.z != z) { diff --git a/leaf-server/minecraft-patches/features/0189-Use-UUID-for-cure-reputation.patch b/leaf-server/minecraft-patches/features/0187-Use-UUID-for-cure-reputation.patch similarity index 90% rename from leaf-server/minecraft-patches/features/0189-Use-UUID-for-cure-reputation.patch rename to leaf-server/minecraft-patches/features/0187-Use-UUID-for-cure-reputation.patch index abb59c03..243d8878 100644 --- a/leaf-server/minecraft-patches/features/0189-Use-UUID-for-cure-reputation.patch +++ b/leaf-server/minecraft-patches/features/0187-Use-UUID-for-cure-reputation.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Use UUID for cure reputation diff --git a/net/minecraft/world/entity/monster/ZombieVillager.java b/net/minecraft/world/entity/monster/ZombieVillager.java -index d4b6c93f9f0e109be300164c4fd9167aba2d951c..301228895f0347ec514cefc8a11d8ca7bc2f2225 100644 +index d4b6c93f9f0e109be300164c4fd9167aba2d951c..138e62965a4e532972e51c16b429e050bb147788 100644 --- a/net/minecraft/world/entity/monster/ZombieVillager.java +++ b/net/minecraft/world/entity/monster/ZombieVillager.java @@ -310,9 +310,10 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder { @@ -16,7 +16,7 @@ index d4b6c93f9f0e109be300164c4fd9167aba2d951c..301228895f0347ec514cefc8a11d8ca7 if (playerByUuid instanceof ServerPlayer) { CriteriaTriggers.CURED_ZOMBIE_VILLAGER.trigger((ServerPlayer)playerByUuid, this, villager); - serverLevel.onReputationEvent(ReputationEventType.ZOMBIE_VILLAGER_CURED, playerByUuid, villager); -+ // serverLevel.onReputationEvent(ReputationEventType.ZOMBIE_VILLAGER_CURED, playerByUuid, villager); // Leaf - move up ++ //serverLevel.onReputationEvent(ReputationEventType.ZOMBIE_VILLAGER_CURED, playerByUuid, villager); // Leaf - Use UUID for cure reputation - move up } } diff --git a/leaf-server/minecraft-patches/features/0190-Cache-potential-behaviors-in-Brain.patch b/leaf-server/minecraft-patches/features/0188-Cache-potential-behaviors-in-Brain.patch similarity index 69% rename from leaf-server/minecraft-patches/features/0190-Cache-potential-behaviors-in-Brain.patch rename to leaf-server/minecraft-patches/features/0188-Cache-potential-behaviors-in-Brain.patch index 5b0006d5..05706456 100644 --- a/leaf-server/minecraft-patches/features/0190-Cache-potential-behaviors-in-Brain.patch +++ b/leaf-server/minecraft-patches/features/0188-Cache-potential-behaviors-in-Brain.patch @@ -5,14 +5,14 @@ Subject: [PATCH] Cache potential behaviors in Brain diff --git a/net/minecraft/world/entity/ai/Brain.java b/net/minecraft/world/entity/ai/Brain.java -index 97dad57ba873c0f6404a490e358739dbaf11bc55..34b66ee67927bc0796d6c5f069393618abca9d74 100644 +index 4dde1642a33349335f374f17123a700dde1079d7..5e86c8f6dffc7b4dd17acc43ec4c458368bf92a4 100644 --- a/net/minecraft/world/entity/ai/Brain.java +++ b/net/minecraft/world/entity/ai/Brain.java @@ -60,6 +60,7 @@ public class Brain { private Activity defaultActivity = Activity.IDLE; private long lastScheduleUpdate = -9999L; -+ private ObjectArrayList> cachedPotentialBehaviors; ++ private ObjectArrayList> cachedPotentialBehaviors; // Leaf - Cache potential behaviors in Brain public static Brain.Provider provider( Collection> memoryTypes, Collection>> sensorTypes ) { @@ -20,7 +20,7 @@ index 97dad57ba873c0f6404a490e358739dbaf11bc55..34b66ee67927bc0796d6c5f069393618 for (Brain.MemoryValue memoryValue : memoryValues) { memoryValue.setMemoryInternal(this); } -+ this.invalidateBehaviorCache(); ++ this.invalidateBehaviorCache(); // Leaf - Cache potential behaviors in Brain } public DataResult serializeStart(DynamicOps ops) { @@ -28,7 +28,7 @@ index 97dad57ba873c0f6404a490e358739dbaf11bc55..34b66ee67927bc0796d6c5f069393618 this.activeActivities.clear(); this.activeActivities.addAll(this.coreActivities); this.activeActivities.add(activity); -+ this.invalidateBehaviorCache(); ++ this.invalidateBehaviorCache(); // Leaf - Cache potential behaviors in Brain } } @@ -36,56 +36,47 @@ index 97dad57ba873c0f6404a490e358739dbaf11bc55..34b66ee67927bc0796d6c5f069393618 .computeIfAbsent(activity, activity1 -> new it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet<>()) // Leaf - Replace brain activity maps with optimized collection .add((BehaviorControl)pair.getSecond()); } -+ this.invalidateBehaviorCache(); ++ this.invalidateBehaviorCache(); // Leaf - Cache potential behaviors in Brain } @VisibleForTesting public void removeAllBehaviors() { this.availableBehaviorsByPriority.clear(); -+ this.invalidateBehaviorCache(); ++ this.invalidateBehaviorCache(); // Leaf - Cache potential behaviors in Brain } public boolean isActive(Activity activity) { -@@ -452,30 +457,40 @@ public class Brain { +@@ -452,23 +457,44 @@ public class Brain { } } - private void startEachNonRunningBehavior(ServerLevel level, E entity) { -- // Leaf start - Collect then startEachNonRunningBehavior in Brain -- final long gameTime = level.getGameTime(); -- List> behaviorsToStart = new ObjectArrayList<>(); -- -- for (Activity activeActivity : this.activeActivities) { -- for (Map>> priorityMap : this.availableBehaviorsByPriority.values()) { -- Set> behaviors = priorityMap.get(activeActivity); -- -- if (behaviors != null && !behaviors.isEmpty()) { -- for (BehaviorControl behaviorControl : behaviors) { -- if (behaviorControl.getStatus() == Behavior.Status.STOPPED) { -- behaviorsToStart.add(behaviorControl); -- } +- long gameTime = level.getGameTime(); ++ // Leaf start - Cache potential behaviors in Brain + private void invalidateBehaviorCache() { + this.cachedPotentialBehaviors = null; + } + + private void rebuildBehaviorCache() { + this.cachedPotentialBehaviors = new ObjectArrayList<>(30); -+ -+ for (Map>> map : this.availableBehaviorsByPriority.values()) { + + for (Map>> map : this.availableBehaviorsByPriority.values()) { +- for (Entry>> entry : map.entrySet()) { + for (Map.Entry>> entry : map.entrySet()) { -+ Activity activity = entry.getKey(); -+ if (this.activeActivities.contains(activity)) { + Activity activity = entry.getKey(); + if (this.activeActivities.contains(activity)) { +- for (BehaviorControl behaviorControl : entry.getValue()) { +- if (behaviorControl.getStatus() == Behavior.Status.STOPPED) { +- behaviorControl.tryStart(level, entity, gameTime); +- } + for (BehaviorControl task : entry.getValue()) { + this.cachedPotentialBehaviors.add(task); } } } } -- if (!behaviorsToStart.isEmpty()) { -- for (BehaviorControl behaviorControl : behaviorsToStart) { -- behaviorControl.tryStart(level, entity, gameTime); -+ } -+ + } + + private ObjectArrayList> getPotentialBehaviors() { + if (this.cachedPotentialBehaviors == null) { + this.rebuildBehaviorCache(); @@ -99,9 +90,11 @@ index 97dad57ba873c0f6404a490e358739dbaf11bc55..34b66ee67927bc0796d6c5f069393618 + for (BehaviorControl task : this.getPotentialBehaviors()) { + if (task.getStatus() == Behavior.Status.STOPPED) { + task.tryStart(level, entity, startTime); - } - } -- // Leaf end - Collect then startEachNonRunningBehavior in Brain - } - ++ } ++ } ++ } ++ // Leaf end - Cache potential behaviors in Brain ++ private void tickEachRunningBehavior(ServerLevel level, E entity) { + long gameTime = level.getGameTime(); + diff --git a/leaf-server/minecraft-patches/features/0191-Use-ActivationList-on-runningBehaviors.patch b/leaf-server/minecraft-patches/features/0189-Use-ActivationList-on-runningBehaviors.patch similarity index 77% rename from leaf-server/minecraft-patches/features/0191-Use-ActivationList-on-runningBehaviors.patch rename to leaf-server/minecraft-patches/features/0189-Use-ActivationList-on-runningBehaviors.patch index 667f2a4c..cc37bd53 100644 --- a/leaf-server/minecraft-patches/features/0191-Use-ActivationList-on-runningBehaviors.patch +++ b/leaf-server/minecraft-patches/features/0189-Use-ActivationList-on-runningBehaviors.patch @@ -5,14 +5,14 @@ Subject: [PATCH] Use ActivationList on runningBehaviors diff --git a/net/minecraft/world/entity/ai/Brain.java b/net/minecraft/world/entity/ai/Brain.java -index 34b66ee67927bc0796d6c5f069393618abca9d74..f7dd07feea8884c686e78becb1f9cbd0d2769915 100644 +index 5e86c8f6dffc7b4dd17acc43ec4c458368bf92a4..948731703d25eb3f86a83d45b7fd6ce4b4d3c4e8 100644 --- a/net/minecraft/world/entity/ai/Brain.java +++ b/net/minecraft/world/entity/ai/Brain.java @@ -61,6 +61,7 @@ public class Brain { private long lastScheduleUpdate = -9999L; - private ObjectArrayList> cachedPotentialBehaviors; -+ private org.dreeam.leaf.util.list.ActivationList> runningBehaviors; + private ObjectArrayList> cachedPotentialBehaviors; // Leaf - Cache potential behaviors in Brain ++ private org.dreeam.leaf.util.list.ActivationList> runningBehaviors; // Leaf - Use ActivationList on runningBehaviors public static Brain.Provider provider( Collection> memoryTypes, Collection>> sensorTypes ) { @@ -33,29 +33,31 @@ index 34b66ee67927bc0796d6c5f069393618abca9d74..f7dd07feea8884c686e78becb1f9cbd0 - } - - return list; -+ return this.getRunningBehaviorsList(); ++ return this.getRunningBehaviorsList(); // Leaf - Use ActivationList on runningBehaviors } public void useDefaultActivity() { -@@ -453,12 +442,14 @@ public class Brain { +@@ -453,6 +442,7 @@ public class Brain { long gameTime = owner.level().getGameTime(); for (BehaviorControl behaviorControl : this.getRunningBehaviors()) { -+ this.getRunningBehaviorsList().setVisibility(behaviorControl, false); ++ this.getRunningBehaviorsList().setVisibility(behaviorControl, false); // Leaf - Use ActivationList on runningBehaviors behaviorControl.doStop(level, owner, gameTime); } } - +@@ -460,6 +450,7 @@ public class Brain { + // Leaf start - Cache potential behaviors in Brain private void invalidateBehaviorCache() { this.cachedPotentialBehaviors = null; -+ this.runningBehaviors = null; ++ this.runningBehaviors = null; // Leaf - Use ActivationList on runningBehaviors } private void rebuildBehaviorCache() { -@@ -476,6 +467,25 @@ public class Brain { +@@ -477,6 +468,27 @@ public class Brain { } } ++ // Leaf start - Use ActivationList on runningBehaviors + private void initializeRunningBehaviors() { + this.runningBehaviors = new org.dreeam.leaf.util.list.ActivationList<>(false); + @@ -74,11 +76,12 @@ index 34b66ee67927bc0796d6c5f069393618abca9d74..f7dd07feea8884c686e78becb1f9cbd0 + } + return this.runningBehaviors; + } ++ // Leaf end - Use ActivationList on runningBehaviors + private ObjectArrayList> getPotentialBehaviors() { if (this.cachedPotentialBehaviors == null) { this.rebuildBehaviorCache(); -@@ -489,6 +499,9 @@ public class Brain { +@@ -490,6 +502,9 @@ public class Brain { for (BehaviorControl task : this.getPotentialBehaviors()) { if (task.getStatus() == Behavior.Status.STOPPED) { task.tryStart(level, entity, startTime); @@ -88,13 +91,15 @@ index 34b66ee67927bc0796d6c5f069393618abca9d74..f7dd07feea8884c686e78becb1f9cbd0 } } } -@@ -498,6 +511,9 @@ public class Brain { +@@ -500,6 +515,11 @@ public class Brain { for (BehaviorControl behaviorControl : this.getRunningBehaviors()) { behaviorControl.tickOrStop(level, entity, gameTime); ++ // Leaf start - Use ActivationList on runningBehaviors + if (behaviorControl.getStatus() != Behavior.Status.RUNNING) { + this.getRunningBehaviorsList().setVisibility(behaviorControl, false); + } ++ // Leaf end - Use ActivationList on runningBehaviors } } diff --git a/leaf-server/minecraft-patches/features/0192-Paper-Fix-infinite-loop-in-RegionFile-IO.patch b/leaf-server/minecraft-patches/features/0190-Paper-Fix-infinite-loop-in-RegionFile-IO.patch similarity index 56% rename from leaf-server/minecraft-patches/features/0192-Paper-Fix-infinite-loop-in-RegionFile-IO.patch rename to leaf-server/minecraft-patches/features/0190-Paper-Fix-infinite-loop-in-RegionFile-IO.patch index 64550a29..8efc83f0 100644 --- a/leaf-server/minecraft-patches/features/0192-Paper-Fix-infinite-loop-in-RegionFile-IO.patch +++ b/leaf-server/minecraft-patches/features/0190-Paper-Fix-infinite-loop-in-RegionFile-IO.patch @@ -1,11 +1,19 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Taiyou06 -Date: Mon, 9 Jun 2025 12:00:57 +0200 +From: Spottedleaf +Date: Mon, 9 Jun 2025 02:46:34 -0700 Subject: [PATCH] Paper: Fix infinite loop in RegionFile IO +Original license: GPLv3 +Original project: https://github.com/PaperMC/Paper + +https://github.com/PaperMC/Paper/commit/519e4224b1ba73a99c58c8fc53aab003eb6af37a + +If an exception is thrown during decompress then the read process +would be started again, which of course would eventually throw in +the decompress process. diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java b/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java -index 60ed8cff397c964323fbda203ebfab3c7c9a873b..32ee1d3a0ae67738a65545e6a0046a12fb940fa4 100644 +index 60ed8cff397c964323fbda203ebfab3c7c9a873b..88207a3afd0260f572c7f54003d566c2c1cb1633 100644 --- a/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java +++ b/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java @@ -1143,7 +1143,7 @@ public final class MoonriseRegionFileIO { @@ -13,7 +21,7 @@ index 60ed8cff397c964323fbda203ebfab3c7c9a873b..32ee1d3a0ae67738a65545e6a0046a12 } - if (compoundTag == null) { -+ if (throwable == null && compoundTag == null) { ++ if (throwable == null && compoundTag == null) { // Paper - Fix infinite loop in RegionFile IO // need to re-try from the start this.scheduleReadIO(); return; diff --git a/leaf-server/minecraft-patches/features/0191-Paper-Fix-excess-slot-updates-inventory-state-id-des.patch b/leaf-server/minecraft-patches/features/0191-Paper-Fix-excess-slot-updates-inventory-state-id-des.patch new file mode 100644 index 00000000..d921c5df --- /dev/null +++ b/leaf-server/minecraft-patches/features/0191-Paper-Fix-excess-slot-updates-inventory-state-id-des.patch @@ -0,0 +1,20 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Taiyou06 +Date: Wed, 11 Jun 2025 20:51:36 +0200 +Subject: [PATCH] Paper: Fix excess slot updates / inventory state id desync + +Original Patch: https://github.com/PaperMC/Paper/pull/12654 + +diff --git a/net/minecraft/world/inventory/AbstractContainerMenu.java b/net/minecraft/world/inventory/AbstractContainerMenu.java +index ff2ff95ec9d94e2e31e8174196b384c37d56f38a..2a49a0bdeb61c4fadddc241c8ebca908959d7e9c 100644 +--- a/net/minecraft/world/inventory/AbstractContainerMenu.java ++++ b/net/minecraft/world/inventory/AbstractContainerMenu.java +@@ -553,7 +553,7 @@ public abstract class AbstractContainerMenu { + + slot.setChanged(); + // CraftBukkit start - Make sure the client has the right slot contents +- if (player instanceof ServerPlayer serverPlayer && slot.getMaxStackSize() != 64) { ++ if (player instanceof ServerPlayer serverPlayer && slot.getMaxStackSize() != net.minecraft.world.Container.MAX_STACK) { + serverPlayer.connection.send(new ClientboundContainerSetSlotPacket(this.containerId, this.incrementStateId(), slot.index, slot.getItem())); + // Updating a crafting inventory makes the client reset the result slot, have to send it again + if (this.getBukkitView().getType() == org.bukkit.event.inventory.InventoryType.WORKBENCH || this.getBukkitView().getType() == org.bukkit.event.inventory.InventoryType.CRAFTING) { diff --git a/leaf-server/paper-patches/features/0043-dump-pwt-thread.patch b/leaf-server/paper-patches/features/0043-dump-pwt-thread.patch index 3af35014..7d59e65b 100644 --- a/leaf-server/paper-patches/features/0043-dump-pwt-thread.patch +++ b/leaf-server/paper-patches/features/0043-dump-pwt-thread.patch @@ -5,24 +5,14 @@ Subject: [PATCH] dump pwt thread diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java -index e45d5da04428c26fc6aa97fba974bde3573d7950..745a9afcdb8ea3047c1fcdc91971ba8f034cbd39 100644 +index e45d5da04428c26fc6aa97fba974bde3573d7950..16e5ab49bc96f64143eb9e0dff19b33a7e3b5f3a 100644 --- a/src/main/java/org/spigotmc/WatchdogThread.java +++ b/src/main/java/org/spigotmc/WatchdogThread.java -@@ -8,6 +8,7 @@ import java.lang.management.ThreadInfo; - import java.util.logging.Level; - import java.util.logging.Logger; - import net.minecraft.server.MinecraftServer; -+import net.minecraft.server.level.ServerLevel; - import org.bukkit.Bukkit; - import org.bukkit.craftbukkit.CraftServer; - -@@ -124,8 +125,21 @@ public class WatchdogThread extends ca.spottedleaf.moonrise.common.util.TickThre - logger.log(Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Leaf!):"); // Paper // Gale - branding changes // Leaf - Rebrand - FeatureHooks.dumpAllChunkLoadInfo(MinecraftServer.getServer(), isLongTimeout); // Paper - log detailed tick information +@@ -126,6 +126,21 @@ public class WatchdogThread extends ca.spottedleaf.moonrise.common.util.TickThre WatchdogThread.dumpThread(ManagementFactory.getThreadMXBean().getThreadInfo(MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE), logger); -+ // Leaf start logger.log(Level.SEVERE, "------------------------------"); -- + ++ // Leaf start - dump pwt thread + logger.log(Level.SEVERE, "Parallel world ticking thread dump"); + for (Thread thread : org.apache.commons.lang3.ThreadUtils.getAllThreads()) { + if (MinecraftServer.getServer().serverThread == thread || thread instanceof WatchdogThread) { @@ -30,12 +20,13 @@ index e45d5da04428c26fc6aa97fba974bde3573d7950..745a9afcdb8ea3047c1fcdc91971ba8f + } + if (thread instanceof ca.spottedleaf.moonrise.common.util.TickThread tickThread) { + if (tickThread instanceof ServerLevelTickThread tickThread1) { -+ WatchdogThread.dumpThread(ManagementFactory.getThreadMXBean().getThreadInfo(tickThread1.getId(), Integer.MAX_VALUE), logger); ++ WatchdogThread.dumpThread(ManagementFactory.getThreadMXBean().getThreadInfo(tickThread1.threadId(), Integer.MAX_VALUE), logger); + } + } + } + logger.log(Level.SEVERE, "------------------------------"); -+ // Leaf end ++ // Leaf end - dump pwt thread ++ // Paper start - Only print full dump on long timeouts if (isLongTimeout) { logger.log(Level.SEVERE, "Entire Thread Dump:"); diff --git a/leaf-server/src/main/java/gg/pufferfish/pufferfish/util/AsyncExecutor.java b/leaf-server/src/main/java/gg/pufferfish/pufferfish/util/AsyncExecutor.java index e417ef8d..85d37d3d 100644 --- a/leaf-server/src/main/java/gg/pufferfish/pufferfish/util/AsyncExecutor.java +++ b/leaf-server/src/main/java/gg/pufferfish/pufferfish/util/AsyncExecutor.java @@ -13,7 +13,7 @@ public class AsyncExecutor implements Runnable { private final Logger LOGGER = LogManager.getLogger("Leaf"); private final PriorityQueue jobs = PriorityQueues.synchronize(new ObjectArrayFIFOQueue<>()); - private final Thread thread; + public final Thread thread; private volatile boolean killswitch = false; public AsyncExecutor(String threadName) { @@ -28,10 +28,10 @@ public class AsyncExecutor implements Runnable { thread.start(); } - public void kill() throws InterruptedException { + public void join(long millis) throws InterruptedException { killswitch = true; LockSupport.unpark(thread); - thread.join(); + thread.join(millis); } public void submit(Runnable runnable) { diff --git a/leaf-server/src/main/java/org/dreeam/leaf/async/AsyncPlayerDataSaving.java b/leaf-server/src/main/java/org/dreeam/leaf/async/AsyncPlayerDataSaving.java index 3df32778..b67eda75 100644 --- a/leaf-server/src/main/java/org/dreeam/leaf/async/AsyncPlayerDataSaving.java +++ b/leaf-server/src/main/java/org/dreeam/leaf/async/AsyncPlayerDataSaving.java @@ -12,20 +12,30 @@ import java.util.concurrent.TimeUnit; public class AsyncPlayerDataSaving { - public static final ExecutorService IO_POOL = new ThreadPoolExecutor( - 1, 1, 0L, TimeUnit.MILLISECONDS, - new LinkedBlockingQueue<>(), - new com.google.common.util.concurrent.ThreadFactoryBuilder() - .setPriority(Thread.NORM_PRIORITY - 2) - .setNameFormat("Leaf IO Thread") - .setUncaughtExceptionHandler(Util::onThreadException) - .build(), - new ThreadPoolExecutor.DiscardPolicy() - ); + public static ExecutorService IO_POOL = null; private AsyncPlayerDataSaving() { } + public static void init() { + if (IO_POOL == null) { + IO_POOL = new ThreadPoolExecutor( + 1, + 1, + 0L, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue<>(), + new com.google.common.util.concurrent.ThreadFactoryBuilder() + .setPriority(Thread.NORM_PRIORITY - 2) + .setNameFormat("Leaf IO Thread") + .setUncaughtExceptionHandler(Util::onThreadException) + .build(), + new ThreadPoolExecutor.DiscardPolicy() + ); + } else { + throw new IllegalStateException(); + } + } + public static Optional> submit(Runnable runnable) { if (!AsyncPlayerDataSave.enabled) { runnable.run(); 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 ee6d490d..3103e125 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 @@ -1,37 +1,59 @@ 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.ai.AsyncGoalThread; +import org.dreeam.leaf.async.path.AsyncPathProcessor; import org.dreeam.leaf.async.tracker.MultithreadedTracker; -public class ShutdownExecutors { - public static void shutdown(MinecraftServer server) { +import java.util.concurrent.TimeUnit; - if (server.mobSpawnExecutor != null) { +public class ShutdownExecutors { + + public static final Logger LOGGER = LogManager.getLogger("Leaf"); + + public static void shutdown(MinecraftServer server) { + if (server.mobSpawnExecutor != null && server.mobSpawnExecutor.thread.isAlive()) { + LOGGER.info("Waiting for mob spawning thread to shutdown..."); try { - server.mobSpawnExecutor.kill(); + server.mobSpawnExecutor.join(3000L); } catch (InterruptedException ignored) { } } if (AsyncPlayerDataSaving.IO_POOL != null) { + LOGGER.info("Waiting for player I/O executor to shutdown..."); AsyncPlayerDataSaving.IO_POOL.shutdown(); try { - AsyncPlayerDataSaving.IO_POOL.awaitTermination(300L, java.util.concurrent.TimeUnit.SECONDS); + AsyncPlayerDataSaving.IO_POOL.awaitTermination(60L, TimeUnit.SECONDS); } catch (InterruptedException ignored) { } } if (server.asyncGoalThread != null) { + LOGGER.info("Waiting for mob target finding thread to shutdown..."); + AsyncGoalThread.RUNNING = false; try { - server.asyncGoalThread.join(); + server.asyncGoalThread.join(3000L); } catch (InterruptedException ignored) { } } if (MultithreadedTracker.TRACKER_EXECUTOR != null) { + LOGGER.info("Waiting for mob tracker executor to shutdown..."); MultithreadedTracker.TRACKER_EXECUTOR.shutdown(); try { - MultithreadedTracker.TRACKER_EXECUTOR.awaitTermination(10L, java.util.concurrent.TimeUnit.SECONDS); + MultithreadedTracker.TRACKER_EXECUTOR.awaitTermination(10L, TimeUnit.SECONDS); + } catch (InterruptedException ignored) { + } + } + + if (AsyncPathProcessor.PATH_PROCESSING_EXECUTOR != null) { + LOGGER.info("Waiting for mob pathfinding executor to shutdown..."); + AsyncPathProcessor.PATH_PROCESSING_EXECUTOR.shutdown(); + try { + AsyncPathProcessor.PATH_PROCESSING_EXECUTOR.awaitTermination(10L, TimeUnit.SECONDS); } catch (InterruptedException ignored) { } } diff --git a/leaf-server/src/main/java/org/dreeam/leaf/async/ai/AsyncGoalThread.java b/leaf-server/src/main/java/org/dreeam/leaf/async/ai/AsyncGoalThread.java index 06bd5e48..e989adbf 100644 --- a/leaf-server/src/main/java/org/dreeam/leaf/async/ai/AsyncGoalThread.java +++ b/leaf-server/src/main/java/org/dreeam/leaf/async/ai/AsyncGoalThread.java @@ -9,6 +9,7 @@ import java.util.concurrent.locks.LockSupport; public class AsyncGoalThread extends Thread { + public static volatile boolean RUNNING = true; public AsyncGoalThread(final MinecraftServer server) { super(() -> run(server), "Leaf Async Goal Thread"); this.setDaemon(false); @@ -18,7 +19,7 @@ public class AsyncGoalThread extends Thread { } private static void run(MinecraftServer server) { - while (server.isRunning()) { + while (RUNNING) { boolean retry = false; for (ServerLevel level : server.getAllLevels()) { var exec = level.asyncGoalExecutor; diff --git a/leaf-server/src/main/java/org/dreeam/leaf/async/path/AsyncPathProcessor.java b/leaf-server/src/main/java/org/dreeam/leaf/async/path/AsyncPathProcessor.java index 7ebcec15..a1f2fb95 100644 --- a/leaf-server/src/main/java/org/dreeam/leaf/async/path/AsyncPathProcessor.java +++ b/leaf-server/src/main/java/org/dreeam/leaf/async/path/AsyncPathProcessor.java @@ -1,6 +1,7 @@ package org.dreeam.leaf.async.path; import com.google.common.util.concurrent.ThreadFactoryBuilder; +import net.minecraft.Util; import net.minecraft.server.MinecraftServer; import net.minecraft.world.level.pathfinder.Path; import org.apache.logging.log4j.LogManager; @@ -15,6 +16,7 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.CompletableFuture; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -28,49 +30,25 @@ public class AsyncPathProcessor { private static final String THREAD_PREFIX = "Leaf Async Pathfinding"; private static final Logger LOGGER = LogManager.getLogger(THREAD_PREFIX); private static long lastWarnMillis = System.currentTimeMillis(); - private static final ThreadPoolExecutor pathProcessingExecutor = new ThreadPoolExecutor( - 1, - AsyncPathfinding.asyncPathfindingMaxThreads, - AsyncPathfinding.asyncPathfindingKeepalive, TimeUnit.SECONDS, - getQueueImpl(), - new ThreadFactoryBuilder() - .setNameFormat(THREAD_PREFIX + " Thread - %d") - .setPriority(Thread.NORM_PRIORITY - 2) - .build(), - new RejectedTaskHandler() - ); + public static ThreadPoolExecutor PATH_PROCESSING_EXECUTOR = null; - private static class RejectedTaskHandler implements RejectedExecutionHandler { - @Override - public void rejectedExecution(Runnable rejectedTask, ThreadPoolExecutor executor) { - BlockingQueue workQueue = executor.getQueue(); - if (!executor.isShutdown()) { - switch (AsyncPathfinding.asyncPathfindingRejectPolicy) { - case FLUSH_ALL -> { - if (!workQueue.isEmpty()) { - List pendingTasks = new ArrayList<>(workQueue.size()); - - workQueue.drainTo(pendingTasks); - - for (Runnable pendingTask : pendingTasks) { - pendingTask.run(); - } - } - rejectedTask.run(); - } - case CALLER_RUNS -> rejectedTask.run(); - } - } - - if (System.currentTimeMillis() - lastWarnMillis > 30000L) { - LOGGER.warn("Async pathfinding processor is busy! Pathfinding tasks will be treated as policy defined in config. Increasing max-threads in Leaf config may help."); - lastWarnMillis = System.currentTimeMillis(); - } + public static void init() { + if (PATH_PROCESSING_EXECUTOR == null) { + PATH_PROCESSING_EXECUTOR = new ThreadPoolExecutor( + getCorePoolSize(), + getMaxPoolSize(), + getKeepAliveTime(), TimeUnit.SECONDS, + getQueueImpl(), + getThreadFactory(), + getRejectedPolicy() + ); + } else { + throw new IllegalStateException(); } } protected static CompletableFuture queue(@NotNull AsyncPath path) { - return CompletableFuture.runAsync(path::process, pathProcessingExecutor) + return CompletableFuture.runAsync(path::process, PATH_PROCESSING_EXECUTOR) .orTimeout(60L, TimeUnit.SECONDS) .exceptionally(throwable -> { if (throwable instanceof TimeoutException e) { @@ -98,9 +76,57 @@ public class AsyncPathProcessor { } } + private static int getCorePoolSize() { + return 1; + } + + private static int getMaxPoolSize() { + return AsyncPathfinding.asyncPathfindingMaxThreads; + } + + private static long getKeepAliveTime() { + return AsyncPathfinding.asyncPathfindingKeepalive; + } + private static BlockingQueue getQueueImpl() { final int queueCapacity = AsyncPathfinding.asyncPathfindingQueueSize; return new LinkedBlockingQueue<>(queueCapacity); } + + private static @NotNull ThreadFactory getThreadFactory() { + return new ThreadFactoryBuilder() + .setNameFormat(THREAD_PREFIX + " Thread - %d") + .setPriority(Thread.NORM_PRIORITY - 2) + .setUncaughtExceptionHandler(Util::onThreadException) + .build(); + } + + private static @NotNull RejectedExecutionHandler getRejectedPolicy() { + return (Runnable rejectedTask, ThreadPoolExecutor executor) -> { + BlockingQueue workQueue = executor.getQueue(); + if (!executor.isShutdown()) { + switch (AsyncPathfinding.asyncPathfindingRejectPolicy) { + case FLUSH_ALL -> { + if (!workQueue.isEmpty()) { + List pendingTasks = new ArrayList<>(workQueue.size()); + + workQueue.drainTo(pendingTasks); + + for (Runnable pendingTask : pendingTasks) { + pendingTask.run(); + } + } + rejectedTask.run(); + } + case CALLER_RUNS -> rejectedTask.run(); + } + } + + if (System.currentTimeMillis() - lastWarnMillis > 30000L) { + LOGGER.warn("Async pathfinding processor is busy! Pathfinding tasks will be treated as policy defined in config. Increasing max-threads in Leaf config may help."); + lastWarnMillis = System.currentTimeMillis(); + } + }; + } } diff --git a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/async/AsyncPathfinding.java b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/async/AsyncPathfinding.java index 003458e5..19eabb55 100644 --- a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/async/AsyncPathfinding.java +++ b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/async/AsyncPathfinding.java @@ -60,5 +60,9 @@ public class AsyncPathfinding extends ConfigModules { ? PathfindTaskRejectPolicy.FLUSH_ALL.toString() : PathfindTaskRejectPolicy.CALLER_RUNS.toString()) ); + + if (enabled) { + org.dreeam.leaf.async.path.AsyncPathProcessor.init(); + } } } diff --git a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/async/AsyncPlayerDataSave.java b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/async/AsyncPlayerDataSave.java index 6d555ce0..c87908e2 100644 --- a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/async/AsyncPlayerDataSave.java +++ b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/async/AsyncPlayerDataSave.java @@ -19,5 +19,9 @@ public class AsyncPlayerDataSave extends ConfigModules { 异步保存玩家数据."""); enabled = config.getBoolean(getBasePath() + ".enabled", enabled); + + if (enabled) { + org.dreeam.leaf.async.AsyncPlayerDataSaving.init(); + } } } diff --git a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/async/MultithreadedTracker.java b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/async/MultithreadedTracker.java index 7a01b4b1..8c6c257f 100644 --- a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/async/MultithreadedTracker.java +++ b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/async/MultithreadedTracker.java @@ -57,6 +57,7 @@ public class MultithreadedTracker extends ConfigModules { if (asyncEntityTrackerQueueSize <= 0) asyncEntityTrackerQueueSize = asyncEntityTrackerMaxThreads * 384; + if (enabled) { org.dreeam.leaf.async.tracker.MultithreadedTracker.init(); } diff --git a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/OptimiseBlockEntities.java b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/OptimiseBlockEntities.java deleted file mode 100644 index e1ddf5eb..00000000 --- a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/OptimiseBlockEntities.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.dreeam.leaf.config.modules.opt; - -import org.dreeam.leaf.config.ConfigModules; -import org.dreeam.leaf.config.EnumConfigCategory; - -public class OptimiseBlockEntities extends ConfigModules { - - public String getBasePath() { - return EnumConfigCategory.PERF.getBaseKeyName(); - } - - public static boolean enabled = true; - - @Override - public void onLoaded() { - enabled = config.getBoolean(getBasePath() + ".optimise-block-entities", enabled); - } -} diff --git a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/OptimizeBlockEntities.java b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/OptimizeBlockEntities.java new file mode 100644 index 00000000..4e76dea4 --- /dev/null +++ b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/OptimizeBlockEntities.java @@ -0,0 +1,24 @@ +package org.dreeam.leaf.config.modules.opt; + +import org.dreeam.leaf.config.ConfigModules; +import org.dreeam.leaf.config.EnumConfigCategory; + +public class OptimizeBlockEntities extends ConfigModules { + + public String getBasePath() { + return EnumConfigCategory.PERF.getBaseKeyName(); + } + + public static boolean enabled = true; + + @Override + public void onLoaded() { + // Transfer old config + Boolean optimiseBlockEntities = config.getBoolean(getBasePath() + ".optimise-block-entities"); + if (optimiseBlockEntities != null && optimiseBlockEntities) { + enabled = true; + } + + enabled = config.getBoolean(getBasePath() + ".optimize-block-entities", enabled); + } +} diff --git a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/OptimizePlayerMovementProcessing.java b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/OptimizePlayerMovementProcessing.java index 3f407850..f8016d34 100644 --- a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/OptimizePlayerMovementProcessing.java +++ b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/OptimizePlayerMovementProcessing.java @@ -17,6 +17,5 @@ public class OptimizePlayerMovementProcessing extends ConfigModules { Whether to optimize player movement processing by skipping unnecessary edge checks and avoiding redundant view distance updates.""", """ 是否优化玩家移动处理,跳过不必要的边缘检查并避免冗余的视距更新。""")); - } } diff --git a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/PreloadNaturalMobSpawning.java b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/PreloadNaturalMobSpawning.java deleted file mode 100644 index 50a5742e..00000000 --- a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/PreloadNaturalMobSpawning.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.dreeam.leaf.config.modules.opt; - -import org.dreeam.leaf.config.ConfigModules; -import org.dreeam.leaf.config.EnumConfigCategory; - -public class PreloadNaturalMobSpawning extends ConfigModules { - public String getBasePath() { - return EnumConfigCategory.PERF.getBaseKeyName() + ".preload-mob-spawning-position"; - } - - public static boolean enabled = false; - - @Override - public void onLoaded() { - enabled = config.getBoolean(getBasePath() + ".enabled", enabled); - } -} diff --git a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/ReduceChunkSourceUpdates.java b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/ReduceChunkSourceUpdates.java index e89a0ad2..77fb1a41 100644 --- a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/ReduceChunkSourceUpdates.java +++ b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/ReduceChunkSourceUpdates.java @@ -15,7 +15,7 @@ public class ReduceChunkSourceUpdates extends ConfigModules { public void onLoaded() { enabled = config.getBoolean(getBasePath() + ".enabled", enabled, config.pickStringRegionBased( - "Reduces chunk source updates on inter-chunk player moves. (Recommended to enable)", + "Reduces chunk source updates on inter-chunk player moves.", "减少玩家跨区块移动时的区块源更新。" ) ); diff --git a/leaf-server/src/main/java/org/dreeam/leaf/util/map/BlockPosIterator.java b/leaf-server/src/main/java/org/dreeam/leaf/util/map/BlockPosIterator.java index 7e4b0baf..2165d64e 100644 --- a/leaf-server/src/main/java/org/dreeam/leaf/util/map/BlockPosIterator.java +++ b/leaf-server/src/main/java/org/dreeam/leaf/util/map/BlockPosIterator.java @@ -46,25 +46,25 @@ public final class BlockPosIterator extends AbstractIterator { MutableBlockPos pos = this.pos; if (pos == null) { return this.pos = new MutableBlockPos(this.startX, this.startY, this.startZ); - } else { - int x = pos.getX(); - int y = pos.getY(); - int z = pos.getZ(); - - if (y < this.endY) { - y += 1; - } else if (x < this.endX) { - x += 1; - y = this.startY; - } else if (z < this.endZ) { - z += 1; - x = this.startX; - } else { - return this.endOfData(); - } - - pos.set(x, y, z); - return pos; } + int x = pos.getX(); + int y = pos.getY(); + int z = pos.getZ(); + + if (y < this.endY) { + y += 1; + } else if (x < this.endX) { + x += 1; + y = this.startY; + } else if (z < this.endZ) { + z += 1; + x = this.startX; + y = this.startY; // Reset y also! + } else { + return this.endOfData(); + } + + pos.set(x, y, z); + return pos; } } diff --git a/leaf-server/src/main/java/org/dreeam/leaf/world/block/OptimizedPoweredRails.java b/leaf-server/src/main/java/org/dreeam/leaf/world/block/OptimizedPoweredRails.java index f888ff94..9580adc4 100644 --- a/leaf-server/src/main/java/org/dreeam/leaf/world/block/OptimizedPoweredRails.java +++ b/leaf-server/src/main/java/org/dreeam/leaf/world/block/OptimizedPoweredRails.java @@ -1,5 +1,6 @@ package org.dreeam.leaf.world.block; +import it.unimi.dsi.fastutil.objects.Object2BooleanOpenHashMap; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.level.Level; @@ -8,8 +9,6 @@ import net.minecraft.world.level.block.PoweredRailBlock; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.RailShape; -import java.util.HashMap; - import static net.minecraft.world.level.block.Block.*; import static net.minecraft.world.level.block.PoweredRailBlock.POWERED; import static net.minecraft.world.level.block.PoweredRailBlock.SHAPE; @@ -23,6 +22,8 @@ public class OptimizedPoweredRails { private static int RAIL_POWER_LIMIT = 8; + private static final Object2BooleanOpenHashMap CHECKED_POS_POOL = new Object2BooleanOpenHashMap<>(); + private static void giveShapeUpdate(Level level, BlockState state, BlockPos pos, BlockPos fromPos, Direction direction) { BlockState oldState = level.getBlockState(pos); Block.updateOrDestroy( @@ -45,8 +46,8 @@ public class OptimizedPoweredRails { public static void updateState(PoweredRailBlock self, BlockState state, Level level, BlockPos pos) { boolean shouldBePowered = level.hasNeighborSignal(pos) || - self.findPoweredRailSignal(level, pos, state, true, 0) || - self.findPoweredRailSignal(level, pos, state, false, 0); + findPoweredRailSignalFaster(self, level, pos, state, true, 0, CHECKED_POS_POOL) || + findPoweredRailSignalFaster(self, level, pos, state, false, 0, CHECKED_POS_POOL); if (shouldBePowered != state.getValue(POWERED)) { RailShape railShape = state.getValue(SHAPE); if (railShape.isSlope()) { @@ -63,9 +64,9 @@ public class OptimizedPoweredRails { private static boolean findPoweredRailSignalFaster(PoweredRailBlock self, Level world, BlockPos pos, boolean bl, int distance, RailShape shape, - HashMap checkedPos) { + Object2BooleanOpenHashMap checkedPos) { BlockState blockState = world.getBlockState(pos); - boolean speedCheck = checkedPos.containsKey(pos) && checkedPos.get(pos); + boolean speedCheck = checkedPos.containsKey(pos) && checkedPos.getBoolean(pos); if (speedCheck) { return world.hasNeighborSignal(pos) || findPoweredRailSignalFaster(self, world, pos, blockState, bl, distance + 1, checkedPos); @@ -95,7 +96,7 @@ public class OptimizedPoweredRails { private static boolean findPoweredRailSignalFaster(PoweredRailBlock self, Level level, BlockPos pos, BlockState state, boolean bl, int distance, - HashMap checkedPos) { + Object2BooleanOpenHashMap checkedPos) { if (distance >= RAIL_POWER_LIMIT - 1) return false; int i = pos.getX(); int j = pos.getY(); @@ -165,7 +166,8 @@ public class OptimizedPoweredRails { private static void powerLane(PoweredRailBlock self, Level world, BlockPos pos, BlockState mainState, RailShape railShape) { world.setBlock(pos, mainState.setValue(POWERED, true), UPDATE_FORCE_PLACE); - HashMap checkedPos = new HashMap<>(); + Object2BooleanOpenHashMap checkedPos = CHECKED_POS_POOL; + checkedPos.clear(); checkedPos.put(pos, true); int[] count = new int[2]; if (railShape == RailShape.NORTH_SOUTH) { // Order: +z, -z @@ -179,6 +181,7 @@ public class OptimizedPoweredRails { } updateRails(self, true, world, pos, mainState, count); } + checkedPos.clear(); } private static void dePowerLane(PoweredRailBlock self, Level world, BlockPos pos, @@ -199,39 +202,46 @@ public class OptimizedPoweredRails { } private static void setRailPositionsPower(PoweredRailBlock self, Level world, BlockPos pos, - HashMap checkedPos, int[] count, int i, Direction dir) { + Object2BooleanOpenHashMap checkedPos, int[] count, int i, Direction dir) { for (int z = 1; z < RAIL_POWER_LIMIT; z++) { BlockPos newPos = pos.relative(dir, z); BlockState state = world.getBlockState(newPos); if (checkedPos.containsKey(newPos)) { - if (!checkedPos.get(newPos)) break; + if (!checkedPos.getBoolean(newPos)) + break; count[i]++; - } else if (!state.is(self) || state.getValue(POWERED) || !( - world.hasNeighborSignal(newPos) || + } else if (!state.is(self) || state.getValue(POWERED) || !(world.hasNeighborSignal(newPos) || findPoweredRailSignalFaster(self, world, newPos, state, true, 0, checkedPos) || - findPoweredRailSignalFaster(self, world, newPos, state, false, 0, checkedPos) - )) { + findPoweredRailSignalFaster(self, world, newPos, state, false, 0, checkedPos))) { checkedPos.put(newPos, false); break; } else { checkedPos.put(newPos, true); - world.setBlock(newPos, state.setValue(POWERED, true), UPDATE_FORCE_PLACE); + if (!state.getValue(POWERED)) { + world.setBlock(newPos, state.setValue(POWERED, true), UPDATE_FORCE_PLACE); + } count[i]++; } } } private static void setRailPositionsDePower(PoweredRailBlock self, Level world, BlockPos pos, - int[] count, int i, Direction dir) { + int[] count, int i, Direction dir) { + Object2BooleanOpenHashMap checkedPos = CHECKED_POS_POOL; + checkedPos.clear(); for (int z = 1; z < RAIL_POWER_LIMIT; z++) { BlockPos newPos = pos.relative(dir, z); BlockState state = world.getBlockState(newPos); if (!state.is(self) || !state.getValue(POWERED) || world.hasNeighborSignal(newPos) || - self.findPoweredRailSignal(world, newPos, state, true, 0) || - self.findPoweredRailSignal(world, newPos, state, false, 0)) break; - world.setBlock(newPos, state.setValue(POWERED, false), UPDATE_FORCE_PLACE); + findPoweredRailSignalFaster(self, world, newPos, state, true, 0, checkedPos) || + findPoweredRailSignalFaster(self, world, newPos, state, false, 0, checkedPos)) + break; + if (state.getValue(POWERED)) { + world.setBlock(newPos, state.setValue(POWERED, false), UPDATE_FORCE_PLACE); + } count[i]++; } + checkedPos.clear(); } private static void shapeUpdateEnd(PoweredRailBlock self, Level world, BlockPos pos, BlockState mainState, diff --git a/licenses/Apache-2.0.txt b/licenses/Apache-2.0.txt new file mode 100644 index 00000000..62589edd --- /dev/null +++ b/licenses/Apache-2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/public/readme/README_CN.md b/public/readme/README_CN.md index 94fee8df..74cba815 100644 --- a/public/readme/README_CN.md +++ b/public/readme/README_CN.md @@ -17,7 +17,7 @@ ## 🍃 特点 - **基于 [Gale](https://github.com/Dreeam-qwq/Gale)**,以获得更好的性能 - **异步**寻路、生物生成和实体追踪 -- **大量优化**融合自 [其他核心](https://github.com/Winds-Studio/Leaf#-致谢) 的补丁, 和我们自己的 +- **大量优化**融合自 [其他核心](#-致谢) 和我们自己的的补丁 - **完全兼容** Spigot 和 Paper 插件 - **最新依赖**,保持所有依赖项为最新版本 - **允许用户名使用所有字符**,包括中文和其他字符 @@ -87,11 +87,9 @@ java { ``` ## ⚖️ 许可证 -Paperweight 文件基于 [MIT](licenses/MIT.txt) 许可证。 -补丁基于 [MIT](licenses/MIT.txt) 许可证,除非在补丁顶部注释中另有说明。 -二进制文件基于 [GPL-3.0](licenses/GPL-3.0.txt) 许可证。 +Leaf 根据其上游项目及其他材料,采用多种开源许可证授权, -另请参阅 [PaperMC/Paper](https://github.com/PaperMC/Paper) 和 [PaperMC/paperweight](https://github.com/PaperMC/paperweight) 了解本项目使用的一些材料的许可证。 +请参阅 [LICENSE.md](../../LICENSE.md) 获取完整的许可信息。 ## 📜 致谢 感谢以下项目。Leaf 包含了一些取自这些项目的补丁。