diff --git a/patches/server/0008-Pufferfish-Dynamic-Activation-of-Brain.patch b/patches/server/0008-Pufferfish-Dynamic-Activation-of-Brain.patch index 218fcb57f..b9006e0bf 100644 --- a/patches/server/0008-Pufferfish-Dynamic-Activation-of-Brain.patch +++ b/patches/server/0008-Pufferfish-Dynamic-Activation-of-Brain.patch @@ -371,7 +371,7 @@ index 0000000000000000000000000000000000000000..a2e60c43074df560eb01f150bf52b8d0 + } +} diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index 0b2f2fbe462ed628ef3d640824d4162e79279089..e469b2782932275caa4bb760eefff82916c47d3a 100644 +index 5242f861834737876f639195dc259666705411e4..e6ef67125f59195104b013de8f69669a8e059a1f 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -38,7 +38,6 @@ import co.aikar.timings.MinecraftTimings; @@ -382,7 +382,7 @@ index 0b2f2fbe462ed628ef3d640824d4162e79279089..e469b2782932275caa4bb760eefff829 import org.galemc.gale.configuration.GaleWorldConfiguration; public class ActivationRange -@@ -238,6 +237,26 @@ public class ActivationRange +@@ -238,6 +237,23 @@ public class ActivationRange } // Paper end - Configurable marker ticking ActivationRange.activateEntity(entity); @@ -394,10 +394,7 @@ index 0b2f2fbe462ed628ef3d640824d4162e79279089..e469b2782932275caa4bb760eefff829 + entity.activatedPriorityReset = true; + entity.activatedPriority = org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.maximumActivationPrio; + } -+ net.minecraft.world.phys.Vec3 playerVec = player.position(); -+ net.minecraft.world.phys.Vec3 entityVec = entity.position(); -+ double diffX = playerVec.x - entityVec.x, diffY = playerVec.y - entityVec.y, diffZ = playerVec.z - entityVec.z; -+ int squaredDistance = (int) (diffX * diffX + diffY * diffY + diffZ * diffZ); ++ int squaredDistance = (int) player.distanceToSqr(entity); + entity.activatedPriority = squaredDistance > org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.startDistanceSquared ? + Math.max(1, Math.min(squaredDistance >> org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.activationDistanceMod, entity.activatedPriority)) : + 1; @@ -409,7 +406,7 @@ index 0b2f2fbe462ed628ef3d640824d4162e79279089..e469b2782932275caa4bb760eefff829 } // Paper end } -@@ -254,12 +273,12 @@ public class ActivationRange +@@ -254,12 +270,12 @@ public class ActivationRange if ( MinecraftServer.currentTick > entity.activatedTick ) { if ( entity.defaultActivationState ) diff --git a/patches/server/0011-Purpur-Server-Changes.patch b/patches/server/0011-Purpur-Server-Changes.patch index e32934e86..d0426423c 100644 --- a/patches/server/0011-Purpur-Server-Changes.patch +++ b/patches/server/0011-Purpur-Server-Changes.patch @@ -24824,7 +24824,7 @@ index 0000000000000000000000000000000000000000..129acb8ad139decc6b1c023cb10bc32d + // Paper end - lifecycle events +} diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index 17fe0c5661671a5d7ba7627c41f8e3f6662878b7..5e00b8bfd99680b6a6d48d85e272f62bb61811eb 100644 +index e6ef67125f59195104b013de8f69669a8e059a1f..275ccdf6cd322430ae29b606fdf6af510a62c480 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -215,6 +215,8 @@ public class ActivationRange @@ -24836,7 +24836,7 @@ index 17fe0c5661671a5d7ba7627c41f8e3f6662878b7..5e00b8bfd99680b6a6d48d85e272f62b // Paper start int worldHeight = world.getHeight(); ActivationRange.maxBB = player.getBoundingBox().inflate( maxRange, worldHeight, maxRange ); -@@ -413,6 +415,7 @@ public class ActivationRange +@@ -410,6 +412,7 @@ public class ActivationRange */ public static boolean checkIfActive(Entity entity) { diff --git a/patches/server/0015-Remove-Timings.patch b/patches/server/0015-Remove-Timings.patch index edaf59304..96040fef3 100644 --- a/patches/server/0015-Remove-Timings.patch +++ b/patches/server/0015-Remove-Timings.patch @@ -1838,7 +1838,7 @@ index 579c2e69d8f6ce8398eb1297d1d1ead98c9068a5..00000000000000000000000000000000 - -} diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index 5e00b8bfd99680b6a6d48d85e272f62bb61811eb..ebcecc78c475ba9436b894be971c3771ffc80caf 100644 +index 275ccdf6cd322430ae29b606fdf6af510a62c480..4894b7b006e20a383e509b69b6642593478d78c1 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -34,7 +34,6 @@ import net.minecraft.world.entity.projectile.FireworkRocketEntity; @@ -1857,7 +1857,7 @@ index 5e00b8bfd99680b6a6d48d85e272f62bb61811eb..ebcecc78c475ba9436b894be971c3771 final int miscActivationRange = world.spigotConfig.miscActivationRange; final int raiderActivationRange = world.spigotConfig.raiderActivationRange; final int animalActivationRange = world.spigotConfig.animalActivationRange; -@@ -262,7 +260,6 @@ public class ActivationRange +@@ -259,7 +257,6 @@ public class ActivationRange } // Paper end } diff --git a/patches/server/0099-Remove-stream-in-PlayerSensor.patch b/patches/server/0099-Remove-stream-in-PlayerSensor.patch new file mode 100644 index 000000000..122e9dc34 --- /dev/null +++ b/patches/server/0099-Remove-stream-in-PlayerSensor.patch @@ -0,0 +1,62 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> +Date: Tue, 9 Nov 2077 00:00:00 +0800 +Subject: [PATCH] Remove stream in PlayerSensor + +Stream operations in PlayerSensor take too much time +while ticking Villager farms, so just replace it with for loop =-= +Before: 164ms +After: 18ms + +diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/PlayerSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/PlayerSensor.java +index 2e887e426dcd79e2dda401f127d0e01ca537e80e..6ef968a5224830959d6f36193810debe7f14e21e 100644 +--- a/src/main/java/net/minecraft/world/entity/ai/sensing/PlayerSensor.java ++++ b/src/main/java/net/minecraft/world/entity/ai/sensing/PlayerSensor.java +@@ -21,17 +21,39 @@ public class PlayerSensor extends Sensor { + + @Override + protected void doTick(ServerLevel world, LivingEntity entity) { +- List list = world.players() +- .stream() +- .filter(EntitySelector.NO_SPECTATORS) +- .filter(player -> entity.closerThan(player, 16.0)) +- .sorted(Comparator.comparingDouble(entity::distanceToSqr)) +- .collect(Collectors.toList()); ++ // Leaf start - Remove stream in PlayerSensor ++ List list = new java.util.ArrayList<>(); ++ for (Player player : world.players()) { ++ if (!EntitySelector.NO_SPECTATORS.test(player)) { ++ continue; ++ } ++ if (!entity.closerThan(player, 16.0)) { ++ continue; ++ } ++ list.add(player); ++ } ++ list.sort(Comparator.comparingDouble(entity::distanceToSqr)); ++ // Leaf end - Remove stream in PlayerSensor + Brain brain = entity.getBrain(); + brain.setMemory(MemoryModuleType.NEAREST_PLAYERS, list); +- List list2 = list.stream().filter(player -> isEntityTargetable(entity, player)).collect(Collectors.toList()); ++ // Leaf start - Remove stream in PlayerSensor ++ List list2 = new java.util.ArrayList<>(); ++ for (Player player : list) { ++ if (isEntityTargetable(entity, player)) { ++ list2.add(player); ++ } ++ } ++ // Leaf end - Remove stream in PlayerSensor + brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_PLAYER, list2.isEmpty() ? null : list2.get(0)); +- Optional optional = list2.stream().filter(player -> isEntityAttackable(entity, player)).findFirst(); ++ // Leaf start - Remove stream in PlayerSensor ++ Optional optional = Optional.empty(); ++ for (Player player : list2) { ++ if (isEntityAttackable(entity, player)) { ++ optional = Optional.of(player); ++ break; ++ } ++ } ++ // Leaf end - Remove stream in PlayerSensor + brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER, optional); + } + } diff --git a/patches/server/0100-Remove-stream-in-GolemSensor.patch b/patches/server/0100-Remove-stream-in-GolemSensor.patch new file mode 100644 index 000000000..e30945b68 --- /dev/null +++ b/patches/server/0100-Remove-stream-in-GolemSensor.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> +Date: Tue, 9 Nov 2077 00:00:00 +0800 +Subject: [PATCH] Remove stream in GolemSensor + +Stream operations in GolemSensor is really expensive and takes +up 80% time per method call. +Before: 192ms +After: 17ms + +diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/GolemSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/GolemSensor.java +index 94d730e2d8159184a95da4b23266bf2e330be707..f78a342270104ca1082ea535d1152541d7297d8c 100644 +--- a/src/main/java/net/minecraft/world/entity/ai/sensing/GolemSensor.java ++++ b/src/main/java/net/minecraft/world/entity/ai/sensing/GolemSensor.java +@@ -34,7 +34,15 @@ public class GolemSensor extends Sensor { + public static void checkForNearbyGolem(LivingEntity entity) { + Optional> optional = entity.getBrain().getMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES); + if (!optional.isEmpty()) { +- boolean bl = optional.get().stream().anyMatch(livingEntity -> livingEntity.getType().equals(EntityType.IRON_GOLEM)); ++ // Leaf start - Remove stream in GolemSensor ++ boolean bl = false; ++ for (LivingEntity livingEntity : optional.get()) { ++ if (livingEntity.getType().equals(EntityType.IRON_GOLEM)) { ++ bl = true; ++ break; ++ } ++ } ++ // Leaf end - Remove stream in GolemSensor + if (bl) { + golemDetected(entity); + } diff --git a/patches/server/0099-Replace-Entity-active-effects-map-with-optimized-col.patch b/patches/server/0101-Replace-Entity-active-effects-map-with-optimized-col.patch similarity index 100% rename from patches/server/0099-Replace-Entity-active-effects-map-with-optimized-col.patch rename to patches/server/0101-Replace-Entity-active-effects-map-with-optimized-col.patch diff --git a/patches/server/0101-Replace-criterion-map-with-optimized-collection.patch b/patches/server/0102-Replace-criterion-map-with-optimized-collection.patch similarity index 100% rename from patches/server/0101-Replace-criterion-map-with-optimized-collection.patch rename to patches/server/0102-Replace-criterion-map-with-optimized-collection.patch diff --git a/patches/server/0102-Reduce-worldgen-allocations.patch b/patches/server/0103-Reduce-worldgen-allocations.patch similarity index 100% rename from patches/server/0102-Reduce-worldgen-allocations.patch rename to patches/server/0103-Reduce-worldgen-allocations.patch diff --git a/patches/server/0100-Replace-brain-maps-with-optimized-collection.patch b/patches/server/0104-Replace-brain-maps-with-optimized-collection.patch similarity index 100% rename from patches/server/0100-Replace-brain-maps-with-optimized-collection.patch rename to patches/server/0104-Replace-brain-maps-with-optimized-collection.patch diff --git a/patches/server/0103-Fix-MC-183518.patch b/patches/server/0105-Fix-MC-183518.patch similarity index 100% rename from patches/server/0103-Fix-MC-183518.patch rename to patches/server/0105-Fix-MC-183518.patch diff --git a/patches/server/0104-Use-caffeine-cache-kickPermission-instead-of-using-g.patch b/patches/server/0106-Use-caffeine-cache-kickPermission-instead-of-using-g.patch similarity index 100% rename from patches/server/0104-Use-caffeine-cache-kickPermission-instead-of-using-g.patch rename to patches/server/0106-Use-caffeine-cache-kickPermission-instead-of-using-g.patch diff --git a/patches/server/0105-Do-not-place-player-if-the-server-is-full.patch b/patches/server/0107-Do-not-place-player-if-the-server-is-full.patch similarity index 100% rename from patches/server/0105-Do-not-place-player-if-the-server-is-full.patch rename to patches/server/0107-Do-not-place-player-if-the-server-is-full.patch diff --git a/patches/server/0106-Fix-MC-200418.patch b/patches/server/0108-Fix-MC-200418.patch similarity index 100% rename from patches/server/0106-Fix-MC-200418.patch rename to patches/server/0108-Fix-MC-200418.patch diff --git a/patches/server/0107-Fix-MC-119417.patch b/patches/server/0109-Fix-MC-119417.patch similarity index 100% rename from patches/server/0107-Fix-MC-119417.patch rename to patches/server/0109-Fix-MC-119417.patch diff --git a/patches/server/0108-Fix-MC-223153.patch b/patches/server/0110-Fix-MC-223153.patch similarity index 100% rename from patches/server/0108-Fix-MC-223153.patch rename to patches/server/0110-Fix-MC-223153.patch diff --git a/patches/server/0109-Optimize-LeavesProtocolManager-init-protocol.patch b/patches/server/0111-Optimize-LeavesProtocolManager-init-protocol.patch similarity index 100% rename from patches/server/0109-Optimize-LeavesProtocolManager-init-protocol.patch rename to patches/server/0111-Optimize-LeavesProtocolManager-init-protocol.patch diff --git a/patches/server/0110-Cache-CraftEntityType-minecraftToBukkit-convert.patch b/patches/server/0112-Cache-CraftEntityType-minecraftToBukkit-convert.patch similarity index 100% rename from patches/server/0110-Cache-CraftEntityType-minecraftToBukkit-convert.patch rename to patches/server/0112-Cache-CraftEntityType-minecraftToBukkit-convert.patch diff --git a/patches/server/0111-Configurable-player-knockback-zombie.patch b/patches/server/0113-Configurable-player-knockback-zombie.patch similarity index 100% rename from patches/server/0111-Configurable-player-knockback-zombie.patch rename to patches/server/0113-Configurable-player-knockback-zombie.patch diff --git a/patches/server/0112-Hide-specified-item-components-to-clients.patch b/patches/server/0114-Hide-specified-item-components-to-clients.patch similarity index 100% rename from patches/server/0112-Hide-specified-item-components-to-clients.patch rename to patches/server/0114-Hide-specified-item-components-to-clients.patch diff --git a/patches/server/0113-Paper-PR-Skip-AI-during-inactive-ticks-for-non-aware.patch b/patches/server/0115-Paper-PR-Skip-AI-during-inactive-ticks-for-non-aware.patch similarity index 100% rename from patches/server/0113-Paper-PR-Skip-AI-during-inactive-ticks-for-non-aware.patch rename to patches/server/0115-Paper-PR-Skip-AI-during-inactive-ticks-for-non-aware.patch diff --git a/patches/server/0114-Paper-PR-Reduce-work-done-in-CraftMapCanvas.drawImag.patch b/patches/server/0116-Paper-PR-Reduce-work-done-in-CraftMapCanvas.drawImag.patch similarity index 100% rename from patches/server/0114-Paper-PR-Reduce-work-done-in-CraftMapCanvas.drawImag.patch rename to patches/server/0116-Paper-PR-Reduce-work-done-in-CraftMapCanvas.drawImag.patch diff --git a/patches/server/0115-Paper-PR-Throttle-failed-spawn-attempts.patch b/patches/server/0117-Paper-PR-Throttle-failed-spawn-attempts.patch similarity index 100% rename from patches/server/0115-Paper-PR-Throttle-failed-spawn-attempts.patch rename to patches/server/0117-Paper-PR-Throttle-failed-spawn-attempts.patch diff --git a/patches/server/0116-Paper-PR-Prevent-zombie-reinforcements-loading-chunk.patch b/patches/server/0118-Paper-PR-Prevent-zombie-reinforcements-loading-chunk.patch similarity index 100% rename from patches/server/0116-Paper-PR-Prevent-zombie-reinforcements-loading-chunk.patch rename to patches/server/0118-Paper-PR-Prevent-zombie-reinforcements-loading-chunk.patch diff --git a/patches/server/0117-Dont-send-useless-entity-packets.patch b/patches/server/0119-Dont-send-useless-entity-packets.patch similarity index 100% rename from patches/server/0117-Dont-send-useless-entity-packets.patch rename to patches/server/0119-Dont-send-useless-entity-packets.patch diff --git a/patches/server/0118-Don-t-spawn-if-lastSpawnState-is-null.patch b/patches/server/0120-Don-t-spawn-if-lastSpawnState-is-null.patch similarity index 100% rename from patches/server/0118-Don-t-spawn-if-lastSpawnState-is-null.patch rename to patches/server/0120-Don-t-spawn-if-lastSpawnState-is-null.patch diff --git a/patches/server/0119-Multithreaded-Tracker.patch b/patches/server/0121-Multithreaded-Tracker.patch similarity index 100% rename from patches/server/0119-Multithreaded-Tracker.patch rename to patches/server/0121-Multithreaded-Tracker.patch diff --git a/patches/server/0120-Nitori-Async-playerdata-Save.patch b/patches/server/0122-Nitori-Async-playerdata-Save.patch similarity index 100% rename from patches/server/0120-Nitori-Async-playerdata-Save.patch rename to patches/server/0122-Nitori-Async-playerdata-Save.patch diff --git a/patches/server/0121-Change-max-stack-count.patch b/patches/server/0123-Change-max-stack-count.patch similarity index 100% rename from patches/server/0121-Change-max-stack-count.patch rename to patches/server/0123-Change-max-stack-count.patch diff --git a/patches/server/0122-Reduce-object-complexity-to-make-block-isValid-calls.patch b/patches/server/0124-Reduce-object-complexity-to-make-block-isValid-calls.patch similarity index 100% rename from patches/server/0122-Reduce-object-complexity-to-make-block-isValid-calls.patch rename to patches/server/0124-Reduce-object-complexity-to-make-block-isValid-calls.patch diff --git a/patches/server/0123-Optimize-nearby-alive-players-for-spawning.patch b/patches/server/0125-Optimize-nearby-alive-players-for-spawning.patch similarity index 100% rename from patches/server/0123-Optimize-nearby-alive-players-for-spawning.patch rename to patches/server/0125-Optimize-nearby-alive-players-for-spawning.patch diff --git a/patches/server/0124-Cache-blockstate-cache.patch b/patches/server/0126-Cache-blockstate-cache.patch similarity index 100% rename from patches/server/0124-Cache-blockstate-cache.patch rename to patches/server/0126-Cache-blockstate-cache.patch diff --git a/patches/server/0125-Fix-MC-177381.patch b/patches/server/0127-Fix-MC-177381.patch similarity index 100% rename from patches/server/0125-Fix-MC-177381.patch rename to patches/server/0127-Fix-MC-177381.patch diff --git a/patches/server/0126-Asynchronous-locator.patch b/patches/server/0128-Asynchronous-locator.patch similarity index 100% rename from patches/server/0126-Asynchronous-locator.patch rename to patches/server/0128-Asynchronous-locator.patch diff --git a/patches/server/0128-Use-QuickSort-in-NearestLivingEntitySensor.patch b/patches/server/0128-Use-QuickSort-in-NearestLivingEntitySensor.patch deleted file mode 100644 index 2d665cf53..000000000 --- a/patches/server/0128-Use-QuickSort-in-NearestLivingEntitySensor.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> -Date: Sat, 26 Oct 2024 15:00:21 +0800 -Subject: [PATCH] Use QuickSort in NearestLivingEntitySensor - - -diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java -index 5a059e1ec232d82e8e891ae78fea962bec2f878e..490c5322f8286f92f9ba4583f59ed60618ad33e5 100644 ---- a/src/main/java/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java -+++ b/src/main/java/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java -@@ -16,10 +16,16 @@ public class NearestLivingEntitySensor extends Sensor - protected void doTick(ServerLevel world, T entity) { - AABB aABB = entity.getBoundingBox().inflate((double)this.radiusXZ(), (double)this.radiusY(), (double)this.radiusXZ()); - List list = world.getEntitiesOfClass(LivingEntity.class, aABB, e -> e != entity && e.isAlive()); -- list.sort(Comparator.comparingDouble(entity::distanceToSqr)); -+ // Leaf start - Use QuickSort in NearestLivingEntitySensor -+ LivingEntity[] sortArray = list.toArray(new LivingEntity[]{}); -+ it.unimi.dsi.fastutil.objects.ObjectArrays.quickSort(sortArray, Comparator.comparingDouble(entity::distanceToSqr)); -+ List sortedList = java.util.Arrays.asList(sortArray); -+ // Leaf end - Use QuickSort in NearestLivingEntitySensor - Brain brain = entity.getBrain(); -- brain.setMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES, list); -- brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, new NearestVisibleLivingEntities(entity, list)); -+ // Leaf start - Use QuickSort in NearestLivingEntitySensor -+ brain.setMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES, sortedList); -+ brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, new NearestVisibleLivingEntities(entity, sortedList)); -+ // Leaf end - Use QuickSort in NearestLivingEntitySensor - } - - protected int radiusXZ() { diff --git a/patches/server/0127-Virtual-thread-for-chat-executor.patch b/patches/server/0129-Virtual-thread-for-chat-executor.patch similarity index 100% rename from patches/server/0127-Virtual-thread-for-chat-executor.patch rename to patches/server/0129-Virtual-thread-for-chat-executor.patch diff --git a/patches/server/0130-Smart-sort-entities-in-NearestLivingEntitySensor.patch b/patches/server/0130-Smart-sort-entities-in-NearestLivingEntitySensor.patch new file mode 100644 index 000000000..0a4afdc96 --- /dev/null +++ b/patches/server/0130-Smart-sort-entities-in-NearestLivingEntitySensor.patch @@ -0,0 +1,97 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> +Date: Tue, 9 Nov 2077 00:00:00 +0800 +Subject: [PATCH] Smart sort entities in NearestLivingEntitySensor + +This patch optimizes sorting algorithm by dynamically sorting based +on entity count, if entity count doesn't reach the Bucket Sort threshold, +Quick Sort of Fastutil will be used. +When entity count reached the threshold, Bucket Sort will be used. +This offers a 10~15% performance improvement in average. +In best situation, this can give an up to 50% improvement. + +diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java +index 5a059e1ec232d82e8e891ae78fea962bec2f878e..7cb18a2191a4b520ee81230106045d18faa384ee 100644 +--- a/src/main/java/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java ++++ b/src/main/java/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java +@@ -12,16 +12,77 @@ import net.minecraft.world.entity.ai.memory.NearestVisibleLivingEntities; + import net.minecraft.world.phys.AABB; + + public class NearestLivingEntitySensor extends Sensor { ++ // Leaf start - Smart sort entities in NearestLivingEntitySensor ++ private static final int NUM_BUCKETS = org.apache.commons.lang3.math.NumberUtils.toInt((System.getProperty("Leaf.nearestEntitySensorBucketCount", "10")), 10); ++ private static final int BUCKET_SORT_THRESHOLD = (int) Math.floor(NUM_BUCKETS * org.apache.commons.lang3.math.NumberUtils.toDouble(System.getProperty("Leaf.nearestEntitySensorBucketSortThresholdRatio", "2.0"), 2.0D)); ++ // Leaf end - Smart sort entities in NearestLivingEntitySensor + @Override + protected void doTick(ServerLevel world, T entity) { + AABB aABB = entity.getBoundingBox().inflate((double)this.radiusXZ(), (double)this.radiusY(), (double)this.radiusXZ()); + List list = world.getEntitiesOfClass(LivingEntity.class, aABB, e -> e != entity && e.isAlive()); +- list.sort(Comparator.comparingDouble(entity::distanceToSqr)); ++ // Leaf start - Smart sort entities in NearestLivingEntitySensor ++ LivingEntity[] sortedEntities = smartSortEntities(list.toArray(new LivingEntity[]{}), entity); ++ List sortedList = java.util.Arrays.asList(sortedEntities); ++ // Leaf end - Smart sort entities in NearestLivingEntitySensor + Brain brain = entity.getBrain(); +- brain.setMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES, list); +- brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, new NearestVisibleLivingEntities(entity, list)); ++ // Leaf start - Smart sort entities in NearestLivingEntitySensor ++ brain.setMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES, sortedList); ++ brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, new NearestVisibleLivingEntities(entity, sortedList)); ++ // Leaf end - Smart sort entities in NearestLivingEntitySensor + } + ++ // Leaf start - Smart sort entities in NearestLivingEntitySensor ++ private LivingEntity[] smartSortEntities(LivingEntity[] entities, T referenceEntity) { ++ if (entities.length <= 1) { ++ return entities; ++ } ++ final Comparator comparator = Comparator.comparingDouble(referenceEntity::distanceToSqr); ++ ++ if (entities.length < BUCKET_SORT_THRESHOLD) { ++ it.unimi.dsi.fastutil.objects.ObjectArrays.quickSort(entities, comparator); ++ return entities; ++ } ++ ++ // Create buckets ++ @SuppressWarnings("unchecked") ++ List[] buckets = new List[NUM_BUCKETS]; ++ for (int i = 0; i < NUM_BUCKETS; i++) { ++ buckets[i] = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(); ++ } ++ ++ // Find max distance to normalize bucket distribution - Leaf ++ double maxDistSq = 0.0; ++ for (LivingEntity e : entities) { ++ maxDistSq = Math.max(maxDistSq, referenceEntity.distanceToSqr(e)); ++ } ++ ++ // Handle edge case where all entities are at the same position - Leaf ++ if (maxDistSq == 0.0) { ++ return entities; ++ } ++ ++ // Distribute entities into buckets ++ for (LivingEntity e : entities) { ++ double distSq = referenceEntity.distanceToSqr(e); ++ int bucketIndex = (int) ((distSq / maxDistSq) * (NUM_BUCKETS - 1)); ++ buckets[bucketIndex].add(e); ++ } ++ ++ // Sort each bucket and combine results ++ int currentIndex = 0; ++ for (List bucket : buckets) { ++ if (!bucket.isEmpty()) { ++ bucket.sort(comparator); ++ for (LivingEntity e : bucket) { ++ entities[currentIndex++] = e; ++ } ++ } ++ } ++ ++ return entities; ++ } ++ // Leaf end - Smart sort entities in NearestLivingEntitySensor ++ + protected int radiusXZ() { + return 16; + } diff --git a/patches/server/0129-Further-reduce-memory-footprint-of-CompoundTag.patch b/patches/server/0131-Further-reduce-memory-footprint-of-CompoundTag.patch similarity index 100% rename from patches/server/0129-Further-reduce-memory-footprint-of-CompoundTag.patch rename to patches/server/0131-Further-reduce-memory-footprint-of-CompoundTag.patch diff --git a/patches/server/0130-Optimize-Entity-distanceToSqr.patch b/patches/server/0132-Optimize-Entity-distanceToSqr.patch similarity index 100% rename from patches/server/0130-Optimize-Entity-distanceToSqr.patch rename to patches/server/0132-Optimize-Entity-distanceToSqr.patch diff --git a/patches/server/0131-EMC-Don-t-use-snapshots-for-TileEntity-getOwner.patch b/patches/server/0133-EMC-Don-t-use-snapshots-for-TileEntity-getOwner.patch similarity index 100% rename from patches/server/0131-EMC-Don-t-use-snapshots-for-TileEntity-getOwner.patch rename to patches/server/0133-EMC-Don-t-use-snapshots-for-TileEntity-getOwner.patch diff --git a/patches/server/0132-EMC-Default-don-t-use-blockstate-snapshots.patch b/patches/server/0134-EMC-Default-don-t-use-blockstate-snapshots.patch similarity index 100% rename from patches/server/0132-EMC-Default-don-t-use-blockstate-snapshots.patch rename to patches/server/0134-EMC-Default-don-t-use-blockstate-snapshots.patch diff --git a/patches/server/0133-Cache-tile-entity-position.patch b/patches/server/0135-Cache-tile-entity-position.patch similarity index 100% rename from patches/server/0133-Cache-tile-entity-position.patch rename to patches/server/0135-Cache-tile-entity-position.patch diff --git a/patches/server/0134-TT20-Lag-compensation.patch b/patches/server/0136-TT20-Lag-compensation.patch similarity index 100% rename from patches/server/0134-TT20-Lag-compensation.patch rename to patches/server/0136-TT20-Lag-compensation.patch diff --git a/patches/server/0135-DivineMC-Lithium-entity.fast_elytra_check-entity.fas.patch b/patches/server/0137-DivineMC-Lithium-entity.fast_elytra_check-entity.fas.patch similarity index 93% rename from patches/server/0135-DivineMC-Lithium-entity.fast_elytra_check-entity.fas.patch rename to patches/server/0137-DivineMC-Lithium-entity.fast_elytra_check-entity.fas.patch index 3223a653b..10ca20e3b 100644 --- a/patches/server/0135-DivineMC-Lithium-entity.fast_elytra_check-entity.fas.patch +++ b/patches/server/0137-DivineMC-Lithium-entity.fast_elytra_check-entity.fas.patch @@ -11,7 +11,7 @@ Original license: LGPL v3 Original project: https://github.com/CaffeineMC/lithium-fabric diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 241e2598973939b7d19768cd9ca7cd8f3818c053..7ce6ce7212b942a8d6b64c98fab8fe060d813c61 100644 +index 241e2598973939b7d19768cd9ca7cd8f3818c053..ac3ef40aabf08081efd28dd30c0c856d1858c44f 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -2769,6 +2769,7 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/0135-Fix-wrong-entity-behavior-in-fluid-caused-by-inconsi.patch b/patches/server/0138-Fix-wrong-entity-behavior-in-fluid-caused-by-inconsi.patch similarity index 100% rename from patches/server/0135-Fix-wrong-entity-behavior-in-fluid-caused-by-inconsi.patch rename to patches/server/0138-Fix-wrong-entity-behavior-in-fluid-caused-by-inconsi.patch diff --git a/patches/server/0136-C2ME-Reduce-Allocations.patch b/patches/server/0139-C2ME-Reduce-Allocations.patch similarity index 100% rename from patches/server/0136-C2ME-Reduce-Allocations.patch rename to patches/server/0139-C2ME-Reduce-Allocations.patch diff --git a/patches/server/0137-Lithium-fast-util.patch b/patches/server/0140-Lithium-fast-util.patch similarity index 100% rename from patches/server/0137-Lithium-fast-util.patch rename to patches/server/0140-Lithium-fast-util.patch diff --git a/patches/server/0138-Lithium-CompactSineLUT.patch b/patches/server/0141-Lithium-CompactSineLUT.patch similarity index 100% rename from patches/server/0138-Lithium-CompactSineLUT.patch rename to patches/server/0141-Lithium-CompactSineLUT.patch diff --git a/patches/server/0139-Lithium-IterateOutwardsCache.patch b/patches/server/0142-Lithium-IterateOutwardsCache.patch similarity index 100% rename from patches/server/0139-Lithium-IterateOutwardsCache.patch rename to patches/server/0142-Lithium-IterateOutwardsCache.patch diff --git a/patches/server/0140-Lithium-HashedList.patch b/patches/server/0143-Lithium-HashedList.patch similarity index 100% rename from patches/server/0140-Lithium-HashedList.patch rename to patches/server/0143-Lithium-HashedList.patch diff --git a/patches/server/0141-Use-MCUtil.asyncExecutor-for-MAIN_WORKER_EXECUTOR.patch b/patches/server/0144-Use-MCUtil.asyncExecutor-for-MAIN_WORKER_EXECUTOR.patch similarity index 100% rename from patches/server/0141-Use-MCUtil.asyncExecutor-for-MAIN_WORKER_EXECUTOR.patch rename to patches/server/0144-Use-MCUtil.asyncExecutor-for-MAIN_WORKER_EXECUTOR.patch diff --git a/patches/server/0142-Fix-tick-function-tag-running-before-load.patch b/patches/server/0145-Fix-tick-function-tag-running-before-load.patch similarity index 100% rename from patches/server/0142-Fix-tick-function-tag-running-before-load.patch rename to patches/server/0145-Fix-tick-function-tag-running-before-load.patch diff --git a/patches/server/0143-Better-inline-world-height.patch b/patches/server/0146-Better-inline-world-height.patch similarity index 100% rename from patches/server/0143-Better-inline-world-height.patch rename to patches/server/0146-Better-inline-world-height.patch diff --git a/patches/server/0144-branchless-clamp-logic.patch b/patches/server/0147-branchless-clamp-logic.patch similarity index 100% rename from patches/server/0144-branchless-clamp-logic.patch rename to patches/server/0147-branchless-clamp-logic.patch diff --git a/patches/server/0148-SparklyPaper-Throttle-hopper-when-full.patch b/patches/server/0148-SparklyPaper-Throttle-hopper-when-full.patch new file mode 100644 index 000000000..493ca424f --- /dev/null +++ b/patches/server/0148-SparklyPaper-Throttle-hopper-when-full.patch @@ -0,0 +1,51 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> +Date: Tue, 9 Nov 2077 00:00:00 +0800 +Subject: [PATCH] SparklyPaper Throttle hopper when full + +Original project: https://github.com/SparklyPower/SparklyPaper + +diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java +index 99fc84e10a10f3d4eededd6ce7be7700e3c3a8e4..58c7c1db907d6c7a7ff99308260dadf487d79864 100644 +--- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java ++++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java +@@ -443,6 +443,11 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen + Direction enumdirection = blockEntity.facing.getOpposite(); + + if (HopperBlockEntity.isFullContainer(iinventory, enumdirection)) { ++ // Leaf start - Throttle hopper when full ++ if (org.dreeam.leaf.config.modules.opt.ThrottleHopperWhenFull.enabled && org.dreeam.leaf.config.modules.opt.ThrottleHopperWhenFull.skipTicks > 0) { ++ blockEntity.setCooldown(org.dreeam.leaf.config.modules.opt.ThrottleHopperWhenFull.skipTicks); ++ } ++ // Leaf end - Throttle hopper when full + return false; + } else { + // Paper start - Perf: Optimize Hoppers +diff --git a/src/main/java/org/dreeam/leaf/config/modules/opt/ThrottleHopperWhenFull.java b/src/main/java/org/dreeam/leaf/config/modules/opt/ThrottleHopperWhenFull.java +new file mode 100644 +index 0000000000000000000000000000000000000000..97257fb1db8e54a35b9badb8cf0a2be2e0646e51 +--- /dev/null ++++ b/src/main/java/org/dreeam/leaf/config/modules/opt/ThrottleHopperWhenFull.java +@@ -0,0 +1,22 @@ ++package org.dreeam.leaf.config.modules.opt; ++ ++import org.dreeam.leaf.config.ConfigModules; ++import org.dreeam.leaf.config.EnumConfigCategory; ++ ++public class ThrottleHopperWhenFull extends ConfigModules { ++ ++ public String getBasePath() { ++ return EnumConfigCategory.PERF.getBaseKeyName() + ".throttle-hopper-when-full"; ++ } ++ ++ public static boolean enabled = false; ++ public static int skipTicks = 0; ++ ++ @Override ++ public void onLoaded() { ++ enabled = config.getBoolean(getBasePath() + ".enabled", enabled, """ ++ Throttles the hopper if target container is full."""); ++ skipTicks = config.getInt(getBasePath() + ".skip-ticks", skipTicks, """ ++ How many ticks to throttle when the Hopper is throttled."""); ++ } ++}