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() {}
+}