Working on actually hook up events to use new one

This commit is contained in:
TomTheFurry
2022-06-01 22:55:58 +08:00
parent 5f7de8ff5b
commit 87fdfc5048
9 changed files with 134 additions and 204 deletions
+1 -1
Submodule core updated: 94b20a363d...f4f186ff78
@@ -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<Boolean> 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<Integer> previousKeyDown = new HashSet<Integer>();
public void onKeyInput() {
ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
if (CONFIG.client().advanced().debugging().getDebugKeybindingsEnabled())
if (Config.Client.Advanced.Debugging.enableDebugKeybindings.get())
{
HashSet<Integer> currentKeyDown = new HashSet<Integer>();
@@ -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;
}
@@ -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);
@@ -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 <https://www.gnu.org/licenses/>.
*/
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
}
@@ -17,8 +17,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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
}
@@ -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 {
}
@@ -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();
}
}
@@ -17,7 +17,8 @@
"events.MixinClientLevel",
"events.MixinMinecraft",
"events.MixinBlockUpdate",
"events.MixinLightmap"
"events.MixinLightmap",
"client.MixinGameRenderer"
],
"server": [
"MixinDedicatedServer"