From 712ae97235e6bee34c0ec7a18734a55e7fa83c89 Mon Sep 17 00:00:00 2001 From: Levent Date: Thu, 12 Mar 2026 22:36:33 +0000 Subject: [PATCH 1/3] Experimental logless chat messages --- .../oyvey/ducks/render/IChatComponent.java | 9 +++++ .../oyvey/features/commands/Command.java | 15 +++++--- .../features/commands/impl/BindCommand.java | 2 +- .../features/commands/impl/HelpCommand.java | 4 +-- .../oyvey/features/modules/Module.java | 4 +-- .../modules/client/NotificationsModule.java | 2 +- .../oyvey/manager/CommandManager.java | 4 +-- .../mixin/render/MixinChatComponent.java | 32 +++++++++++++++++ .../alpha432/oyvey/util/player/ChatUtil.java | 36 +++++++++++++++---- src/main/resources/oyvey.mixins.json | 1 + 10 files changed, 90 insertions(+), 19 deletions(-) create mode 100644 src/main/java/me/alpha432/oyvey/ducks/render/IChatComponent.java create mode 100644 src/main/java/me/alpha432/oyvey/mixin/render/MixinChatComponent.java diff --git a/src/main/java/me/alpha432/oyvey/ducks/render/IChatComponent.java b/src/main/java/me/alpha432/oyvey/ducks/render/IChatComponent.java new file mode 100644 index 0000000..282475e --- /dev/null +++ b/src/main/java/me/alpha432/oyvey/ducks/render/IChatComponent.java @@ -0,0 +1,9 @@ +package me.alpha432.oyvey.ducks.render; + +import net.minecraft.client.GuiMessage; +import net.minecraft.network.chat.MessageSignature; + +public interface IChatComponent { + void oyvey$addMessage(GuiMessage message); + void oyvey$removeMessage(MessageSignature signature); +} \ No newline at end of file diff --git a/src/main/java/me/alpha432/oyvey/features/commands/Command.java b/src/main/java/me/alpha432/oyvey/features/commands/Command.java index c1cad6a..52385d1 100644 --- a/src/main/java/me/alpha432/oyvey/features/commands/Command.java +++ b/src/main/java/me/alpha432/oyvey/features/commands/Command.java @@ -25,7 +25,7 @@ public abstract class Command extends Feature { public abstract void createArgumentBuilder(LiteralArgumentBuilder builder); protected int success(String message, Object... format) { - sendMessage(message, format); + sendMessage(message, "success", format); return NO_OP; } @@ -34,7 +34,7 @@ public abstract class Command extends Feature { } protected int fail(String message, Object... format) { - sendMessage("{red} " + message, format); + sendMessage("{red} " + format, "fail"); return NO_OP; } @@ -58,11 +58,18 @@ public abstract class Command extends Feature { return true; } - public static void sendMessage(String message, Object... format) { + public static void sendMessage(String message, String identifier) { if (message == null) { return; } - ChatUtil.sendMessage(TextUtil.text(message, format)); + ChatUtil.sendMessage(TextUtil.text(message), identifier); + } + + public static void sendMessage(String message, String identifier, Object... format) { + if (message == null) { + return; + } + ChatUtil.sendMessage(TextUtil.text(message, format), identifier); } public static LiteralArgumentBuilder literal(String literal) { diff --git a/src/main/java/me/alpha432/oyvey/features/commands/impl/BindCommand.java b/src/main/java/me/alpha432/oyvey/features/commands/impl/BindCommand.java index 3d94686..aa5fe73 100644 --- a/src/main/java/me/alpha432/oyvey/features/commands/impl/BindCommand.java +++ b/src/main/java/me/alpha432/oyvey/features/commands/impl/BindCommand.java @@ -40,7 +40,7 @@ public class BindCommand extends Command { if (event.getKey() == GLFW_KEY_ESCAPE) { module = null; - sendMessage("Operation canceled."); + sendMessage("Operation canceled.", "fail"); return; } diff --git a/src/main/java/me/alpha432/oyvey/features/commands/impl/HelpCommand.java b/src/main/java/me/alpha432/oyvey/features/commands/impl/HelpCommand.java index 3ce8ac4..42376f9 100644 --- a/src/main/java/me/alpha432/oyvey/features/commands/impl/HelpCommand.java +++ b/src/main/java/me/alpha432/oyvey/features/commands/impl/HelpCommand.java @@ -66,7 +66,7 @@ public class HelpCommand extends Command { List paginated = commands.subList((pageIndex - 1) * ITEMS_PER_PAGE, Math.min(commands.size(), pageIndex * ITEMS_PER_PAGE)); - sendMessage("Commands (%s):", commands.size()); + sendMessage("Commands (%s):", "general", commands.size()); for (Command command : paginated) { StringJoiner joiner = new StringJoiner(", "); @@ -74,7 +74,7 @@ public class HelpCommand extends Command { joiner.add(alias); } - sendMessage("{dark_gray} %s: {reset}\n %s", + sendMessage("{dark_gray} %s: {reset}\n %s", "general", joiner, command.getDescription()); } diff --git a/src/main/java/me/alpha432/oyvey/features/modules/Module.java b/src/main/java/me/alpha432/oyvey/features/modules/Module.java index 69b6c1c..86c5942 100644 --- a/src/main/java/me/alpha432/oyvey/features/modules/Module.java +++ b/src/main/java/me/alpha432/oyvey/features/modules/Module.java @@ -88,11 +88,11 @@ public class Module extends Feature implements Jsonable, Toggleable { Module module = OyVey.moduleManager.getModuleByDisplayName(name); Module originalModule = OyVey.moduleManager.getModuleByName(name); if (module == null && originalModule == null) { - Command.sendMessage(this.getDisplayName() + ", name: " + this.getName() + ", has been renamed to: " + name); + Command.sendMessage(this.getDisplayName() + ", name: " + this.getName() + ", has been renamed to: " + name, "general"); this.displayName.setValue(name); return; } - Command.sendMessage("{red} A module of this name already exists."); + Command.sendMessage("{red} A module of this name already exists.", "general"); } @Override diff --git a/src/main/java/me/alpha432/oyvey/features/modules/client/NotificationsModule.java b/src/main/java/me/alpha432/oyvey/features/modules/client/NotificationsModule.java index 0352afe..cda421a 100644 --- a/src/main/java/me/alpha432/oyvey/features/modules/client/NotificationsModule.java +++ b/src/main/java/me/alpha432/oyvey/features/modules/client/NotificationsModule.java @@ -28,6 +28,6 @@ public class NotificationsModule extends Module { ChatUtil.sendMessage(TextUtil.text(MODULE_FORMAT, event.getFeature().getName(), moduleState ? "{green}" : "{red}", - moduleState ? "on" : "off")); + moduleState ? "on" : "off"), event.getFeature().getName()); } } diff --git a/src/main/java/me/alpha432/oyvey/manager/CommandManager.java b/src/main/java/me/alpha432/oyvey/manager/CommandManager.java index 569f1c1..0031130 100644 --- a/src/main/java/me/alpha432/oyvey/manager/CommandManager.java +++ b/src/main/java/me/alpha432/oyvey/manager/CommandManager.java @@ -48,9 +48,9 @@ public class CommandManager extends Feature implements Jsonable { int result = dispatcher.execute(message.substring( commandPrefix.length()).trim(), this); if (result == SINGLE_SUCCESS) { - Command.sendMessage("{green} Command executed successfully"); + Command.sendMessage("{green} Command executed successfully", "general"); } else if (result == SINGLE_FAILURE) { - Command.sendMessage("{red} Failed to execute command"); + Command.sendMessage("{red} Failed to execute command", "general"); } } catch (CommandSyntaxException e) { LOGGER.error("Failed to execute command", e); diff --git a/src/main/java/me/alpha432/oyvey/mixin/render/MixinChatComponent.java b/src/main/java/me/alpha432/oyvey/mixin/render/MixinChatComponent.java new file mode 100644 index 0000000..579013f --- /dev/null +++ b/src/main/java/me/alpha432/oyvey/mixin/render/MixinChatComponent.java @@ -0,0 +1,32 @@ +package me.alpha432.oyvey.mixin.render; + +import me.alpha432.oyvey.ducks.render.IChatComponent; +import net.minecraft.client.GuiMessage; +import net.minecraft.client.gui.components.ChatComponent; +import net.minecraft.network.chat.MessageSignature; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.List; + +@Mixin(ChatComponent.class) +public abstract class MixinChatComponent implements IChatComponent { + @Shadow + private List allMessages; + + @Shadow + private void refreshTrimmedMessages() {} + + @Override + public void oyvey$addMessage(GuiMessage message) { + this.allMessages.addFirst(message); + this.refreshTrimmedMessages(); + } + + @Override + public void oyvey$removeMessage(MessageSignature signature) { + this.allMessages.removeIf(message -> signature.equals(message.signature())); + this.refreshTrimmedMessages(); + } +} \ No newline at end of file diff --git a/src/main/java/me/alpha432/oyvey/util/player/ChatUtil.java b/src/main/java/me/alpha432/oyvey/util/player/ChatUtil.java index 2faf4f0..ee26078 100644 --- a/src/main/java/me/alpha432/oyvey/util/player/ChatUtil.java +++ b/src/main/java/me/alpha432/oyvey/util/player/ChatUtil.java @@ -1,33 +1,55 @@ package me.alpha432.oyvey.util.player; import me.alpha432.oyvey.OyVey; +import me.alpha432.oyvey.ducks.render.IChatComponent; import me.alpha432.oyvey.features.commands.Command; import net.minecraft.ChatFormatting; +import net.minecraft.client.GuiMessage; +import net.minecraft.client.GuiMessageTag; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MessageSignature; import net.minecraft.network.chat.Style; +import java.nio.charset.StandardCharsets; + import static me.alpha432.oyvey.util.traits.Util.mc; public class ChatUtil { - public static void sendMessage(Component message) { - sendSilentMessage(Component.empty() + private static final GuiMessageTag MESSAGE_TAG = new GuiMessageTag( + OyVey.colorManager.getColorAsInt(), + null, + null, + null + ); + + public static void sendMessage(Component message, String identifier) { + sendClientSideMessage(Component.empty() .setStyle(Style.EMPTY.withColor(ChatFormatting.GRAY)) .append("<") .append(getClientNameComponent()) .append(">") .append(" ") - .append(message)); + .append(message), identifier); } - public static void sendSilentMessage(Component message) { + public static void sendClientSideMessage(Component message, String identifier) { if (Command.nullCheck()) { return; } - // TODO add silent support ig - mc.gui.getChat().addMessage(message); + IChatComponent chat = (IChatComponent) mc.gui.getChat(); + MessageSignature signature = new MessageSignature(get256Bytes(identifier)); + chat.oyvey$removeMessage(signature); + chat.oyvey$addMessage(new GuiMessage(mc.gui.getGuiTicks(), message, signature, MESSAGE_TAG)); } - + public static Component getClientNameComponent() { return Component.empty().withColor(OyVey.colorManager.getColorAsInt()).append("OyVey"); } + + private static byte[] get256Bytes(String identifier) { + byte[] bytes = new byte[256]; + byte[] identifierBytes = identifier.getBytes(StandardCharsets.UTF_8); + System.arraycopy(identifierBytes, 0, bytes, 0, Math.min(bytes.length, identifierBytes.length)); + return bytes; + } } \ No newline at end of file diff --git a/src/main/resources/oyvey.mixins.json b/src/main/resources/oyvey.mixins.json index 5b20c43..fa007d6 100644 --- a/src/main/resources/oyvey.mixins.json +++ b/src/main/resources/oyvey.mixins.json @@ -11,6 +11,7 @@ "input.MixinKeyboard", "input.MixinMouse", "network.MixinClientPlayNetworkHandler", + "render.MixinChatComponent", "render.MixinLevelRenderer", "render.MixinRenderTickCounter", "render.MixinWorldRenderer", From 3f8f8cfab98cf5788e489f9a6f334fd84c2a65bd Mon Sep 17 00:00:00 2001 From: Levent Date: Tue, 24 Mar 2026 19:47:27 +0000 Subject: [PATCH 2/3] fix static initialization of GuiMessageTag to reflect dynamic color changes. --- .../alpha432/oyvey/util/player/ChatUtil.java | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/main/java/me/alpha432/oyvey/util/player/ChatUtil.java b/src/main/java/me/alpha432/oyvey/util/player/ChatUtil.java index ee26078..01964f8 100644 --- a/src/main/java/me/alpha432/oyvey/util/player/ChatUtil.java +++ b/src/main/java/me/alpha432/oyvey/util/player/ChatUtil.java @@ -15,13 +15,6 @@ import java.nio.charset.StandardCharsets; import static me.alpha432.oyvey.util.traits.Util.mc; public class ChatUtil { - private static final GuiMessageTag MESSAGE_TAG = new GuiMessageTag( - OyVey.colorManager.getColorAsInt(), - null, - null, - null - ); - public static void sendMessage(Component message, String identifier) { sendClientSideMessage(Component.empty() .setStyle(Style.EMPTY.withColor(ChatFormatting.GRAY)) @@ -33,19 +26,22 @@ public class ChatUtil { } public static void sendClientSideMessage(Component message, String identifier) { - if (Command.nullCheck()) { - return; - } + if (Command.nullCheck()) return; + IChatComponent chat = (IChatComponent) mc.gui.getChat(); MessageSignature signature = new MessageSignature(get256Bytes(identifier)); chat.oyvey$removeMessage(signature); - chat.oyvey$addMessage(new GuiMessage(mc.gui.getGuiTicks(), message, signature, MESSAGE_TAG)); + chat.oyvey$addMessage(new GuiMessage(mc.gui.getGuiTicks(), message, signature, getMessageTag())); } public static Component getClientNameComponent() { return Component.empty().withColor(OyVey.colorManager.getColorAsInt()).append("OyVey"); } + private static GuiMessageTag getMessageTag() { + return new GuiMessageTag(OyVey.colorManager.getColorAsInt(), null, null, null); + } + private static byte[] get256Bytes(String identifier) { byte[] bytes = new byte[256]; byte[] identifierBytes = identifier.getBytes(StandardCharsets.UTF_8); From c9f0df511643a89a43e95e40cb49c42a2e1075a2 Mon Sep 17 00:00:00 2001 From: Levent Date: Tue, 24 Mar 2026 19:49:54 +0000 Subject: [PATCH 3/3] replace magic string identifiers with MessageIdentifiers constants --- .../oyvey/features/commands/Command.java | 15 ++++++--------- .../features/commands/MessageIdentifiers.java | 7 +++++++ .../oyvey/manager/CommandManager.java | 19 ++++++++++--------- 3 files changed, 23 insertions(+), 18 deletions(-) create mode 100644 src/main/java/me/alpha432/oyvey/features/commands/MessageIdentifiers.java diff --git a/src/main/java/me/alpha432/oyvey/features/commands/Command.java b/src/main/java/me/alpha432/oyvey/features/commands/Command.java index 52385d1..2e271a5 100644 --- a/src/main/java/me/alpha432/oyvey/features/commands/Command.java +++ b/src/main/java/me/alpha432/oyvey/features/commands/Command.java @@ -9,6 +9,7 @@ import me.alpha432.oyvey.util.TextUtil; import me.alpha432.oyvey.util.player.ChatUtil; import static com.mojang.brigadier.Command.SINGLE_SUCCESS; +import static me.alpha432.oyvey.features.commands.MessageIdentifiers.*; public abstract class Command extends Feature { public static final int NO_OP = -1; @@ -25,7 +26,7 @@ public abstract class Command extends Feature { public abstract void createArgumentBuilder(LiteralArgumentBuilder builder); protected int success(String message, Object... format) { - sendMessage(message, "success", format); + sendMessage(message, SUCCESS, format); return NO_OP; } @@ -34,7 +35,7 @@ public abstract class Command extends Feature { } protected int fail(String message, Object... format) { - sendMessage("{red} " + format, "fail"); + sendMessage("{red} " + message, FAIL, format); return NO_OP; } @@ -59,16 +60,12 @@ public abstract class Command extends Feature { } public static void sendMessage(String message, String identifier) { - if (message == null) { - return; - } + if (message == null) return; ChatUtil.sendMessage(TextUtil.text(message), identifier); } public static void sendMessage(String message, String identifier, Object... format) { - if (message == null) { - return; - } + if (message == null) return; ChatUtil.sendMessage(TextUtil.text(message, format), identifier); } @@ -79,4 +76,4 @@ public abstract class Command extends Feature { public static RequiredArgumentBuilder argument(String name, ArgumentType type) { return RequiredArgumentBuilder.argument(name, type); } -} +} \ No newline at end of file diff --git a/src/main/java/me/alpha432/oyvey/features/commands/MessageIdentifiers.java b/src/main/java/me/alpha432/oyvey/features/commands/MessageIdentifiers.java new file mode 100644 index 0000000..0e072e4 --- /dev/null +++ b/src/main/java/me/alpha432/oyvey/features/commands/MessageIdentifiers.java @@ -0,0 +1,7 @@ +package me.alpha432.oyvey.features.commands; + +public class MessageIdentifiers { + public static final String GENERAL = "general"; + public static final String SUCCESS = "success"; + public static final String FAIL = "fail"; +} \ No newline at end of file diff --git a/src/main/java/me/alpha432/oyvey/manager/CommandManager.java b/src/main/java/me/alpha432/oyvey/manager/CommandManager.java index 0031130..a1906b1 100644 --- a/src/main/java/me/alpha432/oyvey/manager/CommandManager.java +++ b/src/main/java/me/alpha432/oyvey/manager/CommandManager.java @@ -17,6 +17,7 @@ import java.util.*; import static com.mojang.brigadier.Command.SINGLE_SUCCESS; import static me.alpha432.oyvey.features.commands.Command.SINGLE_FAILURE; +import static me.alpha432.oyvey.features.commands.MessageIdentifiers.GENERAL; public class CommandManager extends Feature implements Jsonable { private static final Logger LOGGER = LogManager.getLogger("Commands"); @@ -45,16 +46,16 @@ public class CommandManager extends Feature implements Jsonable { public void onChatSent(String message) { try { - int result = dispatcher.execute(message.substring( - commandPrefix.length()).trim(), this); + int result = dispatcher.execute(message.substring(commandPrefix.length()).trim(), this); + if (result == SINGLE_SUCCESS) { - Command.sendMessage("{green} Command executed successfully", "general"); + Command.sendMessage("{green} Command executed successfully", GENERAL); } else if (result == SINGLE_FAILURE) { - Command.sendMessage("{red} Failed to execute command", "general"); + Command.sendMessage("{red} Failed to execute command", GENERAL); } } catch (CommandSyntaxException e) { LOGGER.error("Failed to execute command", e); - Command.sendMessage("{red} %s", e.getMessage()); + Command.sendMessage("{red} %s", GENERAL, e.getMessage()); } } @@ -101,10 +102,10 @@ public class CommandManager extends Feature implements Jsonable { @Override public void fromJson(JsonElement element) { - if (element == null || !element.isJsonObject()) { - return; - } + if (element == null || !element.isJsonObject()) return; + JsonObject object = element.getAsJsonObject(); + if (object.has("prefix")) { setCommandPrefix(object.get("prefix").getAsString()); } @@ -114,4 +115,4 @@ public class CommandManager extends Feature implements Jsonable { public String getFileName() { return "commands.json"; } -} +} \ No newline at end of file