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:
TomTheFurry
2022-07-25 19:44:12 +08:00
parent 69202b86cd
commit 640c6b8a9c
26 changed files with 503 additions and 131 deletions
@@ -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);
@@ -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());
@@ -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() {}
@@ -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
}
@@ -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)
@@ -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,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;
@@ -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
}
@@ -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,4 +1,4 @@
package com.seibel.lod.forge.mixins;
package com.seibel.lod.forge.mixins.client;
import com.mojang.blaze3d.platform.NativeImage;
@@ -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;
@@ -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,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;
@@ -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() {
@@ -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;
+10 -8
View File
@@ -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": []
}