9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2025-12-19 15:09:25 +00:00

fix async mob spawning TRACKED entities not count (#393)

* fix unloaded and TRACKED entities not count

#392

* move to archived
This commit is contained in:
hayanesuru
2025-07-08 22:54:12 +09:00
committed by GitHub
parent 88303ed880
commit ac6e483e8d
56 changed files with 89 additions and 52 deletions

View File

@@ -14,7 +14,7 @@ Generally faster than the non-async approach
iterate over all entities, get their chunk, and increment the count
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
index 79674f4bd7a12c42dec19a4175012d7a2dc88b84..0a97a491737807d59815b75635fa3d8c94901ba8 100644
index a640cb4d767c6c81ad27bbf0dd8027a80a2fc224..f4d4f39540a25d6772c8078d0ff01af04d90c8e7 100644
--- a/net/minecraft/server/level/ChunkMap.java
+++ b/net/minecraft/server/level/ChunkMap.java
@@ -287,6 +287,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@@ -26,7 +26,7 @@ index 79674f4bd7a12c42dec19a4175012d7a2dc88b84..0a97a491737807d59815b75635fa3d8c
}
// Paper end - Optional per player mob spawns
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
index 46e171ca454253c32e22c0c18587e9a7ba19f331..1c7e2e5124c7d4c1b86039b0327bfd92c49df9b1 100644
index 46e171ca454253c32e22c0c18587e9a7ba19f331..43156ecde8bb86c77f3b13c17b3330eae95efcc3 100644
--- a/net/minecraft/server/level/ServerChunkCache.java
+++ b/net/minecraft/server/level/ServerChunkCache.java
@@ -70,11 +70,11 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
@@ -78,7 +78,7 @@ index 46e171ca454253c32e22c0c18587e9a7ba19f331..1c7e2e5124c7d4c1b86039b0327bfd92
// Paper start - per player mob spawning backoff
for (int ii = 0; ii < ServerPlayer.MOBCATEGORY_TOTAL_ENUMS; ii++) {
player.mobCounts[ii] = 0;
@@ -524,14 +541,14 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
@@ -524,34 +541,27 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
player.mobBackoffCounts[ii] = newBackoff;
}
// Paper end - per player mob spawning backoff
@@ -89,26 +89,46 @@ index 46e171ca454253c32e22c0c18587e9a7ba19f331..1c7e2e5124c7d4c1b86039b0327bfd92
_pufferfish_spawnCountsReady.set(true);
}
if (_pufferfish_spawnCountsReady.getAndSet(false)) {
+ int mapped = distanceManager.getNaturalSpawnChunkCount();
+ final int mapped = distanceManager.getNaturalSpawnChunkCount();
+ final Iterable<Entity> entities = this.level.getAllEntities();
net.minecraft.server.MinecraftServer.getServer().mobSpawnExecutor.submit(() -> {
- int mapped = distanceManager.getNaturalSpawnChunkCount();
ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet.Iterator<Entity> objectiterator =
level.entityTickList.entities.iterator(ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet.ITERATOR_FLAG_SEE_ADDITIONS);
try {
@@ -542,10 +559,10 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
new LocalMobCapCalculator(chunkMap) : null;
// This ensures the caps are properly enforced by using the correct calculator
- ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet.Iterator<Entity> objectiterator =
- level.entityTickList.entities.iterator(ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet.ITERATOR_FLAG_SEE_ADDITIONS);
- try {
- gg.pufferfish.pufferfish.util.IterableWrapper<Entity> wrappedIterator =
- new gg.pufferfish.pufferfish.util.IterableWrapper<>(objectiterator);
- // Fix: Use proper mob cap calculator based on configuration
- LocalMobCapCalculator mobCapCalculator = !level.paperConfig().entities.spawning.perPlayerMobSpawns ?
- new LocalMobCapCalculator(chunkMap) : null;
-
- // This ensures the caps are properly enforced by using the correct calculator
- lastSpawnState = NaturalSpawner.createState(
+ lastSpawnState = NaturalSpawner.createState1( // Leaf - optimize mob spawning
mapped,
wrappedIterator,
- mapped,
- wrappedIterator,
- ServerChunkCache.this::getFullChunk,
- mobCapCalculator, // This is the key fix - was previously null
- level.paperConfig().entities.spawning.perPlayerMobSpawns
- );
- } finally {
- objectiterator.finishedIterating();
- }
+ // Fix: Use proper mob cap calculator based on configuration
+ LocalMobCapCalculator mobCapCalculator = !level.paperConfig().entities.spawning.perPlayerMobSpawns ?
+ new LocalMobCapCalculator(chunkMap) : null;
+
+ // This ensures the caps are properly enforced by using the correct calculator
+ lastSpawnState = NaturalSpawner.createState1( // Leaf - optimize mob spawning
+ mapped,
+ entities,
+ this.level, // Leaf - optimize mob spawning
mobCapCalculator, // This is the key fix - was previously null
level.paperConfig().entities.spawning.perPlayerMobSpawns
);
@@ -610,6 +627,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
+ mobCapCalculator, // This is the key fix - was previously null
+ level.paperConfig().entities.spawning.perPlayerMobSpawns
+ );
_pufferfish_spawnCountsReady.set(true);
});
}
@@ -610,6 +620,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
chunkRange = Math.min(chunkRange, 8);
entityPlayer.playerNaturallySpawnedEvent = new com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent(entityPlayer.getBukkitEntity(), (byte) chunkRange);
entityPlayer.playerNaturallySpawnedEvent.callEvent();
@@ -116,7 +136,7 @@ index 46e171ca454253c32e22c0c18587e9a7ba19f331..1c7e2e5124c7d4c1b86039b0327bfd92
}
// Paper end - PlayerNaturallySpawnCreaturesEvent
boolean flag = this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) != 0L && this.level.getLevelData().getGameTime() % this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) == 0L; // CraftBukkit
@@ -621,16 +639,40 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
@@ -621,16 +632,40 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
List<LevelChunk> list = this.spawningChunks;
try {
@@ -162,7 +182,7 @@ index 46e171ca454253c32e22c0c18587e9a7ba19f331..1c7e2e5124c7d4c1b86039b0327bfd92
list.clear();
}
@@ -648,7 +690,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
@@ -648,7 +683,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
}
if (!spawnCategories.isEmpty()) {
@@ -184,7 +204,7 @@ index 02c2b9c1978959e1ee0be5c72a5f7b98aa282fc2..4ec5142e233c87d2bb1ebe883cf10a5a
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/level/NaturalSpawner.java b/net/minecraft/world/level/NaturalSpawner.java
index 81e176d17fb072f9ee531639abfe42134ae833a9..1052353f3a1ed52ac51cb0bb12f9e6a47c8bc6c8 100644
index 81e176d17fb072f9ee531639abfe42134ae833a9..c3284577437412e1c3fb891bee2b0e20b52ccd59 100644
--- a/net/minecraft/world/level/NaturalSpawner.java
+++ b/net/minecraft/world/level/NaturalSpawner.java
@@ -68,6 +68,7 @@ public final class NaturalSpawner {
@@ -195,7 +215,7 @@ index 81e176d17fb072f9ee531639abfe42134ae833a9..1052353f3a1ed52ac51cb0bb12f9e6a4
public static NaturalSpawner.SpawnState createState(
int spawnableChunkCount, Iterable<Entity> entities, NaturalSpawner.ChunkGetter chunkGetter, LocalMobCapCalculator calculator, final boolean countMobs
) {
@@ -108,9 +109,69 @@ public final class NaturalSpawner {
@@ -108,9 +109,71 @@ public final class NaturalSpawner {
}
}
@@ -225,6 +245,7 @@ index 81e176d17fb072f9ee531639abfe42134ae833a9..1052353f3a1ed52ac51cb0bb12f9e6a4
+ // Paper end - Only count natural spawns
+ BlockPos blockPos = entity.blockPosition();
+ LevelChunk chunk = level.chunkSource.fullChunks.get(ChunkPos.asLong(blockPos));
+ if (chunk != null) {
+ MobSpawnSettings.MobSpawnCost mobSpawnCost = getRoughBiome(blockPos, chunk).getMobSettings().getMobSpawnCost(entity.getType());
+ if (mobSpawnCost != null) {
+ potentialCalculator.addCharge(entity.blockPosition(), mobSpawnCost.charge());
@@ -258,6 +279,7 @@ index 81e176d17fb072f9ee531639abfe42134ae833a9..1052353f3a1ed52ac51cb0bb12f9e6a4
+ }
+ }
+ }
+ }
+
+ return new NaturalSpawner.SpawnState(spawnableChunkCount, map, potentialCalculator, calculator, chunkCap);
+ }
@@ -266,7 +288,7 @@ index 81e176d17fb072f9ee531639abfe42134ae833a9..1052353f3a1ed52ac51cb0bb12f9e6a4
static Biome getRoughBiome(BlockPos pos, ChunkAccess chunk) {
return chunk.getNoiseBiome(QuartPos.fromBlock(pos.getX()), QuartPos.fromBlock(pos.getY()), QuartPos.fromBlock(pos.getZ())).value();
}
@@ -265,28 +326,68 @@ public final class NaturalSpawner {
@@ -265,28 +328,68 @@ public final class NaturalSpawner {
MobCategory category, ServerLevel level, ChunkAccess chunk, BlockPos pos, NaturalSpawner.SpawnPredicate filter, NaturalSpawner.AfterSpawnCallback callback, final int maxSpawns, final @Nullable Consumer<Entity> trackEntity, final boolean nothing
// Paper end - throttle failed spawn attempts
) {
@@ -342,7 +364,7 @@ index 81e176d17fb072f9ee531639abfe42134ae833a9..1052353f3a1ed52ac51cb0bb12f9e6a4
mutableBlockPos.set(x, y, z);
double d = x + 0.5;
double d1 = z + 0.5;
@@ -295,8 +396,8 @@ public final class NaturalSpawner {
@@ -295,8 +398,8 @@ public final class NaturalSpawner {
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 (spawnerData == null) {
@@ -353,7 +375,7 @@ index 81e176d17fb072f9ee531639abfe42134ae833a9..1052353f3a1ed52ac51cb0bb12f9e6a4
);
if (randomSpawnMobAt.isEmpty()) {
break;
@@ -307,7 +408,7 @@ public final class NaturalSpawner {
@@ -307,7 +410,7 @@ public final class NaturalSpawner {
}
// Paper start - PreCreatureSpawnEvent
@@ -362,7 +384,7 @@ index 81e176d17fb072f9ee531639abfe42134ae833a9..1052353f3a1ed52ac51cb0bb12f9e6a4
// Paper start - per player mob count backoff
if (doSpawning == PreSpawnStatus.ABORT || doSpawning == PreSpawnStatus.CANCELLED) {
level.getChunkSource().chunkMap.updateFailurePlayerMobTypeMap(mutableBlockPos.getX() >> 4, mutableBlockPos.getZ() >> 4, category);
@@ -414,6 +515,44 @@ public final class NaturalSpawner {
@@ -414,6 +517,44 @@ public final class NaturalSpawner {
&& level.noCollision(entityType.getSpawnAABB(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5));
return success ? PreSpawnStatus.SUCCESS : PreSpawnStatus.FAIL; // Paper - PreCreatureSpawnEvent
}
@@ -407,7 +429,7 @@ index 81e176d17fb072f9ee531639abfe42134ae833a9..1052353f3a1ed52ac51cb0bb12f9e6a4
@Nullable
private static Mob getMobForSpawn(ServerLevel level, EntityType<?> entityType) {
@@ -449,6 +588,17 @@ public final class NaturalSpawner {
@@ -449,6 +590,17 @@ public final class NaturalSpawner {
: mobsAt(level, structureManager, generator, category, pos, biome).getRandom(random);
}
@@ -425,7 +447,7 @@ index 81e176d17fb072f9ee531639abfe42134ae833a9..1052353f3a1ed52ac51cb0bb12f9e6a4
private static boolean canSpawnMobAt(
ServerLevel level, StructureManager structureManager, ChunkGenerator generator, MobCategory category, MobSpawnSettings.SpawnerData data, BlockPos pos
) {
@@ -463,6 +613,16 @@ public final class NaturalSpawner {
@@ -463,6 +615,16 @@ public final class NaturalSpawner {
: generator.getMobsAt(biome != null ? biome : (org.dreeam.leaf.config.modules.opt.OptimizeBiome.mobSpawn ? level.getBiomeCached(null, pos) : level.getBiome(pos)), structureManager, cetagory, pos); // Leaf - cache getBiome
}
@@ -442,7 +464,7 @@ index 81e176d17fb072f9ee531639abfe42134ae833a9..1052353f3a1ed52ac51cb0bb12f9e6a4
public static boolean isInNetherFortressBounds(BlockPos pos, ServerLevel level, MobCategory category, StructureManager structureManager) {
if (category == MobCategory.MONSTER && level.getBlockState(pos.below()).is(Blocks.NETHER_BRICKS)) {
Structure structure = structureManager.registryAccess().lookupOrThrow(Registries.STRUCTURE).getValue(BuiltinStructures.FORTRESS);
@@ -472,6 +632,17 @@ public final class NaturalSpawner {
@@ -472,6 +634,17 @@ public final class NaturalSpawner {
}
}
@@ -460,7 +482,7 @@ index 81e176d17fb072f9ee531639abfe42134ae833a9..1052353f3a1ed52ac51cb0bb12f9e6a4
private static BlockPos getRandomPosWithin(Level level, LevelChunk chunk) {
ChunkPos pos = chunk.getPos();
int i = pos.getMinBlockX() + level.random.nextInt(16);
@@ -612,18 +783,21 @@ public final class NaturalSpawner {
@@ -612,18 +785,21 @@ public final class NaturalSpawner {
@Nullable
private EntityType<?> lastCheckedType;
private double lastCharge;
@@ -483,7 +505,7 @@ index 81e176d17fb072f9ee531639abfe42134ae833a9..1052353f3a1ed52ac51cb0bb12f9e6a4
}
private boolean canSpawn(EntityType<?> entityType, BlockPos pos, ChunkAccess chunk) {
@@ -680,5 +854,32 @@ public final class NaturalSpawner {
@@ -680,5 +856,32 @@ public final class NaturalSpawner {
boolean canSpawnForCategoryLocal(MobCategory category, ChunkPos chunkPos) {
return this.localMobCapCalculator.canSpawn(category, chunkPos);
}
@@ -594,3 +616,16 @@ index 11c7c299d4affb9e78488590e7db939efe6e3dd9..a89c61aac1f1a35dc8c5943c0002661c
public void createStructures(
RegistryAccess registryAccess,
ChunkGeneratorStructureState structureState,
diff --git a/net/minecraft/world/level/entity/EntityTickList.java b/net/minecraft/world/level/entity/EntityTickList.java
index 5a90b3bffeeb08a168b370e49d18c5f8b257a980..ba173bc1751c495e6fa497566b5ed3c7a9547364 100644
--- a/net/minecraft/world/level/entity/EntityTickList.java
+++ b/net/minecraft/world/level/entity/EntityTickList.java
@@ -9,7 +9,7 @@ import javax.annotation.Nullable;
import net.minecraft.world.entity.Entity;
public class EntityTickList {
- public final ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet<net.minecraft.world.entity.Entity> entities = new ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet<>(org.dreeam.leaf.config.modules.async.AsyncMobSpawning.enabled); // Paper - rewrite chunk system // Pufferfish - private->public and do thread check
+ private final ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet<net.minecraft.world.entity.Entity> entities = new ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet<>(); // Paper - rewrite chunk system
// Leaf start - SparklyPaper - parallel world ticking mod
// preserve original constructor

View File

@@ -5,10 +5,10 @@ Subject: [PATCH] throttle mob spawning
diff --git a/net/minecraft/world/level/NaturalSpawner.java b/net/minecraft/world/level/NaturalSpawner.java
index ab6fa7ed111ef16a0b6774c21988589ee2110c66..b1220364424db2e0dce58c5a0f6334e2e9f06dec 100644
index c3284577437412e1c3fb891bee2b0e20b52ccd59..bb5b51b661542996c5a3dce2dc873bf198a89745 100644
--- a/net/minecraft/world/level/NaturalSpawner.java
+++ b/net/minecraft/world/level/NaturalSpawner.java
@@ -215,6 +215,17 @@ public final class NaturalSpawner {
@@ -217,6 +217,17 @@ public final class NaturalSpawner {
// Paper start - Optional per player mob spawns
final boolean canSpawn;
int maxSpawns = Integer.MAX_VALUE;

View File

@@ -5,10 +5,10 @@ Subject: [PATCH] optimize random tick
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
index 1c7e2e5124c7d4c1b86039b0327bfd92c49df9b1..976fcc96f8f0a10338c5b98bd3908e6def217676 100644
index 43156ecde8bb86c77f3b13c17b3330eae95efcc3..ba0f66b5089e252e5d532cb4b94c6246a65d69d8 100644
--- a/net/minecraft/server/level/ServerChunkCache.java
+++ b/net/minecraft/server/level/ServerChunkCache.java
@@ -676,7 +676,13 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
@@ -669,7 +669,13 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
list.clear();
}

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] Fix Pufferfish and Purpur patches
diff --git a/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java b/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java
index 5b844d2fea387f2cb655169f458ec0ca627f1c65..f267abd6f905180cfa5cf4961cf79f57544a891c 100644
index f5302d038e4bb731075dccde4015627dc9e7b420..afaff6dcfe2044c465693dd0971d07644470ba8a 100644
--- a/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java
+++ b/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java
@@ -32,9 +32,11 @@ public record ServerBuildInfoImpl(

View File

@@ -20,7 +20,7 @@ index a4d5c65edc1db59f3486ce5d3757cc306211a54b..b00a82816784ea2f6422ca98c1f11597
// Paper start
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
index 63f6b5d00b401fe670fd237e53dd2073d042535b..eb51cfce4069035664d2d1e3d30ab681e917dee6 100644
index a43f3d6e54de52da6b1ee050aefd0028a1adafcf..db71a9fc02bfac7799b58f07da044e53b2273e98 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
@@ -185,7 +185,7 @@ public final class CraftBlockStates {

View File

@@ -6,7 +6,7 @@ Subject: [PATCH] Paw optimization
Some random optimizations
diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
index ae9c9a96ac070f629564fba867749df173fd4f85..461b7ae34a4448cac0f9ca315b25ed9e7564f0b8 100644
index e9ec96e9aee0cdf72ff18f8a42389ff78869f58c..ae0b0e2bea46707d78adc60d2cc212a813bef076 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
@@ -244,13 +244,37 @@ public class CraftBlockData implements BlockData {

View File

@@ -3,6 +3,7 @@ package gg.pufferfish.pufferfish.util;
import it.unimi.dsi.fastutil.PriorityQueue;
import it.unimi.dsi.fastutil.PriorityQueues;
import it.unimi.dsi.fastutil.objects.ObjectArrayFIFOQueue;
import net.minecraft.Util;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -21,6 +22,7 @@ public class AsyncExecutor implements Runnable {
.name(threadName)
.priority(Thread.NORM_PRIORITY - 1)
.daemon(false)
.uncaughtExceptionHandler(Util::onThreadException)
.unstarted(this);
}