diff --git a/common/src/main/java/com/seibel/lod/common/LodCommonMain.java b/common/src/main/java/com/seibel/lod/common/LodCommonMain.java index e10f5b68c..cd673180d 100644 --- a/common/src/main/java/com/seibel/lod/common/LodCommonMain.java +++ b/common/src/main/java/com/seibel/lod/common/LodCommonMain.java @@ -31,11 +31,8 @@ import com.seibel.lod.core.config.ConfigBase; */ public class LodCommonMain { public static boolean forge = false; - public static boolean serverSided; public static LodForgeMethodCaller forgeMethodCaller; - - public static void startup(LodForgeMethodCaller caller, boolean serverSided) { - LodCommonMain.serverSided = serverSided; + public static void startup(LodForgeMethodCaller caller) { if (caller != null) { LodCommonMain.forge = true; forgeMethodCaller = caller; @@ -43,14 +40,13 @@ public class LodCommonMain { DependencySetup.createInitialBindings(); - if (!serverSided) { - new NetworkReceiver().register_Client(); - } else { - new NetworkReceiver().register_Server(); - } +// if (!serverSided) { +// new NetworkReceiver().register_Client(); +// } else { +// new NetworkReceiver().register_Server(); +// } } - public static void initConfig() { ConfigBase.init(Config.class); } diff --git a/common/src/main/java/com/seibel/lod/common/networking/NetworkReceiver.java b/common/src/main/java/com/seibel/lod/common/networking/NetworkReceiver.java index 8a74254c7..49e6998dd 100644 --- a/common/src/main/java/com/seibel/lod/common/networking/NetworkReceiver.java +++ b/common/src/main/java/com/seibel/lod/common/networking/NetworkReceiver.java @@ -30,6 +30,8 @@ import net.minecraft.network.FriendlyByteBuf; /** * @author Ran */ +// Comment: What does the 'server' side mean? Dedicated server? Or does it include the internal server? +// (I removed the hookup that calls the register method, since I'm not sure what it is doing yet) public class NetworkReceiver { public void register_Client() { NetworkManager.registerReceiver(NetworkManager.serverToClient(), Networking.RESOURCE_LOCATION, new ClientReceiver()); diff --git a/core b/core index f4f186ff7..d5e24ad2b 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit f4f186ff7824994e2876cde892cc07a638f8006f +Subproject commit d5e24ad2bbe5ec70c1247811e4d7bb62b7bc4080 diff --git a/fabric/src/main/java/com/seibel/lod/fabric/ClientProxy.java b/fabric/src/main/java/com/seibel/lod/fabric/FabricClientProxy.java similarity index 61% rename from fabric/src/main/java/com/seibel/lod/fabric/ClientProxy.java rename to fabric/src/main/java/com/seibel/lod/fabric/FabricClientProxy.java index e7cf3b983..feb332655 100644 --- a/fabric/src/main/java/com/seibel/lod/fabric/ClientProxy.java +++ b/fabric/src/main/java/com/seibel/lod/fabric/FabricClientProxy.java @@ -22,29 +22,17 @@ package com.seibel.lod.fabric; import com.seibel.lod.common.wrappers.McObjectConverter; import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment; import com.seibel.lod.core.api.internal.a7.ClientApi; -import com.seibel.lod.core.api.internal.a7.ServerApi; import com.seibel.lod.core.config.Config; -import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler; import com.mojang.blaze3d.platform.InputConstants; import com.seibel.lod.common.wrappers.chunk.ChunkWrapper; -import com.seibel.lod.common.wrappers.world.DimensionTypeWrapper; import com.seibel.lod.common.wrappers.world.WorldWrapper; -import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper; -import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton; -import dev.architectury.init.fabric.ArchitecturyClient; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientChunkEvents; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; -import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; -import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.TitleScreen; -import net.minecraft.core.BlockPos; -import net.minecraft.server.MinecraftServer; import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.chunk.LevelChunk; import java.util.HashSet; import java.util.function.Supplier; @@ -59,9 +47,8 @@ import org.lwjgl.glfw.GLFW; * @author Ran * @version 11-23-2021 */ -public class ClientProxy +public class FabricClientProxy { - private final ServerApi serverApi = ServerApi.INSTANCE; private final ClientApi clientApi = ClientApi.INSTANCE; public static Supplier isGenerationThreadChecker = null; @@ -71,36 +58,51 @@ public class ClientProxy * @author Ran */ public void registerEvents() { - /* Register the mod accessor*/ + isGenerationThreadChecker = BatchGenerationEnvironment::isCurrentThreadDistantGeneratorThread; - //TODO: ClientChunkLoadEvent - #if PRE_MC_1_18_1 // in 1.18+, we use mixin hook in setClientLightReady(true) - ClientChunkEvents.CHUNK_LOAD.register(this::chunkLoadEvent); - #endif - //TODO: ClientChunkSaveEvent + /* Register the mod needed event callbacks */ - /* The Client Level Events are in the mixins - Client world load event is in MixinClientLevel - Client world unload event is in ??? */ - //TODO: ClientLevelLoadEvent - //TODO: ClientLevelUnloadEvent - - //TODO: ClientRenderInitEvent - //TODO: ClientRenderFreeEvent - //TODO: ClientRenderStartEvent - //TODO: ClientRenderLevelTerrainEvent - WorldRenderEvents.AFTER_SETUP.register((renderContext) -> { - clientApi.renderLods(getLevelWrapper(renderContext.world()), - McObjectConverter.Convert(renderContext.projectionMatrix()), - McObjectConverter.Convert(renderContext.matrixStack().last().pose()), - renderContext.tickDelta()); + // ClientTickEvent + ClientTickEvents.START_CLIENT_TICK.register((client) -> { + ClientApi.INSTANCE.clientTickEvent(); }); - /* Keyboard Events */ + // ClientLevelLoadEvent - Done in MixinClientPacketListener + // ClientLevelUnloadEvent - Done in MixinClientPacketListener + + // ClientChunkLoadEvent + // TODO: Is using setClientLightReady one still better? + //#if PRE_MC_1_18_1 // in 1.18+, we use mixin hook in setClientLightReady(true) + ClientChunkEvents.CHUNK_LOAD.register((level, chunk) -> + ClientApi.INSTANCE.clientChunkLoadEvent( + new ChunkWrapper(chunk, level), + WorldWrapper.getWorldWrapper(level) + )); + //#endif + // ClientChunkSaveEvent + ClientChunkEvents.CHUNK_UNLOAD.register((level, chunk)-> + ClientApi.INSTANCE.clientChunkSaveEvent( + new ChunkWrapper(chunk, level), + WorldWrapper.getWorldWrapper(level) + )); + + // RendererStartupEvent - Done in MixinGameRenderer + // RendererShutdownEvent - Done in MixinGameRenderer + + + // ClientRenderLevelTerrainEvent + WorldRenderEvents.AFTER_SETUP.register((renderContext) -> + clientApi.renderLods(getLevelWrapper(renderContext.world()), + McObjectConverter.Convert(renderContext.projectionMatrix()), + McObjectConverter.Convert(renderContext.matrixStack().last().pose()), + renderContext.tickDelta()) + ); + + // Debug keyboard event + // FIXME: Use better hooks so it doesn't trigger even in text boxes ClientTickEvents.END_CLIENT_TICK.register(client -> { if (client.player != null && isValidTime()) onKeyInput(); }); - isGenerationThreadChecker = BatchGenerationEnvironment::isCurrentThreadDistantGeneratorThread; } private boolean isValidTime() { @@ -110,14 +112,14 @@ public class ClientProxy return WorldWrapper.getWorldWrapper(level); } - public void blockChangeEvent(LevelAccessor world, BlockPos pos) { - if (!isValidTime()) return; - IChunkWrapper chunk = new ChunkWrapper(world.getChunk(pos), world); - DimensionTypeWrapper dimType = DimensionTypeWrapper.getDimensionTypeWrapper(world.dimensionType()); - - // recreate the LOD where the blocks were changed - // TODO: serverApi.blockChangeEvent(chunk, dimType); - } +// public void blockChangeEvent(LevelAccessor world, BlockPos pos) { +// if (!isValidTime()) return; +// IChunkWrapper chunk = new ChunkWrapper(world.getChunk(pos), world); +// DimensionTypeWrapper dimType = DimensionTypeWrapper.getDimensionTypeWrapper(world.dimensionType()); +// +// // recreate the LOD where the blocks were changed +// // TODO: serverApi.blockChangeEvent(chunk, dimType); +// } private static final int[] KEY_TO_CHECK_FOR = {GLFW.GLFW_KEY_F6, GLFW.GLFW_KEY_F8}; diff --git a/fabric/src/main/java/com/seibel/lod/fabric/FabricServerProxy.java b/fabric/src/main/java/com/seibel/lod/fabric/FabricServerProxy.java index 44a9be358..fda82249e 100644 --- a/fabric/src/main/java/com/seibel/lod/fabric/FabricServerProxy.java +++ b/fabric/src/main/java/com/seibel/lod/fabric/FabricServerProxy.java @@ -39,23 +39,40 @@ public class FabricServerProxy { } /** * Registers Fabric Events - * @author Ran + * @author Ran, Tom */ public void registerEvents() { + + /* Register the mod needed event callbacks */ + + // TEST EVENT ServerTickEvents.END_SERVER_TICK.register(this::tester); - /* World Events */ + + // ServerTickEvent ServerTickEvents.END_SERVER_TICK.register((server) -> serverApi.serverTickEvent()); - /* Server World Events */ + // ServerWorldLoadEvent + //TODO: Check if both of this use the correct timed events. (i.e. is it 'ed' or 'ing' one?) + ServerLifecycleEvents.SERVER_STARTED.register((server) -> { + if (isValidTime()) ServerApi.INSTANCE.serverWorldLoadEvent(); + }); + // ServerWorldUnloadEvent + ServerLifecycleEvents.SERVER_STOPPING.register((server) -> { + if (isValidTime()) ServerApi.INSTANCE.serverWorldUnloadEvent(); + }); + + // ServerLevelLoadEvent ServerWorldEvents.LOAD.register((server, level) -> { if (isValidTime()) ServerApi.INSTANCE.serverLevelLoadEvent(getLevelWrapper(level)); }); + // ServerLevelUnloadEvent ServerWorldEvents.UNLOAD.register((server, level) -> { if (isValidTime()) ServerApi.INSTANCE.serverLevelUnloadEvent(getLevelWrapper(level)); }); + // ServerChunkLoadEvent ServerChunkEvents.CHUNK_LOAD.register((server, chunk) -> { IWorldWrapper level = getLevelWrapper(chunk.getLevel()); @@ -64,15 +81,7 @@ public class FabricServerProxy { level); } ); - //TODO: ServerChunkSaveEvent - - //TODO: Check if both of this use the correct timed events. (i.e. is it 'ed' or 'ing' one?) - ServerLifecycleEvents.SERVER_STARTED.register((server) -> { - if (isValidTime()) ServerApi.INSTANCE.serverWorldLoadEvent(); - }); - ServerLifecycleEvents.SERVER_STOPPING.register((server) -> { - if (isValidTime()) ServerApi.INSTANCE.serverWorldUnloadEvent(); - }); + // ServerChunkSaveEvent - Done in MixinChunkMap } // This just exists here for testing purposes, it'll be removed in the future diff --git a/fabric/src/main/java/com/seibel/lod/fabric/Main.java b/fabric/src/main/java/com/seibel/lod/fabric/Main.java index f06d8c958..99fe7b192 100644 --- a/fabric/src/main/java/com/seibel/lod/fabric/Main.java +++ b/fabric/src/main/java/com/seibel/lod/fabric/Main.java @@ -21,7 +21,7 @@ package com.seibel.lod.fabric; import com.seibel.lod.common.LodCommonMain; import com.seibel.lod.core.ModInfo; -import com.seibel.lod.core.api.internal.InternalApiShared; +import com.seibel.lod.core.api.internal.a7.SharedApi; import com.seibel.lod.core.handlers.dependencyInjection.ModAccessorHandler; import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler; import com.seibel.lod.core.logging.DhLoggerBuilder; @@ -35,6 +35,9 @@ import com.seibel.lod.fabric.wrappers.modAccessor.StarlightAccessor; import com.seibel.lod.fabric.wrappers.FabricDependencySetup; import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.api.DedicatedServerModInitializer; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; +import net.minecraft.client.Minecraft; import org.apache.logging.log4j.Logger; import java.lang.invoke.MethodHandles; @@ -48,14 +51,14 @@ import java.lang.invoke.MethodHandles; * @author Ran * @version 12-1-2021 */ -public class Main implements ClientModInitializer +public class Main implements ClientModInitializer, DedicatedServerModInitializer { // This is a client mod so it should implement ClientModInitializer and in fabric.mod.json it should have "environment": "client" // Once it works on servers change the implement to ModInitializer and in fabric.mod.json it should be "environment": "*" private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName()); - public static ClientProxy client_proxy; + public static FabricClientProxy client_proxy; public static FabricServerProxy server_proxy; @@ -63,20 +66,30 @@ public class Main implements ClientModInitializer // This loads the mod before minecraft loads which causes a lot of issues @Override public void onInitializeClient() { - // no. + SharedApi.inDedicatedEnvironment = false; + ClientLifecycleEvents.CLIENT_STARTED.register(Main::init); + } + + @Override + public void onInitializeServer() { + SharedApi.inDedicatedEnvironment = true; + init(null); // TODO: Check if init in here is ok } // This loads the mod after minecraft loads which doesn't causes a lot of issues - public static void init() { - LodCommonMain.startup(null, false); + public static void init(Minecraft minecraft) { + LodCommonMain.startup(null); FabricDependencySetup.createInitialBindings(); FabricDependencySetup.finishBinding(); LodCommonMain.initConfig(); LOGGER.info(ModInfo.READABLE_NAME + ", Version: " + ModInfo.VERSION); + if (!SharedApi.inDedicatedEnvironment) { + client_proxy = new FabricClientProxy(); + client_proxy.registerEvents(); + } + server_proxy = new FabricServerProxy(); + server_proxy.registerEvents(); - // Check if this works - client_proxy = new ClientProxy(); - client_proxy.registerEvents(); if (SingletonHandler.get(IModChecker.class).isModLoaded("sodium")) { ModAccessorHandler.bind(ISodiumAccessor.class, new SodiumAccessor()); } @@ -86,17 +99,6 @@ public class Main implements ClientModInitializer if (SingletonHandler.get(IModChecker.class).isModLoaded("optifine")) { ModAccessorHandler.bind(IOptifineAccessor.class, new OptifineAccessor()); } - ModAccessorHandler.finishBinding(); } - - public static void initServer() { - LodCommonMain.startup(null, true); - FabricDependencySetup.createInitialBindings(); - FabricDependencySetup.finishBinding(); - server_proxy = new FabricServerProxy(); - server_proxy.registerEvents(); - LodCommonMain.initConfig(); - LOGGER.info(ModInfo.READABLE_NAME + ", Version: " + ModInfo.VERSION); - } } diff --git a/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinDedicatedServer.java b/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinDedicatedServer.java index c85136156..83c7e56b1 100644 --- a/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinDedicatedServer.java +++ b/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinDedicatedServer.java @@ -27,9 +27,11 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(DedicatedServer.class) +@Deprecated // Please use the OnServerLoadEvent in core instead, or + // the ServerLifecycleEvents in Fabric public class MixinDedicatedServer { - @Inject(method = "initServer", at = @At("TAIL")) - public void initServer(CallbackInfoReturnable cir) { - Main.initServer(); - } +// @Inject(method = "initServer", at = @At("TAIL")) +// public void initServer(CallbackInfoReturnable cir) { +// Main.initServer(); +// } } diff --git a/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinMinecraft.java b/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinMinecraft.java index a3f3953db..feb7f6888 100644 --- a/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinMinecraft.java +++ b/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinMinecraft.java @@ -32,9 +32,10 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; * @author Ran */ @Mixin(value = Minecraft.class) +@Deprecated // Moved to using fabric lifecycle events public class MixinMinecraft { - @Inject(method = "", at = @At("TAIL")) - private void startMod(GameConfig gameConfig, CallbackInfo ci) { - Main.init(); - } +// @Inject(method = "", at = @At("TAIL")) +// private void startMod(GameConfig gameConfig, CallbackInfo ci) { +// Main.init(); +// } } diff --git a/fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinClientLevel.java b/fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinClientLevel.java index 1a9d29373..789bca07c 100644 --- a/fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinClientLevel.java +++ b/fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinClientLevel.java @@ -47,20 +47,20 @@ import java.util.function.Supplier; * This class is used for world loading events * @author Ran * - * FIXME: Why does forge not have the 1.18+ onChunkLightReady mixin? */ @Mixin(ClientLevel.class) public class MixinClientLevel { - @Inject(method = "", at = @At("TAIL")) - private void loadWorldEvent(ClientPacketListener clientPacketListener, ClientLevel.ClientLevelData clientLevelData, ResourceKey resourceKey, - #if POST_MC_1_18_2 Holder holder, #else DimensionType dimensionType, #endif int i, - #if POST_MC_1_18_1 int j, #endif Supplier supplier, LevelRenderer levelRenderer, boolean bl, long l, CallbackInfo ci) { - SharedApi.LOGGER.info("Loading level: " + WorldWrapper.getWorldWrapper((ClientLevel)(Object)this)); - ClientApi.INSTANCE.clientLevelLoadEvent(WorldWrapper.getWorldWrapper((ClientLevel)(Object)this)); - } + //Moved to MixinClientPacketListener +// @Inject(method = "", at = @At("TAIL")) +// private void loadWorldEvent(ClientPacketListener clientPacketListener, ClientLevel.ClientLevelData clientLevelData, ResourceKey resourceKey, +// #if POST_MC_1_18_2 Holder holder, #else DimensionType dimensionType, #endif int i, +// #if POST_MC_1_18_1 int j, #endif Supplier supplier, LevelRenderer levelRenderer, boolean bl, long l, CallbackInfo ci) { +// SharedApi.LOGGER.info("Loading level: " + WorldWrapper.getWorldWrapper((ClientLevel)(Object)this)); +// ClientApi.INSTANCE.clientLevelLoadEvent(WorldWrapper.getWorldWrapper((ClientLevel)(Object)this)); +// } - #if POST_MC_1_18_1 + #if POST_MC_1_18_1 // Only the setLightReady is only available after 1.18. This ensure light data is ready. @Inject(method = "setLightReady", at = @At("HEAD")) private void onChunkLightReady(int x, int z, CallbackInfo ci) { ClientLevel l = (ClientLevel) (Object) this; diff --git a/fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinClientPacketListener.java b/fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinClientPacketListener.java index bc07d9cf0..19007d4c0 100644 --- a/fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinClientPacketListener.java +++ b/fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinClientPacketListener.java @@ -1,10 +1,49 @@ package com.seibel.lod.fabric.mixins.client; +import com.seibel.lod.common.wrappers.world.WorldWrapper; +import com.seibel.lod.core.api.internal.a7.ClientApi; +import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.ClientPacketListener; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; @Mixin(ClientPacketListener.class) public class MixinClientPacketListener { + @Shadow + private ClientLevel level; + + /** THIS EXPLANATION IS WRITTEN BY FABRIC. + * An explanation why we unload entities during onGameJoin: (On in our remapping name case, handleLogin(TODO: CHECK)) + * Proxies such as Waterfall may send another Game Join packet if entity meta rewrite is disabled, so we will cover ourselves. + * Velocity by default will send a Game Join packet when the player changes servers, which will create a new client world. + * Also anyone can send another GameJoinPacket at any time, so we need to watch out. + */ + @Inject(method = "handleLogin", at = @At("HEAD")) + void onHandleLoginStart() { + if (level != null) ClientApi.INSTANCE.clientLevelUnloadEvent(WorldWrapper.getWorldWrapper(level)); + } + + @Inject(method = "handleLogin", at = @At("RETURN")) + void onHandleLoginEnd() { + ClientApi.INSTANCE.clientLevelLoadEvent(WorldWrapper.getWorldWrapper(level)); + } + + @Inject(method = "handleRespawn", at = @At("HEAD")) + void onHandleRespawnStart() { + ClientApi.INSTANCE.clientLevelUnloadEvent(WorldWrapper.getWorldWrapper(level)); + } + @Inject(method = "handleRespawn", at = @At("RETURN")) + void onHandleRespawnEnd() { + ClientApi.INSTANCE.clientLevelLoadEvent(WorldWrapper.getWorldWrapper(level)); + } + + @Inject(method = "cleanup", at = @At("HEAD")) + void onCleanupStart() { + if (level != null) ClientApi.INSTANCE.clientLevelUnloadEvent(WorldWrapper.getWorldWrapper(level)); + } + diff --git a/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinDebugScreenOverlay.java b/fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinDebugScreenOverlay.java similarity index 94% rename from fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinDebugScreenOverlay.java rename to fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinDebugScreenOverlay.java index f591f01cd..51d777f6c 100644 --- a/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinDebugScreenOverlay.java +++ b/fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinDebugScreenOverlay.java @@ -1,4 +1,4 @@ -package com.seibel.lod.fabric.mixins; +package com.seibel.lod.fabric.mixins.client; import com.seibel.lod.core.render.F3Screen; import net.minecraft.client.gui.components.DebugScreenOverlay; diff --git a/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinFogRenderer.java b/fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinFogRenderer.java similarity index 92% rename from fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinFogRenderer.java rename to fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinFogRenderer.java index b4273e8c3..ffa03d2f9 100644 --- a/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinFogRenderer.java +++ b/fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinFogRenderer.java @@ -17,8 +17,9 @@ * along with this program. If not, see . */ -package com.seibel.lod.fabric.mixins; +package com.seibel.lod.fabric.mixins.client; +import com.seibel.lod.core.config.Config; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -42,7 +43,6 @@ import net.minecraft.world.level.material.FogType; @Mixin(FogRenderer.class) public class MixinFogRenderer { - private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class); // Using this instead of Float.MAX_VALUE because Sodium don't like it. private static final float A_REALLY_REALLY_BIG_VALUE = 420694206942069.F; @@ -61,7 +61,7 @@ public class MixinFogRenderer { Entity entity = camera.getEntity(); boolean isSpecialFog = (entity instanceof LivingEntity) && ((LivingEntity) entity).hasEffect(MobEffects.BLINDNESS); if (!isSpecialFog && cameraNotInFluid && fogMode == FogMode.FOG_TERRAIN - && CONFIG.client().graphics().fogQuality().getDisableVanillaFog()) + && Config.Client.Graphics.FogQuality.disableVanillaFog.get()) { #if PRE_MC_1_17_1 RenderSystem.fogStart(A_REALLY_REALLY_BIG_VALUE); diff --git a/fabric/src/main/java/com/seibel/lod/fabric/mixins/events/MixinLightmap.java b/fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinLightmap.java similarity index 95% rename from fabric/src/main/java/com/seibel/lod/fabric/mixins/events/MixinLightmap.java rename to fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinLightmap.java index 19fa07c7f..fc909c5ed 100644 --- a/fabric/src/main/java/com/seibel/lod/fabric/mixins/events/MixinLightmap.java +++ b/fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinLightmap.java @@ -1,4 +1,4 @@ -package com.seibel.lod.fabric.mixins.events; +package com.seibel.lod.fabric.mixins.client; import com.mojang.blaze3d.platform.NativeImage; diff --git a/fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinMinecraft.java b/fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinMinecraft.java deleted file mode 100644 index d25db857d..000000000 --- a/fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinMinecraft.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of the Distant Horizons mod (formerly the LOD Mod), - * licensed under the GNU LGPL v3 License. - * - * Copyright (C) 2020-2022 James Seibel - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, version 3. - * - * 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.seibel.lod.fabric.mixins.events; - -import com.seibel.lod.fabric.Main; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.screens.Screen; -import net.minecraft.client.multiplayer.ClientLevel; - -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Mixin; -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.callback.CallbackInfo; - -/** - * This class is used for world unloading events - * @author Ran - */ -@Mixin(Minecraft.class) -public class MixinMinecraft { - @Shadow @Nullable public ClientLevel level; - - @Inject(method = "setLevel", at = @At("HEAD")) - private void unloadWorldEvent_sL(ClientLevel clientLevel, CallbackInfo ci) { - if (level != null) Main.client_proxy.worldUnloadEvent(level); - } - - @Inject(method = "clearLevel(Lnet/minecraft/client/gui/screens/Screen;)V", at = @At("HEAD")) - private void unloadWorldEvent_cL(Screen screen, CallbackInfo ci) { - if (this.level != null) Main.client_proxy.worldUnloadEvent(this.level); - } -} diff --git a/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinOptionsScreen.java b/fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinOptionsScreen.java similarity index 95% rename from fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinOptionsScreen.java rename to fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinOptionsScreen.java index d4c2e863c..f954df5c4 100644 --- a/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinOptionsScreen.java +++ b/fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinOptionsScreen.java @@ -17,11 +17,12 @@ * along with this program. If not, see . */ -package com.seibel.lod.fabric.mixins; +package com.seibel.lod.fabric.mixins.client; import com.seibel.lod.common.wrappers.config.GetConfigScreen; import com.seibel.lod.common.wrappers.config.TexturedButtonWidget; import com.seibel.lod.core.ModInfo; +import com.seibel.lod.core.config.Config; import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler; import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton; import net.minecraft.client.gui.screens.OptionsScreen; @@ -52,7 +53,7 @@ public class MixinOptionsScreen extends Screen { @Inject(at = @At("HEAD"),method = "init") private void lodconfig$init(CallbackInfo ci) { - if (SingletonHandler.get(ILodConfigWrapperSingleton.class).client().getOptionsButton()) + if (Config.Client.optionsButton.get()) this. #if PRE_MC_1_17_1 addButton #else addRenderableWidget #endif (new TexturedButtonWidget( // Where the button is on the screen diff --git a/fabric/src/main/java/com/seibel/lod/fabric/mixins/events/MixinBlockUpdate.java b/fabric/src/main/java/com/seibel/lod/fabric/mixins/events/MixinBlockUpdate.java index b99175688..18b7cd6f7 100644 --- a/fabric/src/main/java/com/seibel/lod/fabric/mixins/events/MixinBlockUpdate.java +++ b/fabric/src/main/java/com/seibel/lod/fabric/mixins/events/MixinBlockUpdate.java @@ -36,11 +36,13 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; * @author Ran */ @Mixin(ClientboundBlockUpdatePacket.class) +@Deprecated public abstract class MixinBlockUpdate { @Shadow public abstract BlockPos getPos(); - @Inject(method = "handle(Lnet/minecraft/network/protocol/game/ClientGamePacketListener;)V", at = @At("TAIL")) - private void onBlockUpdate(ClientGamePacketListener clientGamePacketListener, CallbackInfo ci) { - Main.client_proxy.blockChangeEvent(Minecraft.getInstance().player.clientLevel, this.getPos()); - } + //TODO: Check if this event will be needed in new reworked system +// @Inject(method = "handle(Lnet/minecraft/network/protocol/game/ClientGamePacketListener;)V", at = @At("TAIL")) +// private void onBlockUpdate(ClientGamePacketListener clientGamePacketListener, CallbackInfo ci) { +// Main.client_proxy.blockChangeEvent(Minecraft.getInstance().player.clientLevel, this.getPos()); +// } } diff --git a/fabric/src/main/java/com/seibel/lod/fabric/mixins/events/MixinServerLevel.java b/fabric/src/main/java/com/seibel/lod/fabric/mixins/events/MixinServerLevel.java index 8d18f8c02..2d23c8a2a 100644 --- a/fabric/src/main/java/com/seibel/lod/fabric/mixins/events/MixinServerLevel.java +++ b/fabric/src/main/java/com/seibel/lod/fabric/mixins/events/MixinServerLevel.java @@ -32,20 +32,21 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; * @author Ran */ @Mixin(ServerLevel.class) +@Deprecated // TODO: Not sure if this is needed anymore public class MixinServerLevel { - #if PRE_MC_1_17_1 - @Inject(method = "save", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerChunkCache;save(Z)V", shift = At.Shift.AFTER)) - private void saveWorldEvent(ProgressListener progressListener, boolean bl, boolean bl2, CallbackInfo ci) { - Main.client_proxy.worldSaveEvent(); - } - #else - @Inject(method = "save", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;saveAll()V", shift = At.Shift.AFTER)) - private void saveWorldEvent_sA(ProgressListener progressListener, boolean bl, boolean bl2, CallbackInfo ci) { - Main.client_proxy.worldSaveEvent(); - } - @Inject(method = "save", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;autoSave()V", shift = At.Shift.AFTER)) - private void saveWorldEvent_aS(ProgressListener progressListener, boolean bl, boolean bl2, CallbackInfo ci) { - Main.client_proxy.worldSaveEvent(); - } - #endif +// #if PRE_MC_1_17_1 +// @Inject(method = "save", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerChunkCache;save(Z)V", shift = At.Shift.AFTER)) +// private void saveWorldEvent(ProgressListener progressListener, boolean bl, boolean bl2, CallbackInfo ci) { +// Main.client_proxy.worldSaveEvent(); +// } +// #else +// @Inject(method = "save", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;saveAll()V", shift = At.Shift.AFTER)) +// private void saveWorldEvent_sA(ProgressListener progressListener, boolean bl, boolean bl2, CallbackInfo ci) { +// Main.client_proxy.worldSaveEvent(); +// } +// @Inject(method = "save", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;autoSave()V", shift = At.Shift.AFTER)) +// private void saveWorldEvent_aS(ProgressListener progressListener, boolean bl, boolean bl2, CallbackInfo ci) { +// Main.client_proxy.worldSaveEvent(); +// } +// #endif } diff --git a/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinChunkGenerator.java b/fabric/src/main/java/com/seibel/lod/fabric/mixins/server/MixinChunkGenerator.java similarity index 98% rename from fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinChunkGenerator.java rename to fabric/src/main/java/com/seibel/lod/fabric/mixins/server/MixinChunkGenerator.java index ee678a2b6..4fae15c45 100644 --- a/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinChunkGenerator.java +++ b/fabric/src/main/java/com/seibel/lod/fabric/mixins/server/MixinChunkGenerator.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.seibel.lod.fabric.mixins; +package com.seibel.lod.fabric.mixins.server; import org.spongepowered.asm.mixin.Mixin; import net.minecraft.world.level.chunk.ChunkGenerator; diff --git a/fabric/src/main/java/com/seibel/lod/fabric/mixins/server/MixinChunkMap.java b/fabric/src/main/java/com/seibel/lod/fabric/mixins/server/MixinChunkMap.java new file mode 100644 index 000000000..56afd2322 --- /dev/null +++ b/fabric/src/main/java/com/seibel/lod/fabric/mixins/server/MixinChunkMap.java @@ -0,0 +1,29 @@ +package com.seibel.lod.fabric.mixins.server; + +import com.seibel.lod.common.wrappers.chunk.ChunkWrapper; +import com.seibel.lod.common.wrappers.world.WorldWrapper; +import com.seibel.lod.core.api.internal.a7.ServerApi; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ChunkMap; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.chunk.ChunkAccess; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; + +@Mixin(ChunkMap.class) +public class MixinChunkMap { + static final String CHUNK_SERIALIZER_WRITE + = "Lnet/minecraft/world/level/chunk/storage/ChunkSerializer;write(" + + "Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/level/chunk/ChunkAccess;)" + + "Lnet/minecraft/nbt/CompoundTag;"; + + @Inject(method = "save", at = @At(value = "INVOKE", target = CHUNK_SERIALIZER_WRITE)) + private void onChunkSave(ServerLevel serverLevel, ChunkAccess chunkAccess, CompoundTag compoundTag) { + ServerApi.INSTANCE.serverChunkSaveEvent( + new ChunkWrapper(chunkAccess, serverLevel), + WorldWrapper.getWorldWrapper(serverLevel) + ); + } + +} diff --git a/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinUtilBackgroudThread.java b/fabric/src/main/java/com/seibel/lod/fabric/mixins/server/MixinUtilBackgroudThread.java similarity index 85% rename from fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinUtilBackgroudThread.java rename to fabric/src/main/java/com/seibel/lod/fabric/mixins/server/MixinUtilBackgroudThread.java index 66fcf7100..dfc499b6b 100644 --- a/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinUtilBackgroudThread.java +++ b/fabric/src/main/java/com/seibel/lod/fabric/mixins/server/MixinUtilBackgroudThread.java @@ -17,12 +17,12 @@ * along with this program. If not, see . */ -package com.seibel.lod.fabric.mixins; +package com.seibel.lod.fabric.mixins.server; import java.util.concurrent.ExecutorService; import java.util.function.Supplier; -import com.seibel.lod.fabric.ClientProxy; +import com.seibel.lod.fabric.FabricClientProxy; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -38,7 +38,7 @@ public class MixinUtilBackgroudThread @Inject(method = "backgroundExecutor", at = @At("HEAD"), cancellable = true) private static void overrideUtil$backgroundExecutor(CallbackInfoReturnable ci) { - if (ClientProxy.isGenerationThreadChecker != null && ClientProxy.isGenerationThreadChecker.get()) + if (FabricClientProxy.isGenerationThreadChecker != null && FabricClientProxy.isGenerationThreadChecker.get()) { //ApiShared.LOGGER.info("util backgroundExecutor triggered"); ci.setReturnValue(new DummyRunExecutorService()); @@ -50,7 +50,7 @@ public class MixinUtilBackgroudThread at = @At("HEAD"), cancellable = true) private static void overrideUtil$wrapThreadWithTaskName(String string, Runnable r, CallbackInfoReturnable ci) { - if (ClientProxy.isGenerationThreadChecker != null && ClientProxy.isGenerationThreadChecker.get()) + if (FabricClientProxy.isGenerationThreadChecker != null && FabricClientProxy.isGenerationThreadChecker.get()) { //ApiShared.LOGGER.info("util wrapThreadWithTaskName(Runnable) triggered"); ci.setReturnValue(r); @@ -62,7 +62,7 @@ public class MixinUtilBackgroudThread at = @At("HEAD"), cancellable = true) private static void overrideUtil$wrapThreadWithTaskNameForSupplier(String string, Supplier r, CallbackInfoReturnable> ci) { - if (ClientProxy.isGenerationThreadChecker != null && ClientProxy.isGenerationThreadChecker.get()) + if (FabricClientProxy.isGenerationThreadChecker != null && FabricClientProxy.isGenerationThreadChecker.get()) { //ApiShared.LOGGER.info("util wrapThreadWithTaskName(Supplier) triggered"); ci.setReturnValue(r); diff --git a/fabric/src/main/java/com/seibel/lod/fabric/mixins/unsafe/MixinThreadingDectector.java b/fabric/src/main/java/com/seibel/lod/fabric/mixins/server/unsafe/MixinThreadingDectector.java similarity index 95% rename from fabric/src/main/java/com/seibel/lod/fabric/mixins/unsafe/MixinThreadingDectector.java rename to fabric/src/main/java/com/seibel/lod/fabric/mixins/server/unsafe/MixinThreadingDectector.java index e579d5643..899e1a0bf 100644 --- a/fabric/src/main/java/com/seibel/lod/fabric/mixins/unsafe/MixinThreadingDectector.java +++ b/fabric/src/main/java/com/seibel/lod/fabric/mixins/server/unsafe/MixinThreadingDectector.java @@ -17,11 +17,12 @@ * along with this program. If not, see . */ -package com.seibel.lod.fabric.mixins.unsafe; +package com.seibel.lod.fabric.mixins.server.unsafe; import net.minecraft.server.level.ServerLevel; import org.spongepowered.asm.mixin.Mixin; +//FIXME: Is this still needed? #if POST_MC_1_18_1 import net.minecraft.util.ThreadingDetector; diff --git a/fabric/src/main/resources/fabric.lod.mixins.json b/fabric/src/main/resources/fabric.lod.mixins.json index 81e68cf89..c323c1025 100644 --- a/fabric/src/main/resources/fabric.lod.mixins.json +++ b/fabric/src/main/resources/fabric.lod.mixins.json @@ -3,25 +3,19 @@ "minVersion": "0.8", "package": "com.seibel.lod.fabric.mixins", "mixins": [ - "unsafe.MixinThreadingDectector", - "MixinUtilBackgroudThread", - "events.MixinServerLevel" + "server.unsafe.MixinThreadingDectector", + "server.MixinChunkGenerator", + "server.MixinChunkMap", + "server.MixinUtilBackgroudThread" ], "client": [ - "MixinMinecraft", - "MixinOptionsScreen", - "MixinWorldRenderer", - "MixinFogRenderer", - "MixinChunkGenerator", - "MixinDebugScreenOverlay", - "events.MixinClientLevel", - "events.MixinMinecraft", - "events.MixinBlockUpdate", - "events.MixinLightmap", - "client.MixinGameRenderer" - ], - "server": [ - "MixinDedicatedServer" + "client.MixinClientLevel", + "client.MixinClientPacketListener", + "client.MixinDebugScreenOverlay", + "client.MixinFogRenderer", + "client.MixinGameRenderer", + "client.MixinLightmap", + "client.MixinOptionsScreen" ], "injectors": { "defaultRequire": 1 diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index 381f3f755..a224970bf 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -16,11 +16,15 @@ "license": "LGPL", "icon": "icon.png", - "environment": "client", + "environment": "*", "entrypoints": { "client": [ "com.seibel.lod.fabric.Main" ], + "server": [ + "com.seibel.lod.fabric.Main" + ], + "modmenu": [ "com.seibel.lod.fabric.wrappers.config.ModMenuIntegration" ]