From 87fdfc50489d9e6ba2e1fad0569070b114f798df Mon Sep 17 00:00:00 2001 From: TomTheFurry Date: Wed, 1 Jun 2022 22:55:58 +0800 Subject: [PATCH] Working on actually hook up events to use new one --- core | 2 +- .../com/seibel/lod/fabric/ClientProxy.java | 109 +++++----------- .../seibel/lod/fabric/FabricServerProxy.java | 59 +++++++-- .../lod/fabric/mixins/MixinWorldRenderer.java | 117 ------------------ .../{events => client}/MixinClientLevel.java | 12 +- .../client/MixinClientPacketListener.java | 11 ++ .../mixins/client/MixinGameRenderer.java | 25 ++++ .../{events => client}/MixinMinecraft.java | 0 .../src/main/resources/fabric.lod.mixins.json | 3 +- 9 files changed, 134 insertions(+), 204 deletions(-) delete mode 100644 fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinWorldRenderer.java rename fabric/src/main/java/com/seibel/lod/fabric/mixins/{events => client}/MixinClientLevel.java (79%) create mode 100644 fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinClientPacketListener.java create mode 100644 fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinGameRenderer.java rename fabric/src/main/java/com/seibel/lod/fabric/mixins/{events => client}/MixinMinecraft.java (100%) diff --git a/core b/core index 94b20a363..f4f186ff7 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit 94b20a363d33460a44d2507e2deb19fae53abab1 +Subproject commit f4f186ff7824994e2876cde892cc07a638f8006f diff --git a/fabric/src/main/java/com/seibel/lod/fabric/ClientProxy.java b/fabric/src/main/java/com/seibel/lod/fabric/ClientProxy.java index cf7d433a4..e7cf3b983 100644 --- a/fabric/src/main/java/com/seibel/lod/fabric/ClientProxy.java +++ b/fabric/src/main/java/com/seibel/lod/fabric/ClientProxy.java @@ -19,9 +19,11 @@ package com.seibel.lod.fabric; +import com.seibel.lod.common.wrappers.McObjectConverter; import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment; -import com.seibel.lod.core.api.internal.ClientApi; -import com.seibel.lod.core.api.internal.EventApi; +import com.seibel.lod.core.api.internal.a7.ClientApi; +import com.seibel.lod.core.api.internal.a7.ServerApi; +import com.seibel.lod.core.config.Config; import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler; import com.mojang.blaze3d.platform.InputConstants; import com.seibel.lod.common.wrappers.chunk.ChunkWrapper; @@ -30,8 +32,10 @@ import com.seibel.lod.common.wrappers.world.WorldWrapper; import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper; import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientChunkEvents; +import dev.architectury.init.fabric.ArchitecturyClient; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents; import net.minecraft.client.Minecraft; @@ -57,7 +61,7 @@ import org.lwjgl.glfw.GLFW; */ public class ClientProxy { - private final EventApi eventApi = EventApi.INSTANCE; + private final ServerApi serverApi = ServerApi.INSTANCE; private final ClientApi clientApi = ClientApi.INSTANCE; public static Supplier isGenerationThreadChecker = null; @@ -69,92 +73,50 @@ public class ClientProxy public void registerEvents() { /* Register the mod accessor*/ - /* World Events */ - //ServerTickEvents.START_SERVER_TICK.register(this::serverTickEvent); - ServerTickEvents.END_SERVER_TICK.register(this::serverTickEvent); - - /* World Events */ - //ServerChunkEvents.CHUNK_LOAD.register(this::chunkLoadEvent); + //TODO: ClientChunkLoadEvent #if PRE_MC_1_18_1 // in 1.18+, we use mixin hook in setClientLightReady(true) ClientChunkEvents.CHUNK_LOAD.register(this::chunkLoadEvent); #endif + //TODO: ClientChunkSaveEvent - /* World Events */ - ServerWorldEvents.LOAD.register((server, level) -> this.worldLoadEvent(level)); - ServerWorldEvents.UNLOAD.register((server, level) -> this.worldUnloadEvent(level)); - - /* The Client World Events are in the mixins + /* The Client Level Events are in the mixins Client world load event is in MixinClientLevel - Client world unload event is in MixinMinecraft */ - /* The save events are in MixinServerLevel */ + Client world unload event is in ??? */ + //TODO: ClientLevelLoadEvent + //TODO: ClientLevelUnloadEvent + + //TODO: ClientRenderInitEvent + //TODO: ClientRenderFreeEvent + //TODO: ClientRenderStartEvent + //TODO: ClientRenderLevelTerrainEvent + WorldRenderEvents.AFTER_SETUP.register((renderContext) -> { + clientApi.renderLods(getLevelWrapper(renderContext.world()), + McObjectConverter.Convert(renderContext.projectionMatrix()), + McObjectConverter.Convert(renderContext.matrixStack().last().pose()), + renderContext.tickDelta()); + }); /* Keyboard Events */ ClientTickEvents.END_CLIENT_TICK.register(client -> { - if (client.player != null) onKeyInput(); + if (client.player != null && isValidTime()) onKeyInput(); }); isGenerationThreadChecker = BatchGenerationEnvironment::isCurrentThreadDistantGeneratorThread; - } - - public void serverTickEvent(MinecraftServer server) - { - eventApi.serverTickEvent(); + private boolean isValidTime() { + return !(Minecraft.getInstance().screen instanceof TitleScreen); + } + private WorldWrapper getLevelWrapper(Level level) { + return WorldWrapper.getWorldWrapper(level); } - public void chunkLoadEvent(LevelAccessor level, LevelChunk chunk) - { - clientApi.clientChunkLoadEvent(new ChunkWrapper(chunk, level), - WorldWrapper.getWorldWrapper(level)); - } - - public void worldSaveEvent() - { - eventApi.worldSaveEvent(); - } - - /** This is also called when a new dimension loads */ - public void worldLoadEvent(Level level) - { - if (Minecraft.getInstance().screen instanceof TitleScreen) return; - if (level != null) { - eventApi.worldLoadEvent(WorldWrapper.getWorldWrapper(level)); - } - } - - public void worldUnloadEvent(Level level) - { - if (level != null) { - eventApi.worldUnloadEvent(WorldWrapper.getWorldWrapper(level)); - } - } - - /** - * Can someone tell me how to make this better - * @author Ran - * - * public void blockChangeEvent(BlockEventData event) { - * // we only care about certain block events - * if (event.getClass() == BlockEventData.BreakEvent.class || - * event.getClass() == BlockEventData.EntityPlaceEvent.class || - * event.getClass() == BlockEventData.EntityMultiPlaceEvent.class || - * event.getClass() == BlockEventData.FluidPlaceBlockEvent.class || - * event.getClass() == BlockEventData.PortalSpawnEvent.class) - * { - * IChunkWrapper chunk = new ChunkWrapper(event.getWorld().getChunk(event.getPos())); - * DimensionTypeWrapper dimType = DimensionTypeWrapper.getDimensionTypeWrapper(event.getWorld().dimensionType()); - * - * // recreate the LOD where the blocks were changed - * eventApi.blockChangeEvent(chunk, dimType); - * } - * } - */ public void blockChangeEvent(LevelAccessor world, BlockPos pos) { + if (!isValidTime()) return; IChunkWrapper chunk = new ChunkWrapper(world.getChunk(pos), world); DimensionTypeWrapper dimType = DimensionTypeWrapper.getDimensionTypeWrapper(world.dimensionType()); // recreate the LOD where the blocks were changed - eventApi.blockChangeEvent(chunk, dimType); + // TODO: serverApi.blockChangeEvent(chunk, dimType); } private static final int[] KEY_TO_CHECK_FOR = {GLFW.GLFW_KEY_F6, GLFW.GLFW_KEY_F8}; @@ -162,8 +124,7 @@ public class ClientProxy HashSet previousKeyDown = new HashSet(); public void onKeyInput() { - ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class); - if (CONFIG.client().advanced().debugging().getDebugKeybindingsEnabled()) + if (Config.Client.Advanced.Debugging.enableDebugKeybindings.get()) { HashSet currentKeyDown = new HashSet(); @@ -180,14 +141,12 @@ public class ClientProxy currentKeyDown.add(i); } } - // Diff and trigger events for (int c : currentKeyDown) { if (!previousKeyDown.contains(c)) { ClientApi.INSTANCE.keyPressedEvent(c); } } - // Update the set previousKeyDown = currentKeyDown; } diff --git a/fabric/src/main/java/com/seibel/lod/fabric/FabricServerProxy.java b/fabric/src/main/java/com/seibel/lod/fabric/FabricServerProxy.java index d0b7af0b5..44a9be358 100644 --- a/fabric/src/main/java/com/seibel/lod/fabric/FabricServerProxy.java +++ b/fabric/src/main/java/com/seibel/lod/fabric/FabricServerProxy.java @@ -1,12 +1,22 @@ package com.seibel.lod.fabric; import com.seibel.lod.common.networking.Networking; -import com.seibel.lod.core.api.internal.EventApi; +import com.seibel.lod.common.wrappers.chunk.ChunkWrapper; +import com.seibel.lod.common.wrappers.world.WorldWrapper; +import com.seibel.lod.core.api.internal.a7.ServerApi; +import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerChunkEvents; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.TitleScreen; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; /** * This handles all events sent to the server, @@ -18,20 +28,55 @@ import net.minecraft.world.entity.player.Player; // TODO public class FabricServerProxy { - private final EventApi eventApi = EventApi.INSTANCE; + private final ServerApi serverApi = ServerApi.INSTANCE; + private boolean isValidTime() { + //FIXME: return true immediately if this is a dedicated server + return !(Minecraft.getInstance().screen instanceof TitleScreen); + } + private WorldWrapper getLevelWrapper(Level level) { + return WorldWrapper.getWorldWrapper(level); + } /** * Registers Fabric Events * @author Ran */ public void registerEvents() { - ServerTickEvents.END_SERVER_TICK.register(this::serverTickEvent); + ServerTickEvents.END_SERVER_TICK.register(this::tester); + /* World Events */ + ServerTickEvents.END_SERVER_TICK.register((server) -> serverApi.serverTickEvent()); + + /* Server World Events */ + ServerWorldEvents.LOAD.register((server, level) + -> { + if (isValidTime()) ServerApi.INSTANCE.serverLevelLoadEvent(getLevelWrapper(level)); + }); + ServerWorldEvents.UNLOAD.register((server, level) + -> { + if (isValidTime()) ServerApi.INSTANCE.serverLevelUnloadEvent(getLevelWrapper(level)); + }); + + ServerChunkEvents.CHUNK_LOAD.register((server, chunk) + -> { + IWorldWrapper level = getLevelWrapper(chunk.getLevel()); + if (isValidTime()) ServerApi.INSTANCE.serverChunkLoadEvent( + new ChunkWrapper(chunk, chunk.getLevel()), + level); + } + ); + //TODO: ServerChunkSaveEvent + + //TODO: Check if both of this use the correct timed events. (i.e. is it 'ed' or 'ing' one?) + ServerLifecycleEvents.SERVER_STARTED.register((server) -> { + if (isValidTime()) ServerApi.INSTANCE.serverWorldLoadEvent(); + }); + ServerLifecycleEvents.SERVER_STOPPING.register((server) -> { + if (isValidTime()) ServerApi.INSTANCE.serverWorldUnloadEvent(); + }); } - public void serverTickEvent(MinecraftServer server) { -// eventApi.serverTickEvent(); - - // This just exists here for testing purposes, it'll be removed in the future + // 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); diff --git a/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinWorldRenderer.java b/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinWorldRenderer.java deleted file mode 100644 index 731603b28..000000000 --- a/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinWorldRenderer.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * This file is part of the Distant Horizons mod (formerly the LOD Mod), - * licensed under the GNU LGPL v3 License. - * - * Copyright (C) 2020-2022 James Seibel - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.seibel.lod.fabric.mixins; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.math.Matrix4f; -import com.seibel.lod.common.wrappers.McObjectConverter; -import com.seibel.lod.core.config.Config; -import com.seibel.lod.core.api.internal.ClientApi; -import com.seibel.lod.core.objects.math.Mat4f; -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.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 MixinWorldRenderer -{ - private static float previousPartialTicks = 0; - - public MixinWorldRenderer() { - throw new NullPointerException("Null cannot be cast to non-null type."); - } - - - // 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(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(mcModelViewMatrix, mcProjectionMatrix, previousPartialTicks); - } - if (Config.Client.Advanced.lodOnlyMode.get()) { - callback.cancel(); - } - } - #endif -} diff --git a/fabric/src/main/java/com/seibel/lod/fabric/mixins/events/MixinClientLevel.java b/fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinClientLevel.java similarity index 79% rename from fabric/src/main/java/com/seibel/lod/fabric/mixins/events/MixinClientLevel.java rename to fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinClientLevel.java index d64894479..1a9d29373 100644 --- a/fabric/src/main/java/com/seibel/lod/fabric/mixins/events/MixinClientLevel.java +++ b/fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinClientLevel.java @@ -17,8 +17,13 @@ * along with this program. If not, see . */ -package com.seibel.lod.fabric.mixins.events; +package com.seibel.lod.fabric.mixins.client; +import com.seibel.lod.common.wrappers.chunk.ChunkWrapper; +import com.seibel.lod.common.wrappers.world.WorldWrapper; +import com.seibel.lod.core.api.internal.a7.ClientApi; +import com.seibel.lod.core.api.internal.a7.SharedApi; +import com.seibel.lod.core.config.Config; import com.seibel.lod.fabric.Main; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.ClientPacketListener; @@ -51,7 +56,8 @@ public class MixinClientLevel { 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) { - Main.client_proxy.worldLoadEvent((ClientLevel) (Object) this); + SharedApi.LOGGER.info("Loading level: " + WorldWrapper.getWorldWrapper((ClientLevel)(Object)this)); + ClientApi.INSTANCE.clientLevelLoadEvent(WorldWrapper.getWorldWrapper((ClientLevel)(Object)this)); } #if POST_MC_1_18_1 @@ -60,7 +66,7 @@ public class MixinClientLevel { ClientLevel l = (ClientLevel) (Object) this; LevelChunk chunk = l.getChunkSource().getChunk(x, z, false); if (chunk!=null&& !chunk.isClientLightReady()) - Main.client_proxy.chunkLoadEvent(l, chunk); + ClientApi.INSTANCE.clientChunkLoadEvent(new ChunkWrapper(chunk, l), WorldWrapper.getWorldWrapper(l)); } #endif } diff --git a/fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinClientPacketListener.java b/fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinClientPacketListener.java new file mode 100644 index 000000000..bc07d9cf0 --- /dev/null +++ b/fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinClientPacketListener.java @@ -0,0 +1,11 @@ +package com.seibel.lod.fabric.mixins.client; + +import net.minecraft.client.multiplayer.ClientPacketListener; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(ClientPacketListener.class) +public class MixinClientPacketListener { + + + +} diff --git a/fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinGameRenderer.java b/fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinGameRenderer.java new file mode 100644 index 000000000..b8d468e71 --- /dev/null +++ b/fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinGameRenderer.java @@ -0,0 +1,25 @@ +package com.seibel.lod.fabric.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; + +@Mixin(GameRenderer.class) +public class MixinGameRenderer { + @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(); + } +} diff --git a/fabric/src/main/java/com/seibel/lod/fabric/mixins/events/MixinMinecraft.java b/fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinMinecraft.java similarity index 100% rename from fabric/src/main/java/com/seibel/lod/fabric/mixins/events/MixinMinecraft.java rename to fabric/src/main/java/com/seibel/lod/fabric/mixins/client/MixinMinecraft.java diff --git a/fabric/src/main/resources/fabric.lod.mixins.json b/fabric/src/main/resources/fabric.lod.mixins.json index 16d0e8d7c..81e68cf89 100644 --- a/fabric/src/main/resources/fabric.lod.mixins.json +++ b/fabric/src/main/resources/fabric.lod.mixins.json @@ -17,7 +17,8 @@ "events.MixinClientLevel", "events.MixinMinecraft", "events.MixinBlockUpdate", - "events.MixinLightmap" + "events.MixinLightmap", + "client.MixinGameRenderer" ], "server": [ "MixinDedicatedServer"