137 lines
9.2 KiB
Diff
137 lines
9.2 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
|
Date: Wed, 3 Dec 2025 16:28:34 +0800
|
|
Subject: [PATCH] Global Entities Counter
|
|
|
|
|
|
diff --git a/io/papermc/paper/threadedregions/RegionizedWorldData.java b/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
|
index 3b39b8f7ccb278cf910e3cc4e00da29790465a81..7cc41630a39c1e29840d70eee78473d06b7c11cd 100644
|
|
--- a/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
|
+++ b/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
|
@@ -520,6 +520,9 @@ public final class RegionizedWorldData {
|
|
public final Map<Long, ChunkSectionItemEntityMovementTracker> itemEntityMovementTrackerMap = new it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap<>();
|
|
// Luminol end
|
|
|
|
+ public int uniqueId = -1; // Lophine - Global Entities Counter
|
|
+ public boolean underGlobalEntitiesCounter = false; // Lophine - Global Entities Counter
|
|
+
|
|
public RegionizedWorldData(final ServerLevel world) {
|
|
this.world = world;
|
|
this.blockLevelTicks = new LevelTicks<>(world::isPositionTickingWithEntitiesLoaded, world, true);
|
|
@@ -529,6 +532,15 @@ public final class RegionizedWorldData {
|
|
this.wireHandler = new alternate.current.wire.WireHandler(world);
|
|
this.turbo = new io.papermc.paper.redstone.RedstoneWireTurbo((RedStoneWireBlock)Blocks.REDSTONE_WIRE);
|
|
|
|
+ // Lophine start - Global Entities Counter
|
|
+ if (fun.bm.lophine.config.modules.experiment.GlobalEntitiesCounter.enabled) {
|
|
+ uniqueId = fun.bm.lophine.utils.EntitiesCounterUtil.generateUniqueId();
|
|
+ fun.bm.lophine.utils.EntitiesCounterUtil.reportAreaMap(world, spawnChunkTracker, uniqueId);
|
|
+ fun.bm.lophine.utils.EntitiesCounterUtil.addDataToLoaded(world, loadedEntities, uniqueId);
|
|
+ underGlobalEntitiesCounter = true;
|
|
+ }
|
|
+ // Lophine end - Global Entities Counter
|
|
+
|
|
// tasks may be drained before the region ticks, so we must set up the tick data early just in case
|
|
this.updateTickData();
|
|
}
|
|
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
|
|
index 05bad0366bd36b8134290a0cceb4d4dfcbbd0544..604681c8fda696dcc824b1b36b53c0d8434ec5c2 100644
|
|
--- a/net/minecraft/server/level/ServerChunkCache.java
|
|
+++ b/net/minecraft/server/level/ServerChunkCache.java
|
|
@@ -516,6 +516,25 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
|
this.chunkMap.tick(hasTimeLeft);
|
|
profilerFiller.pop();
|
|
this.clearCache();
|
|
+ // Lophine start - Global Entities Counter
|
|
+ if (fun.bm.lophine.config.modules.experiment.GlobalEntitiesCounter.enabled) {
|
|
+ io.papermc.paper.threadedregions.RegionizedWorldData regionizedWorldData = this.level.getCurrentWorldData();
|
|
+ if (regionizedWorldData != null) {
|
|
+ if (regionizedWorldData.underGlobalEntitiesCounter) {
|
|
+ if (regionizedWorldData.getLocalPlayers().isEmpty()) {
|
|
+ fun.bm.lophine.utils.EntitiesCounterUtil.onWorldDataUnload(level, regionizedWorldData.uniqueId);
|
|
+ regionizedWorldData.underGlobalEntitiesCounter = false;
|
|
+ }
|
|
+ } else {
|
|
+ if (!regionizedWorldData.getLocalPlayers().isEmpty()) {
|
|
+ fun.bm.lophine.utils.EntitiesCounterUtil.reportAreaMap(level, regionizedWorldData.spawnChunkTracker, regionizedWorldData.uniqueId);
|
|
+ fun.bm.lophine.utils.EntitiesCounterUtil.addDataToLoaded(level, (ca.spottedleaf.moonrise.common.list.ReferenceList<Entity>) regionizedWorldData.getLoadedEntities(), regionizedWorldData.uniqueId);
|
|
+ regionizedWorldData.underGlobalEntitiesCounter = true;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ // Lophine end - Global Entities Counter
|
|
}
|
|
|
|
private void tickChunks() {
|
|
@@ -580,7 +599,13 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
|
}
|
|
spawnState = NaturalSpawner.createState(naturalSpawnChunkCount, regionizedWorldData.getLoadedEntities(), this::getFullChunk, null, true); // Folia - region threading - note: function only cares about loaded entities, doesn't need all
|
|
} else {
|
|
+ // Lophine start - Global Entities Counter
|
|
+ if (fun.bm.lophine.config.modules.experiment.GlobalEntitiesCounter.enabled) {
|
|
+ spawnState = fun.bm.lophine.utils.EntitiesCounterUtil.runRemainingTasks(level, regionizedWorldData.getLoadedEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false);
|
|
+ } else {
|
|
spawnState = NaturalSpawner.createState(naturalSpawnChunkCount, regionizedWorldData.getLoadedEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false); // Folia - region threading - note: function only cares about loaded entities, doesn't need all
|
|
+ }
|
|
+ // Lophine end - Global Entities Counter
|
|
}
|
|
} finally { foliaProfiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.MOB_SPAWN_ENTITY_COUNT); } // Folia - profiler
|
|
// Paper end - Optional per player mob spawns
|
|
@@ -589,7 +614,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
|
boolean _boolean = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.getLocalPlayers().isEmpty(); // CraftBukkit // Folia - region threading
|
|
int _int = this.level.getGameRules().getInt(GameRules.RULE_RANDOMTICKING);
|
|
List<MobCategory> filteredSpawningCategories;
|
|
- if (_boolean && (this.spawnEnemies || this.spawnFriendlies)) {
|
|
+ if (spawnState != null && _boolean && (this.spawnEnemies || this.spawnFriendlies)) { // Lophine - Global Entities Counter
|
|
// Paper start - PlayerNaturallySpawnCreaturesEvent
|
|
for (ServerPlayer entityPlayer : this.level.getLocalPlayers()) { // Folia - region threading
|
|
int chunkRange = Math.min(level.spigotConfig.mobSpawnRange, entityPlayer.getBukkitEntity().getViewDistance());
|
|
@@ -646,7 +671,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
|
this.level.tickThunder(chunk);
|
|
}
|
|
|
|
- if (!spawnCategories.isEmpty()) {
|
|
+ if (spawnState != null && !spawnCategories.isEmpty()) { // Lophine - Global Entities Counter
|
|
if (this.level.getWorldBorder().isWithinBounds(pos)) { // Paper - rewrite chunk system
|
|
NaturalSpawner.spawnForChunk(this.level, chunk, spawnState, spawnCategories);
|
|
}
|
|
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
|
index c0ba36849da0983117901f0cd04b2c785df0010b..0b0d9322632ef1a751add633bdcb87ec84f82704 100644
|
|
--- a/net/minecraft/server/level/ServerLevel.java
|
|
+++ b/net/minecraft/server/level/ServerLevel.java
|
|
@@ -729,6 +729,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
|
}
|
|
|
|
public void tick(BooleanSupplier hasTimeLeft, io.papermc.paper.threadedregions.TickRegions.TickRegionData region) { // Folia - regionised ticking
|
|
+ // Lophine start - Global Entities Counter
|
|
+ if (fun.bm.lophine.config.modules.experiment.GlobalEntitiesCounter.enabled) {
|
|
+ if (fun.bm.lophine.utils.EntitiesCounterUtil.canRunNewTask(this)) fun.bm.lophine.utils.EntitiesCounterUtil.tick(this);
|
|
+ }
|
|
+ // Lophine end - Global Entities Counter
|
|
final io.papermc.paper.threadedregions.RegionizedWorldData regionizedWorldData = this.getCurrentWorldData(); // Folia - regionised ticking
|
|
final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler
|
|
ProfilerFiller profilerFiller = Profiler.get();
|
|
diff --git a/net/minecraft/world/level/NaturalSpawner.java b/net/minecraft/world/level/NaturalSpawner.java
|
|
index 81f4707cf1a7cbdfcfc519cfbe1052cde77aa755..5c53e2d61ce8483d5d9e93e9f3112074c704a546 100644
|
|
--- a/net/minecraft/world/level/NaturalSpawner.java
|
|
+++ b/net/minecraft/world/level/NaturalSpawner.java
|
|
@@ -113,7 +113,7 @@ public final class NaturalSpawner {
|
|
return new NaturalSpawner.SpawnState(spawnableChunkCount, map, potentialCalculator, calculator);
|
|
}
|
|
|
|
- static Biome getRoughBiome(BlockPos pos, ChunkAccess chunk) {
|
|
+ public static Biome getRoughBiome(BlockPos pos, ChunkAccess chunk) { // Lophine - protected -> public
|
|
return chunk.getNoiseBiome(QuartPos.fromBlock(pos.getX()), QuartPos.fromBlock(pos.getY()), QuartPos.fromBlock(pos.getZ())).value();
|
|
}
|
|
|
|
@@ -584,7 +584,7 @@ public final class NaturalSpawner {
|
|
private EntityType<?> lastCheckedType;
|
|
private double lastCharge;
|
|
|
|
- SpawnState(
|
|
+ public SpawnState( // Lophine - protected -> public
|
|
int spawnableChunkCount,
|
|
Object2IntOpenHashMap<MobCategory> mobCategoryCounts,
|
|
PotentialCalculator spawnPotential,
|