diff --git a/leaf-server/minecraft-patches/features/0204-Cache-eligible-players-for-despawn-checks.patch b/leaf-server/minecraft-patches/features/0204-Cache-eligible-players-for-despawn-checks.patch deleted file mode 100644 index 23fa451b..00000000 --- a/leaf-server/minecraft-patches/features/0204-Cache-eligible-players-for-despawn-checks.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Taiyou06 -Date: Fri, 14 Feb 2025 20:08:14 +0100 -Subject: [PATCH] Cache eligible players for despawn checks - - -diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 0f311e603c8df175576a33d5d20369cbcda2be55..3a31f9132a7271ea476cc85c5a10ea7f327256bf 100644 ---- a/net/minecraft/server/level/ServerLevel.java -+++ b/net/minecraft/server/level/ServerLevel.java -@@ -729,6 +729,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - return this.structureManager; - } - -+ public Player[] eligibleDespawnCheckingPlayerCache = new Player[0]; // Leaf - Cache eligible players for despawn checks -+ - public void tick(BooleanSupplier hasTimeLeft) { - this.handlingTick = true; - TickRateManager tickRateManager = this.tickRateManager(); -@@ -796,6 +798,19 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - } - - io.papermc.paper.entity.activation.ActivationRange.activateEntities(this); // Paper - EAR -+ -+ // Leaf start - Cache eligible players for despawn checks -+ List serverPlayers = new ArrayList<>(players().size()); -+ for (int i = 0; i < players().size(); i++) { -+ ServerPlayer player = players().get(i); -+ if (net.minecraft.world.entity.EntitySelector.PLAYER_AFFECTS_SPAWNING.test(player)) { -+ serverPlayers.add(player); -+ } -+ } -+ -+ eligibleDespawnCheckingPlayerCache = serverPlayers.toArray(new Player[0]); -+ // Leaf end - Cache eligible players for despawn checks -+ - this.entityTickList - .forEach( - entity -> { -diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index 42032812e3c50f3ade62a0e69cb1168d83c42a71..b77c545788ade614d7ae0b29ccfcd4d50c4ddf55 100644 ---- a/net/minecraft/server/level/ServerPlayer.java -+++ b/net/minecraft/server/level/ServerPlayer.java -@@ -1546,6 +1546,13 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc - this.containerMenu.broadcastChanges(); - } - -+ // Leaf start - Cache eligible players for despawn checks -+ @Override -+ public boolean isAlive() { -+ return !this.isRemoved() && this.entityData.get(DATA_HEALTH_ID) > 0.0f && !this.dead; -+ } -+ // Leaf end - Cache eligible players for despawn checks -+ - // CraftBukkit start - moved bed result checks from below into separate method - private Either getBedResult(BlockPos at, Direction direction) { - if (this.isSleeping() || !this.isAlive()) { -diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java -index 867353500482247bbec79f407246902c79a3d14a..4a1a336914eff8a178dcd992bd1bfea25a8be76b 100644 ---- a/net/minecraft/world/entity/Mob.java -+++ b/net/minecraft/world/entity/Mob.java -@@ -722,7 +722,24 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab - if (this.level().getDifficulty() == Difficulty.PEACEFUL && this.shouldDespawnInPeaceful()) { - this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause - } else if (!this.isPersistenceRequired() && !this.requiresCustomPersistence()) { -- Entity nearestPlayer = this.level().findNearbyPlayer(this, -1.0, EntitySelector.PLAYER_AFFECTS_SPAWNING); // Paper - Affects Spawning API -+ // Leaf start - Cache eligible players for despawn checks -+ Entity nearestPlayer = null; -+ -+ if (this.level() instanceof ServerLevel serverLevel) { -+ double minDist = Double.MAX_VALUE; -+ for (int i = 0; i < serverLevel.eligibleDespawnCheckingPlayerCache.length; i++) { -+ Player cachedPlayer = serverLevel.eligibleDespawnCheckingPlayerCache[i]; -+ double d1 = cachedPlayer.distanceToSqr(this); -+ if (d1 <= minDist) { -+ minDist = d1; -+ nearestPlayer = cachedPlayer; -+ } -+ } -+ } else { -+ nearestPlayer = this.level().findNearbyPlayer(this, -1.0, EntitySelector.PLAYER_AFFECTS_SPAWNING); // Paper - Affects Spawning API -+ } -+ // Leaf end - Cache eligible players for despawn checks -+ - if (nearestPlayer != null) { - // Paper start - Configurable despawn distances - final io.papermc.paper.configuration.WorldConfiguration.Entities.Spawning.DespawnRangePair despawnRangePair = this.level().paperConfig().entities.spawning.despawnRanges.get(this.getType().getCategory()); diff --git a/leaf-server/minecraft-patches/features/0204-optimize-mob-despawn.patch b/leaf-server/minecraft-patches/features/0204-optimize-mob-despawn.patch new file mode 100644 index 00000000..d4e68d44 --- /dev/null +++ b/leaf-server/minecraft-patches/features/0204-optimize-mob-despawn.patch @@ -0,0 +1,52 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: hayanesuru +Date: Fri, 4 Jul 2025 03:22:38 +0900 +Subject: [PATCH] optimize mob despawn + + +diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java +index 0f311e603c8df175576a33d5d20369cbcda2be55..498b1ab5013030c4b9fe0eca57215d93965c43b6 100644 +--- a/net/minecraft/server/level/ServerLevel.java ++++ b/net/minecraft/server/level/ServerLevel.java +@@ -796,6 +796,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + } + + io.papermc.paper.entity.activation.ActivationRange.activateEntities(this); // Paper - EAR ++ ++ if (org.dreeam.leaf.config.modules.opt.OptimizeDespawn.enabled) despawnMap.prepare(this); // Leaf - optimize despawn + this.entityTickList + .forEach( + entity -> { +@@ -831,6 +833,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + } + } + ); ++ if (org.dreeam.leaf.config.modules.opt.OptimizeDespawn.enabled) despawnMap.reset(); // Leaf - optimize despawn + this.tickBlockEntities(); + } + // Paper - rewrite chunk system +@@ -943,6 +946,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + + private int currentIceAndSnowTick = 0; protected void resetIceAndSnowTick() { this.currentIceAndSnowTick = this.simpleRandom.nextInt(16); } // Gale - Airplane - optimize random calls in chunk ticking + ++ public final org.dreeam.leaf.world.DespawnMap despawnMap = new org.dreeam.leaf.world.DespawnMap(); // Leaf - optimize despawn + public void tickChunk(LevelChunk chunk, int randomTickSpeed) { + final net.minecraft.world.level.levelgen.BitRandomSource simpleRandom = this.simpleRandom; // Paper - optimise random ticking // Leaf - Faster random generator - upcasting + ChunkPos pos = chunk.getPos(); +diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java +index 867353500482247bbec79f407246902c79a3d14a..173ec6919cef2aa90c40d3bf33d927a2db7b4922 100644 +--- a/net/minecraft/world/entity/Mob.java ++++ b/net/minecraft/world/entity/Mob.java +@@ -722,6 +722,12 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab + if (this.level().getDifficulty() == Difficulty.PEACEFUL && this.shouldDespawnInPeaceful()) { + this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + } else if (!this.isPersistenceRequired() && !this.requiresCustomPersistence()) { ++ // Leaf start - optimize despawn ++ if (org.dreeam.leaf.config.modules.opt.OptimizeDespawn.enabled) { ++ ((ServerLevel) level()).despawnMap.checkDespawn(this); ++ return; ++ } ++ // Leaf end - optimize despawn + Entity nearestPlayer = this.level().findNearbyPlayer(this, -1.0, EntitySelector.PLAYER_AFFECTS_SPAWNING); // Paper - Affects Spawning API + if (nearestPlayer != null) { + // Paper start - Configurable despawn distances diff --git a/leaf-server/minecraft-patches/features/0214-SparklyPaper-Parallel-world-ticking.patch b/leaf-server/minecraft-patches/features/0214-SparklyPaper-Parallel-world-ticking.patch index fd158551..3a7d0265 100644 --- a/leaf-server/minecraft-patches/features/0214-SparklyPaper-Parallel-world-ticking.patch +++ b/leaf-server/minecraft-patches/features/0214-SparklyPaper-Parallel-world-ticking.patch @@ -411,7 +411,7 @@ index 8f41326fda8c5f9f6926038508be6c6529b051bc..46e171ca454253c32e22c0c18587e9a7 } } diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 3a31f9132a7271ea476cc85c5a10ea7f327256bf..58ec5cfb21d4834c3aaa74f76ca8a536eb86c30c 100644 +index 498b1ab5013030c4b9fe0eca57215d93965c43b6..397ac1603c742b82e74cfb5d3e579935d74933a2 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java @@ -180,7 +180,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -469,9 +469,9 @@ index 3a31f9132a7271ea476cc85c5a10ea7f327256bf..58ec5cfb21d4834c3aaa74f76ca8a536 // Paper start @Override public boolean hasChunk(int chunkX, int chunkZ) { -@@ -731,8 +752,112 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - - public Player[] eligibleDespawnCheckingPlayerCache = new Player[0]; // Leaf - Cache eligible players for despawn checks +@@ -729,8 +750,112 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + return this.structureManager; + } + // Leaf start - SparklyPaper - parallel world ticking + private void processAsyncReadRequests() { @@ -582,7 +582,7 @@ index 3a31f9132a7271ea476cc85c5a10ea7f327256bf..58ec5cfb21d4834c3aaa74f76ca8a536 TickRateManager tickRateManager = this.tickRateManager(); boolean runsNormally = tickRateManager.runsNormally(); if (runsNormally) { -@@ -740,6 +865,14 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -738,6 +863,14 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.advanceWeatherCycle(); } @@ -597,7 +597,7 @@ index 3a31f9132a7271ea476cc85c5a10ea7f327256bf..58ec5cfb21d4834c3aaa74f76ca8a536 int _int = this.getGameRules().getInt(GameRules.RULE_PLAYERS_SLEEPING_PERCENTAGE); if (this.purpurConfig.playersSkipNight && this.sleepStatus.areEnoughSleeping(_int) && this.sleepStatus.areEnoughDeepSleeping(_int, this.players)) { // Purpur - Config for skipping night // Paper start - create time skip event - move up calculations -@@ -1317,9 +1450,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1306,9 +1439,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe fluidState.tick(this, pos, blockState); } // Paper start - rewrite chunk system @@ -612,7 +612,7 @@ index 3a31f9132a7271ea476cc85c5a10ea7f327256bf..58ec5cfb21d4834c3aaa74f76ca8a536 // Paper end - rewrite chunk system } -@@ -1330,9 +1466,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1319,9 +1455,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe blockState.tick(this, pos, this.random); } // Paper start - rewrite chunk system @@ -627,7 +627,7 @@ index 3a31f9132a7271ea476cc85c5a10ea7f327256bf..58ec5cfb21d4834c3aaa74f76ca8a536 // Paper end - rewrite chunk system } -@@ -1597,6 +1736,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1586,6 +1725,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } private void addPlayer(ServerPlayer player) { @@ -636,7 +636,7 @@ index 3a31f9132a7271ea476cc85c5a10ea7f327256bf..58ec5cfb21d4834c3aaa74f76ca8a536 Entity entity = this.getEntity(player.getUUID()); if (entity != null) { LOGGER.warn("Force-added player with duplicate UUID {}", player.getUUID()); -@@ -1609,7 +1750,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1598,7 +1739,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // CraftBukkit start private boolean addEntity(Entity entity, @Nullable org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) { @@ -651,7 +651,7 @@ index 3a31f9132a7271ea476cc85c5a10ea7f327256bf..58ec5cfb21d4834c3aaa74f76ca8a536 // Paper start - extra debug info if (entity.valid) { diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index b77c545788ade614d7ae0b29ccfcd4d50c4ddf55..9906244ab2e447de25546f25ec5f6ef6c4b221ab 100644 +index 42032812e3c50f3ade62a0e69cb1168d83c42a71..4140d5beb01b530e97ae308eedc639de70df696f 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java @@ -465,6 +465,8 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc @@ -680,7 +680,7 @@ index b77c545788ade614d7ae0b29ccfcd4d50c4ddf55..9906244ab2e447de25546f25ec5f6ef6 // CraftBukkit start /* this.isChangingDimension = true; -@@ -1780,6 +1785,12 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -1773,6 +1778,12 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc return OptionalInt.empty(); } else { // CraftBukkit start @@ -693,7 +693,7 @@ index b77c545788ade614d7ae0b29ccfcd4d50c4ddf55..9906244ab2e447de25546f25ec5f6ef6 this.containerMenu = abstractContainerMenu; // Moved up if (!this.isImmobile()) this.connection -@@ -1844,6 +1855,11 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -1837,6 +1848,11 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc } @Override public void closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) { diff --git a/leaf-server/minecraft-patches/features/0219-Use-BFS-on-getSlopeDistance.patch b/leaf-server/minecraft-patches/features/0219-Use-BFS-on-getSlopeDistance.patch index 4e11cba9..177a1ade 100644 --- a/leaf-server/minecraft-patches/features/0219-Use-BFS-on-getSlopeDistance.patch +++ b/leaf-server/minecraft-patches/features/0219-Use-BFS-on-getSlopeDistance.patch @@ -9,10 +9,10 @@ Leaf: ~48ms (-36%) This should help drastically on the farms that use actively changing fluids. diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 1b0bd86212e7ff0b8a80a524250b69bd68a9c685..d3b711d4aa5c54c05310a2089a8c371fc2c2acdf 100644 +index 56e6691f4fc425f13fe5f1fd40de16f4c54a3195..f77bd9472300aec6958ebfa69469fb4e1ee36484 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java -@@ -1449,6 +1449,10 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1438,6 +1438,10 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.emptyTime = 0; } diff --git a/leaf-server/minecraft-patches/features/0225-Micro-optimizations-for-random-tick.patch b/leaf-server/minecraft-patches/features/0225-Micro-optimizations-for-random-tick.patch index fc044571..676cf25f 100644 --- a/leaf-server/minecraft-patches/features/0225-Micro-optimizations-for-random-tick.patch +++ b/leaf-server/minecraft-patches/features/0225-Micro-optimizations-for-random-tick.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Micro optimizations for random tick diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index d3b711d4aa5c54c05310a2089a8c371fc2c2acdf..478e8fa7955b3a084a7b519c0b4cddb399f72758 100644 +index f77bd9472300aec6958ebfa69469fb4e1ee36484..a9f33e705b3c0abfa3dcc01647a57c06bb614e1c 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java -@@ -1048,7 +1048,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1036,7 +1036,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // Paper start - optimise random ticking private void optimiseRandomTick(final LevelChunk chunk, final int tickSpeed) { final LevelChunkSection[] sections = chunk.getSections(); @@ -17,7 +17,7 @@ index d3b711d4aa5c54c05310a2089a8c371fc2c2acdf..478e8fa7955b3a084a7b519c0b4cddb3 final net.minecraft.world.level.levelgen.BitRandomSource simpleRandom = this.simpleRandom; // Leaf - Faster random generator - upcasting final boolean doubleTickFluids = !ca.spottedleaf.moonrise.common.PlatformHooks.get().configFixMC224294(); -@@ -1057,41 +1057,41 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1045,41 +1045,41 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe final int offsetZ = cpos.z << 4; for (int sectionIndex = 0, sectionsLen = sections.length; sectionIndex < sectionsLen; sectionIndex++) { diff --git a/leaf-server/minecraft-patches/features/0233-Async-target-finding.patch b/leaf-server/minecraft-patches/features/0233-Async-target-finding.patch index c66b91d7..e3463b25 100644 --- a/leaf-server/minecraft-patches/features/0233-Async-target-finding.patch +++ b/leaf-server/minecraft-patches/features/0233-Async-target-finding.patch @@ -134,7 +134,7 @@ index 9b8d119116b0c3a51d3fe2ff7efb33cc39627cc4..436e73086678e4afbf94f1b7bca9b0c7 // Gale start - Pufferfish - SIMD support diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 478e8fa7955b3a084a7b519c0b4cddb399f72758..fc61a7083232148397a0b330ce2a4d70ba38543d 100644 +index a9f33e705b3c0abfa3dcc01647a57c06bb614e1c..02c2b9c1978959e1ee0be5c72a5f7b98aa282fc2 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java @@ -175,7 +175,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -178,7 +178,7 @@ index 478e8fa7955b3a084a7b519c0b4cddb399f72758..fc61a7083232148397a0b330ce2a4d70 // Leaf start - SparklyPaper - parallel world ticking - Shutdown handling for async reads diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java -index 4a1a336914eff8a178dcd992bd1bfea25a8be76b..7e3b35df01b63735fd4d5202788477a1342708a5 100644 +index 173ec6919cef2aa90c40d3bf33d927a2db7b4922..e99fd3cd5ca6863facd189bf9cd4a3d5c102424a 100644 --- a/net/minecraft/world/entity/Mob.java +++ b/net/minecraft/world/entity/Mob.java @@ -138,6 +138,12 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab @@ -206,7 +206,7 @@ index 4a1a336914eff8a178dcd992bd1bfea25a8be76b..7e3b35df01b63735fd4d5202788477a1 } // Paper end -@@ -793,6 +804,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab +@@ -782,6 +793,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab if (this.goalSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking this.goalSelector.tick(); } diff --git a/leaf-server/minecraft-patches/features/0255-Optimize-isEyeInFluid.patch b/leaf-server/minecraft-patches/features/0255-Optimize-isEyeInFluid.patch index d7b89f02..788d3f82 100644 --- a/leaf-server/minecraft-patches/features/0255-Optimize-isEyeInFluid.patch +++ b/leaf-server/minecraft-patches/features/0255-Optimize-isEyeInFluid.patch @@ -79,10 +79,10 @@ index 6c7edbbf3935c40ccb78bee680ea75431718b9bd..fd2f79d976c9587b00380f8b8f784b32 public String toString() { return "Reference{" + this.key + "=" + this.value + "}"; diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index 89751b2651f85eefeca7c782460297fbb2ddbcff..a15c1c0a1eeb80bd10d5590dce73cb726569c61f 100644 +index 9ec5f1ebc013b427e92f92d6df722b42aa7f73d7..38edf089bac1de826cfc7e72384151ee25e46a95 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -1911,7 +1911,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -1904,7 +1904,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc this.awardStat(Stats.SWIM_ONE_CM, rounded); this.causeFoodExhaustion(this.level().spigotConfig.swimMultiplier * (float) rounded * 0.01F, org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.SWIM); // CraftBukkit - EntityExhaustionEvent // Spigot } diff --git a/leaf-server/minecraft-patches/features/0261-optimize-mob-spawning.patch b/leaf-server/minecraft-patches/features/0261-optimize-mob-spawning.patch index 396722c2..341e97fa 100644 --- a/leaf-server/minecraft-patches/features/0261-optimize-mob-spawning.patch +++ b/leaf-server/minecraft-patches/features/0261-optimize-mob-spawning.patch @@ -172,13 +172,13 @@ index 46e171ca454253c32e22c0c18587e9a7ba19f331..1c7e2e5124c7d4c1b86039b0327bfd92 } } diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index fc61a7083232148397a0b330ce2a4d70ba38543d..d319e4d7e12c4bae63893ad25dcdc3ed59c88d97 100644 +index 02c2b9c1978959e1ee0be5c72a5f7b98aa282fc2..4ec5142e233c87d2bb1ebe883cf10a5a1e5100b3 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java -@@ -1114,6 +1114,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - +@@ -1103,6 +1103,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe private int currentIceAndSnowTick = 0; protected void resetIceAndSnowTick() { this.currentIceAndSnowTick = this.simpleRandom.nextInt(16); } // Gale - Airplane - optimize random calls in chunk ticking + public final org.dreeam.leaf.world.DespawnMap despawnMap = new org.dreeam.leaf.world.DespawnMap(); // Leaf - optimize despawn + public final org.dreeam.leaf.world.NatureSpawnChunkMap natureSpawnChunkMap = new org.dreeam.leaf.world.NatureSpawnChunkMap(); // Leaf - optimize mob spawning public void tickChunk(LevelChunk chunk, int randomTickSpeed) { final net.minecraft.world.level.levelgen.BitRandomSource simpleRandom = this.simpleRandom; // Paper - optimise random ticking // Leaf - Faster random generator - upcasting diff --git a/leaf-server/minecraft-patches/features/0268-optimize-random-tick.patch b/leaf-server/minecraft-patches/features/0268-optimize-random-tick.patch index 968d128b..76629e4b 100644 --- a/leaf-server/minecraft-patches/features/0268-optimize-random-tick.patch +++ b/leaf-server/minecraft-patches/features/0268-optimize-random-tick.patch @@ -24,12 +24,12 @@ index 1c7e2e5124c7d4c1b86039b0327bfd92c49df9b1..976fcc96f8f0a10338c5b98bd3908e6d this.level.tickCustomSpawners(this.spawnEnemies, this.spawnFriendlies); } diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index d319e4d7e12c4bae63893ad25dcdc3ed59c88d97..08c6f93bcc028c876e17870681382aa9fa2ba3ee 100644 +index 4ec5142e233c87d2bb1ebe883cf10a5a1e5100b3..307738d09dc4eb5918cbfb1153feb739fbc1cc68 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java -@@ -1115,6 +1115,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - private int currentIceAndSnowTick = 0; protected void resetIceAndSnowTick() { this.currentIceAndSnowTick = this.simpleRandom.nextInt(16); } // Gale - Airplane - optimize random calls in chunk ticking +@@ -1104,6 +1104,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + public final org.dreeam.leaf.world.DespawnMap despawnMap = new org.dreeam.leaf.world.DespawnMap(); // Leaf - optimize despawn public final org.dreeam.leaf.world.NatureSpawnChunkMap natureSpawnChunkMap = new org.dreeam.leaf.world.NatureSpawnChunkMap(); // Leaf - optimize mob spawning + public final org.dreeam.leaf.world.RandomTickSystem randomTickSystem = new org.dreeam.leaf.world.RandomTickSystem(); // Leaf - optimize random tick public void tickChunk(LevelChunk chunk, int randomTickSpeed) { diff --git a/leaf-server/minecraft-patches/features/0272-Replace-EntitySelectorOptions-map-with-optimized-col.patch b/leaf-server/minecraft-patches/features/0271-Replace-EntitySelectorOptions-map-with-optimized-col.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0272-Replace-EntitySelectorOptions-map-with-optimized-col.patch rename to leaf-server/minecraft-patches/features/0271-Replace-EntitySelectorOptions-map-with-optimized-col.patch diff --git a/leaf-server/minecraft-patches/features/0273-Cache-function-execution-result.patch b/leaf-server/minecraft-patches/features/0272-Cache-function-execution-result.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0273-Cache-function-execution-result.patch rename to leaf-server/minecraft-patches/features/0272-Cache-function-execution-result.patch diff --git a/leaf-server/minecraft-patches/features/0274-optimize-no-action-time.patch b/leaf-server/minecraft-patches/features/0273-optimize-no-action-time.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0274-optimize-no-action-time.patch rename to leaf-server/minecraft-patches/features/0273-optimize-no-action-time.patch diff --git a/leaf-server/minecraft-patches/features/0276-optimize-waypoint.patch b/leaf-server/minecraft-patches/features/0274-optimize-waypoint.patch similarity index 82% rename from leaf-server/minecraft-patches/features/0276-optimize-waypoint.patch rename to leaf-server/minecraft-patches/features/0274-optimize-waypoint.patch index df9f4fd1..0ec9817a 100644 --- a/leaf-server/minecraft-patches/features/0276-optimize-waypoint.patch +++ b/leaf-server/minecraft-patches/features/0274-optimize-waypoint.patch @@ -5,16 +5,18 @@ Subject: [PATCH] optimize waypoint diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 5ee9394fd35a9f61e6a54126ed2c567dff19c05b..502c6afe9ff8cb3d163862920794f15cec2f78a8 100644 +index eff20b8de6bddfeec4f25e6381bf914bca38e1c6..50dd29948e89e3f618722201841429121d7f19e0 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -5117,12 +5117,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -5145,6 +5145,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return; } // Paper end - Block invalid positions and bounding box + boolean blockUpdated; // Leaf - optimize waypoint if (this.position.x != x || this.position.y != y || this.position.z != z) { + synchronized (this.posLock) { // Paper - detailed watchdog information this.position = new Vec3(x, y, z); +@@ -5152,7 +5153,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess int floor = Mth.floor(x); int floor1 = Mth.floor(y); int floor2 = Mth.floor(z); @@ -24,7 +26,7 @@ index 5ee9394fd35a9f61e6a54126ed2c567dff19c05b..502c6afe9ff8cb3d163862920794f15c this.blockPosition = new BlockPos(floor, floor1, floor2); this.inBlockState = null; if (SectionPos.blockToSectionCoord(floor) != this.chunkPosition.x || SectionPos.blockToSectionCoord(floor2) != this.chunkPosition.z) { -@@ -5131,7 +5133,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -5161,7 +5163,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } this.levelCallback.onMove(); diff --git a/leaf-server/minecraft-patches/features/0271-Paw-optimization.patch b/leaf-server/minecraft-patches/features/0275-Paw-optimization.patch similarity index 98% rename from leaf-server/minecraft-patches/features/0271-Paw-optimization.patch rename to leaf-server/minecraft-patches/features/0275-Paw-optimization.patch index 2337ae64..6248324c 100644 --- a/leaf-server/minecraft-patches/features/0271-Paw-optimization.patch +++ b/leaf-server/minecraft-patches/features/0275-Paw-optimization.patch @@ -100,10 +100,10 @@ index 4535858701b2bb232b9d2feb2af6551526232ddc..e65c62dbe4c1560ae153e4c4344e9194 - // Paper end - detailed watchdog information } diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 08c6f93bcc028c876e17870681382aa9fa2ba3ee..58a77b5aa49cb56eea33757e982ba1852bbfb679 100644 +index 307738d09dc4eb5918cbfb1153feb739fbc1cc68..0fc09b85e9d8e12f8103dcf755afa3928361c812 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java -@@ -1518,13 +1518,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1507,13 +1507,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // Paper end - log detailed entity tick information public void tickNonPassenger(Entity entity) { @@ -117,7 +117,7 @@ index 08c6f93bcc028c876e17870681382aa9fa2ba3ee..58a77b5aa49cb56eea33757e982ba185 entity.setOldPosAndRot(); entity.tickCount++; entity.totalEntityAge++; // Paper - age-like counter for all entities -@@ -1537,13 +1531,6 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1526,13 +1520,6 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe for (Entity entity1 : entity.getPassengers()) { this.tickPassenger(entity, entity1, isActive); // Paper - EAR 2 } @@ -132,7 +132,7 @@ index 08c6f93bcc028c876e17870681382aa9fa2ba3ee..58a77b5aa49cb56eea33757e982ba185 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 eff20b8de6bddfeec4f25e6381bf914bca38e1c6..5ee9394fd35a9f61e6a54126ed2c567dff19c05b 100644 +index 50dd29948e89e3f618722201841429121d7f19e0..502c6afe9ff8cb3d163862920794f15cec2f78a8 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -1170,16 +1170,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -193,9 +193,9 @@ index eff20b8de6bddfeec4f25e6381bf914bca38e1c6..5ee9394fd35a9f61e6a54126ed2c567d } public void addDeltaMovement(Vec3 addend) { -@@ -5146,9 +5118,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - } +@@ -5147,9 +5119,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess // Paper end - Block invalid positions and bounding box + boolean blockUpdated; // Leaf - optimize waypoint if (this.position.x != x || this.position.y != y || this.position.z != z) { - synchronized (this.posLock) { // Paper - detailed watchdog information this.position = new Vec3(x, y, z); diff --git a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/OptimizeDespawn.java b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/OptimizeDespawn.java new file mode 100644 index 00000000..76530c19 --- /dev/null +++ b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/OptimizeDespawn.java @@ -0,0 +1,19 @@ +package org.dreeam.leaf.config.modules.opt; + +import org.dreeam.leaf.config.ConfigModules; +import org.dreeam.leaf.config.EnumConfigCategory; +import org.dreeam.leaf.config.annotations.Experimental; + +public class OptimizeDespawn extends ConfigModules { + public String getBasePath() { + return EnumConfigCategory.PERF.getBaseKeyName() + ".optimize-mob-despawn"; + } + + @Experimental + public static boolean enabled = false; + + @Override + public void onLoaded() { + enabled = config.getBoolean(getBasePath(), enabled); + } +} diff --git a/leaf-server/src/main/java/org/dreeam/leaf/world/DespawnMap.java b/leaf-server/src/main/java/org/dreeam/leaf/world/DespawnMap.java new file mode 100644 index 00000000..ff90af01 --- /dev/null +++ b/leaf-server/src/main/java/org/dreeam/leaf/world/DespawnMap.java @@ -0,0 +1,85 @@ +package org.dreeam.leaf.world; + +import io.papermc.paper.configuration.WorldConfiguration; +import io.papermc.paper.configuration.type.DespawnRange; +import it.unimi.dsi.fastutil.objects.ObjectArrays; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.EntitySelector; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import org.bukkit.event.entity.EntityRemoveEvent; + +import java.util.List; + +public final class DespawnMap { + private static final ServerPlayer[] EMPTY_PLAYER_ARRAY = {}; + + private ServerPlayer[] players = EMPTY_PLAYER_ARRAY; + private double[] pos = {}; + + public void prepare(ServerLevel world) { + this.players = world.players().toArray(EMPTY_PLAYER_ARRAY); + + List playerList = world.players(); + ServerPlayer[] list = new ServerPlayer[playerList.size()]; + int newSize = 0; + for (ServerPlayer player1 : playerList) { + if (EntitySelector.PLAYER_AFFECTS_SPAWNING.test(player1)) { + list[newSize++] = player1; + } + } + list = ObjectArrays.trim(list, newSize); + this.players = list; + this.pos = new double[this.players.length * 3]; + for (int i = 0; i < players.length; i++) { + this.pos[i * 3] = this.players[i].getX(); + this.pos[i * 3 + 1] = this.players[i].getY(); + this.pos[i * 3 + 2] = this.players[i].getZ(); + } + } + + public void reset() { + this.players = EMPTY_PLAYER_ARRAY; + } + + public void checkDespawn(Mob mob) { + double x = mob.getX(); + double y = mob.getY(); + double z = mob.getZ(); + double distance = Double.MAX_VALUE; + Player nearestPlayer = null; + for (int i = 0, playersSize = players.length; i < playersSize; i++) { + final double dx = this.pos[i * 3] - x; + final double dy = this.pos[i * 3 + 1] - y; + final double dz = this.pos[i * 3 + 2] - z; + double d1 = dx * dx + dy * dy + dz * dz; + if (d1 < distance) { + distance = d1; + nearestPlayer = players[i]; + } + } + if (nearestPlayer == null) { + return; + } + Level world = mob.level(); + final WorldConfiguration.Entities.Spawning.DespawnRangePair despawnRangePair = world.paperConfig().entities.spawning.despawnRanges.get(mob.getType().getCategory()); + final DespawnRange.Shape shape = world.paperConfig().entities.spawning.despawnRangeShape; + final double dy = Math.abs(nearestPlayer.getY() - y); + final double dySqr = Mth.square(dy); + final double dxSqr = Mth.square(nearestPlayer.getX() - x); + final double dzSqr = Mth.square(nearestPlayer.getZ() - z); + final double distanceSquared = dxSqr + dzSqr + dySqr; + if (despawnRangePair.hard().shouldDespawn(shape, dxSqr, dySqr, dzSqr, dy) && mob.removeWhenFarAway(distanceSquared)) { + mob.discard(EntityRemoveEvent.Cause.DESPAWN); + } else if (despawnRangePair.soft().shouldDespawn(shape, dxSqr, dySqr, dzSqr, dy)) { + if (mob.getNoActionTime() > 600 && mob.random.nextInt(800) == 0 && mob.removeWhenFarAway(distanceSquared)) { + mob.discard(EntityRemoveEvent.Cause.DESPAWN); + } + } else { + mob.setNoActionTime(0); + } + } +}