From 04af46d580afa80c965c0ecc867e701c9ca7eae0 Mon Sep 17 00:00:00 2001 From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> Date: Sun, 9 Nov 2025 21:40:41 +1400 Subject: [PATCH 1/8] Fix architectury compatibility on NeoForge --- build.gradle.kts | 3 +++ fabric/build.gradle.kts | 3 +++ .../moonrise/fabric/FabricHooks.java | 5 ++++- gradle.properties | 1 + neoforge/build.gradle.kts | 3 +++ .../moonrise/neoforge/NeoForgeHooks.java | 4 ++++ .../architectury/ArchitecturyHooks.java | 19 +++++++++++++++++++ .../resources/workaround_shadow_2 | 0 .../common/util/BaseChunkSystemHooks.java | 1 + .../mixin/chunk_system/ChunkMapMixin.java | 5 +++-- 10 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 src/architectury/java/ca/spottedleaf/moonrise/compat/architectury/ArchitecturyHooks.java create mode 100644 src/architectury/resources/workaround_shadow_2 diff --git a/build.gradle.kts b/build.gradle.kts index e83fbe1e..b8b1e813 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,12 +14,14 @@ val aw2at = Aw2AtTask.configureDefault( ) sourceSets.create("lithium") +sourceSets.create("architectury") neoForge { neoFormVersion = libs.versions.neoform.get() validateAccessTransformers = true accessTransformers.files.setFrom(aw2at.flatMap { t -> t.outputFile }) addModdingDependenciesTo(sourceSets.getByName("lithium")) + addModdingDependenciesTo(sourceSets.getByName("architectury")) } dependencies { @@ -36,6 +38,7 @@ dependencies { compileOnly(libs.clothConfig.neoforge) "lithiumCompileOnly"("maven.modrinth:lithium:${rootProject.property("neo_lithium_version")}") + "architecturyCompileOnly"("maven.modrinth:architectury-api:${rootProject.property("neo_architectury_version")}") compileOnly(sourceSets.getByName("lithium").output) } diff --git a/fabric/build.gradle.kts b/fabric/build.gradle.kts index 02d59621..a59d3b95 100644 --- a/fabric/build.gradle.kts +++ b/fabric/build.gradle.kts @@ -24,8 +24,10 @@ dependencies { runtimeOnly(rootProject.sourceSets.main.get().output) runtimeOnly(rootProject.sourceSets.getByName("lithium").output) + runtimeOnly(rootProject.sourceSets.getByName("architectury").output) shadow(project(":")) shadow(rootProject.sourceSets.getByName("lithium").output) + shadow(rootProject.sourceSets.getByName("architectury").output) compileOnly(project(":")) libs(libs.concurrentutil) { isTransitive = false } @@ -111,6 +113,7 @@ loom { sourceSet("main") sourceSet("main", project.rootProject) sourceSet("lithium", project.rootProject) + sourceSet("architectury", project.rootProject) } } } diff --git a/fabric/src/main/java/ca/spottedleaf/moonrise/fabric/FabricHooks.java b/fabric/src/main/java/ca/spottedleaf/moonrise/fabric/FabricHooks.java index a39e8f4d..40f0f923 100644 --- a/fabric/src/main/java/ca/spottedleaf/moonrise/fabric/FabricHooks.java +++ b/fabric/src/main/java/ca/spottedleaf/moonrise/fabric/FabricHooks.java @@ -3,6 +3,7 @@ import ca.spottedleaf.moonrise.common.util.BaseChunkSystemHooks; import ca.spottedleaf.moonrise.common.PlatformHooks; import ca.spottedleaf.moonrise.common.util.ConfigHolder; +import ca.spottedleaf.moonrise.compat.architectury.ArchitecturyHooks; import ca.spottedleaf.moonrise.patches.chunk_system.ticket.ChunkSystemTicketType; import com.mojang.datafixers.DSL; import com.mojang.datafixers.DataFixer; @@ -112,7 +113,9 @@ public void chunkUnloadFromWorld(final LevelChunk chunk) { @Override public void chunkSyncSave(final ServerLevel world, final ChunkAccess chunk, final SerializableChunkData data) { - + if (this.hasArchitectury) { + ArchitecturyHooks.onSaveEvent(chunk, world, data); + } } @Override diff --git a/gradle.properties b/gradle.properties index 83d44832..efb96911 100644 --- a/gradle.properties +++ b/gradle.properties @@ -24,3 +24,4 @@ junit_version=5.11.3 # version ids from modrinth fabric_lithium_version=iMuOZwcu neo_lithium_version=LGakFQ7r +neo_architectury_version=baQ6rP1K diff --git a/neoforge/build.gradle.kts b/neoforge/build.gradle.kts index 546299ff..60eb45c7 100644 --- a/neoforge/build.gradle.kts +++ b/neoforge/build.gradle.kts @@ -23,6 +23,7 @@ neoForge { sourceSet(sourceSets.main.get()) sourceSet(rootProject.sourceSets.main.get()) sourceSet(rootProject.sourceSets.getByName("lithium")) + sourceSet(rootProject.sourceSets.getByName("architectury")) } } runs { @@ -44,8 +45,10 @@ val gui = rootProject.property("enable_gui").toString() == "true" dependencies { runtimeOnly(rootProject.sourceSets.main.get().output) runtimeOnly(rootProject.sourceSets.getByName("lithium").output) + runtimeOnly(rootProject.sourceSets.getByName("architectury").output) shadow(project(":")) shadow(rootProject.sourceSets.getByName("lithium").output) + shadow(rootProject.sourceSets.getByName("architectury").output) compileOnly(project(":")) libs(libs.concurrentutil) { isTransitive = false } diff --git a/neoforge/src/main/java/ca/spottedleaf/moonrise/neoforge/NeoForgeHooks.java b/neoforge/src/main/java/ca/spottedleaf/moonrise/neoforge/NeoForgeHooks.java index 25ba677e..0b096fc2 100644 --- a/neoforge/src/main/java/ca/spottedleaf/moonrise/neoforge/NeoForgeHooks.java +++ b/neoforge/src/main/java/ca/spottedleaf/moonrise/neoforge/NeoForgeHooks.java @@ -4,6 +4,7 @@ import ca.spottedleaf.moonrise.common.PlatformHooks; import ca.spottedleaf.moonrise.common.util.ConfigHolder; import ca.spottedleaf.moonrise.common.util.CoordinateUtils; +import ca.spottedleaf.moonrise.compat.architectury.ArchitecturyHooks; import ca.spottedleaf.moonrise.patches.chunk_system.ticket.ChunkSystemTicketType; import com.mojang.datafixers.DSL; import com.mojang.datafixers.DataFixer; @@ -122,6 +123,9 @@ public void chunkUnloadFromWorld(final LevelChunk chunk) { @Override public void chunkSyncSave(final ServerLevel world, final ChunkAccess chunk, final SerializableChunkData data) { NeoForge.EVENT_BUS.post(new ChunkDataEvent.Save(chunk, world, data)); + if (this.hasArchitectury) { + ArchitecturyHooks.onSaveEvent(chunk, world, data); + } } @Override diff --git a/src/architectury/java/ca/spottedleaf/moonrise/compat/architectury/ArchitecturyHooks.java b/src/architectury/java/ca/spottedleaf/moonrise/compat/architectury/ArchitecturyHooks.java new file mode 100644 index 00000000..2fe5500b --- /dev/null +++ b/src/architectury/java/ca/spottedleaf/moonrise/compat/architectury/ArchitecturyHooks.java @@ -0,0 +1,19 @@ +package ca.spottedleaf.moonrise.compat.architectury; + +import dev.architectury.event.events.common.ChunkEvent; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.storage.SerializableChunkData; + +public final class ArchitecturyHooks { + /** + * Invokes Architectury's ChunkEvent.SAVE_DATA event. + * + * @param chunkAccess The chunk that is saved. + * @param level The level the chunk is in. + * @param data The data. + */ + public static void onSaveEvent(ChunkAccess chunkAccess, ServerLevel level, SerializableChunkData data) { + ChunkEvent.SAVE_DATA.invoker().save(chunkAccess, level, data); + } +} diff --git a/src/architectury/resources/workaround_shadow_2 b/src/architectury/resources/workaround_shadow_2 new file mode 100644 index 00000000..e69de29b diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/BaseChunkSystemHooks.java b/src/main/java/ca/spottedleaf/moonrise/common/util/BaseChunkSystemHooks.java index 71f5a202..1b08558b 100644 --- a/src/main/java/ca/spottedleaf/moonrise/common/util/BaseChunkSystemHooks.java +++ b/src/main/java/ca/spottedleaf/moonrise/common/util/BaseChunkSystemHooks.java @@ -21,6 +21,7 @@ public abstract class BaseChunkSystemHooks implements ChunkSystemHooks { private final boolean hasLithium = ((PlatformHooks) this).isModLoaded("lithium"); + protected final boolean hasArchitectury = ((PlatformHooks) this).isModLoaded("architectury"); @Override public void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run) { diff --git a/src/main/java/ca/spottedleaf/moonrise/mixin/chunk_system/ChunkMapMixin.java b/src/main/java/ca/spottedleaf/moonrise/mixin/chunk_system/ChunkMapMixin.java index c6007cd5..47e9977f 100644 --- a/src/main/java/ca/spottedleaf/moonrise/mixin/chunk_system/ChunkMapMixin.java +++ b/src/main/java/ca/spottedleaf/moonrise/mixin/chunk_system/ChunkMapMixin.java @@ -55,6 +55,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.io.IOException; import java.io.Writer; import java.nio.file.Path; @@ -480,8 +481,8 @@ public boolean saveChunkIfNeeded(final ChunkHolder chunkHolder, final long time) * @author Spottedleaf * @see NewChunkHolder#save(boolean) */ - @Overwrite - public boolean save(final ChunkAccess chunk) { + @Inject(method = "save", at = @At("HEAD")) + public void save(ChunkAccess chunk, CallbackInfoReturnable cir) { throw new UnsupportedOperationException(); } From 0926d8f6742227c047ca429e9b7770269f73e243 Mon Sep 17 00:00:00 2001 From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> Date: Sun, 9 Nov 2025 22:10:47 +1400 Subject: [PATCH 2/8] Remove architectury neoforge hook --- .../java/ca/spottedleaf/moonrise/neoforge/NeoForgeHooks.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/neoforge/src/main/java/ca/spottedleaf/moonrise/neoforge/NeoForgeHooks.java b/neoforge/src/main/java/ca/spottedleaf/moonrise/neoforge/NeoForgeHooks.java index 0b096fc2..25ba677e 100644 --- a/neoforge/src/main/java/ca/spottedleaf/moonrise/neoforge/NeoForgeHooks.java +++ b/neoforge/src/main/java/ca/spottedleaf/moonrise/neoforge/NeoForgeHooks.java @@ -4,7 +4,6 @@ import ca.spottedleaf.moonrise.common.PlatformHooks; import ca.spottedleaf.moonrise.common.util.ConfigHolder; import ca.spottedleaf.moonrise.common.util.CoordinateUtils; -import ca.spottedleaf.moonrise.compat.architectury.ArchitecturyHooks; import ca.spottedleaf.moonrise.patches.chunk_system.ticket.ChunkSystemTicketType; import com.mojang.datafixers.DSL; import com.mojang.datafixers.DataFixer; @@ -123,9 +122,6 @@ public void chunkUnloadFromWorld(final LevelChunk chunk) { @Override public void chunkSyncSave(final ServerLevel world, final ChunkAccess chunk, final SerializableChunkData data) { NeoForge.EVENT_BUS.post(new ChunkDataEvent.Save(chunk, world, data)); - if (this.hasArchitectury) { - ArchitecturyHooks.onSaveEvent(chunk, world, data); - } } @Override From 843788fb2c0d84848990120794b9c68d5e069afa Mon Sep 17 00:00:00 2001 From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> Date: Sun, 9 Nov 2025 23:28:35 +1400 Subject: [PATCH 3/8] Fix Fabric Architectury compatibility Now can run Architectury with Moonrise on Fabric --- .../moonrise/fabric/FabricHooks.java | 11 +- .../moonrise/neoforge/NeoForgeHooks.java | 5 + ...gePersistentEntitySectionManagerMixin.java | 27 ++ .../resources/moonrise-neoforge.mixins.json | 1 + .../architectury/ArchitecturyHooks.java | 6 + .../moonrise/common/PlatformHooks.java | 2 + .../common/util/BaseChunkSystemHooks.java | 1 - .../PersistentEntitySectionManagerMixin.java | 304 ++++++++++++++++++ .../mixin/chunk_system/ServerLevelMixin.java | 2 +- .../level/entity/EntityLookup.java | 8 + src/main/resources/moonrise.mixins.json | 1 + 11 files changed, 365 insertions(+), 3 deletions(-) create mode 100644 neoforge/src/main/java/ca/spottedleaf/moonrise/neoforge/mixin/chunk_system/NeoForgePersistentEntitySectionManagerMixin.java create mode 100644 src/main/java/ca/spottedleaf/moonrise/mixin/chunk_system/PersistentEntitySectionManagerMixin.java diff --git a/fabric/src/main/java/ca/spottedleaf/moonrise/fabric/FabricHooks.java b/fabric/src/main/java/ca/spottedleaf/moonrise/fabric/FabricHooks.java index 40f0f923..0381a10d 100644 --- a/fabric/src/main/java/ca/spottedleaf/moonrise/fabric/FabricHooks.java +++ b/fabric/src/main/java/ca/spottedleaf/moonrise/fabric/FabricHooks.java @@ -44,6 +44,7 @@ public final class FabricHooks extends BaseChunkSystemHooks implements PlatformHooks { private static final boolean HAS_FABRIC_LIFECYCLE_EVENTS = FabricLoader.getInstance().isModLoaded("fabric-lifecycle-events-v1"); + public static final boolean HAS_ARCHITECTURY = FabricLoader.getInstance().isModLoaded("architectury"); private static final Logger LOGGER = LogUtils.getLogger(); @@ -113,7 +114,7 @@ public void chunkUnloadFromWorld(final LevelChunk chunk) { @Override public void chunkSyncSave(final ServerLevel world, final ChunkAccess chunk, final SerializableChunkData data) { - if (this.hasArchitectury) { + if (HAS_ARCHITECTURY) { ArchitecturyHooks.onSaveEvent(chunk, world, data); } } @@ -143,6 +144,14 @@ public void addToGetEntities(final Level world, final Entity entity, final AABB } } + @Override + public boolean onAddEntity(final ServerLevel world, final Entity entity) { + if (HAS_ARCHITECTURY) { + return ArchitecturyHooks.onEntityAdd(entity, world); + } + return true; + } + @Override public void addToGetEntities(final Level world, final EntityTypeTest entityTypeTest, final AABB boundingBox, final Predicate predicate, final List into, final int maxCount) { diff --git a/neoforge/src/main/java/ca/spottedleaf/moonrise/neoforge/NeoForgeHooks.java b/neoforge/src/main/java/ca/spottedleaf/moonrise/neoforge/NeoForgeHooks.java index 25ba677e..54647f19 100644 --- a/neoforge/src/main/java/ca/spottedleaf/moonrise/neoforge/NeoForgeHooks.java +++ b/neoforge/src/main/java/ca/spottedleaf/moonrise/neoforge/NeoForgeHooks.java @@ -149,6 +149,11 @@ public void addToGetEntities(final Level world, final Entity entity, final AABB } } + @Override + public boolean onAddEntity(final ServerLevel world, final Entity entity) { + return true; + } + @Override public void addToGetEntities(final Level world, final EntityTypeTest entityTypeTest, final AABB boundingBox, final Predicate predicate, final List into, final int maxCount) { diff --git a/neoforge/src/main/java/ca/spottedleaf/moonrise/neoforge/mixin/chunk_system/NeoForgePersistentEntitySectionManagerMixin.java b/neoforge/src/main/java/ca/spottedleaf/moonrise/neoforge/mixin/chunk_system/NeoForgePersistentEntitySectionManagerMixin.java new file mode 100644 index 00000000..16f4dbe4 --- /dev/null +++ b/neoforge/src/main/java/ca/spottedleaf/moonrise/neoforge/mixin/chunk_system/NeoForgePersistentEntitySectionManagerMixin.java @@ -0,0 +1,27 @@ +package ca.spottedleaf.moonrise.neoforge.mixin.chunk_system; + +import net.minecraft.world.level.entity.EntityAccess; +import net.minecraft.world.level.entity.PersistentEntitySectionManager; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(PersistentEntitySectionManager.class) +abstract class NeoForgePersistentEntitySectionManagerMixin { + @Inject( + method = "addNewEntityWithoutEvent", + at = @At("HEAD") + ) + private void addNewEntityWithoutEvent(T entity, CallbackInfoReturnable cir) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "addEntityWithoutEvent", + at = @At("HEAD") + ) + private void addEntityWithoutEvent(T entity, boolean worldGenSpawned, CallbackInfoReturnable cir) { + throw new UnsupportedOperationException(); + } +} diff --git a/neoforge/src/main/resources/moonrise-neoforge.mixins.json b/neoforge/src/main/resources/moonrise-neoforge.mixins.json index 33d90907..940a3f9c 100644 --- a/neoforge/src/main/resources/moonrise-neoforge.mixins.json +++ b/neoforge/src/main/resources/moonrise-neoforge.mixins.json @@ -3,6 +3,7 @@ "package": "ca.spottedleaf.moonrise.neoforge.mixin", "mixins": [ "chunk_system.NeoForgeMinecraftServerMixin", + "chunk_system.NeoForgePersistentEntitySectionManagerMixin", "chunk_system.NeoForgeServerLevelMixin", "chunk_system.NeoForgeTicketStorageMixin", "collisions.EntityMixin", diff --git a/src/architectury/java/ca/spottedleaf/moonrise/compat/architectury/ArchitecturyHooks.java b/src/architectury/java/ca/spottedleaf/moonrise/compat/architectury/ArchitecturyHooks.java index 2fe5500b..a515a857 100644 --- a/src/architectury/java/ca/spottedleaf/moonrise/compat/architectury/ArchitecturyHooks.java +++ b/src/architectury/java/ca/spottedleaf/moonrise/compat/architectury/ArchitecturyHooks.java @@ -1,7 +1,9 @@ package ca.spottedleaf.moonrise.compat.architectury; import dev.architectury.event.events.common.ChunkEvent; +import dev.architectury.event.events.common.EntityEvent; import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.storage.SerializableChunkData; @@ -16,4 +18,8 @@ public final class ArchitecturyHooks { public static void onSaveEvent(ChunkAccess chunkAccess, ServerLevel level, SerializableChunkData data) { ChunkEvent.SAVE_DATA.invoker().save(chunkAccess, level, data); } + + public static boolean onEntityAdd(Entity entity, ServerLevel level) { + return !EntityEvent.ADD.invoker().add(entity, level).isFalse(); + } } diff --git a/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java index ea9fbb1b..7990a541 100644 --- a/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java +++ b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java @@ -62,6 +62,8 @@ public default boolean isModLoaded(final String modId) { public void addToGetEntities(final Level world, final Entity entity, final AABB boundingBox, final Predicate predicate, final List into); + public boolean onAddEntity(final ServerLevel world, final Entity entity); + public void addToGetEntities(final Level world, final EntityTypeTest entityTypeTest, final AABB boundingBox, final Predicate predicate, final List into, final int maxCount); diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/BaseChunkSystemHooks.java b/src/main/java/ca/spottedleaf/moonrise/common/util/BaseChunkSystemHooks.java index 1b08558b..71f5a202 100644 --- a/src/main/java/ca/spottedleaf/moonrise/common/util/BaseChunkSystemHooks.java +++ b/src/main/java/ca/spottedleaf/moonrise/common/util/BaseChunkSystemHooks.java @@ -21,7 +21,6 @@ public abstract class BaseChunkSystemHooks implements ChunkSystemHooks { private final boolean hasLithium = ((PlatformHooks) this).isModLoaded("lithium"); - protected final boolean hasArchitectury = ((PlatformHooks) this).isModLoaded("architectury"); @Override public void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run) { diff --git a/src/main/java/ca/spottedleaf/moonrise/mixin/chunk_system/PersistentEntitySectionManagerMixin.java b/src/main/java/ca/spottedleaf/moonrise/mixin/chunk_system/PersistentEntitySectionManagerMixin.java new file mode 100644 index 00000000..83b5786e --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/mixin/chunk_system/PersistentEntitySectionManagerMixin.java @@ -0,0 +1,304 @@ +package ca.spottedleaf.moonrise.mixin.chunk_system; + +import it.unimi.dsi.fastutil.longs.LongSet; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.FullChunkStatus; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.entity.*; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import java.io.IOException; +import java.io.Writer; +import java.util.UUID; +import java.util.function.Consumer; +import java.util.stream.Stream; + +@Mixin(PersistentEntitySectionManager.class) +abstract class PersistentEntitySectionManagerMixin { + @Mutable @Final @Shadow EntitySectionStorage sectionStorage; + @Inject( + method = "", + at = @At("RETURN") + ) + private void destroyFields(final CallbackInfo ci) { + this.sectionStorage = null; + } + @Inject( + method = "addNewEntity", + at = @At("HEAD") + ) + private void addNewEntity(T access, CallbackInfoReturnable cir) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "addEntity", + at = @At("HEAD") + ) + private void addEntity(T access, boolean worldGenSpawned, CallbackInfoReturnable cir) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "removeSectionIfEmpty", + at = @At("HEAD") + ) + private void removeSectionIfEmpty(long sectionKey, EntitySection section, CallbackInfo ci) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "addEntityUuid", + at = @At("HEAD") + ) + private void addEntityUuid(T access, CallbackInfoReturnable cir) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "getEffectiveStatus", + at = @At("HEAD") + ) + private static void getEffectiveStatus(T entity, Visibility visibility, CallbackInfoReturnable cir) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "isTicking", + at = @At("HEAD") + ) + private void isTicking(ChunkPos chunkPos, CallbackInfoReturnable cir) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "addLegacyChunkEntities", + at = @At("HEAD") + ) + private void addLegacyChunkEntities(Stream entities, CallbackInfo ci) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "addWorldGenChunkEntities", + at = @At("HEAD") + ) + private void addWorldGenChunkEntities(Stream entities, CallbackInfo ci) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "startTicking", + at = @At("HEAD") + ) + private void startTicking(T entity, CallbackInfo ci) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "stopTicking", + at = @At("HEAD") + ) + private void stopTicking(T entity, CallbackInfo ci) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "startTracking", + at = @At("HEAD") + ) + private void startTracking(T entity, CallbackInfo ci) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "stopTracking", + at = @At("HEAD") + ) + private void stopTracking(T entity, CallbackInfo ci) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "updateChunkStatus(Lnet/minecraft/world/level/ChunkPos;Lnet/minecraft/world/level/entity/Visibility;)V", + at = @At("HEAD") + ) + private void updateChunkStatus(ChunkPos chunkPos, Visibility visibility, CallbackInfo ci) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "updateChunkStatus(Lnet/minecraft/world/level/ChunkPos;Lnet/minecraft/server/level/FullChunkStatus;)V", + at = @At("HEAD") + ) + private void updateChunkStatus(ChunkPos chunkPos, FullChunkStatus status, CallbackInfo ci) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "ensureChunkQueuedForLoad", + at = @At("HEAD") + ) + private void ensureChunkQueuedForLoad(long chunkPosValue, CallbackInfo ci) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "storeChunkSections", + at = @At("HEAD") + ) + private void storeChunkSections(long chunkPosValue, Consumer entityAction, CallbackInfoReturnable cir) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "requestChunkLoad", + at = @At("HEAD") + ) + private void requestChunkLoad(long chunkPosValue, CallbackInfo ci) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "processChunkUnload", + at = @At("HEAD") + ) + private void processChunkUnload(long chunkPosValue, CallbackInfoReturnable cir) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "unloadEntity", + at = @At("HEAD") + ) + private void unloadEntity(T entity, CallbackInfo ci) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "processUnloads", + at = @At("HEAD") + ) + private void processUnloads(CallbackInfo ci) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "processPendingLoads", + at = @At("HEAD") + ) + private void processPendingLoads(CallbackInfo ci) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "tick", + at = @At("HEAD") + ) + private void tick(CallbackInfo ci) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "getAllChunksToSave", + at = @At("HEAD") + ) + private void getAllChunksToSave(CallbackInfoReturnable cir) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "autoSave", + at = @At("HEAD") + ) + private void autoSave(CallbackInfo ci) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "saveAll", + at = @At("HEAD") + ) + private void saveAll(CallbackInfo ci) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "close", + at = @At("HEAD") + ) + private void close(CallbackInfo ci) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "isLoaded", + at = @At("HEAD") + ) + private void isLoaded(UUID uuid, CallbackInfoReturnable cir) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "getEntityGetter", + at = @At("HEAD") + ) + public void getEntityGetter(CallbackInfoReturnable> cir) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "canPositionTick(Lnet/minecraft/core/BlockPos;)Z", + at = @At("HEAD") + ) + public void canPositionTick(BlockPos pos, CallbackInfoReturnable cir) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "canPositionTick(Lnet/minecraft/world/level/ChunkPos;)Z", + at = @At("HEAD") + ) + public void canPositionTick(ChunkPos chunkPos, CallbackInfoReturnable cir) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "areEntitiesLoaded(J)Z", + at = @At("HEAD") + ) + public void areEntitiesLoaded(long chunkPos, CallbackInfoReturnable cir) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "dumpSections", + at = @At("HEAD") + ) + public void dumpSections(Writer writer, CallbackInfo ci) throws IOException { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "gatherStats", + at = @At("HEAD") + ) + public void gatherStats(CallbackInfoReturnable cir) { + throw new UnsupportedOperationException(); + } + + @Inject( + method = "count", + at = @At("HEAD") + ) + public void count(CallbackInfoReturnable cir) { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/ca/spottedleaf/moonrise/mixin/chunk_system/ServerLevelMixin.java b/src/main/java/ca/spottedleaf/moonrise/mixin/chunk_system/ServerLevelMixin.java index c27e8728..44b8d67f 100644 --- a/src/main/java/ca/spottedleaf/moonrise/mixin/chunk_system/ServerLevelMixin.java +++ b/src/main/java/ca/spottedleaf/moonrise/mixin/chunk_system/ServerLevelMixin.java @@ -141,7 +141,7 @@ private void init(MinecraftServer minecraftServer, Executor executor, ResourceKey resourceKey, LevelStem levelStem, boolean bl, long l, List list, boolean bl2, RandomSequences randomSequences, CallbackInfo ci) { - this.entityManager = null; + //this.entityManager = null; // Keep entityManager non-null, architectury needs it this.moonrise$setEntityLookup(new ServerEntityLookup((ServerLevel)(Object)this, ((ServerLevel)(Object)this).new EntityCallbacks())); this.chunkTaskScheduler = new ChunkTaskScheduler((ServerLevel)(Object)this); diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java index 2516a5b6..1e136a38 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java @@ -2,12 +2,14 @@ import ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable; import ca.spottedleaf.concurrentutil.map.SWMRLong2ObjectHashTable; +import ca.spottedleaf.moonrise.common.PlatformHooks; import ca.spottedleaf.moonrise.common.list.EntityList; import ca.spottedleaf.moonrise.common.util.CoordinateUtils; import ca.spottedleaf.moonrise.common.util.WorldUtil; import ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity; import net.minecraft.core.BlockPos; import net.minecraft.server.level.FullChunkStatus; +import net.minecraft.server.level.ServerLevel; import net.minecraft.util.AbortableIterationConsumer; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; @@ -436,6 +438,12 @@ protected boolean addEntity(final Entity entity, final boolean fromDisk, final b return false; } + if (this.world instanceof ServerLevel serverLevel) { + if (!PlatformHooks.get().onAddEntity(serverLevel, entity)) { + return false; + } + } + ((ChunkSystemEntity)entity).moonrise$setSectionX(sectionX); ((ChunkSystemEntity)entity).moonrise$setSectionY(sectionY); ((ChunkSystemEntity)entity).moonrise$setSectionZ(sectionZ); diff --git a/src/main/resources/moonrise.mixins.json b/src/main/resources/moonrise.mixins.json index 5065353e..932ea4d1 100644 --- a/src/main/resources/moonrise.mixins.json +++ b/src/main/resources/moonrise.mixins.json @@ -38,6 +38,7 @@ "chunk_system.LevelReaderMixin", "chunk_system.MinecraftServerMixin", "chunk_system.NoiseBasedChunkGeneratorMixin", + "chunk_system.PersistentEntitySectionManagerMixin", "chunk_system.PlayerListMixin", "chunk_system.PlayerSpawnFinderMixin", "chunk_system.PoiManagerMixin", From e06fc469618b1774b27ae5ddfc130406a0484428 Mon Sep 17 00:00:00 2001 From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> Date: Tue, 11 Nov 2025 03:31:16 +1400 Subject: [PATCH 4/8] Make PersistentEntitySectionManager completely noop --- .../chunk_system/PersistentEntitySectionManagerMixin.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/ca/spottedleaf/moonrise/mixin/chunk_system/PersistentEntitySectionManagerMixin.java b/src/main/java/ca/spottedleaf/moonrise/mixin/chunk_system/PersistentEntitySectionManagerMixin.java index 83b5786e..ddcd609c 100644 --- a/src/main/java/ca/spottedleaf/moonrise/mixin/chunk_system/PersistentEntitySectionManagerMixin.java +++ b/src/main/java/ca/spottedleaf/moonrise/mixin/chunk_system/PersistentEntitySectionManagerMixin.java @@ -11,7 +11,6 @@ import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.io.IOException; @@ -23,12 +22,15 @@ @Mixin(PersistentEntitySectionManager.class) abstract class PersistentEntitySectionManagerMixin { @Mutable @Final @Shadow EntitySectionStorage sectionStorage; + @Mutable @Shadow @Final private LevelEntityGetter entityGetter; + @Inject( method = "", at = @At("RETURN") ) private void destroyFields(final CallbackInfo ci) { this.sectionStorage = null; + this.entityGetter = null; } @Inject( method = "addNewEntity", From 88430baf544dd2da53effc1b4799909817b5d637 Mon Sep 17 00:00:00 2001 From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> Date: Tue, 11 Nov 2025 03:33:02 +1400 Subject: [PATCH 5/8] [ci skip] add missing javadoc for ArchitecturyHooks --- .../moonrise/compat/architectury/ArchitecturyHooks.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/architectury/java/ca/spottedleaf/moonrise/compat/architectury/ArchitecturyHooks.java b/src/architectury/java/ca/spottedleaf/moonrise/compat/architectury/ArchitecturyHooks.java index a515a857..af4b755d 100644 --- a/src/architectury/java/ca/spottedleaf/moonrise/compat/architectury/ArchitecturyHooks.java +++ b/src/architectury/java/ca/spottedleaf/moonrise/compat/architectury/ArchitecturyHooks.java @@ -19,6 +19,13 @@ public static void onSaveEvent(ChunkAccess chunkAccess, ServerLevel level, Seria ChunkEvent.SAVE_DATA.invoker().save(chunkAccess, level, data); } + /** + * Invokes Architectury's EntityEvent.ADD event. + * + * @param entity The entity that is added. + * @param level The level the entity is in. + * @return Whether the entity should be added. + */ public static boolean onEntityAdd(Entity entity, ServerLevel level) { return !EntityEvent.ADD.invoker().add(entity, level).isFalse(); } From a050a2e4449efb193fe93b18d1b997b1600da6e9 Mon Sep 17 00:00:00 2001 From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> Date: Tue, 11 Nov 2025 04:11:37 +1400 Subject: [PATCH 6/8] Destroy all fields --- .../PersistentEntitySectionManagerMixin.java | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/main/java/ca/spottedleaf/moonrise/mixin/chunk_system/PersistentEntitySectionManagerMixin.java b/src/main/java/ca/spottedleaf/moonrise/mixin/chunk_system/PersistentEntitySectionManagerMixin.java index ddcd609c..639d8484 100644 --- a/src/main/java/ca/spottedleaf/moonrise/mixin/chunk_system/PersistentEntitySectionManagerMixin.java +++ b/src/main/java/ca/spottedleaf/moonrise/mixin/chunk_system/PersistentEntitySectionManagerMixin.java @@ -1,5 +1,6 @@ package ca.spottedleaf.moonrise.mixin.chunk_system; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.LongSet; import net.minecraft.core.BlockPos; import net.minecraft.server.level.FullChunkStatus; @@ -13,16 +14,26 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import java.io.IOException; + import java.io.Writer; +import java.util.Queue; +import java.util.Set; import java.util.UUID; import java.util.function.Consumer; import java.util.stream.Stream; @Mixin(PersistentEntitySectionManager.class) abstract class PersistentEntitySectionManagerMixin { - @Mutable @Final @Shadow EntitySectionStorage sectionStorage; + @Mutable @Shadow @Final EntitySectionStorage sectionStorage; @Mutable @Shadow @Final private LevelEntityGetter entityGetter; + @Mutable @Shadow @Final LevelCallback callbacks; + @Mutable @Shadow @Final private EntityPersistentStorage permanentStorage; + @Mutable @Shadow @Final Set knownUuids; + @Mutable @Shadow @Final private Long2ObjectMap chunkVisibility; + @Mutable @Shadow @Final private Long2ObjectMap chunkLoadStatuses; + @Mutable @Shadow @Final private LongSet chunksToUnload; + @Mutable @Shadow @Final private Queue> loadingInbox; + @Mutable @Shadow @Final private EntityLookup visibleEntityStorage; @Inject( method = "", @@ -31,6 +42,14 @@ abstract class PersistentEntitySectionManagerMixin { private void destroyFields(final CallbackInfo ci) { this.sectionStorage = null; this.entityGetter = null; + this.callbacks = null; + this.permanentStorage = null; + this.knownUuids = null; + this.chunkVisibility = null; + this.chunkLoadStatuses = null; + this.chunksToUnload = null; + this.loadingInbox = null; + this.visibleEntityStorage = null; } @Inject( method = "addNewEntity", @@ -284,7 +303,7 @@ public void areEntitiesLoaded(long chunkPos, CallbackInfoReturnable cir method = "dumpSections", at = @At("HEAD") ) - public void dumpSections(Writer writer, CallbackInfo ci) throws IOException { + public void dumpSections(Writer writer, CallbackInfo ci) { throw new UnsupportedOperationException(); } From c5295978418f4063afa97846b3676832919c0040 Mon Sep 17 00:00:00 2001 From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> Date: Wed, 12 Nov 2025 04:14:18 +1400 Subject: [PATCH 7/8] Move to screenEntity --- .../ca/spottedleaf/moonrise/fabric/FabricHooks.java | 11 +++-------- .../spottedleaf/moonrise/neoforge/NeoForgeHooks.java | 5 ----- .../ca/spottedleaf/moonrise/common/PlatformHooks.java | 2 -- 3 files changed, 3 insertions(+), 15 deletions(-) diff --git a/fabric/src/main/java/ca/spottedleaf/moonrise/fabric/FabricHooks.java b/fabric/src/main/java/ca/spottedleaf/moonrise/fabric/FabricHooks.java index 0381a10d..793b4fad 100644 --- a/fabric/src/main/java/ca/spottedleaf/moonrise/fabric/FabricHooks.java +++ b/fabric/src/main/java/ca/spottedleaf/moonrise/fabric/FabricHooks.java @@ -144,14 +144,6 @@ public void addToGetEntities(final Level world, final Entity entity, final AABB } } - @Override - public boolean onAddEntity(final ServerLevel world, final Entity entity) { - if (HAS_ARCHITECTURY) { - return ArchitecturyHooks.onEntityAdd(entity, world); - } - return true; - } - @Override public void addToGetEntities(final Level world, final EntityTypeTest entityTypeTest, final AABB boundingBox, final Predicate predicate, final List into, final int maxCount) { @@ -186,6 +178,9 @@ public void entityMove(final Entity entity, final long oldSection, final long ne @Override public boolean screenEntity(final ServerLevel world, final Entity entity, final boolean fromDisk, final boolean event) { + if (HAS_ARCHITECTURY) { + return ArchitecturyHooks.onEntityAdd(entity, world); + } return true; } diff --git a/neoforge/src/main/java/ca/spottedleaf/moonrise/neoforge/NeoForgeHooks.java b/neoforge/src/main/java/ca/spottedleaf/moonrise/neoforge/NeoForgeHooks.java index 54647f19..25ba677e 100644 --- a/neoforge/src/main/java/ca/spottedleaf/moonrise/neoforge/NeoForgeHooks.java +++ b/neoforge/src/main/java/ca/spottedleaf/moonrise/neoforge/NeoForgeHooks.java @@ -149,11 +149,6 @@ public void addToGetEntities(final Level world, final Entity entity, final AABB } } - @Override - public boolean onAddEntity(final ServerLevel world, final Entity entity) { - return true; - } - @Override public void addToGetEntities(final Level world, final EntityTypeTest entityTypeTest, final AABB boundingBox, final Predicate predicate, final List into, final int maxCount) { diff --git a/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java index 7990a541..ea9fbb1b 100644 --- a/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java +++ b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java @@ -62,8 +62,6 @@ public default boolean isModLoaded(final String modId) { public void addToGetEntities(final Level world, final Entity entity, final AABB boundingBox, final Predicate predicate, final List into); - public boolean onAddEntity(final ServerLevel world, final Entity entity); - public void addToGetEntities(final Level world, final EntityTypeTest entityTypeTest, final AABB boundingBox, final Predicate predicate, final List into, final int maxCount); From 707dc426b09c378fe6b84035227ca2b6eecb4e06 Mon Sep 17 00:00:00 2001 From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> Date: Wed, 12 Nov 2025 04:16:57 +1400 Subject: [PATCH 8/8] Remove unused code --- .../patches/chunk_system/level/entity/EntityLookup.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java index 1e136a38..70b360a5 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java @@ -438,12 +438,6 @@ protected boolean addEntity(final Entity entity, final boolean fromDisk, final b return false; } - if (this.world instanceof ServerLevel serverLevel) { - if (!PlatformHooks.get().onAddEntity(serverLevel, entity)) { - return false; - } - } - ((ChunkSystemEntity)entity).moonrise$setSectionX(sectionX); ((ChunkSystemEntity)entity).moonrise$setSectionY(sectionY); ((ChunkSystemEntity)entity).moonrise$setSectionZ(sectionZ);