Rework forge to new a1.7 structure. Minecraft runs and it builds. But crash on loading into world due to... weirdness
This commit is contained in:
@@ -57,12 +57,12 @@ public class DependencySetup {
|
||||
DependencySetupDoneCheck.isDone = true;
|
||||
}
|
||||
|
||||
@Environment(EnvType.SERVER)
|
||||
//@Environment(EnvType.SERVER)
|
||||
public static void createServerBindings() {
|
||||
SingletonInjector.INSTANCE.bind(IMinecraftSharedWrapper.class, MinecraftDedicatedServerWrapper.INSTANCE);
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
//@Environment(EnvType.CLIENT)
|
||||
public static void createClientBindings() {
|
||||
SingletonInjector.INSTANCE.bind(IMinecraftClientWrapper.class, MinecraftClientWrapper.INSTANCE);
|
||||
SingletonInjector.INSTANCE.bind(IMinecraftSharedWrapper.class, MinecraftClientWrapper.INSTANCE);
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
* @author James Seibel
|
||||
* @version 3-5-2022
|
||||
*/
|
||||
@Environment(EnvType.CLIENT)
|
||||
//@Environment(EnvType.CLIENT)
|
||||
public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecraftSharedWrapper
|
||||
{
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ import net.minecraft.server.dedicated.DedicatedServer;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@Environment(EnvType.SERVER)
|
||||
//@Environment(EnvType.SERVER)
|
||||
public class MinecraftDedicatedServerWrapper implements IMinecraftSharedWrapper {
|
||||
public static final MinecraftDedicatedServerWrapper INSTANCE = new MinecraftDedicatedServerWrapper();
|
||||
private MinecraftDedicatedServerWrapper() {}
|
||||
|
||||
+1
-1
@@ -76,7 +76,7 @@ import org.apache.logging.log4j.Logger;
|
||||
* @author James Seibel
|
||||
* @version 12-12-2021
|
||||
*/
|
||||
@Environment(EnvType.CLIENT)
|
||||
//@Environment(EnvType.CLIENT)
|
||||
public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
||||
{
|
||||
public static final MinecraftRenderWrapper INSTANCE = new MinecraftRenderWrapper();
|
||||
|
||||
@@ -73,7 +73,7 @@ public class LevelWrapper implements ILevelWrapper
|
||||
levelType = ELevelType.UNKNOWN;
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
//@Environment(EnvType.CLIENT)
|
||||
private static LevelAccessor getSinglePlayerServerLevel() {
|
||||
MinecraftClientWrapper client = MinecraftClientWrapper.INSTANCE;
|
||||
return client.mc.getSingleplayerServer().getPlayerList()
|
||||
|
||||
+1
-1
Submodule core updated: 973be40324...ff2763df9e
@@ -5,7 +5,6 @@ import com.seibel.lod.common.wrappers.chunk.ChunkWrapper;
|
||||
import com.seibel.lod.common.wrappers.world.LevelWrapper;
|
||||
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||
import com.seibel.lod.core.api.internal.a7.ServerApi;
|
||||
import com.seibel.lod.core.api.internal.a7.SharedApi;
|
||||
import com.seibel.lod.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerChunkEvents;
|
||||
@@ -27,6 +26,7 @@ import java.util.function.Supplier;
|
||||
* and is the starting point for most of the mod.
|
||||
*
|
||||
* @author Ran
|
||||
* @author Tomlee
|
||||
* @version 5-11-2022
|
||||
*/
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ public class MixinGameRenderer {
|
||||
ClientApi.INSTANCE.rendererShutdownEvent();
|
||||
}
|
||||
|
||||
//FIXME: This I think will dup multiple renderStartupEvent calls...
|
||||
// FIXME: This I think will dup multiple renderStartupEvent calls...
|
||||
@Inject(method = {"reloadShaders", "preloadUiShader", "preloadShader"}, at = @At("TAIL"))
|
||||
public void onStartupShaders(CallbackInfo ci) {
|
||||
SharedApi.LOGGER.info("Starting up renderer");
|
||||
@@ -32,7 +32,7 @@ public class MixinGameRenderer {
|
||||
ClientApi.INSTANCE.rendererShutdownEvent();
|
||||
}
|
||||
|
||||
//FIXME: This I think will dup multiple renderStartupEvent calls...
|
||||
// FIXME: This I think will dup multiple renderStartupEvent calls...
|
||||
@Inject(method = {"reloadShaders", "preloadUiShader", "preloadShader"}, at = @At("TAIL"))
|
||||
public void onStartupShaders(CallbackInfo ci) {
|
||||
SharedApi.LOGGER.info("Starting up renderer");
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.fabric.mixins.client;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.math.Matrix4f;
|
||||
import com.seibel.lod.common.wrappers.world.LevelWrapper;
|
||||
import com.seibel.lod.core.config.Config;
|
||||
import com.seibel.lod.common.wrappers.McObjectConverter;
|
||||
import com.seibel.lod.core.api.internal.a7.ClientApi;
|
||||
import com.seibel.lod.core.objects.math.Mat4f;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.renderer.LevelRenderer;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import org.lwjgl.opengl.GL15;
|
||||
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(LevelWrapper.getWorldWrapper(level), mcModelViewMatrix, mcProjectionMatrix, previousPartialTicks);
|
||||
}
|
||||
if (Config.Client.Advanced.lodOnlyMode.get()) {
|
||||
callback.cancel();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
+1
-3
@@ -22,8 +22,6 @@ package com.seibel.lod.fabric.mixins.server;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.seibel.lod.fabric.FabricClientProxy;
|
||||
import com.seibel.lod.fabric.FabricDedicatedServerMain;
|
||||
import com.seibel.lod.fabric.FabricServerProxy;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
@@ -35,7 +33,7 @@ import com.seibel.lod.core.util.DummyRunExecutorService;
|
||||
import net.minecraft.Util;
|
||||
|
||||
@Mixin(Util.class)
|
||||
public class MixinUtilBackgroudThread
|
||||
public class MixinUtilBackgroundThread
|
||||
{
|
||||
@Inject(method = "backgroundExecutor", at = @At("HEAD"), cancellable = true)
|
||||
private static void overrideUtil$backgroundExecutor(CallbackInfoReturnable<ExecutorService> ci)
|
||||
+1
-2
@@ -19,7 +19,6 @@
|
||||
|
||||
package com.seibel.lod.fabric.mixins.server.unsafe;
|
||||
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
//FIXME: Is this still needed?
|
||||
@@ -38,7 +37,7 @@ 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 MixinThreadingDectector {
|
||||
public class MixinThreadingDetector {
|
||||
@Mutable
|
||||
@Shadow
|
||||
private Semaphore lock;
|
||||
@@ -3,10 +3,10 @@
|
||||
"minVersion": "0.8",
|
||||
"package": "com.seibel.lod.fabric.mixins",
|
||||
"mixins": [
|
||||
"server.unsafe.MixinThreadingDectector",
|
||||
"server.unsafe.MixinThreadingDetector",
|
||||
"server.MixinChunkGenerator",
|
||||
"server.MixinChunkMap",
|
||||
"server.MixinUtilBackgroudThread"
|
||||
"server.MixinUtilBackgroundThread"
|
||||
],
|
||||
"client": [
|
||||
"client.MixinClientLevel",
|
||||
@@ -14,6 +14,7 @@
|
||||
"client.MixinDebugScreenOverlay",
|
||||
"client.MixinFogRenderer",
|
||||
"client.MixinGameRenderer",
|
||||
"client.MixinLevelRenderer",
|
||||
"client.MixinLightmap",
|
||||
"client.MixinOptionsScreen"
|
||||
],
|
||||
|
||||
@@ -20,21 +20,20 @@
|
||||
package com.seibel.lod.forge;
|
||||
|
||||
import com.seibel.lod.common.wrappers.world.LevelWrapper;
|
||||
import com.seibel.lod.core.api.internal.ClientApi;
|
||||
import com.seibel.lod.core.api.internal.EventApi;
|
||||
import com.seibel.lod.core.api.internal.a7.ClientApi;
|
||||
import com.seibel.lod.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||
|
||||
import net.minecraft.client.gui.screens.TitleScreen;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraftforge.event.world.ChunkDataEvent;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import com.seibel.lod.common.wrappers.chunk.ChunkWrapper;
|
||||
import com.seibel.lod.common.wrappers.world.DimensionTypeWrapper;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraftforge.client.event.InputEvent;
|
||||
import net.minecraftforge.event.TickEvent;
|
||||
import net.minecraftforge.event.world.BlockEvent;
|
||||
import net.minecraftforge.event.world.ChunkEvent;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
|
||||
@@ -47,72 +46,132 @@ import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
*/
|
||||
public class ForgeClientProxy
|
||||
{
|
||||
private final EventApi eventApi = EventApi.INSTANCE;
|
||||
private final ClientApi clientApi = ClientApi.INSTANCE;
|
||||
|
||||
|
||||
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
|
||||
@SubscribeEvent
|
||||
public void serverTickEvent(TickEvent.ServerTickEvent event)
|
||||
public void clientTickEvent(TickEvent.ClientTickEvent event)
|
||||
{
|
||||
if (event.phase != TickEvent.Phase.START) return;
|
||||
eventApi.serverTickEvent();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void chunkLoadEvent(ChunkEvent.Load event)
|
||||
{
|
||||
clientApi.clientChunkLoadEvent(new ChunkWrapper(event.getChunk(), event.getWorld()), LevelWrapper.getWorldWrapper(event.getWorld()));
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void worldSaveEvent(WorldEvent.Save event)
|
||||
{
|
||||
eventApi.worldSaveEvent();
|
||||
}
|
||||
|
||||
/** This is also called when a new dimension loads */
|
||||
@SubscribeEvent
|
||||
public void worldLoadEvent(WorldEvent.Load event)
|
||||
{
|
||||
if (Minecraft.getInstance().screen instanceof TitleScreen) return;
|
||||
if (event.getWorld() != null) {
|
||||
eventApi.worldLoadEvent(LevelWrapper.getWorldWrapper(event.getWorld()));
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void worldUnloadEvent(WorldEvent.Unload event)
|
||||
{
|
||||
eventApi.worldUnloadEvent(LevelWrapper.getWorldWrapper(event.getWorld()));
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void blockChangeEvent(BlockEvent event)
|
||||
{
|
||||
// we only care about certain block events
|
||||
if (event.getClass() == BlockEvent.BreakEvent.class ||
|
||||
event.getClass() == BlockEvent.EntityPlaceEvent.class ||
|
||||
event.getClass() == BlockEvent.EntityMultiPlaceEvent.class ||
|
||||
event.getClass() == BlockEvent.FluidPlaceBlockEvent.class ||
|
||||
event.getClass() == BlockEvent.PortalSpawnEvent.class)
|
||||
if (event.phase == TickEvent.Phase.START)
|
||||
{
|
||||
IChunkWrapper chunk = new ChunkWrapper(event.getWorld().getChunk(event.getPos()), event.getWorld());
|
||||
DimensionTypeWrapper dimType = DimensionTypeWrapper.getDimensionTypeWrapper(event.getWorld().dimensionType());
|
||||
|
||||
// recreate the LOD where the blocks were changed
|
||||
eventApi.blockChangeEvent(chunk, dimType);
|
||||
ClientApi.INSTANCE.clientTickEvent();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SubscribeEvent
|
||||
public void onKeyInput(InputEvent.KeyInputEvent event)
|
||||
public void clientLevelLoadEvent(WorldEvent.Load event)
|
||||
{
|
||||
if (event.getWorld() instanceof ClientLevel)
|
||||
{
|
||||
LevelWrapper level = new LevelWrapper(event.getWorld());
|
||||
ClientApi.INSTANCE.clientLevelLoadEvent(level);
|
||||
}
|
||||
}
|
||||
@SubscribeEvent
|
||||
public void clientLevelUnloadEvent(WorldEvent.Unload event)
|
||||
{
|
||||
if (event.getWorld() instanceof ClientLevel)
|
||||
{
|
||||
LevelWrapper level = new LevelWrapper(event.getWorld());
|
||||
ClientApi.INSTANCE.clientLevelUnloadEvent(level);
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void clientChunkLoadEvent(ChunkDataEvent.Load event)
|
||||
{
|
||||
if (event.getWorld() instanceof ClientLevel)
|
||||
{
|
||||
IChunkWrapper chunk = new ChunkWrapper(event.getChunk(), event.getWorld());
|
||||
LevelWrapper level = new LevelWrapper(event.getWorld());
|
||||
ClientApi.INSTANCE.clientChunkLoadEvent(chunk, level);
|
||||
}
|
||||
}
|
||||
@SubscribeEvent
|
||||
public void clientChunkSaveEvent(ChunkDataEvent.Save event)
|
||||
{
|
||||
if (event.getWorld() instanceof ClientLevel)
|
||||
{
|
||||
IChunkWrapper chunk = new ChunkWrapper(event.getChunk(), event.getWorld());
|
||||
LevelWrapper level = new LevelWrapper(event.getWorld());
|
||||
ClientApi.INSTANCE.clientChunkSaveEvent(chunk, level);
|
||||
}
|
||||
}
|
||||
|
||||
// RendererStartupEvent - Done in MixinGameRenderer
|
||||
// RendererShutdownEvent - Done in MixinGameRenderer
|
||||
// ClientRenderLevelTerrainEvent - Done in MixinGameRenderer
|
||||
|
||||
// Register KeyBindings
|
||||
@SubscribeEvent
|
||||
public void registerKeyBindings(InputEvent.KeyInputEvent event)
|
||||
{
|
||||
if (Minecraft.getInstance().player == null) return;
|
||||
if (event.getAction() != GLFW.GLFW_PRESS) return;
|
||||
clientApi.keyPressedEvent(event.getKey());
|
||||
ClientApi.INSTANCE.keyPressedEvent(event.getKey());
|
||||
}
|
||||
|
||||
|
||||
// @SubscribeEvent
|
||||
// public void serverTickEvent(TickEvent.ServerTickEvent event)
|
||||
// {
|
||||
// if (event.phase != TickEvent.Phase.START) return;
|
||||
// eventApi.serverTickEvent();
|
||||
// }
|
||||
////
|
||||
//
|
||||
// @SubscribeEvent
|
||||
// public void chunkLoadEvent(ChunkEvent.Load event)
|
||||
// {
|
||||
// clientApi.clientChunkLoadEvent(new ChunkWrapper(event.getChunk(), event.getWorld()), LevelWrapper.getWorldWrapper(event.getWorld()));
|
||||
// }
|
||||
//
|
||||
// @SubscribeEvent
|
||||
// public void worldSaveEvent(WorldEvent.Save event)
|
||||
// {
|
||||
// eventApi.worldSaveEvent();
|
||||
// }
|
||||
//
|
||||
// /** This is also called when a new dimension loads */
|
||||
// @SubscribeEvent
|
||||
// public void worldLoadEvent(WorldEvent.Load event)
|
||||
// {
|
||||
// if (Minecraft.getInstance().screen instanceof TitleScreen) return;
|
||||
// if (event.getWorld() != null) {
|
||||
// eventApi.worldLoadEvent(LevelWrapper.getWorldWrapper(event.getWorld()));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @SubscribeEvent
|
||||
// public void worldUnloadEvent(WorldEvent.Unload event)
|
||||
// {
|
||||
// eventApi.worldUnloadEvent(LevelWrapper.getWorldWrapper(event.getWorld()));
|
||||
// }
|
||||
//
|
||||
// @SubscribeEvent
|
||||
// public void blockChangeEvent(BlockEvent event)
|
||||
// {
|
||||
// // we only care about certain block events
|
||||
// if (event.getClass() == BlockEvent.BreakEvent.class ||
|
||||
// event.getClass() == BlockEvent.EntityPlaceEvent.class ||
|
||||
// event.getClass() == BlockEvent.EntityMultiPlaceEvent.class ||
|
||||
// event.getClass() == BlockEvent.FluidPlaceBlockEvent.class ||
|
||||
// event.getClass() == BlockEvent.PortalSpawnEvent.class)
|
||||
// {
|
||||
// IChunkWrapper chunk = new ChunkWrapper(event.getWorld().getChunk(event.getPos()), event.getWorld());
|
||||
// DimensionTypeWrapper dimType = DimensionTypeWrapper.getDimensionTypeWrapper(event.getWorld().dimensionType());
|
||||
//
|
||||
// // recreate the LOD where the blocks were changed
|
||||
// eventApi.blockChangeEvent(chunk, dimType);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @SubscribeEvent
|
||||
// public void onKeyInput(InputEvent.KeyInputEvent event)
|
||||
// {
|
||||
// if (Minecraft.getInstance().player == null) return;
|
||||
// if (event.getAction() != GLFW.GLFW_PRESS) return;
|
||||
// clientApi.keyPressedEvent(event.getKey());
|
||||
// }
|
||||
//
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -21,12 +21,13 @@ package com.seibel.lod.forge;
|
||||
|
||||
import com.seibel.lod.common.LodCommonMain;
|
||||
import com.seibel.lod.common.forge.LodForgeMethodCaller;
|
||||
import com.seibel.lod.common.wrappers.DependencySetup;
|
||||
import com.seibel.lod.common.wrappers.config.GetConfigScreen;
|
||||
import com.seibel.lod.common.wrappers.minecraft.MinecraftClientWrapper;
|
||||
import com.seibel.lod.core.ModInfo;
|
||||
import com.seibel.lod.core.api.internal.InternalApiShared;
|
||||
import com.seibel.lod.core.handlers.ReflectionHandler;
|
||||
import com.seibel.lod.core.handlers.dependencyInjection.ModAccessorInjector;
|
||||
import com.seibel.lod.core.handlers.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.lod.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.lod.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
|
||||
import com.seibel.lod.forge.wrappers.ForgeDependencySetup;
|
||||
@@ -46,8 +47,7 @@ import net.minecraftforge.client.model.data.ModelDataMap;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.fml.ModLoadingContext;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||
import net.minecraftforge.fml.event.lifecycle.*;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
#if PRE_MC_1_17_1
|
||||
import net.minecraftforge.fml.ExtensionPoint;
|
||||
@@ -74,33 +74,48 @@ import java.util.Random;
|
||||
public class ForgeMain implements LodForgeMethodCaller
|
||||
{
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
|
||||
|
||||
public static ForgeClientProxy forgeClientProxy;
|
||||
|
||||
|
||||
private void init(final FMLCommonSetupEvent event)
|
||||
{
|
||||
// make sure the dependencies are set up before the mod needs them
|
||||
// LodCommonMain.startup(this, !FMLLoader.getDist().isClient());
|
||||
LodCommonMain.startup(this);
|
||||
ForgeDependencySetup.createInitialBindings();
|
||||
LodCommonMain.initConfig();
|
||||
LOGGER.info(ModInfo.READABLE_NAME + " initializing...");
|
||||
}
|
||||
|
||||
public static ForgeClientProxy client_proxy = null;
|
||||
public static ForgeServerProxy server_proxy = null;
|
||||
|
||||
public ForgeMain()
|
||||
{
|
||||
// Register the methods for server and other game events we are interested in
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::init);
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onClientStart);
|
||||
// Register the mod initializer (Actual event registration is done in the different proxies)
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::initClient);
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::initDedicated);
|
||||
}
|
||||
|
||||
private void onClientStart(final FMLClientSetupEvent event)
|
||||
private void initClient(final FMLClientSetupEvent event)
|
||||
{
|
||||
DependencySetup.createClientBindings();
|
||||
initCommon();
|
||||
|
||||
client_proxy = new ForgeClientProxy();
|
||||
MinecraftForge.EVENT_BUS.register(client_proxy);
|
||||
server_proxy = new ForgeServerProxy(false);
|
||||
MinecraftForge.EVENT_BUS.register(server_proxy);
|
||||
|
||||
postInitCommon();
|
||||
}
|
||||
|
||||
private void initDedicated(final FMLDedicatedServerSetupEvent event)
|
||||
{
|
||||
DependencySetup.createServerBindings();
|
||||
initCommon();
|
||||
|
||||
server_proxy = new ForgeServerProxy(true);
|
||||
MinecraftForge.EVENT_BUS.register(server_proxy);
|
||||
|
||||
postInitCommon();
|
||||
}
|
||||
|
||||
private void initCommon() {
|
||||
LodCommonMain.startup(this);
|
||||
ForgeDependencySetup.createInitialBindings();
|
||||
LOGGER.info(ModInfo.READABLE_NAME + ", Version: " + ModInfo.VERSION);
|
||||
|
||||
if (ReflectionHandler.instance.optifinePresent()) {
|
||||
ModAccessorInjector.bind(IOptifineAccessor.class, new OptifineAccessor());
|
||||
ModAccessorInjector.INSTANCE.bind(IOptifineAccessor.class, new OptifineAccessor());
|
||||
}
|
||||
|
||||
#if PRE_MC_1_17_1
|
||||
ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.CONFIGGUIFACTORY,
|
||||
() -> (client, parent) -> GetConfigScreen.getScreen(parent));
|
||||
@@ -108,8 +123,13 @@ public class ForgeMain implements LodForgeMethodCaller
|
||||
ModLoadingContext.get().registerExtensionPoint(ConfigGuiHandler.ConfigGuiFactory.class,
|
||||
() -> new ConfigGuiHandler.ConfigGuiFactory((client, parent) -> GetConfigScreen.getScreen(parent)));
|
||||
#endif
|
||||
forgeClientProxy = new ForgeClientProxy();
|
||||
MinecraftForge.EVENT_BUS.register(forgeClientProxy);
|
||||
}
|
||||
|
||||
private void postInitCommon() {
|
||||
LOGGER.info("Post-Initializing Mod");
|
||||
SingletonInjector.INSTANCE.runDelayedSetup();
|
||||
LodCommonMain.initConfig();
|
||||
LOGGER.info("Mod Post-Initialized");
|
||||
}
|
||||
|
||||
private final ModelDataMap dataMap = new ModelDataMap.Builder().build();
|
||||
@@ -124,7 +144,7 @@ public class ForgeMain implements LodForgeMethodCaller
|
||||
}
|
||||
#endif
|
||||
|
||||
@Override
|
||||
@Override //TODO: Check this if its still needed
|
||||
public int colorResolverGetColor(ColorResolver resolver, Biome biome, double x, double z) {
|
||||
#if MC_1_17_1______Still_needed
|
||||
return resolver.m_130045_(biome, x, z);
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
package com.seibel.lod.forge;
|
||||
|
||||
import com.seibel.lod.common.networking.Networking;
|
||||
import com.seibel.lod.common.wrappers.chunk.ChunkWrapper;
|
||||
import com.seibel.lod.common.wrappers.world.LevelWrapper;
|
||||
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||
import com.seibel.lod.core.api.internal.a7.ClientApi;
|
||||
import com.seibel.lod.core.api.internal.a7.ServerApi;
|
||||
import com.seibel.lod.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screens.TitleScreen;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraftforge.event.TickEvent;
|
||||
import net.minecraftforge.event.server.ServerStartedEvent;
|
||||
import net.minecraftforge.event.server.ServerStoppingEvent;
|
||||
import net.minecraftforge.event.world.ChunkDataEvent;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ForgeServerProxy {
|
||||
private final ServerApi serverApi = ServerApi.INSTANCE;
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
private final boolean isDedicated;
|
||||
public static Supplier<Boolean> isGenerationThreadChecker = null;
|
||||
|
||||
public ForgeServerProxy(boolean isDedicated) {
|
||||
this.isDedicated = isDedicated;
|
||||
isGenerationThreadChecker = BatchGenerationEnvironment::isCurrentThreadDistantGeneratorThread;
|
||||
}
|
||||
private boolean isValidTime() {
|
||||
if (isDedicated) return true;
|
||||
|
||||
//FIXME: This may cause init issue...
|
||||
return !(Minecraft.getInstance().screen instanceof TitleScreen);
|
||||
}
|
||||
private LevelWrapper getLevelWrapper(Level level) {
|
||||
return LevelWrapper.getWorldWrapper(level);
|
||||
}
|
||||
|
||||
|
||||
// ServerTickEvent (at end)
|
||||
@SubscribeEvent
|
||||
private void serverTickEvent(TickEvent.ServerTickEvent event) {
|
||||
if (event.phase == TickEvent.Phase.END) {
|
||||
if (isValidTime()) serverApi.serverTickEvent();
|
||||
}
|
||||
}
|
||||
|
||||
// ServerWorldLoadEvent
|
||||
@SubscribeEvent
|
||||
private void dedicatedWorldLoadEvent(ServerStartedEvent event) {
|
||||
if (isValidTime()) serverApi.serverWorldLoadEvent(isDedicated);
|
||||
}
|
||||
|
||||
// ServerWorldUnloadEvent
|
||||
@SubscribeEvent
|
||||
private void serverWorldUnloadEvent(ServerStoppingEvent event) {
|
||||
if (isValidTime()) serverApi.serverWorldUnloadEvent();
|
||||
}
|
||||
|
||||
// ServerLevelLoadEvent
|
||||
@SubscribeEvent
|
||||
private void serverLevelLoadEvent(WorldEvent.Load event) {
|
||||
if (isValidTime()) {
|
||||
if (event.getWorld() instanceof ServerLevel) {
|
||||
serverApi.serverLevelLoadEvent(getLevelWrapper((Level) event.getWorld()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ServerLevelUnloadEvent
|
||||
@SubscribeEvent
|
||||
private void serverLevelUnloadEvent(WorldEvent.Unload event) {
|
||||
if (isValidTime()) {
|
||||
if (event.getWorld() instanceof ServerLevel) {
|
||||
serverApi.serverLevelUnloadEvent(getLevelWrapper((Level) event.getWorld()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void serverChunkLoadEvent(ChunkDataEvent.Load event)
|
||||
{
|
||||
if (isValidTime()) {
|
||||
if (event.getWorld() instanceof ServerLevel) {
|
||||
IChunkWrapper chunk = new ChunkWrapper(event.getChunk(), event.getWorld());
|
||||
LevelWrapper level = new LevelWrapper(event.getWorld());
|
||||
ClientApi.INSTANCE.clientChunkLoadEvent(chunk, level);
|
||||
}
|
||||
}
|
||||
}
|
||||
@SubscribeEvent
|
||||
public void serverChunkSaveEvent(ChunkDataEvent.Save event)
|
||||
{
|
||||
if (isValidTime()) {
|
||||
if (event.getWorld() instanceof ServerLevel) {
|
||||
IChunkWrapper chunk = new ChunkWrapper(event.getChunk(), event.getWorld());
|
||||
LevelWrapper level = new LevelWrapper(event.getWorld());
|
||||
ClientApi.INSTANCE.clientChunkSaveEvent(chunk, level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This just exists here for testing purposes, it'll be removed in the future
|
||||
public void tester(MinecraftServer server) {
|
||||
for (ServerPlayer player : server.getPlayerList().getPlayers()) {
|
||||
FriendlyByteBuf payload = Networking.createNew();
|
||||
payload.writeInt(1);
|
||||
System.out.println("Sending int 1");
|
||||
Networking.send(player, payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.seibel.lod.forge.mixins;
|
||||
package com.seibel.lod.forge.mixins.client;
|
||||
|
||||
import com.seibel.lod.core.render.F3Screen;
|
||||
import net.minecraft.client.gui.components.DebugScreenOverlay;
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.forge.mixins;
|
||||
package com.seibel.lod.forge.mixins.client;
|
||||
|
||||
import com.seibel.lod.core.config.Config;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.seibel.lod.forge.mixins.client;
|
||||
|
||||
import com.seibel.lod.core.api.internal.a7.ClientApi;
|
||||
import com.seibel.lod.core.api.internal.a7.SharedApi;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
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;
|
||||
|
||||
// TODO: Check if this port from fabric works
|
||||
@Mixin(GameRenderer.class)
|
||||
public class MixinGameRenderer {
|
||||
#if POST_MC_1_17_1
|
||||
@Inject(method = "shutdownShaders", at = @At("HEAD"))
|
||||
public void onShutdownShaders(CallbackInfo ci) {
|
||||
SharedApi.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) {
|
||||
SharedApi.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) {
|
||||
SharedApi.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) {
|
||||
SharedApi.LOGGER.info("Starting up renderer");
|
||||
ClientApi.INSTANCE.rendererStartupEvent();
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
+16
-7
@@ -17,22 +17,27 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.forge.mixins;
|
||||
package com.seibel.lod.forge.mixins.client;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.math.Matrix4f;
|
||||
import com.seibel.lod.common.wrappers.McObjectConverter;
|
||||
import com.seibel.lod.common.wrappers.world.LevelWrapper;
|
||||
import com.seibel.lod.core.config.Config;
|
||||
import com.seibel.lod.core.api.internal.ClientApi;
|
||||
import com.seibel.lod.core.api.internal.a7.ClientApi;
|
||||
import com.seibel.lod.core.objects.math.Mat4f;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.renderer.LevelRenderer;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import org.lwjgl.opengl.GL15;
|
||||
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;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* This class is used to mix in my rendering code
|
||||
* before Minecraft starts rendering blocks.
|
||||
@@ -47,11 +52,15 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
* @version 12-31-2021
|
||||
*/
|
||||
@Mixin(LevelRenderer.class)
|
||||
public class MixinWorldRenderer
|
||||
public class MixinLevelRenderer
|
||||
{
|
||||
@Shadow
|
||||
private ClientLevel level;
|
||||
|
||||
@Unique
|
||||
private static float previousPartialTicks = 0;
|
||||
|
||||
public MixinWorldRenderer() {
|
||||
public MixinLevelRenderer() {
|
||||
throw new NullPointerException("Null cannot be cast to non-null type.");
|
||||
}
|
||||
|
||||
@@ -79,7 +88,7 @@ public class MixinWorldRenderer
|
||||
mcProjectionMatrix.transpose();
|
||||
Mat4f mcModelViewMatrix = McObjectConverter.Convert(matrixStackIn.last().pose());
|
||||
|
||||
ClientApi.INSTANCE.renderLods(mcModelViewMatrix, mcProjectionMatrix, previousPartialTicks);
|
||||
ClientApi.INSTANCE.renderLods(LevelWrapper.getWorldWrapper(level), mcModelViewMatrix, mcProjectionMatrix, previousPartialTicks);
|
||||
}
|
||||
if (Config.Client.Advanced.lodOnlyMode.get()) {
|
||||
callback.cancel();
|
||||
@@ -104,7 +113,7 @@ public class MixinWorldRenderer
|
||||
Mat4f mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrixStack.last().pose());
|
||||
Mat4f mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
|
||||
|
||||
ClientApi.INSTANCE.renderLods(mcModelViewMatrix, mcProjectionMatrix, previousPartialTicks);
|
||||
ClientApi.INSTANCE.renderLods(LevelWrapper.getWorldWrapper(level), mcModelViewMatrix, mcProjectionMatrix, previousPartialTicks);
|
||||
}
|
||||
if (Config.Client.Advanced.lodOnlyMode.get()) {
|
||||
callback.cancel();
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.seibel.lod.forge.mixins;
|
||||
package com.seibel.lod.forge.mixins.client;
|
||||
|
||||
|
||||
import com.mojang.blaze3d.platform.NativeImage;
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.forge.mixins;
|
||||
package com.seibel.lod.forge.mixins.client;
|
||||
|
||||
import com.seibel.lod.common.wrappers.config.GetConfigScreen;
|
||||
import com.seibel.lod.common.wrappers.config.TexturedButtonWidget;
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.forge.mixins;
|
||||
package com.seibel.lod.forge.mixins.server;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.seibel.lod.forge.mixins;
|
||||
package com.seibel.lod.forge.mixins.server;
|
||||
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
+2
-2
@@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.forge.mixins;
|
||||
package com.seibel.lod.forge.mixins.server;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.function.Supplier;
|
||||
@@ -33,7 +33,7 @@ import com.seibel.lod.core.util.DummyRunExecutorService;
|
||||
import net.minecraft.Util;
|
||||
|
||||
@Mixin(Util.class)
|
||||
public class MixinUtilBackgroudThread
|
||||
public class MixinUtilBackgroundThread
|
||||
{
|
||||
|
||||
private static boolean shouldApplyOverride() {
|
||||
+2
-3
@@ -17,9 +17,8 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.forge.mixins.unsafe;
|
||||
package com.seibel.lod.forge.mixins.server.unsafe;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
#if POST_MC_1_18_1
|
||||
|
||||
import net.minecraft.util.ThreadingDetector;
|
||||
@@ -36,7 +35,7 @@ import java.util.concurrent.Semaphore;
|
||||
* FIXME: Recheck this
|
||||
*/
|
||||
@Mixin(ThreadingDetector.class)
|
||||
public class MixinThreadingDectector {
|
||||
public class MixinThreadingDetector {
|
||||
@Mutable
|
||||
@Shadow
|
||||
private Semaphore lock;
|
||||
@@ -3,16 +3,18 @@
|
||||
"minVersion": "0.8",
|
||||
"package": "com.seibel.lod.forge.mixins",
|
||||
"mixins": [
|
||||
"MixinUtilBackgroudThread"
|
||||
"server.unsafe.MixinThreadingDetector",
|
||||
"server.MixinUtilBackgroundThread",
|
||||
"server.MixinChunkGenerator",
|
||||
"server.MixinTFChunkGenerator"
|
||||
],
|
||||
"client": [
|
||||
"MixinOptionsScreen",
|
||||
"MixinWorldRenderer",
|
||||
"MixinFogRenderer",
|
||||
"MixinChunkGenerator",
|
||||
"MixinLightmap",
|
||||
"MixinTFChunkGenerator",
|
||||
"MixinDebugScreenOverlay"
|
||||
"client.MixinDebugScreenOverlay",
|
||||
"client.MixinFogRenderer",
|
||||
"client.MixinGameRenderer",
|
||||
"client.MixinLevelRenderer",
|
||||
"client.MixinLightmap",
|
||||
"client.MixinOptionsScreen"
|
||||
],
|
||||
"server": []
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user