aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spark-fabric/src/main/java/me/lucko/spark/fabric/FabricWorldInfoProvider.java103
-rw-r--r--spark-fabric/src/main/java/me/lucko/spark/fabric/mixin/WorldAccessor.java35
-rw-r--r--spark-fabric/src/main/resources/spark.mixins.json3
-rw-r--r--spark-forge/src/main/java/me/lucko/spark/forge/ForgeWorldInfoProvider.java55
-rw-r--r--spark-forge/src/main/resources/META-INF/accesstransformer.cfg1
-rw-r--r--spark-neoforge/src/main/java/me/lucko/spark/neoforge/NeoForgeWorldInfoProvider.java100
-rw-r--r--spark-neoforge/src/main/resources/META-INF/accesstransformer.cfg1
7 files changed, 176 insertions, 122 deletions
diff --git a/spark-fabric/src/main/java/me/lucko/spark/fabric/FabricWorldInfoProvider.java b/spark-fabric/src/main/java/me/lucko/spark/fabric/FabricWorldInfoProvider.java
index d7dc7a7..eae9c86 100644
--- a/spark-fabric/src/main/java/me/lucko/spark/fabric/FabricWorldInfoProvider.java
+++ b/spark-fabric/src/main/java/me/lucko/spark/fabric/FabricWorldInfoProvider.java
@@ -20,8 +20,8 @@
package me.lucko.spark.fabric;
-import it.unimi.dsi.fastutil.longs.LongIterator;
-import it.unimi.dsi.fastutil.longs.LongSet;
+import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
+import java.lang.reflect.Method;
import me.lucko.spark.common.platform.world.AbstractChunkInfo;
import me.lucko.spark.common.platform.world.CountMap;
import me.lucko.spark.common.platform.world.WorldInfoProvider;
@@ -29,6 +29,8 @@ import me.lucko.spark.fabric.mixin.ClientEntityManagerAccessor;
import me.lucko.spark.fabric.mixin.ClientWorldAccessor;
import me.lucko.spark.fabric.mixin.ServerEntityManagerAccessor;
import me.lucko.spark.fabric.mixin.ServerWorldAccessor;
+import me.lucko.spark.fabric.mixin.WorldAccessor;
+import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity;
@@ -40,30 +42,13 @@ import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.GameRules;
import net.minecraft.world.entity.ClientEntityManager;
import net.minecraft.world.entity.EntityIndex;
-import net.minecraft.world.entity.EntityTrackingSection;
-import net.minecraft.world.entity.SectionedEntityCache;
+import net.minecraft.world.entity.EntityLookup;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
-import java.util.stream.Stream;
public abstract class FabricWorldInfoProvider implements WorldInfoProvider {
- protected List<FabricChunkInfo> getChunksFromCache(SectionedEntityCache<Entity> cache) {
- LongSet loadedChunks = cache.getChunkPositions();
- List<FabricChunkInfo> list = new ArrayList<>(loadedChunks.size());
-
- for (LongIterator iterator = loadedChunks.iterator(); iterator.hasNext(); ) {
- long chunkPos = iterator.nextLong();
- Stream<EntityTrackingSection<Entity>> sections = cache.getTrackingSections(chunkPos);
-
- list.add(new FabricChunkInfo(chunkPos, sections));
- }
-
- return list;
- }
-
public static final class Server extends FabricWorldInfoProvider {
private final MinecraftServer server;
@@ -78,10 +63,15 @@ public abstract class FabricWorldInfoProvider implements WorldInfoProvider {
int chunks = 0;
for (ServerWorld world : this.server.getWorlds()) {
- ServerEntityManager<Entity> entityManager = ((ServerWorldAccessor) world).getEntityManager();
- EntityIndex<?> entityIndex = ((ServerEntityManagerAccessor) entityManager).getIndex();
- entities += entityIndex.size();
+ if (FabricLoader.getInstance().isModLoaded("moonrise")) {
+ entities += MoonriseMethods.getEntityCount(((WorldAccessor) world).spark$getEntityLookup());
+ } else {
+ ServerEntityManager<Entity> entityManager = ((ServerWorldAccessor) world).getEntityManager();
+ EntityIndex<?> entityIndex = ((ServerEntityManagerAccessor) entityManager).getIndex();
+ entities += entityIndex.size();
+ }
+
chunks += world.getChunkManager().getLoadedChunkCount();
}
@@ -93,11 +83,15 @@ public abstract class FabricWorldInfoProvider implements WorldInfoProvider {
ChunksResult<FabricChunkInfo> data = new ChunksResult<>();
for (ServerWorld world : this.server.getWorlds()) {
- ServerEntityManager<Entity> entityManager = ((ServerWorldAccessor) world).getEntityManager();
- SectionedEntityCache<Entity> cache = ((ServerEntityManagerAccessor) entityManager).getCache();
+ Long2ObjectOpenHashMap<FabricChunkInfo> worldInfos = new Long2ObjectOpenHashMap<>();
+
+ for (Entity entity : ((WorldAccessor) world).spark$getEntityLookup().iterate()) {
+ FabricChunkInfo info = worldInfos.computeIfAbsent(
+ entity.getChunkPos().toLong(), FabricChunkInfo::new);
+ info.entityCounts.increment(entity.getType());
+ }
- List<FabricChunkInfo> list = getChunksFromCache(cache);
- data.put(world.getRegistryKey().getValue().getPath(), list);
+ data.put(world.getRegistryKey().getValue().getPath(), List.copyOf(worldInfos.values()));
}
return data;
@@ -140,10 +134,16 @@ public abstract class FabricWorldInfoProvider implements WorldInfoProvider {
return null;
}
- ClientEntityManager<Entity> entityManager = ((ClientWorldAccessor) world).getEntityManager();
- EntityIndex<?> entityIndex = ((ClientEntityManagerAccessor) entityManager).getIndex();
+ int entities;
+
+ if (FabricLoader.getInstance().isModLoaded("moonrise")) {
+ entities = MoonriseMethods.getEntityCount(((WorldAccessor) world).spark$getEntityLookup());
+ } else {
+ ClientEntityManager<Entity> entityManager = ((ClientWorldAccessor) world).getEntityManager();
+ EntityIndex<?> entityIndex = ((ClientEntityManagerAccessor) entityManager).getIndex();
+ entities = entityIndex.size();
+ }
- int entities = entityIndex.size();
int chunks = world.getChunkManager().getLoadedChunkCount();
return new CountsResult(-1, entities, -1, chunks);
@@ -158,11 +158,14 @@ public abstract class FabricWorldInfoProvider implements WorldInfoProvider {
ChunksResult<FabricChunkInfo> data = new ChunksResult<>();
- ClientEntityManager<Entity> entityManager = ((ClientWorldAccessor) world).getEntityManager();
- SectionedEntityCache<Entity> cache = ((ClientEntityManagerAccessor) entityManager).getCache();
+ Long2ObjectOpenHashMap<FabricChunkInfo> worldInfos = new Long2ObjectOpenHashMap<>();
- List<FabricChunkInfo> list = getChunksFromCache(cache);
- data.put(world.getRegistryKey().getValue().getPath(), list);
+ for (Entity entity : ((WorldAccessor) world).spark$getEntityLookup().iterate()) {
+ FabricChunkInfo info = worldInfos.computeIfAbsent(entity.getChunkPos().toLong(), FabricChunkInfo::new);
+ info.entityCounts.increment(entity.getType());
+ }
+
+ data.put(world.getRegistryKey().getValue().getPath(), List.copyOf(worldInfos.values()));
return data;
}
@@ -197,17 +200,10 @@ public abstract class FabricWorldInfoProvider implements WorldInfoProvider {
static final class FabricChunkInfo extends AbstractChunkInfo<EntityType<?>> {
private final CountMap<EntityType<?>> entityCounts;
- FabricChunkInfo(long chunkPos, Stream<EntityTrackingSection<Entity>> entities) {
+ FabricChunkInfo(long chunkPos) {
super(ChunkPos.getPackedX(chunkPos), ChunkPos.getPackedZ(chunkPos));
this.entityCounts = new CountMap.Simple<>(new HashMap<>());
- entities.forEach(section -> {
- if (section.getStatus().shouldTrack()) {
- section.stream().forEach(entity ->
- this.entityCounts.increment(entity.getType())
- );
- }
- });
}
@Override
@@ -221,5 +217,28 @@ public abstract class FabricWorldInfoProvider implements WorldInfoProvider {
}
}
+ private static final class MoonriseMethods {
+ private static Method getEntityCount;
+
+ private static Method getEntityCountMethod(EntityLookup<Entity> getter) {
+ if (getEntityCount == null) {
+ try {
+ getEntityCount = getter.getClass().getMethod("getEntityCount");
+ } catch (final ReflectiveOperationException e) {
+ throw new RuntimeException("Cannot find Moonrise getEntityCount method", e);
+ }
+ }
+ return getEntityCount;
+ }
+
+ private static int getEntityCount(EntityLookup<Entity> getter) {
+ try {
+ return (int) getEntityCountMethod(getter).invoke(getter);
+ } catch (final ReflectiveOperationException e) {
+ throw new RuntimeException("Failed to invoke Moonrise getEntityCount method", e);
+ }
+ }
+ }
+
}
diff --git a/spark-fabric/src/main/java/me/lucko/spark/fabric/mixin/WorldAccessor.java b/spark-fabric/src/main/java/me/lucko/spark/fabric/mixin/WorldAccessor.java
new file mode 100644
index 0000000..e50dc20
--- /dev/null
+++ b/spark-fabric/src/main/java/me/lucko/spark/fabric/mixin/WorldAccessor.java
@@ -0,0 +1,35 @@
+/*
+ * This file is part of spark.
+ *
+ * Copyright (c) lucko (Luck) <luck@lucko.me>
+ * Copyright (c) contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package me.lucko.spark.fabric.mixin;
+
+import net.minecraft.entity.Entity;
+import net.minecraft.world.World;
+import net.minecraft.world.entity.EntityLookup;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Invoker;
+
+@Mixin(World.class)
+public interface WorldAccessor {
+
+ @Invoker(value = "getEntityLookup")
+ EntityLookup<Entity> spark$getEntityLookup();
+
+}
diff --git a/spark-fabric/src/main/resources/spark.mixins.json b/spark-fabric/src/main/resources/spark.mixins.json
index 27676a6..a8e280c 100644
--- a/spark-fabric/src/main/resources/spark.mixins.json
+++ b/spark-fabric/src/main/resources/spark.mixins.json
@@ -8,7 +8,8 @@
],
"mixins": [
"ServerEntityManagerAccessor",
- "ServerWorldAccessor"
+ "ServerWorldAccessor",
+ "WorldAccessor"
],
"plugin": "me.lucko.spark.fabric.plugin.FabricSparkMixinPlugin"
} \ No newline at end of file
diff --git a/spark-forge/src/main/java/me/lucko/spark/forge/ForgeWorldInfoProvider.java b/spark-forge/src/main/java/me/lucko/spark/forge/ForgeWorldInfoProvider.java
index 286605a..0d1724e 100644
--- a/spark-forge/src/main/java/me/lucko/spark/forge/ForgeWorldInfoProvider.java
+++ b/spark-forge/src/main/java/me/lucko/spark/forge/ForgeWorldInfoProvider.java
@@ -20,8 +20,7 @@
package me.lucko.spark.forge;
-import it.unimi.dsi.fastutil.longs.LongIterator;
-import it.unimi.dsi.fastutil.longs.LongSet;
+import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import me.lucko.spark.common.platform.world.AbstractChunkInfo;
import me.lucko.spark.common.platform.world.CountMap;
import me.lucko.spark.common.platform.world.WorldInfoProvider;
@@ -34,32 +33,14 @@ import net.minecraft.world.entity.EntityType;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.entity.EntityLookup;
-import net.minecraft.world.level.entity.EntitySection;
-import net.minecraft.world.level.entity.EntitySectionStorage;
import net.minecraft.world.level.entity.PersistentEntitySectionManager;
import net.minecraft.world.level.entity.TransientEntitySectionManager;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
-import java.util.stream.Stream;
public abstract class ForgeWorldInfoProvider implements WorldInfoProvider {
- protected List<ForgeChunkInfo> getChunksFromCache(EntitySectionStorage<Entity> cache) {
- LongSet loadedChunks = cache.getAllChunksWithExistingSections();
- List<ForgeChunkInfo> list = new ArrayList<>(loadedChunks.size());
-
- for (LongIterator iterator = loadedChunks.iterator(); iterator.hasNext(); ) {
- long chunkPos = iterator.nextLong();
- Stream<EntitySection<Entity>> sections = cache.getExistingSectionsInChunk(chunkPos);
-
- list.add(new ForgeChunkInfo(chunkPos, sections));
- }
-
- return list;
- }
-
public static final class Server extends ForgeWorldInfoProvider {
private final MinecraftServer server;
@@ -89,11 +70,15 @@ public abstract class ForgeWorldInfoProvider implements WorldInfoProvider {
ChunksResult<ForgeChunkInfo> data = new ChunksResult<>();
for (ServerLevel level : this.server.getAllLevels()) {
- PersistentEntitySectionManager<Entity> entityManager = level.entityManager;
- EntitySectionStorage<Entity> cache = entityManager.sectionStorage;
+ Long2ObjectOpenHashMap<ForgeChunkInfo> levelInfos = new Long2ObjectOpenHashMap<>();
- List<ForgeChunkInfo> list = getChunksFromCache(cache);
- data.put(level.dimension().location().getPath(), list);
+ for (Entity entity : level.getEntities().getAll()) {
+ ForgeChunkInfo info = levelInfos.computeIfAbsent(
+ entity.chunkPosition().toLong(), ForgeChunkInfo::new);
+ info.entityCounts.increment(entity.getType());
+ }
+
+ data.put(level.dimension().location().getPath(), List.copyOf(levelInfos.values()));
}
return data;
@@ -155,11 +140,14 @@ public abstract class ForgeWorldInfoProvider implements WorldInfoProvider {
ChunksResult<ForgeChunkInfo> data = new ChunksResult<>();
- TransientEntitySectionManager<Entity> entityManager = level.entityStorage;
- EntitySectionStorage<Entity> cache = entityManager.sectionStorage;
+ Long2ObjectOpenHashMap<ForgeChunkInfo> levelInfos = new Long2ObjectOpenHashMap<>();
- List<ForgeChunkInfo> list = getChunksFromCache(cache);
- data.put(level.dimension().location().getPath(), list);
+ for (Entity entity : level.getEntities().getAll()) {
+ ForgeChunkInfo info = levelInfos.computeIfAbsent(entity.chunkPosition().toLong(), ForgeChunkInfo::new);
+ info.entityCounts.increment(entity.getType());
+ }
+
+ data.put(level.dimension().location().getPath(), List.copyOf(levelInfos.values()));
return data;
}
@@ -191,20 +179,13 @@ public abstract class ForgeWorldInfoProvider implements WorldInfoProvider {
}
}
- static final class ForgeChunkInfo extends AbstractChunkInfo<EntityType<?>> {
+ public static final class ForgeChunkInfo extends AbstractChunkInfo<EntityType<?>> {
private final CountMap<EntityType<?>> entityCounts;
- ForgeChunkInfo(long chunkPos, Stream<EntitySection<Entity>> entities) {
+ ForgeChunkInfo(long chunkPos) {
super(ChunkPos.getX(chunkPos), ChunkPos.getZ(chunkPos));
this.entityCounts = new CountMap.Simple<>(new HashMap<>());
- entities.forEach(section -> {
- if (section.getStatus().isAccessible()) {
- section.getEntities().forEach(entity ->
- this.entityCounts.increment(entity.getType())
- );
- }
- });
}
@Override
diff --git a/spark-forge/src/main/resources/META-INF/accesstransformer.cfg b/spark-forge/src/main/resources/META-INF/accesstransformer.cfg
index 2699a0e..3772274 100644
--- a/spark-forge/src/main/resources/META-INF/accesstransformer.cfg
+++ b/spark-forge/src/main/resources/META-INF/accesstransformer.cfg
@@ -5,3 +5,4 @@ public net.minecraft.client.multiplayer.ClientLevel f_171631_ # entityStorage
public net.minecraft.world.level.entity.TransientEntitySectionManager f_157638_ # sectionStorage
public net.minecraft.world.level.entity.TransientEntitySectionManager f_157637_ # entityStorage
public net.minecraft.client.Minecraft f_91018_ # gameThread
+public net.minecraft.client.multiplayer.ClientLevel m_142646_()Lnet/minecraft/world/level/entity/LevelEntityGetter; # getEntities
diff --git a/spark-neoforge/src/main/java/me/lucko/spark/neoforge/NeoForgeWorldInfoProvider.java b/spark-neoforge/src/main/java/me/lucko/spark/neoforge/NeoForgeWorldInfoProvider.java
index fe6a6c8..d172ecf 100644
--- a/spark-neoforge/src/main/java/me/lucko/spark/neoforge/NeoForgeWorldInfoProvider.java
+++ b/spark-neoforge/src/main/java/me/lucko/spark/neoforge/NeoForgeWorldInfoProvider.java
@@ -20,8 +20,8 @@
package me.lucko.spark.neoforge;
-import it.unimi.dsi.fastutil.longs.LongIterator;
-import it.unimi.dsi.fastutil.longs.LongSet;
+import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
+import java.lang.reflect.Method;
import me.lucko.spark.common.platform.world.AbstractChunkInfo;
import me.lucko.spark.common.platform.world.CountMap;
import me.lucko.spark.common.platform.world.WorldInfoProvider;
@@ -34,32 +34,16 @@ import net.minecraft.world.entity.EntityType;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.entity.EntityLookup;
-import net.minecraft.world.level.entity.EntitySection;
-import net.minecraft.world.level.entity.EntitySectionStorage;
+import net.minecraft.world.level.entity.LevelEntityGetter;
import net.minecraft.world.level.entity.PersistentEntitySectionManager;
import net.minecraft.world.level.entity.TransientEntitySectionManager;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
-import java.util.stream.Stream;
+import net.neoforged.fml.ModList;
public abstract class NeoForgeWorldInfoProvider implements WorldInfoProvider {
- protected List<ForgeChunkInfo> getChunksFromCache(EntitySectionStorage<Entity> cache) {
- LongSet loadedChunks = cache.getAllChunksWithExistingSections();
- List<ForgeChunkInfo> list = new ArrayList<>(loadedChunks.size());
-
- for (LongIterator iterator = loadedChunks.iterator(); iterator.hasNext(); ) {
- long chunkPos = iterator.nextLong();
- Stream<EntitySection<Entity>> sections = cache.getExistingSectionsInChunk(chunkPos);
-
- list.add(new ForgeChunkInfo(chunkPos, sections));
- }
-
- return list;
- }
-
public static final class Server extends NeoForgeWorldInfoProvider {
private final MinecraftServer server;
@@ -74,10 +58,15 @@ public abstract class NeoForgeWorldInfoProvider implements WorldInfoProvider {
int chunks = 0;
for (ServerLevel level : this.server.getAllLevels()) {
- PersistentEntitySectionManager<Entity> entityManager = level.entityManager;
- EntityLookup<Entity> entityIndex = entityManager.visibleEntityStorage;
- entities += entityIndex.count();
+ if (ModList.get().isLoaded("moonrise")) {
+ entities += MoonriseMethods.getEntityCount(level.getEntities());
+ } else {
+ PersistentEntitySectionManager<Entity> entityManager = level.entityManager;
+ EntityLookup<Entity> entityIndex = entityManager.visibleEntityStorage;
+ entities += entityIndex.count();
+ }
+
chunks += level.getChunkSource().getLoadedChunksCount();
}
@@ -89,11 +78,15 @@ public abstract class NeoForgeWorldInfoProvider implements WorldInfoProvider {
ChunksResult<ForgeChunkInfo> data = new ChunksResult<>();
for (ServerLevel level : this.server.getAllLevels()) {
- PersistentEntitySectionManager<Entity> entityManager = level.entityManager;
- EntitySectionStorage<Entity> cache = entityManager.sectionStorage;
+ Long2ObjectOpenHashMap<ForgeChunkInfo> levelInfos = new Long2ObjectOpenHashMap<>();
+
+ for (Entity entity : level.getEntities().getAll()) {
+ ForgeChunkInfo info = levelInfos.computeIfAbsent(
+ entity.chunkPosition().toLong(), ForgeChunkInfo::new);
+ info.entityCounts.increment(entity.getType());
+ }
- List<ForgeChunkInfo> list = getChunksFromCache(cache);
- data.put(level.dimension().location().getPath(), list);
+ data.put(level.dimension().location().getPath(), List.copyOf(levelInfos.values()));
}
return data;
@@ -137,10 +130,15 @@ public abstract class NeoForgeWorldInfoProvider implements WorldInfoProvider {
return null;
}
- TransientEntitySectionManager<Entity> entityManager = level.entityStorage;
- EntityLookup<Entity> entityIndex = entityManager.entityStorage;
+ int entities;
+ if (ModList.get().isLoaded("moonrise")) {
+ entities = MoonriseMethods.getEntityCount(level.getEntities());
+ } else {
+ TransientEntitySectionManager<Entity> entityManager = level.entityStorage;
+ EntityLookup<Entity> entityIndex = entityManager.entityStorage;
+ entities = entityIndex.count();
+ }
- int entities = entityIndex.count();
int chunks = level.getChunkSource().getLoadedChunksCount();
return new CountsResult(-1, entities, -1, chunks);
@@ -155,11 +153,14 @@ public abstract class NeoForgeWorldInfoProvider implements WorldInfoProvider {
ChunksResult<ForgeChunkInfo> data = new ChunksResult<>();
- TransientEntitySectionManager<Entity> entityManager = level.entityStorage;
- EntitySectionStorage<Entity> cache = entityManager.sectionStorage;
+ Long2ObjectOpenHashMap<ForgeChunkInfo> levelInfos = new Long2ObjectOpenHashMap<>();
- List<ForgeChunkInfo> list = getChunksFromCache(cache);
- data.put(level.dimension().location().getPath(), list);
+ for (Entity entity : level.getEntities().getAll()) {
+ ForgeChunkInfo info = levelInfos.computeIfAbsent(entity.chunkPosition().toLong(), ForgeChunkInfo::new);
+ info.entityCounts.increment(entity.getType());
+ }
+
+ data.put(level.dimension().location().getPath(), List.copyOf(levelInfos.values()));
return data;
}
@@ -194,17 +195,10 @@ public abstract class NeoForgeWorldInfoProvider implements WorldInfoProvider {
public static final class ForgeChunkInfo extends AbstractChunkInfo<EntityType<?>> {
private final CountMap<EntityType<?>> entityCounts;
- ForgeChunkInfo(long chunkPos, Stream<EntitySection<Entity>> entities) {
+ ForgeChunkInfo(long chunkPos) {
super(ChunkPos.getX(chunkPos), ChunkPos.getZ(chunkPos));
this.entityCounts = new CountMap.Simple<>(new HashMap<>());
- entities.forEach(section -> {
- if (section.getStatus().isAccessible()) {
- section.getEntities().forEach(entity ->
- this.entityCounts.increment(entity.getType())
- );
- }
- });
}
@Override
@@ -218,5 +212,27 @@ public abstract class NeoForgeWorldInfoProvider implements WorldInfoProvider {
}
}
+ private static final class MoonriseMethods {
+ private static Method getEntityCount;
+
+ private static Method getEntityCountMethod(LevelEntityGetter<Entity> getter) {
+ if (getEntityCount == null) {
+ try {
+ getEntityCount = getter.getClass().getMethod("getEntityCount");
+ } catch (final ReflectiveOperationException e) {
+ throw new RuntimeException("Cannot find Moonrise getEntityCount method", e);
+ }
+ }
+ return getEntityCount;
+ }
+
+ private static int getEntityCount(LevelEntityGetter<Entity> getter) {
+ try {
+ return (int) getEntityCountMethod(getter).invoke(getter);
+ } catch (final ReflectiveOperationException e) {
+ throw new RuntimeException("Failed to invoke Moonrise getEntityCount method", e);
+ }
+ }
+ }
}
diff --git a/spark-neoforge/src/main/resources/META-INF/accesstransformer.cfg b/spark-neoforge/src/main/resources/META-INF/accesstransformer.cfg
index 43d14fc..80f3f6e 100644
--- a/spark-neoforge/src/main/resources/META-INF/accesstransformer.cfg
+++ b/spark-neoforge/src/main/resources/META-INF/accesstransformer.cfg
@@ -2,6 +2,7 @@ public net.minecraft.server.level.ServerLevel entityManager # entityManager
public net.minecraft.world.level.entity.PersistentEntitySectionManager sectionStorage # sectionStorage
public net.minecraft.world.level.entity.PersistentEntitySectionManager visibleEntityStorage # visibleEntityStorage
public net.minecraft.client.multiplayer.ClientLevel entityStorage # entityStorage
+public net.minecraft.client.multiplayer.ClientLevel getEntities()Lnet/minecraft/world/level/entity/LevelEntityGetter; # getEntities
public net.minecraft.world.level.entity.TransientEntitySectionManager sectionStorage # sectionStorage
public net.minecraft.world.level.entity.TransientEntitySectionManager entityStorage # entityStorage
public net.minecraft.client.Minecraft gameThread # gameThread