From 46228e582ba165a6d89ff55cc7892f38297d7702 Mon Sep 17 00:00:00 2001 From: Gregory Mitchell <54124162+gmitch215@users.noreply.github.com> Date: Sun, 1 Sep 2024 15:51:27 -0500 Subject: [PATCH 01/16] Upgrade to Gradle 8.10 --- gradle/wrapper/gradle-wrapper.jar | Bin 43453 -> 43504 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 5 ++++- gradlew.bat | 2 ++ 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e6441136f3d4ba8a0da8d277868979cfbc8ad796..2c3521197d7c4586c843d1d3e9090525f1898cde 100644 GIT binary patch delta 8703 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 Ojj7^59?Sdh$^Qpp*~F>< delta 8662 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 09523c0e..9355b415 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index b740cf13..f5feea6d 100755 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/gradlew.bat b/gradlew.bat index 25da30db..9d21a218 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## From e65778ba17b8fb2eb6a5061406c5165a5d8fda90 Mon Sep 17 00:00:00 2001 From: Gregory Mitchell <54124162+gmitch215@users.noreply.github.com> Date: Sun, 1 Sep 2024 16:03:17 -0500 Subject: [PATCH 02/16] Update Version, Fabric Version --- build.gradle.kts | 2 +- mod/fabric/build.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 75c4f792..ab1293cf 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -52,7 +52,7 @@ tasks { allprojects { val mc = "1.21" - val pr = "0.2.2" + val pr = "0.3.0" project.ext["minecraft_version"] = mc project.ext["project_version"] = pr diff --git a/mod/fabric/build.gradle.kts b/mod/fabric/build.gradle.kts index f37bd258..a13e38a8 100644 --- a/mod/fabric/build.gradle.kts +++ b/mod/fabric/build.gradle.kts @@ -12,7 +12,7 @@ description = "Fabric Mod for SocketMC Client-side Implementation" val minecraft = project.ext["minecraft_version"].toString() val parchment = project.ext["parchment"].toString() -val fabric = "0.100.2" +val fabric = "0.102.0" dependencies { api(project(":socketmc-core")) From 7ec70a6b81b6c138b5b5ccdb176524d71214eb34 Mon Sep 17 00:00:00 2001 From: Gregory Mitchell <54124162+gmitch215@users.noreply.github.com> Date: Sun, 1 Sep 2024 22:11:55 -0500 Subject: [PATCH 03/16] Reformat Retriever Implementation - Add Window Constructor - Move Retrievers inside Module Packages --- .../gmitch215/socketmc/retriever/Window.java | 51 +++++++++++++++++-- .../FabricRetriever.java | 39 +++++++------- .../fabric/mixin/PacketDecoderMixin.java | 2 +- .../{retriever => forge}/ForgeRetriever.java | 39 +++++++------- .../forge/mixin/PacketDecoderMixin.java | 2 +- 5 files changed, 92 insertions(+), 41 deletions(-) rename mod/fabric/src/main/java/xyz/gmitch215/socketmc/{retriever => fabric}/FabricRetriever.java (69%) rename mod/forge/src/main/java/xyz/gmitch215/socketmc/{retriever => forge}/ForgeRetriever.java (69%) diff --git a/core/src/main/java/xyz/gmitch215/socketmc/retriever/Window.java b/core/src/main/java/xyz/gmitch215/socketmc/retriever/Window.java index a87f2682..992b2891 100644 --- a/core/src/main/java/xyz/gmitch215/socketmc/retriever/Window.java +++ b/core/src/main/java/xyz/gmitch215/socketmc/retriever/Window.java @@ -26,7 +26,44 @@ public final class Window implements Serializable { String platform; int refreshRate; - Window() {} + /** + * Creates a new, empty window. + */ + public Window() {} + + /** + * Creates a new window with the specified parameters. + * @param id Window ID + * @param fullscreen Fullscreen Mode + * @param x X Position + * @param y Y Position + * @param width Width + * @param height Height + * @param screenWidth Screen Width + * @param screenHeight Screen Height + * @param guiScaledWidth GUI Scaled Width + * @param guiScaledHeight GUI Scaled Height + * @param guiScale GUI Scale + * @param framerateLimit Framerate Limit + * @param platform Window Platform + * @param refreshRate Refresh Rate + */ + public Window(long id, boolean fullscreen, int x, int y, int width, int height, int screenWidth, int screenHeight, int guiScaledWidth, int guiScaledHeight, double guiScale, int framerateLimit, String platform, int refreshRate) { + this.id = id; + this.fullscreen = fullscreen; + this.x = x; + this.y = y; + this.width = width; + this.height = height; + this.screenWidth = screenWidth; + this.screenHeight = screenHeight; + this.guiScaledWidth = guiScaledWidth; + this.guiScaledHeight = guiScaledHeight; + this.guiScale = guiScale; + this.framerateLimit = framerateLimit; + this.platform = platform; + this.refreshRate = refreshRate; + } /** * Gets the window ID. @@ -125,8 +162,16 @@ public int getFramerateLimit() { } /** - *

Gets the platform this window is currently on.

- *

Common values are {@code "win32"}, {@code "cocoa"}, {@code "wayland"}, and {@code "x11"}. {@code "null"} will be returned if not accessible, and {@code ""} will be returned if something happened.

+ *

Gets the platform this window is currently using.

+ *

Some potential values are:

+ *
    + *
  • {@code win32} if on Windows
  • + *
  • {@code cocoa} if on macOS
  • + *
  • {@code x11} or {@code wayland} if on Unix
  • + *
  • {@code null} if inaccessible
  • + *
  • {@code } if can't fetch the value
  • + *
  • {@code unknown} if not using a generally known windows API
  • + *
* @return Window Platform */ public String getPlatform() { diff --git a/mod/fabric/src/main/java/xyz/gmitch215/socketmc/retriever/FabricRetriever.java b/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/FabricRetriever.java similarity index 69% rename from mod/fabric/src/main/java/xyz/gmitch215/socketmc/retriever/FabricRetriever.java rename to mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/FabricRetriever.java index 299213e7..bbb464aa 100644 --- a/mod/fabric/src/main/java/xyz/gmitch215/socketmc/retriever/FabricRetriever.java +++ b/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/FabricRetriever.java @@ -1,8 +1,12 @@ -package xyz.gmitch215.socketmc.retriever; +package xyz.gmitch215.socketmc.fabric; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFuture; import net.minecraft.network.FriendlyByteBuf; +import xyz.gmitch215.socketmc.retriever.ClientProperty; +import xyz.gmitch215.socketmc.retriever.Retriever; +import xyz.gmitch215.socketmc.retriever.RetrieverType; +import xyz.gmitch215.socketmc.retriever.Window; import xyz.gmitch215.socketmc.util.InputType; import java.io.ByteArrayOutputStream; @@ -26,23 +30,22 @@ private FabricRetriever() {} create(RetrieverType.CURRENT_WINDOW, () -> { com.mojang.blaze3d.platform.Window window = minecraft.getWindow(); - Window w = new Window(); - w.id = window.getWindow(); - w.fullscreen = window.isFullscreen(); - w.x = window.getX(); - w.y = window.getY(); - w.width = window.getWidth(); - w.height = window.getHeight(); - w.screenWidth = window.getScreenWidth(); - w.screenHeight = window.getScreenHeight(); - w.guiScaledWidth = window.getGuiScaledWidth(); - w.guiScaledHeight = window.getGuiScaledHeight(); - w.guiScale = window.getGuiScale(); - w.framerateLimit = window.getFramerateLimit(); - w.platform = com.mojang.blaze3d.platform.Window.getPlatform(); - w.refreshRate = window.getRefreshRate(); - - return w; + return new Window( + window.getWindow(), + window.isFullscreen(), + window.getX(), + window.getY(), + window.getWidth(), + window.getHeight(), + window.getScreenWidth(), + window.getScreenHeight(), + window.getGuiScaledWidth(), + window.getGuiScaledHeight(), + window.getGuiScale(), + window.getFramerateLimit(), + com.mojang.blaze3d.platform.Window.getPlatform(), + window.getRefreshRate() + ); }), create(RetrieverType.PAUSED, minecraft::isPaused), create(RetrieverType.FPS, minecraft::getFps), diff --git a/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/mixin/PacketDecoderMixin.java b/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/mixin/PacketDecoderMixin.java index 7bae3a60..3ac11218 100644 --- a/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/mixin/PacketDecoderMixin.java +++ b/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/mixin/PacketDecoderMixin.java @@ -15,7 +15,7 @@ import xyz.gmitch215.socketmc.fabric.machines.FabricMachineFinder; import xyz.gmitch215.socketmc.instruction.Instruction; import xyz.gmitch215.socketmc.machines.MachineFinder; -import xyz.gmitch215.socketmc.retriever.FabricRetriever; +import xyz.gmitch215.socketmc.fabric.FabricRetriever; import xyz.gmitch215.socketmc.retriever.Retriever; import xyz.gmitch215.socketmc.retriever.RetrieverType; import xyz.gmitch215.socketmc.spigot.SocketPlugin; diff --git a/mod/forge/src/main/java/xyz/gmitch215/socketmc/retriever/ForgeRetriever.java b/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/ForgeRetriever.java similarity index 69% rename from mod/forge/src/main/java/xyz/gmitch215/socketmc/retriever/ForgeRetriever.java rename to mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/ForgeRetriever.java index 1f4bd9b3..2a070591 100644 --- a/mod/forge/src/main/java/xyz/gmitch215/socketmc/retriever/ForgeRetriever.java +++ b/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/ForgeRetriever.java @@ -1,8 +1,12 @@ -package xyz.gmitch215.socketmc.retriever; +package xyz.gmitch215.socketmc.forge; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFuture; import net.minecraft.network.FriendlyByteBuf; +import xyz.gmitch215.socketmc.retriever.ClientProperty; +import xyz.gmitch215.socketmc.retriever.Retriever; +import xyz.gmitch215.socketmc.retriever.RetrieverType; +import xyz.gmitch215.socketmc.retriever.Window; import xyz.gmitch215.socketmc.util.InputType; import java.io.ByteArrayOutputStream; @@ -26,23 +30,22 @@ private ForgeRetriever() {} create(RetrieverType.CURRENT_WINDOW, () -> { com.mojang.blaze3d.platform.Window window = minecraft.getWindow(); - Window w = new Window(); - w.id = window.getWindow(); - w.fullscreen = window.isFullscreen(); - w.x = window.getX(); - w.y = window.getY(); - w.width = window.getWidth(); - w.height = window.getHeight(); - w.screenWidth = window.getScreenWidth(); - w.screenHeight = window.getScreenHeight(); - w.guiScaledWidth = window.getGuiScaledWidth(); - w.guiScaledHeight = window.getGuiScaledHeight(); - w.guiScale = window.getGuiScale(); - w.framerateLimit = window.getFramerateLimit(); - w.platform = com.mojang.blaze3d.platform.Window.getPlatform(); - w.refreshRate = window.getRefreshRate(); - - return w; + return new Window( + window.getWindow(), + window.isFullscreen(), + window.getX(), + window.getY(), + window.getWidth(), + window.getHeight(), + window.getScreenWidth(), + window.getScreenHeight(), + window.getGuiScaledWidth(), + window.getGuiScaledHeight(), + window.getGuiScale(), + window.getFramerateLimit(), + com.mojang.blaze3d.platform.Window.getPlatform(), + window.getRefreshRate() + ); }), create(RetrieverType.PAUSED, minecraft::isPaused), create(RetrieverType.FPS, minecraft::getFps), diff --git a/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/mixin/PacketDecoderMixin.java b/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/mixin/PacketDecoderMixin.java index 551e06e3..7a3a37ba 100644 --- a/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/mixin/PacketDecoderMixin.java +++ b/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/mixin/PacketDecoderMixin.java @@ -15,7 +15,7 @@ import xyz.gmitch215.socketmc.forge.machines.ForgeMachineFinder; import xyz.gmitch215.socketmc.instruction.Instruction; import xyz.gmitch215.socketmc.machines.MachineFinder; -import xyz.gmitch215.socketmc.retriever.ForgeRetriever; +import xyz.gmitch215.socketmc.forge.ForgeRetriever; import xyz.gmitch215.socketmc.retriever.Retriever; import xyz.gmitch215.socketmc.retriever.RetrieverType; import xyz.gmitch215.socketmc.spigot.SocketPlugin; From 1ab48d8ae86fb679a49a96adbdf7695ae29cf111 Mon Sep 17 00:00:00 2001 From: Gregory Mitchell <54124162+gmitch215@users.noreply.github.com> Date: Sun, 1 Sep 2024 22:13:17 -0500 Subject: [PATCH 04/16] Import static `minecraft` variable --- .../fabric/screen/FabricScreenUtil.java | 18 +++++++++--------- .../forge/machines/OpenScreenMachine.java | 16 +++++++++------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/screen/FabricScreenUtil.java b/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/screen/FabricScreenUtil.java index 044575cf..c3ec8075 100644 --- a/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/screen/FabricScreenUtil.java +++ b/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/screen/FabricScreenUtil.java @@ -93,28 +93,28 @@ public static DefaultScreen findDefault(Screen screen) { } static final Button.OnPress BUTTON_PRESS_EVENT = b -> { - AbstractScreen s0 = fromMinecraft(FabricSocketMC.minecraft.screen); + AbstractScreen s0 = fromMinecraft(minecraft.screen); if (s0 == null) return; FabricSocketMC.sendEvent(5, Map.of("screen", s0, "button", fromMinecraft(b))); }; static final Checkbox.OnValueChange CHECKBOX_CHANGE_EVENT = (b, state) -> { - AbstractScreen s0 = fromMinecraft(FabricSocketMC.minecraft.screen); + AbstractScreen s0 = fromMinecraft(minecraft.screen); if (s0 == null) return; FabricSocketMC.sendEvent(6, Map.of("screen", s0, "button", fromMinecraft(b), "state", state)); }; static final BiConsumer EDIT_BOX_EVENT = (w, s) -> { - AbstractScreen s0 = fromMinecraft(FabricSocketMC.minecraft.screen); + AbstractScreen s0 = fromMinecraft(minecraft.screen); if (s0 == null) return; FabricSocketMC.sendEvent(7, Map.of("screen", s0, "widget", fromMinecraft(w), "text", s)); }; static final net.minecraft.client.gui.components.CycleButton.OnValueChange CYCLE_BUTTON_EVENT = (b, o) -> { - AbstractScreen s0 = fromMinecraft(FabricSocketMC.minecraft.screen); + AbstractScreen s0 = fromMinecraft(minecraft.screen); if (s0 == null) return; FabricSocketMC.sendEvent(8, Map.of("screen", s0, "button", fromMinecraft(b), "value", o)); @@ -135,12 +135,12 @@ public static AbstractWidget toMinecraft(Positionable renderable) { // Widgets case xyz.gmitch215.socketmc.screen.ui.TextWidget widget -> { if (width == -1 || height == -1) - yield new StringWidget(x, y, message, FabricSocketMC.minecraft.font); + yield new StringWidget(x, y, message, minecraft.font); else - yield new StringWidget(x, y, width, height, message, FabricSocketMC.minecraft.font); + yield new StringWidget(x, y, width, height, message, minecraft.font); } case xyz.gmitch215.socketmc.screen.ui.FocusedTextWidget widget -> { - FocusableTextWidget w = new FocusableTextWidget(width, message, FabricSocketMC.minecraft.font, widget.isAlwaysShowBorder(), widget.getPadding()); + FocusableTextWidget w = new FocusableTextWidget(width, message, minecraft.font, widget.isAlwaysShowBorder(), widget.getPadding()); w.setPosition(widget.getX(), widget.getY()); yield w; @@ -157,7 +157,7 @@ public static AbstractWidget toMinecraft(Positionable renderable) { yield w; } case xyz.gmitch215.socketmc.screen.ui.EditTextWidget widget -> { - EditBox w = new EditBox(FabricSocketMC.minecraft.font, x, y, width, height, message); + EditBox w = new EditBox(minecraft.font, x, y, width, height, message); w.setResponder(s -> EDIT_BOX_EVENT.accept(w, s)); yield w; @@ -169,7 +169,7 @@ public static AbstractWidget toMinecraft(Positionable renderable) { case ImageButton button -> new net.minecraft.client.gui.components.ImageButton(x, y, width, height, FabricUtil.toMinecraft(button.getSprite()), BUTTON_PRESS_EVENT); case xyz.gmitch215.socketmc.screen.ui.CheckboxButton button -> - Checkbox.builder(message, FabricSocketMC.minecraft.font).onValueChange(CHECKBOX_CHANGE_EVENT).pos(x, y).build(); + Checkbox.builder(message, minecraft.font).onValueChange(CHECKBOX_CHANGE_EVENT).pos(x, y).build(); case xyz.gmitch215.socketmc.screen.ui.SendInstructionButton button -> new FabricSendInstructionButton(x, y, width, height, message, button.getInstruction()); case xyz.gmitch215.socketmc.screen.ui.LockButton button -> new LockIconButton(x, y, BUTTON_PRESS_EVENT); diff --git a/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/machines/OpenScreenMachine.java b/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/machines/OpenScreenMachine.java index 432255c3..79f0615f 100644 --- a/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/machines/OpenScreenMachine.java +++ b/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/machines/OpenScreenMachine.java @@ -17,6 +17,8 @@ import org.jetbrains.annotations.Nullable; import xyz.gmitch215.socketmc.forge.ForgeSocketMC; +import static xyz.gmitch215.socketmc.forge.ForgeSocketMC.minecraft; + @InstructionId(Instruction.OPEN_SCREEN) public final class OpenScreenMachine implements Machine { @@ -28,10 +30,10 @@ static Screen defaultScreen(@NotNull DefaultScreen screen, @Nullable Screen last return switch (screen.getIdentifier()) { case "title" -> new TitleScreen(); case "pause" -> new PauseScreen(true); - case "options" -> new OptionsScreen(lastScreen, ForgeSocketMC.minecraft.options); + case "options" -> new OptionsScreen(lastScreen, minecraft.options); case "share_to_lan" -> new ShareToLanScreen(lastScreen); - case "advancements" -> new AdvancementsScreen(ForgeSocketMC.minecraft.getConnection().getAdvancements(), lastScreen); - case "stats" -> new StatsScreen(lastScreen, ForgeSocketMC.minecraft.player.getStats()); + case "advancements" -> new AdvancementsScreen(minecraft.getConnection().getAdvancements(), lastScreen); + case "stats" -> new StatsScreen(lastScreen, minecraft.player.getStats()); case "alert" -> { Component title = ForgeUtil.fromJson(screen.data("title", String.class)); Component message = ForgeUtil.fromJson(screen.data("message", String.class)); @@ -81,13 +83,13 @@ public void onInstruction(@NotNull Instruction instruction) throws Exception { AbstractScreen screen = instruction.parameter(0, AbstractScreen.class); if (screen instanceof DefaultScreen s) { - Screen screen0 = defaultScreen(s, ForgeSocketMC.minecraft.screen); - ForgeSocketMC.minecraft.execute(() -> ForgeSocketMC.minecraft.setScreen(screen0)); + Screen screen0 = defaultScreen(s, minecraft.screen); + minecraft.execute(() -> minecraft.setScreen(screen0)); } if (screen instanceof CustomScreen s) { - Screen screen0 = new ForgeScreen(s, ForgeSocketMC.minecraft.screen); - ForgeSocketMC.minecraft.execute(() -> ForgeSocketMC.minecraft.setScreen(screen0)); + Screen screen0 = new ForgeScreen(s, minecraft.screen); + minecraft.execute(() -> minecraft.setScreen(screen0)); } } From fff2fc21db91e2a4bd55461ed32935f821222f88 Mon Sep 17 00:00:00 2001 From: Gregory Mitchell <54124162+gmitch215@users.noreply.github.com> Date: Sun, 1 Sep 2024 22:13:26 -0500 Subject: [PATCH 05/16] Use Class Identifier for Mixins --- .../socketmc/fabric/mixin/events/PlayerMouseInputEvent.java | 3 ++- .../socketmc/fabric/mixin/events/PlayerPressKeyEvent.java | 3 ++- .../socketmc/forge/mixin/events/PlayerMouseInputEvent.java | 3 ++- .../socketmc/forge/mixin/events/PlayerPressKeyEvent.java | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/mixin/events/PlayerMouseInputEvent.java b/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/mixin/events/PlayerMouseInputEvent.java index ce253a4f..4bd88163 100644 --- a/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/mixin/events/PlayerMouseInputEvent.java +++ b/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/mixin/events/PlayerMouseInputEvent.java @@ -1,5 +1,6 @@ package xyz.gmitch215.socketmc.fabric.mixin.events; +import net.minecraft.client.MouseHandler; import xyz.gmitch215.socketmc.fabric.FabricSocketMC; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; @@ -9,7 +10,7 @@ import java.util.Map; -@Mixin(targets = "net.minecraft.client.MouseHandler") +@Mixin(MouseHandler.class) public class PlayerMouseInputEvent { @Unique diff --git a/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/mixin/events/PlayerPressKeyEvent.java b/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/mixin/events/PlayerPressKeyEvent.java index 77550933..d0c5daf9 100644 --- a/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/mixin/events/PlayerPressKeyEvent.java +++ b/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/mixin/events/PlayerPressKeyEvent.java @@ -1,5 +1,6 @@ package xyz.gmitch215.socketmc.fabric.mixin.events; +import net.minecraft.client.KeyboardHandler; import xyz.gmitch215.socketmc.fabric.FabricSocketMC; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -8,7 +9,7 @@ import java.util.Map; -@Mixin(targets = "net.minecraft.client.KeyboardHandler") +@Mixin(KeyboardHandler.class) public class PlayerPressKeyEvent { @Inject(method = "keyPress", at = @At("HEAD")) diff --git a/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/mixin/events/PlayerMouseInputEvent.java b/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/mixin/events/PlayerMouseInputEvent.java index 77734ca4..fab9040b 100644 --- a/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/mixin/events/PlayerMouseInputEvent.java +++ b/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/mixin/events/PlayerMouseInputEvent.java @@ -1,5 +1,6 @@ package xyz.gmitch215.socketmc.forge.mixin.events; +import net.minecraft.client.MouseHandler; import xyz.gmitch215.socketmc.forge.ForgeSocketMC; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -8,7 +9,7 @@ import java.util.Map; -@Mixin(targets = "net.minecraft.client.MouseHandler") +@Mixin(MouseHandler.class) public class PlayerMouseInputEvent { @Inject(method = "onMove", at = @At("HEAD")) diff --git a/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/mixin/events/PlayerPressKeyEvent.java b/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/mixin/events/PlayerPressKeyEvent.java index f30a5c31..5f38df8e 100644 --- a/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/mixin/events/PlayerPressKeyEvent.java +++ b/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/mixin/events/PlayerPressKeyEvent.java @@ -1,5 +1,6 @@ package xyz.gmitch215.socketmc.forge.mixin.events; +import net.minecraft.client.KeyboardHandler; import xyz.gmitch215.socketmc.forge.ForgeSocketMC; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -8,7 +9,7 @@ import java.util.Map; -@Mixin(targets = "net.minecraft.client.KeyboardHandler") +@Mixin(KeyboardHandler.class) public class PlayerPressKeyEvent { @Inject(method = "keyPress", at = @At("HEAD")) From 3f88bc561a158e6c13a95fef2e80ce7ae50e5ddc Mon Sep 17 00:00:00 2001 From: Gregory Mitchell <54124162+gmitch215@users.noreply.github.com> Date: Sun, 1 Sep 2024 22:13:35 -0500 Subject: [PATCH 06/16] Add NeoForge Support --- .gitignore | 3 +- build.gradle.kts | 3 + mod/neoforge/build.gradle.kts | 82 +++++ .../socketmc/neoforge/NeoForgeEvents.java | 21 ++ .../socketmc/neoforge/NeoForgeRetriever.java | 83 +++++ .../socketmc/neoforge/NeoForgeSocketMC.java | 63 ++++ .../socketmc/neoforge/NeoForgeUtil.java | 90 ++++++ .../neoforge/machines/CloseScreenMachine.java | 20 ++ .../machines/DisplayToastMachine.java | 27 ++ .../machines/DrawBeaconBeamMachine.java | 51 ++++ .../neoforge/machines/DrawBufferMachine.java | 61 ++++ .../neoforge/machines/DrawContextMachine.java | 282 +++++++++++++++++ .../machines/DrawItemStackMachine.java | 43 +++ .../neoforge/machines/DrawShapeMachine.java | 76 +++++ .../neoforge/machines/DrawTextMachine.java | 43 +++ .../neoforge/machines/DrawTextureMachine.java | 51 ++++ .../machines/NeoForgeMachineFinder.java | 32 ++ .../machines/OpenBookAndQuillMachine.java | 22 ++ .../neoforge/machines/OpenScreenMachine.java | 95 ++++++ .../neoforge/machines/PingMachine.java | 25 ++ .../neoforge/machines/RenderingMachine.java | 59 ++++ .../neoforge/machines/SetOverlayMachine.java | 29 ++ .../neoforge/mixin/AbstractWidgetMixin.java | 47 +++ .../socketmc/neoforge/mixin/GuiMixin.java | 26 ++ .../mixin/OnlineOptionsScreenMixin.java | 34 +++ .../neoforge/mixin/PacketDecoderMixin.java | 108 +++++++ .../mixin/events/PlayerChangeScreenEvent.java | 32 ++ .../mixin/events/PlayerMouseInputEvent.java | 30 ++ .../mixin/events/PlayerPressKeyEvent.java | 20 ++ .../socketmc/neoforge/mod/AuditLogScreen.java | 72 +++++ .../socketmc/neoforge/mod/MainScreen.java | 62 ++++ .../neoforge/mod/ModPermissionsScreen.java | 175 +++++++++++ .../neoforge/screen/NeoForgeCustomButton.java | 29 ++ .../neoforge/screen/NeoForgeCustomWidget.java | 30 ++ .../screen/NeoForgeGraphicsContext.java | 80 +++++ .../neoforge/screen/NeoForgeOverlay.java | 24 ++ .../neoforge/screen/NeoForgeScreen.java | 80 +++++ .../neoforge/screen/NeoForgeScreenUtil.java | 288 ++++++++++++++++++ .../screen/NeoForgeSendInstructionButton.java | 29 ++ .../neoforge/screen/NeoForgeToast.java | 34 +++ .../resources/META-INF/accesstransformer.cfg | 45 +++ .../resources/META-INF/neoforge.mods.toml | 22 ++ .../resources/socketmc-neoforge.mixins.json | 16 + .../machines/TestNeoForgeMachineFinder.java | 24 ++ .../machines/TestOpenScreenMachine.java | 22 ++ settings.gradle.kts | 3 +- 46 files changed, 2591 insertions(+), 2 deletions(-) create mode 100644 mod/neoforge/build.gradle.kts create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/NeoForgeEvents.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/NeoForgeRetriever.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/NeoForgeSocketMC.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/NeoForgeUtil.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/CloseScreenMachine.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DisplayToastMachine.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DrawBeaconBeamMachine.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DrawBufferMachine.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DrawContextMachine.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DrawItemStackMachine.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DrawShapeMachine.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DrawTextMachine.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DrawTextureMachine.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/NeoForgeMachineFinder.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/OpenBookAndQuillMachine.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/OpenScreenMachine.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/PingMachine.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/RenderingMachine.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/SetOverlayMachine.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mixin/AbstractWidgetMixin.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mixin/GuiMixin.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mixin/OnlineOptionsScreenMixin.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mixin/PacketDecoderMixin.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mixin/events/PlayerChangeScreenEvent.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mixin/events/PlayerMouseInputEvent.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mixin/events/PlayerPressKeyEvent.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mod/AuditLogScreen.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mod/MainScreen.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mod/ModPermissionsScreen.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeCustomButton.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeCustomWidget.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeGraphicsContext.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeOverlay.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeScreen.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeScreenUtil.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeSendInstructionButton.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeToast.java create mode 100644 mod/neoforge/src/main/resources/META-INF/accesstransformer.cfg create mode 100644 mod/neoforge/src/main/resources/META-INF/neoforge.mods.toml create mode 100644 mod/neoforge/src/main/resources/socketmc-neoforge.mixins.json create mode 100644 mod/neoforge/src/test/java/xyz/gmitch215/socketmc/neoforge/machines/TestNeoForgeMachineFinder.java create mode 100644 mod/neoforge/src/test/java/xyz/gmitch215/socketmc/neoforge/machines/TestOpenScreenMachine.java diff --git a/.gitignore b/.gitignore index e85769c7..f7562d1b 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ build/ .kotlin/ logs/ .DS_Store -run/ \ No newline at end of file +run/ +runs/ \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index ab1293cf..55b5e16b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,6 +12,8 @@ plugins { // Mod id("fabric-loom") version "1.7.3" apply false id("net.minecraftforge.gradle") version "6.0.27" apply false + id("net.neoforged.gradle.userdev") version "7.0.162" apply false + id("net.neoforged.gradle.mixin") version "7.0.162" apply false id("org.parchmentmc.librarian.forgegradle") version "1.+" apply false id("org.spongepowered.mixin") version "0.7.+" apply false id("com.modrinth.minotaur") version "2.+" apply false @@ -94,6 +96,7 @@ allprojects { maven("https://maven.parchmentmc.org") maven("https://maven.terraformersmc.com/") maven("https://libraries.minecraft.net/") + maven("https://maven.neoforged.net/releases/") } publishing { diff --git a/mod/neoforge/build.gradle.kts b/mod/neoforge/build.gradle.kts new file mode 100644 index 00000000..2b0d493c --- /dev/null +++ b/mod/neoforge/build.gradle.kts @@ -0,0 +1,82 @@ +plugins { + id("net.neoforged.gradle.userdev") + id("net.neoforged.gradle.mixin") + id("com.modrinth.minotaur") +} + +description = "NeoForge Mod for SocketMC Client-side Implementation" + +val minecraft = project.ext["minecraft_version"].toString() +val parchmentV = project.ext["parchment"].toString() + +val neoforge = "21.0.167" + +dependencies { + api(project(":socketmc-core")) + api(project(":socketmc-shared")) + + implementation("net.neoforged:neoforge:$neoforge") +} + +minecraft { + accessTransformers { + file("src/main/resources/META-INF/accesstransformer.cfg") + } +} + +subsystems { + parchment { + minecraftVersion.set(minecraft) + mappingsVersion.set(parchmentV) + } +} + +mixin { + config("socketmc-neoforge.mixins.json") +} + +runs { + named("client") { + workingDirectory("run") + modSources(sourceSets["main"]) + + dependencies { + runtime(configurations.runtimeClasspath.get()) + } + } +} + +tasks { + jar { + from(project(":socketmc-core").sourceSets["main"].output) + from(project(":socketmc-shared").sourceSets["main"].output) + duplicatesStrategy = DuplicatesStrategy.EXCLUDE + } + + processResources { + filesMatching("**/*.toml") { + expand(project.properties) + } + } + + named("modrinth") { + dependsOn("reobfJar") + } +} + +modrinth { + token.set(System.getenv("MODRINTH_TOKEN")) + projectId.set(project.ext["id"].toString()) + + versionName.set("SocketMC v$version") + versionNumber.set(version.toString()) + versionType.set(project.ext["version_type"].toString()) + + uploadFile.set(tasks.jar.get().archiveFile.get().asFile) + gameVersions.add(project.ext["minecraft_version"].toString()) + changelog.set(project.ext["changelog"].toString()) + + loaders.add("neoforge") + + syncBodyFrom.set(rootProject.file("README.md").bufferedReader().use { it.readText() }) +} \ No newline at end of file diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/NeoForgeEvents.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/NeoForgeEvents.java new file mode 100644 index 00000000..124b02ef --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/NeoForgeEvents.java @@ -0,0 +1,21 @@ +package xyz.gmitch215.socketmc.neoforge; + +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.neoforge.client.event.ClientTickEvent; +import net.neoforged.neoforge.event.entity.player.PlayerEvent; +import xyz.gmitch215.socketmc.neoforge.machines.RenderingMachine; + +public final class NeoForgeEvents { + + @SubscribeEvent + public void onDisconnect(PlayerEvent.PlayerLoggedOutEvent event) { + NeoForgeSocketMC.eventsEnabled = false; + } + + @SubscribeEvent + public void tick(ClientTickEvent.Post event) { + // Machines + RenderingMachine.tick(); + } + +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/NeoForgeRetriever.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/NeoForgeRetriever.java new file mode 100644 index 00000000..1356b097 --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/NeoForgeRetriever.java @@ -0,0 +1,83 @@ +package xyz.gmitch215.socketmc.neoforge; + +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelFuture; +import net.minecraft.network.FriendlyByteBuf; +import xyz.gmitch215.socketmc.retriever.ClientProperty; +import xyz.gmitch215.socketmc.retriever.Retriever; +import xyz.gmitch215.socketmc.retriever.RetrieverType; +import xyz.gmitch215.socketmc.retriever.Window; +import xyz.gmitch215.socketmc.util.InputType; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static xyz.gmitch215.socketmc.neoforge.NeoForgeSocketMC.minecraft; +import static xyz.gmitch215.socketmc.retriever.Retriever.create; + +public final class NeoForgeRetriever { + + private NeoForgeRetriever() {} + + public static final Set> PROPERTIES = Stream.concat( + Retriever.PROPERTIES.stream(), + Stream.of( + create(RetrieverType.CURRENT_WINDOW, () -> { + com.mojang.blaze3d.platform.Window window = minecraft.getWindow(); + + return new Window( + window.getWindow(), + window.isFullscreen(), + window.getX(), + window.getY(), + window.getWidth(), + window.getHeight(), + window.getScreenWidth(), + window.getScreenHeight(), + window.getGuiScaledWidth(), + window.getGuiScaledHeight(), + window.getGuiScale(), + window.getFramerateLimit(), + com.mojang.blaze3d.platform.Window.getPlatform(), + window.getRefreshRate() + ); + }), + create(RetrieverType.PAUSED, minecraft::isPaused), + create(RetrieverType.FPS, minecraft::getFps), + create(RetrieverType.GPU_UTILIZATION, minecraft::getGpuUtilization), + create(RetrieverType.LAUNCH_VERSION, minecraft::getLaunchedVersion), + create(RetrieverType.VERSION_TYPE, minecraft::getVersionType), + create(RetrieverType.LAST_INPUT_TYPE, () -> switch (minecraft.getLastInputType()) { + case KEYBOARD_ARROW -> InputType.KEYBOARD_ARROW; + case KEYBOARD_TAB -> InputType.KEYBOARD_TAB; + case MOUSE -> InputType.MOUSE; + default -> InputType.NONE; + }), + create(RetrieverType.COMMAND_HISTORY, () -> minecraft.commandHistory().history().toArray(new String[0])) + ) + ).collect(Collectors.toSet()); + + public static void response(UUID id, Object value) throws Exception { + FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer()); + buf.writeVarInt(-5); + buf.writeUUID(id); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ObjectOutputStream outw = new ObjectOutputStream(out); + outw.writeObject(value); + outw.close(); + + buf.writeByteArray(out.toByteArray()); + + ChannelFuture future = minecraft.player.connection.getConnection().channel().writeAndFlush(buf); + future.await(); + if (!future.isSuccess()) + throw new IOException("Failed to send retriever response", future.cause()); + } + +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/NeoForgeSocketMC.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/NeoForgeSocketMC.java new file mode 100644 index 00000000..f77ed972 --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/NeoForgeSocketMC.java @@ -0,0 +1,63 @@ +package xyz.gmitch215.socketmc.neoforge; + +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelFuture; +import net.minecraft.client.Minecraft; +import net.minecraft.network.FriendlyByteBuf; +import net.neoforged.fml.common.Mod; +import xyz.gmitch215.socketmc.SocketMC; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.util.Map; + +@Mod("socketmc") +public final class NeoForgeSocketMC implements SocketMC { + + public static boolean eventsEnabled = false; + + public static Minecraft minecraft; + + public NeoForgeSocketMC() { + minecraft = Minecraft.getInstance(); + GAME_DIRECTORY.set(minecraft.gameDirectory); + INSTANCE.set(this); + } + + public static void sendEvent(int id, Map params) { + if (!eventsEnabled) return; + if (minecraft.player == null) return; + + try { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ObjectOutputStream obj = new ObjectOutputStream(out); + obj.writeObject(params); + obj.close(); + + FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer()); + buf.writeVarInt(-3); + buf.writeVarInt(id); + buf.writeByteArray(out.toByteArray()); + + ChannelFuture future = minecraft.player.connection.getConnection().channel().writeAndFlush(buf); + future.await(); + if (!future.isSuccess()) + throw new IOException("Failed to send event", future.cause()); + } catch (IOException | InterruptedException e) { + SocketMC.print(e); + } + } + + // Implementation + + @Override + public void sendSocketMCEvent(int id, Map params) { + sendEvent(id, params); + } + + @Override + public long getWindowId() { + return minecraft.getWindow().getWindow(); + } +} \ No newline at end of file diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/NeoForgeUtil.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/NeoForgeUtil.java new file mode 100644 index 00000000..a20e626e --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/NeoForgeUtil.java @@ -0,0 +1,90 @@ +package xyz.gmitch215.socketmc.neoforge; + +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.minecraft.client.gui.components.WidgetSprites; +import net.minecraft.nbt.TagParser; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; +import xyz.gmitch215.socketmc.screen.util.Sprite; +import xyz.gmitch215.socketmc.screen.util.Tooltip; +import xyz.gmitch215.socketmc.util.Identifier; +import xyz.gmitch215.socketmc.util.NBTTag; +import xyz.gmitch215.socketmc.util.render.text.JsonText; + +import static xyz.gmitch215.socketmc.neoforge.NeoForgeSocketMC.minecraft; + +public final class NeoForgeUtil { + + private NeoForgeUtil() {} + + public static Component fromJson(String json) { + if (json == null) return Component.empty(); + return Component.Serializer.fromJson(json, minecraft.level.registryAccess()); + } + + public static String toJson(Component component) { + if (component == null) return ""; + return Component.Serializer.toJson(component, minecraft.level.registryAccess()); + } + + public static JsonText toText(Component component) { + if (component == null) return JsonText.empty(); + return JsonText.raw(toJson(component)); + } + + public static Identifier fromMinecraft(ResourceLocation resourceLocation) { + if (resourceLocation == null) return null; + return new Identifier(resourceLocation.getNamespace(), resourceLocation.getPath()); + } + + public static ResourceLocation toMinecraft(Identifier identifier) { + if (identifier == null) return null; + return ResourceLocation.fromNamespaceAndPath(identifier.getNamespace(), identifier.getPath()); + } + + public static Sprite fromMinecraft(WidgetSprites widgetSprites) { + return new Sprite( + fromMinecraft(widgetSprites.enabled()), + fromMinecraft(widgetSprites.enabledFocused()), + fromMinecraft(widgetSprites.disabled()), + fromMinecraft(widgetSprites.disabledFocused()) + ); + } + + public static WidgetSprites toMinecraft(Sprite sprite) { + return new WidgetSprites( + toMinecraft(sprite.getEnabled()), + toMinecraft(sprite.getEnabledHovered()), + toMinecraft(sprite.getDisabled()), + toMinecraft(sprite.getDisabledHovered()) + ); + } + + public static Tooltip fromMinecraft(net.minecraft.client.gui.components.Tooltip tooltip) { + if (tooltip == null) return null; + + return new Tooltip( + toJson(tooltip.message), + toJson(tooltip.narration) + ); + } + + public static net.minecraft.client.gui.components.Tooltip toMinecraft(Tooltip tooltip) { + if (tooltip == null) return null; + + return net.minecraft.client.gui.components.Tooltip.create( + fromJson(tooltip.getTooltipJSON()), + fromJson(tooltip.getNarrationMessageJSON()) + ); + } + + public static ItemStack toItem(NBTTag tag) { + try { + return ItemStack.parse(minecraft.level.registryAccess(), TagParser.parseTag(tag.toTag())).orElse(ItemStack.EMPTY); + } catch (CommandSyntaxException e) { + return ItemStack.EMPTY; + } + } + +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/CloseScreenMachine.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/CloseScreenMachine.java new file mode 100644 index 00000000..78f6e74a --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/CloseScreenMachine.java @@ -0,0 +1,20 @@ +package xyz.gmitch215.socketmc.neoforge.machines; + +import org.jetbrains.annotations.NotNull; +import xyz.gmitch215.socketmc.instruction.Instruction; +import xyz.gmitch215.socketmc.instruction.InstructionId; +import xyz.gmitch215.socketmc.instruction.Machine; +import xyz.gmitch215.socketmc.neoforge.NeoForgeSocketMC; + +@InstructionId(Instruction.CLOSE_SCREEN) +public final class CloseScreenMachine implements Machine { + + public static final CloseScreenMachine MACHINE = new CloseScreenMachine(); + + private CloseScreenMachine() {} + + @Override + public void onInstruction(@NotNull Instruction instruction) throws Exception { + NeoForgeSocketMC.minecraft.execute(() -> NeoForgeSocketMC.minecraft.setScreen(null)); + } +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DisplayToastMachine.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DisplayToastMachine.java new file mode 100644 index 00000000..7ca23260 --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DisplayToastMachine.java @@ -0,0 +1,27 @@ +package xyz.gmitch215.socketmc.neoforge.machines; + +import net.minecraft.client.gui.components.toasts.Toast; +import org.jetbrains.annotations.NotNull; +import xyz.gmitch215.socketmc.instruction.Instruction; +import xyz.gmitch215.socketmc.instruction.InstructionId; +import xyz.gmitch215.socketmc.instruction.Machine; +import xyz.gmitch215.socketmc.neoforge.screen.NeoForgeScreenUtil; + +import static xyz.gmitch215.socketmc.neoforge.NeoForgeSocketMC.minecraft; + + +@InstructionId(Instruction.DISPLAY_TOAST) +public final class DisplayToastMachine implements Machine { + + public static final DisplayToastMachine MACHINE = new DisplayToastMachine(); + + private DisplayToastMachine() {} + + @Override + public void onInstruction(@NotNull Instruction instruction) throws Exception { + xyz.gmitch215.socketmc.screen.Toast toast = instruction.firstParameter(xyz.gmitch215.socketmc.screen.Toast.class); + Toast toast0 = NeoForgeScreenUtil.toMinecraft(toast); + minecraft.execute(() -> minecraft.getToasts().addToast(toast0)); + } + +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DrawBeaconBeamMachine.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DrawBeaconBeamMachine.java new file mode 100644 index 00000000..834be2d8 --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DrawBeaconBeamMachine.java @@ -0,0 +1,51 @@ +package xyz.gmitch215.socketmc.neoforge.machines; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.DeltaTracker; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.renderer.blockentity.BeaconRenderer; +import xyz.gmitch215.socketmc.instruction.Instruction; +import xyz.gmitch215.socketmc.instruction.InstructionId; +import xyz.gmitch215.socketmc.instruction.Machine; +import xyz.gmitch215.socketmc.util.LifecycleMap; + +import java.util.function.BiConsumer; + +import static xyz.gmitch215.socketmc.neoforge.NeoForgeSocketMC.minecraft; + +@InstructionId(Instruction.DRAW_BEACON_BEAM) +public final class DrawBeaconBeamMachine implements Machine { + + public static final DrawBeaconBeamMachine MACHINE = new DrawBeaconBeamMachine(); + + private DrawBeaconBeamMachine() {} + + private static final LifecycleMap> lifecycle = new LifecycleMap<>(); + + public static void frameTick(GuiGraphics graphics, DeltaTracker delta) { + lifecycle.run(); + lifecycle.forEach(c -> c.accept(graphics, delta)); + } + + @Override + public void onInstruction(Instruction instruction) { + int x = instruction.intParameter(0); + int y = instruction.intParameter(1); + int z = instruction.intParameter(2); + int height = instruction.intParameter(3); + int color = instruction.intParameter(4); + int yOffset = instruction.intParameter(5); + float beamRadius = instruction.floatParameter(6); + float glowRadius = instruction.floatParameter(7); + long millis = instruction.lastLongParameter(); + + PoseStack stack = new PoseStack(); + stack.pushPose(); + stack.translate(x, y, z); + + lifecycle.store((graphics, delta) -> BeaconRenderer.renderBeaconBeam( + stack, graphics.bufferSource(), BeaconRenderer.BEAM_LOCATION, delta.getGameTimeDeltaPartialTick(true), 1.0F, minecraft.level.getGameTime(), + yOffset, height, color, beamRadius, glowRadius + ), millis); + } +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DrawBufferMachine.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DrawBufferMachine.java new file mode 100644 index 00000000..a2cdaf6a --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DrawBufferMachine.java @@ -0,0 +1,61 @@ +package xyz.gmitch215.socketmc.neoforge.machines; + +import com.mojang.blaze3d.vertex.*; +import net.minecraft.client.DeltaTracker; +import net.minecraft.client.gui.GuiGraphics; +import org.jetbrains.annotations.NotNull; +import org.joml.Matrix4f; +import xyz.gmitch215.socketmc.instruction.Instruction; +import xyz.gmitch215.socketmc.instruction.InstructionId; +import xyz.gmitch215.socketmc.instruction.Machine; +import xyz.gmitch215.socketmc.util.LifecycleMap; +import xyz.gmitch215.socketmc.util.render.RenderBuffer; +import xyz.gmitch215.socketmc.util.render.Vertex; + +import java.util.function.Consumer; + +@InstructionId(Instruction.DRAW_BUFFER) +public final class DrawBufferMachine implements Machine { + + public static final DrawBufferMachine MACHINE = new DrawBufferMachine(); + + private DrawBufferMachine() {} + + private static final LifecycleMap> lifecycle = new LifecycleMap<>(); + + public static void frameTick(GuiGraphics graphics, DeltaTracker delta) { + lifecycle.run(); + lifecycle.forEach(c -> c.accept(graphics)); + } + + @Override + public void onInstruction(@NotNull Instruction instruction) { + RenderBuffer buffer = instruction.parameter(0, RenderBuffer.class); + long millis = instruction.lastLongParameter(); + + VertexFormat.Mode mode = switch (buffer.getMode()) { + case LINES -> VertexFormat.Mode.LINES; + case LINE_STRIP -> VertexFormat.Mode.LINE_STRIP; + case TRIANGLES -> VertexFormat.Mode.TRIANGLES; + case TRIANGLE_STRIP -> VertexFormat.Mode.TRIANGLE_STRIP; + case TRIANGLE_FAN -> VertexFormat.Mode.TRIANGLE_FAN; + case QUADRILATERALS -> VertexFormat.Mode.QUADS; + }; + + lifecycle.store(graphics -> { + Tesselator tesselator = Tesselator.getInstance(); + Matrix4f matrix = graphics.pose().last().pose(); + + BufferBuilder builder = tesselator.begin(mode, DefaultVertexFormat.POSITION_COLOR); + + for (Vertex vertex : buffer.getVertices()) { + int color = buffer.getColor(vertex); + + builder.addVertex(matrix, vertex.getX(), vertex.getY(), vertex.getZ()) + .setColor((color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF, (color >> 24) & 0xFF); + } + + BufferUploader.drawWithShader(builder.buildOrThrow()); + }, millis); + } +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DrawContextMachine.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DrawContextMachine.java new file mode 100644 index 00000000..4717e4e1 --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DrawContextMachine.java @@ -0,0 +1,282 @@ +package xyz.gmitch215.socketmc.neoforge.machines; + +import com.mojang.blaze3d.platform.Lighting; +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.DeltaTracker; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.ItemDisplayContext; +import net.minecraft.world.item.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.joml.Matrix3f; +import org.joml.Matrix4f; +import org.joml.Quaternionf; +import xyz.gmitch215.socketmc.instruction.Instruction; +import xyz.gmitch215.socketmc.instruction.InstructionId; +import xyz.gmitch215.socketmc.instruction.Machine; +import xyz.gmitch215.socketmc.neoforge.NeoForgeUtil; +import xyz.gmitch215.socketmc.neoforge.screen.NeoForgeGraphicsContext; +import xyz.gmitch215.socketmc.util.Identifier; +import xyz.gmitch215.socketmc.util.LifecycleMap; +import xyz.gmitch215.socketmc.util.NBTTag; +import xyz.gmitch215.socketmc.util.SerializableConsumer; +import xyz.gmitch215.socketmc.util.render.DrawingContext; +import xyz.gmitch215.socketmc.util.render.GraphicsContext; +import xyz.gmitch215.socketmc.util.render.ItemDisplayType; + +import java.util.List; +import java.util.Optional; +import java.util.function.Consumer; +import java.util.function.Function; + +import static xyz.gmitch215.socketmc.neoforge.NeoForgeSocketMC.minecraft; + +@InstructionId(Instruction.DRAW_CONTEXT) +@SuppressWarnings("unchecked") +public final class DrawContextMachine implements Machine { + + public static final DrawContextMachine MACHINE = new DrawContextMachine(); + + private DrawContextMachine() {} + + private static final LifecycleMap> lifecycle = new LifecycleMap<>(); + + public static void frameTick(GuiGraphics graphics, DeltaTracker delta) { + lifecycle.run(); + lifecycle.forEach(c -> c.accept(graphics)); + } + + @Override + public void onInstruction(@NotNull Instruction instruction) throws Exception { + DrawingContext context = instruction.firstParameter(DrawingContext.class); + long millis = instruction.lastLongParameter(); + + lifecycle.store(graphics -> draw(graphics, context), millis); + } + + public static void draw(GuiGraphics graphics, DrawingContext context) { + for (Function func : context) { + DrawingContext.Command cmd = func.apply(NeoForgeGraphicsContext.INSTANCE); + + RenderType type = switch (cmd.getType()) { + case DEFAULT -> RenderType.gui(); + case OVERLAY -> RenderType.guiOverlay(); + case TEXT_HIGHLIGHT -> RenderType.guiTextHighlight(); + case GHOST_RECIPE_OVERLAY -> RenderType.guiGhostRecipeOverlay(); + }; + + List modifiers = cmd.getModifiers(); + boolean modding = !modifiers.isEmpty(); + + if (modding) { + graphics.pose().pushPose(); + + for (DrawingContext.Modifier mod : modifiers) + applyModifier(mod, graphics.pose()); + } + + switch (cmd.getId()) { + case DrawingContext.H_LINE -> { + int minX = cmd.firstIntParameter(); + int maxX = cmd.intParameter(1); + int y = cmd.intParameter(2); + int rgb = cmd.lastIntParameter(); + + graphics.hLine(type, minX, maxX, y, rgb); + } + case DrawingContext.V_LINE -> { + int x = cmd.firstIntParameter(); + int minY = cmd.intParameter(1); + int maxY = cmd.intParameter(2); + int rgb = cmd.lastIntParameter(); + + graphics.vLine(type, x, minY, maxY, rgb); + } + case DrawingContext.ENABLE_SCISSOR -> { + int minX = cmd.firstIntParameter(); + int minY = cmd.intParameter(1); + int maxX = cmd.intParameter(2); + int maxY = cmd.lastIntParameter(); + + graphics.enableScissor(minX, minY, maxX, maxY); + } + case DrawingContext.DISABLE_SCISSOR -> graphics.disableScissor(); + case DrawingContext.FILL -> { + int minX = cmd.firstIntParameter(); + int minY = cmd.intParameter(1); + int maxX = cmd.intParameter(2); + int maxY = cmd.intParameter(3); + int z = cmd.intParameter(4); + int rgb = cmd.lastIntParameter(); + + graphics.fill(type, minX, minY, maxX, maxY, z, rgb); + } + case DrawingContext.FILL_GRADIENT -> { + int minX = cmd.firstIntParameter(); + int minY = cmd.intParameter(1); + int maxX = cmd.intParameter(2); + int maxY = cmd.intParameter(3); + int z = cmd.intParameter(4); + int from = cmd.intParameter(5); + int to = cmd.lastIntParameter(); + + graphics.fillGradient(type, minX, minY, maxX, maxY, z, from, to); + } + case DrawingContext.DRAW_CENTERED_STRING -> { + int x = cmd.firstIntParameter(); + int y = cmd.intParameter(1); + String text = cmd.stringParameter(2); + int rgb = cmd.lastIntParameter(); + + graphics.drawCenteredString(minecraft.font, NeoForgeUtil.fromJson(text), x, y, rgb); + } + case DrawingContext.DRAW_STRING -> { + int x = cmd.firstIntParameter(); + int y = cmd.intParameter(1); + String text = cmd.stringParameter(2); + int rgb = cmd.intParameter(3); + boolean dropShadow = cmd.lastBooleanParameter(); + + graphics.drawString(minecraft.font, NeoForgeUtil.fromJson(text), x, y, rgb, dropShadow); + } + case DrawingContext.DRAW_WORD_WRAP -> { + int x = cmd.firstIntParameter(); + int y = cmd.intParameter(1); + int width = cmd.intParameter(2); + String text = cmd.stringParameter(3); + int rgb = cmd.intParameter(4); + + graphics.drawWordWrap(minecraft.font, NeoForgeUtil.fromJson(text), x, y, width, rgb); + } + case DrawingContext.OUTLINE -> { + int minX = cmd.firstIntParameter(); + int minY = cmd.intParameter(1); + int maxX = cmd.intParameter(2); + int maxY = cmd.intParameter(3); + int rgb = cmd.lastIntParameter(); + + graphics.renderOutline(minX, minY, maxX, maxY, rgb); + } + case DrawingContext.BLIT -> { + Identifier texture = cmd.firstParameter(Identifier.class); + int x = cmd.intParameter(1); + int y = cmd.intParameter(2); + float u = cmd.intParameter(3); + float v = cmd.intParameter(4); + int width = cmd.intParameter(5); + int height = cmd.intParameter(6); + int textureWidth = cmd.intParameter(7); + int textureHeight = cmd.lastIntParameter(); + + graphics.blit(NeoForgeUtil.toMinecraft(texture), x, y, u, v, width, height, textureWidth, textureHeight); + } + case DrawingContext.BLIT_SPRITE -> { + Identifier sprite = cmd.firstParameter(Identifier.class); + int x = cmd.intParameter(1); + int y = cmd.intParameter(2); + int width = cmd.intParameter(3); + int height = cmd.intParameter(4); + int z = cmd.intParameter(5); + + graphics.blitSprite(NeoForgeUtil.toMinecraft(sprite), x, y, z, width, height); + } + case DrawingContext.DRAW_TOOLTIP -> { + int x = cmd.firstIntParameter(); + int y = cmd.intParameter(1); + List text = ((List) cmd.lastParameter(List.class)) + .stream() + .map(NeoForgeUtil::fromJson) + .toList(); + + graphics.renderTooltip(minecraft.font, text, Optional.empty(), x, y); + } + case DrawingContext.DRAW_ITEMSTACK -> { + NBTTag tag = cmd.firstParameter(NBTTag.class); + int x = cmd.intParameter(1); + int y = cmd.intParameter(2); + int guiOffset = cmd.intParameter(3); + float scale = cmd.floatParameter(4); + ItemDisplayType displayType = cmd.parameter(5, ItemDisplayType.class); + int combinedLight = cmd.intParameter(6); + int combinedOverlay = cmd.lastIntParameter(); + + ItemStack stack = NeoForgeUtil.toItem(tag); + ItemDisplayContext ctx = switch (displayType) { + case NONE -> ItemDisplayContext.NONE; + case THIRD_PERSON_LEFT_HAND -> ItemDisplayContext.THIRD_PERSON_LEFT_HAND; + case THIRD_PERSON_RIGHT_HAND -> ItemDisplayContext.THIRD_PERSON_RIGHT_HAND; + case FIRST_PERSON_LEFT_HAND -> ItemDisplayContext.FIRST_PERSON_LEFT_HAND; + case FIRST_PERSON_RIGHT_HAND -> ItemDisplayContext.FIRST_PERSON_RIGHT_HAND; + case HEAD -> ItemDisplayContext.HEAD; + case GROUND -> ItemDisplayContext.GROUND; + case FIXED -> ItemDisplayContext.FIXED; + default -> ItemDisplayContext.GUI; + }; + + BakedModel model = minecraft.getItemRenderer().getModel(stack, minecraft.level, minecraft.player, 0); + graphics.pose().pushPose(); + graphics.pose().translate(x + (scale / 2), y + (scale / 2), 150 + (model.isGui3d() ? guiOffset : 0)); + graphics.pose().scale(scale, -scale, scale); + + boolean noLight = !model.usesBlockLight(); + if (noLight) + Lighting.setupForFlatItems(); + + minecraft.getItemRenderer().render(stack, ctx, false, graphics.pose(), graphics.bufferSource(), combinedLight, combinedOverlay, model); + graphics.flush(); + if (noLight) + Lighting.setupFor3DItems(); + + graphics.pose().popPose(); + } + } + + if (modding) + graphics.pose().popPose(); + } + } + + public static void applyModifier(DrawingContext.Modifier mod, PoseStack pose) { + switch (mod.getId()) { + case DrawingContext.MODIFIER_SCALE -> { + float x = mod.firstFloatParameter(); + float y = mod.floatParameter(1); + float z = mod.lastFloatParameter(); + + pose.scale(x, y, z); + } + case DrawingContext.MODIFIER_TRANSLATE -> { + float x = mod.firstFloatParameter(); + float y = mod.floatParameter(1); + float z = mod.lastFloatParameter(); + + pose.translate(x, y, z); + } + case DrawingContext.MODIFIER_ROTATE -> { + Quaternionf quaternion = mod.firstParameter(Quaternionf.class); + + pose.mulPose(quaternion); + } + case DrawingContext.MODIFIER_ROTATE_AROUND -> { + Quaternionf quaternion = mod.firstParameter(Quaternionf.class); + float x = mod.floatParameter(1); + float y = mod.floatParameter(2); + float z = mod.lastFloatParameter(); + + pose.rotateAround(quaternion, x, y, z); + } + case DrawingContext.MODIFIER_APPLY_POSE -> { + SerializableConsumer consumer = mod.firstParameter(SerializableConsumer.class); + + consumer.accept(pose.last().pose()); + } + case DrawingContext.MODIFIER_APPLY_NORMAL -> { + SerializableConsumer consumer = mod.firstParameter(SerializableConsumer.class); + + consumer.accept(pose.last().normal()); + } + } + } +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DrawItemStackMachine.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DrawItemStackMachine.java new file mode 100644 index 00000000..26982f60 --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DrawItemStackMachine.java @@ -0,0 +1,43 @@ +package xyz.gmitch215.socketmc.neoforge.machines; + +import net.minecraft.client.DeltaTracker; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.world.item.ItemStack; +import org.jetbrains.annotations.NotNull; +import xyz.gmitch215.socketmc.neoforge.NeoForgeUtil; +import xyz.gmitch215.socketmc.instruction.Instruction; +import xyz.gmitch215.socketmc.instruction.InstructionId; +import xyz.gmitch215.socketmc.instruction.Machine; +import xyz.gmitch215.socketmc.util.LifecycleMap; +import xyz.gmitch215.socketmc.util.NBTTag; + +import java.util.function.BiConsumer; + +@InstructionId(Instruction.DRAW_ITEMSTACK) +public final class DrawItemStackMachine implements Machine { + + public static final DrawItemStackMachine MACHINE = new DrawItemStackMachine(); + + private DrawItemStackMachine() {} + + private static final LifecycleMap> lifecycle = new LifecycleMap<>(); + + public static void frameTick(GuiGraphics graphics, DeltaTracker delta) { + lifecycle.run(); + lifecycle.forEach(c -> c.accept(graphics, delta)); + } + + @Override + public void onInstruction(@NotNull Instruction instruction) throws Exception { + NBTTag tag = instruction.firstParameter(NBTTag.class); + int x = instruction.intParameter(1); + int y = instruction.intParameter(2); + int guiOffset = instruction.intParameter(3); + int randomSeed = instruction.intParameter(4); + long millis = instruction.lastLongParameter(); + + ItemStack item = NeoForgeUtil.toItem(tag); + + lifecycle.store((graphics, delta) -> graphics.renderItem(item, x, y, guiOffset, randomSeed), millis); + } +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DrawShapeMachine.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DrawShapeMachine.java new file mode 100644 index 00000000..d5e2a35c --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DrawShapeMachine.java @@ -0,0 +1,76 @@ +package xyz.gmitch215.socketmc.neoforge.machines; + +import net.minecraft.client.DeltaTracker; +import net.minecraft.client.gui.GuiGraphics; +import org.jetbrains.annotations.NotNull; +import xyz.gmitch215.socketmc.instruction.Instruction; +import xyz.gmitch215.socketmc.instruction.InstructionId; +import xyz.gmitch215.socketmc.instruction.Machine; +import xyz.gmitch215.socketmc.util.LifecycleMap; + +import java.util.function.Consumer; + +@InstructionId(Instruction.DRAW_SHAPE) +public final class DrawShapeMachine implements Machine { + + public static final DrawShapeMachine MACHINE = new DrawShapeMachine(); + + private DrawShapeMachine() {} + + private static final LifecycleMap> lifecycle = new LifecycleMap<>(); + + public static void frameTick(GuiGraphics graphics, DeltaTracker delta) { + lifecycle.run(); + lifecycle.forEach(c -> c.accept(graphics)); + } + + private static void fill(int x, int y, Instruction i) { + int width = i.intParameter(3); + int height = i.intParameter(4); + int color = i.intParameter(5); + long millis = i.lastLongParameter(); + + lifecycle.store(graphics -> graphics.fill(x, y, x + width, y + height, color), millis); + } + + private static void gradient(int x, int y, Instruction i) { + int width = i.intParameter(3); + int height = i.intParameter(4); + int z = i.intParameter(5); + int color1 = i.intParameter(6); + int color2 = i.intParameter(7); + long millis = i.lastLongParameter(); + + lifecycle.store(graphics -> graphics.fillGradient(x, y, x + width, y + height, z, color1, color2), millis); + } + + private static void vline(int x, int y, Instruction i) { + int height = i.intParameter(3); + int color = i.intParameter(4); + long millis = i.lastLongParameter(); + + lifecycle.store(graphics -> graphics.vLine(x, y, y + height, color), millis); + } + + private static void hline(int x, int y, Instruction i) { + int width = i.intParameter(3); + int color = i.intParameter(4); + long millis = i.lastLongParameter(); + + lifecycle.store(graphics -> graphics.hLine(x, x + width, y, color), millis); + } + + @Override + public void onInstruction(@NotNull Instruction instruction) { + String id = instruction.parameter(0, String.class); + int x = instruction.intParameter(1); + int y = instruction.intParameter(2); + + switch (id) { + case "fill" -> fill(x, y, instruction); + case "gradient" -> gradient(x, y, instruction); + case "line_v" -> vline(x, y, instruction); + case "line_h" -> hline(x, y, instruction); + } + } +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DrawTextMachine.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DrawTextMachine.java new file mode 100644 index 00000000..61a62ddc --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DrawTextMachine.java @@ -0,0 +1,43 @@ +package xyz.gmitch215.socketmc.neoforge.machines; + +import net.minecraft.client.DeltaTracker; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.network.chat.Component; +import org.jetbrains.annotations.NotNull; +import xyz.gmitch215.socketmc.instruction.Instruction; +import xyz.gmitch215.socketmc.instruction.InstructionId; +import xyz.gmitch215.socketmc.instruction.Machine; +import xyz.gmitch215.socketmc.util.LifecycleMap; + +import java.util.function.Consumer; + +import static xyz.gmitch215.socketmc.neoforge.NeoForgeSocketMC.minecraft; + +@InstructionId(Instruction.DRAW_TEXT) +public final class DrawTextMachine implements Machine { + + public static final DrawTextMachine MACHINE = new DrawTextMachine(); + + private DrawTextMachine() {} + + private static final LifecycleMap> lifecycle = new LifecycleMap<>(); + + public static void frameTick(GuiGraphics graphics, DeltaTracker delta) { + lifecycle.run(); + lifecycle.forEach(c -> c.accept(graphics)); + } + + @Override + public void onInstruction(@NotNull Instruction instruction) { + int x = instruction.intParameter(0); + int y = instruction.intParameter(1); + Component c = Component.Serializer.fromJson(instruction.parameter(2, String.class), minecraft.level.registryAccess()); + int color = instruction.intParameter(3); + boolean dropShadow = instruction.parameter(4, Boolean.class); + long millis = instruction.parameter(5, Long.class); + + lifecycle.store(graphics -> graphics.drawString(minecraft.font, c, x, y, color, dropShadow), millis); + } + +} + diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DrawTextureMachine.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DrawTextureMachine.java new file mode 100644 index 00000000..d4980565 --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/DrawTextureMachine.java @@ -0,0 +1,51 @@ +package xyz.gmitch215.socketmc.neoforge.machines; + +import net.minecraft.client.DeltaTracker; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.resources.ResourceLocation; +import xyz.gmitch215.socketmc.neoforge.NeoForgeUtil; +import xyz.gmitch215.socketmc.instruction.Instruction; +import xyz.gmitch215.socketmc.instruction.InstructionId; +import xyz.gmitch215.socketmc.instruction.Machine; +import xyz.gmitch215.socketmc.util.Identifier; +import xyz.gmitch215.socketmc.util.LifecycleMap; + +import java.util.function.Consumer; + +@InstructionId(Instruction.DRAW_TEXTURE) +public final class DrawTextureMachine implements Machine { + + public static final DrawTextureMachine MACHINE = new DrawTextureMachine(); + + private DrawTextureMachine() {} + + private static final LifecycleMap> lifecycle = new LifecycleMap<>(); + + public static void frameTick(GuiGraphics graphics, DeltaTracker delta) { + lifecycle.run(); + lifecycle.forEach(c -> c.accept(graphics)); + } + + @Override + public void onInstruction(Instruction instruction) { + int x = instruction.intParameter(0); + int y = instruction.intParameter(1); + int width = instruction.intParameter(2); + int height = instruction.intParameter(3); + Identifier texture = instruction.parameter(4, Identifier.class); + + int u = instruction.intParameter(5); + int v = instruction.intParameter(6); + int regionWidth = instruction.intParameter(7); + int regionHeight = instruction.intParameter(8); + + long millis = instruction.lastLongParameter(); + + ResourceLocation l = NeoForgeUtil.toMinecraft(texture); + int rw = regionWidth == -1 ? width : regionWidth; + int rh = regionHeight == -1 ? height : regionHeight; + + lifecycle.store(graphics -> graphics.blit(l, x, y, width, height, u, v, rw, rh, 256, 256), millis); + } + +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/NeoForgeMachineFinder.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/NeoForgeMachineFinder.java new file mode 100644 index 00000000..12fee53c --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/NeoForgeMachineFinder.java @@ -0,0 +1,32 @@ +package xyz.gmitch215.socketmc.neoforge.machines; + +import xyz.gmitch215.socketmc.instruction.Machine; +import xyz.gmitch215.socketmc.machines.LogMessageMachine; +import xyz.gmitch215.socketmc.machines.MachineFinder; + +import java.util.List; +import java.util.stream.Stream; + +public final class NeoForgeMachineFinder { + + private NeoForgeMachineFinder() {} + + public static final List> MACHINES = Stream.concat(MachineFinder.SHARED_MACHINES.stream(), Stream.of( + PingMachine.class, + DrawTextMachine.class, + DrawShapeMachine.class, + DrawBufferMachine.class, + LogMessageMachine.class, + DrawTextureMachine.class, + OpenBookAndQuillMachine.class, + OpenScreenMachine.class, + CloseScreenMachine.class, + RenderingMachine.class, + DrawBeaconBeamMachine.class, + DrawContextMachine.class, + DisplayToastMachine.class, + SetOverlayMachine.class, + DrawItemStackMachine.class + )).toList(); + +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/OpenBookAndQuillMachine.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/OpenBookAndQuillMachine.java new file mode 100644 index 00000000..e57e410d --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/OpenBookAndQuillMachine.java @@ -0,0 +1,22 @@ +package xyz.gmitch215.socketmc.neoforge.machines; + +import net.minecraft.world.InteractionHand; +import net.minecraft.world.item.Items; +import xyz.gmitch215.socketmc.instruction.Instruction; +import xyz.gmitch215.socketmc.instruction.InstructionId; +import xyz.gmitch215.socketmc.instruction.Machine; +import xyz.gmitch215.socketmc.neoforge.NeoForgeSocketMC; + +@InstructionId(Instruction.OPEN_BOOK_AND_QUILL) +public final class OpenBookAndQuillMachine implements Machine { + + public static final OpenBookAndQuillMachine MACHINE = new OpenBookAndQuillMachine(); + + private OpenBookAndQuillMachine() {} + + @Override + public void onInstruction(Instruction instruction) { + NeoForgeSocketMC.minecraft.player.openItemGui(Items.WRITABLE_BOOK.getDefaultInstance(), InteractionHand.MAIN_HAND); + } + +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/OpenScreenMachine.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/OpenScreenMachine.java new file mode 100644 index 00000000..8db0a3df --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/OpenScreenMachine.java @@ -0,0 +1,95 @@ +package xyz.gmitch215.socketmc.neoforge.machines; + +import net.minecraft.client.gui.screens.*; +import net.minecraft.client.gui.screens.achievement.StatsScreen; +import net.minecraft.client.gui.screens.advancements.AdvancementsScreen; +import net.minecraft.client.gui.screens.options.OptionsScreen; +import net.minecraft.network.chat.Component; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import xyz.gmitch215.socketmc.instruction.Instruction; +import xyz.gmitch215.socketmc.instruction.InstructionId; +import xyz.gmitch215.socketmc.instruction.Machine; +import xyz.gmitch215.socketmc.neoforge.NeoForgeUtil; +import xyz.gmitch215.socketmc.neoforge.screen.NeoForgeScreen; +import xyz.gmitch215.socketmc.screen.AbstractScreen; +import xyz.gmitch215.socketmc.screen.CustomScreen; +import xyz.gmitch215.socketmc.screen.DefaultScreen; + +import static xyz.gmitch215.socketmc.neoforge.NeoForgeSocketMC.minecraft; + +@InstructionId(Instruction.OPEN_SCREEN) +public final class OpenScreenMachine implements Machine { + + public static final OpenScreenMachine MACHINE = new OpenScreenMachine(); + + private OpenScreenMachine() {}; + + static Screen defaultScreen(@NotNull DefaultScreen screen, @Nullable Screen lastScreen) { + return switch (screen.getIdentifier()) { + case "title" -> new TitleScreen(); + case "pause" -> new PauseScreen(true); + case "options" -> new OptionsScreen(lastScreen, minecraft.options); + case "share_to_lan" -> new ShareToLanScreen(lastScreen); + case "advancements" -> new AdvancementsScreen(minecraft.getConnection().getAdvancements(), lastScreen); + case "stats" -> new StatsScreen(lastScreen, minecraft.player.getStats()); + case "alert" -> { + Component title = NeoForgeUtil.fromJson(screen.data("title", String.class)); + Component message = NeoForgeUtil.fromJson(screen.data("message", String.class)); + String button = screen.data("button", String.class); + + if (button == null) + yield new AlertScreen(() -> {}, title, message); + else + yield new AlertScreen(() -> {}, title, message, NeoForgeUtil.fromJson(button), true); + } + case "disconnected" -> { + Component title = NeoForgeUtil.fromJson(screen.data("title", String.class)); + Component reason = NeoForgeUtil.fromJson(screen.data("reason", String.class)); + String button = screen.data("button", String.class); + + if (button == null) + yield new DisconnectedScreen(lastScreen, title, reason); + else + yield new DisconnectedScreen(lastScreen, title, reason, NeoForgeUtil.fromJson(button)); + } + case "message" -> { + Component message = NeoForgeUtil.fromJson(screen.data("message", String.class)); + yield new GenericMessageScreen(message); + } + case "death" -> { + String cause = screen.data("cause", String.class); + boolean hardcore = screen.data("hardcore", Boolean.class); + + if (cause == null) + yield new DeathScreen(null, hardcore); + else + yield new DeathScreen(NeoForgeUtil.fromJson(cause), hardcore); + } + case "error" -> { + Component title = NeoForgeUtil.fromJson(screen.data("title", String.class)); + Component message = NeoForgeUtil.fromJson(screen.data("message", String.class)); + + yield new ErrorScreen(title, message); + } + + default -> throw new AssertionError("Unexpected value: " + screen.getIdentifier()); + }; + } + + @Override + public void onInstruction(@NotNull Instruction instruction) throws Exception { + AbstractScreen screen = instruction.parameter(0, AbstractScreen.class); + + if (screen instanceof DefaultScreen s) { + Screen screen0 = defaultScreen(s, minecraft.screen); + minecraft.execute(() -> minecraft.setScreen(screen0)); + } + + if (screen instanceof CustomScreen s) { + Screen screen0 = new NeoForgeScreen(s, minecraft.screen); + minecraft.execute(() -> minecraft.setScreen(screen0)); + } + } + +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/PingMachine.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/PingMachine.java new file mode 100644 index 00000000..756279bf --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/PingMachine.java @@ -0,0 +1,25 @@ +package xyz.gmitch215.socketmc.neoforge.machines; + +import org.jetbrains.annotations.NotNull; +import xyz.gmitch215.socketmc.SocketMC; +import xyz.gmitch215.socketmc.instruction.Instruction; +import xyz.gmitch215.socketmc.instruction.InstructionId; +import xyz.gmitch215.socketmc.instruction.Machine; +import xyz.gmitch215.socketmc.neoforge.NeoForgeSocketMC; + +@InstructionId(Instruction.PING) +public final class PingMachine implements Machine { + + public static final PingMachine MACHINE = new PingMachine(); + + private PingMachine() {} + + @Override + public void onInstruction(@NotNull Instruction instruction) { + SocketMC.LOGGER.info("Received ping instruction"); + + if (!NeoForgeSocketMC.eventsEnabled) + NeoForgeSocketMC.eventsEnabled = true; + } + +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/RenderingMachine.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/RenderingMachine.java new file mode 100644 index 00000000..8444925a --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/RenderingMachine.java @@ -0,0 +1,59 @@ +package xyz.gmitch215.socketmc.neoforge.machines; + +import net.minecraft.client.gui.GuiGraphics; +import org.joml.Matrix4f; +import xyz.gmitch215.socketmc.instruction.Instruction; +import xyz.gmitch215.socketmc.instruction.InstructionId; +import xyz.gmitch215.socketmc.instruction.Machine; +import xyz.gmitch215.socketmc.instruction.RenderInstruction; +import xyz.gmitch215.socketmc.util.LifecycleMap; + +import java.util.List; +import java.util.function.Function; + +import static xyz.gmitch215.socketmc.neoforge.NeoForgeSocketMC.minecraft; + +@InstructionId(Instruction.RENDERER) +public final class RenderingMachine implements Machine { + + public static final RenderingMachine MACHINE = new RenderingMachine(); + + private RenderingMachine() {} + + private static final LifecycleMap lifecycle = new LifecycleMap<>(); + + public static void tick() { + lifecycle.run(); + lifecycle.forEach(Runnable::run); + } + + public static final List>> RENDERERS = List.of( + // GameRenderer + List.of( + i -> { + Matrix4f matrix = i.data("matrix", Matrix4f.class); + return () -> minecraft.gameRenderer.renderItemInHand( + minecraft.gameRenderer.getMainCamera(), + minecraft.getTimer().getGameTimeDeltaPartialTick(true), + matrix + ); + }, + i -> { + float strength = i.data("strength", Float.class); + GuiGraphics graphics = new GuiGraphics(minecraft, minecraft.renderBuffers().bufferSource()); + return () -> minecraft.gameRenderer.renderConfusionOverlay(graphics, strength); + } + ) + ); + + @Override + public void onInstruction(Instruction instruction) { + RenderInstruction render = instruction.lastParameter(RenderInstruction.class); + + Runnable action = RENDERERS.get(render.getOrdinal()).get(render.getSubOrdinal()).apply(render); + long millis = (long) render.data("time"); + + lifecycle.store(action, millis); + } + +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/SetOverlayMachine.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/SetOverlayMachine.java new file mode 100644 index 00000000..643093c1 --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/SetOverlayMachine.java @@ -0,0 +1,29 @@ +package xyz.gmitch215.socketmc.neoforge.machines; + +import xyz.gmitch215.socketmc.instruction.Instruction; +import xyz.gmitch215.socketmc.instruction.InstructionId; +import xyz.gmitch215.socketmc.instruction.Machine; +import xyz.gmitch215.socketmc.neoforge.screen.NeoForgeOverlay; +import xyz.gmitch215.socketmc.screen.Overlay; + +import static xyz.gmitch215.socketmc.neoforge.NeoForgeSocketMC.minecraft; + +@InstructionId(Instruction.SET_OVERLAY) +public final class SetOverlayMachine implements Machine { + + public static final SetOverlayMachine MACHINE = new SetOverlayMachine(); + + private SetOverlayMachine() {} + + @Override + public void onInstruction(Instruction instruction) { + Object overlay = instruction.firstParameter(); + + if (overlay == null) + minecraft.setOverlay(null); + else + minecraft.setOverlay(new NeoForgeOverlay((Overlay) overlay)); + } + +} + diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mixin/AbstractWidgetMixin.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mixin/AbstractWidgetMixin.java new file mode 100644 index 00000000..cef0e4af --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mixin/AbstractWidgetMixin.java @@ -0,0 +1,47 @@ +package xyz.gmitch215.socketmc.neoforge.mixin; + +import net.minecraft.client.gui.components.AbstractWidget; +import org.spongepowered.asm.mixin.Mixin; +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 xyz.gmitch215.socketmc.neoforge.screen.NeoForgeScreenUtil; +import xyz.gmitch215.socketmc.screen.Positionable; +import xyz.gmitch215.socketmc.screen.ScreenWidget; +import xyz.gmitch215.socketmc.util.ReflectionUtil; +import xyz.gmitch215.socketmc.util.SerializableConsumer; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +@Mixin(AbstractWidget.class) +public class AbstractWidgetMixin implements ScreenWidget { + + @Unique + private final Set> socketMC$clickListeners = new HashSet<>(); + + @Inject(method = "onClick", at = @At("TAIL")) + public void onClick(double mouseX, double mouseY, CallbackInfo ci) { + Positionable widget = NeoForgeScreenUtil.fromMinecraft((AbstractWidget) (Object) this); + if (widget == null) return; + + socketMC$clickListeners.forEach(listener -> { + listener.accept(widget); + + AbstractWidget applied = NeoForgeScreenUtil.toMinecraft(widget); + ReflectionUtil.apply((AbstractWidget) (Object) this, applied, AbstractWidget.class); + }); + } + + @Override + public void socketMC$addClickListeners(Collection> listener) { + socketMC$clickListeners.addAll(listener); + } + + @Override + public Set> socketMC$getClickListeners() { + return socketMC$clickListeners; + } +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mixin/GuiMixin.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mixin/GuiMixin.java new file mode 100644 index 00000000..26c5d26d --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mixin/GuiMixin.java @@ -0,0 +1,26 @@ +package xyz.gmitch215.socketmc.neoforge.mixin; + +import net.minecraft.client.DeltaTracker; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.GuiGraphics; +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 xyz.gmitch215.socketmc.neoforge.machines.*; + +@Mixin(Gui.class) +public class GuiMixin { + + @Inject(method = "render", at = @At(value = "TAIL")) + public void render(GuiGraphics drawContext, DeltaTracker tickDelta, CallbackInfo callbackInfo) { + DrawTextMachine.frameTick(drawContext, tickDelta); + DrawShapeMachine.frameTick(drawContext, tickDelta); + DrawBufferMachine.frameTick(drawContext, tickDelta); + DrawTextureMachine.frameTick(drawContext, tickDelta); + DrawBeaconBeamMachine.frameTick(drawContext, tickDelta); + DrawContextMachine.frameTick(drawContext, tickDelta); + DrawItemStackMachine.frameTick(drawContext, tickDelta); + } + +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mixin/OnlineOptionsScreenMixin.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mixin/OnlineOptionsScreenMixin.java new file mode 100644 index 00000000..c2d5a3c3 --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mixin/OnlineOptionsScreenMixin.java @@ -0,0 +1,34 @@ +package xyz.gmitch215.socketmc.neoforge.mixin; + +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.Tooltip; +import net.minecraft.client.gui.screens.options.OnlineOptionsScreen; +import net.minecraft.client.gui.screens.options.OptionsSubScreen; +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 xyz.gmitch215.socketmc.neoforge.mod.MainScreen; + +@Mixin(OnlineOptionsScreen.class) +public class OnlineOptionsScreenMixin extends OptionsSubScreen { + + protected OnlineOptionsScreenMixin() { + super(null, null, null); + } + + @Inject(method = "init", at = @At("TAIL")) + public void init(CallbackInfo ci) { + Button socketMC = Button.builder(Component.literal("\uD83D\uDD0C"), button -> minecraft.setScreen(new MainScreen(this))) + .pos(this.width - 105, this.height - 26) + .size(20, 20) + .build(); + + socketMC.setTooltip(Tooltip.create(MainScreen.TITLE)); + addRenderableWidget(socketMC); + } + + @Override + public void addOptions() {} +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mixin/PacketDecoderMixin.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mixin/PacketDecoderMixin.java new file mode 100644 index 00000000..154eeeae --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mixin/PacketDecoderMixin.java @@ -0,0 +1,108 @@ +package xyz.gmitch215.socketmc.neoforge.mixin; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.PacketDecoder; +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 xyz.gmitch215.socketmc.ModAuditLog; +import xyz.gmitch215.socketmc.SocketMC; +import xyz.gmitch215.socketmc.config.ModPermission; +import xyz.gmitch215.socketmc.instruction.Instruction; +import xyz.gmitch215.socketmc.machines.MachineFinder; +import xyz.gmitch215.socketmc.neoforge.NeoForgeSocketMC; +import xyz.gmitch215.socketmc.neoforge.machines.NeoForgeMachineFinder; +import xyz.gmitch215.socketmc.neoforge.NeoForgeRetriever; +import xyz.gmitch215.socketmc.retriever.Retriever; +import xyz.gmitch215.socketmc.retriever.RetrieverType; +import xyz.gmitch215.socketmc.spigot.SocketPlugin; + +import java.util.List; +import java.util.UUID; + +import static xyz.gmitch215.socketmc.neoforge.NeoForgeSocketMC.minecraft; + +@Mixin(PacketDecoder.class) +public class PacketDecoderMixin { + + @Inject(method = "decode", at = @At("HEAD"), cancellable = true) + protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List list, CallbackInfo ci) { + if (byteBuf.readableBytes() == 0) return; + + try { + FriendlyByteBuf buf = new FriendlyByteBuf(byteBuf.copy()); + int id = buf.readVarInt(); + switch (id) { + // Instruction Sent + case -2: { + ci.cancel(); + byteBuf.clear(); + + byte[] i0 = buf.readByteArray(); + Instruction i = Instruction.fromByteArray(i0); + + byte[] p0 = buf.readByteArray(); + SocketPlugin p = SocketPlugin.fromByteArray(p0); + + minecraft.execute(() -> { + try { + ModPermission perm = i.getPermission(); + if (SocketMC.isPermissionEnabled(p, perm)) { + MachineFinder.getMachine(NeoForgeMachineFinder.MACHINES, i.getId()).onInstruction(i); + } else { + SocketMC.LOGGER.warn("Plugin {} tried to execute instruction {} without permission", p.getPluginName(), i.getId()); + ModAuditLog.INSTANCE.log("Plugin " + p.getPluginName() + " tried to execute instruction '" + i.getId() + "' without permission"); + } + + SocketMC.LOGGER.info(ModAuditLog.CLIENT_RECEIVED_MESSAGE, i, i0.length); + SocketMC.addPlugin(p); + ModAuditLog.INSTANCE.logReceived(i, p); + } catch (Exception e) { + SocketMC.print(e); + } + }); + } + // Retriever Requested + case -4: { + byteBuf.clear(); + ci.cancel(); + + UUID retriever = buf.readUUID(); + + byte[] r0 = buf.readByteArray(); + RetrieverType r = RetrieverType.fromByteArray(r0); + + byte[] p0 = buf.readByteArray(); + SocketPlugin p = SocketPlugin.fromByteArray(p0); + + Object value = Retriever.value(r, NeoForgeRetriever.PROPERTIES); + + NeoForgeSocketMC.minecraft.execute(() -> { + try { + ModPermission perm = r.getPermission(); + if (SocketMC.isPermissionEnabled(p, perm)) { + NeoForgeRetriever.response(retriever, value); + } else { + SocketMC.LOGGER.warn("Plugin {} tried to retrieve {} without permission", p.getPluginName(), r.getId()); + ModAuditLog.INSTANCE.log("Plugin " + p.getPluginName() + " tried to retrieve '" + r.getId() + "' without permission"); + } + + SocketMC.LOGGER.info(ModAuditLog.CLIENT_RECEIVED_MESSAGE, r, r0.length); + SocketMC.addPlugin(p); + ModAuditLog.INSTANCE.logReceived(r, p, value); + } catch (Exception e) { + SocketMC.print(e); + } + }); + break; + } + } + } catch (Exception e) { + SocketMC.print(e); + } + } + +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mixin/events/PlayerChangeScreenEvent.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mixin/events/PlayerChangeScreenEvent.java new file mode 100644 index 00000000..df9650b9 --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mixin/events/PlayerChangeScreenEvent.java @@ -0,0 +1,32 @@ +package xyz.gmitch215.socketmc.neoforge.mixin.events; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.Screen; +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 xyz.gmitch215.socketmc.neoforge.NeoForgeSocketMC; +import xyz.gmitch215.socketmc.neoforge.screen.NeoForgeScreenUtil; +import xyz.gmitch215.socketmc.screen.AbstractScreen; + +import java.util.Map; + +import static xyz.gmitch215.socketmc.neoforge.NeoForgeSocketMC.minecraft; + +@Mixin(Minecraft.class) +public class PlayerChangeScreenEvent { + + @Inject(method = "setScreen", at = @At("HEAD")) + public void onScreenChange(Screen screen, CallbackInfo ci) { + if (!NeoForgeSocketMC.eventsEnabled) return; + + AbstractScreen oldScreen = NeoForgeScreenUtil.fromMinecraft(minecraft.screen); + AbstractScreen newScreen = NeoForgeScreenUtil.fromMinecraft(screen); + + if (oldScreen != null && newScreen != null) { + NeoForgeSocketMC.sendEvent(4, Map.of("old", oldScreen, "new", newScreen)); + } + } + +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mixin/events/PlayerMouseInputEvent.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mixin/events/PlayerMouseInputEvent.java new file mode 100644 index 00000000..2028ea5f --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mixin/events/PlayerMouseInputEvent.java @@ -0,0 +1,30 @@ +package xyz.gmitch215.socketmc.neoforge.mixin.events; + +import net.minecraft.client.MouseHandler; +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 xyz.gmitch215.socketmc.neoforge.NeoForgeSocketMC; + +import java.util.Map; + +@Mixin(MouseHandler.class) +public class PlayerMouseInputEvent { + + @Inject(method = "onMove", at = @At("HEAD")) + private void onMove(long window, double x, double y, CallbackInfo ci){ + NeoForgeSocketMC.sendEvent(1, Map.of("x", x, "y", y)); + } + + @Inject(method = "onScroll", at = @At("HEAD")) + private void onScroll(long window, double xOffset, double yOffset, CallbackInfo ci){ + NeoForgeSocketMC.sendEvent(2, Map.of("x", xOffset, "y", yOffset)); + } + + @Inject(method = "onPress", at = @At("HEAD")) + private void onPress(long window, int button, int action, int mods, CallbackInfo ci){ + NeoForgeSocketMC.sendEvent(3, Map.of("button", button, "action", action, "mods", mods)); + } + +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mixin/events/PlayerPressKeyEvent.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mixin/events/PlayerPressKeyEvent.java new file mode 100644 index 00000000..0a4e7227 --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mixin/events/PlayerPressKeyEvent.java @@ -0,0 +1,20 @@ +package xyz.gmitch215.socketmc.neoforge.mixin.events; + +import net.minecraft.client.KeyboardHandler; +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 xyz.gmitch215.socketmc.neoforge.NeoForgeSocketMC; + +import java.util.Map; + +@Mixin(KeyboardHandler.class) +public class PlayerPressKeyEvent { + + @Inject(method = "keyPress", at = @At("HEAD")) + public void onKeyPress(long window, int key, int scancode, int action, int modifiers, CallbackInfo ci) { + NeoForgeSocketMC.sendEvent(0, Map.of("key", key, "flags", modifiers, "action", action)); + } + +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mod/AuditLogScreen.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mod/AuditLogScreen.java new file mode 100644 index 00000000..410e3ef5 --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mod/AuditLogScreen.java @@ -0,0 +1,72 @@ +package xyz.gmitch215.socketmc.neoforge.mod; + +import net.minecraft.Util; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.FocusableTextWidget; +import net.minecraft.client.gui.components.StringWidget; +import net.minecraft.client.gui.layouts.GridLayout; +import net.minecraft.client.gui.layouts.HeaderAndFooterLayout; +import net.minecraft.client.gui.layouts.LayoutSettings; +import net.minecraft.client.gui.layouts.LinearLayout; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.CommonComponents; +import net.minecraft.network.chat.Component; +import xyz.gmitch215.socketmc.ModAuditLog; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import static xyz.gmitch215.socketmc.neoforge.mod.MainScreen.AUDIT_LOG; + +public final class AuditLogScreen extends Screen { + + private final Screen previousScreen; + private final HeaderAndFooterLayout layout = new HeaderAndFooterLayout(this, 61, 33); + + public static final Component OPEN_AUDIT_LOG = Component.translatable("gui.socketmc.open_audit_log"); + + public AuditLogScreen(Screen previousScreen) { + super(AUDIT_LOG); + + this.previousScreen = previousScreen; + } + + @Override + public void init() { + LinearLayout top = layout.addToHeader(LinearLayout.vertical().spacing(8)); + top.addChild(new StringWidget(AUDIT_LOG, this.font), LayoutSettings::alignHorizontallyCenter); + + GridLayout grid = new GridLayout(); + grid.defaultCellSetting().paddingHorizontal(8).paddingBottom(4); + + GridLayout.RowHelper rows = grid.createRowHelper(1); + List lines = new ArrayList<>(ModAuditLog.INSTANCE.readLog(10)); + + if (lines.isEmpty()) + rows.addChild(new StringWidget(Component.translatable("gui.socketmc.no_logs"), this.font)); + else for (String line : lines) + rows.addChild(new FocusableTextWidget(this.width - 80, Component.literal(line), this.font)); + + LinearLayout bottom = layout.addToFooter(LinearLayout.horizontal().spacing(8)); + bottom.addChild(Button.builder(CommonComponents.GUI_BACK, button -> onClose()).build()); + + URI logFolder = ModAuditLog.INSTANCE.getFolder().toURI(); + bottom.addChild(Button.builder(OPEN_AUDIT_LOG, button -> Util.getPlatform().openUri(logFolder)).build()); + + layout.addToContents(grid); + layout.visitWidgets(this::addRenderableWidget); + repositionElements(); + } + + @Override + public void repositionElements() { + this.layout.arrangeElements(); + } + + @Override + public void onClose() { + minecraft.setScreen(previousScreen); + } + +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mod/MainScreen.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mod/MainScreen.java new file mode 100644 index 00000000..9937a039 --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mod/MainScreen.java @@ -0,0 +1,62 @@ +package xyz.gmitch215.socketmc.neoforge.mod; + +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.StringWidget; +import net.minecraft.client.gui.layouts.GridLayout; +import net.minecraft.client.gui.layouts.HeaderAndFooterLayout; +import net.minecraft.client.gui.layouts.LayoutSettings; +import net.minecraft.client.gui.layouts.LinearLayout; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.CommonComponents; +import net.minecraft.network.chat.Component; + +import java.util.function.Function; + +public final class MainScreen extends Screen { + + public static final Component TITLE = Component.translatable("gui.socketmc.title"); + + public static final Component PERMISSIONS = Component.translatable("gui.socketmc.permissions"); + public static final Component AUDIT_LOG = Component.translatable("gui.socketmc.audit_log"); + + private Screen previousScreen; + private final HeaderAndFooterLayout layout = new HeaderAndFooterLayout(this, 61, 33); + + public MainScreen(Screen previousScreen) { + super(TITLE); + this.previousScreen = previousScreen; + } + + @Override + public void onClose() { + minecraft.setScreen(previousScreen); + } + + @Override + public void init() { + LinearLayout top = layout.addToHeader(LinearLayout.vertical().spacing(8)); + top.addChild(new StringWidget(TITLE, this.font), LayoutSettings::alignHorizontallyCenter); + + GridLayout grid = new GridLayout(); + grid.defaultCellSetting().paddingHorizontal(4).paddingBottom(4).alignHorizontallyCenter(); + + GridLayout.RowHelper rows = grid.createRowHelper(2); + rows.addChild(screen(PERMISSIONS, ModPermissionsScreen::new)); + rows.addChild(screen(AUDIT_LOG, AuditLogScreen::new)); + + layout.addToContents(grid); + layout.addToFooter(Button.builder(CommonComponents.GUI_DONE, button -> this.onClose()).width(200).build()); + layout.visitWidgets(this::addRenderableWidget); + repositionElements(); + } + + @Override + public void repositionElements() { + this.layout.arrangeElements(); + } + + private Button screen(Component text, Function screenSupplier) { + return Button.builder(text, button -> minecraft.setScreen(screenSupplier.apply(previousScreen))).build(); + } + +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mod/ModPermissionsScreen.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mod/ModPermissionsScreen.java new file mode 100644 index 00000000..f5b80b22 --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/mod/ModPermissionsScreen.java @@ -0,0 +1,175 @@ +package xyz.gmitch215.socketmc.neoforge.mod; + +import net.minecraft.Util; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.FocusableTextWidget; +import net.minecraft.client.gui.components.StringWidget; +import net.minecraft.client.gui.components.Tooltip; +import net.minecraft.client.gui.layouts.GridLayout; +import net.minecraft.client.gui.layouts.HeaderAndFooterLayout; +import net.minecraft.client.gui.layouts.LayoutSettings; +import net.minecraft.client.gui.layouts.LinearLayout; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.CommonComponents; +import net.minecraft.network.chat.Component; +import xyz.gmitch215.socketmc.SocketMC; +import xyz.gmitch215.socketmc.config.ModPermission; +import xyz.gmitch215.socketmc.spigot.SocketPlugin; + +import java.net.URI; +import java.util.Collections; +import java.util.List; +import java.util.function.Function; + +public final class ModPermissionsScreen extends Screen { + + private final SocketPlugin current; + private final Screen previousScreen; + private final HeaderAndFooterLayout layout = new HeaderAndFooterLayout(this, 60, 30); + + public ModPermissionsScreen(Screen previousScreen) { + this(null, previousScreen); + } + + public ModPermissionsScreen(SocketPlugin current, Screen previousScreen) { + super(MainScreen.PERMISSIONS); + + this.current = current; + this.previousScreen = previousScreen; + } + + public void init() { + init(0); + } + + public void init(int page0) { + List plugins = SocketMC.plugins(); + Collections.sort(plugins); + + int pageMax = (plugins.size() + 6) / 7; + int page = Math.max(0, Math.min(page0, pageMax)); + plugins = plugins.subList(page * 7, Math.min(plugins.size(), (page + 1) * 7)); + + LinearLayout header = layout.addToHeader(LinearLayout.vertical().spacing(8)); + header.addChild(new StringWidget(MainScreen.PERMISSIONS, this.font), LayoutSettings::alignHorizontallyCenter); + + GridLayout parentGrid = new GridLayout(); + parentGrid.defaultCellSetting().paddingHorizontal(12).paddingBottom(4); + + GridLayout.RowHelper rows = parentGrid.createRowHelper(2); + + LinearLayout left = LinearLayout.vertical().spacing(16); + left.defaultCellSetting().alignHorizontallyLeft(); + + Component def = Component.translatable("options.gamma.default"); + if (current == null) { + FocusableTextWidget text = new FocusableTextWidget(this.width - 80, def, this.font); + left.addChild(text); + } else { + StringWidget text = new StringWidget(def, this.font) { + @Override + public void onClick(double mouseX, double mouseY, int button) { minecraft.setScreen(screen(null)); } + }; + left.addChild(text); + } + + for (final SocketPlugin plugin : plugins) { + boolean same = plugin.equals(current); + Component name = Component.literal(plugin.getPluginName()); + Tooltip tooltip = Tooltip.create(Component.literal(plugin.getPluginName() + " v" + plugin.getPluginVersion())); + + if (same) { + FocusableTextWidget text = new FocusableTextWidget(this.width - 80, name, this.font); + text.setTooltip(tooltip); + left.addChild(text); + } else { + StringWidget text = new StringWidget(name, this.font) { + @Override + public void onClick(double mouseX, double mouseY, int button) { minecraft.setScreen(screen(plugin)); } + }; + + text.setTooltip(tooltip); + left.addChild(text); + } + } + + rows.addChild(left); + + if (pageMax != 1) { + LinearLayout buttons = LinearLayout.horizontal().spacing(4); + buttons.defaultCellSetting().paddingTop(4); + + if (page > 0) + buttons.addChild(Button.builder(Component.literal("<-"), button -> page(page + 1)).width(40).build()); + if (page < pageMax) + buttons.addChild(Button.builder(Component.literal("->"), button -> page(page - 1)).width(40).build()); + + left.addChild(buttons); + } + + GridLayout right = new GridLayout(); + right.defaultCellSetting().paddingVertical(2).paddingHorizontal(8); + + GridLayout.RowHelper rightRows = right.createRowHelper(2); + for (ModPermission permission : ModPermission.values()) { + boolean state = SocketMC.isPermissionEnabled(current, permission); + + Function message = on -> Component.translatable(permission.getKey()) + .append(": ") + .append(on ? CommonComponents.OPTION_ON : CommonComponents.OPTION_OFF); + + Button permButton = Button.builder(message.apply(state), button -> { + boolean currentState = SocketMC.isPermissionEnabled(current, permission); + SocketMC.setPermissionEnabled(current, permission, !currentState); + button.setMessage(message.apply(!currentState)); + }).width(120).build(); + + if (!permission.isChangeable()) + permButton.active = false; + + Component tooltip = Component.translatable(permission.getTooltip()); + permButton.setTooltip(Tooltip.create(tooltip)); + + rightRows.addChild(permButton); + } + + if (current != null && current.getPluginUrl() != null) { + URI url = URI.create(current.getPluginUrl()); + + LinearLayout rightBottom = LinearLayout.horizontal().spacing(4); + rightBottom.defaultCellSetting().paddingTop(4); + rightBottom.addChild(Button.builder(Component.translatable("gui.socketmc.website"), + button -> Util.getPlatform().openUri(url)).width(240).build()); + + rightRows.addChild(rightBottom); + } + rows.addChild(right); + + layout.addToContents(parentGrid); + layout.addToFooter(Button.builder(CommonComponents.GUI_BACK, button -> onClose()).width(200).build()); + layout.visitWidgets(this::addRenderableWidget); + repositionElements(); + } + + public void page(int newPage) { + clearWidgets(); + clearFocus(); + init(newPage); + setInitialFocus(); + } + + @Override + public void repositionElements() { + layout.arrangeElements(); + } + + @Override + public void onClose() { + minecraft.setScreen(previousScreen); + } + + private ModPermissionsScreen screen(SocketPlugin plugin) { + return new ModPermissionsScreen(plugin, previousScreen); + } + +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeCustomButton.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeCustomButton.java new file mode 100644 index 00000000..24be7b95 --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeCustomButton.java @@ -0,0 +1,29 @@ +package xyz.gmitch215.socketmc.neoforge.screen; + +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import xyz.gmitch215.socketmc.neoforge.NeoForgeUtil; +import xyz.gmitch215.socketmc.neoforge.machines.DrawContextMachine; +import xyz.gmitch215.socketmc.screen.ui.CustomButton; + +import static xyz.gmitch215.socketmc.neoforge.screen.NeoForgeScreenUtil.BUTTON_PRESS_EVENT; + +public final class NeoForgeCustomButton extends Button { + + final CustomButton handle; + + public NeoForgeCustomButton(CustomButton handle) { + super(handle.getX(), handle.getY(), handle.getWidth(), handle.getHeight(), NeoForgeUtil.fromJson(handle.getMessageJSON()), BUTTON_PRESS_EVENT, DEFAULT_NARRATION); + + this.handle = handle; + } + + @Override + protected void renderWidget(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) { + if (handle.isRenderDefault()) + super.renderWidget(guiGraphics, mouseX, mouseY, partialTick); + + DrawContextMachine.draw(guiGraphics, handle.getContext()); + } + +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeCustomWidget.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeCustomWidget.java new file mode 100644 index 00000000..04e45f9d --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeCustomWidget.java @@ -0,0 +1,30 @@ +package xyz.gmitch215.socketmc.neoforge.screen; + +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.AbstractWidget; +import net.minecraft.client.gui.narration.NarratedElementType; +import net.minecraft.client.gui.narration.NarrationElementOutput; +import xyz.gmitch215.socketmc.neoforge.NeoForgeUtil; +import xyz.gmitch215.socketmc.neoforge.machines.DrawContextMachine; +import xyz.gmitch215.socketmc.screen.ui.CustomWidget; + +public final class NeoForgeCustomWidget extends AbstractWidget { + + final CustomWidget handle; + + public NeoForgeCustomWidget(CustomWidget handle) { + super(handle.getX(), handle.getY(), handle.getWidth(), handle.getHeight(), NeoForgeUtil.fromJson(handle.getMessageJSON())); + + this.handle = handle; + } + + @Override + protected void renderWidget(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) { + DrawContextMachine.draw(guiGraphics, handle.getContext()); + } + + @Override + protected void updateWidgetNarration(NarrationElementOutput narrationElementOutput) { + narrationElementOutput.add(NarratedElementType.TITLE, createNarrationMessage()); + } +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeGraphicsContext.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeGraphicsContext.java new file mode 100644 index 00000000..242288ea --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeGraphicsContext.java @@ -0,0 +1,80 @@ +package xyz.gmitch215.socketmc.neoforge.screen; + +import com.mojang.blaze3d.platform.InputConstants; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import xyz.gmitch215.socketmc.util.InputType; +import xyz.gmitch215.socketmc.util.input.Key; +import xyz.gmitch215.socketmc.util.render.GraphicsContext; + +import static xyz.gmitch215.socketmc.neoforge.NeoForgeSocketMC.minecraft; + +public final class NeoForgeGraphicsContext implements GraphicsContext { + + public static final NeoForgeGraphicsContext INSTANCE = new NeoForgeGraphicsContext(); + + private NeoForgeGraphicsContext() {} + + @Override + public int getFps() { + return minecraft.getFps(); + } + + @Override + public int getScreenWidth() { + return minecraft.getWindow().getScreenWidth(); + } + + @Override + public int getScreenHeight() { + return minecraft.getWindow().getScreenHeight(); + } + + @Override + public int getMouseX() { + return (int) (getRawMouseX() * minecraft.getWindow().getGuiScaledWidth() / minecraft.getWindow().getScreenWidth()); + } + + @Override + public int getMouseY() { + return (int) (getRawMouseY() * minecraft.getWindow().getGuiScaledHeight() / minecraft.getWindow().getScreenHeight()); + } + + @Override + public double getRawMouseX() { + return minecraft.mouseHandler.xpos(); + } + + @Override + public double getRawMouseY() { + return minecraft.mouseHandler.ypos(); + } + + @Override + public float getPartialTicks() { + return minecraft.getTimer().getGameTimeDeltaTicks(); + } + + @Override + @NotNull + public String getClipboard() { + return minecraft.keyboardHandler.getClipboard(); + } + + @Override + @Nullable + public InputType getLastInputType() { + return switch (minecraft.getLastInputType()) { + case MOUSE -> InputType.MOUSE; + case KEYBOARD_TAB -> InputType.KEYBOARD_TAB; + case KEYBOARD_ARROW -> InputType.KEYBOARD_ARROW; + default -> InputType.NONE; + }; + } + + @Override + public boolean isKeyDown(@Nullable Key key) { + if (key == null) return false; + return InputConstants.isKeyDown(minecraft.getWindow().getWindow(), key.getCode()); + } +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeOverlay.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeOverlay.java new file mode 100644 index 00000000..9355749c --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeOverlay.java @@ -0,0 +1,24 @@ +package xyz.gmitch215.socketmc.neoforge.screen; + +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.Overlay; +import xyz.gmitch215.socketmc.neoforge.machines.DrawContextMachine; + +public final class NeoForgeOverlay extends Overlay { + + private xyz.gmitch215.socketmc.screen.Overlay handle; + + public NeoForgeOverlay(xyz.gmitch215.socketmc.screen.Overlay handle) { + this.handle = handle; + } + + @Override + public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) { + DrawContextMachine.draw(guiGraphics, handle.getContext()); + } + + @Override + public boolean isPauseScreen() { + return handle.isPauseScreen(); + } +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeScreen.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeScreen.java new file mode 100644 index 00000000..ca910667 --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeScreen.java @@ -0,0 +1,80 @@ +package xyz.gmitch215.socketmc.neoforge.screen; + +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.Component; +import org.jetbrains.annotations.Nullable; +import xyz.gmitch215.socketmc.neoforge.NeoForgeUtil; +import xyz.gmitch215.socketmc.screen.CustomScreen; +import xyz.gmitch215.socketmc.screen.Positionable; +import xyz.gmitch215.socketmc.screen.layout.Layout; + +import java.util.List; + +public final class NeoForgeScreen extends Screen { + + final CustomScreen handle; + + @Nullable + final Screen previousScreen; + + public NeoForgeScreen(CustomScreen handle, Screen previousScreen) { + super(NeoForgeUtil.fromJson(handle.getTitleJSON())); + this.handle = handle; + this.previousScreen = previousScreen; + } + + @Override + public Component getNarrationMessage() { + return NeoForgeUtil.fromJson(handle.getNarrationMessageJSON()); + } + + @Override + public void init() { + List children = handle.getChildren(); + for (Positionable child : children) + addRenderableWidget(NeoForgeScreenUtil.toMinecraft(child)); + + if (handle.getLayout() != null) + repositionElements(); + } + + @Override + public void repositionElements() { + if (handle.getLayout() != null) { + Layout layout = handle.getLayout(); + if (layout.isFullscreen()) { + layout.setWidth(width); + layout.setHeight(height); + } + + layout.arrangeElements(); + } + + super.repositionElements(); + } + + @Override + public void onClose() { + minecraft.setScreen(previousScreen); + } + + @Override + public void renderBackground(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) { + switch (handle.getBackground()) { + case DEFAULT -> super.renderBackground(graphics, mouseX, mouseY, partialTick); + case PANORAMA -> { + renderPanorama(graphics, partialTick); + renderBlurredBackground(partialTick); + renderMenuBackground(graphics); + } + case TRANSPARENT -> renderTransparentBackground(graphics); + } + } + + @Override + public boolean shouldCloseOnEsc() { + return handle.isCloseableOnEscape(); + } + +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeScreenUtil.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeScreenUtil.java new file mode 100644 index 00000000..11973798 --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeScreenUtil.java @@ -0,0 +1,288 @@ +package xyz.gmitch215.socketmc.neoforge.screen; + +import net.minecraft.client.gui.components.AbstractWidget; +import net.minecraft.client.gui.components.*; +import net.minecraft.client.gui.components.toasts.SystemToast; +import net.minecraft.client.gui.components.toasts.Toast; +import net.minecraft.client.gui.components.toasts.TutorialToast; +import net.minecraft.client.gui.screens.*; +import net.minecraft.client.gui.screens.achievement.StatsScreen; +import net.minecraft.client.gui.screens.advancements.AdvancementsScreen; +import net.minecraft.client.gui.screens.options.OptionsScreen; +import net.minecraft.network.chat.Component; +import xyz.gmitch215.socketmc.neoforge.NeoForgeSocketMC; +import xyz.gmitch215.socketmc.neoforge.NeoForgeUtil; +import xyz.gmitch215.socketmc.screen.AbstractScreen; +import xyz.gmitch215.socketmc.screen.DefaultScreen; +import xyz.gmitch215.socketmc.screen.Positionable; +import xyz.gmitch215.socketmc.screen.ScreenWidget; +import xyz.gmitch215.socketmc.screen.ui.CycleButton; +import xyz.gmitch215.socketmc.screen.ui.ImageButton; +import xyz.gmitch215.socketmc.screen.ui.ImageWidget; +import xyz.gmitch215.socketmc.screen.ui.*; +import xyz.gmitch215.socketmc.screen.util.Tooltip; +import xyz.gmitch215.socketmc.util.render.text.JsonText; +import xyz.gmitch215.socketmc.util.render.text.Text; + +import java.util.Map; +import java.util.function.BiConsumer; +import java.util.function.Function; + +import static xyz.gmitch215.socketmc.neoforge.NeoForgeSocketMC.minecraft; + +@SuppressWarnings({"unchecked", "rawtypes"}) +public final class NeoForgeScreenUtil { + + private NeoForgeScreenUtil() {} + + public static AbstractScreen fromMinecraft(Screen screen) { + if (screen == null) return null; + + AbstractScreen s0 = findDefault(screen); + if (s0 == null) { + if (screen instanceof NeoForgeScreen forge) s0 = forge.handle; + } + + return s0; + } + + public static DefaultScreen findDefault(Screen screen) { + if (screen == null) return null; + + return switch (screen) { + case TitleScreen ignored -> DefaultScreen.TITLE; + case PauseScreen ignored -> DefaultScreen.PAUSE; + case OptionsScreen ignored -> DefaultScreen.OPTIONS; + case ShareToLanScreen ignored -> DefaultScreen.SHARE_TO_LAN; + case AdvancementsScreen ignored -> DefaultScreen.ADVANCEMENTS; + case StatsScreen ignored -> DefaultScreen.STATS; + + case AlertScreen s -> { + JsonText title = NeoForgeUtil.toText(s.getTitle()); + JsonText message = NeoForgeUtil.toText(s.messageText); + JsonText button = NeoForgeUtil.toText(s.okButton); + + yield DefaultScreen.alert(title, message); + } + case DisconnectedScreen s -> { + JsonText title = NeoForgeUtil.toText(s.getTitle()); + JsonText reason = NeoForgeUtil.toText(s.details.reason()); + JsonText button = NeoForgeUtil.toText(s.buttonText); + + yield DefaultScreen.disconnected(title, reason); + } + case GenericMessageScreen s -> { + JsonText message = NeoForgeUtil.toText(s.getTitle()); + + yield DefaultScreen.message(message); + } + case DeathScreen s -> { + JsonText cause = NeoForgeUtil.toText(s.causeOfDeath); + boolean hardcore = s.hardcore; + + yield DefaultScreen.death(cause, hardcore); + } + case ErrorScreen s -> { + JsonText title = NeoForgeUtil.toText(s.getTitle()); + JsonText message = NeoForgeUtil.toText(s.message); + + yield DefaultScreen.error(title, message); + } + default -> null; + }; + } + + static final Button.OnPress BUTTON_PRESS_EVENT = b -> { + AbstractScreen s0 = fromMinecraft(minecraft.screen); + if (s0 == null) return; + + NeoForgeSocketMC.sendEvent(5, Map.of("screen", s0, "button", fromMinecraft(b))); + }; + + static final Checkbox.OnValueChange CHECKBOX_CHANGE_EVENT = (b, state) -> { + AbstractScreen s0 = fromMinecraft(minecraft.screen); + if (s0 == null) return; + + NeoForgeSocketMC.sendEvent(6, Map.of("screen", s0, "button", fromMinecraft(b), "state", state)); + }; + + static final BiConsumer EDIT_BOX_EVENT = (w, s) -> { + AbstractScreen s0 = fromMinecraft(minecraft.screen); + if (s0 == null) return; + + NeoForgeSocketMC.sendEvent(7, Map.of("screen", s0, "widget", fromMinecraft(w), "text", s)); + }; + + static final net.minecraft.client.gui.components.CycleButton.OnValueChange CYCLE_BUTTON_EVENT = (b, o) -> { + AbstractScreen s0 = fromMinecraft(minecraft.screen); + if (s0 == null) return; + + NeoForgeSocketMC.sendEvent(8, Map.of("screen", s0, "button", fromMinecraft(b), "value", o)); + }; + + public static AbstractWidget toMinecraft(Positionable renderable) { + if (renderable == null) return null; + + int x = renderable.getX(); + int y = renderable.getY(); + int width = renderable.getWidth(); + int height = renderable.getHeight(); + Tooltip tooltip = renderable.getTooltip(); + + Component message = renderable instanceof AbstractTextWidget text ? NeoForgeUtil.fromJson(text.getMessageJSON()) : null; + + AbstractWidget w0 = switch (renderable) { + // Widgets + case TextWidget widget -> { + if (width == -1 || height == -1) + yield new StringWidget(x, y, message, minecraft.font); + else + yield new StringWidget(x, y, width, height, message, minecraft.font); + } + case FocusedTextWidget widget -> { + FocusableTextWidget w = new FocusableTextWidget(width, message, minecraft.font, widget.isAlwaysShowBorder(), widget.getPadding()); + w.setPosition(widget.getX(), widget.getY()); + + yield w; + } + case ImageWidget widget -> { + net.minecraft.client.gui.components.ImageWidget w = switch (widget.getType()) { + case TEXTURE -> net.minecraft.client.gui.components.ImageWidget.texture(width, height, NeoForgeUtil.toMinecraft(widget.getLocation()), width, height); + case SPRITE -> net.minecraft.client.gui.components.ImageWidget.sprite(width, height, NeoForgeUtil.toMinecraft(widget.getLocation())); + }; + w.setPosition(x, y); + + yield w; + } + case EditTextWidget widget -> { + EditBox w = new EditBox(minecraft.font, x, y, width, height, message); + w.setResponder(s -> EDIT_BOX_EVENT.accept(w, s)); + + yield w; + } + case CustomWidget widget -> new NeoForgeCustomWidget(widget); + + // Buttons + case TextButton button -> Button.builder(message, BUTTON_PRESS_EVENT).bounds(x, y, width, height).build(); + case ImageButton button -> + new net.minecraft.client.gui.components.ImageButton(x, y, width, height, NeoForgeUtil.toMinecraft(button.getSprite()), BUTTON_PRESS_EVENT); + case CheckboxButton button -> Checkbox.builder(message, minecraft.font).onValueChange(CHECKBOX_CHANGE_EVENT).pos(x, y).build(); + case SendInstructionButton button -> new NeoForgeSendInstructionButton(x, y, width, height, message, button.getInstruction()); + case LockButton button -> new LockIconButton(x, y, BUTTON_PRESS_EVENT); + case CycleButton button -> { + Function stringifier = o -> NeoForgeUtil.fromJson(((Text) button.getStringifier().apply(o)).toJSON()); + + yield net.minecraft.client.gui.components.CycleButton + .builder(stringifier) + .withValues(button.getValues()) + .create(x, y, width, height, message, CYCLE_BUTTON_EVENT); + } + case CustomButton button -> new NeoForgeCustomButton(button); + + case null, default -> null; + }; + if (w0 == null) return null; + + w0.setTooltip(NeoForgeUtil.toMinecraft(tooltip)); + + ScreenWidget f0 = (ScreenWidget) w0; + f0.socketMC$addClickListeners(renderable.getListeners()); + + return w0; + } + + public static Positionable fromMinecraft(AbstractWidget renderable) { + if (renderable == null) return null; + + int x = renderable.getX(); + int y = renderable.getY(); + int width = renderable.getWidth(); + int height = renderable.getHeight(); + Tooltip tooltip = NeoForgeUtil.fromMinecraft(renderable.getTooltip()); + + Positionable w0 = switch (renderable) { + // Widgets + case StringWidget widget -> new TextWidget(x, y, width, height, NeoForgeUtil.toJson(widget.getMessage())); + case FocusableTextWidget widget -> new FocusedTextWidget(x, y, width, height, NeoForgeUtil.toJson(widget.getMessage()), widget.alwaysShowBorder, widget.padding); + case net.minecraft.client.gui.components.ImageWidget.Sprite widget -> new ImageWidget(x, y, width, height, ImageWidget.Type.SPRITE, NeoForgeUtil.fromMinecraft(widget.sprite)); + case net.minecraft.client.gui.components.ImageWidget.Texture widget -> new ImageWidget(x, y, width, height, ImageWidget.Type.TEXTURE, NeoForgeUtil.fromMinecraft(widget.texture)); + case EditBox widget -> new EditTextWidget(x, y, width, height, NeoForgeUtil.toJson(widget.getMessage())); + case NeoForgeCustomWidget widget -> widget.handle; + + // Buttons + case net.minecraft.client.gui.components.ImageButton button -> new ImageButton(x, y, width, height, NeoForgeUtil.fromMinecraft(button.sprites)); + case NeoForgeSendInstructionButton button -> new SendInstructionButton(x, y, width, height, NeoForgeUtil.toJson(button.getMessage()), button.instruction); + case LockIconButton button -> new LockButton(x, y); + case NeoForgeCustomButton button -> button.handle; + case Button button -> new TextButton(x, y, width, height, NeoForgeUtil.toJson(button.getMessage())); + case Checkbox button -> new CheckboxButton(x, y, NeoForgeUtil.toJson(button.getMessage())); + case net.minecraft.client.gui.components.CycleButton button -> { + Function stringifier = o -> JsonText.raw(NeoForgeUtil.toJson((Component) button.valueStringifier.apply(o))); + yield new CycleButton(x, y, width, height, JsonText.raw(NeoForgeUtil.toJson(button.getMessage())), stringifier, button.values.getDefaultList()); + } + + case null, default -> null; + }; + if (w0 == null) return null; + + w0.setTooltip(tooltip); + + ScreenWidget f0 = (ScreenWidget) renderable; + f0.socketMC$getClickListeners().forEach(w0::onClick); + + return w0; + } + + public static Toast toMinecraft(xyz.gmitch215.socketmc.screen.Toast toast) { + return switch (toast.getType()) { + // Custom + case 0 -> new NeoForgeToast(toast); + + // System + case 1 -> { + xyz.gmitch215.socketmc.screen.Toast.System type = toast.firstParameter(xyz.gmitch215.socketmc.screen.Toast.System.class); + String title = toast.stringParameter(1); + String message = toast.lastStringParameter(); + + SystemToast.SystemToastId id = switch (type) { + case WORLD_BACKUP -> SystemToast.SystemToastId.WORLD_BACKUP; + case LOW_DISK_SPACE -> SystemToast.SystemToastId.LOW_DISK_SPACE; + case NARRATOR_TOGGLE -> SystemToast.SystemToastId.NARRATOR_TOGGLE; + case FILE_DROP_FAILURE -> SystemToast.SystemToastId.FILE_DROP_FAILURE; + case PACK_COPY_FAILURE -> SystemToast.SystemToastId.PACK_COPY_FAILURE; + case PACK_LOAD_FAILURE -> SystemToast.SystemToastId.PACK_LOAD_FAILURE; + case PERIODIC_NOTIFICATION -> SystemToast.SystemToastId.PERIODIC_NOTIFICATION; + case CHUNK_LOAD_FAILURE -> SystemToast.SystemToastId.CHUNK_LOAD_FAILURE; + case CHUNK_SAVE_FAILURE -> SystemToast.SystemToastId.CHUNK_SAVE_FAILURE; + case WORLD_ACCESS_FAILURE -> SystemToast.SystemToastId.WORLD_ACCESS_FAILURE; + case UNSECURE_SERVER_WARNING -> SystemToast.SystemToastId.UNSECURE_SERVER_WARNING; + }; + + yield SystemToast.multiline(minecraft, id, NeoForgeUtil.fromJson(title), NeoForgeUtil.fromJson(message)); + } + + // Tutorial + case 2 -> { + xyz.gmitch215.socketmc.screen.Toast.Tutorial type = toast.firstParameter(xyz.gmitch215.socketmc.screen.Toast.Tutorial.class); + String title = toast.stringParameter(1); + String message = toast.stringParameter(2); + boolean progressable = toast.lastBooleanParameter(); + + TutorialToast.Icons icon = switch (type) { + case TREE -> TutorialToast.Icons.TREE; + case MOUSE -> TutorialToast.Icons.MOUSE; + case RECIPE_BOOK -> TutorialToast.Icons.RECIPE_BOOK; + case RIGHT_CLICK -> TutorialToast.Icons.RIGHT_CLICK; + case MOVEMENT_KEYS -> TutorialToast.Icons.MOVEMENT_KEYS; + case WOODEN_PLANKS -> TutorialToast.Icons.WOODEN_PLANKS; + case SOCIAL_INTERACTIONS -> TutorialToast.Icons.SOCIAL_INTERACTIONS; + }; + + yield new TutorialToast(icon, NeoForgeUtil.fromJson(title), NeoForgeUtil.fromJson(message), progressable); + } + + default -> throw new IllegalStateException("Unexpected value: " + toast.getType()); + }; + } + +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeSendInstructionButton.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeSendInstructionButton.java new file mode 100644 index 00000000..ac6922b3 --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeSendInstructionButton.java @@ -0,0 +1,29 @@ +package xyz.gmitch215.socketmc.neoforge.screen; + +import net.minecraft.client.gui.components.Button; +import net.minecraft.network.chat.Component; +import xyz.gmitch215.socketmc.SocketMC; +import xyz.gmitch215.socketmc.instruction.Instruction; +import xyz.gmitch215.socketmc.machines.MachineFinder; +import xyz.gmitch215.socketmc.neoforge.machines.NeoForgeMachineFinder; + +import static xyz.gmitch215.socketmc.neoforge.screen.NeoForgeScreenUtil.BUTTON_PRESS_EVENT; + +public final class NeoForgeSendInstructionButton extends Button { + + final Instruction instruction; + + public NeoForgeSendInstructionButton(int x, int y, int width, int height, Component message, Instruction i) { + super(x, y, width, height, message, b -> { + try { + MachineFinder.getMachine(NeoForgeMachineFinder.MACHINES, i.getId()).onInstruction(i); + } catch (Exception e) { + SocketMC.print(e); + } + + BUTTON_PRESS_EVENT.onPress(b); + }, Button.DEFAULT_NARRATION); + + this.instruction = i; + } +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeToast.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeToast.java new file mode 100644 index 00000000..f5f7b66a --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/screen/NeoForgeToast.java @@ -0,0 +1,34 @@ +package xyz.gmitch215.socketmc.neoforge.screen; + +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.toasts.Toast; +import net.minecraft.client.gui.components.toasts.ToastComponent; +import xyz.gmitch215.socketmc.neoforge.machines.DrawContextMachine; +import xyz.gmitch215.socketmc.util.render.DrawingContext; + +public final class NeoForgeToast implements Toast { + + final xyz.gmitch215.socketmc.screen.Toast handle; + + public NeoForgeToast(xyz.gmitch215.socketmc.screen.Toast handle) { + this.handle = handle; + } + + @Override + public Visibility render(GuiGraphics guiGraphics, ToastComponent toastComponent, long timeSinceLastVisible) { + DrawingContext context = handle.firstParameter(DrawingContext.class); + DrawContextMachine.draw(guiGraphics, context); + + return timeSinceLastVisible >= handle.getDuration() * toastComponent.getNotificationDisplayTimeMultiplier() ? Visibility.HIDE : Visibility.SHOW; + } + + @Override + public int width() { + return handle.getWidth(); + } + + @Override + public int height() { + return handle.getHeight(); + } +} diff --git a/mod/neoforge/src/main/resources/META-INF/accesstransformer.cfg b/mod/neoforge/src/main/resources/META-INF/accesstransformer.cfg new file mode 100644 index 00000000..09db2dbb --- /dev/null +++ b/mod/neoforge/src/main/resources/META-INF/accesstransformer.cfg @@ -0,0 +1,45 @@ +## Screen API + +# Tooltip +public net.minecraft.client.gui.components.Tooltip message # message +public net.minecraft.client.gui.components.Tooltip narration # narration + +# ImageWidget$Sprite +public net.minecraft.client.gui.components.ImageWidget$Sprite +public net.minecraft.client.gui.components.ImageWidget$Sprite sprite # sprite + +# ImageWidget$Texture +public net.minecraft.client.gui.components.ImageWidget$Texture +public net.minecraft.client.gui.components.ImageWidget$Texture texture # texture + +# FocusableTextWidget +public net.minecraft.client.gui.components.FocusableTextWidget alwaysShowBorder # alwaysShowBorder +public net.minecraft.client.gui.components.FocusableTextWidget padding # padding + +# ImageButton +public net.minecraft.client.gui.components.ImageButton sprites # sprites + +# AlertScreen +public net.minecraft.client.gui.screens.AlertScreen messageText # messageText +public net.minecraft.client.gui.screens.AlertScreen okButton # okButton + +# DisconnectedScreen +public net.minecraft.client.gui.screens.DisconnectedScreen details # details +public net.minecraft.client.gui.screens.DisconnectedScreen buttonText # buttonText + +# DeathScreen +public net.minecraft.client.gui.screens.DeathScreen causeOfDeath # causeOfDeath +public net.minecraft.client.gui.screens.DeathScreen hardcore # hardcore + +# ErrorScreen +public net.minecraft.client.gui.screens.ErrorScreen message # message + +# CycleButton +public net.minecraft.client.gui.components.CycleButton valueStringifier # valueStringifier +public net.minecraft.client.gui.components.CycleButton values # values + +## Rendering API + +# GameRenderer +public net.minecraft.client.renderer.GameRenderer renderItemInHand(Lnet/minecraft/client/Camera;FLorg/joml/Matrix4f;)V # renderItemInHand +public net.minecraft.client.renderer.GameRenderer renderConfusionOverlay(Lnet/minecraft/client/gui/GuiGraphics;F)V # renderConfusionOverlay \ No newline at end of file diff --git a/mod/neoforge/src/main/resources/META-INF/neoforge.mods.toml b/mod/neoforge/src/main/resources/META-INF/neoforge.mods.toml new file mode 100644 index 00000000..ef6c92af --- /dev/null +++ b/mod/neoforge/src/main/resources/META-INF/neoforge.mods.toml @@ -0,0 +1,22 @@ +modLoader="javafml" +loaderVersion="[3,)" +license="GPL-3.0" +showAsDataPack=false +showAsResourcePack=false + +[[mods]] +modId="${project.ext.id}" +displayName="${project.ext.name}" +version="${project.version}" +description="${project.description}" +authors="${project.ext.author}" +logoFile="assets/icon.png" +license="${project.ext.license}" +issueTrackerURL="${project.ext.github}/issues" +displayURL="${project.ext.github}" + +[[mixins]] +config = "socketmc-neoforge.mixins.json" + +[[accessTransformers]] +file = "META-INF/accesstransformer.cfg" \ No newline at end of file diff --git a/mod/neoforge/src/main/resources/socketmc-neoforge.mixins.json b/mod/neoforge/src/main/resources/socketmc-neoforge.mixins.json new file mode 100644 index 00000000..dd2cc507 --- /dev/null +++ b/mod/neoforge/src/main/resources/socketmc-neoforge.mixins.json @@ -0,0 +1,16 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "xyz.gmitch215.socketmc.neoforge.mixin", + "compatibilityLevel": "JAVA_17", + "client": [ + "PacketDecoderMixin", + "GuiMixin", + "AbstractWidgetMixin", + "OnlineOptionsScreenMixin", + + "events.PlayerPressKeyEvent", + "events.PlayerMouseInputEvent", + "events.PlayerChangeScreenEvent" + ] +} \ No newline at end of file diff --git a/mod/neoforge/src/test/java/xyz/gmitch215/socketmc/neoforge/machines/TestNeoForgeMachineFinder.java b/mod/neoforge/src/test/java/xyz/gmitch215/socketmc/neoforge/machines/TestNeoForgeMachineFinder.java new file mode 100644 index 00000000..dda5f75a --- /dev/null +++ b/mod/neoforge/src/test/java/xyz/gmitch215/socketmc/neoforge/machines/TestNeoForgeMachineFinder.java @@ -0,0 +1,24 @@ +package xyz.gmitch215.socketmc.neoforge.machines; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import xyz.gmitch215.socketmc.instruction.Instruction; +import xyz.gmitch215.socketmc.instruction.Machine; +import xyz.gmitch215.socketmc.machines.MachineFinder; + +public class TestNeoForgeMachineFinder { + + @Test + @DisplayName("Test MachineFinder#getMachine (NeoForge)") + public void testGetMachine() { + Assertions.assertTrue(Instruction.ids().length > 0); + + for (String id : Instruction.ids()) { + Machine m = MachineFinder.getMachine(NeoForgeMachineFinder.MACHINES, id); + Assertions.assertNotNull(m, "NeoForge Machine for id '" + id + "' not found"); + Assertions.assertDoesNotThrow(() -> m.getClass().getDeclaredField("MACHINE"), "Missing 'MACHINE' field in forge machine for id '" + id + "'"); + } + } + +} diff --git a/mod/neoforge/src/test/java/xyz/gmitch215/socketmc/neoforge/machines/TestOpenScreenMachine.java b/mod/neoforge/src/test/java/xyz/gmitch215/socketmc/neoforge/machines/TestOpenScreenMachine.java new file mode 100644 index 00000000..fec809ba --- /dev/null +++ b/mod/neoforge/src/test/java/xyz/gmitch215/socketmc/neoforge/machines/TestOpenScreenMachine.java @@ -0,0 +1,22 @@ +package xyz.gmitch215.socketmc.neoforge.machines; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import xyz.gmitch215.socketmc.screen.DefaultScreen; + +public class TestOpenScreenMachine { + + @Test + @DisplayName("Test OpenScreenMachine#defaultScreen") + public void testDefaultScreen() { + for (DefaultScreen screen : DefaultScreen.getAllScreens()) { + try { + Assertions.assertNotNull(OpenScreenMachine.defaultScreen(screen, null)); + } catch (NullPointerException ignored) { + // Found Screen, needs "minecraft" + } + } + } + +} diff --git a/settings.gradle.kts b/settings.gradle.kts index a9c7e867..4987d5a2 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -3,7 +3,7 @@ rootProject.name = "SocketMC" include(":socketmc-core") project(":socketmc-core").projectDir = rootDir.resolve("core") -listOf("shared", "fabric", "forge").forEach { +listOf("shared", "fabric", "forge", "neoforge").forEach { include(":socketmc-$it") project(":socketmc-$it").projectDir = rootDir.resolve("mod/$it") } @@ -21,5 +21,6 @@ pluginManagement { maven("https://maven.fabricmc.net/") maven("https://maven.minecraftforge.net/") maven("https://maven.parchmentmc.org") + maven("https://maven.neoforged.net/releases/") } } \ No newline at end of file From 9e30355b31e199ad21f74a2c8570293442895266 Mon Sep 17 00:00:00 2001 From: Gregory Mitchell <54124162+gmitch215@users.noreply.github.com> Date: Sat, 7 Sep 2024 21:23:29 -0500 Subject: [PATCH 07/16] Update Imports --- .../fabric/machines/OpenScreenMachine.java | 14 +++++++------- .../forge/machines/OpenScreenMachine.java | 17 ++++++++--------- .../neoforge/machines/OpenScreenMachine.java | 2 +- .../gmitch215/socketmc/util/BukkitNBTTag.java | 1 - 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/machines/OpenScreenMachine.java b/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/machines/OpenScreenMachine.java index e27cad82..53b30df0 100644 --- a/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/machines/OpenScreenMachine.java +++ b/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/machines/OpenScreenMachine.java @@ -1,5 +1,12 @@ package xyz.gmitch215.socketmc.fabric.machines; +import net.minecraft.client.gui.screens.*; +import net.minecraft.client.gui.screens.achievement.StatsScreen; +import net.minecraft.client.gui.screens.advancements.AdvancementsScreen; +import net.minecraft.client.gui.screens.options.OptionsScreen; +import net.minecraft.network.chat.Component; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import xyz.gmitch215.socketmc.fabric.FabricUtil; import xyz.gmitch215.socketmc.fabric.screen.FabricScreen; import xyz.gmitch215.socketmc.instruction.Instruction; @@ -8,13 +15,6 @@ import xyz.gmitch215.socketmc.screen.AbstractScreen; import xyz.gmitch215.socketmc.screen.CustomScreen; import xyz.gmitch215.socketmc.screen.DefaultScreen; -import net.minecraft.client.gui.screens.*; -import net.minecraft.client.gui.screens.achievement.StatsScreen; -import net.minecraft.client.gui.screens.advancements.AdvancementsScreen; -import net.minecraft.client.gui.screens.options.OptionsScreen; -import net.minecraft.network.chat.Component; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import static xyz.gmitch215.socketmc.fabric.FabricSocketMC.minecraft; diff --git a/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/machines/OpenScreenMachine.java b/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/machines/OpenScreenMachine.java index 79f0615f..da43a9fb 100644 --- a/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/machines/OpenScreenMachine.java +++ b/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/machines/OpenScreenMachine.java @@ -1,5 +1,12 @@ package xyz.gmitch215.socketmc.forge.machines; +import net.minecraft.client.gui.screens.*; +import net.minecraft.client.gui.screens.achievement.StatsScreen; +import net.minecraft.client.gui.screens.advancements.AdvancementsScreen; +import net.minecraft.client.gui.screens.options.OptionsScreen; +import net.minecraft.network.chat.Component; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import xyz.gmitch215.socketmc.forge.ForgeUtil; import xyz.gmitch215.socketmc.forge.screen.ForgeScreen; import xyz.gmitch215.socketmc.instruction.Instruction; @@ -8,14 +15,6 @@ import xyz.gmitch215.socketmc.screen.AbstractScreen; import xyz.gmitch215.socketmc.screen.CustomScreen; import xyz.gmitch215.socketmc.screen.DefaultScreen; -import net.minecraft.client.gui.screens.*; -import net.minecraft.client.gui.screens.achievement.StatsScreen; -import net.minecraft.client.gui.screens.advancements.AdvancementsScreen; -import net.minecraft.client.gui.screens.options.OptionsScreen; -import net.minecraft.network.chat.Component; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import xyz.gmitch215.socketmc.forge.ForgeSocketMC; import static xyz.gmitch215.socketmc.forge.ForgeSocketMC.minecraft; @@ -24,7 +23,7 @@ public final class OpenScreenMachine implements Machine { public static final OpenScreenMachine MACHINE = new OpenScreenMachine(); - private OpenScreenMachine() {}; + private OpenScreenMachine() {} static Screen defaultScreen(@NotNull DefaultScreen screen, @Nullable Screen lastScreen) { return switch (screen.getIdentifier()) { diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/OpenScreenMachine.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/OpenScreenMachine.java index 8db0a3df..a9488ad3 100644 --- a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/OpenScreenMachine.java +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/OpenScreenMachine.java @@ -23,7 +23,7 @@ public final class OpenScreenMachine implements Machine { public static final OpenScreenMachine MACHINE = new OpenScreenMachine(); - private OpenScreenMachine() {}; + private OpenScreenMachine() {} static Screen defaultScreen(@NotNull DefaultScreen screen, @Nullable Screen lastScreen) { return switch (screen.getIdentifier()) { diff --git a/plugin/spigot/src/main/java/xyz/gmitch215/socketmc/util/BukkitNBTTag.java b/plugin/spigot/src/main/java/xyz/gmitch215/socketmc/util/BukkitNBTTag.java index b40adbb1..c211042e 100644 --- a/plugin/spigot/src/main/java/xyz/gmitch215/socketmc/util/BukkitNBTTag.java +++ b/plugin/spigot/src/main/java/xyz/gmitch215/socketmc/util/BukkitNBTTag.java @@ -2,7 +2,6 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; import net.minecraft.nbt.TagParser; -import net.minecraft.server.MinecraftServer; import org.bukkit.craftbukkit.v1_21_R1.CraftRegistry; import org.bukkit.craftbukkit.v1_21_R1.inventory.CraftItemStack; import org.bukkit.inventory.ItemStack; From 8cf17f84845d883a24934da7908927e070e1f11a Mon Sep 17 00:00:00 2001 From: Gregory Mitchell <54124162+gmitch215@users.noreply.github.com> Date: Sat, 7 Sep 2024 21:25:07 -0500 Subject: [PATCH 08/16] Create `Instruction#SET_WINDOW_ICON` --- .../socketmc/instruction/Instruction.java | 21 ++++++++ .../fabric/machines/FabricMachineFinder.java | 3 +- .../fabric/machines/SetWindowIconMachine.java | 52 +++++++++++++++++++ .../forge/machines/ForgeMachineFinder.java | 3 +- .../forge/machines/SetWindowIconMachine.java | 52 +++++++++++++++++++ .../machines/NeoForgeMachineFinder.java | 3 +- .../machines/SetWindowIconMachine.java | 52 +++++++++++++++++++ 7 files changed, 183 insertions(+), 3 deletions(-) create mode 100644 mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/machines/SetWindowIconMachine.java create mode 100644 mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/machines/SetWindowIconMachine.java create mode 100644 mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/SetWindowIconMachine.java diff --git a/core/src/main/java/xyz/gmitch215/socketmc/instruction/Instruction.java b/core/src/main/java/xyz/gmitch215/socketmc/instruction/Instruction.java index 68a3447f..2e85423b 100644 --- a/core/src/main/java/xyz/gmitch215/socketmc/instruction/Instruction.java +++ b/core/src/main/java/xyz/gmitch215/socketmc/instruction/Instruction.java @@ -181,6 +181,12 @@ public final class Instruction implements Serializable, Paramaterized { @InstructionPermission(ModPermission.USE_GUI) public static final String DRAW_ITEMSTACK = "draw_itemstack"; + /** + * Instruction to change the native window icon of the client. + */ + @InstructionPermission(ModPermission.USE_GUI) + public static final String SET_WINDOW_ICON = "set_window_icon"; + @Serial private static final long serialVersionUID = -4177824277470078500L; @@ -1719,6 +1725,21 @@ public static Instruction drawItemStack(@NotNull NBTTag item, int x, int y, int return new Instruction(DRAW_ITEMSTACK, List.of(item, x, y, guiOffset, randomSeed, millis)); } + /** + *

Creates a {@link #SET_WINDOW_ICON} instruction.

+ *
    + *
  • On Windows/Linux, a {@code .png} file must be loaded. The recommended size is {@code 16x16}.
  • + *
  • On macOS, a {@code .icns} file must be loaded.
  • + *
+ *

The library will not make an effort to validate the byte array.

+ * @param icon Icon to Set + * @return Set Window Icon Instruction + */ + @NotNull + public static Instruction setWindowIcon(byte[] icon) { + return new Instruction(SET_WINDOW_ICON, List.of(icon)); + } + // // Serialization diff --git a/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/machines/FabricMachineFinder.java b/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/machines/FabricMachineFinder.java index 44e35acd..cb82ccbf 100644 --- a/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/machines/FabricMachineFinder.java +++ b/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/machines/FabricMachineFinder.java @@ -26,7 +26,8 @@ private FabricMachineFinder() {} DrawContextMachine.class, DisplayToastMachine.class, SetOverlayMachine.class, - DrawItemStackMachine.class + DrawItemStackMachine.class, + SetWindowIconMachine.class )).toList(); } diff --git a/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/machines/SetWindowIconMachine.java b/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/machines/SetWindowIconMachine.java new file mode 100644 index 00000000..d679a1c9 --- /dev/null +++ b/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/machines/SetWindowIconMachine.java @@ -0,0 +1,52 @@ +package xyz.gmitch215.socketmc.fabric.machines; + +import com.mojang.blaze3d.platform.MacosUtil; +import com.mojang.blaze3d.platform.NativeImage; +import org.lwjgl.glfw.GLFW; +import org.lwjgl.glfw.GLFWImage; +import org.lwjgl.system.MemoryStack; +import org.lwjgl.system.MemoryUtil; +import xyz.gmitch215.socketmc.instruction.Instruction; +import xyz.gmitch215.socketmc.instruction.InstructionId; +import xyz.gmitch215.socketmc.instruction.Machine; + +import java.io.ByteArrayInputStream; +import java.nio.ByteBuffer; + +import static xyz.gmitch215.socketmc.fabric.FabricSocketMC.minecraft; + +@InstructionId(Instruction.SET_WINDOW_ICON) +public final class SetWindowIconMachine implements Machine { + + public static final SetWindowIconMachine MACHINE = new SetWindowIconMachine(); + + private SetWindowIconMachine() {} + + @Override + public void onInstruction(Instruction instruction) throws Exception { + byte[] icon = instruction.parameter(0, byte[].class); + + int i = GLFW.glfwGetPlatform(); + switch (i) { + case 393217, 393220 -> { + try (MemoryStack stack = MemoryStack.stackPush()) { + GLFWImage.Buffer buffer = GLFWImage.malloc(1, stack); + try (NativeImage image = NativeImage.read(icon)) { + ByteBuffer bytes = MemoryUtil.memAlloc(image.getWidth() * image.getHeight() * 4); + bytes.asIntBuffer().put(image.getPixelsRGBA()); + + buffer.position(0); + buffer.width(image.getWidth()); + buffer.height(image.getHeight()); + buffer.pixels(bytes); + + GLFW.glfwSetWindowIcon(minecraft.getWindow().getWindow(), buffer.position(0)); + MemoryUtil.memFree(bytes); + } + } + } + case 393218 -> MacosUtil.loadIcon(() -> new ByteArrayInputStream(icon)); + } + } + +} diff --git a/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/machines/ForgeMachineFinder.java b/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/machines/ForgeMachineFinder.java index 30790a9b..1edf78bb 100644 --- a/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/machines/ForgeMachineFinder.java +++ b/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/machines/ForgeMachineFinder.java @@ -26,7 +26,8 @@ private ForgeMachineFinder() {} DrawContextMachine.class, DisplayToastMachine.class, SetOverlayMachine.class, - DrawItemStackMachine.class + DrawItemStackMachine.class, + SetWindowIconMachine.class )).toList(); } diff --git a/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/machines/SetWindowIconMachine.java b/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/machines/SetWindowIconMachine.java new file mode 100644 index 00000000..f2bc9263 --- /dev/null +++ b/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/machines/SetWindowIconMachine.java @@ -0,0 +1,52 @@ +package xyz.gmitch215.socketmc.forge.machines; + +import com.mojang.blaze3d.platform.MacosUtil; +import com.mojang.blaze3d.platform.NativeImage; +import org.lwjgl.glfw.GLFW; +import org.lwjgl.glfw.GLFWImage; +import org.lwjgl.system.MemoryStack; +import org.lwjgl.system.MemoryUtil; +import xyz.gmitch215.socketmc.instruction.Instruction; +import xyz.gmitch215.socketmc.instruction.InstructionId; +import xyz.gmitch215.socketmc.instruction.Machine; + +import java.io.ByteArrayInputStream; +import java.nio.ByteBuffer; + +import static xyz.gmitch215.socketmc.forge.ForgeSocketMC.minecraft; + +@InstructionId(Instruction.SET_WINDOW_ICON) +public final class SetWindowIconMachine implements Machine { + + public static final SetWindowIconMachine MACHINE = new SetWindowIconMachine(); + + private SetWindowIconMachine() {} + + @Override + public void onInstruction(Instruction instruction) throws Exception { + byte[] icon = instruction.parameter(0, byte[].class); + + int i = GLFW.glfwGetPlatform(); + switch (i) { + case 393217, 393220 -> { + try (MemoryStack stack = MemoryStack.stackPush()) { + GLFWImage.Buffer buffer = GLFWImage.malloc(1, stack); + try (NativeImage image = NativeImage.read(icon)) { + ByteBuffer bytes = MemoryUtil.memAlloc(image.getWidth() * image.getHeight() * 4); + bytes.asIntBuffer().put(image.getPixelsRGBA()); + + buffer.position(0); + buffer.width(image.getWidth()); + buffer.height(image.getHeight()); + buffer.pixels(bytes); + + GLFW.glfwSetWindowIcon(minecraft.getWindow().getWindow(), buffer.position(0)); + MemoryUtil.memFree(bytes); + } + } + } + case 393218 -> MacosUtil.loadIcon(() -> new ByteArrayInputStream(icon)); + } + } + +} diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/NeoForgeMachineFinder.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/NeoForgeMachineFinder.java index 12fee53c..5d6d3917 100644 --- a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/NeoForgeMachineFinder.java +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/NeoForgeMachineFinder.java @@ -26,7 +26,8 @@ private NeoForgeMachineFinder() {} DrawContextMachine.class, DisplayToastMachine.class, SetOverlayMachine.class, - DrawItemStackMachine.class + DrawItemStackMachine.class, + SetWindowIconMachine.class )).toList(); } diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/SetWindowIconMachine.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/SetWindowIconMachine.java new file mode 100644 index 00000000..13b56d1b --- /dev/null +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/SetWindowIconMachine.java @@ -0,0 +1,52 @@ +package xyz.gmitch215.socketmc.neoforge.machines; + +import com.mojang.blaze3d.platform.MacosUtil; +import com.mojang.blaze3d.platform.NativeImage; +import org.lwjgl.glfw.GLFW; +import org.lwjgl.glfw.GLFWImage; +import org.lwjgl.system.MemoryStack; +import org.lwjgl.system.MemoryUtil; +import xyz.gmitch215.socketmc.instruction.Instruction; +import xyz.gmitch215.socketmc.instruction.InstructionId; +import xyz.gmitch215.socketmc.instruction.Machine; + +import java.io.ByteArrayInputStream; +import java.nio.ByteBuffer; + +import static xyz.gmitch215.socketmc.neoforge.NeoForgeSocketMC.minecraft; + +@InstructionId(Instruction.SET_WINDOW_ICON) +public final class SetWindowIconMachine implements Machine { + + public static final SetWindowIconMachine MACHINE = new SetWindowIconMachine(); + + private SetWindowIconMachine() {} + + @Override + public void onInstruction(Instruction instruction) throws Exception { + byte[] icon = instruction.parameter(0, byte[].class); + + int i = GLFW.glfwGetPlatform(); + switch (i) { + case 393217, 393220 -> { + try (MemoryStack stack = MemoryStack.stackPush()) { + GLFWImage.Buffer buffer = GLFWImage.malloc(1, stack); + try (NativeImage image = NativeImage.read(icon)) { + ByteBuffer bytes = MemoryUtil.memAlloc(image.getWidth() * image.getHeight() * 4); + bytes.asIntBuffer().put(image.getPixelsRGBA()); + + buffer.position(0); + buffer.width(image.getWidth()); + buffer.height(image.getHeight()); + buffer.pixels(bytes); + + GLFW.glfwSetWindowIcon(minecraft.getWindow().getWindow(), buffer.position(0)); + MemoryUtil.memFree(bytes); + } + } + } + case 393218 -> MacosUtil.loadIcon(() -> new ByteArrayInputStream(icon)); + } + } + +} From b83602ce958e7444276dcbb3111b6e32446870cc Mon Sep 17 00:00:00 2001 From: Gregory Mitchell <54124162+gmitch215@users.noreply.github.com> Date: Sat, 7 Sep 2024 21:25:24 -0500 Subject: [PATCH 09/16] Create `ModPermission#CHANGE_GAME_PREFERENCES` --- .../java/xyz/gmitch215/socketmc/config/ModPermission.java | 5 +++++ .../src/main/resources/assets/socketmc/lang/en_us.json | 4 +++- .../src/main/resources/assets/socketmc/lang/es_es.json | 4 +++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/xyz/gmitch215/socketmc/config/ModPermission.java b/core/src/main/java/xyz/gmitch215/socketmc/config/ModPermission.java index f9e796e4..9c448fea 100644 --- a/core/src/main/java/xyz/gmitch215/socketmc/config/ModPermission.java +++ b/core/src/main/java/xyz/gmitch215/socketmc/config/ModPermission.java @@ -60,6 +60,11 @@ public enum ModPermission { */ READ_GAME_PROPERTIES(true), + /** + * Permission to change various soft game preferences, such as social interactions. + */ + CHANGE_GAME_PREFERENCES(false), + ; private final boolean changeable; diff --git a/mod/shared/src/main/resources/assets/socketmc/lang/en_us.json b/mod/shared/src/main/resources/assets/socketmc/lang/en_us.json index e02bbd78..ede288dd 100644 --- a/mod/shared/src/main/resources/assets/socketmc/lang/en_us.json +++ b/mod/shared/src/main/resources/assets/socketmc/lang/en_us.json @@ -23,5 +23,7 @@ "gui.socketmc.permission.read_gui_properties": "Read GUI Properties", "gui.socketmc.permission.read_gui_properties.tooltip": "Permission to read GUI properties, such as the screen size, window size, and more.", "gui.socketmc.permission.read_game_properties": "Read Game Properties", - "gui.socketmc.permission.read_game_properties.tooltip": "Permission to read various client game properties, such as command history and in-game information." + "gui.socketmc.permission.read_game_properties.tooltip": "Permission to read various client game properties, such as command history and in-game information.", + "gui.socketmc.permission.change_game_preferences": "Change Game Preferences", + "gui.socketmc.permission.change_game_preferences.tooltip": "Permission to change various soft game preferences, such as social interactions." } \ No newline at end of file diff --git a/mod/shared/src/main/resources/assets/socketmc/lang/es_es.json b/mod/shared/src/main/resources/assets/socketmc/lang/es_es.json index 7ffea75a..ca7b03f4 100644 --- a/mod/shared/src/main/resources/assets/socketmc/lang/es_es.json +++ b/mod/shared/src/main/resources/assets/socketmc/lang/es_es.json @@ -23,5 +23,7 @@ "gui.socketmc.permission.read_gui_properties": "Leer Propiedades de la GUI", "gui.socketmc.permission.read_gui_properties.tooltip": "Permiso para leer las propiedades de la GUI, como el tamaño de la ventana y la posición de la ventana.", "gui.socketmc.permission.read_game_properties": "Leer Propiedades del Juego", - "gui.socketmc.permission.read_game_properties.tooltip": "Permiso para leer las propiedades del juego, como el historial de comandos y la información del juego." + "gui.socketmc.permission.read_game_properties.tooltip": "Permiso para leer las propiedades del juego, como el historial de comandos y la información del juego.", + "gui.socketmc.permission.change_game_preferences": "Cambiar Preferencias del Juego", + "gui.socketmc.permission.change_game_preferences.tooltip": "Permiso para cambiar las preferencias del juego, como las interacciones sociales." } \ No newline at end of file From 316da22a3df2d575a9480a834e8083171cde9088 Mon Sep 17 00:00:00 2001 From: Gregory Mitchell <54124162+gmitch215@users.noreply.github.com> Date: Sat, 7 Sep 2024 21:26:41 -0500 Subject: [PATCH 10/16] Add New RenderInstructions - Create DebugRenderer - Create GameRenderer#renderItemActivation --- .../instruction/RenderInstruction.java | 68 ++++++++++++++++++- .../fabric/machines/RenderingMachine.java | 35 ++++++++-- .../src/main/resources/socketmc.accesswidener | 9 ++- .../forge/machines/RenderingMachine.java | 34 ++++++++-- .../resources/META-INF/accesstransformer.cfg | 9 ++- .../neoforge/machines/RenderingMachine.java | 34 ++++++++-- .../resources/META-INF/accesstransformer.cfg | 9 ++- 7 files changed, 175 insertions(+), 23 deletions(-) diff --git a/core/src/main/java/xyz/gmitch215/socketmc/instruction/RenderInstruction.java b/core/src/main/java/xyz/gmitch215/socketmc/instruction/RenderInstruction.java index da13ac1c..f4c88f8e 100644 --- a/core/src/main/java/xyz/gmitch215/socketmc/instruction/RenderInstruction.java +++ b/core/src/main/java/xyz/gmitch215/socketmc/instruction/RenderInstruction.java @@ -3,9 +3,11 @@ import org.jetbrains.annotations.NotNull; import org.joml.Matrix4f; import xyz.gmitch215.socketmc.util.DataHolder; +import xyz.gmitch215.socketmc.util.NBTTag; import java.io.Serial; import java.io.Serializable; +import java.security.SecureRandom; import java.time.Duration; import java.util.HashMap; import java.util.Map; @@ -74,6 +76,15 @@ public static RenderInstruction.GameRenderer game() { return new GameRenderer(); } + /** + * Creates a new instruction for the DebugRenderer. + * @return Debug Renderer Instruction + */ + @NotNull + public static RenderInstruction.DebugRenderer debug() { + return new DebugRenderer(); + } + /** * Represents instructions for the Game Renderer. */ @@ -120,7 +131,7 @@ public void transformItemInHand(@NotNull Matrix4f matrix, long millis) throws Il } /** - * Renders the confusion effect, used when the player has the nausea effect. + * Renders the confusion effect. Used when the player has the nausea effect. * @param strength The strength of the effect, between 0 and 1 * @throws IllegalArgumentException if the strength is not between 0 and 1 */ @@ -135,6 +146,61 @@ public void renderConfusionEffect(float strength) throws IllegalArgumentExceptio isFilled = true; } + /** + * Renders the item activation effect. Used when the player activates a Totem of Undying. + * @param item The item that is being activated + * @throws IllegalArgumentException if the item is null + */ + public void renderItemActivation(@NotNull NBTTag item) throws IllegalArgumentException { + SecureRandom random = new SecureRandom(); + renderItemActivation(item, random.nextFloat() * 2.0f - 1.0f, random.nextFloat() * 2.0f - 1.0f); + } + + /** + * Renders the item activation effect. Used when the player activates a Totem of Undying. + * @param item The item that is being activated + * @param offsetX The final offsetX the item should glide to + * @param offsetY The final offsetY the item should glide to + * @throws IllegalArgumentException if the item is null + */ + public void renderItemActivation(@NotNull NBTTag item, float offsetX, float offsetY) throws IllegalArgumentException { + checkFilled(); + + data.put("item", item); + data.put("offsetX", offsetX); + data.put("offsetY", offsetY); + + subOrdinal = 2; + isFilled = true; + } + + } + + public static final class DebugRenderer extends RenderInstruction { + + /** + * The ordinal for a {@link RenderInstruction.DebugRenderer}. + */ + public static final int ORDINAL = 1; + + @Serial + private static final long serialVersionUID = -2873349323016509570L; + + private DebugRenderer() { super(ORDINAL); } + + /** + * Renders the chunk border seen when using the F3+G debug keybind. + * @param enabled Whether the chunk border should be rendered + */ + public void renderChunkborder(boolean enabled) { + checkFilled(); + + data.put("enabled", enabled); + + subOrdinal = 0; + isFilled = true; + } + } } diff --git a/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/machines/RenderingMachine.java b/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/machines/RenderingMachine.java index 1a6d0619..b7230c2a 100644 --- a/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/machines/RenderingMachine.java +++ b/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/machines/RenderingMachine.java @@ -1,16 +1,17 @@ package xyz.gmitch215.socketmc.fabric.machines; import net.minecraft.client.gui.GuiGraphics; +import xyz.gmitch215.socketmc.fabric.FabricUtil; import xyz.gmitch215.socketmc.instruction.Instruction; import xyz.gmitch215.socketmc.instruction.InstructionId; import xyz.gmitch215.socketmc.instruction.Machine; import xyz.gmitch215.socketmc.instruction.RenderInstruction; import xyz.gmitch215.socketmc.util.LifecycleMap; import org.joml.Matrix4f; -import xyz.gmitch215.socketmc.fabric.FabricSocketMC; +import xyz.gmitch215.socketmc.util.NBTTag; import java.util.List; -import java.util.function.Function; +import java.util.function.BiFunction; import static xyz.gmitch215.socketmc.fabric.FabricSocketMC.minecraft; @@ -22,16 +23,17 @@ public final class RenderingMachine implements Machine { private RenderingMachine() {} private static final LifecycleMap lifecycle = new LifecycleMap<>(); + private static final Runnable DONE = () -> {}; public static void tick() { lifecycle.run(); lifecycle.forEach(Runnable::run); } - public static final List>> RENDERERS = List.of( + public static final List>> RENDERERS = List.of( // GameRenderer List.of( - i -> { + (i, time) -> { Matrix4f matrix = i.data("matrix", Matrix4f.class); return () -> minecraft.gameRenderer.renderItemInHand( minecraft.gameRenderer.getMainCamera(), @@ -39,10 +41,29 @@ public static void tick() { matrix ); }, - i -> { + (i, time) -> { float strength = i.data("strength", Float.class); GuiGraphics graphics = new GuiGraphics(minecraft, minecraft.renderBuffers().bufferSource()); return () -> minecraft.gameRenderer.renderConfusionOverlay(graphics, strength); + }, + (i, time) -> { + NBTTag item = i.data("item", NBTTag.class); + float offsetX = i.data("offsetX", Float.class); + float offsetY = i.data("offsetY", Float.class); + + minecraft.gameRenderer.itemActivationItem = FabricUtil.toItem(item); + minecraft.gameRenderer.itemActivationTicks = (int) (time / 50); + minecraft.gameRenderer.itemActivationOffX = offsetX; + minecraft.gameRenderer.itemActivationOffY = offsetY; + + return DONE; + } + ), + // DebugRenderer + List.of( + (i, time) -> { + minecraft.debugRenderer.renderChunkborder = i.data("enabled", Boolean.class); + return DONE; } ) ); @@ -50,10 +71,10 @@ public static void tick() { @Override public void onInstruction(Instruction instruction) { RenderInstruction render = instruction.lastParameter(RenderInstruction.class); - - Runnable action = RENDERERS.get(render.getOrdinal()).get(render.getSubOrdinal()).apply(render); long millis = (long) render.data("time"); + Runnable action = RENDERERS.get(render.getOrdinal()).get(render.getSubOrdinal()).apply(render, millis); + lifecycle.store(action, millis); } diff --git a/mod/fabric/src/main/resources/socketmc.accesswidener b/mod/fabric/src/main/resources/socketmc.accesswidener index 958ba314..aaf33ce8 100644 --- a/mod/fabric/src/main/resources/socketmc.accesswidener +++ b/mod/fabric/src/main/resources/socketmc.accesswidener @@ -47,4 +47,11 @@ accessible field net/minecraft/client/gui/components/CycleButton values Lnet/min # GameRenderer accessible method net/minecraft/client/renderer/GameRenderer renderItemInHand (Lnet/minecraft/client/Camera;FLorg/joml/Matrix4f;)V -accessible method net/minecraft/client/renderer/GameRenderer renderConfusionOverlay (Lnet/minecraft/client/gui/GuiGraphics;F)V \ No newline at end of file +accessible method net/minecraft/client/renderer/GameRenderer renderConfusionOverlay (Lnet/minecraft/client/gui/GuiGraphics;F)V +accessible field net/minecraft/client/renderer/GameRenderer itemActivationItem Lnet/minecraft/world/item/ItemStack; +accessible field net/minecraft/client/renderer/GameRenderer itemActivationTicks I +accessible field net/minecraft/client/renderer/GameRenderer itemActivationOffX F +accessible field net/minecraft/client/renderer/GameRenderer itemActivationOffY F + +# DebugRenderer +accessible field net/minecraft/client/renderer/debug/DebugRenderer renderChunkborder Z \ No newline at end of file diff --git a/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/machines/RenderingMachine.java b/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/machines/RenderingMachine.java index a0113e51..2f46c303 100644 --- a/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/machines/RenderingMachine.java +++ b/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/machines/RenderingMachine.java @@ -1,15 +1,17 @@ package xyz.gmitch215.socketmc.forge.machines; import net.minecraft.client.gui.GuiGraphics; +import xyz.gmitch215.socketmc.forge.ForgeUtil; import xyz.gmitch215.socketmc.instruction.Instruction; import xyz.gmitch215.socketmc.instruction.InstructionId; import xyz.gmitch215.socketmc.instruction.Machine; import xyz.gmitch215.socketmc.instruction.RenderInstruction; import xyz.gmitch215.socketmc.util.LifecycleMap; import org.joml.Matrix4f; +import xyz.gmitch215.socketmc.util.NBTTag; import java.util.List; -import java.util.function.Function; +import java.util.function.BiFunction; import static xyz.gmitch215.socketmc.forge.ForgeSocketMC.minecraft; @@ -21,16 +23,17 @@ public final class RenderingMachine implements Machine { private RenderingMachine() {} private static final LifecycleMap lifecycle = new LifecycleMap<>(); + private static final Runnable DONE = () -> {}; public static void tick() { lifecycle.run(); lifecycle.forEach(Runnable::run); } - public static final List>> RENDERERS = List.of( + public static final List>> RENDERERS = List.of( // GameRenderer List.of( - i -> { + (i, time) -> { Matrix4f matrix = i.data("matrix", Matrix4f.class); return () -> minecraft.gameRenderer.renderItemInHand( minecraft.gameRenderer.getMainCamera(), @@ -38,10 +41,29 @@ public static void tick() { matrix ); }, - i -> { + (i, time) -> { float strength = i.data("strength", Float.class); GuiGraphics graphics = new GuiGraphics(minecraft, minecraft.renderBuffers().bufferSource()); return () -> minecraft.gameRenderer.renderConfusionOverlay(graphics, strength); + }, + (i, time) -> { + NBTTag item = i.data("item", NBTTag.class); + float offsetX = i.data("offsetX", Float.class); + float offsetY = i.data("offsetY", Float.class); + + minecraft.gameRenderer.itemActivationItem = ForgeUtil.toItem(item); + minecraft.gameRenderer.itemActivationTicks = (int) (time / 50); + minecraft.gameRenderer.itemActivationOffX = offsetX; + minecraft.gameRenderer.itemActivationOffY = offsetY; + + return DONE; + } + ), + // DebugRenderer + List.of( + (i, time) -> { + minecraft.debugRenderer.renderChunkborder = i.data("enabled", Boolean.class); + return DONE; } ) ); @@ -49,10 +71,10 @@ public static void tick() { @Override public void onInstruction(Instruction instruction) { RenderInstruction render = instruction.lastParameter(RenderInstruction.class); - - Runnable action = RENDERERS.get(render.getOrdinal()).get(render.getSubOrdinal()).apply(render); long millis = (long) render.data("time"); + Runnable action = RENDERERS.get(render.getOrdinal()).get(render.getSubOrdinal()).apply(render, millis); + lifecycle.store(action, millis); } diff --git a/mod/forge/src/main/resources/META-INF/accesstransformer.cfg b/mod/forge/src/main/resources/META-INF/accesstransformer.cfg index 81137fd5..80af82e0 100644 --- a/mod/forge/src/main/resources/META-INF/accesstransformer.cfg +++ b/mod/forge/src/main/resources/META-INF/accesstransformer.cfg @@ -42,4 +42,11 @@ public net.minecraft.client.gui.components.CycleButton f_168861_ # values # GameRenderer public net.minecraft.client.renderer.GameRenderer m_109120_(Lnet/minecraft/client/Camera;FLorg/joml/Matrix4f;)V # renderItemInHand -public net.minecraft.client.renderer.GameRenderer m_280083_(Lnet/minecraft/client/gui/GuiGraphics;F)V # renderConfusionOverlay \ No newline at end of file +public net.minecraft.client.renderer.GameRenderer m_280083_(Lnet/minecraft/client/gui/GuiGraphics;F)V # renderConfusionOverlay +public net.minecraft.client.renderer.GameRenderer f_109080_ # itemActivationItem +public net.minecraft.client.renderer.GameRenderer f_109047_ # itemActivationTicks +public net.minecraft.client.renderer.GameRenderer f_109048_ # itemActivationOffX +public net.minecraft.client.renderer.GameRenderer f_109049_ # itemActivationOffY + +# DebugRenderer +public net.minecraft.client.renderer.debug.DebugRenderer f_113431_ # renderChunkborder \ No newline at end of file diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/RenderingMachine.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/RenderingMachine.java index 8444925a..cc2b3972 100644 --- a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/RenderingMachine.java +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/machines/RenderingMachine.java @@ -6,10 +6,12 @@ import xyz.gmitch215.socketmc.instruction.InstructionId; import xyz.gmitch215.socketmc.instruction.Machine; import xyz.gmitch215.socketmc.instruction.RenderInstruction; +import xyz.gmitch215.socketmc.neoforge.NeoForgeUtil; import xyz.gmitch215.socketmc.util.LifecycleMap; +import xyz.gmitch215.socketmc.util.NBTTag; import java.util.List; -import java.util.function.Function; +import java.util.function.BiFunction; import static xyz.gmitch215.socketmc.neoforge.NeoForgeSocketMC.minecraft; @@ -21,16 +23,17 @@ public final class RenderingMachine implements Machine { private RenderingMachine() {} private static final LifecycleMap lifecycle = new LifecycleMap<>(); + private static final Runnable DONE = () -> {}; public static void tick() { lifecycle.run(); lifecycle.forEach(Runnable::run); } - public static final List>> RENDERERS = List.of( + public static final List>> RENDERERS = List.of( // GameRenderer List.of( - i -> { + (i, time) -> { Matrix4f matrix = i.data("matrix", Matrix4f.class); return () -> minecraft.gameRenderer.renderItemInHand( minecraft.gameRenderer.getMainCamera(), @@ -38,10 +41,29 @@ public static void tick() { matrix ); }, - i -> { + (i, time) -> { float strength = i.data("strength", Float.class); GuiGraphics graphics = new GuiGraphics(minecraft, minecraft.renderBuffers().bufferSource()); return () -> minecraft.gameRenderer.renderConfusionOverlay(graphics, strength); + }, + (i, time) -> { + NBTTag item = i.data("item", NBTTag.class); + float offsetX = i.data("offsetX", Float.class); + float offsetY = i.data("offsetY", Float.class); + + minecraft.gameRenderer.itemActivationItem = NeoForgeUtil.toItem(item); + minecraft.gameRenderer.itemActivationTicks = (int) (time / 50); + minecraft.gameRenderer.itemActivationOffX = offsetX; + minecraft.gameRenderer.itemActivationOffY = offsetY; + + return DONE; + } + ), + // DebugRenderer + List.of( + (i, time) -> { + minecraft.debugRenderer.renderChunkborder = i.data("enabled", Boolean.class); + return DONE; } ) ); @@ -49,10 +71,10 @@ public static void tick() { @Override public void onInstruction(Instruction instruction) { RenderInstruction render = instruction.lastParameter(RenderInstruction.class); - - Runnable action = RENDERERS.get(render.getOrdinal()).get(render.getSubOrdinal()).apply(render); long millis = (long) render.data("time"); + Runnable action = RENDERERS.get(render.getOrdinal()).get(render.getSubOrdinal()).apply(render, millis); + lifecycle.store(action, millis); } diff --git a/mod/neoforge/src/main/resources/META-INF/accesstransformer.cfg b/mod/neoforge/src/main/resources/META-INF/accesstransformer.cfg index 09db2dbb..80a58019 100644 --- a/mod/neoforge/src/main/resources/META-INF/accesstransformer.cfg +++ b/mod/neoforge/src/main/resources/META-INF/accesstransformer.cfg @@ -42,4 +42,11 @@ public net.minecraft.client.gui.components.CycleButton values # values # GameRenderer public net.minecraft.client.renderer.GameRenderer renderItemInHand(Lnet/minecraft/client/Camera;FLorg/joml/Matrix4f;)V # renderItemInHand -public net.minecraft.client.renderer.GameRenderer renderConfusionOverlay(Lnet/minecraft/client/gui/GuiGraphics;F)V # renderConfusionOverlay \ No newline at end of file +public net.minecraft.client.renderer.GameRenderer renderConfusionOverlay(Lnet/minecraft/client/gui/GuiGraphics;F)V # renderConfusionOverlay +public net.minecraft.client.renderer.GameRenderer itemActivationItem # itemActivationItem +public net.minecraft.client.renderer.GameRenderer itemActivationTicks # itemActivationTicks +public net.minecraft.client.renderer.GameRenderer itemActivationOffX # itemActivationOffX +public net.minecraft.client.renderer.GameRenderer itemActivationOffY # itemActivationOffY + +# DebugRenderer +public net.minecraft.client.renderer.debug.DebugRenderer renderChunkborder # renderChunkborder \ No newline at end of file From b361a65388753045b4fec01c2f55b4a12e4132af Mon Sep 17 00:00:00 2001 From: Gregory Mitchell <54124162+gmitch215@users.noreply.github.com> Date: Sun, 8 Sep 2024 16:38:01 -0500 Subject: [PATCH 11/16] Create `Instruction#SHOW_PLAYERS`, `Instruction#HIDE_PLAYERS` --- .../socketmc/instruction/Instruction.java | 59 ++++++++++++++++++- .../socketmc/fabric/FabricSocketMC.java | 18 ++++++ .../socketmc/forge/ForgeSocketMC.java | 18 ++++++ .../socketmc/neoforge/NeoForgeSocketMC.java | 18 ++++++ .../java/xyz/gmitch215/socketmc/SocketMC.java | 10 +++- .../socketmc/machines/HidePlayersMachine.java | 22 +++++++ .../socketmc/machines/MachineFinder.java | 4 +- .../socketmc/machines/ShowPlayersMachine.java | 22 +++++++ 8 files changed, 165 insertions(+), 6 deletions(-) create mode 100644 mod/shared/src/main/java/xyz/gmitch215/socketmc/machines/HidePlayersMachine.java create mode 100644 mod/shared/src/main/java/xyz/gmitch215/socketmc/machines/ShowPlayersMachine.java diff --git a/core/src/main/java/xyz/gmitch215/socketmc/instruction/Instruction.java b/core/src/main/java/xyz/gmitch215/socketmc/instruction/Instruction.java index 2e85423b..b5b9ce4d 100644 --- a/core/src/main/java/xyz/gmitch215/socketmc/instruction/Instruction.java +++ b/core/src/main/java/xyz/gmitch215/socketmc/instruction/Instruction.java @@ -20,9 +20,8 @@ import java.lang.reflect.Modifier; import java.net.URI; import java.time.Duration; -import java.util.ArrayList; +import java.util.*; import java.util.List; -import java.util.Objects; /** * Represents a SocketMC Instruction to be sent to the client. @@ -187,6 +186,18 @@ public final class Instruction implements Serializable, Paramaterized { @InstructionPermission(ModPermission.USE_GUI) public static final String SET_WINDOW_ICON = "set_window_icon"; + /** + * Instruction to show players on the social interactions menu. + */ + @InstructionPermission(ModPermission.CHANGE_GAME_PREFERENCES) + public static final String SHOW_PLAYERS = "show_players"; + + /** + * Instruction to hide players from the social interactions menu. + */ + @InstructionPermission(ModPermission.CHANGE_GAME_PREFERENCES) + public static final String HIDE_PLAYERS = "hide_players"; + @Serial private static final long serialVersionUID = -4177824277470078500L; @@ -1740,6 +1751,50 @@ public static Instruction setWindowIcon(byte[] icon) { return new Instruction(SET_WINDOW_ICON, List.of(icon)); } + /** + * Creates a {@link #SHOW_PLAYERS} instruction. + * @param players Players to Show + * @return Show Players Instruction + */ + public static Instruction showPlayers(@NotNull Iterable players) { + if (players == null) throw new IllegalArgumentException("Players cannot be null"); + + return new Instruction(SHOW_PLAYERS, List.of(players)); + } + + /** + * Creates a {@link #SHOW_PLAYERS} instruction. + * @param players Players to Show + * @return Show Players Instruction + */ + public static Instruction showPlayers(@NotNull UUID... players) { + if (players == null) throw new IllegalArgumentException("Players cannot be null"); + + return new Instruction(SHOW_PLAYERS, List.of(players)); + } + + /** + * Creates a {@link #HIDE_PLAYERS} instruction. + * @param players Players to Hide + * @return Hide Players Instruction + */ + public static Instruction hidePlayers(@NotNull Iterable players) { + if (players == null) throw new IllegalArgumentException("Players cannot be null"); + + return new Instruction(HIDE_PLAYERS, List.of(players)); + } + + /** + * Creates a {@link #HIDE_PLAYERS} instruction. + * @param players Players to Hide + * @return Hide Players Instruction + */ + public static Instruction hidePlayers(@NotNull UUID... players) { + if (players == null) throw new IllegalArgumentException("Players cannot be null"); + + return new Instruction(HIDE_PLAYERS, List.of(players)); + } + // // Serialization diff --git a/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/FabricSocketMC.java b/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/FabricSocketMC.java index 74e1ad34..1c6a0268 100644 --- a/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/FabricSocketMC.java +++ b/mod/fabric/src/main/java/xyz/gmitch215/socketmc/fabric/FabricSocketMC.java @@ -16,7 +16,10 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; +import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.UUID; @Environment(EnvType.CLIENT) public final class FabricSocketMC implements SocketMC, ClientModInitializer { @@ -83,4 +86,19 @@ public void sendSocketMCEvent(int id, Map params) { public long getWindowId() { return minecraft.getWindow().getWindow(); } + + @Override + public void showPlayers(List players) { + players.forEach(minecraft.getPlayerSocialManager()::showPlayer); + } + + @Override + public void hidePlayers(List players) { + players.forEach(minecraft.getPlayerSocialManager()::hidePlayer); + } + + @Override + public Set getHiddenPlayers() { + return minecraft.getPlayerSocialManager().getHiddenPlayers(); + } } diff --git a/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/ForgeSocketMC.java b/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/ForgeSocketMC.java index 35229d47..f4a02d4f 100644 --- a/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/ForgeSocketMC.java +++ b/mod/forge/src/main/java/xyz/gmitch215/socketmc/forge/ForgeSocketMC.java @@ -11,7 +11,10 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; +import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.UUID; @Mod("socketmc") public final class ForgeSocketMC implements SocketMC { @@ -64,4 +67,19 @@ public void sendSocketMCEvent(int id, Map params) { public long getWindowId() { return minecraft.getWindow().getWindow(); } + + @Override + public void showPlayers(List players) { + players.forEach(minecraft.getPlayerSocialManager()::showPlayer); + } + + @Override + public void hidePlayers(List players) { + players.forEach(minecraft.getPlayerSocialManager()::hidePlayer); + } + + @Override + public Set getHiddenPlayers() { + return minecraft.getPlayerSocialManager().getHiddenPlayers(); + } } diff --git a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/NeoForgeSocketMC.java b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/NeoForgeSocketMC.java index f77ed972..d0896160 100644 --- a/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/NeoForgeSocketMC.java +++ b/mod/neoforge/src/main/java/xyz/gmitch215/socketmc/neoforge/NeoForgeSocketMC.java @@ -10,7 +10,10 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; +import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.UUID; @Mod("socketmc") public final class NeoForgeSocketMC implements SocketMC { @@ -60,4 +63,19 @@ public void sendSocketMCEvent(int id, Map params) { public long getWindowId() { return minecraft.getWindow().getWindow(); } + + @Override + public void showPlayers(List players) { + players.forEach(minecraft.getPlayerSocialManager()::showPlayer); + } + + @Override + public void hidePlayers(List players) { + players.forEach(minecraft.getPlayerSocialManager()::hidePlayer); + } + + @Override + public Set getHiddenPlayers() { + return minecraft.getPlayerSocialManager().getHiddenPlayers(); + } } \ No newline at end of file diff --git a/mod/shared/src/main/java/xyz/gmitch215/socketmc/SocketMC.java b/mod/shared/src/main/java/xyz/gmitch215/socketmc/SocketMC.java index d443353e..839b052c 100644 --- a/mod/shared/src/main/java/xyz/gmitch215/socketmc/SocketMC.java +++ b/mod/shared/src/main/java/xyz/gmitch215/socketmc/SocketMC.java @@ -13,9 +13,7 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; @@ -32,6 +30,12 @@ public interface SocketMC { long getWindowId(); + void showPlayers(List players); + + void hidePlayers(List players); + + Set getHiddenPlayers(); + // Static Util static void print(Throwable t) { diff --git a/mod/shared/src/main/java/xyz/gmitch215/socketmc/machines/HidePlayersMachine.java b/mod/shared/src/main/java/xyz/gmitch215/socketmc/machines/HidePlayersMachine.java new file mode 100644 index 00000000..6afc1dab --- /dev/null +++ b/mod/shared/src/main/java/xyz/gmitch215/socketmc/machines/HidePlayersMachine.java @@ -0,0 +1,22 @@ +package xyz.gmitch215.socketmc.machines; + +import org.jetbrains.annotations.NotNull; +import xyz.gmitch215.socketmc.SocketMC; +import xyz.gmitch215.socketmc.instruction.Instruction; +import xyz.gmitch215.socketmc.instruction.InstructionId; +import xyz.gmitch215.socketmc.instruction.Machine; + +import java.util.UUID; + +@InstructionId(Instruction.SHOW_PLAYERS) +public final class HidePlayersMachine implements Machine { + + public static final HidePlayersMachine MACHINE = new HidePlayersMachine(); + + private HidePlayersMachine() {} + + @Override + public void onInstruction(@NotNull Instruction instruction) throws Exception { + SocketMC.INSTANCE.get().hidePlayers(instruction.getParameters(UUID.class)); + } +} diff --git a/mod/shared/src/main/java/xyz/gmitch215/socketmc/machines/MachineFinder.java b/mod/shared/src/main/java/xyz/gmitch215/socketmc/machines/MachineFinder.java index dd89a329..c3e815f0 100644 --- a/mod/shared/src/main/java/xyz/gmitch215/socketmc/machines/MachineFinder.java +++ b/mod/shared/src/main/java/xyz/gmitch215/socketmc/machines/MachineFinder.java @@ -23,7 +23,9 @@ private MachineFinder() {} OSBeepMachine.class, ExternalPopupMachine.class, ExternalMessageMachine.class, - SetWindowTitleMachine.class + SetWindowTitleMachine.class, + ShowPlayersMachine.class, + HidePlayersMachine.class ); public static Machine getMachine(@NotNull Collection> machines, @NotNull String id) { diff --git a/mod/shared/src/main/java/xyz/gmitch215/socketmc/machines/ShowPlayersMachine.java b/mod/shared/src/main/java/xyz/gmitch215/socketmc/machines/ShowPlayersMachine.java new file mode 100644 index 00000000..f15ea924 --- /dev/null +++ b/mod/shared/src/main/java/xyz/gmitch215/socketmc/machines/ShowPlayersMachine.java @@ -0,0 +1,22 @@ +package xyz.gmitch215.socketmc.machines; + +import org.jetbrains.annotations.NotNull; +import xyz.gmitch215.socketmc.SocketMC; +import xyz.gmitch215.socketmc.instruction.Instruction; +import xyz.gmitch215.socketmc.instruction.InstructionId; +import xyz.gmitch215.socketmc.instruction.Machine; + +import java.util.UUID; + +@InstructionId(Instruction.SHOW_PLAYERS) +public final class ShowPlayersMachine implements Machine { + + public static final ShowPlayersMachine MACHINE = new ShowPlayersMachine(); + + private ShowPlayersMachine() {} + + @Override + public void onInstruction(@NotNull Instruction instruction) throws Exception { + SocketMC.INSTANCE.get().showPlayers(instruction.getParameters(UUID.class)); + } +} From 5c84fe1f2dfa0a664ffa0a9626edd0ed6f3c15b8 Mon Sep 17 00:00:00 2001 From: Gregory Mitchell <54124162+gmitch215@users.noreply.github.com> Date: Sun, 8 Sep 2024 16:38:26 -0500 Subject: [PATCH 12/16] Create `Paramaterized#getParameters(Class)` --- .../xyz/gmitch215/socketmc/util/Paramaterized.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/core/src/main/java/xyz/gmitch215/socketmc/util/Paramaterized.java b/core/src/main/java/xyz/gmitch215/socketmc/util/Paramaterized.java index 8930390c..97603232 100644 --- a/core/src/main/java/xyz/gmitch215/socketmc/util/Paramaterized.java +++ b/core/src/main/java/xyz/gmitch215/socketmc/util/Paramaterized.java @@ -18,6 +18,20 @@ public interface Paramaterized { @Unmodifiable List getParameters(); + /** + * Gets the parameters of the specified type. + * @param type The type of the parameters to get + * @return The parameters of the specified type + * @param The type of the parameters + */ + default List getParameters(@NotNull Class type) { + return getParameters() + .stream() + .filter(type::isInstance) + .map(type::cast) + .toList(); + } + /** * Gets the parameter at the specified index. * @param index The index of the parameter to get From dc5f5123a0e0d278ffdb2df4d25c1fc89788d580 Mon Sep 17 00:00:00 2001 From: Gregory Mitchell <54124162+gmitch215@users.noreply.github.com> Date: Sun, 8 Sep 2024 16:38:38 -0500 Subject: [PATCH 13/16] Create `RetrieverType#HIDDEN_PLAYERS` --- .../xyz/gmitch215/socketmc/retriever/RetrieverType.java | 6 ++++++ .../java/xyz/gmitch215/socketmc/retriever/Retriever.java | 8 +++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/xyz/gmitch215/socketmc/retriever/RetrieverType.java b/core/src/main/java/xyz/gmitch215/socketmc/retriever/RetrieverType.java index 93866349..f9499471 100644 --- a/core/src/main/java/xyz/gmitch215/socketmc/retriever/RetrieverType.java +++ b/core/src/main/java/xyz/gmitch215/socketmc/retriever/RetrieverType.java @@ -122,6 +122,12 @@ public final class RetrieverType implements Serializable { @RetrieverPermission(ModPermission.READ_GAME_PROPERTIES) public static final RetrieverType COMMAND_HISTORY = new RetrieverType<>("command_history", String[].class); + /** + * A retriever for the client's hidden players on their social interaction screen. + */ + @RetrieverPermission(ModPermission.READ_GAME_PROPERTIES) + public static final RetrieverType HIDDEN_PLAYERS = new RetrieverType<>("hidden_players", UUID[].class); + // private final String id; diff --git a/mod/shared/src/main/java/xyz/gmitch215/socketmc/retriever/Retriever.java b/mod/shared/src/main/java/xyz/gmitch215/socketmc/retriever/Retriever.java index 5f1508aa..d613d5e2 100644 --- a/mod/shared/src/main/java/xyz/gmitch215/socketmc/retriever/Retriever.java +++ b/mod/shared/src/main/java/xyz/gmitch215/socketmc/retriever/Retriever.java @@ -4,10 +4,7 @@ import xyz.gmitch215.socketmc.config.ModPermission; import xyz.gmitch215.socketmc.spigot.SocketPlugin; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.function.Supplier; @SuppressWarnings("unchecked") @@ -30,7 +27,8 @@ public final class Retriever { }), create(RetrieverType.FREE_MEMORY, Runtime.getRuntime()::freeMemory), create(RetrieverType.TOTAL_MEMORY, Runtime.getRuntime()::totalMemory), - create(RetrieverType.MAX_MEMORY, Runtime.getRuntime()::maxMemory) + create(RetrieverType.MAX_MEMORY, Runtime.getRuntime()::maxMemory), + create(RetrieverType.HIDDEN_PLAYERS, () -> SocketMC.INSTANCE.get().getHiddenPlayers().toArray(UUID[]::new)) ); // From 730210ab475ba56c3c169e9a4cd2609dd410698b Mon Sep 17 00:00:00 2001 From: Gregory Mitchell <54124162+gmitch215@users.noreply.github.com> Date: Sun, 8 Sep 2024 16:48:20 -0500 Subject: [PATCH 14/16] Add Missing Annotations --- .../java/xyz/gmitch215/socketmc/instruction/Instruction.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/main/java/xyz/gmitch215/socketmc/instruction/Instruction.java b/core/src/main/java/xyz/gmitch215/socketmc/instruction/Instruction.java index b5b9ce4d..15b04c33 100644 --- a/core/src/main/java/xyz/gmitch215/socketmc/instruction/Instruction.java +++ b/core/src/main/java/xyz/gmitch215/socketmc/instruction/Instruction.java @@ -1756,6 +1756,7 @@ public static Instruction setWindowIcon(byte[] icon) { * @param players Players to Show * @return Show Players Instruction */ + @NotNull public static Instruction showPlayers(@NotNull Iterable players) { if (players == null) throw new IllegalArgumentException("Players cannot be null"); @@ -1767,6 +1768,7 @@ public static Instruction showPlayers(@NotNull Iterable players) { * @param players Players to Show * @return Show Players Instruction */ + @NotNull public static Instruction showPlayers(@NotNull UUID... players) { if (players == null) throw new IllegalArgumentException("Players cannot be null"); @@ -1778,6 +1780,7 @@ public static Instruction showPlayers(@NotNull UUID... players) { * @param players Players to Hide * @return Hide Players Instruction */ + @NotNull public static Instruction hidePlayers(@NotNull Iterable players) { if (players == null) throw new IllegalArgumentException("Players cannot be null"); @@ -1789,6 +1792,7 @@ public static Instruction hidePlayers(@NotNull Iterable players) { * @param players Players to Hide * @return Hide Players Instruction */ + @NotNull public static Instruction hidePlayers(@NotNull UUID... players) { if (players == null) throw new IllegalArgumentException("Players cannot be null"); From 228f19fe13c80ff1defe506a973bd62e93896bd3 Mon Sep 17 00:00:00 2001 From: Gregory Mitchell <54124162+gmitch215@users.noreply.github.com> Date: Sun, 8 Sep 2024 17:02:33 -0500 Subject: [PATCH 15/16] Fix HidePlayersMachine.java --- .../xyz/gmitch215/socketmc/machines/HidePlayersMachine.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod/shared/src/main/java/xyz/gmitch215/socketmc/machines/HidePlayersMachine.java b/mod/shared/src/main/java/xyz/gmitch215/socketmc/machines/HidePlayersMachine.java index 6afc1dab..37b17bf5 100644 --- a/mod/shared/src/main/java/xyz/gmitch215/socketmc/machines/HidePlayersMachine.java +++ b/mod/shared/src/main/java/xyz/gmitch215/socketmc/machines/HidePlayersMachine.java @@ -8,7 +8,7 @@ import java.util.UUID; -@InstructionId(Instruction.SHOW_PLAYERS) +@InstructionId(Instruction.HIDE_PLAYERS) public final class HidePlayersMachine implements Machine { public static final HidePlayersMachine MACHINE = new HidePlayersMachine(); From f541b4984bc88c839999896206e23a4ccfa29756 Mon Sep 17 00:00:00 2001 From: Gregory Mitchell <54124162+gmitch215@users.noreply.github.com> Date: Sun, 8 Sep 2024 17:03:52 -0500 Subject: [PATCH 16/16] Remove Unnecessary `clean` Task --- .github/workflows/build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a9b599cd..7f5ac46b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -64,7 +64,7 @@ jobs: - name: Change Permissions run: chmod +x ./gradlew - name: Build with Gradle - run: ./gradlew clean assemble publishToMavenLocal + run: ./gradlew assemble publishToMavenLocal upload: runs-on: ubuntu-latest @@ -83,7 +83,7 @@ jobs: - name: Change Permissions run: chmod +x ./gradlew - name: Build with Gradle - run: ./gradlew clean assemble + run: ./gradlew assemble - name: Upload Artifacts uses: actions/upload-artifact@v4 with: @@ -110,7 +110,7 @@ jobs: - name: Change Permissions run: chmod +x ./gradlew - name: Build JavaDocs - run: ./gradlew clean allJavadoc + run: ./gradlew allJavadoc - name: Deploy JavaDoc run: bash javadoc.sh ${GITHUB_SHA::7} @@ -133,4 +133,4 @@ jobs: run: chmod +x ./gradlew - name: Build with Gradle run: | - ./gradlew clean publish -Psuffix=${GITHUB_SHA::7} -Purl=https://maven.pkg.github.com/gmitch215/SocketMC -Pusername=${{ secrets.GITHUB_ACTOR }} -Ppassword=${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + ./gradlew publish -Psuffix=${GITHUB_SHA::7} -Purl=https://maven.pkg.github.com/gmitch215/SocketMC -Pusername=${{ secrets.GITHUB_ACTOR }} -Ppassword=${{ secrets.GITHUB_TOKEN }} \ No newline at end of file