From 535d0ff10e24d322bc3fd8d05eecf8c106911c55 Mon Sep 17 00:00:00 2001 From: Cadiboo <37298044+Cadiboo@users.noreply.github.com> Date: Thu, 11 Apr 2024 20:25:24 +1000 Subject: [PATCH] More stuff working --- build.gradle | 5 + .../io/github/cadiboo/nocubes/NoCubes.java | 28 +--- .../nocubes/client/ClientEventSubscriber.java | 60 -------- .../cadiboo/nocubes/client/KeyMappings.java | 49 +++---- .../cadiboo/nocubes/client/RenderHelper.java | 23 ++- .../client/render/OverlayRenderers.java | 135 ++++++++---------- .../cadiboo/nocubes/fabric/ClientInit.java | 23 +++ .../github/cadiboo/nocubes/fabric/Init.java | 28 ++++ .../cadiboo/nocubes/forge/ClientInit.java | 97 +++++++++++++ .../io/github/cadiboo/nocubes/forge/Init.java | 11 ++ .../nocubes/mixin/NoCubesMixinPlugin.java | 2 +- .../nocubes/mixin/PlayerListMixin.java | 35 +++++ ...lientHandshakePacketListenerImplMixin.java | 38 +++++ .../mixin/client/LevelRendererMixin.java | 63 ++++++-- .../client/NonSodiumLevelRendererMixin.java | 28 ++++ .../nocubes/network/NoCubesNetwork.java | 6 +- .../network/S2CUpdateNoCubesConfig.java | 27 ++++ src/main/resources/fabric.mod.json | 5 +- src/main/resources/mixins.nocubes.json | 7 +- 19 files changed, 456 insertions(+), 214 deletions(-) delete mode 100644 src/main/java/io/github/cadiboo/nocubes/client/ClientEventSubscriber.java create mode 100644 src/main/java/io/github/cadiboo/nocubes/fabric/ClientInit.java create mode 100644 src/main/java/io/github/cadiboo/nocubes/fabric/Init.java create mode 100644 src/main/java/io/github/cadiboo/nocubes/forge/ClientInit.java create mode 100644 src/main/java/io/github/cadiboo/nocubes/forge/Init.java create mode 100644 src/main/java/io/github/cadiboo/nocubes/mixin/PlayerListMixin.java create mode 100644 src/main/java/io/github/cadiboo/nocubes/mixin/client/ClientHandshakePacketListenerImplMixin.java create mode 100644 src/main/java/io/github/cadiboo/nocubes/mixin/client/NonSodiumLevelRendererMixin.java create mode 100644 src/main/java/io/github/cadiboo/nocubes/network/S2CUpdateNoCubesConfig.java diff --git a/build.gradle b/build.gradle index ad7a36f8..ff6491f5 100644 --- a/build.gradle +++ b/build.gradle @@ -95,6 +95,11 @@ dependencies { // // Apply Mixin AP // annotationProcessor 'org.spongepowered:mixin:0.8.5:processor' +// // From https://github.com/MinecraftForge/MinecraftForge/blob/0579572148079a6bc483ff42404878962fc48702/build.gradle#L55 +// def NIGHTCONFIG_VERSION = '3.6.0' +// // See https://github.com/MinecraftForge/MinecraftForge/blob/0579572148079a6bc483ff42404878962fc48702/build.gradle#L280-L281 +// library "com.electronwill.night-config:core:${NIGHTCONFIG_VERSION}" +// library "com.electronwill.night-config:toml:${NIGHTCONFIG_VERSION}" // For the config color picker (we include it in our production jar with ShadowJar) library 'org.beryx:awt-color-factory:1.0.2' // For @Nullable diff --git a/src/main/java/io/github/cadiboo/nocubes/NoCubes.java b/src/main/java/io/github/cadiboo/nocubes/NoCubes.java index 57e6ebf3..2ea03799 100644 --- a/src/main/java/io/github/cadiboo/nocubes/NoCubes.java +++ b/src/main/java/io/github/cadiboo/nocubes/NoCubes.java @@ -3,43 +3,17 @@ import io.github.cadiboo.nocubes.config.NoCubesConfig; import io.github.cadiboo.nocubes.smoothable.SmoothableHandler; import io.github.cadiboo.nocubes.util.ModUtil; -import net.fabricmc.api.ModInitializer; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; /** * @author Cadiboo */ -public final class NoCubes implements ModInitializer { +public final class NoCubes { public static final String MOD_ID = "nocubes"; public static final SmoothableHandler smoothableHandler = SmoothableHandler.create(); - @Override - public void onInitialize() { - // This code runs as soon as Minecraft is in a mod-load-ready state. - // However, some things (like resources) may still be uninitialized. - // Proceed with mild caution. - - // TODO: REMOVE - NoCubesConfig.Common.debugEnabled = true; - NoCubesConfig.Client.render = true; - NoCubesConfig.Server.mesher = NoCubesConfig.Server.MesherType.SurfaceNets.instance; - NoCubesConfig.Server.collisionsEnabled = true; - NoCubesConfig.Server.tempMobCollisionsDisabled = true; - NoCubesConfig.Server.extendFluidsRange = 3; - NoCubesConfig.Smoothables.recomputeInMemoryLookup(java.util.Collections.emptyList(), java.util.Collections.emptyList(), true); - } - -// public NoCubes() { -// var modBus = FMLJavaModLoadingContext.get().getModEventBus(); -// NoCubesConfig.register(ModLoadingContext.get(), modBus); -// if (FMLEnvironment.dist.isClient()) -// modBus.addListener((RegisterKeyMappingsEvent event) -> KeyMappings.register(event, MinecraftForge.EVENT_BUS)); -// NoCubesNetwork.register(); -// modBus.addListener((FMLClientSetupEvent event) -> OverlayRenderers.register(MinecraftForge.EVENT_BUS)); -// } - // region API /** * For other mods. diff --git a/src/main/java/io/github/cadiboo/nocubes/client/ClientEventSubscriber.java b/src/main/java/io/github/cadiboo/nocubes/client/ClientEventSubscriber.java deleted file mode 100644 index 18270033..00000000 --- a/src/main/java/io/github/cadiboo/nocubes/client/ClientEventSubscriber.java +++ /dev/null @@ -1,60 +0,0 @@ -//package io.github.cadiboo.nocubes.client; -// -//import io.github.cadiboo.nocubes.NoCubes; -//import io.github.cadiboo.nocubes.config.NoCubesConfig; -//import io.github.cadiboo.nocubes.network.NoCubesNetwork; -//import net.minecraft.client.Minecraft; -//import net.minecraft.client.gui.screens.Screen; -//import net.minecraftforge.api.distmarker.Dist; -//import net.minecraftforge.client.event.ClientPlayerNetworkEvent; -//import net.minecraftforge.eventbus.api.SubscribeEvent; -//import net.minecraftforge.fml.common.Mod; -//import net.minecraftforge.network.NetworkHooks; -//import org.apache.logging.log4j.LogManager; -//import org.apache.logging.log4j.Logger; -// -///** -// * @author Cadiboo -// */ -//@Mod.EventBusSubscriber(Dist.CLIENT) -//public final class ClientEventSubscriber { -// -// private static final Logger LOG = LogManager.getLogger(); -// -// @SubscribeEvent -// public static void onClientJoinServer(ClientPlayerNetworkEvent.LoggingIn event) { -// LOG.debug("Client joined server"); -// loadDefaultServerConfigIfWeAreOnAModdedServerWithoutNoCubes(event); -// ClientUtil.sendPlayerInfoMessage(); -// ClientUtil.warnPlayerIfVisualsDisabled(); -// if (!NoCubesNetwork.currentServerHasNoCubes) { -// // This lets players not phase through the ground on servers that don't have NoCubes installed -// NoCubesConfig.Server.collisionsEnabled = false; -// ClientUtil.warnPlayer(NoCubes.MOD_ID + ".notification.notInstalledOnServer", KeyMappings.translate(KeyMappings.TOGGLE_SMOOTHABLE_BLOCK_TYPE)); -// } -// } -// -// /** -// * This lets NoCubes load properly on modded servers that don't have it installed -// */ -// private static void loadDefaultServerConfigIfWeAreOnAModdedServerWithoutNoCubes(ClientPlayerNetworkEvent.LoggingIn event) { -// if (NoCubesNetwork.currentServerHasNoCubes) { -// // Forge has synced the server config to us, no need to load the default (see ConfigSync.syncConfigs) -// LOG.debug("Not loading default server config - current server has NoCubes installed"); -// return; -// } -// -// var connection = event.getConnection(); -// if (connection != null && NetworkHooks.isVanillaConnection(connection)) { -// // Forge has already loaded the default server configs for us (see NetworkHooks#handleClientLoginSuccess(Connection)) -// LOG.debug("Not loading default server config - Forge has already loaded it for us"); -// return; -// } -// -// if (connection == null) -// LOG.debug("Connection was null, assuming we're connected to a modded server without NoCubes!"); -// LOG.debug("Connected to a modded server that doesn't have NoCubes installed, loading default server config"); -// NoCubesConfig.Hacks.loadDefaultServerConfig(); -// } -// -//} diff --git a/src/main/java/io/github/cadiboo/nocubes/client/KeyMappings.java b/src/main/java/io/github/cadiboo/nocubes/client/KeyMappings.java index bd3af2f2..51a272a0 100644 --- a/src/main/java/io/github/cadiboo/nocubes/client/KeyMappings.java +++ b/src/main/java/io/github/cadiboo/nocubes/client/KeyMappings.java @@ -13,14 +13,13 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.HitResult; -//import net.minecraftforge.client.event.RegisterKeyMappingsEvent; -//import net.minecraftforge.event.TickEvent; -//import net.minecraftforge.eventbus.api.IEventBus; import org.apache.commons.lang3.tuple.Pair; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.lwjgl.glfw.GLFW; +import java.util.function.Consumer; + import static io.github.cadiboo.nocubes.client.RenderHelper.reloadAllChunks; /** @@ -40,30 +39,28 @@ public final class KeyMappings { public static final String TOGGLE_SMOOTHABLE_BLOCK_TYPE = "toggleSmoothable"; public static final String TOGGLE_SMOOTHABLE_BLOCK_STATE = "toggleSmoothableBlockState"; -// public static void register(RegisterKeyMappingsEvent registerEvent, IEventBus forgeBus) { -// LOG.debug("Registering keybindings"); -// var keybindings = Lists.newArrayList( -// makeKeybinding(registerEvent, TOGGLE_VISUALS, InputConstants.UNKNOWN.getValue(), KeyMappings::toggleVisuals), -// makeKeybinding(registerEvent, TOGGLE_SMOOTHABLE_BLOCK_TYPE, GLFW.GLFW_KEY_N, () -> toggleLookedAtSmoothable(true)), -// makeKeybinding(registerEvent, TOGGLE_SMOOTHABLE_BLOCK_STATE, InputConstants.UNKNOWN.getValue(), () -> toggleLookedAtSmoothable(false)) -// ); -// forgeBus.addListener((TickEvent.ClientTickEvent tickEvent) -> { -// if (tickEvent.phase != TickEvent.Phase.END) -// return; -// for (var keybinding : keybindings) -// if (keybinding.getKey().consumeClick()) { -// LOG.debug("Keybinding {} pressed", keybinding.getKey().getName()); -// keybinding.getValue().run(); -// } -// }); -// } + public static void register(Consumer registerKey, Consumer registerClientTickHandler) { + LOG.debug("Registering keybindings"); + var keybindings = Lists.newArrayList( + makeKeybinding(registerKey, TOGGLE_VISUALS, InputConstants.UNKNOWN.getValue(), KeyMappings::toggleVisuals), + makeKeybinding(registerKey, TOGGLE_SMOOTHABLE_BLOCK_TYPE, GLFW.GLFW_KEY_N, () -> toggleLookedAtSmoothable(true)), + makeKeybinding(registerKey, TOGGLE_SMOOTHABLE_BLOCK_STATE, InputConstants.UNKNOWN.getValue(), () -> toggleLookedAtSmoothable(false)) + ); + registerClientTickHandler.accept(() -> { + for (var keybinding : keybindings) + if (keybinding.getKey().consumeClick()) { + LOG.debug("Keybinding {} pressed", keybinding.getKey().getName()); + keybinding.getValue().run(); + } + }); + } -// private static Pair makeKeybinding(RegisterKeyMappingsEvent event, String name, int key, Runnable action) { -// LOG.debug("Registering keybinding {}", name); -// var mapping = new KeyMapping(qualifyName(name), key, NoCubes.MOD_ID + ".keycategory"); -// event.register(mapping); -// return Pair.of(mapping, action); -// } + private static Pair makeKeybinding(Consumer registerKey, String name, int key, Runnable action) { + LOG.debug("Registering keybinding {}", name); + var mapping = new KeyMapping(qualifyName(name), key, NoCubes.MOD_ID + ".keycategory"); + registerKey.accept(mapping); + return Pair.of(mapping, action); + } private static String qualifyName(String name) { return NoCubes.MOD_ID + ".key." + name; diff --git a/src/main/java/io/github/cadiboo/nocubes/client/RenderHelper.java b/src/main/java/io/github/cadiboo/nocubes/client/RenderHelper.java index 68610b5b..78ae60cd 100644 --- a/src/main/java/io/github/cadiboo/nocubes/client/RenderHelper.java +++ b/src/main/java/io/github/cadiboo/nocubes/client/RenderHelper.java @@ -46,14 +46,29 @@ public static void drawLinePosColorFromTo(BlockPos startOffset, Vec start, Block ); } - public static void drawFacePosColor(Face face, Vec3 camera, BlockPos pos, ColorParser.Color color, VertexConsumer buffer, PoseStack matrix) { + public static void drawFacePosColor( + Face face, Vec3 camera, + BlockPos pos, ColorParser.Color color, + VertexConsumer buffer, PoseStack matrix + ) { + drawFacePosColor( + face, camera.x, camera.y, camera.z, + pos, color, buffer, matrix + ); + } + + public static void drawFacePosColor( + Face face, double cameraX, double cameraY, double cameraZ, + BlockPos pos, ColorParser.Color color, + VertexConsumer buffer, PoseStack matrix + ) { var v0 = face.v0; var v1 = face.v1; var v2 = face.v2; var v3 = face.v3; - var x = pos.getX() - camera.x; - var y = pos.getY() - camera.y; - var z = pos.getZ() - camera.z; + var x = pos.getX() - cameraX; + var y = pos.getY() - cameraY; + var z = pos.getZ() - cameraZ; var v0x = (float) (x + v0.x); var v1x = (float) (x + v1.x); diff --git a/src/main/java/io/github/cadiboo/nocubes/client/render/OverlayRenderers.java b/src/main/java/io/github/cadiboo/nocubes/client/render/OverlayRenderers.java index 83da678c..231c4695 100644 --- a/src/main/java/io/github/cadiboo/nocubes/client/render/OverlayRenderers.java +++ b/src/main/java/io/github/cadiboo/nocubes/client/render/OverlayRenderers.java @@ -18,19 +18,18 @@ import net.minecraft.client.renderer.RenderType; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.shapes.BooleanOp; import net.minecraft.world.phys.shapes.Shapes; -//import net.minecraftforge.client.event.RenderHighlightEvent; -//import net.minecraftforge.client.event.RenderLevelStageEvent; -//import net.minecraftforge.eventbus.api.IEventBus; import org.apache.commons.lang3.tuple.Pair; import org.apache.logging.log4j.LogManager; import java.util.List; +import java.util.function.Consumer; import java.util.function.Predicate; import java.util.function.Supplier; @@ -43,80 +42,66 @@ */ public final class OverlayRenderers { -// public static void register(IEventBus events) { -// events.addListener(OverlayRenderers::renderBlockHighlight); -// var meshProfiler = new RollingProfiler(600); -// var debugOverlays = Lists.>newArrayList( -// Pair.of("drawOutlineAroundNearbySmoothableBlocks", OverlayRenderers::drawOutlineAroundNearbySmoothableBlocks), -// Pair.of("drawOutlineAroundNearbySmoothableBlocks", OverlayRenderers::drawOutlineAroundNearbySmoothableBlocks), -// Pair.of("maybeRenderMeshAndRecordPerformance", (camera, matrix, lines) -> maybeRenderMeshAndRecordPerformance(camera, matrix, lines, meshProfiler)), -// Pair.of("drawNearbyMeshCollisions", OverlayRenderers::drawNearbyMeshCollisions), -// Pair.of("drawNearbyCollisions", OverlayRenderers::drawNearbyCollisions), -// Pair.of("drawNearbyDensities", OverlayRenderers::drawNearbyDensities) -// ); -// events.addListener((RenderLevelStageEvent event) -> renderDebugOverlays(event, debugOverlays)); -// } + public static void register(Consumer> registerPerFrameHandler) { + var meshProfiler = new RollingProfiler(600); + var debugOverlays = Lists.>newArrayList( + Pair.of("drawOutlineAroundNearbySmoothableBlocks", OverlayRenderers::drawOutlineAroundNearbySmoothableBlocks), + Pair.of("drawOutlineAroundNearbySmoothableBlocks", OverlayRenderers::drawOutlineAroundNearbySmoothableBlocks), + Pair.of("maybeRenderMeshAndRecordPerformance", (camera, matrix, lines) -> maybeRenderMeshAndRecordPerformance(camera, matrix, lines, meshProfiler)), + Pair.of("drawNearbyMeshCollisions", OverlayRenderers::drawNearbyMeshCollisions), + Pair.of("drawNearbyCollisions", OverlayRenderers::drawNearbyCollisions), + Pair.of("drawNearbyDensities", OverlayRenderers::drawNearbyDensities) + ); + registerPerFrameHandler.accept(matrix -> renderDebugOverlays(matrix, debugOverlays)); + } + public static boolean renderNoCubesBlockHighlight( + PoseStack matrix, VertexConsumer buffer, + double cameraX, double cameraY, double cameraZ, + BlockGetter world, BlockPos lookingAtPos, BlockState state + ) { + if (!NoCubesConfig.Client.render) + return false; + if (!NoCubesConfig.Client.renderSelectionBox) + return false; + if (!NoCubes.smoothableHandler.isSmoothable(state)) + return false; + var mesher = NoCubesConfig.Server.mesher; + var stateSolidity = MeshRenderer.isSolidRender(state); + try (var area = new Area(world, lookingAtPos, ModUtil.VEC_ONE, mesher)) { + var color = NoCubesConfig.Client.selectionBoxColor; + Predicate isSmoothable = NoCubes.smoothableHandler::isSmoothable; + mesher.generateGeometry(area, s -> isSmoothable.test(s) && MeshRenderer.isSolidRender(s) == stateSolidity, (pos, face) -> { + drawFacePosColor(face, cameraX, cameraY, cameraZ, area.start, color, buffer, matrix); + return true; + }); + } + return true; + } -// public static void renderBlockHighlight(RenderHighlightEvent event) { -// if (!NoCubesConfig.Client.render) -// return; -// if (!NoCubesConfig.Client.renderSelectionBox) -// return; -// var world = Minecraft.getInstance().level; -// if (world == null) -// return; -// var targetHitResult = event.getTarget(); -// if (!(targetHitResult instanceof BlockHitResult target)) -// return; -// var lookingAtPos = target.getBlockPos(); -// var state = world.getBlockState(lookingAtPos); -// if (!NoCubes.smoothableHandler.isSmoothable(state)) -// return; -// -// event.setCanceled(true); -// -// var camera = event.getCamera().getPosition(); -// var matrix = event.getPoseStack(); -// var buffer = event.getMultiBufferSource().getBuffer(RenderType.lines()); -// var mesher = NoCubesConfig.Server.mesher; -// var stateSolidity = MeshRenderer.isSolidRender(state); -// try (var area = new Area(world, lookingAtPos, ModUtil.VEC_ONE, mesher)) { -// var color = NoCubesConfig.Client.selectionBoxColor; -// Predicate isSmoothable = NoCubes.smoothableHandler::isSmoothable; -// mesher.generateGeometry(area, s -> isSmoothable.test(s) && MeshRenderer.isSolidRender(s) == stateSolidity, (pos, face) -> { -// drawFacePosColor(face, camera, area.start, color, buffer, matrix); -// return true; -// }); -// } -// } -// -// public static void renderDebugOverlays(RenderLevelStageEvent event, List> overlays) { -// if (!NoCubesConfig.Common.debugEnabled) -// return; -// -// if (event.getStage() != RenderLevelStageEvent.Stage.AFTER_CUTOUT_BLOCKS) -// return; -// -// var minecraft = Minecraft.getInstance(); -// var camera = minecraft.gameRenderer.getMainCamera(); -// -//// drawBlockDestructionProgressForDebug(minecraft, camera); -// var bufferSource = minecraft.renderBuffers().bufferSource(); -// Supplier linesSupplier = () -> bufferSource.getBuffer(RenderType.lines()); -// overlays.forEach(overlay -> { -// var profiler = minecraft.getProfiler(); -// profiler.push(overlay.getLeft()); -// try { -// overlay.getRight().render(camera, event.getPoseStack(), linesSupplier); -// } finally { -// profiler.pop(); -// } -// }); -// -// // Hack to finish buffer because RenderWorldLastEvent seems to fire after vanilla normally finishes them -// bufferSource.endBatch(RenderType.lines()); -// } + static void renderDebugOverlays(PoseStack matrix, List> overlays) { + if (!NoCubesConfig.Common.debugEnabled) + return; + + var minecraft = Minecraft.getInstance(); + var camera = minecraft.gameRenderer.getMainCamera(); + +// drawBlockDestructionProgressForDebug(minecraft, camera); + var bufferSource = minecraft.renderBuffers().bufferSource(); + Supplier linesSupplier = () -> bufferSource.getBuffer(RenderType.lines()); + overlays.forEach(overlay -> { + var profiler = minecraft.getProfiler(); + profiler.push(overlay.getLeft()); + try { + overlay.getRight().render(camera, matrix, linesSupplier); + } finally { + profiler.pop(); + } + }); + + // Hack to finish buffer because RenderWorldLastEvent seems to fire after vanilla normally finishes them + bufferSource.endBatch(RenderType.lines()); + } interface DebugOverlay { void render(Camera camera, PoseStack matrix, Supplier linesSupplier); diff --git a/src/main/java/io/github/cadiboo/nocubes/fabric/ClientInit.java b/src/main/java/io/github/cadiboo/nocubes/fabric/ClientInit.java new file mode 100644 index 00000000..be5595f2 --- /dev/null +++ b/src/main/java/io/github/cadiboo/nocubes/fabric/ClientInit.java @@ -0,0 +1,23 @@ +package io.github.cadiboo.nocubes.fabric; + +import io.github.cadiboo.nocubes.client.KeyMappings; +import io.github.cadiboo.nocubes.network.NoCubesNetwork; +import io.github.cadiboo.nocubes.network.S2CUpdateNoCubesConfig; +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; +import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; + +public class ClientInit implements ClientModInitializer { + + @Override + public void onInitializeClient() { + ClientPlayNetworking.registerGlobalReceiver(S2CUpdateNoCubesConfig.TYPE, (player, packet, responseSender) -> { + NoCubesNetwork.currentServerHasNoCubes = true; + }); + KeyMappings.register( + KeyBindingHelper::registerKeyBinding, + keyBindingsOnTick -> ClientTickEvents.START_CLIENT_TICK.register(client -> keyBindingsOnTick.run()) + ); + } +} diff --git a/src/main/java/io/github/cadiboo/nocubes/fabric/Init.java b/src/main/java/io/github/cadiboo/nocubes/fabric/Init.java new file mode 100644 index 00000000..29336b41 --- /dev/null +++ b/src/main/java/io/github/cadiboo/nocubes/fabric/Init.java @@ -0,0 +1,28 @@ +package io.github.cadiboo.nocubes.fabric; + +import io.github.cadiboo.nocubes.config.ColorParser; +import io.github.cadiboo.nocubes.config.NoCubesConfig; +import net.fabricmc.api.ModInitializer; + +public class Init implements ModInitializer { + + @Override + public void onInitialize() { + // This code runs as soon as Minecraft is in a mod-load-ready state. + // However, some things (like resources) may still be uninitialized. + // Proceed with mild caution. + + // TODO: REMOVE + { + NoCubesConfig.Common.debugEnabled = true; + NoCubesConfig.Client.render = true; + NoCubesConfig.Client.renderSelectionBox = true; + NoCubesConfig.Client.selectionBoxColor = new ColorParser.Color(0, 255, 255, 255); + NoCubesConfig.Server.mesher = NoCubesConfig.Server.MesherType.SurfaceNets.instance; + NoCubesConfig.Server.collisionsEnabled = true; + NoCubesConfig.Server.tempMobCollisionsDisabled = true; + NoCubesConfig.Server.extendFluidsRange = 3; + NoCubesConfig.Smoothables.recomputeInMemoryLookup(java.util.Collections.emptyList(), java.util.Collections.emptyList(), true); + } + } +} diff --git a/src/main/java/io/github/cadiboo/nocubes/forge/ClientInit.java b/src/main/java/io/github/cadiboo/nocubes/forge/ClientInit.java new file mode 100644 index 00000000..ba430756 --- /dev/null +++ b/src/main/java/io/github/cadiboo/nocubes/forge/ClientInit.java @@ -0,0 +1,97 @@ +package io.github.cadiboo.nocubes.forge; + +//import net.minecraftforge.api.distmarker.Dist; +//import net.minecraftforge.client.event.ClientPlayerNetworkEvent; +//import net.minecraftforge.eventbus.api.SubscribeEvent; +//import net.minecraftforge.fml.common.Mod; +//import net.minecraftforge.network.NetworkHooks; +//import net.minecraftforge.client.event.RenderHighlightEvent; +//import net.minecraftforge.client.event.RenderLevelStageEvent; +//import net.minecraftforge.eventbus.api.IEventBus; +//import net.minecraftforge.client.event.RegisterKeyMappingsEvent; +//import net.minecraftforge.event.TickEvent; +//import net.minecraftforge.eventbus.api.IEventBus; +import io.github.cadiboo.nocubes.client.KeyMappings; +import io.github.cadiboo.nocubes.client.render.OverlayRenderers; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.world.phys.BlockHitResult; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** + * @author Cadiboo + */ +public final class ClientInit { + + private static final Logger LOG = LogManager.getLogger(); + +// public static void register(IEventBus modBus) { +// var events = MinecraftForge.EVENT_BUS; +// modBus.addListener((RegisterKeyMappingsEvent registerEvent) -> { +// KeyMappings.register(registerEvent::register, onTick -> events.addListener((TickEvent.ClientTickEvent tickEvent) -> { +// if (tickEvent.phase != TickEvent.Phase.END) +// return; +// onTick.run(); +// })); +// }); +// modBus.addListener((FMLClientSetupEvent clientSetupEvent) -> { +// OverlayRenderers.register(onFrame -> events.addListener((RenderLevelStageEvent event) -> { +// if (event.getStage() != RenderLevelStageEvent.Stage.AFTER_CUTOUT_BLOCKS) +// return; +// onFrame.accept(event.getPoseStack()); +// })); +// events.addListener((RenderHighlightEvent event) -> { +// var world = Minecraft.getInstance().level; +// if (world == null) +// return; +// var targetHitResult = event.getTarget(); +// if (!(targetHitResult instanceof BlockHitResult target)) +// return; +// var lookingAtPos = target.getBlockPos(); +// var camera = event.getCamera().getPosition(); +// if (OverlayRenderers.renderNoCubesBlockHighlight( +// event.getPoseStack(), event.getMultiBufferSource().getBuffer(RenderType.lines()), +// camera.x, camera.y, camera.z, +// world, lookingAtPos, world.getBlockState(lookingAtPos) +// )) +// event.setCanceled(true); +// }); +// }); +// events.addListener((ClientPlayerNetworkEvent.LoggingIn event) -> { +// LOG.debug("Client joined server"); +// loadDefaultServerConfigIfWeAreOnAModdedServerWithoutNoCubes(event); +// ClientUtil.sendPlayerInfoMessage(); +// ClientUtil.warnPlayerIfVisualsDisabled(); +// if (!NoCubesNetwork.currentServerHasNoCubes) { +// // This lets players not phase through the ground on servers that don't have NoCubes installed +// NoCubesConfig.Server.collisionsEnabled = false; +// ClientUtil.warnPlayer(NoCubes.MOD_ID + ".notification.notInstalledOnServer", KeyMappings.translate(KeyMappings.TOGGLE_SMOOTHABLE_BLOCK_TYPE)); +// } +// }); +// } + +// /** +// * This lets NoCubes load properly on modded servers that don't have it installed +// */ +// private static void loadDefaultServerConfigIfWeAreOnAModdedServerWithoutNoCubes(ClientPlayerNetworkEvent.LoggingIn event) { +// if (NoCubesNetwork.currentServerHasNoCubes) { +// // Forge has synced the server config to us, no need to load the default (see ConfigSync.syncConfigs) +// LOG.debug("Not loading default server config - current server has NoCubes installed"); +// return; +// } +// +// var connection = event.getConnection(); +// if (connection != null && NetworkHooks.isVanillaConnection(connection)) { +// // Forge has already loaded the default server configs for us (see NetworkHooks#handleClientLoginSuccess(Connection)) +// LOG.debug("Not loading default server config - Forge has already loaded it for us"); +// return; +// } +// +// if (connection == null) +// LOG.debug("Connection was null, assuming we're connected to a modded server without NoCubes!"); +// LOG.debug("Connected to a modded server that doesn't have NoCubes installed, loading default server config"); +// NoCubesConfig.Hacks.loadDefaultServerConfig(); +// } + +} diff --git a/src/main/java/io/github/cadiboo/nocubes/forge/Init.java b/src/main/java/io/github/cadiboo/nocubes/forge/Init.java new file mode 100644 index 00000000..68956c92 --- /dev/null +++ b/src/main/java/io/github/cadiboo/nocubes/forge/Init.java @@ -0,0 +1,11 @@ +package io.github.cadiboo.nocubes.forge; + +public class Init { +// public static void register() { +// var modBus = FMLJavaModLoadingContext.get().getModEventBus(); +// NoCubesConfig.register(ModLoadingContext.get(), modBus); +// if (FMLEnvironment.dist.isClient()) +// ClientInit.register(modBus); +// NoCubesNetwork.register(); +// } +} diff --git a/src/main/java/io/github/cadiboo/nocubes/mixin/NoCubesMixinPlugin.java b/src/main/java/io/github/cadiboo/nocubes/mixin/NoCubesMixinPlugin.java index 1adda5e7..6fd1789a 100644 --- a/src/main/java/io/github/cadiboo/nocubes/mixin/NoCubesMixinPlugin.java +++ b/src/main/java/io/github/cadiboo/nocubes/mixin/NoCubesMixinPlugin.java @@ -27,7 +27,7 @@ public NoCubesMixinPlugin() { } boolean shouldApply(String mixinClassName) { - if (mixinClassName.equals("io.github.cadiboo.nocubes.mixin.client.LevelRendererMixin")) + if (mixinClassName.equals("io.github.cadiboo.nocubes.mixin.client.NonSodiumLevelRendererMixin")) return !sodiumInstalled; if (mixinClassName.startsWith("io.github.cadiboo.nocubes.mixin.client.optifine")) return optiFineInstalled; diff --git a/src/main/java/io/github/cadiboo/nocubes/mixin/PlayerListMixin.java b/src/main/java/io/github/cadiboo/nocubes/mixin/PlayerListMixin.java new file mode 100644 index 00000000..9d4be929 --- /dev/null +++ b/src/main/java/io/github/cadiboo/nocubes/mixin/PlayerListMixin.java @@ -0,0 +1,35 @@ +package io.github.cadiboo.nocubes.mixin; + +import io.github.cadiboo.nocubes.network.S2CUpdateNoCubesConfig; +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; +import net.minecraft.network.Connection; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.players.PlayerList; +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; + +/** + * NoCubes needs to know if the server it is connecting to has NoCubes installed. + * This is because some features (collisions) require the mod to be installed on the server as well as the client. + * This packet lets us know that the mod is installed on the server - if we don't receive it, the mod isn't installed. + */ +@Mixin(PlayerList.class) +public class PlayerListMixin { + + @Inject( + method = "placeNewPlayer", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/players/PlayerList;sendPlayerPermissionLevel(Lnet/minecraft/server/level/ServerPlayer;)V" + ) + ) + public void nocubes$sendServerHasNoCubesPacket( + Connection connection, ServerPlayer serverPlayer, + CallbackInfo ci + ) { + ServerPlayNetworking.send(serverPlayer, new S2CUpdateNoCubesConfig()); + } + +} diff --git a/src/main/java/io/github/cadiboo/nocubes/mixin/client/ClientHandshakePacketListenerImplMixin.java b/src/main/java/io/github/cadiboo/nocubes/mixin/client/ClientHandshakePacketListenerImplMixin.java new file mode 100644 index 00000000..3d89b981 --- /dev/null +++ b/src/main/java/io/github/cadiboo/nocubes/mixin/client/ClientHandshakePacketListenerImplMixin.java @@ -0,0 +1,38 @@ +package io.github.cadiboo.nocubes.mixin.client; + +import io.github.cadiboo.nocubes.mixin.PlayerListMixin; +import io.github.cadiboo.nocubes.network.NoCubesNetwork; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.multiplayer.ClientHandshakePacketListenerImpl; +import net.minecraft.client.multiplayer.ServerData; +import net.minecraft.network.Connection; +import net.minecraft.network.chat.Component; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.time.Duration; +import java.util.function.Consumer; + +/** + * See {@link PlayerListMixin} for documentation. + */ +@Mixin(ClientHandshakePacketListenerImpl.class) +public abstract class ClientHandshakePacketListenerImplMixin { + + @Inject( + method = "", + at = @At("TAIL") + ) + private void nocubes$setUpDefaultValuesInCaseTargetServerDoesNotHaveModInstalled( + Connection connection, Minecraft minecraft, + ServerData serverData, Screen screen, + boolean bl, Duration duration, Consumer consumer, + CallbackInfo ci + ) { + NoCubesNetwork.currentServerHasNoCubes = false; + } + +} diff --git a/src/main/java/io/github/cadiboo/nocubes/mixin/client/LevelRendererMixin.java b/src/main/java/io/github/cadiboo/nocubes/mixin/client/LevelRendererMixin.java index 0411f327..5891721f 100644 --- a/src/main/java/io/github/cadiboo/nocubes/mixin/client/LevelRendererMixin.java +++ b/src/main/java/io/github/cadiboo/nocubes/mixin/client/LevelRendererMixin.java @@ -1,27 +1,60 @@ package io.github.cadiboo.nocubes.mixin.client; -import io.github.cadiboo.nocubes.hooks.ClientHooks; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import io.github.cadiboo.nocubes.client.render.OverlayRenderers; +import net.minecraft.client.Camera; +import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.LevelRenderer; +import net.minecraft.client.renderer.LightTexture; +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.block.state.BlockState; +import org.joml.Matrix4f; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.Constant; -import org.spongepowered.asm.mixin.injection.ModifyConstant; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(LevelRenderer.class) public class LevelRendererMixin { - /** - * @see ClientHooks#expandDirtyRenderAreaExtension - */ - @ModifyConstant( - method = { - "setBlockDirty(Lnet/minecraft/core/BlockPos;Z)V", - "setBlocksDirty(IIIIII)V", - }, - constant = @Constant(intValue = 1), - require = 6 * 2 // 6 replacements for each method, targets 2 methods + @Inject( + method = "renderHitOutline", + at = @At("HEAD"), + cancellable = true ) - public int noCubes$setBlocksDirty(int originalValue) { - return ClientHooks.expandDirtyRenderAreaExtension(originalValue); + public void noCubes$renderHitOutline( + PoseStack matrix, VertexConsumer buffer, + Entity cameraEntity, + double cameraX, double cameraY, double cameraZ, + BlockPos pos, BlockState state, + CallbackInfo ci + ) + { + var world = cameraEntity == null ? null : cameraEntity.level(); + if (world == null) + return; + if (OverlayRenderers.renderNoCubesBlockHighlight( + matrix, buffer, + cameraX, cameraY, cameraZ, + world, pos, state + )) + ci.cancel(); } + @Inject( + method = "renderLevel", + at = @At("TAIL") + ) + public void noCubes$renderOverlays( + PoseStack poseStack, + float partialTicks, long l, boolean shouldRenderBlockOutline, + Camera camera, GameRenderer gameRenderer, + LightTexture lightTexture, Matrix4f matrix4f, + CallbackInfo ci + ) { + // Bad, fix me + OverlayRenderers.register(perFrameAction -> perFrameAction.accept(poseStack)); + } } diff --git a/src/main/java/io/github/cadiboo/nocubes/mixin/client/NonSodiumLevelRendererMixin.java b/src/main/java/io/github/cadiboo/nocubes/mixin/client/NonSodiumLevelRendererMixin.java new file mode 100644 index 00000000..12242fe3 --- /dev/null +++ b/src/main/java/io/github/cadiboo/nocubes/mixin/client/NonSodiumLevelRendererMixin.java @@ -0,0 +1,28 @@ +package io.github.cadiboo.nocubes.mixin.client; + +import io.github.cadiboo.nocubes.hooks.ClientHooks; +import net.minecraft.client.renderer.LevelRenderer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.Constant; +import org.spongepowered.asm.mixin.injection.ModifyConstant; + +@Mixin(LevelRenderer.class) +public class NonSodiumLevelRendererMixin { + + /** + * @see ClientHooks#expandDirtyRenderAreaExtension + * Sodium @Overwrites these methods so we don't try to apply this when it is installed since it crashes. + */ + @ModifyConstant( + method = { + "setBlockDirty(Lnet/minecraft/core/BlockPos;Z)V", + "setBlocksDirty(IIIIII)V", + }, + constant = @Constant(intValue = 1), + require = 6 * 2 // 6 replacements for each method, targets 2 methods + ) + public int noCubes$setBlocksDirty(int originalValue) { + return ClientHooks.expandDirtyRenderAreaExtension(originalValue); + } + +} diff --git a/src/main/java/io/github/cadiboo/nocubes/network/NoCubesNetwork.java b/src/main/java/io/github/cadiboo/nocubes/network/NoCubesNetwork.java index 622968f9..281571bf 100644 --- a/src/main/java/io/github/cadiboo/nocubes/network/NoCubesNetwork.java +++ b/src/main/java/io/github/cadiboo/nocubes/network/NoCubesNetwork.java @@ -60,7 +60,7 @@ public final class NoCubesNetwork { * Called from inside the mod constructor. */ public static void register() { -// int networkId = 0; + int networkId = 0; // // Client -> Server // register( // networkId, @@ -85,7 +85,7 @@ public static void register() { // S2CUpdateServerConfig::decode, // S2CUpdateServerConfig::handle // ); -// } + } // // static void register(int index, Class messageType, BiConsumer encoder, Function decoder, BiConsumer> handler) { // CHANNEL.registerMessage( @@ -104,6 +104,6 @@ public static void register() { // handler.accept(msg, ctx); // } // ); - } +// } } diff --git a/src/main/java/io/github/cadiboo/nocubes/network/S2CUpdateNoCubesConfig.java b/src/main/java/io/github/cadiboo/nocubes/network/S2CUpdateNoCubesConfig.java new file mode 100644 index 00000000..bcaa8d41 --- /dev/null +++ b/src/main/java/io/github/cadiboo/nocubes/network/S2CUpdateNoCubesConfig.java @@ -0,0 +1,27 @@ +package io.github.cadiboo.nocubes.network; + +import io.github.cadiboo.nocubes.NoCubes; +import net.fabricmc.fabric.api.networking.v1.FabricPacket; +import net.fabricmc.fabric.api.networking.v1.PacketType; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; + +public class S2CUpdateNoCubesConfig implements FabricPacket { + public static final PacketType TYPE = PacketType.create(new ResourceLocation(NoCubes.MOD_ID, "syncconfig"), S2CUpdateNoCubesConfig::read); + + public S2CUpdateNoCubesConfig() { + } + + public static S2CUpdateNoCubesConfig read(FriendlyByteBuf buf) { + return new S2CUpdateNoCubesConfig(); + } + + @Override + public void write(FriendlyByteBuf buf) { + } + + @Override + public PacketType getType() { + return TYPE; + } +} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index f5062e72..e0890ad5 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -20,7 +20,10 @@ "environment": "*", "entrypoints": { "main": [ - "io.github.cadiboo.nocubes.NoCubes" + "io.github.cadiboo.nocubes.fabric.Init" + ], + "client": [ + "io.github.cadiboo.nocubes.fabric.ClientInit" ] }, "mixins": [ diff --git a/src/main/resources/mixins.nocubes.json b/src/main/resources/mixins.nocubes.json index e49c6814..3fa51498 100644 --- a/src/main/resources/mixins.nocubes.json +++ b/src/main/resources/mixins.nocubes.json @@ -14,18 +14,21 @@ "BlockStateBaseMixin", "EntityMixin", "LevelMixin", - "PlayerMixin", - "client.optifine.BlockStateMixin" + "PlayerListMixin", + "PlayerMixin" ], "client": [ "client.BlockRenderDispatcherMixin", + "client.ClientHandshakePacketListenerImplMixin", "client.LevelRendererMixin", "client.LiquidBlockRendererMixin", + "client.NonSodiumLevelRendererMixin", "client.RenderChunkCompileTaskMixin", "client.RenderChunkMixin", "client.RenderChunkRebuildTaskMixin", "client.RenderChunkRegionMixin", "client.ScreenEffectRendererMixin", + "client.optifine.BlockStateMixin", "client.optifine.ChunkCacheOFMixin", "client.optifine.RenderChunkMixin", "client.sodium.ChunkBuilderMeshingTaskMixin",