Rework fabric hooks to use more fabric api if possible

(Since, honestly, their hooks location is way better when it exists...)
This commit is contained in:
TomTheFurry
2022-06-02 12:57:32 +08:00
parent 87fdfc5048
commit 1fb42f3c8e
23 changed files with 242 additions and 208 deletions
@@ -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);
}
@@ -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());
+1 -1
Submodule core updated: f4f186ff78...d5e24ad2bb
@@ -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<Boolean> 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};
@@ -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
@@ -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);
}
}
@@ -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<Boolean> cir) {
Main.initServer();
}
// @Inject(method = "initServer", at = @At("TAIL"))
// public void initServer(CallbackInfoReturnable<Boolean> cir) {
// Main.initServer();
// }
}
@@ -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 = "<init>", at = @At("TAIL"))
private void startMod(GameConfig gameConfig, CallbackInfo ci) {
Main.init();
}
// @Inject(method = "<init>", at = @At("TAIL"))
// private void startMod(GameConfig gameConfig, CallbackInfo ci) {
// Main.init();
// }
}
@@ -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 = "<init>", 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 = "<init>", 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;
@@ -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));
}
@@ -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;
@@ -17,8 +17,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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);
@@ -1,4 +1,4 @@
package com.seibel.lod.fabric.mixins.events;
package com.seibel.lod.fabric.mixins.client;
import com.mojang.blaze3d.platform.NativeImage;
@@ -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 <https://www.gnu.org/licenses/>.
*/
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);
}
}
@@ -17,11 +17,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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
@@ -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());
// }
}
@@ -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
}
@@ -17,7 +17,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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;
@@ -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)
);
}
}
@@ -17,12 +17,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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<ExecutorService> 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<Runnable> 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<Supplier<?>> 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);
@@ -17,11 +17,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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;
@@ -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
+5 -1
View File
@@ -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"
]