diff --git a/fabric/src/main/java/com/seibel/lod/fabric/mixins/server/MixinUtilBackgroundThread.java b/fabric/src/main/java/com/seibel/lod/fabric/mixins/server/MixinUtilBackgroundThread.java new file mode 100644 index 000000000..464ac14e6 --- /dev/null +++ b/fabric/src/main/java/com/seibel/lod/fabric/mixins/server/MixinUtilBackgroundThread.java @@ -0,0 +1,73 @@ +/* + * 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.server; + +import java.util.concurrent.ExecutorService; +import java.util.function.Supplier; + +import com.seibel.lod.fabric.FabricServerProxy; +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; + +import com.seibel.lod.core.util.objects.DummyRunExecutorService; + +import net.minecraft.Util; + +@Mixin(Util.class) +public class MixinUtilBackgroundThread +{ + @Inject(method = "backgroundExecutor", at = @At("HEAD"), cancellable = true) + private static void overrideUtil$backgroundExecutor(CallbackInfoReturnable ci) + { + if (FabricServerProxy.isGenerationThreadChecker != null && FabricServerProxy.isGenerationThreadChecker.get()) + { + //ApiShared.LOGGER.info("util backgroundExecutor triggered"); + ci.setReturnValue(new DummyRunExecutorService()); + } + } + + #if POST_MC_1_17_1 + @Inject(method = "wrapThreadWithTaskName(Ljava/lang/String;Ljava/lang/Runnable;)Ljava/lang/Runnable;", + at = @At("HEAD"), cancellable = true) + private static void overrideUtil$wrapThreadWithTaskName(String string, Runnable r, CallbackInfoReturnable ci) + { + if (FabricServerProxy.isGenerationThreadChecker != null && FabricServerProxy.isGenerationThreadChecker.get()) + { + //ApiShared.LOGGER.info("util wrapThreadWithTaskName(Runnable) triggered"); + ci.setReturnValue(r); + } + } + #endif + #if POST_MC_1_18_1 + @Inject(method = "wrapThreadWithTaskName(Ljava/lang/String;Ljava/util/function/Supplier;)Ljava/util/function/Supplier;", + at = @At("HEAD"), cancellable = true) + private static void overrideUtil$wrapThreadWithTaskNameForSupplier(String string, Supplier r, CallbackInfoReturnable> ci) + { + if (FabricServerProxy.isGenerationThreadChecker != null && FabricServerProxy.isGenerationThreadChecker.get()) + { + //ApiShared.LOGGER.info("util wrapThreadWithTaskName(Supplier) triggered"); + ci.setReturnValue(r); + } + } + #endif + +} diff --git a/fabric/src/main/java/com/seibel/lod/fabric/wrappers/config/ModMenuIntegration.java b/fabric/src/main/java/com/seibel/lod/fabric/wrappers/config/ModMenuIntegration.java new file mode 100644 index 000000000..25a9f40e6 --- /dev/null +++ b/fabric/src/main/java/com/seibel/lod/fabric/wrappers/config/ModMenuIntegration.java @@ -0,0 +1,35 @@ +/* + * 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.wrappers.config; + +import com.seibel.lod.common.wrappers.gui.GetConfigScreen; +import com.terraformersmc.modmenu.api.ConfigScreenFactory; +import com.terraformersmc.modmenu.api.ModMenuApi; + +/** + * For making the config show up in modmenu + */ +public class ModMenuIntegration implements ModMenuApi { + // For the custom config code + @Override + public ConfigScreenFactory getModConfigScreenFactory() { + return parent -> GetConfigScreen.getScreen(parent); + } +} diff --git a/fabric/src/main/java/com/seibel/lod/fabric/wrappers/modAccessor/BCLibAccessor.java b/fabric/src/main/java/com/seibel/lod/fabric/wrappers/modAccessor/BCLibAccessor.java new file mode 100644 index 000000000..c4c043956 --- /dev/null +++ b/fabric/src/main/java/com/seibel/lod/fabric/wrappers/modAccessor/BCLibAccessor.java @@ -0,0 +1,25 @@ +package com.seibel.lod.fabric.wrappers.modAccessor; + +import com.seibel.lod.core.wrapperInterfaces.modAccessor.IBCLibAccessor; +import ru.bclib.config.ClientConfig; +import ru.bclib.config.Configs; +import ru.bclib.util.BackgroundInfo; + +import java.awt.*; + +public class BCLibAccessor implements IBCLibAccessor { + @Override + public String getModName() { + return "BCLib"; + } + + public void setRenderCustomFog(boolean newValue) { + // Change the value of CUSTOM_FOG_RENDERING in the bclib client config + Configs.CLIENT_CONFIG.set(ClientConfig.CUSTOM_FOG_RENDERING, newValue); + } + + @Override + public Color getFogColor() { + return new Color(BackgroundInfo.fogColorRed, BackgroundInfo.fogColorGreen, BackgroundInfo.fogColorBlue); + } +} \ No newline at end of file diff --git a/fabric/src/main/java/com/seibel/lod/fabric/wrappers/modAccessor/OptifineAccessor.java b/fabric/src/main/java/com/seibel/lod/fabric/wrappers/modAccessor/OptifineAccessor.java new file mode 100644 index 000000000..0d2c838fb --- /dev/null +++ b/fabric/src/main/java/com/seibel/lod/fabric/wrappers/modAccessor/OptifineAccessor.java @@ -0,0 +1,44 @@ +/* + * 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.wrappers.modAccessor; + +import java.util.HashSet; + +import com.seibel.lod.core.pos.DhChunkPos; +import com.seibel.lod.core.wrapperInterfaces.modAccessor.AbstractOptifineAccessor; +import com.seibel.lod.core.wrapperInterfaces.modAccessor.IOptifineAccessor; + +public class OptifineAccessor extends AbstractOptifineAccessor +{ + + @Override + public String getModName() + { + return "Optifine-Fabric-1.18.X"; + } + + @Override + public HashSet getNormalRenderedChunks() + { + // TODO: Impl proper methods here + return null; + } + +} diff --git a/fabric/src/main/java/com/seibel/lod/fabric/wrappers/modAccessor/SodiumAccessor.java b/fabric/src/main/java/com/seibel/lod/fabric/wrappers/modAccessor/SodiumAccessor.java new file mode 100644 index 000000000..2f083939a --- /dev/null +++ b/fabric/src/main/java/com/seibel/lod/fabric/wrappers/modAccessor/SodiumAccessor.java @@ -0,0 +1,122 @@ +/* + * 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.wrappers.modAccessor; + +import java.util.HashSet; +import java.util.stream.Collectors; + +import com.seibel.lod.core.pos.DhChunkPos; +import com.seibel.lod.core.dependencyInjection.SingletonInjector; +import com.seibel.lod.core.util.math.Mat4f; +import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory; +import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; +import com.seibel.lod.core.wrapperInterfaces.modAccessor.ISodiumAccessor; + + +import com.seibel.lod.core.wrapperInterfaces.world.IClientLevelWrapper; +import me.jellysquid.mods.sodium.client.render.SodiumWorldRenderer; +import net.minecraft.client.Minecraft; +#if PRE_MC_1_17_1 +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.protocol.Packet; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.phys.AABB; +#else +import net.minecraft.world.level.LevelHeightAccessor; +#endif + +public class SodiumAccessor implements ISodiumAccessor { + private final IWrapperFactory factory = SingletonInjector.INSTANCE.get(IWrapperFactory.class); + private final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); + + public IClientLevelWrapper levelWrapper; + public Mat4f mcModelViewMatrix; + public Mat4f mcProjectionMatrix; + public float partialTicks; + + @Override + public String getModName() { + return "Sodium-Fabric"; + } + + #if POST_MC_1_17_1 + @Override + public HashSet getNormalRenderedChunks() { + SodiumWorldRenderer renderer = SodiumWorldRenderer.instance(); + LevelHeightAccessor height = Minecraft.getInstance().level; + + #if POST_MC_1_18_1 + // 0b11 = Lighted chunk & loaded chunk + return renderer.getChunkTracker().getChunks(0b00).filter( + (long l) -> { + return true; + }).mapToObj(DhChunkPos::new).collect(Collectors.toCollection(HashSet::new)); + #else + // TODO: Maybe use a mixin to make this more efficient, and maybe ignore changes behind the camera + return MC_RENDER.getMaximumRenderedChunks().stream().filter((DHChunkPos chunk) -> { + return (renderer.isBoxVisible( + chunk.getMinBlockX()+1, height.getMinBuildHeight()+1, chunk.getMinBlockZ()+1, + chunk.getMinBlockX()+15, height.getMaxBuildHeight()-1, chunk.getMinBlockZ()+15)); + }).collect(Collectors.toCollection(HashSet::new)); + #endif + } + #else + @Override + public HashSet getNormalRenderedChunks() { + SodiumWorldRenderer renderer = SodiumWorldRenderer.getInstance(); + LevelAccessor height = Minecraft.getInstance().level; + // TODO: Maybe use a mixin to make this more efficient + return MC_RENDER.getMaximumRenderedChunks().stream().filter((DHChunkPos chunk) -> { + FakeChunkEntity AABB = new FakeChunkEntity(chunk.getX(), chunk.getZ(), height.getMaxBuildHeight()); + return (renderer.isEntityVisible(AABB)); + }).collect(Collectors.toCollection(HashSet::new)); + } + + private static class FakeChunkEntity extends Entity { + public int cx; + public int cz; + public int my; + public FakeChunkEntity(int chunkX, int chunkZ, int maxHeight) { + super(EntityType.AREA_EFFECT_CLOUD, null); + cx = chunkX; + cz = chunkZ; + my = maxHeight; + } + @Override + public AABB getBoundingBoxForCulling() { + return new AABB(cx*16+1, 1, cz*16+1, + cx*16+15, my-1, cz*16+15); + } + @Override + protected void defineSynchedData() {} + @Override + protected void readAdditionalSaveData(CompoundTag paramCompoundTag) {} + @Override + protected void addAdditionalSaveData(CompoundTag paramCompoundTag) {} + @Override + public Packet getAddEntityPacket() { + throw new UnsupportedOperationException("This is a FAKE CHUNK ENTITY... For tricking the Sodium to check a AABB."); + } + } + #endif + +} diff --git a/fabric/src/main/java/com/seibel/lod/fabric/wrappers/modAccessor/StarlightAccessor.java b/fabric/src/main/java/com/seibel/lod/fabric/wrappers/modAccessor/StarlightAccessor.java new file mode 100644 index 000000000..727a558ae --- /dev/null +++ b/fabric/src/main/java/com/seibel/lod/fabric/wrappers/modAccessor/StarlightAccessor.java @@ -0,0 +1,35 @@ +/* + * 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.wrappers.modAccessor; + +import com.seibel.lod.core.wrapperInterfaces.modAccessor.IStarlightAccessor; + + +public class StarlightAccessor implements IStarlightAccessor { + + @Override + public String getModName() { + return "Starlight-Fabric-1.18.X"; + } + + public StarlightAccessor() { + + } +} diff --git a/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinClientLevel.java b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinClientLevel.java new file mode 100644 index 000000000..5b27ac20b --- /dev/null +++ b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinClientLevel.java @@ -0,0 +1,66 @@ +/* + * 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.fabriclike.mixins.client; + +import com.seibel.lod.common.wrappers.chunk.ChunkWrapper; +import com.seibel.lod.common.wrappers.world.ClientLevelWrapper; +import com.seibel.lod.core.api.internal.ClientApi; +import net.minecraft.client.multiplayer.ClientLevel; +#if POST_MC_1_18_2 +#endif +import net.minecraft.world.level.chunk.LevelChunk; +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.CallbackInfo; + +/** + * This class is used for world loading events + * @author Ran + * + */ + +@Mixin(ClientLevel.class) +public class MixinClientLevel +{ +// //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) +// { +// ClientApi.INSTANCE.clientLevelLoadEvent(WorldWrapper.getWorldWrapper((ClientLevel)(Object)this)); +// } + + #if POST_MC_1_18_1 // Only the setLightReady is only available after 1.18. This ensures the light data is ready. + @Inject(method = "setLightReady", at = @At("HEAD")) + private void onChunkLightReady(int x, int z, CallbackInfo ci) + { + ClientLevel clientLevel = (ClientLevel) (Object) this; + LevelChunk chunk = clientLevel.getChunkSource().getChunk(x, z, false); + + if (chunk != null && !chunk.isClientLightReady()) + { + ClientApi.INSTANCE.clientChunkLoadEvent(new ChunkWrapper(chunk, clientLevel, ClientLevelWrapper.getWrapper(clientLevel)), ClientLevelWrapper.getWrapper(clientLevel)); + } + } + #endif + +} diff --git a/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinClientPacketListener.java b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinClientPacketListener.java new file mode 100644 index 000000000..3ab1d8128 --- /dev/null +++ b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinClientPacketListener.java @@ -0,0 +1,51 @@ +package com.seibel.lod.fabriclike.mixins.client; + +import com.seibel.lod.common.wrappers.world.ClientLevelWrapper; +import com.seibel.lod.core.api.internal.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; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@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(CallbackInfo ci) + { + // not the best way to notify Core that we are no longer in the previous world, but it will have to do for now + ClientApi.INSTANCE.onClientOnlyDisconnected(); + } + @Inject(method = "handleLogin", at = @At("RETURN")) + void onHandleLoginEnd(CallbackInfo ci) { ClientApi.INSTANCE.onClientOnlyConnected(); } + + @Inject(method = "handleRespawn", at = @At("HEAD")) + void onHandleRespawnStart(CallbackInfo ci) { ClientApi.INSTANCE.clientLevelUnloadEvent(ClientLevelWrapper.getWrapper(level)); } + @Inject(method = "handleRespawn", at = @At("RETURN")) + void onHandleRespawnEnd(CallbackInfo ci) { ClientApi.INSTANCE.clientLevelLoadEvent(ClientLevelWrapper.getWrapper(level)); } + + @Inject(method = "cleanup", at = @At("HEAD")) + void onCleanupStart(CallbackInfo ci) + { + // TODO which unload method should be used? do we need both? + if (level != null) + { + ClientApi.INSTANCE.clientLevelUnloadEvent(ClientLevelWrapper.getWrapper(level)); + } + } + +} diff --git a/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinDebugScreenOverlay.java b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinDebugScreenOverlay.java new file mode 100644 index 000000000..a998bd0ff --- /dev/null +++ b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinDebugScreenOverlay.java @@ -0,0 +1,21 @@ +package com.seibel.lod.fabriclike.mixins.client; + +import com.seibel.lod.core.logging.f3.F3Screen; +import net.minecraft.client.gui.components.DebugScreenOverlay; +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; + +import java.util.List; + +@Mixin(DebugScreenOverlay.class) +public class MixinDebugScreenOverlay { + + @Inject(method = "getSystemInformation", at = @At("RETURN")) + private void addCustomF3(CallbackInfoReturnable> cir) { + List messages = cir.getReturnValue(); + F3Screen.addStringToDisplay(messages); + } + +} diff --git a/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinFogRenderer.java b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinFogRenderer.java new file mode 100644 index 000000000..879cc94d8 --- /dev/null +++ b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinFogRenderer.java @@ -0,0 +1,78 @@ +/* + * 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.fabriclike.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; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import com.mojang.blaze3d.systems.RenderSystem; + +import net.minecraft.client.Camera; +import net.minecraft.client.renderer.FogRenderer; +import net.minecraft.client.renderer.FogRenderer.FogMode; +import net.minecraft.world.effect.MobEffects; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +#if PRE_MC_1_17_1 +import net.minecraft.world.level.material.FluidState; +#else +import net.minecraft.world.level.material.FogType; +#endif + +@Mixin(FogRenderer.class) +public class MixinFogRenderer { + + // Using this instead of Float.MAX_VALUE because Sodium don't like it. + private static final float A_REALLY_REALLY_BIG_VALUE = 420694206942069.F; + private static final float A_EVEN_LARGER_VALUE = 42069420694206942069.F; + + @Inject(at = @At("RETURN"), method = "setupFog") + #if PRE_MC_1_19 + private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, CallbackInfo callback) { + #else + private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float g, CallbackInfo callback) { + #endif + #if PRE_MC_1_17_1 + FluidState fluidState = camera.getFluidInCamera(); + boolean cameraNotInFluid = fluidState.isEmpty(); + #else + FogType fogTypes = camera.getFluidInCamera(); + boolean cameraNotInFluid = fogTypes == FogType.NONE; + #endif + + 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.disableVanillaFog.get()) + { + #if PRE_MC_1_17_1 + RenderSystem.fogStart(A_REALLY_REALLY_BIG_VALUE); + RenderSystem.fogEnd(A_EVEN_LARGER_VALUE); + #else + RenderSystem.setShaderFogStart(A_REALLY_REALLY_BIG_VALUE); + RenderSystem.setShaderFogEnd(A_EVEN_LARGER_VALUE); + #endif + } + } + +} diff --git a/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinGameRenderer.java b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinGameRenderer.java new file mode 100644 index 000000000..983e31c47 --- /dev/null +++ b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinGameRenderer.java @@ -0,0 +1,47 @@ +package com.seibel.lod.fabriclike.mixins.client; + +import com.seibel.lod.core.api.internal.ClientApi; +import net.minecraft.client.renderer.GameRenderer; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +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.CallbackInfo; + +@Mixin(GameRenderer.class) +public class MixinGameRenderer +{ + private static final Logger LOGGER = LogManager.getLogger(MixinGameRenderer.class.getSimpleName()); + + + #if POST_MC_1_17_1 + @Inject(method = "shutdownShaders", at = @At("HEAD")) + public void onShutdownShaders(CallbackInfo ci) { + LOGGER.info("Shutting down renderer"); + ClientApi.INSTANCE.rendererShutdownEvent(); + } + + // FIXME: This I think will dup multiple renderStartupEvent calls... + @Inject(method = {"reloadShaders", "preloadUiShader", "preloadShader"}, at = @At("TAIL")) + public void onStartupShaders(CallbackInfo ci) { + LOGGER.info("Starting up renderer"); + ClientApi.INSTANCE.rendererStartupEvent(); + } + #else + // FIXME: on 1.16 we dont have stuff for reloading/shutting down shaders + + @Inject(method = "shutdownShaders", at = @At("HEAD")) + public void onShutdownShaders(CallbackInfo ci) { + LOGGER.info("Shutting down renderer"); + ClientApi.INSTANCE.rendererShutdownEvent(); + } + + // FIXME: This I think will dup multiple renderStartupEvent calls... + @Inject(method = {"reloadShaders", "preloadUiShader", "preloadShader"}, at = @At("TAIL")) + public void onStartupShaders(CallbackInfo ci) { + LOGGER.info("Starting up renderer"); + ClientApi.INSTANCE.rendererStartupEvent(); + } + #endif +} diff --git a/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinLevelRenderer.java b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinLevelRenderer.java new file mode 100644 index 000000000..e09ec4b2f --- /dev/null +++ b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinLevelRenderer.java @@ -0,0 +1,114 @@ +/* + * This file is part of the Distant Horizons mod (formerly the LOD Mod), + * licensed under the GNU GPL 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 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.seibel.lod.fabriclike.mixins.client; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Matrix4f; +import com.seibel.lod.core.config.Config; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.renderer.LevelRenderer; +import net.minecraft.client.renderer.RenderType; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +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 to mix in my rendering code + * before Minecraft starts rendering blocks. + * If this wasn't done, and we used Forge's + * render last event, the LODs would render on top + * of the normal terrain. + * + * This is also the mixin for rendering the clouds + * + * @author coolGi + * @author James Seibel + * @version 12-31-2021 + */ +@Mixin(LevelRenderer.class) +public class MixinLevelRenderer +{ + @Shadow + private ClientLevel level; + @Unique + private static float previousPartialTicks = 0; + + // Inject rendering at first call to renderChunkLayer + // HEAD or RETURN + #if PRE_MC_1_17_1 + @Inject(at = @At("RETURN"), method = "renderSky(Lcom/mojang/blaze3d/vertex/PoseStack;F)V") + private void renderSky(PoseStack matrixStackIn, float partialTicks, CallbackInfo callback) + { + // get the partial ticks since renderBlockLayer doesn't + // have access to them + previousPartialTicks = partialTicks; + } + + @Inject(at = @At("HEAD"), + method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDD)V", + cancellable = true) + private void renderChunkLayer(RenderType renderType, PoseStack matrixStackIn, double xIn, double yIn, double zIn, CallbackInfo callback) + { +// // only render before solid blocks +// if (renderType.equals(RenderType.solid())) +// { +// // get MC's current projection matrix +// float[] mcProjMatrixRaw = new float[16]; +// GL15.glGetFloatv(GL15.GL_PROJECTION_MATRIX, mcProjMatrixRaw); +// Mat4f mcProjectionMatrix = new Mat4f(mcProjMatrixRaw); +// mcProjectionMatrix.transpose(); +// Mat4f mcModelViewMatrix = McObjectConverter.Convert(matrixStackIn.last().pose()); +// +// ClientApi.INSTANCE.renderLods(LevelWrapper.getWorldWrapper(level), mcModelViewMatrix, mcProjectionMatrix, previousPartialTicks); +// } + if (Config.Client.Advanced.lodOnlyMode.get()) { + callback.cancel(); + } + } + #else + @Inject(method = "renderClouds", at = @At("HEAD"), cancellable = true) + public void renderClouds(PoseStack poseStack, Matrix4f projectionMatrix, float tickDelta, double cameraX, double cameraY, double cameraZ, CallbackInfo ci) { + // get the partial ticks since renderChunkLayer doesn't + // have access to them + previousPartialTicks = tickDelta; + } + + @Inject(at = @At("HEAD"), + method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLcom/mojang/math/Matrix4f;)V", + cancellable = true) + private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double cameraXBlockPos, double cameraYBlockPos, double cameraZBlockPos, Matrix4f projectionMatrix, CallbackInfo callback) + { +// // only render before solid blocks +// if (renderType.equals(RenderType.solid())) +// { +// Mat4f mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrixStack.last().pose()); +// Mat4f mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix); +// +// ClientApi.INSTANCE.renderLods(ClientLevelWrapper.getWrapper(level), mcModelViewMatrix, mcProjectionMatrix, previousPartialTicks); +// } + if (Config.Client.Advanced.lodOnlyMode.get()) { + callback.cancel(); + } + } + #endif +} diff --git a/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinLightmap.java b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinLightmap.java new file mode 100644 index 000000000..1bed35d16 --- /dev/null +++ b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinLightmap.java @@ -0,0 +1,27 @@ +package com.seibel.lod.fabriclike.mixins.client; + + +import com.mojang.blaze3d.platform.NativeImage; +import com.seibel.lod.common.wrappers.minecraft.MinecraftRenderWrapper; +import net.minecraft.client.renderer.LightTexture; +import org.spongepowered.asm.mixin.Final; +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; + +@Mixin(LightTexture.class) +public class MixinLightmap { + @Shadow + @Final + public NativeImage lightPixels; + + @Inject(method="updateLightTexture", at=@At( + value="INVOKE", + target="Lnet/minecraft/client/renderer/texture/DynamicTexture;upload()V")) + public void updateLightTexture(float f, CallbackInfo ci) { + //ApiShared.LOGGER.info("Lightmap update"); + MinecraftRenderWrapper.INSTANCE.updateLightmap(lightPixels); + } +} diff --git a/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinMinecraft.java b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinMinecraft.java new file mode 100644 index 000000000..75b552baa --- /dev/null +++ b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinMinecraft.java @@ -0,0 +1,48 @@ +package com.seibel.lod.fabriclike.mixins.client; + +import com.seibel.lod.common.wrappers.gui.updater.UpdateModScreen; +import com.seibel.lod.core.config.Config; +import com.seibel.lod.core.dependencyInjection.SingletonInjector; +import com.seibel.lod.core.jar.installer.ModrinthGetter; +import com.seibel.lod.core.jar.updater.SelfUpdater; +import com.seibel.lod.core.wrapperInterfaces.IVersionConstants; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.gui.screens.TitleScreen; +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.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +/** + * @author coolGi + */ +@Mixin(Minecraft.class) +public class MixinMinecraft +{ + @Redirect( + method = "(Lnet/minecraft/client/main/GameConfig;)V", + at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;setScreen(Lnet/minecraft/client/gui/screens/Screen;)V") + ) + public void onOpenScreen(Minecraft instance, Screen guiScreen) { + if (!Config.Client.AutoUpdater.enableAutoUpdater.get()) { // Don't do anything if the user doesn't want it + instance.setScreen(guiScreen); // Sets the screen back to the vanilla screen as if nothing ever happened + return; + } + + if (SelfUpdater.onStart()) { + instance.setScreen(new UpdateModScreen( + new TitleScreen(false), // We don't want to use the vanilla title screen as it would fade the buttons + ModrinthGetter.getLatestIDForVersion(SingletonInjector.INSTANCE.get(IVersionConstants.class).getMinecraftVersion()) + )); + } else { + instance.setScreen(guiScreen); // Sets the screen back to the vanilla screen as if nothing ever happened + } + } + + @Inject(at = @At("HEAD"), method = "close()V") + public void close(CallbackInfo ci) { + SelfUpdater.onClose(); + } +} diff --git a/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinOptionsScreen.java b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinOptionsScreen.java new file mode 100644 index 000000000..8f4741eb2 --- /dev/null +++ b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinOptionsScreen.java @@ -0,0 +1,77 @@ +/* + * 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.fabriclike.mixins.client; + +import com.seibel.lod.common.wrappers.gui.GetConfigScreen; +import com.seibel.lod.common.wrappers.gui.TexturedButtonWidget; +import com.seibel.lod.core.ModInfo; +import com.seibel.lod.core.config.Config; +import net.minecraft.client.gui.screens.OptionsScreen; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.Component; +#if PRE_MC_1_19 +import net.minecraft.network.chat.TranslatableComponent; +#endif +import net.minecraft.resources.ResourceLocation; +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.CallbackInfo; + +import java.util.Objects; + +/** + * Adds a button to the menu to goto the config + * + * @author coolGi + * @version 12-02-2021 +*/ +@Mixin(OptionsScreen.class) +public class MixinOptionsScreen extends Screen { + // Get the texture for the button + private static final ResourceLocation ICON_TEXTURE = new ResourceLocation(ModInfo.ID,"textures/gui/button.png"); + protected MixinOptionsScreen(Component title) { + super(title); + } + + @Inject(at = @At("HEAD"),method = "init") + private void lodconfig$init(CallbackInfo ci) { + 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 + this.width / 2 - 180, this.height / 6 - 12, + // Width and height of the button + 20, 20, + // Offset + 0, 0, + // Some textuary stuff + 20, ICON_TEXTURE, 20, 40, + // Create the button and tell it where to go + // For now it goes to the client option by default + (buttonWidget) -> Objects.requireNonNull(minecraft).setScreen(GetConfigScreen.getScreen(this)), + // Add a title to the utton + #if PRE_MC_1_19 + new TranslatableComponent(ModInfo.ID + ".title"))); + #else + Component.translatable(ModInfo.ID + ".title"))); + #endif + } +} diff --git a/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinTextureUtil.java b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinTextureUtil.java new file mode 100644 index 000000000..9a34c5251 --- /dev/null +++ b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/client/MixinTextureUtil.java @@ -0,0 +1,27 @@ +package com.seibel.lod.fabriclike.mixins.client; + +import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.platform.TextureUtil; +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.Redirect; + +/** + * Sets Minecraft's LOD Bias (looks similar to mipmaps) + * + * @author coolGi + */ +@Mixin(TextureUtil.class) +public class MixinTextureUtil { + @Redirect(method = "Lcom/mojang/blaze3d/platform/TextureUtil;prepareImage(Lcom/mojang/blaze3d/platform/NativeImage$InternalGlFormat;IIII)V", + at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/GlStateManager;_texParameter(IIF)V", remap=false)) + private static void setLodBias(int target, int pname, float param) { + float biasValue = Config.Client.Graphics.AdvancedGraphics.lodBias.get().floatValue(); + if (biasValue != 0) { + // The target is GL11.GL_TEXTURE_2D + // And the pname is GL14.GL_TEXTURE_LOD_BIAS + GlStateManager._texParameter(target, pname, biasValue); + } + } +} diff --git a/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/events/MixinBlockUpdate.java b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/events/MixinBlockUpdate.java new file mode 100644 index 000000000..70d7b54a3 --- /dev/null +++ b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/events/MixinBlockUpdate.java @@ -0,0 +1,42 @@ +/* + * 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.fabriclike.mixins.events; + +import net.minecraft.core.BlockPos; +import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +/** + * If someone has a better way to do this then please let me know. + * + * @author Ran + */ +@Mixin(ClientboundBlockUpdatePacket.class) +@Deprecated +public abstract class MixinBlockUpdate { + @Shadow public abstract BlockPos 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/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/events/MixinServerLevel.java b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/events/MixinServerLevel.java new file mode 100644 index 000000000..de12f01a3 --- /dev/null +++ b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/events/MixinServerLevel.java @@ -0,0 +1,47 @@ +/* + * 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.fabriclike.mixins.events; + +import net.minecraft.server.level.ServerLevel; +import org.spongepowered.asm.mixin.Mixin; + +/** + * This class is used for world saving events + * @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 +} diff --git a/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/server/MixinChunkGenerator.java b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/server/MixinChunkGenerator.java new file mode 100644 index 000000000..9bf1911eb --- /dev/null +++ b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/server/MixinChunkGenerator.java @@ -0,0 +1,55 @@ +/* + * 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.fabriclike.mixins.server; + +import org.spongepowered.asm.mixin.Mixin; +import net.minecraft.world.level.chunk.ChunkGenerator; + +#if PRE_MC_1_18_1 +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.WorldGenRegion; +import net.minecraft.world.level.StructureFeatureManager; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.levelgen.WorldgenRandom; + +@Mixin(ChunkGenerator.class) +public class MixinChunkGenerator { + @Redirect(method = "applyBiomeDecoration", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/level/biome/Biome;generate(Lnet/minecraft/world/level/StructureFeatureManager;" + + "Lnet/minecraft/world/level/chunk/ChunkGenerator;Lnet/minecraft/server/level/WorldGenRegion;J" + + "Lnet/minecraft/world/level/levelgen/WorldgenRandom;Lnet/minecraft/core/BlockPos;)V" + + )) + private void wrapBiomeGenerateCall(Biome biome, StructureFeatureManager structFeatManager, ChunkGenerator generator, + WorldGenRegion genRegion, long l, WorldgenRandom random, BlockPos pos) { + synchronized(ChunkGenerator.class) { + biome.generate(structFeatManager, (ChunkGenerator)(Object)this, genRegion, l, random, pos); + } + } +} + +#else +@Mixin(ChunkGenerator.class) +public class MixinChunkGenerator {} +#endif \ No newline at end of file diff --git a/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/server/MixinChunkMap.java b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/server/MixinChunkMap.java new file mode 100644 index 000000000..a2cb68f56 --- /dev/null +++ b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/server/MixinChunkMap.java @@ -0,0 +1,38 @@ +package com.seibel.lod.fabriclike.mixins.server; + +import com.seibel.lod.common.wrappers.chunk.ChunkWrapper; +import com.seibel.lod.common.wrappers.world.ServerLevelWrapper; +import com.seibel.lod.core.api.internal.ServerApi; +import net.minecraft.server.level.ChunkMap; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.chunk.ChunkAccess; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(ChunkMap.class) +public class MixinChunkMap { + + @Unique + private 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;"; + + @Shadow + @Final + ServerLevel level; + + @Inject(method = "save", at = @At(value = "INVOKE", target = CHUNK_SERIALIZER_WRITE)) + private void onChunkSave(ChunkAccess chunk, CallbackInfoReturnable ci) { + ServerApi.INSTANCE.serverChunkSaveEvent( + new ChunkWrapper(chunk, level, ServerLevelWrapper.getWrapper(level)), + ServerLevelWrapper.getWrapper(level) + ); + } + +} diff --git a/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/server/unsafe/MixinThreadingDetector.java b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/server/unsafe/MixinThreadingDetector.java new file mode 100644 index 000000000..a2029a2d7 --- /dev/null +++ b/fabricLike/src/main/java/com/seibel/lod/fabriclike/mixins/server/unsafe/MixinThreadingDetector.java @@ -0,0 +1,53 @@ +/* + * 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.fabriclike.mixins.server.unsafe; + +import org.spongepowered.asm.mixin.Mixin; + +//FIXME: Is this still needed? +#if POST_MC_1_18_1 + +import net.minecraft.util.ThreadingDetector; +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.callback.CallbackInfo; + +import java.util.concurrent.Semaphore; + +/** + * Why does this exist? But okay! (Will be probably removed when the experimental generator is done) + */ +@Mixin(ThreadingDetector.class) +public class MixinThreadingDetector { + @Mutable + @Shadow + private Semaphore lock; + + @Inject(method = "", at = @At("RETURN")) + private void setSemaphore(CallbackInfo ci) { + this.lock = new Semaphore(2); + } +} +#else +@Mixin(ServerLevel.class) + public class MixinThreadingDectector {} //FIXME: Is there some way to make this file just not be added? +#endif diff --git a/fabricLike/src/main/java/com/seibel/lod/fabriclike/wrappers/FabricLikeDependencySetup.java b/fabricLike/src/main/java/com/seibel/lod/fabriclike/wrappers/FabricLikeDependencySetup.java new file mode 100644 index 000000000..ae1a23a89 --- /dev/null +++ b/fabricLike/src/main/java/com/seibel/lod/fabriclike/wrappers/FabricLikeDependencySetup.java @@ -0,0 +1,38 @@ +/* + * 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.fabriclike.wrappers; + +import com.seibel.lod.core.dependencyInjection.SingletonInjector; + +/** + * Binds all necessary dependencies, so we + * can access them in Core.
+ * This needs to be called before any Core classes + * are loaded. + * + * @author James Seibel + * @author Ran + * @version 3-5-2022 + */ +public class FabricLikeDependencySetup { + public static void createInitialBindings() {} + + public static void runDelayedSetup() {} +}