From 02faf4ca4484e577670c869719eca99cbc5a8515 Mon Sep 17 00:00:00 2001 From: crosby-moe <32882447+crosby-moe@users.noreply.github.com> Date: Wed, 28 Jan 2026 13:57:30 -0500 Subject: [PATCH 01/14] map tab names --- .../meteordevelopment/meteorclient/gui/tabs/Tab.java | 9 +++++++-- .../meteorclient/gui/tabs/TabScreen.java | 2 +- .../meteorclient/gui/tabs/WindowTabScreen.java | 2 +- .../meteorclient/gui/tabs/builtin/ConfigTab.java | 2 +- .../meteorclient/gui/tabs/builtin/FriendsTab.java | 2 +- .../meteorclient/gui/tabs/builtin/GuiTab.java | 2 +- .../meteorclient/gui/tabs/builtin/HudTab.java | 2 +- .../meteorclient/gui/tabs/builtin/MacrosTab.java | 2 +- .../meteorclient/gui/tabs/builtin/ModulesTab.java | 2 +- .../meteorclient/gui/tabs/builtin/PathManagerTab.java | 2 +- .../meteorclient/gui/tabs/builtin/ProfilesTab.java | 2 +- .../meteorclient/gui/widgets/WTopBar.java | 4 ++-- .../resources/assets/meteor-client/language/en_us.json | 9 +++++++++ 13 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/gui/tabs/Tab.java b/src/main/java/meteordevelopment/meteorclient/gui/tabs/Tab.java index f7774038a1..85c20a9dc2 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/tabs/Tab.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/tabs/Tab.java @@ -6,15 +6,16 @@ package meteordevelopment.meteorclient.gui.tabs; import meteordevelopment.meteorclient.gui.GuiTheme; +import meteordevelopment.meteorclient.utils.misc.MeteorTranslations; import net.minecraft.client.gui.screen.Screen; import static meteordevelopment.meteorclient.MeteorClient.mc; public abstract class Tab { - public final String name; + private final String translationKey; public Tab(String name) { - this.name = name; + this.translationKey = "tab." + name; } public void openScreen(GuiTheme theme) { @@ -26,4 +27,8 @@ public void openScreen(GuiTheme theme) { public abstract TabScreen createScreen(GuiTheme theme); public abstract boolean isScreen(Screen screen); + + public String getTitle() { + return MeteorTranslations.translate(this.translationKey); + } } diff --git a/src/main/java/meteordevelopment/meteorclient/gui/tabs/TabScreen.java b/src/main/java/meteordevelopment/meteorclient/gui/tabs/TabScreen.java index 56be6ba739..6994abd73e 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/tabs/TabScreen.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/tabs/TabScreen.java @@ -14,7 +14,7 @@ public abstract class TabScreen extends WidgetScreen { public final Tab tab; public TabScreen(GuiTheme theme, Tab tab) { - super(theme, tab.name); + super(theme, tab.getTitle()); this.tab = tab; } diff --git a/src/main/java/meteordevelopment/meteorclient/gui/tabs/WindowTabScreen.java b/src/main/java/meteordevelopment/meteorclient/gui/tabs/WindowTabScreen.java index b87a6894a1..a0e2ea4895 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/tabs/WindowTabScreen.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/tabs/WindowTabScreen.java @@ -16,7 +16,7 @@ public abstract class WindowTabScreen extends TabScreen { public WindowTabScreen(GuiTheme theme, Tab tab) { super(theme, tab); - window = super.add(theme.window(tab.name)).center().widget(); + window = super.add(theme.window(tab.getTitle())).center().widget(); } @Override diff --git a/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/ConfigTab.java b/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/ConfigTab.java index 55d84c1f8d..8aa01729ec 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/ConfigTab.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/ConfigTab.java @@ -17,7 +17,7 @@ public class ConfigTab extends Tab { public ConfigTab() { - super("Config"); + super("config"); } @Override diff --git a/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/FriendsTab.java b/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/FriendsTab.java index aeaec4e1ed..b96a6b72a3 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/FriendsTab.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/FriendsTab.java @@ -24,7 +24,7 @@ public class FriendsTab extends Tab { public FriendsTab() { - super("Friends"); + super("friends"); } @Override diff --git a/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/GuiTab.java b/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/GuiTab.java index 35122c6551..6a028058f7 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/GuiTab.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/GuiTab.java @@ -21,7 +21,7 @@ public class GuiTab extends Tab { public GuiTab() { - super("GUI"); + super("gui"); } @Override diff --git a/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/HudTab.java b/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/HudTab.java index 326f49b29e..7fe6a4d2a4 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/HudTab.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/HudTab.java @@ -23,7 +23,7 @@ public class HudTab extends Tab { public HudTab() { - super("HUD"); + super("hud"); } @Override diff --git a/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/MacrosTab.java b/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/MacrosTab.java index 1ba286fd59..db833d53af 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/MacrosTab.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/MacrosTab.java @@ -24,7 +24,7 @@ public class MacrosTab extends Tab { public MacrosTab() { - super("Macros"); + super("macros"); } @Override diff --git a/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/ModulesTab.java b/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/ModulesTab.java index 093bbe2683..0c51eb1ca0 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/ModulesTab.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/ModulesTab.java @@ -13,7 +13,7 @@ public class ModulesTab extends Tab { public ModulesTab() { - super("Modules"); + super("modules"); } @Override diff --git a/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/PathManagerTab.java b/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/PathManagerTab.java index d2fd0ade51..65496af04a 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/PathManagerTab.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/PathManagerTab.java @@ -15,7 +15,7 @@ public class PathManagerTab extends Tab { public PathManagerTab() { - super(PathManagers.get().getName()); + super("pathing"); } @Override diff --git a/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/ProfilesTab.java b/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/ProfilesTab.java index 680e21d48c..4140cef365 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/ProfilesTab.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/ProfilesTab.java @@ -59,7 +59,7 @@ public class ProfilesTab extends Tab { } public ProfilesTab() { - super("Profiles"); + super("profiles"); } @Override diff --git a/src/main/java/meteordevelopment/meteorclient/gui/widgets/WTopBar.java b/src/main/java/meteordevelopment/meteorclient/gui/widgets/WTopBar.java index 5e20f5a3a5..1b5d1eb59e 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/widgets/WTopBar.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/widgets/WTopBar.java @@ -44,7 +44,7 @@ public WTopBarButton(Tab tab) { protected void onCalculateSize() { double pad = pad(); - width = pad + theme.textWidth(tab.name) + pad; + width = pad + theme.textWidth(tab.getTitle()) + pad; height = pad + theme.textHeight() + pad; } @@ -67,7 +67,7 @@ protected void onRender(GuiRenderer renderer, double mouseX, double mouseY, doub Color color = getButtonColor(pressed || (mc.currentScreen instanceof TabScreen && ((TabScreen) mc.currentScreen).tab == tab), mouseOver); renderer.quad(x, y, width, height, color); - renderer.text(tab.name, x + pad, y + pad, getNameColor(), false); + renderer.text(tab.getTitle(), x + pad, y + pad, getNameColor(), false); } } } diff --git a/src/main/resources/assets/meteor-client/language/en_us.json b/src/main/resources/assets/meteor-client/language/en_us.json index bc9f17c8bd..4ff468a7c2 100644 --- a/src/main/resources/assets/meteor-client/language/en_us.json +++ b/src/main/resources/assets/meteor-client/language/en_us.json @@ -5,6 +5,15 @@ "meteor.key.open-commands": "Open Commands", "meteor.key.open-gui": "Open GUI", + "tab.config": "Config", + "tab.friends": "Friends", + "tab.gui": "GUI", + "tab.hud": "HUD", + "tab.macros": "Macros", + "tab.modules": "Modules", + "tab.pathing": "Pathing", + "tab.profiles": "Profiles", + "command.bind.description": "Binds a specified module to the next pressed key.", "command.binds.description": "List of all bound modules.", "command.commands.description": "List of all commands.", From 443422f68634896b6601b623aa969c550e3c317c Mon Sep 17 00:00:00 2001 From: crosby-moe <32882447+crosby-moe@users.noreply.github.com> Date: Wed, 28 Jan 2026 14:01:47 -0500 Subject: [PATCH 02/14] map chat feedback prefixes --- .../meteorclient/commands/Command.java | 11 ++++------ .../commands/commands/ModulesCommand.java | 2 +- .../commands/commands/ResetCommand.java | 6 +++--- .../systems/modules/Category.java | 2 +- .../meteorclient/systems/modules/Module.java | 20 +++++++++++-------- .../modules/misc/swarm/SwarmConnection.java | 8 ++++---- .../systems/modules/misc/swarm/SwarmHost.java | 8 ++++---- .../modules/misc/swarm/SwarmWorker.java | 12 +++++------ .../utils/misc/MeteorStarscript.java | 12 +++++------ .../meteorclient/utils/player/ChatUtils.java | 16 +++++++-------- .../assets/meteor-client/language/en_us.json | 4 +++- 11 files changed, 52 insertions(+), 49 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/commands/Command.java b/src/main/java/meteordevelopment/meteorclient/commands/Command.java index 0809c14978..d6381b4ff7 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/Command.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/Command.java @@ -11,7 +11,6 @@ import com.mojang.brigadier.builder.RequiredArgumentBuilder; import meteordevelopment.meteorclient.MeteorClient; import meteordevelopment.meteorclient.systems.config.Config; -import meteordevelopment.meteorclient.utils.Utils; import meteordevelopment.meteorclient.utils.misc.MeteorTranslations; import meteordevelopment.meteorclient.utils.player.ChatUtils; import net.minecraft.client.MinecraftClient; @@ -30,13 +29,11 @@ public abstract class Command { protected static final MinecraftClient mc = MeteorClient.mc; private final String name; - private final String title; private final List aliases; public final String translationKey; public Command(String name, String... aliases) { this.name = name; - this.title = Utils.nameToTitle(name); this.aliases = List.of(aliases); this.translationKey = "command." + name; } @@ -87,22 +84,22 @@ public String toString(String... args) { public void info(Text message) { ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.sendMsg(title, message); + ChatUtils.sendMsg(translationKey, message); } public void info(String message, Object... args) { ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.infoPrefix(title, MeteorTranslations.translate(translationKey + ".info." + message, message, args)); + ChatUtils.infoPrefix(translationKey, MeteorTranslations.translate(translationKey + ".info." + message, message, args)); // todo Textify body } public void warning(String message, Object... args) { ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.warningPrefix(title, MeteorTranslations.translate(translationKey + ".warning." + message, message, args)); + ChatUtils.warningPrefix(translationKey, MeteorTranslations.translate(translationKey + ".warning." + message, message, args)); // todo Textify body } public void error(String message, Object... args) { ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.errorPrefix(title, MeteorTranslations.translate(translationKey + ".error." + message, message, args)); + ChatUtils.errorPrefix(translationKey, MeteorTranslations.translate(translationKey + ".error." + message, message, args)); // todo Textify body } public MutableText translatable(String string, Object... args) { diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/ModulesCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/ModulesCommand.java index b3aaf85cf6..8910ee97fe 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/ModulesCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/ModulesCommand.java @@ -29,7 +29,7 @@ public void build(LiteralArgumentBuilder builder) { Modules.loopCategories().forEach(category -> { MutableText categoryMessage = Text.literal(""); Modules.get().getGroup(category).forEach(module -> categoryMessage.append(getModuleText(module))); - ChatUtils.sendMsg(category.getName(), categoryMessage); // todo + ChatUtils.sendMsg(category.translationKey, categoryMessage); }); return SINGLE_SUCCESS; diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/ResetCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/ResetCommand.java index d5cd90994e..a9db13805e 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/ResetCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/ResetCommand.java @@ -33,7 +33,7 @@ public void build(LiteralArgumentBuilder builder) { })) .then(literal("all").executes(context -> { Modules.get().getAll().forEach(module -> module.settings.forEach(group -> group.forEach(Setting::reset))); - ChatUtils.infoPrefix("Modules", "Reset all module settings"); + ChatUtils.infoPrefix("tab.modules", "Reset all module settings"); return SINGLE_SUCCESS; })) ).then(literal("gui").executes(context -> { @@ -52,12 +52,12 @@ public void build(LiteralArgumentBuilder builder) { })) .then(literal("all").executes(context -> { Modules.get().getAll().forEach(module -> module.keybind.reset()); - ChatUtils.infoPrefix("Modules", "Reset all binds."); + ChatUtils.infoPrefix("tab.modules", "Reset all binds."); return SINGLE_SUCCESS; })) ).then(literal("hud").executes(context -> { Hud.get().resetToDefaultElements(); - ChatUtils.infoPrefix("HUD", "Reset all elements."); + ChatUtils.infoPrefix("tab.hud", "Reset all elements."); return SINGLE_SUCCESS; })); } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/Category.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/Category.java index 69688550ab..1f5b863452 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/Category.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/Category.java @@ -11,7 +11,7 @@ public class Category { public final String name; - private final String translationKey; + public final String translationKey; public final ItemStack icon; private final int nameHash; diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/Module.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/Module.java index 9ac7b74004..444cc2f2e5 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/Module.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/Module.java @@ -124,22 +124,22 @@ public void sendToggledMsg() { public void info(Text message) { ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.sendMsg(null /* todo translatable Text */, message); + ChatUtils.sendMsg(this.getTranslationKey(), message); } public void info(String message, Object... args) { ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.infoPrefix(null /* todo translatable Text */, message, args); + ChatUtils.infoPrefix(this.getTranslationKey(), message, args); } public void warning(String message, Object... args) { ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.warningPrefix(null /* todo translatable Text */, message, args); + ChatUtils.warningPrefix(this.getTranslationKey(), message, args); } public void error(String message, Object... args) { ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.errorPrefix(null /* todo translatable Text */, message, args); + ChatUtils.errorPrefix(this.getTranslationKey(), message, args); } public boolean isActive() { @@ -150,20 +150,24 @@ public String getInfoString() { return null; } + public String getTranslationKey() { + return "module." + this.name; + } + public String getTitle() { - return MeteorTranslations.translate("module." + this.name); + return MeteorTranslations.translate(this.getTranslationKey()); } public MutableText getTitleText() { - return MeteorClient.translatable("module." + this.name); + return MeteorClient.translatable(this.getTranslationKey()); } public String getDescription() { - return MeteorTranslations.translate("module." + this.name + ".description"); + return MeteorTranslations.translate(this.getTranslationKey() + ".description"); } public MutableText getDescriptionText() { - return MeteorClient.translatable("module." + this.name + ".description"); + return MeteorClient.translatable(this.getTranslationKey() + ".description"); } @Override diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmConnection.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmConnection.java index 0ba20420bf..79f4156e7a 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmConnection.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmConnection.java @@ -22,7 +22,7 @@ public SwarmConnection(Socket socket) { @Override public void run() { - ChatUtils.infoPrefix("Swarm", "New worker connected on %s.", getIp(socket.getInetAddress().getHostAddress())); + ChatUtils.infoPrefix("module.swarm", "New worker connected on %s.", getIp(socket.getInetAddress().getHostAddress())); try { DataOutputStream out = new DataOutputStream(socket.getOutputStream()); @@ -33,7 +33,7 @@ public void run() { out.writeUTF(messageToSend); out.flush(); } catch (Exception e) { - ChatUtils.errorPrefix("Swarm", "Encountered error when sending command."); + ChatUtils.errorPrefix("module.swarm", "Encountered error when sending command."); e.printStackTrace(); } @@ -43,7 +43,7 @@ public void run() { out.close(); } catch (IOException e) { - ChatUtils.infoPrefix("Swarm", "Error creating a connection with %s on port %s.", getIp(socket.getInetAddress().getHostAddress()), socket.getPort()); + ChatUtils.infoPrefix("module.swarm", "Error creating a connection with %s on port %s.", getIp(socket.getInetAddress().getHostAddress()), socket.getPort()); e.printStackTrace(); } } @@ -55,7 +55,7 @@ public void disconnect() { e.printStackTrace(); } - ChatUtils.infoPrefix("Swarm", "Worker disconnected on ip: %s.", socket.getInetAddress().getHostAddress()); + ChatUtils.infoPrefix("module.swarm", "Worker disconnected on ip: %s.", socket.getInetAddress().getHostAddress()); interrupt(); } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmHost.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmHost.java index 6e645760a8..180c588669 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmHost.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmHost.java @@ -21,7 +21,7 @@ public SwarmHost(int port) { socket = new ServerSocket(port); } catch (IOException e) { socket = null; - ChatUtils.errorPrefix("Swarm", "Couldn't start a server on port %s.", port); + ChatUtils.errorPrefix("module.swarm", "Couldn't start a server on port %s.", port); e.printStackTrace(); } @@ -30,14 +30,14 @@ public SwarmHost(int port) { @Override public void run() { - ChatUtils.infoPrefix("Swarm", "Listening for incoming connections on port %s.", socket.getLocalPort()); + ChatUtils.infoPrefix("module.swarm", "Listening for incoming connections on port %s.", socket.getLocalPort()); while (!isInterrupted()) { try { Socket connection = socket.accept(); assignConnectionToSubServer(connection); } catch (IOException e) { - ChatUtils.errorPrefix("Swarm", "Error making a connection to worker."); + ChatUtils.errorPrefix("module.swarm", "Error making a connection to worker."); e.printStackTrace(); } } @@ -63,7 +63,7 @@ public void disconnect() { e.printStackTrace(); } - ChatUtils.infoPrefix("Swarm", "Server closed on port %s.", socket.getLocalPort()); + ChatUtils.infoPrefix("module.swarm", "Server closed on port %s.", socket.getLocalPort()); interrupt(); } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmWorker.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmWorker.java index 5f4f419217..9b3e00e8ef 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmWorker.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmWorker.java @@ -23,7 +23,7 @@ public SwarmWorker(String ip, int port) { socket = new Socket(ip, port); } catch (Exception e) { socket = null; - ChatUtils.warningPrefix("Swarm", "Server not found at %s on port %s.", ip, port); + ChatUtils.warningPrefix("module.swarm", "Server not found at %s on port %s.", ip, port); e.printStackTrace(); } @@ -32,7 +32,7 @@ public SwarmWorker(String ip, int port) { @Override public void run() { - ChatUtils.infoPrefix("Swarm", "Connected to Swarm host on at %s on port %s.", getIp(socket.getInetAddress().getHostAddress()), socket.getPort()); + ChatUtils.infoPrefix("module.swarm", "Connected to Swarm host on at %s on port %s.", getIp(socket.getInetAddress().getHostAddress()), socket.getPort()); try { DataInputStream in = new DataInputStream(socket.getInputStream()); @@ -42,12 +42,12 @@ public void run() { String read = in.readUTF(); if (read.startsWith("swarm")) { - ChatUtils.infoPrefix("Swarm", "Received command: (highlight)%s", read); + ChatUtils.infoPrefix("module.swarm", "Received command: (highlight)%s", read); try { Commands.dispatch(read); } catch (Exception e) { - ChatUtils.error("Error fetching command."); + ChatUtils.errorPrefix("module.swarm", "Error fetching command."); e.printStackTrace(); } } @@ -55,7 +55,7 @@ public void run() { in.close(); } catch (IOException e) { - ChatUtils.errorPrefix("Swarm", "Error in connection to host."); + ChatUtils.errorPrefix("module.swarm", "Error in connection to host."); e.printStackTrace(); disconnect(); } @@ -70,7 +70,7 @@ public void disconnect() { PathManagers.get().stop(); - ChatUtils.infoPrefix("Swarm", "Disconnected from host."); + ChatUtils.infoPrefix("module.swarm", "Disconnected from host."); interrupt(); } diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorStarscript.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorStarscript.java index c6abd876b9..b510f82770 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorStarscript.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorStarscript.java @@ -243,12 +243,12 @@ public static void printChatError(int i, Error error) { String caller = getCallerName(); if (caller != null) { - if (i != -1) ChatUtils.errorPrefix("Starscript", "%d, %d '%c': %s (from %s)", i, error.character, error.ch, error.message, caller); - else ChatUtils.errorPrefix("Starscript", "%d '%c': %s (from %s)", error.character, error.ch, error.message, caller); + if (i != -1) ChatUtils.errorPrefix("starscript.title", "%d, %d '%c': %s (from %s)", i, error.character, error.ch, error.message, caller); + else ChatUtils.errorPrefix("starscript.title", "%d '%c': %s (from %s)", error.character, error.ch, error.message, caller); } else { - if (i != -1) ChatUtils.errorPrefix("Starscript", "%d, %d '%c': %s", i, error.character, error.ch, error.message); - else ChatUtils.errorPrefix("Starscript", "%d '%c': %s", error.character, error.ch, error.message); + if (i != -1) ChatUtils.errorPrefix("starscript.title", "%d, %d '%c': %s", i, error.character, error.ch, error.message); + else ChatUtils.errorPrefix("starscript.title", "%d '%c': %s", error.character, error.ch, error.message); } } @@ -259,8 +259,8 @@ public static void printChatError(Error error) { public static void printChatError(StarscriptError e) { String caller = getCallerName(); - if (caller != null) ChatUtils.errorPrefix("Starscript", "%s (from %s)", e.getMessage(), caller); - else ChatUtils.errorPrefix("Starscript", "%s", e.getMessage()); + if (caller != null) ChatUtils.errorPrefix("starscript.title", "%s (from %s)", e.getMessage(), caller); + else ChatUtils.errorPrefix("starscript.title", "%s", e.getMessage()); } private static String getCallerName() { diff --git a/src/main/java/meteordevelopment/meteorclient/utils/player/ChatUtils.java b/src/main/java/meteordevelopment/meteorclient/utils/player/ChatUtils.java index c3e21511ad..d3fa35cefa 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/player/ChatUtils.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/player/ChatUtils.java @@ -140,22 +140,22 @@ public static void sendMsg(int id, Formatting color, String message, Object... a sendMsg(id, null, null, color, message, args); } - public static void sendMsg(int id, @Nullable String prefixTitle, @Nullable Formatting prefixColor, Formatting messageColor, String messageContent, Object... args) { + public static void sendMsg(int id, @Nullable String prefixKey, @Nullable Formatting prefixColor, Formatting messageColor, String messageContent, Object... args) { MutableText message = formatMsg(String.format(messageContent, args), messageColor); - sendMsg(id, prefixTitle, prefixColor, message); + sendMsg(id, prefixKey, prefixColor, message); } - public static void sendMsg(int id, @Nullable String prefixTitle, @Nullable Formatting prefixColor, String messageContent, Formatting messageColor) { + public static void sendMsg(int id, @Nullable String prefixKey, @Nullable Formatting prefixColor, String messageContent, Formatting messageColor) { MutableText message = formatMsg(messageContent, messageColor); - sendMsg(id, prefixTitle, prefixColor, message); + sendMsg(id, prefixKey, prefixColor, message); } - public static void sendMsg(int id, @Nullable String prefixTitle, @Nullable Formatting prefixColor, Text msg) { + public static void sendMsg(int id, @Nullable String prefixKey, @Nullable Formatting prefixColor, Text msg) { if (mc.world == null) return; MutableText message = Text.empty(); message.append(getPrefix()); - if (prefixTitle != null) message.append(getCustomPrefix(prefixTitle, prefixColor)); + if (prefixKey != null) message.append(getCustomPrefix(prefixKey, prefixColor)); message.append(msg); if (!Config.get().deleteChatFeedback.get()) id = 0; @@ -164,13 +164,13 @@ public static void sendMsg(int id, @Nullable String prefixTitle, @Nullable Forma mc.execute(() -> ((IChatHud) mc.inGameHud.getChatHud()).meteor$add(message, finalId)); } - private static MutableText getCustomPrefix(String prefixTitle, Formatting prefixColor) { + private static MutableText getCustomPrefix(String prefixKey, Formatting prefixColor) { MutableText prefix = Text.empty(); prefix.setStyle(prefix.getStyle().withFormatting(Formatting.GRAY)); prefix.append("["); - MutableText moduleTitle = Text.literal(prefixTitle); + MutableText moduleTitle = MeteorClient.translatable(prefixKey); moduleTitle.setStyle(moduleTitle.getStyle().withFormatting(prefixColor)); prefix.append(moduleTitle); diff --git a/src/main/resources/assets/meteor-client/language/en_us.json b/src/main/resources/assets/meteor-client/language/en_us.json index 4ff468a7c2..36626bb1d6 100644 --- a/src/main/resources/assets/meteor-client/language/en_us.json +++ b/src/main/resources/assets/meteor-client/language/en_us.json @@ -4037,5 +4037,7 @@ "module.bow-aimbot.general.nametagged": "Nametagged", "module.bow-aimbot.general.nametagged.description": "Whether or not to attack mobs with a name tag.", "module.bow-aimbot.general.pause-on-combat": "Pause On Combat", - "module.bow-aimbot.general.pause-on-combat.description": "Freezes Baritone temporarily until you released the bow." + "module.bow-aimbot.general.pause-on-combat.description": "Freezes Baritone temporarily until you released the bow.", + + "starscript.title": "Starscript" } From abf619d6f987e5bf576f23c884bd4fba7699245d Mon Sep 17 00:00:00 2001 From: crosby-moe <32882447+crosby-moe@users.noreply.github.com> Date: Wed, 28 Jan 2026 14:11:32 -0500 Subject: [PATCH 03/14] add `ChatUtils` methods with translatable content support --- .../meteorclient/commands/Command.java | 27 +++++-- .../commands/commands/BindsCommand.java | 2 +- .../commands/commands/CommandsCommand.java | 2 +- .../commands/commands/FriendsCommand.java | 6 +- .../commands/commands/ModulesCommand.java | 2 +- .../commands/commands/ResetCommand.java | 8 +-- .../commands/commands/SwarmCommand.java | 4 +- .../meteorclient/mixin/BookScreenMixin.java | 2 +- .../mixin/ClientPlayNetworkHandlerMixin.java | 3 +- .../meteorclient/systems/modules/Module.java | 29 ++++++-- .../systems/modules/misc/Notifier.java | 8 +-- .../modules/misc/swarm/SwarmConnection.java | 8 +-- .../systems/modules/misc/swarm/SwarmHost.java | 8 +-- .../modules/misc/swarm/SwarmWorker.java | 12 ++-- .../utils/misc/MeteorStarscript.java | 12 ++-- .../meteorclient/utils/player/ChatUtils.java | 71 ++++++++++++++----- 16 files changed, 135 insertions(+), 69 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/commands/Command.java b/src/main/java/meteordevelopment/meteorclient/commands/Command.java index d6381b4ff7..492c3964a9 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/Command.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/Command.java @@ -87,19 +87,34 @@ public void info(Text message) { ChatUtils.sendMsg(translationKey, message); } - public void info(String message, Object... args) { + public void info(String messageKey, Object... args) { ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.infoPrefix(translationKey, MeteorTranslations.translate(translationKey + ".info." + message, message, args)); // todo Textify body + ChatUtils.infoPrefix(translationKey, translationKey + ".info." + messageKey, args); } - public void warning(String message, Object... args) { + public void infoRaw(String message, Object... args) { ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.warningPrefix(translationKey, MeteorTranslations.translate(translationKey + ".warning." + message, message, args)); // todo Textify body + ChatUtils.infoPrefixRaw(translationKey, message, args); } - public void error(String message, Object... args) { + public void warning(String messageKey, Object... args) { ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.errorPrefix(translationKey, MeteorTranslations.translate(translationKey + ".error." + message, message, args)); // todo Textify body + ChatUtils.warningPrefix(translationKey, translationKey + ".warning." + messageKey, args); + } + + public void warningRaw(String message, Object... args) { + ChatUtils.forceNextPrefixClass(getClass()); + ChatUtils.warningPrefixRaw(translationKey, message, args); + } + + public void error(String messageKey, Object... args) { + ChatUtils.forceNextPrefixClass(getClass()); + ChatUtils.errorPrefix(translationKey, translationKey + ".error." + messageKey, args); + } + + public void errorRaw(String message, Object... args) { + ChatUtils.forceNextPrefixClass(getClass()); + ChatUtils.errorPrefixRaw(translationKey, message, args); } public MutableText translatable(String string, Object... args) { diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/BindsCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/BindsCommand.java index 76abdda30c..d1b8d42e39 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/BindsCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/BindsCommand.java @@ -31,7 +31,7 @@ public void build(LiteralArgumentBuilder builder) { .filter(module -> module.keybind.isSet()) .toList(); - ChatUtils.info("--- Bound Modules ((highlight)%d(default)) ---", modules.size()); + ChatUtils.infoRaw("--- Bound Modules ((highlight)%d(default)) ---", modules.size()); for (Module module : modules) { HoverEvent hoverEvent = new HoverEvent.ShowText(getTooltip(module)); diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/CommandsCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/CommandsCommand.java index 6f0be6c8e1..76d0876c1a 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/CommandsCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/CommandsCommand.java @@ -26,7 +26,7 @@ public CommandsCommand() { @Override public void build(LiteralArgumentBuilder builder) { builder.executes(context -> { - ChatUtils.info("--- Commands ((highlight)%d(default)) ---", Commands.COMMANDS.size()); + ChatUtils.infoRaw("--- Commands ((highlight)%d(default)) ---", Commands.COMMANDS.size()); MutableText commands = Text.literal(""); Commands.COMMANDS.forEach(command -> commands.append(getCommandText(command))); diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/FriendsCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/FriendsCommand.java index 84d12f56c6..8f2840b0bd 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/FriendsCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/FriendsCommand.java @@ -30,7 +30,7 @@ public void build(LiteralArgumentBuilder builder) { Friend friend = new Friend(profile.name(), profile.id()); if (Friends.get().add(friend)) { - ChatUtils.sendMsg(friend.hashCode(), Formatting.GRAY, "Added (highlight)%s (default)to friends.".formatted(friend.getName())); + ChatUtils.sendMsgRaw(friend.hashCode(), Formatting.GRAY, "Added (highlight)%s (default)to friends.".formatted(friend.getName())); } else error("Already friends with that player."); @@ -49,7 +49,7 @@ public void build(LiteralArgumentBuilder builder) { } if (Friends.get().remove(friend)) { - ChatUtils.sendMsg(friend.hashCode(), Formatting.GRAY, "Removed (highlight)%s (default)from friends.".formatted(friend.getName())); + ChatUtils.sendMsgRaw(friend.hashCode(), Formatting.GRAY, "Removed (highlight)%s (default)from friends.".formatted(friend.getName())); } else error("Failed to remove that friend."); @@ -60,7 +60,7 @@ public void build(LiteralArgumentBuilder builder) { builder.then(literal("list").executes(context -> { info("--- Friends ((highlight)%s(default)) ---", Friends.get().count()); - Friends.get().forEach(friend -> ChatUtils.info("(highlight)%s".formatted(friend.getName()))); + Friends.get().forEach(friend -> ChatUtils.infoRaw("(highlight)%s".formatted(friend.getName()))); return SINGLE_SUCCESS; }) ); diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/ModulesCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/ModulesCommand.java index 8910ee97fe..b6d28610c4 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/ModulesCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/ModulesCommand.java @@ -24,7 +24,7 @@ public ModulesCommand() { @Override public void build(LiteralArgumentBuilder builder) { builder.executes(context -> { - ChatUtils.info("--- Modules ((highlight)%d(default)) ---", Modules.get().getCount()); + ChatUtils.infoRaw("--- Modules ((highlight)%d(default)) ---", Modules.get().getCount()); Modules.loopCategories().forEach(category -> { MutableText categoryMessage = Text.literal(""); diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/ResetCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/ResetCommand.java index a9db13805e..88fdc78e50 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/ResetCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/ResetCommand.java @@ -33,13 +33,13 @@ public void build(LiteralArgumentBuilder builder) { })) .then(literal("all").executes(context -> { Modules.get().getAll().forEach(module -> module.settings.forEach(group -> group.forEach(Setting::reset))); - ChatUtils.infoPrefix("tab.modules", "Reset all module settings"); + ChatUtils.infoPrefixRaw("tab.modules", "Reset all module settings"); return SINGLE_SUCCESS; })) ).then(literal("gui").executes(context -> { GuiThemes.get().clearWindowConfigs(); GuiThemes.get().settings.reset(); - ChatUtils.info("Reset all GUI settings."); + ChatUtils.infoRaw("Reset all GUI settings."); return SINGLE_SUCCESS; })).then(literal("bind") .then(argument("module", ModuleArgumentType.create()).executes(context -> { @@ -52,12 +52,12 @@ public void build(LiteralArgumentBuilder builder) { })) .then(literal("all").executes(context -> { Modules.get().getAll().forEach(module -> module.keybind.reset()); - ChatUtils.infoPrefix("tab.modules", "Reset all binds."); + ChatUtils.infoPrefixRaw("tab.modules", "Reset all binds."); return SINGLE_SUCCESS; })) ).then(literal("hud").executes(context -> { Hud.get().resetToDefaultElements(); - ChatUtils.infoPrefix("tab.hud", "Reset all elements."); + ChatUtils.infoPrefixRaw("tab.hud", "Reset all elements."); return SINGLE_SUCCESS; })); } diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/SwarmCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/SwarmCommand.java index d00b57f437..cc2281657b 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/SwarmCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/SwarmCommand.java @@ -111,11 +111,11 @@ public void build(LiteralArgumentBuilder builder) { if (swarm.isActive()) { if (swarm.isHost()) { if (swarm.host.getConnectionCount() > 0) { - ChatUtils.info("--- Swarm Connections (highlight)(%s/%s)(default) ---", swarm.host.getConnectionCount(), swarm.host.getConnections().length); + ChatUtils.infoRaw("--- Swarm Connections (highlight)(%s/%s)(default) ---", swarm.host.getConnectionCount(), swarm.host.getConnections().length); for (int i = 0; i < swarm.host.getConnections().length; i++) { SwarmConnection connection = swarm.host.getConnections()[i]; - if (connection != null) ChatUtils.info("(highlight)Worker %s(default): %s.", i, connection.getConnection()); + if (connection != null) ChatUtils.infoRaw("(highlight)Worker %s(default): %s.", i, connection.getConnection()); } } else { diff --git a/src/main/java/meteordevelopment/meteorclient/mixin/BookScreenMixin.java b/src/main/java/meteordevelopment/meteorclient/mixin/BookScreenMixin.java index 4da1997a8a..1936238b0f 100644 --- a/src/main/java/meteordevelopment/meteorclient/mixin/BookScreenMixin.java +++ b/src/main/java/meteordevelopment/meteorclient/mixin/BookScreenMixin.java @@ -73,7 +73,7 @@ private void onInit(CallbackInfo info) { long size = MemoryUtil.memLengthUTF8(encoded, true); if (size > available) { - ChatUtils.error("Could not copy to clipboard: Out of memory."); + ChatUtils.errorRaw("Could not copy to clipboard: Out of memory."); } else { GLFW.glfwSetClipboardString(mc.getWindow().getHandle(), encoded); } diff --git a/src/main/java/meteordevelopment/meteorclient/mixin/ClientPlayNetworkHandlerMixin.java b/src/main/java/meteordevelopment/meteorclient/mixin/ClientPlayNetworkHandlerMixin.java index 876a80e776..3a7af0fe64 100644 --- a/src/main/java/meteordevelopment/meteorclient/mixin/ClientPlayNetworkHandlerMixin.java +++ b/src/main/java/meteordevelopment/meteorclient/mixin/ClientPlayNetworkHandlerMixin.java @@ -41,7 +41,6 @@ import net.minecraft.world.chunk.WorldChunk; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; -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; @@ -151,7 +150,7 @@ private void onSendChatMessage(String message, CallbackInfo ci, @Local(argsOnly try { Commands.dispatch(message.substring(Config.get().prefix.get().length())); } catch (CommandSyntaxException e) { - ChatUtils.error(e.getMessage()); + ChatUtils.errorRaw(e.getMessage()); } client.inGameHud.getChatHud().addToMessageHistory(message); diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/Module.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/Module.java index 444cc2f2e5..fe201d007a 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/Module.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/Module.java @@ -118,7 +118,7 @@ public void disable() { public void sendToggledMsg() { if (Config.get().chatFeedback.get() && chatFeedback) { ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.sendMsg(this.hashCode(), Formatting.GRAY, "Toggled (highlight)%s(default) %s(default).", null /* todo translatable Text */, isActive() ? Formatting.GREEN + "on" : Formatting.RED + "off"); + ChatUtils.sendMsgRaw(this.hashCode(), Formatting.GRAY, "Toggled (highlight)%s(default) %s(default).", null /* todo translatable Text */, isActive() ? Formatting.GREEN + "on" : Formatting.RED + "off"); } } @@ -127,19 +127,34 @@ public void info(Text message) { ChatUtils.sendMsg(this.getTranslationKey(), message); } - public void info(String message, Object... args) { + public void info(String messageKey, Object... args) { ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.infoPrefix(this.getTranslationKey(), message, args); + ChatUtils.infoPrefix(this.getTranslationKey(), messageKey, args); } - public void warning(String message, Object... args) { + public void infoRaw(String message, Object... args) { ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.warningPrefix(this.getTranslationKey(), message, args); + ChatUtils.infoPrefixRaw(this.getTranslationKey(), message, args); } - public void error(String message, Object... args) { + public void warning(String messageKey, Object... args) { ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.errorPrefix(this.getTranslationKey(), message, args); + ChatUtils.warningPrefix(this.getTranslationKey(), messageKey, args); + } + + public void warningRaw(String message, Object... args) { + ChatUtils.forceNextPrefixClass(getClass()); + ChatUtils.warningPrefixRaw(this.getTranslationKey(), message, args); + } + + public void error(String messageKey, Object... args) { + ChatUtils.forceNextPrefixClass(getClass()); + ChatUtils.errorPrefix(this.getTranslationKey(), messageKey, args); + } + + public void errorRaw(String message, Object... args) { + ChatUtils.forceNextPrefixClass(getClass()); + ChatUtils.errorPrefixRaw(this.getTranslationKey(), message, args); } public boolean isActive() { diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/Notifier.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/Notifier.java index a5dcf327c1..cc6dc6fd3e 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/Notifier.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/Notifier.java @@ -190,7 +190,7 @@ private void onEntityAdded(EntityAddedEvent event) { if (!event.entity.getUuid().equals(mc.player.getUuid()) && entities.get().contains(event.entity.getType()) && visualRange.get() && this.event.get() != Event.Despawn) { if (event.entity instanceof PlayerEntity) { if ((!visualRangeIgnoreFriends.get() || !Friends.get().isFriend(((PlayerEntity) event.entity))) && (!visualRangeIgnoreFakes.get() || !(event.entity instanceof FakePlayerEntity))) { - ChatUtils.sendMsg(event.entity.getId() + 100, Formatting.GRAY, "(highlight)%s(default) has entered your visual range!", event.entity.getName().getString()); + ChatUtils.sendMsgRaw(event.entity.getId() + 100, Formatting.GRAY, "(highlight)%s(default) has entered your visual range!", event.entity.getName().getString()); if (visualMakeSound.get()) mc.world.playSoundFromEntity(mc.player, mc.player, SoundEvents.ENTITY_EXPERIENCE_ORB_PICKUP, SoundCategory.AMBIENT, 3.0F, 1.0F); @@ -214,7 +214,7 @@ private void onEntityRemoved(EntityRemovedEvent event) { if (!event.entity.getUuid().equals(mc.player.getUuid()) && entities.get().contains(event.entity.getType()) && visualRange.get() && this.event.get() != Event.Spawn) { if (event.entity instanceof PlayerEntity) { if ((!visualRangeIgnoreFriends.get() || !Friends.get().isFriend(((PlayerEntity) event.entity))) && (!visualRangeIgnoreFakes.get() || !(event.entity instanceof FakePlayerEntity))) { - ChatUtils.sendMsg(event.entity.getId() + 100, Formatting.GRAY, "(highlight)%s(default) has left your visual range!", event.entity.getName().getString()); + ChatUtils.sendMsgRaw(event.entity.getId() + 100, Formatting.GRAY, "(highlight)%s(default) has left your visual range!", event.entity.getName().getString()); if (visualMakeSound.get()) mc.world.playSoundFromEntity(mc.player, mc.player, SoundEvents.ENTITY_EXPERIENCE_ORB_PICKUP, SoundCategory.AMBIENT, 3.0F, 1.0F); @@ -302,7 +302,7 @@ private void onReceivePacket(PacketEvent.Receive event) { double distance = PlayerUtils.distanceTo(entity); if (totemsDistanceCheck.get() && distance > totemsDistance.get()) return; - ChatUtils.sendMsg(getChatId(entity), Formatting.GRAY, "(highlight)%s (default)popped (highlight)%d (default)%s.", entity.getName().getString(), pops, pops == 1 ? "totem" : "totems"); + ChatUtils.sendMsgRaw(getChatId(entity), Formatting.GRAY, "(highlight)%s (default)popped (highlight)%d (default)%s.", entity.getName().getString(), pops, pops == 1 ? "totem" : "totems"); } } default -> {} @@ -331,7 +331,7 @@ private void onTick(TickEvent.Post event) { if (player.deathTime > 0 || player.getHealth() <= 0) { int pops = totemPopMap.removeInt(player.getUuid()); - ChatUtils.sendMsg(getChatId(player), Formatting.GRAY, "(highlight)%s (default)died after popping (highlight)%d (default)%s.", player.getName().getString(), pops, pops == 1 ? "totem" : "totems"); + ChatUtils.sendMsgRaw(getChatId(player), Formatting.GRAY, "(highlight)%s (default)died after popping (highlight)%d (default)%s.", player.getName().getString(), pops, pops == 1 ? "totem" : "totems"); chatIdMap.removeInt(player.getUuid()); } } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmConnection.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmConnection.java index 79f4156e7a..75e78ca881 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmConnection.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmConnection.java @@ -22,7 +22,7 @@ public SwarmConnection(Socket socket) { @Override public void run() { - ChatUtils.infoPrefix("module.swarm", "New worker connected on %s.", getIp(socket.getInetAddress().getHostAddress())); + ChatUtils.infoPrefixRaw("module.swarm", "New worker connected on %s.", getIp(socket.getInetAddress().getHostAddress())); try { DataOutputStream out = new DataOutputStream(socket.getOutputStream()); @@ -33,7 +33,7 @@ public void run() { out.writeUTF(messageToSend); out.flush(); } catch (Exception e) { - ChatUtils.errorPrefix("module.swarm", "Encountered error when sending command."); + ChatUtils.errorPrefixRaw("module.swarm", "Encountered error when sending command."); e.printStackTrace(); } @@ -43,7 +43,7 @@ public void run() { out.close(); } catch (IOException e) { - ChatUtils.infoPrefix("module.swarm", "Error creating a connection with %s on port %s.", getIp(socket.getInetAddress().getHostAddress()), socket.getPort()); + ChatUtils.infoPrefixRaw("module.swarm", "Error creating a connection with %s on port %s.", getIp(socket.getInetAddress().getHostAddress()), socket.getPort()); e.printStackTrace(); } } @@ -55,7 +55,7 @@ public void disconnect() { e.printStackTrace(); } - ChatUtils.infoPrefix("module.swarm", "Worker disconnected on ip: %s.", socket.getInetAddress().getHostAddress()); + ChatUtils.infoPrefixRaw("module.swarm", "Worker disconnected on ip: %s.", socket.getInetAddress().getHostAddress()); interrupt(); } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmHost.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmHost.java index 180c588669..89fe3a17f5 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmHost.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmHost.java @@ -21,7 +21,7 @@ public SwarmHost(int port) { socket = new ServerSocket(port); } catch (IOException e) { socket = null; - ChatUtils.errorPrefix("module.swarm", "Couldn't start a server on port %s.", port); + ChatUtils.errorPrefixRaw("module.swarm", "Couldn't start a server on port %s.", port); e.printStackTrace(); } @@ -30,14 +30,14 @@ public SwarmHost(int port) { @Override public void run() { - ChatUtils.infoPrefix("module.swarm", "Listening for incoming connections on port %s.", socket.getLocalPort()); + ChatUtils.infoPrefixRaw("module.swarm", "Listening for incoming connections on port %s.", socket.getLocalPort()); while (!isInterrupted()) { try { Socket connection = socket.accept(); assignConnectionToSubServer(connection); } catch (IOException e) { - ChatUtils.errorPrefix("module.swarm", "Error making a connection to worker."); + ChatUtils.errorPrefixRaw("module.swarm", "Error making a connection to worker."); e.printStackTrace(); } } @@ -63,7 +63,7 @@ public void disconnect() { e.printStackTrace(); } - ChatUtils.infoPrefix("module.swarm", "Server closed on port %s.", socket.getLocalPort()); + ChatUtils.infoPrefixRaw("module.swarm", "Server closed on port %s.", socket.getLocalPort()); interrupt(); } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmWorker.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmWorker.java index 9b3e00e8ef..249750cb07 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmWorker.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmWorker.java @@ -23,7 +23,7 @@ public SwarmWorker(String ip, int port) { socket = new Socket(ip, port); } catch (Exception e) { socket = null; - ChatUtils.warningPrefix("module.swarm", "Server not found at %s on port %s.", ip, port); + ChatUtils.warningPrefixRaw("module.swarm", "Server not found at %s on port %s.", ip, port); e.printStackTrace(); } @@ -32,7 +32,7 @@ public SwarmWorker(String ip, int port) { @Override public void run() { - ChatUtils.infoPrefix("module.swarm", "Connected to Swarm host on at %s on port %s.", getIp(socket.getInetAddress().getHostAddress()), socket.getPort()); + ChatUtils.infoPrefixRaw("module.swarm", "Connected to Swarm host on at %s on port %s.", getIp(socket.getInetAddress().getHostAddress()), socket.getPort()); try { DataInputStream in = new DataInputStream(socket.getInputStream()); @@ -42,12 +42,12 @@ public void run() { String read = in.readUTF(); if (read.startsWith("swarm")) { - ChatUtils.infoPrefix("module.swarm", "Received command: (highlight)%s", read); + ChatUtils.infoPrefixRaw("module.swarm", "Received command: (highlight)%s", read); try { Commands.dispatch(read); } catch (Exception e) { - ChatUtils.errorPrefix("module.swarm", "Error fetching command."); + ChatUtils.errorPrefixRaw("module.swarm", "Error fetching command."); e.printStackTrace(); } } @@ -55,7 +55,7 @@ public void run() { in.close(); } catch (IOException e) { - ChatUtils.errorPrefix("module.swarm", "Error in connection to host."); + ChatUtils.errorPrefixRaw("module.swarm", "Error in connection to host."); e.printStackTrace(); disconnect(); } @@ -70,7 +70,7 @@ public void disconnect() { PathManagers.get().stop(); - ChatUtils.infoPrefix("module.swarm", "Disconnected from host."); + ChatUtils.infoPrefixRaw("module.swarm", "Disconnected from host."); interrupt(); } diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorStarscript.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorStarscript.java index b510f82770..d521f11698 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorStarscript.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorStarscript.java @@ -243,12 +243,12 @@ public static void printChatError(int i, Error error) { String caller = getCallerName(); if (caller != null) { - if (i != -1) ChatUtils.errorPrefix("starscript.title", "%d, %d '%c': %s (from %s)", i, error.character, error.ch, error.message, caller); - else ChatUtils.errorPrefix("starscript.title", "%d '%c': %s (from %s)", error.character, error.ch, error.message, caller); + if (i != -1) ChatUtils.errorPrefixRaw("starscript.title", "%d, %d '%c': %s (from %s)", i, error.character, error.ch, error.message, caller); + else ChatUtils.errorPrefixRaw("starscript.title", "%d '%c': %s (from %s)", error.character, error.ch, error.message, caller); } else { - if (i != -1) ChatUtils.errorPrefix("starscript.title", "%d, %d '%c': %s", i, error.character, error.ch, error.message); - else ChatUtils.errorPrefix("starscript.title", "%d '%c': %s", error.character, error.ch, error.message); + if (i != -1) ChatUtils.errorPrefixRaw("starscript.title", "%d, %d '%c': %s", i, error.character, error.ch, error.message); + else ChatUtils.errorPrefixRaw("starscript.title", "%d '%c': %s", error.character, error.ch, error.message); } } @@ -259,8 +259,8 @@ public static void printChatError(Error error) { public static void printChatError(StarscriptError e) { String caller = getCallerName(); - if (caller != null) ChatUtils.errorPrefix("starscript.title", "%s (from %s)", e.getMessage(), caller); - else ChatUtils.errorPrefix("starscript.title", "%s", e.getMessage()); + if (caller != null) ChatUtils.errorPrefixRaw("starscript.title", "%s (from %s)", e.getMessage(), caller); + else ChatUtils.errorPrefixRaw("starscript.title", "%s", e.getMessage()); } private static String getCallerName() { diff --git a/src/main/java/meteordevelopment/meteorclient/utils/player/ChatUtils.java b/src/main/java/meteordevelopment/meteorclient/utils/player/ChatUtils.java index d3fa35cefa..99e82aae7c 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/player/ChatUtils.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/player/ChatUtils.java @@ -94,32 +94,56 @@ public static void sendPlayerMsg(String message, boolean addToHistory) { // Default - public static void info(String message, Object... args) { - sendMsg(Formatting.GRAY, message, args); + public static void info(String messageKey, Object... args) { + sendMsg(Formatting.GRAY, messageKey, args); } - public static void infoPrefix(String prefix, String message, Object... args) { - sendMsg(0, prefix, Formatting.LIGHT_PURPLE, Formatting.GRAY, message, args); + public static void infoRaw(String message, Object... args) { + sendMsgRaw(Formatting.GRAY, message, args); + } + + public static void infoPrefix(String prefix, String messageKey, Object... args) { + sendMsg(0, prefix, Formatting.LIGHT_PURPLE, Formatting.GRAY, messageKey, args); + } + + public static void infoPrefixRaw(String prefix, String message, Object... args) { + sendMsgRaw(0, prefix, Formatting.LIGHT_PURPLE, Formatting.GRAY, message, args); } // Warning - public static void warning(String message, Object... args) { - sendMsg(Formatting.YELLOW, message, args); + public static void warning(String messageKey, Object... args) { + sendMsg(Formatting.YELLOW, messageKey, args); + } + + public static void warningRaw(String message, Object... args) { + sendMsgRaw(Formatting.YELLOW, message, args); + } + + public static void warningPrefix(String prefix, String messageKey, Object... args) { + sendMsg(0, prefix, Formatting.LIGHT_PURPLE, Formatting.YELLOW, messageKey, args); } - public static void warningPrefix(String prefix, String message, Object... args) { - sendMsg(0, prefix, Formatting.LIGHT_PURPLE, Formatting.YELLOW, message, args); + public static void warningPrefixRaw(String prefix, String message, Object... args) { + sendMsgRaw(0, prefix, Formatting.LIGHT_PURPLE, Formatting.YELLOW, message, args); } // Error - public static void error(String message, Object... args) { - sendMsg(Formatting.RED, message, args); + public static void error(String messageKey, Object... args) { + sendMsg(Formatting.RED, messageKey, args); + } + + public static void errorRaw(String message, Object... args) { + sendMsgRaw(Formatting.RED, message, args); } - public static void errorPrefix(String prefix, String message, Object... args) { - sendMsg(0, prefix, Formatting.LIGHT_PURPLE, Formatting.RED, message, args); + public static void errorPrefix(String prefix, String messageKey, Object... args) { + sendMsg(0, prefix, Formatting.LIGHT_PURPLE, Formatting.RED, messageKey, args); + } + + public static void errorPrefixRaw(String prefix, String message, Object... args) { + sendMsgRaw(0, prefix, Formatting.LIGHT_PURPLE, Formatting.RED, message, args); } // Misc @@ -132,19 +156,32 @@ public static void sendMsg(String prefix, Text message) { sendMsg(0, prefix, Formatting.LIGHT_PURPLE, message); } - public static void sendMsg(Formatting color, String message, Object... args) { - sendMsg(0, null, null, color, message, args); + public static void sendMsg(Formatting color, String messageKey, Object... args) { + sendMsg(0, null, null, color, messageKey, args); } - public static void sendMsg(int id, Formatting color, String message, Object... args) { - sendMsg(id, null, null, color, message, args); + public static void sendMsgRaw(Formatting color, String message, Object... args) { + sendMsgRaw(0, null, null, color, message, args); } - public static void sendMsg(int id, @Nullable String prefixKey, @Nullable Formatting prefixColor, Formatting messageColor, String messageContent, Object... args) { + public static void sendMsg(int id, Formatting color, String messageKey, Object... args) { + sendMsg(id, null, null, color, messageKey, args); + } + + public static void sendMsgRaw(int id, Formatting color, String message, Object... args) { + sendMsgRaw(id, null, null, color, message, args); + } + + public static void sendMsgRaw(int id, @Nullable String prefixKey, @Nullable Formatting prefixColor, Formatting messageColor, String messageContent, Object... args) { MutableText message = formatMsg(String.format(messageContent, args), messageColor); sendMsg(id, prefixKey, prefixColor, message); } + public static void sendMsg(int id, @Nullable String prefixKey, @Nullable Formatting prefixColor, Formatting messageColor, String messageContentKey, Object... args) { + MutableText message = MeteorClient.translatable(messageContentKey, args).setStyle(Style.EMPTY.withFormatting(messageColor)); + sendMsg(id, prefixKey, prefixColor, message); + } + public static void sendMsg(int id, @Nullable String prefixKey, @Nullable Formatting prefixColor, String messageContent, Formatting messageColor) { MutableText message = formatMsg(messageContent, messageColor); sendMsg(id, prefixKey, prefixColor, message); From f85a6e72f49fdbda0cf00eb1c3efef858d624697 Mon Sep 17 00:00:00 2001 From: crosby-moe <32882447+crosby-moe@users.noreply.github.com> Date: Wed, 28 Jan 2026 14:52:29 -0500 Subject: [PATCH 04/14] support for styled `Text` arguments --- .../utils/misc/MeteorTranslations.java | 16 ++- .../text/MeteorTranslatableTextComponent.java | 123 +++++++++++++++++- 2 files changed, 126 insertions(+), 13 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java index 4424140ef7..32e312a3b9 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java @@ -110,25 +110,29 @@ public static void clearUnusedLanguages(String currentLanguageCode) { languages.keySet().removeIf(languageCode -> !languageCode.equals(EN_US_CODE) && !languageCode.equals(currentLanguageCode)); } - public static String translate(String key, Object... args) { + public static String translate(String key) { MeteorLanguage currentLang = getCurrentLanguage(); debug(currentLang, key); - String translated = currentLang.get(key, () -> getDefaultLanguage().get(key)); + return currentLang.get(key, () -> getDefaultLanguage().get(key)); + } + public static String translate(String key, Object... args) { try { - return String.format(translated, args); + return String.format(translate(key), args); } catch (IllegalFormatException e) { return key; } } - public static String translate(String key, String fallback, Object... args) { + public static String translate(String key, String fallback) { MeteorLanguage currentLang = getCurrentLanguage(); debug(currentLang, key); - String translated = currentLang.get(key, () -> getDefaultLanguage().get(key, fallback)); + return currentLang.get(key, () -> getDefaultLanguage().get(key, fallback)); + } + public static String translate(String key, String fallback, Object... args) { try { - return String.format(translated, args); + return String.format(translate(key, fallback), args); } catch (IllegalFormatException e) { return fallback; } diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MeteorTranslatableTextComponent.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MeteorTranslatableTextComponent.java index 10f568660e..6962365a3c 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MeteorTranslatableTextComponent.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MeteorTranslatableTextComponent.java @@ -5,16 +5,19 @@ package meteordevelopment.meteorclient.utils.misc.text; +import com.google.common.collect.ImmutableList; import com.mojang.serialization.MapCodec; import meteordevelopment.meteorclient.utils.misc.MeteorTranslations; -import net.minecraft.text.StringVisitable; -import net.minecraft.text.Style; -import net.minecraft.text.TextContent; +import net.minecraft.text.*; import org.jetbrains.annotations.Nullable; import java.util.Arrays; +import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.function.Consumer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import static meteordevelopment.meteorclient.MeteorClient.mc; @@ -23,14 +26,25 @@ public class MeteorTranslatableTextComponent implements TextContent { @Nullable private final String fallback; private final Object[] args; + private final boolean styledArgs; - private String translation; private String cachedLanguage; + private String translation; + private List translations = ImmutableList.of(); public MeteorTranslatableTextComponent(String key, @Nullable String fallback, Object... args) { this.key = key; this.fallback = fallback; this.args = args; + + boolean hasStyledArgs = false; + for (Object o : args) { + if (o instanceof Text) { + hasStyledArgs = true; + break; + } + } + this.styledArgs = hasStyledArgs; } public MeteorTranslatableTextComponent(String key, Object... args) { @@ -40,7 +54,19 @@ public MeteorTranslatableTextComponent(String key, Object... args) { private void updateTranslations() { if (!mc.options.language.equals(this.cachedLanguage)) { cachedLanguage = mc.options.language; - translation = fallback == null ? MeteorTranslations.translate(key, args) : MeteorTranslations.translate(key, fallback, args); + if (styledArgs) { + String template = fallback == null ? MeteorTranslations.translate(key) : MeteorTranslations.translate(key, fallback); + + try { + ImmutableList.Builder builder = ImmutableList.builder(); + this.forEachPart(template, builder::add); + this.translations = builder.build(); + } catch (TranslationException e) { + this.translations = ImmutableList.of(StringVisitable.plain(template)); + } + } else { + translation = fallback == null ? MeteorTranslations.translate(key, args) : MeteorTranslations.translate(key, fallback, args); + } } } @@ -48,14 +74,30 @@ private void updateTranslations() { public Optional visit(StringVisitable.StyledVisitor visitor, Style style) { updateTranslations(); - return visitor.accept(style, translation); + if (styledArgs) { + for (StringVisitable stringVisitable : translations) { + Optional result = stringVisitable.visit(visitor, style); + if (result.isPresent()) return result; + } + return Optional.empty(); + } else { + return visitor.accept(style, translation); + } } @Override public Optional visit(StringVisitable.Visitor visitor) { updateTranslations(); - return visitor.accept(translation); + if (styledArgs) { + for (StringVisitable stringVisitable : translations) { + Optional result = stringVisitable.visit(visitor); + if (result.isPresent()) return result; + } + return Optional.empty(); + } else { + return visitor.accept(translation); + } } @Override @@ -74,4 +116,71 @@ public boolean equals(@Nullable Object o) { public String toString() { return "MeteorTranslatableTextComponent[key=" + key + ", fallback=" + fallback + ", args=" + Arrays.toString(args) + "]"; } + + /// Bunch of bullshit from {@link net.minecraft.text.TranslatableTextContent} + private static final StringVisitable LITERAL_PERCENT_SIGN = StringVisitable.plain("%"); + private static final StringVisitable NULL_ARGUMENT = StringVisitable.plain("null"); + private static final Pattern ARG_FORMAT = Pattern.compile("%(?:(\\d+)\\$)?([A-Za-z%]|$)"); + + private void forEachPart(String translation, Consumer partsConsumer) { + Matcher matcher = ARG_FORMAT.matcher(translation); + + try { + int i = 0; + int j = 0; + + while (matcher.find(j)) { + int k = matcher.start(); + int l = matcher.end(); + if (k > j) { + String string = translation.substring(j, k); + if (string.indexOf(37) != -1) { + throw new IllegalArgumentException(); + } + + partsConsumer.accept(StringVisitable.plain(string)); + } + + String string = matcher.group(2); + String string2 = translation.substring(k, l); + if ("%".equals(string) && "%%".equals(string2)) { + partsConsumer.accept(LITERAL_PERCENT_SIGN); + } else { + if (!"s".equals(string)) { + throw new TranslationException(new TranslatableTextContent(this.key, this.fallback, this.args), "Unsupported format: '" + string2 + "'"); + } + + String string3 = matcher.group(1); + int m = string3 != null ? Integer.parseInt(string3) - 1 : i++; + partsConsumer.accept(this.getArg(m)); + } + + j = l; + } + + if (j < translation.length()) { + String string4 = translation.substring(j); + if (string4.indexOf(37) != -1) { + throw new IllegalArgumentException(); + } + + partsConsumer.accept(StringVisitable.plain(string4)); + } + } catch (IllegalArgumentException e) { + throw new TranslationException(new TranslatableTextContent(this.key, this.fallback, this.args), e); + } + } + + public final StringVisitable getArg(int index) { + if (index >= 0 && index < this.args.length) { + Object object = this.args[index]; + if (object instanceof Text text) { + return text; + } else { + return object == null ? NULL_ARGUMENT : StringVisitable.plain(object.toString()); + } + } else { + throw new TranslationException(new TranslatableTextContent(this.key, this.fallback, this.args), index); + } + } } From e7ca97f4d033b6ce297d14aaaf537fd37c17579e Mon Sep 17 00:00:00 2001 From: crosby-moe <32882447+crosby-moe@users.noreply.github.com> Date: Fri, 30 Jan 2026 08:34:19 -0500 Subject: [PATCH 05/14] map some more command names --- .../meteorclient/commands/Command.java | 5 +- .../commands/commands/BindCommand.java | 6 +- .../commands/commands/BindsCommand.java | 2 +- .../commands/commands/CommandsCommand.java | 6 +- .../commands/commands/DamageCommand.java | 3 +- .../commands/commands/DisconnectCommand.java | 2 +- .../commands/commands/DropCommand.java | 4 +- .../commands/commands/EnchantCommand.java | 4 +- .../commands/commands/FakePlayerCommand.java | 2 +- .../commands/commands/FriendsCommand.java | 12 +- .../commands/commands/GiveCommand.java | 4 +- .../commands/commands/LocateCommand.java | 107 +++++++----------- .../commands/commands/NameHistoryCommand.java | 6 +- .../assets/meteor-client/language/en_us.json | 84 +++++++++++++- 14 files changed, 157 insertions(+), 90 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/commands/Command.java b/src/main/java/meteordevelopment/meteorclient/commands/Command.java index 492c3964a9..76be9caabf 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/Command.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/Command.java @@ -11,7 +11,6 @@ import com.mojang.brigadier.builder.RequiredArgumentBuilder; import meteordevelopment.meteorclient.MeteorClient; import meteordevelopment.meteorclient.systems.config.Config; -import meteordevelopment.meteorclient.utils.misc.MeteorTranslations; import meteordevelopment.meteorclient.utils.player.ChatUtils; import net.minecraft.client.MinecraftClient; import net.minecraft.command.CommandRegistryAccess; @@ -124,4 +123,8 @@ public MutableText translatable(String string, Object... args) { public MutableText translatable(String string, String fallback, Object... args) { return MeteorClient.translatable(translationKey + "." + string, fallback, args); } + + public MutableText getTitle() { + return MeteorClient.translatable(translationKey); + } } diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/BindCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/BindCommand.java index 98302c02fd..9556c94a4f 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/BindCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/BindCommand.java @@ -10,6 +10,7 @@ import meteordevelopment.meteorclient.commands.arguments.ModuleArgumentType; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.systems.modules.Modules; +import meteordevelopment.meteorclient.utils.player.ChatUtils; import net.minecraft.command.CommandSource; public class BindCommand extends Command { @@ -23,7 +24,10 @@ public void build(LiteralArgumentBuilder builder) { Module module = context.getArgument("module", Module.class); Modules.get().setModuleToBind(module); Modules.get().awaitKeyRelease(); - module.info("Press a key to bind the module to."); + + ChatUtils.forceNextPrefixClass(module.getClass()); + ChatUtils.infoPrefix(module.getTranslationKey(), this.translationKey + ".info.press_key"); + return SINGLE_SUCCESS; })); } diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/BindsCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/BindsCommand.java index d1b8d42e39..cbf7d79a13 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/BindsCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/BindsCommand.java @@ -31,7 +31,7 @@ public void build(LiteralArgumentBuilder builder) { .filter(module -> module.keybind.isSet()) .toList(); - ChatUtils.infoRaw("--- Bound Modules ((highlight)%d(default)) ---", modules.size()); + ChatUtils.info(translationKey + ".info.bound_modules", modules.size()); for (Module module : modules) { HoverEvent hoverEvent = new HoverEvent.ShowText(getTooltip(module)); diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/CommandsCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/CommandsCommand.java index 76d0876c1a..ae3a44a070 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/CommandsCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/CommandsCommand.java @@ -26,7 +26,7 @@ public CommandsCommand() { @Override public void build(LiteralArgumentBuilder builder) { builder.executes(context -> { - ChatUtils.infoRaw("--- Commands ((highlight)%d(default)) ---", Commands.COMMANDS.size()); + ChatUtils.info(translationKey + ".info.commands", Commands.COMMANDS.size()); MutableText commands = Text.literal(""); Commands.COMMANDS.forEach(command -> commands.append(getCommandText(command))); @@ -40,7 +40,7 @@ private MutableText getCommandText(Command command) { // Hover tooltip MutableText tooltip = Text.literal(""); - tooltip.append(Text.literal(Utils.nameToTitle(command.getName())).formatted(Formatting.BLUE, Formatting.BOLD)).append("\n"); + tooltip.append(command.getTitle().formatted(Formatting.BLUE, Formatting.BOLD)).append("\n"); MutableText aliases = Text.literal(Config.get().prefix.get() + command.getName()); if (!command.getAliases().isEmpty()) { @@ -56,7 +56,7 @@ private MutableText getCommandText(Command command) { tooltip.append(command.translatable("description")).formatted(Formatting.WHITE); // Text - MutableText text = Text.literal(Utils.nameToTitle(command.getName())); + MutableText text = command.getTitle(); if (command != Commands.COMMANDS.getLast()) text.append(Text.literal(", ").formatted(Formatting.GRAY)); text.setStyle(text diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/DamageCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/DamageCommand.java index 653f411b9e..005acc0d27 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/DamageCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/DamageCommand.java @@ -8,6 +8,7 @@ import com.mojang.brigadier.arguments.IntegerArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; +import meteordevelopment.meteorclient.MeteorClient; import meteordevelopment.meteorclient.commands.Command; import meteordevelopment.meteorclient.systems.modules.Modules; import meteordevelopment.meteorclient.systems.modules.movement.NoFall; @@ -18,7 +19,7 @@ import net.minecraft.util.math.Vec3d; public class DamageCommand extends Command { - private final static SimpleCommandExceptionType INVULNERABLE = new SimpleCommandExceptionType(Text.literal("You are invulnerable.")); + private final static SimpleCommandExceptionType INVULNERABLE = new SimpleCommandExceptionType(MeteorClient.translatable("command.damage.exception.invulnerable")); public DamageCommand() { super("damage", "dmg"); diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/DisconnectCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/DisconnectCommand.java index 2cfa733b92..56d3244f20 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/DisconnectCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/DisconnectCommand.java @@ -21,7 +21,7 @@ public DisconnectCommand() { @Override public void build(LiteralArgumentBuilder builder) { builder.executes(context -> { - mc.player.networkHandler.onDisconnect(new DisconnectS2CPacket(translatable("disconnection_message", Formatting.GRAY, Formatting.BLUE, Formatting.GRAY))); + mc.player.networkHandler.onDisconnect(new DisconnectS2CPacket(translatable("disconnection_message", this.getTitle().formatted(Formatting.BLUE)).formatted(Formatting.GRAY))); return SINGLE_SUCCESS; }); diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/DropCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/DropCommand.java index e03c181216..1dc16bf880 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/DropCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/DropCommand.java @@ -22,8 +22,8 @@ import net.minecraft.item.Items; public class DropCommand extends Command { - private static final SimpleCommandExceptionType NOT_SPECTATOR = new SimpleCommandExceptionType(MeteorClient.translatable("meteor.command.drop.exception.not_spectator")); - private static final SimpleCommandExceptionType NO_SUCH_ITEM = new SimpleCommandExceptionType(MeteorClient.translatable("meteor.command.drop.exception.no_such_item")); + private static final SimpleCommandExceptionType NOT_SPECTATOR = new SimpleCommandExceptionType(MeteorClient.translatable("command.drop.exception.not_spectator")); + private static final SimpleCommandExceptionType NO_SUCH_ITEM = new SimpleCommandExceptionType(MeteorClient.translatable("command.drop.exception.no_such_item")); public DropCommand() { super("drop"); diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/EnchantCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/EnchantCommand.java index d9dc46cb3c..b00a5e91a2 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/EnchantCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/EnchantCommand.java @@ -24,8 +24,8 @@ import java.util.function.ToIntFunction; public class EnchantCommand extends Command { - private static final SimpleCommandExceptionType NOT_IN_CREATIVE = new SimpleCommandExceptionType(MeteorClient.translatable("meteor.command.enchant.exception.not_in_creative")); - private static final SimpleCommandExceptionType NOT_HOLDING_ITEM = new SimpleCommandExceptionType(MeteorClient.translatable("meteor.command.enchant.exception.not_holding_item")); + private static final SimpleCommandExceptionType NOT_IN_CREATIVE = new SimpleCommandExceptionType(MeteorClient.translatable("command.enchant.exception.not_in_creative")); + private static final SimpleCommandExceptionType NOT_HOLDING_ITEM = new SimpleCommandExceptionType(MeteorClient.translatable("command.enchant.exception.not_holding_item")); public EnchantCommand() { super("enchant"); diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/FakePlayerCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/FakePlayerCommand.java index 09dd5e3797..5418679c0d 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/FakePlayerCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/FakePlayerCommand.java @@ -63,7 +63,7 @@ public void build(LiteralArgumentBuilder builder) { builder.then(literal("list") .executes(context -> { - info("--- Fake Players ((highlight)%s(default)) ---", FakePlayerManager.count()); + info("fake_players", FakePlayerManager.count()); FakePlayerManager.forEach(fp -> info("(highlight)%s".formatted(fp.getName().getString()))); return SINGLE_SUCCESS; }) diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/FriendsCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/FriendsCommand.java index 8f2840b0bd..8660c3bba5 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/FriendsCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/FriendsCommand.java @@ -30,9 +30,9 @@ public void build(LiteralArgumentBuilder builder) { Friend friend = new Friend(profile.name(), profile.id()); if (Friends.get().add(friend)) { - ChatUtils.sendMsgRaw(friend.hashCode(), Formatting.GRAY, "Added (highlight)%s (default)to friends.".formatted(friend.getName())); + ChatUtils.sendMsg(friend.hashCode(), Formatting.GRAY, translationKey + ".info.added", friend.getName()); } - else error("Already friends with that player."); + else error("already_friends"); return SINGLE_SUCCESS; }) @@ -44,14 +44,14 @@ public void build(LiteralArgumentBuilder builder) { .executes(context -> { Friend friend = FriendArgumentType.get(context); if (friend == null) { - error("Not friends with that player."); + error("not_friends"); return SINGLE_SUCCESS; } if (Friends.get().remove(friend)) { - ChatUtils.sendMsgRaw(friend.hashCode(), Formatting.GRAY, "Removed (highlight)%s (default)from friends.".formatted(friend.getName())); + ChatUtils.sendMsg(friend.hashCode(), Formatting.GRAY, translationKey + ".info.removed", friend.getName()); } - else error("Failed to remove that friend."); + else error("failed"); return SINGLE_SUCCESS; }) @@ -59,7 +59,7 @@ public void build(LiteralArgumentBuilder builder) { ); builder.then(literal("list").executes(context -> { - info("--- Friends ((highlight)%s(default)) ---", Friends.get().count()); + info("friends", Friends.get().count()); Friends.get().forEach(friend -> ChatUtils.infoRaw("(highlight)%s".formatted(friend.getName()))); return SINGLE_SUCCESS; }) diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/GiveCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/GiveCommand.java index 83b4e8bc12..4cf2d1c3bb 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/GiveCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/GiveCommand.java @@ -19,8 +19,8 @@ import net.minecraft.network.packet.c2s.play.CreativeInventoryActionC2SPacket; public class GiveCommand extends Command { - private final static SimpleCommandExceptionType NOT_IN_CREATIVE = new SimpleCommandExceptionType(MeteorClient.translatable("meteor.command.give.exception.not_in_creative")); - private final static SimpleCommandExceptionType NO_SPACE = new SimpleCommandExceptionType(MeteorClient.translatable("meteor.command.give.exception.no_space")); + private final static SimpleCommandExceptionType NOT_IN_CREATIVE = new SimpleCommandExceptionType(MeteorClient.translatable("command.give.exception.not_in_creative")); + private final static SimpleCommandExceptionType NO_SPACE = new SimpleCommandExceptionType(MeteorClient.translatable("command.give.exception.no_space")); public GiveCommand() { super("give"); diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/LocateCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/LocateCommand.java index 32062c3935..da75d98264 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/LocateCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/LocateCommand.java @@ -79,28 +79,25 @@ public void build(LiteralArgumentBuilder builder) { if (stack.getItem() != Items.FILLED_MAP || stack.get(DataComponentTypes.ITEM_NAME) == null || !stack.get(DataComponentTypes.ITEM_NAME).getString().equals(Text.translatable("filled_map.buried_treasure").getString())) { - error("You need to hold a (highlight)buried treasure map(default)!"); + error("no_buried_treasure_map"); return SINGLE_SUCCESS; } MapDecorationsComponent mapDecorationsComponent = stack.get(DataComponentTypes.MAP_DECORATIONS); if (mapDecorationsComponent == null) { - error("Couldn't locate the map icons!"); + error("no_map_icons"); return SINGLE_SUCCESS; } for (MapDecorationsComponent.Decoration decoration : mapDecorationsComponent.decorations().values()) { if (decoration.type().value().assetId().toString().equals("minecraft:red_x")) { Vec3d coords = new Vec3d(decoration.x(), 62, decoration.z()); - MutableText text = Text.literal("Buried Treasure located at "); - text.append(ChatUtils.formatCoords(coords)); - text.append("."); - info(text); + info("buried_treasure", ChatUtils.formatCoords(coords)); return SINGLE_SUCCESS; } } - error("Couldn't locate the buried treasure!"); + error("cant_locate_buried_treasure"); return SINGLE_SUCCESS; })); @@ -109,28 +106,25 @@ public void build(LiteralArgumentBuilder builder) { if (stack.getItem() != Items.FILLED_MAP || stack.get(DataComponentTypes.ITEM_NAME) == null || !stack.get(DataComponentTypes.ITEM_NAME).getString().equals(Text.translatable("filled_map.mansion").getString())) { - error("You need to hold a (highlight)woodland explorer map(default)!"); + error("no_woodland_explorer_map"); return SINGLE_SUCCESS; } MapDecorationsComponent mapDecorationsComponent = stack.get(DataComponentTypes.MAP_DECORATIONS); if (mapDecorationsComponent == null) { - error("Couldn't locate the map icons!"); + error("no_map_icons"); return SINGLE_SUCCESS; } for (MapDecorationsComponent.Decoration decoration : mapDecorationsComponent.decorations().values()) { if (decoration.type().value().assetId().toString().equals("minecraft:woodland_mansion")) { Vec3d coords = new Vec3d(decoration.x(), 62, decoration.z()); - MutableText text = Text.literal("Mansion located at "); - text.append(ChatUtils.formatCoords(coords)); - text.append("."); - info(text); + info("mansion", ChatUtils.formatCoords(coords)); return SINGLE_SUCCESS; } } - error("Couldn't locate the mansion!"); + error("cant_locate_mansion"); return SINGLE_SUCCESS; })); @@ -142,22 +136,19 @@ public void build(LiteralArgumentBuilder builder) { MapDecorationsComponent mapDecorationsComponent = stack.get(DataComponentTypes.MAP_DECORATIONS); if (mapDecorationsComponent == null) { - error("Couldn't locate the map icons!"); + error("no_map_icons"); return SINGLE_SUCCESS; } for (MapDecorationsComponent.Decoration decoration : mapDecorationsComponent.decorations().values()) { if (decoration.type().value().assetId().toString().equals("minecraft:ocean_monument")) { Vec3d coords = new Vec3d(decoration.x(), 62, decoration.z()); - MutableText text = Text.literal("Monument located at "); - text.append(ChatUtils.formatCoords(coords)); - text.append("."); - info(text); + info("monument", ChatUtils.formatCoords(coords)); return SINGLE_SUCCESS; } } - error("Couldn't locate the monument!"); + error("cant_locate_monument"); return SINGLE_SUCCESS; } @@ -165,17 +156,14 @@ public void build(LiteralArgumentBuilder builder) { if (BaritoneUtils.IS_AVAILABLE) { Vec3d coords = findByBlockList(monumentBlocks); if (coords == null) { - error("No monument found. Try using an (highlight)ocean explorer map(default) for more success."); + error("no_monument_found"); return SINGLE_SUCCESS; } - MutableText text = Text.literal("Monument located at "); - text.append(ChatUtils.formatCoords(coords)); - text.append("."); - info(text); + info("monument", ChatUtils.formatCoords(coords)); return SINGLE_SUCCESS; } - error("Locating this structure without an (highlight)ocean explorer map(default) requires Baritone."); + error("ocean_explorer_no_baritone"); return SINGLE_SUCCESS; })); @@ -189,19 +177,16 @@ public void build(LiteralArgumentBuilder builder) { secondStart = null; secondEnd = null; MeteorClient.EVENT_BUS.subscribe(this); - info("Please throw the first Eye of Ender"); + info("first_eye"); } else if (BaritoneUtils.IS_AVAILABLE) { Vec3d coords = findByBlockList(strongholdBlocks); if (coords == null) { - error("No stronghold found nearby. You can use (highlight)Ender Eyes(default) for more success."); + error("no_stronghold_found"); return SINGLE_SUCCESS; } - MutableText text = Text.literal("Stronghold located at "); - text.append(ChatUtils.formatCoords(coords)); - text.append("."); - info(text); + info("stronghold", ChatUtils.formatCoords(coords)); } else { - error("No Eyes of Ender found in hotbar."); + error("no_eyes_of_ender"); } return SINGLE_SUCCESS; @@ -211,24 +196,22 @@ public void build(LiteralArgumentBuilder builder) { builder.then(literal("nether_fortress").executes(s -> { if (mc.world.getRegistryKey() != World.NETHER) { - error("You need to be in the nether to locate a nether fortress."); + error("not_in_nether"); return SINGLE_SUCCESS; } if (!BaritoneUtils.IS_AVAILABLE) { - error("Locating this structure requires Baritone."); + error("no_baritone"); return SINGLE_SUCCESS; } Vec3d coords = findByBlockList(netherFortressBlocks); if (coords == null) { - error("No nether fortress found."); + error("cant_locate_nether_fortress"); return SINGLE_SUCCESS; } - MutableText text = Text.literal("Fortress located at "); - text.append(ChatUtils.formatCoords(coords)); - text.append("."); - info(text); + + info("nether_fortress", ChatUtils.formatCoords(coords)); return SINGLE_SUCCESS; })); @@ -236,24 +219,22 @@ public void build(LiteralArgumentBuilder builder) { builder.then(literal("end_city").executes(s -> { if (mc.world.getRegistryKey() != World.END) { - error("You need to be in the end to locate an end city."); + error("not_in_end"); return SINGLE_SUCCESS; } if (!BaritoneUtils.IS_AVAILABLE) { - error("Locating this structure requires Baritone."); + error("no_baritone"); return SINGLE_SUCCESS; } Vec3d coords = findByBlockList(endCityBlocks); if (coords == null) { - error("No end city found."); + error("cant_locate_end_city"); return SINGLE_SUCCESS; } - MutableText text = Text.literal("End city located at "); - text.append(ChatUtils.formatCoords(coords)); - text.append("."); - info(text); + + info("end_city", ChatUtils.formatCoords(coords)); return SINGLE_SUCCESS; })); @@ -262,30 +243,28 @@ public void build(LiteralArgumentBuilder builder) { builder.then(literal("lodestone").executes(s -> { ItemStack stack = mc.player.getInventory().getSelectedStack(); if (stack.getItem() != Items.COMPASS) { - error("You need to hold a (highlight)lodestone(default) compass!"); + error("no_lodestone_compass"); return SINGLE_SUCCESS; } ComponentMap components = stack.getComponents(); if (components == null) { - error("Couldn't get the components data. Are you holding a (highlight)lodestone(default) compass?"); + error("no_lodestone_compass_data"); return SINGLE_SUCCESS; } LodestoneTrackerComponent lodestoneTrackerComponent = components.get(DataComponentTypes.LODESTONE_TRACKER); if (lodestoneTrackerComponent == null) { - error("Couldn't get the components data. Are you holding a (highlight)lodestone(default) compass?"); + error("no_lodestone_compass_data"); return SINGLE_SUCCESS; } if (lodestoneTrackerComponent.target().isEmpty()) { - error("Couldn't get the lodestone's target!"); + error("no_lodestone"); return SINGLE_SUCCESS; } Vec3d coords = Vec3d.of(lodestoneTrackerComponent.target().get().pos()); - MutableText text = Text.literal("Lodestone located at "); - text.append(ChatUtils.formatCoords(coords)); - text.append("."); - info(text); + + info("lodestone", ChatUtils.formatCoords(coords)); return SINGLE_SUCCESS; })); @@ -296,7 +275,7 @@ public void build(LiteralArgumentBuilder builder) { } private void cancel() { - warning("Locate canceled"); + warning("canceled"); MeteorClient.EVENT_BUS.unsubscribe(this); } @@ -306,7 +285,7 @@ private void cancel() { return null; } if (posList.size() < 3) { - warning("Only %d block(s) found. This search might be a false positive.", posList.size()); + warning("false_positive", posList.size()); } return new Vec3d(posList.getFirst().getX(), posList.getFirst().getY(), posList.getFirst().getZ()); } @@ -335,11 +314,11 @@ private void firstPosition(double x, double y, double z) { } private void lastPosition(double x, double y, double z) { - info("%s Eye of Ender's trajectory saved.", (this.firstEnd == null) ? "First" : "Second"); + info(this.firstEnd == null ? "first_eye_saved" : "second_eye_saved"); Vec3d pos = new Vec3d(x, y, z); if (this.firstEnd == null) { this.firstEnd = pos; - info("Please throw the second Eye Of Ender from a different location."); + info("eye_different_location"); } else { this.secondEnd = pos; findStronghold(); @@ -350,7 +329,7 @@ private void findStronghold() { PathManagers.get().stop(); if (this.firstStart == null || this.firstEnd == null || this.secondStart == null || this.secondEnd == null) { - error("Missing position data"); + error("missing_position_data"); cancel(); return; } @@ -359,17 +338,15 @@ private void findStronghold() { final double[] end = new double[]{this.firstStart.x, this.firstStart.z, this.firstEnd.x, this.firstEnd.z}; final double[] intersection = calcIntersection(start, end); if (Double.isNaN(intersection[0]) || Double.isNaN(intersection[1]) || Double.isInfinite(intersection[0]) || Double.isInfinite(intersection[1])) { - error("Unable to calculate intersection."); + error("unable_to_calculate"); cancel(); return; } MeteorClient.EVENT_BUS.unsubscribe(this); Vec3d coords = new Vec3d(intersection[0], 0, intersection[1]); - MutableText text = Text.literal("Stronghold roughly located at "); - text.append(ChatUtils.formatCoords(coords)); - text.append("."); - info(text); + + info("stronghold", ChatUtils.formatCoords(coords)); } private double[] calcIntersection(double[] line, double[] line2) { diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/NameHistoryCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/NameHistoryCommand.java index ba5b8aea0c..306cd7fb74 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/NameHistoryCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/NameHistoryCommand.java @@ -60,20 +60,20 @@ public void build(LiteralArgumentBuilder builder) { ) ) .withHoverEvent(new HoverEvent.ShowText( - Text.literal("View on laby.net") + Text.literal("View on laby.net") // todo map .formatted(Formatting.YELLOW) .formatted(Formatting.ITALIC) )) ); - info(initial.append(Text.literal(" Username History:").formatted(Formatting.GRAY))); + info(initial.append(Text.literal(" Username History:").formatted(Formatting.GRAY))); // todo map for (Name entry : history.username_history) { MutableText nameText = Text.literal(entry.name); nameText.formatted(Formatting.AQUA); if (entry.changed_at != null && entry.changed_at.getTime() != 0) { - MutableText changed = Text.literal("Changed at: "); + MutableText changed = Text.literal("Changed at: "); // todo map changed.formatted(Formatting.GRAY); DateFormat formatter = new SimpleDateFormat("hh:mm:ss, dd/MM/yyyy"); diff --git a/src/main/resources/assets/meteor-client/language/en_us.json b/src/main/resources/assets/meteor-client/language/en_us.json index 36626bb1d6..a65ec99c1a 100644 --- a/src/main/resources/assets/meteor-client/language/en_us.json +++ b/src/main/resources/assets/meteor-client/language/en_us.json @@ -14,30 +14,57 @@ "tab.pathing": "Pathing", "tab.profiles": "Profiles", + "command.bind": "Bind", "command.bind.description": "Binds a specified module to the next pressed key.", + "command.bind.info.press_key": "Press a key to bind the module to.", + "command.binds": "Binds", "command.binds.description": "List of all bound modules.", + "command.binds.info.bound_modules": "--- Bound Modules ((highlight)%s(default)) ---", + "command.commands": "Commands", "command.commands.description": "List of all commands.", + "command.commands.info.commands": "--- Commands ((highlight)%s(default)) ----", + "command.damage": "Damage", "command.damage.description": "Damages self.", + "command.damage.exception.invulnerable": "You are invulnerable.", + "command.disconnect": "Disconnect", "command.disconnect.description": "Disconnect from the server", - "command.disconnect.disconnection_message": "%s[%sDisconnectCommand%s] Disconnected by user.", + "command.disconnect.disconnection_message": "[%1$s] Disconnected by user.", + "command.dismount": "Dismount", "command.dismount.description": "Dismounts you from entity you are riding.", + "command.drop": "Drop", "command.drop.description": "Automatically drops specified items.", "command.drop.exception.no_such_item": "Could not find an item with that name!", "command.drop.exception.not_spectator": "Can't drop items while in spectator.", + "command.enchant": "Enchant", "command.enchant.description": "Enchants the item in your hand. REQUIRES Creative mode.", "command.enchant.exception.not_holding_item": "You need to hold some item to enchant.", "command.enchant.exception.not_in_creative": "You must be in creative mode to use this.", + "command.ender-chest": "Ender Chest", "command.ender-chest.description": "Allows you to preview memory of your ender chest.", + "command.fake-player": "Fake Player", "command.fake-player.description": "Manages fake players that you can use for testing.", "command.fake-player.error.not_found": "Couldn't find a Fake Player with that name.", "command.fake-player.info.removed": "Removed Fake Player %s.", + "command.fake-player.info.fake_players": "--- Fake Players ((highlight)%s(default)) ---", + "command.fov": "FOV", "command.fov.description": "Changes your fov.", + "command.friends": "Friends", "command.friends.description": "Manages friends.", + "command.friends.error.already_friends": "Already friends with that player.", + "command.friends.error.failed": "Failed to remove that friend.", + "command.friends.error.not_friends": "Not friends with that player.", + "command.friends.info.added": "Added %s to friends.", + "command.friends.info.removed": "Removed %s from friends.", + "command.friends.info.friends": "--- Friends ((highlight)%s(default)) ---", + "command.gamemode": "Gamemode", "command.gamemode.description": "Changes your gamemode client-side.", + "command.give": "Give", "command.give.description": "Gives you any item.", "command.give.exception.not_in_creative": "You must be in creative mode to use this.", "command.give.exception.no_space": "No space in hotbar.", + "command.hclip": "H-Clip", "command.hclip.description": "Lets you clip through blocks horizontally.", + "command.input": "Input", "command.input.description": "Keyboard input simulation.", "command.input.info.cleared_handlers": "Cleared all keypress handlers.", "command.input.info.active_handlers": "Active keypress handlers: ", @@ -45,42 +72,97 @@ "command.input.info.removed_handler": "Removed keypress handler.", "command.input.warning.no_handlers": "No active keypress handlers.", "command.input.warning.out_of_range": "Index out of range.", + "command.inventory": "Inventory", "command.inventory.description": "Allows you to see parts of another player's inventory.", + "command.locate": "Locate", "command.locate.description": "Locates structures", + "command.locate.error.no_map_icons": "Couldn't locate the map icons!", + "command.locate.error.no_buried_treasure_map": "You need to hold a (highlight)buried treasure map(default)!", + "command.locate.error.cant_locate_buried_treasure": "Couldn't locate the buried treasure!", + "command.locate.error.no_woodland_explorer_map": "You need to hold a (highlight)woodland explorer map(default)!", + "command.locate.error.cant_locate_mansion": "Couldn't locate the mansion!", + "command.locate.error.cant_locate_monument": "Couldn't locate the monument!", + "command.locate.error.no_monument_found": "No monument found. Try using an (highlight)ocean explorer map(default) for more success.", + "command.locate.error.ocean_explorer_no_baritone": "Locating this structure without an (highlight)ocean explorer map(default) requires Baritone.", + "command.locate.error.no_stronghold_found": "No stronghold found nearby. You can use (highlight)Ender Eyes(default) for more success.", + "command.locate.error.no_eyes_of_ender": "No Eyes of Ender found in hotbar.", + "command.locate.error.not_in_nether": "You need to be in the nether to locate a nether fortress.", + "command.locate.error.no_baritone": "Locating this structure requires Baritone.", + "command.locate.error.cant_locate_nether_fortress": "No nether fortress found.", + "command.locate.error.not_in_end": "You need to be in the end to locate an end city.", + "command.locate.error.cant_locate_end_city": "No end city found.", + "command.locate.error.no_lodestone_compass": "You need to hold a (highlight)lodestone(default) compass!", + "command.locate.error.no_lodestone_compass_data": "Couldn't get the components data. Are you holding a (highlight)lodestone(default) compass?", + "command.locate.error.no_lodestone": "Couldn't get the lodestone's target!", + "command.locate.error.missing_position_data": "Missing position data", + "command.locate.error.unable_to_calculate": "Unable to calculate intersection.", + "command.locate.info.buried_treasure": "Buried Treasure located at %1$s.", + "command.locate.info.mansion": "Mansion located at %1$s.", + "command.locate.info.monument": "Monument located at %1$s.", + "command.locate.info.first_eye": "Please throw the first Eye of Ender.", + "command.locate.info.stronghold": "Stronghold located at %1$s.", + "command.locate.info.nether_fortress": "Fortress located at %1$s.", + "command.locate.info.end_city": "End city located at %1$s.", + "command.locate.info.lodestone": "Lodestone located at %1$s.", + "command.locate.info.first_eye_saved": "First Eye of Ender's trajectory saved.", + "command.locate.info.second_eye_saved": "Second Eye of Ender's trajectory saved.", + "command.locate.info.eye_different_location": "Please throw the second Eye Of Ender from a different location.", + "command.locate.warning.canceled": "Locate canceled", + "command.locate.warning.false_positive": "Only %d block(s) found. This search might be a false positive.", + "command.macro": "Macro", "command.macro.description": "Allows you to execute macros.", "command.macro.error.none_scheduled": "No macros are currently scheduled.", "command.macro.error.not_scheduled": "This macro is not currently scheduled.", "command.macro.info.cleared_all": "Cleared all scheduled macros.", "command.macro.info.cleared": "Cleared scheduled macro.", + "command.modules": "Modules", "command.modules.description": "Displays a list of all modules.", + "command.name-history": "Name History", "command.name-history.description": "Provides a list of a players previous names from the laby.net api", "command.name-history.error.error_fetching_name": "There was an error fetching that users name history.", "command.name-history.inaccurate": "This name history entry is not accurate according to laby.net", + "command.nbt": "NBT", "command.nbt.description": "Modifies NBT data for an item, example: .nbt add {display:{Name:'{\"text\":\"$cRed Name\"}'}}", + "command.notebot": "Notebot", "command.notebot.description": "Allows you load notebot files", + "command.peek": "Peek", "command.peek.description": "Lets you see what's inside storage block items.", + "command.profiles": "Profiles", "command.profiles.description": "Loads and saves profiles.", "command.profiles.info.loaded": "Loaded profile (highlight)%s(default).", "command.profiles.info.saved": "Saved profile (highlight)%s(default).", "command.profiles.info.deleted": "Deleted profile (highlight)%s(default).", + "command.reload": "Reload", "command.reload.description": "Reloads many systems.", "command.reload.warning.reloading": "Reloading systems, this may take a while.", + "command.reset": "Reset", "command.reset.description": "Resets specified settings.", + "command.rotation": "Rotation", "command.rotation.description": "Modifies your rotation.", + "command.save-map": "Save Map", "command.save-map.description": "Saves a map to an image.", "command.save-map.error.error_writing_texture": "Error writing map texture", "command.save-map.exception.map_not_found": "You must be holding a filled map.", "command.save-map.exception.oops": "Something went wrong.", + "command.say": "Say", "command.say.description": "Sends messages in chat.", + "command.server": "Server", "command.server.description": "Prints server information", + "command.settings": "Settings", "command.settings.description": "Allows you to view and change module settings.", + "command.spectate": "Spectate", "command.spectate.description": "Allows you to spectate nearby players", + "command.swarm": "Swarm", "command.swarm.description": "Sends commands to connected swarm workers.", + "command.toggle": "Toggle", "command.toggle.description": "Toggles a module.", + "command.vclip": "V-Clip", "command.vclip.description": "Lets you clip through blocks vertically.", + "command.wasp": "Wasp", "command.wasp.description": "Sets the auto wasp target.", "command.wasp.exception.cant_wasp_self": "You cannot target yourself!", "command.wasp.info.target": "%s set as target.", + "command.waypoint": "Waypoint", "command.waypoint.description": "Manages waypoints.", "config.visual.custom-font": "Custom Font", From fc297d812bb1b71045f571158865bf0fe0d2042d Mon Sep 17 00:00:00 2001 From: crosby-moe <32882447+crosby-moe@users.noreply.github.com> Date: Fri, 30 Jan 2026 09:35:55 -0500 Subject: [PATCH 06/14] complex translation argument formatting guh --- .../commands/commands/BindsCommand.java | 2 +- .../commands/commands/CommandsCommand.java | 3 +- .../commands/commands/FakePlayerCommand.java | 3 +- .../commands/commands/FriendsCommand.java | 2 +- .../commands/commands/InputCommand.java | 5 +- .../text/MeteorTranslatableTextComponent.java | 121 ++++++++++-------- .../meteorclient/utils/player/ChatUtils.java | 16 ++- .../assets/meteor-client/language/en_us.json | 10 +- 8 files changed, 89 insertions(+), 73 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/BindsCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/BindsCommand.java index cbf7d79a13..aa19887cf3 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/BindsCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/BindsCommand.java @@ -31,7 +31,7 @@ public void build(LiteralArgumentBuilder builder) { .filter(module -> module.keybind.isSet()) .toList(); - ChatUtils.info(translationKey + ".info.bound_modules", modules.size()); + ChatUtils.info(translationKey + ".info.bound_modules", ChatUtils.highlight(modules.size())); for (Module module : modules) { HoverEvent hoverEvent = new HoverEvent.ShowText(getTooltip(module)); diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/CommandsCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/CommandsCommand.java index ae3a44a070..ca5e1de059 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/CommandsCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/CommandsCommand.java @@ -9,7 +9,6 @@ import meteordevelopment.meteorclient.commands.Command; import meteordevelopment.meteorclient.commands.Commands; import meteordevelopment.meteorclient.systems.config.Config; -import meteordevelopment.meteorclient.utils.Utils; import meteordevelopment.meteorclient.utils.player.ChatUtils; import net.minecraft.command.CommandSource; import net.minecraft.text.ClickEvent; @@ -26,7 +25,7 @@ public CommandsCommand() { @Override public void build(LiteralArgumentBuilder builder) { builder.executes(context -> { - ChatUtils.info(translationKey + ".info.commands", Commands.COMMANDS.size()); + ChatUtils.info(translationKey + ".info.commands", ChatUtils.highlight(Commands.COMMANDS.size())); MutableText commands = Text.literal(""); Commands.COMMANDS.forEach(command -> commands.append(getCommandText(command))); diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/FakePlayerCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/FakePlayerCommand.java index 5418679c0d..8dd8213bc2 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/FakePlayerCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/FakePlayerCommand.java @@ -13,6 +13,7 @@ import meteordevelopment.meteorclient.systems.modules.player.FakePlayer; import meteordevelopment.meteorclient.utils.entity.fakeplayer.FakePlayerEntity; import meteordevelopment.meteorclient.utils.entity.fakeplayer.FakePlayerManager; +import meteordevelopment.meteorclient.utils.player.ChatUtils; import net.minecraft.command.CommandSource; public class FakePlayerCommand extends Command { @@ -63,7 +64,7 @@ public void build(LiteralArgumentBuilder builder) { builder.then(literal("list") .executes(context -> { - info("fake_players", FakePlayerManager.count()); + info("fake_players", ChatUtils.highlight(FakePlayerManager.count())); FakePlayerManager.forEach(fp -> info("(highlight)%s".formatted(fp.getName().getString()))); return SINGLE_SUCCESS; }) diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/FriendsCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/FriendsCommand.java index 8660c3bba5..83d7ec38c7 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/FriendsCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/FriendsCommand.java @@ -59,7 +59,7 @@ public void build(LiteralArgumentBuilder builder) { ); builder.then(literal("list").executes(context -> { - info("friends", Friends.get().count()); + info("friends", ChatUtils.highlight(Friends.get().count())); Friends.get().forEach(friend -> ChatUtils.infoRaw("(highlight)%s".formatted(friend.getName()))); return SINGLE_SUCCESS; }) diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/InputCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/InputCommand.java index c5e96ce16c..1a17bd4ebf 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/InputCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/InputCommand.java @@ -12,6 +12,7 @@ import meteordevelopment.meteorclient.commands.Command; import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.mixin.KeyBindingAccessor; +import meteordevelopment.meteorclient.utils.player.ChatUtils; import meteordevelopment.orbit.EventHandler; import net.minecraft.client.option.KeyBinding; import net.minecraft.client.resource.language.I18n; @@ -92,10 +93,10 @@ public void build(LiteralArgumentBuilder builder) { builder.then(literal("list").executes(ctx -> { if (activeHandlers.isEmpty()) warning("no_handlers"); else { - info(""); + info("active_handlers"); for (int i = 0; i < activeHandlers.size(); i++) { KeypressHandler handler = activeHandlers.get(i); - info("keypress_handler", i, I18n.translate(handler.key.getId()), handler.ticks, handler.totalTicks); + info("keypress_handler", ChatUtils.highlight(i), ChatUtils.highlight(I18n.translate(handler.key.getId())), ChatUtils.highlight(handler.ticks), ChatUtils.highlight(handler.totalTicks)); } } return SINGLE_SUCCESS; diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MeteorTranslatableTextComponent.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MeteorTranslatableTextComponent.java index 6962365a3c..1f89367989 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MeteorTranslatableTextComponent.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MeteorTranslatableTextComponent.java @@ -7,14 +7,14 @@ import com.google.common.collect.ImmutableList; import com.mojang.serialization.MapCodec; +import meteordevelopment.meteorclient.MeteorClient; import meteordevelopment.meteorclient.utils.misc.MeteorTranslations; +import meteordevelopment.meteorclient.utils.player.ChatUtils; +import net.fabricmc.loader.api.FabricLoader; import net.minecraft.text.*; import org.jetbrains.annotations.Nullable; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; -import java.util.Optional; +import java.util.*; import java.util.function.Consumer; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -22,6 +22,7 @@ import static meteordevelopment.meteorclient.MeteorClient.mc; public class MeteorTranslatableTextComponent implements TextContent { + private static final boolean DEBUG_MISSING_ENTRIES = FabricLoader.getInstance().isDevelopmentEnvironment() || Boolean.getBoolean("meteor.lang.debug"); private final String key; @Nullable private final String fallback; @@ -29,7 +30,6 @@ public class MeteorTranslatableTextComponent implements TextContent { private final boolean styledArgs; private String cachedLanguage; - private String translation; private List translations = ImmutableList.of(); public MeteorTranslatableTextComponent(String key, @Nullable String fallback, Object... args) { @@ -62,10 +62,15 @@ private void updateTranslations() { this.forEachPart(template, builder::add); this.translations = builder.build(); } catch (TranslationException e) { + if (DEBUG_MISSING_ENTRIES) { + MeteorClient.LOG.warn("Error translating text", e); + } this.translations = ImmutableList.of(StringVisitable.plain(template)); } } else { - translation = fallback == null ? MeteorTranslations.translate(key, args) : MeteorTranslations.translate(key, fallback, args); + String template = fallback == null ? MeteorTranslations.translate(key, args) : MeteorTranslations.translate(key, fallback, args); + + this.translations = ImmutableList.of(ChatUtils.formatMsg(template, Style.EMPTY)); } } } @@ -74,30 +79,22 @@ private void updateTranslations() { public Optional visit(StringVisitable.StyledVisitor visitor, Style style) { updateTranslations(); - if (styledArgs) { - for (StringVisitable stringVisitable : translations) { - Optional result = stringVisitable.visit(visitor, style); - if (result.isPresent()) return result; - } - return Optional.empty(); - } else { - return visitor.accept(style, translation); + for (StringVisitable stringVisitable : translations) { + Optional result = stringVisitable.visit(visitor, style); + if (result.isPresent()) return result; } + return Optional.empty(); } @Override public Optional visit(StringVisitable.Visitor visitor) { updateTranslations(); - if (styledArgs) { - for (StringVisitable stringVisitable : translations) { - Optional result = stringVisitable.visit(visitor); - if (result.isPresent()) return result; - } - return Optional.empty(); - } else { - return visitor.accept(translation); + for (StringVisitable stringVisitable : translations) { + Optional result = stringVisitable.visit(visitor); + if (result.isPresent()) return result; } + return Optional.empty(); } @Override @@ -117,49 +114,76 @@ public String toString() { return "MeteorTranslatableTextComponent[key=" + key + ", fallback=" + fallback + ", args=" + Arrays.toString(args) + "]"; } - /// Bunch of bullshit from {@link net.minecraft.text.TranslatableTextContent} + private static final StringVisitable LITERAL_PERCENT_SIGN = StringVisitable.plain("%"); private static final StringVisitable NULL_ARGUMENT = StringVisitable.plain("null"); - private static final Pattern ARG_FORMAT = Pattern.compile("%(?:(\\d+)\\$)?([A-Za-z%]|$)"); + // %, optional position argument (\d$), string format (s) || percent literal (%|$) || number format ([-+.]? \d* [df]) + @SuppressWarnings("RegExpRedundantEscape") // then why does it IllegalArgumentException when i remove it dipshit + private static final Pattern ARG_FORMAT = Pattern.compile("%(?:(\\d+)\\$)?([s%]|$|[-+\\.]?\\d*[df])"); private void forEachPart(String translation, Consumer partsConsumer) { Matcher matcher = ARG_FORMAT.matcher(translation); try { - int i = 0; - int j = 0; - - while (matcher.find(j)) { - int k = matcher.start(); - int l = matcher.end(); - if (k > j) { - String string = translation.substring(j, k); + int argPosition = 0; + int charIndex = 0; + + while (matcher.find(charIndex)) { + int start = matcher.start(); + int end = matcher.end(); + if (start > charIndex) { + String string = translation.substring(charIndex, start); if (string.indexOf(37) != -1) { - throw new IllegalArgumentException(); + throw new IllegalArgumentException(string); } partsConsumer.accept(StringVisitable.plain(string)); } String string = matcher.group(2); - String string2 = translation.substring(k, l); + String string2 = translation.substring(start, end); if ("%".equals(string) && "%%".equals(string2)) { partsConsumer.accept(LITERAL_PERCENT_SIGN); } else { - if (!"s".equals(string)) { - throw new TranslationException(new TranslatableTextContent(this.key, this.fallback, this.args), "Unsupported format: '" + string2 + "'"); + String positionArgument = matcher.group(1); + int index = positionArgument != null ? Integer.parseInt(positionArgument) - 1 : argPosition++; + if (index < 0 || index >= this.args.length) { + throw new TranslationException(new TranslatableTextContent(this.key, this.fallback, this.args), index); } - String string3 = matcher.group(1); - int m = string3 != null ? Integer.parseInt(string3) - 1 : i++; - partsConsumer.accept(this.getArg(m)); + Object argument = this.args[index]; + + if (string.equals("s")) { // fast path + StringVisitable visitableArgument = argument instanceof StringVisitable visitable ? visitable + : argument == null ? NULL_ARGUMENT : StringVisitable.plain(argument.toString()); + + partsConsumer.accept(visitableArgument); + } else if (argument instanceof StringVisitable) { + if (argument instanceof MutableText mutableText && mutableText.getSiblings().isEmpty() && mutableText.getContent() instanceof PlainTextContent content) { + try { // attempt to use formatting + String format = "%" + string; + partsConsumer.accept(StringVisitable.styled(String.format(format, content.string()), mutableText.getStyle())); + } catch (IllegalFormatException e) { + throw new TranslationException(new TranslatableTextContent(this.key, this.fallback, this.args), index); + } + } else { // cant use format strings on non-constant/complex arguments + throw new TranslationException(new TranslatableTextContent(this.key, this.fallback, this.args), "Cant use complex format string with Text"); + } + } else { // attempt to use formatting + try { + String format = "%" + string; + partsConsumer.accept(StringVisitable.plain(String.format(format, argument))); + } catch (IllegalFormatException e) { + throw new TranslationException(new TranslatableTextContent(this.key, this.fallback, this.args), index); + } + } } - j = l; + charIndex = end; } - if (j < translation.length()) { - String string4 = translation.substring(j); + if (charIndex < translation.length()) { + String string4 = translation.substring(charIndex); if (string4.indexOf(37) != -1) { throw new IllegalArgumentException(); } @@ -170,17 +194,4 @@ private void forEachPart(String translation, Consumer partsCons throw new TranslationException(new TranslatableTextContent(this.key, this.fallback, this.args), e); } } - - public final StringVisitable getArg(int index) { - if (index >= 0 && index < this.args.length) { - Object object = this.args[index]; - if (object instanceof Text text) { - return text; - } else { - return object == null ? NULL_ARGUMENT : StringVisitable.plain(object.toString()); - } - } else { - throw new TranslationException(new TranslatableTextContent(this.key, this.fallback, this.args), index); - } - } } diff --git a/src/main/java/meteordevelopment/meteorclient/utils/player/ChatUtils.java b/src/main/java/meteordevelopment/meteorclient/utils/player/ChatUtils.java index 99e82aae7c..dc0be270fc 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/player/ChatUtils.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/player/ChatUtils.java @@ -173,7 +173,7 @@ public static void sendMsgRaw(int id, Formatting color, String message, Object.. } public static void sendMsgRaw(int id, @Nullable String prefixKey, @Nullable Formatting prefixColor, Formatting messageColor, String messageContent, Object... args) { - MutableText message = formatMsg(String.format(messageContent, args), messageColor); + MutableText message = formatMsg(String.format(messageContent, args), Style.EMPTY.withFormatting(messageColor)); sendMsg(id, prefixKey, prefixColor, message); } @@ -183,7 +183,7 @@ public static void sendMsg(int id, @Nullable String prefixKey, @Nullable Formatt } public static void sendMsg(int id, @Nullable String prefixKey, @Nullable Formatting prefixColor, String messageContent, Formatting messageColor) { - MutableText message = formatMsg(messageContent, messageColor); + MutableText message = formatMsg(messageContent, Style.EMPTY.withFormatting(messageColor)); sendMsg(id, prefixKey, prefixColor, message); } @@ -253,10 +253,10 @@ private static Text getPrefix() { return PREFIX; } - private static MutableText formatMsg(String message, Formatting defaultColor) { + public static MutableText formatMsg(String message, Style defaultStyle) { StringReader reader = new StringReader(message); MutableText text = Text.empty(); - Style style = Style.EMPTY.withFormatting(defaultColor); + Style style = defaultStyle; StringBuilder result = new StringBuilder(); boolean formatting = false; while (reader.canRead()) { @@ -272,7 +272,7 @@ private static MutableText formatMsg(String message, Formatting defaultColor) { if (formatting && c == ')') { switch (result.toString()) { case "(default)" -> { - style = style.withFormatting(defaultColor); + style = defaultStyle; result.setLength(0); } case "(highlight)" -> { @@ -298,9 +298,13 @@ private static MutableText formatMsg(String message, Formatting defaultColor) { return text; } + public static MutableText highlight(Object object) { + return Text.literal(String.valueOf(object)).formatted(Formatting.WHITE); + } + public static MutableText formatCoords(Vec3d pos) { String coordsString = String.format("(highlight)(underline)%.0f, %.0f, %.0f(default)", pos.x, pos.y, pos.z); - MutableText coordsText = formatMsg(coordsString, Formatting.GRAY); + MutableText coordsText = formatMsg(coordsString, Style.EMPTY.withFormatting(Formatting.GRAY)); if (BaritoneUtils.IS_AVAILABLE) { Style style = coordsText.getStyle().withFormatting(Formatting.BOLD) diff --git a/src/main/resources/assets/meteor-client/language/en_us.json b/src/main/resources/assets/meteor-client/language/en_us.json index a65ec99c1a..cff1d492e4 100644 --- a/src/main/resources/assets/meteor-client/language/en_us.json +++ b/src/main/resources/assets/meteor-client/language/en_us.json @@ -19,10 +19,10 @@ "command.bind.info.press_key": "Press a key to bind the module to.", "command.binds": "Binds", "command.binds.description": "List of all bound modules.", - "command.binds.info.bound_modules": "--- Bound Modules ((highlight)%s(default)) ---", + "command.binds.info.bound_modules": "--- Bound Modules (%s) ---", "command.commands": "Commands", "command.commands.description": "List of all commands.", - "command.commands.info.commands": "--- Commands ((highlight)%s(default)) ----", + "command.commands.info.commands": "--- Commands (%s) ----", "command.damage": "Damage", "command.damage.description": "Damages self.", "command.damage.exception.invulnerable": "You are invulnerable.", @@ -45,7 +45,7 @@ "command.fake-player.description": "Manages fake players that you can use for testing.", "command.fake-player.error.not_found": "Couldn't find a Fake Player with that name.", "command.fake-player.info.removed": "Removed Fake Player %s.", - "command.fake-player.info.fake_players": "--- Fake Players ((highlight)%s(default)) ---", + "command.fake-player.info.fake_players": "--- Fake Players (%s) ---", "command.fov": "FOV", "command.fov.description": "Changes your fov.", "command.friends": "Friends", @@ -55,7 +55,7 @@ "command.friends.error.not_friends": "Not friends with that player.", "command.friends.info.added": "Added %s to friends.", "command.friends.info.removed": "Removed %s from friends.", - "command.friends.info.friends": "--- Friends ((highlight)%s(default)) ---", + "command.friends.info.friends": "--- Friends (%s) ---", "command.gamemode": "Gamemode", "command.gamemode.description": "Changes your gamemode client-side.", "command.give": "Give", @@ -68,7 +68,7 @@ "command.input.description": "Keyboard input simulation.", "command.input.info.cleared_handlers": "Cleared all keypress handlers.", "command.input.info.active_handlers": "Active keypress handlers: ", - "command.input.info.keypress_handler": "(highlight)%d(default) - (highlight)%s %d(default) ticks left out of (highlight)%d(default).", + "command.input.info.keypress_handler": "%s - %s %s ticks left out of %s.", "command.input.info.removed_handler": "Removed keypress handler.", "command.input.warning.no_handlers": "No active keypress handlers.", "command.input.warning.out_of_range": "Index out of range.", From fcf2ecf305484db2ec2b0f98f8d43878eefb9722 Mon Sep 17 00:00:00 2001 From: crosby-moe <32882447+crosby-moe@users.noreply.github.com> Date: Thu, 5 Feb 2026 09:22:11 -0500 Subject: [PATCH 07/14] map more commands --- .../commands/commands/LocateCommand.java | 17 ++-- .../commands/commands/NbtCommand.java | 22 +++--- .../commands/commands/NotebotCommand.java | 16 ++-- .../commands/commands/PeekCommand.java | 4 +- .../commands/commands/ProfilesCommand.java | 7 +- .../commands/commands/ResetCommand.java | 14 ++-- .../commands/commands/SaveMapCommand.java | 4 +- .../commands/commands/ServerCommand.java | 77 +++++++++---------- .../assets/meteor-client/language/en_us.json | 77 ++++++++++++++----- 9 files changed, 140 insertions(+), 98 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/LocateCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/LocateCommand.java index da75d98264..b580a71c75 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/LocateCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/LocateCommand.java @@ -30,6 +30,7 @@ import net.minecraft.network.packet.s2c.play.EntitySpawnS2CPacket; import net.minecraft.text.MutableText; import net.minecraft.text.Text; +import net.minecraft.util.Formatting; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; @@ -79,7 +80,7 @@ public void build(LiteralArgumentBuilder builder) { if (stack.getItem() != Items.FILLED_MAP || stack.get(DataComponentTypes.ITEM_NAME) == null || !stack.get(DataComponentTypes.ITEM_NAME).getString().equals(Text.translatable("filled_map.buried_treasure").getString())) { - error("no_buried_treasure_map"); + error("no_buried_treasure_map", Text.translatable("filled_map.buried_treasure").formatted(Formatting.WHITE)); return SINGLE_SUCCESS; } @@ -106,7 +107,7 @@ public void build(LiteralArgumentBuilder builder) { if (stack.getItem() != Items.FILLED_MAP || stack.get(DataComponentTypes.ITEM_NAME) == null || !stack.get(DataComponentTypes.ITEM_NAME).getString().equals(Text.translatable("filled_map.mansion").getString())) { - error("no_woodland_explorer_map"); + error("no_woodland_explorer_map", Text.translatable("filled_map.mansion").formatted(Formatting.WHITE)); return SINGLE_SUCCESS; } @@ -156,14 +157,14 @@ public void build(LiteralArgumentBuilder builder) { if (BaritoneUtils.IS_AVAILABLE) { Vec3d coords = findByBlockList(monumentBlocks); if (coords == null) { - error("no_monument_found"); + error("no_monument_found", Text.translatable("filled_map.monument").formatted(Formatting.WHITE)); return SINGLE_SUCCESS; } info("monument", ChatUtils.formatCoords(coords)); return SINGLE_SUCCESS; } - error("ocean_explorer_no_baritone"); + error("ocean_explorer_no_baritone", Text.translatable("filled_map.monument").formatted(Formatting.WHITE)); return SINGLE_SUCCESS; })); @@ -181,7 +182,7 @@ public void build(LiteralArgumentBuilder builder) { } else if (BaritoneUtils.IS_AVAILABLE) { Vec3d coords = findByBlockList(strongholdBlocks); if (coords == null) { - error("no_stronghold_found"); + error("no_stronghold_found", Text.translatable("item.minecraft.ender_eye").formatted(Formatting.WHITE)); return SINGLE_SUCCESS; } info("stronghold", ChatUtils.formatCoords(coords)); @@ -243,17 +244,17 @@ public void build(LiteralArgumentBuilder builder) { builder.then(literal("lodestone").executes(s -> { ItemStack stack = mc.player.getInventory().getSelectedStack(); if (stack.getItem() != Items.COMPASS) { - error("no_lodestone_compass"); + error("no_lodestone_compass", Text.translatable("item.minecraft.lodestone_compass").formatted(Formatting.WHITE)); return SINGLE_SUCCESS; } ComponentMap components = stack.getComponents(); if (components == null) { - error("no_lodestone_compass_data"); + error("no_lodestone_compass_data", Text.translatable("item.minecraft.lodestone_compass").formatted(Formatting.WHITE)); return SINGLE_SUCCESS; } LodestoneTrackerComponent lodestoneTrackerComponent = components.get(DataComponentTypes.LODESTONE_TRACKER); if (lodestoneTrackerComponent == null) { - error("no_lodestone_compass_data"); + error("no_lodestone_compass_data", Text.translatable("item.minecraft.lodestone_compass").formatted(Formatting.WHITE)); return SINGLE_SUCCESS; } diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/NbtCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/NbtCommand.java index 667b28c421..507699acfe 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/NbtCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/NbtCommand.java @@ -10,6 +10,7 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; import com.mojang.serialization.DataResult; +import meteordevelopment.meteorclient.MeteorClient; import meteordevelopment.meteorclient.commands.Command; import meteordevelopment.meteorclient.commands.arguments.ComponentMapArgumentType; import meteordevelopment.meteorclient.utils.misc.text.MeteorClickEvent; @@ -42,12 +43,12 @@ public class NbtCommand extends Command { error -> Text.stringifiedTranslatable("arguments.item.malformed", error) ); private final Text copyButton = Text.literal("NBT").setStyle(Style.EMPTY - .withFormatting(Formatting.UNDERLINE) + .withFormatting(Formatting.UNDERLINE, Formatting.WHITE) .withClickEvent(new MeteorClickEvent( this.toString("copy") )) .withHoverEvent(new HoverEvent.ShowText( - Text.literal("Copy the NBT data to your clipboard.") + MeteorClient.translatable(translationKey + ".info.copy_tooltip") ))); public NbtCommand() { @@ -169,23 +170,20 @@ public void build(LiteralArgumentBuilder builder) { DataCommandObject dataCommandObject = new EntityDataObject(mc.player); NbtPathArgumentType.NbtPath handPath = NbtPathArgumentType.NbtPath.parse("SelectedItem"); - MutableText text = Text.empty().append(copyButton); + Text nbtText = Text.literal("{}").formatted(Formatting.WHITE); String nbt = "{}"; try { List nbtElement = handPath.get(dataCommandObject.getNbt()); if (!nbtElement.isEmpty()) { - text.append(" ").append(NbtHelper.toPrettyPrintedText(nbtElement.getFirst())); + nbtText = Text.empty().append(NbtHelper.toPrettyPrintedText(nbtElement.getFirst())).formatted(Formatting.WHITE); nbt = nbtElement.getFirst().toString(); } - } catch (CommandSyntaxException e) { - text.append("{}"); - } + } catch (CommandSyntaxException ignored) {} mc.keyboard.setClipboard(nbt); - text.append(" data copied!"); - info(text); + info("copy", copyButton, nbtText); return SINGLE_SUCCESS; })); @@ -197,7 +195,7 @@ public void build(LiteralArgumentBuilder builder) { int count = IntegerArgumentType.getInteger(context, "count"); stack.setCount(count); setStack(stack); - info("Set mainhand stack count to %s.", count); + info("count", count); } return SINGLE_SUCCESS; @@ -210,12 +208,12 @@ private void setStack(ItemStack stack) { private boolean validBasic(ItemStack stack) { if (!mc.player.getAbilities().creativeMode) { - error("Creative mode only."); + error("not_creative"); return false; } if (stack == ItemStack.EMPTY) { - error("You must hold an item in your main hand."); + error("no_item"); return false; } return true; diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/NotebotCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/NotebotCommand.java index cf6822fb2e..6eba86f857 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/NotebotCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/NotebotCommand.java @@ -34,8 +34,8 @@ import java.util.Map; public class NotebotCommand extends Command { - private static final SimpleCommandExceptionType INVALID_SONG = new SimpleCommandExceptionType(Text.literal("Invalid song.")); - private static final DynamicCommandExceptionType INVALID_PATH = new DynamicCommandExceptionType(object -> Text.literal("'%s' is not a valid path.".formatted(object))); + private static final SimpleCommandExceptionType INVALID_SONG = new SimpleCommandExceptionType(MeteorClient.translatable("command.notebot.error.invalid_song")); + private static final DynamicCommandExceptionType INVALID_PATH = new DynamicCommandExceptionType(object -> MeteorClient.translatable("command.notebot.error.invalid_path", object)); int ticks = -1; private final Map> song = new HashMap<>(); // tick -> notes @@ -111,13 +111,13 @@ public void build(LiteralArgumentBuilder builder) { ticks = -1; song.clear(); MeteorClient.EVENT_BUS.subscribe(this); - info("Recording started"); + info("recording_started"); return SINGLE_SUCCESS; }))); builder.then(literal("record").then(literal("cancel").executes(ctx -> { MeteorClient.EVENT_BUS.unsubscribe(this); - info("Recording cancelled"); + info("recording_cancelled"); return SINGLE_SUCCESS; }))); @@ -176,9 +176,9 @@ private void saveRecording(Path path) { } file.close(); - info("Song saved."); + info("song_saved"); } catch (IOException e) { - info("Couldn't create the file."); + error("cant_create_file"); MeteorClient.EVENT_BUS.unsubscribe(this); } @@ -198,13 +198,13 @@ private Note getNote(PlaySoundS2CPacket soundPacket) { } if (noteLevel == -1) { - error("Error while bruteforcing a note level! Sound: " + soundPacket.getSound().value() + " Pitch: " + pitch); + error("bruteforce", soundPacket.getSound().value(), pitch); return null; } NoteBlockInstrument instrument = getInstrumentFromSound(soundPacket.getSound().value()); if (instrument == null) { - error("Can't find the instrument from sound! Sound: " + soundPacket.getSound().value()); + error("instrument", soundPacket.getSound().value()); return null; } diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/PeekCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/PeekCommand.java index 77d2ac6dcf..b0e393daff 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/PeekCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/PeekCommand.java @@ -7,16 +7,16 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; +import meteordevelopment.meteorclient.MeteorClient; import meteordevelopment.meteorclient.commands.Command; import meteordevelopment.meteorclient.utils.Utils; import net.minecraft.command.CommandSource; import net.minecraft.entity.decoration.ItemFrameEntity; import net.minecraft.item.ItemStack; -import net.minecraft.text.Text; public class PeekCommand extends Command { private static final ItemStack[] ITEMS = new ItemStack[27]; - private static final SimpleCommandExceptionType CANT_PEEK = new SimpleCommandExceptionType(Text.literal("You must be holding a storage block or looking at an item frame.")); + private static final SimpleCommandExceptionType CANT_PEEK = new SimpleCommandExceptionType(MeteorClient.translatable("command.peek.error.cant_peek")); public PeekCommand() { super("peek"); diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/ProfilesCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/ProfilesCommand.java index f8b0b7c25d..c3237e36e6 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/ProfilesCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/ProfilesCommand.java @@ -10,6 +10,7 @@ import meteordevelopment.meteorclient.commands.arguments.ProfileArgumentType; import meteordevelopment.meteorclient.systems.profiles.Profile; import meteordevelopment.meteorclient.systems.profiles.Profiles; +import meteordevelopment.meteorclient.utils.player.ChatUtils; import net.minecraft.command.CommandSource; public class ProfilesCommand extends Command { @@ -25,7 +26,7 @@ public void build(LiteralArgumentBuilder builder) { if (profile != null) { profile.load(); - info("loaded", profile.name.get()); + info("loaded", ChatUtils.highlight(profile.name.get())); } return SINGLE_SUCCESS; @@ -36,7 +37,7 @@ public void build(LiteralArgumentBuilder builder) { if (profile != null) { profile.save(); - info("saved", profile.name.get()); + info("saved", ChatUtils.highlight(profile.name.get())); } return SINGLE_SUCCESS; @@ -47,7 +48,7 @@ public void build(LiteralArgumentBuilder builder) { if (profile != null) { Profiles.get().remove(profile); - info("deleted", profile.name.get()); + info("deleted", ChatUtils.highlight(profile.name.get())); } return SINGLE_SUCCESS; diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/ResetCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/ResetCommand.java index 88fdc78e50..badda137ad 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/ResetCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/ResetCommand.java @@ -28,36 +28,38 @@ public void build(LiteralArgumentBuilder builder) { .then(argument("module", ModuleArgumentType.create()).executes(context -> { Module module = context.getArgument("module", Module.class); module.settings.forEach(group -> group.forEach(Setting::reset)); - module.info("Reset all settings."); + ChatUtils.forceNextPrefixClass(module.getClass()); + ChatUtils.infoPrefix(module.getTranslationKey(), "command.reset.info.module"); return SINGLE_SUCCESS; })) .then(literal("all").executes(context -> { Modules.get().getAll().forEach(module -> module.settings.forEach(group -> group.forEach(Setting::reset))); - ChatUtils.infoPrefixRaw("tab.modules", "Reset all module settings"); + ChatUtils.infoPrefix("tab.modules", "command.reset.info.modules"); return SINGLE_SUCCESS; })) ).then(literal("gui").executes(context -> { GuiThemes.get().clearWindowConfigs(); GuiThemes.get().settings.reset(); - ChatUtils.infoRaw("Reset all GUI settings."); + ChatUtils.info("command.reset.info.gui"); return SINGLE_SUCCESS; })).then(literal("bind") .then(argument("module", ModuleArgumentType.create()).executes(context -> { Module module = context.getArgument("module", Module.class); module.keybind.reset(); - module.info("Reset bind."); + ChatUtils.forceNextPrefixClass(module.getClass()); + ChatUtils.infoPrefix(module.getTranslationKey(), "command.reset.info.bind"); return SINGLE_SUCCESS; })) .then(literal("all").executes(context -> { Modules.get().getAll().forEach(module -> module.keybind.reset()); - ChatUtils.infoPrefixRaw("tab.modules", "Reset all binds."); + ChatUtils.infoPrefix("tab.modules", "command.reset.info.binds"); return SINGLE_SUCCESS; })) ).then(literal("hud").executes(context -> { Hud.get().resetToDefaultElements(); - ChatUtils.infoPrefixRaw("tab.hud", "Reset all elements."); + ChatUtils.infoPrefix("tab.hud", "command.reset.info.hud"); return SINGLE_SUCCESS; })); } diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/SaveMapCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/SaveMapCommand.java index 668893f56b..7f08e467bf 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/SaveMapCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/SaveMapCommand.java @@ -32,8 +32,8 @@ import java.nio.ByteBuffer; public class SaveMapCommand extends Command { - private static final SimpleCommandExceptionType MAP_NOT_FOUND = new SimpleCommandExceptionType(MeteorClient.translatable("meteor.command.save-map.exception.map_not_found")); - private static final SimpleCommandExceptionType OOPS = new SimpleCommandExceptionType(MeteorClient.translatable("meteor.command.save-map.exception.oops")); + private static final SimpleCommandExceptionType MAP_NOT_FOUND = new SimpleCommandExceptionType(MeteorClient.translatable("command.save-map.exception.map_not_found")); + private static final SimpleCommandExceptionType OOPS = new SimpleCommandExceptionType(MeteorClient.translatable("command.save-map.exception.oops")); private final PointerBuffer filters; diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/ServerCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/ServerCommand.java index 746b2b91a7..a781970756 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/ServerCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/ServerCommand.java @@ -13,6 +13,7 @@ import meteordevelopment.meteorclient.events.packets.PacketEvent; import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.mixin.ClientPlayNetworkHandlerAccessor; +import meteordevelopment.meteorclient.utils.player.ChatUtils; import meteordevelopment.meteorclient.utils.world.TickRate; import meteordevelopment.orbit.EventHandler; import net.minecraft.client.network.ServerAddress; @@ -24,11 +25,9 @@ import net.minecraft.network.packet.c2s.play.RequestCommandCompletionsC2SPacket; import net.minecraft.network.packet.s2c.play.CommandSuggestionsS2CPacket; import net.minecraft.network.packet.s2c.play.CommandTreeS2CPacket; +import net.minecraft.screen.ScreenTexts; import net.minecraft.server.integrated.IntegratedServer; -import net.minecraft.text.ClickEvent; -import net.minecraft.text.HoverEvent; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; +import net.minecraft.text.*; import net.minecraft.util.Formatting; import net.minecraft.world.LocalDifficulty; import net.minecraft.world.attribute.EnvironmentAttributes; @@ -88,7 +87,7 @@ public void build(LiteralArgumentBuilder builder) { if (tps > 17.0f) color = Formatting.GREEN; else if (tps > 12.0f) color = Formatting.YELLOW; else color = Formatting.RED; - info("Current TPS: %s%.2f(default).", color, tps); + info("tps", Text.literal(String.format("%.2f", tps)).formatted(color)); return SINGLE_SUCCESS; })); } @@ -97,8 +96,8 @@ private void basicInfo() { if (mc.isIntegratedServerRunning()) { IntegratedServer server = mc.getServer(); - info("Singleplayer"); - if (server != null) info("Version: %s", server.getVersion()); + info("singleplayer"); + if (server != null) info("version", server.getVersion()); return; } @@ -106,7 +105,7 @@ private void basicInfo() { ServerInfo server = mc.getCurrentServerEntry(); if (server == null) { - info("Couldn't obtain any server information."); + error("cant_obtain_info"); return; } @@ -121,34 +120,31 @@ private void basicInfo() { ipText = Text.literal(Formatting.GRAY + server.address); ipText.setStyle(ipText.getStyle() .withClickEvent(new ClickEvent.CopyToClipboard(server.address)) - .withHoverEvent(new HoverEvent.ShowText(Text.literal("Copy to clipboard"))) + .withHoverEvent(new HoverEvent.ShowText(MeteorClient.translatable("command.server.info.copy"))) ); } else { ipText = Text.literal(Formatting.GRAY + server.address); ipText.setStyle(ipText.getStyle() .withClickEvent(new ClickEvent.CopyToClipboard(server.address)) - .withHoverEvent(new HoverEvent.ShowText(Text.literal("Copy to clipboard"))) + .withHoverEvent(new HoverEvent.ShowText(MeteorClient.translatable("command.server.info.copy"))) ); MutableText ipv4Text = Text.literal(String.format("%s (%s)", Formatting.GRAY, ipv4)); ipv4Text.setStyle(ipText.getStyle() .withClickEvent(new ClickEvent.CopyToClipboard(ipv4)) - .withHoverEvent(new HoverEvent.ShowText(Text.literal("Copy to clipboard"))) + .withHoverEvent(new HoverEvent.ShowText(MeteorClient.translatable("command.server.info.copy"))) ); ipText.append(ipv4Text); } - info( - Text.literal(String.format("%sIP: ", Formatting.GRAY)) - .append(ipText) - ); - - info("Port: %d", ServerAddress.parse(server.address).getPort()); - info("Type: %s", mc.getNetworkHandler().getBrand() != null ? mc.getNetworkHandler().getBrand() : "unknown"); - info("Motd: %s", server.label != null ? server.label.getString() : "unknown"); - info("Version: %s", server.version.getString()); - info("Protocol version: %d", server.protocolVersion); - info("Difficulty: %s (Local: %.2f)", - mc.world.getDifficulty().getTranslatableName().getString(), + info("ip", ipText); + + info("port", ServerAddress.parse(server.address).getPort()); + info("type", mc.getNetworkHandler().getBrand() != null ? mc.getNetworkHandler().getBrand() : MeteorClient.translatable("command.server.info.unknown")); + info("motd", server.label != null ? server.label.getString() : MeteorClient.translatable("command.server.info.unknown")); + info("version", server.version.getString()); + info("protocol_version", server.protocolVersion); + info("difficulty", + mc.world.getDifficulty().getTranslatableName(), new LocalDifficulty( mc.world.getDifficulty(), mc.world.getTimeOfDay(), @@ -156,18 +152,18 @@ private void basicInfo() { DimensionType.MOON_SIZES[mc.world.getEnvironmentAttributes().getAttributeValue(EnvironmentAttributes.MOON_PHASE_VISUAL, mc.player.getBlockPos()).getIndex()] // lol ).getLocalDifficulty() ); - info("Day: %d", mc.world.getTimeOfDay() / 24000L); - info("Permission level: %s", formatPerms()); + info("day", mc.world.getTimeOfDay() / 24000L); + info(formatPerms()); } public String formatPerms() { PermissionPredicate permissions = mc.player.getPermissions(); - if (permissions.hasPermission(DefaultPermissions.OWNERS)) return "4 (Owner)"; - else if (permissions.hasPermission(DefaultPermissions.ADMINS)) return "3 (Admin)"; - else if (permissions.hasPermission(DefaultPermissions.GAMEMASTERS)) return "2 (Gamemaster)"; - else if (permissions.hasPermission(DefaultPermissions.MODERATORS)) return "1 (Moderator)"; - else return "0 (No Perms)"; + if (permissions.hasPermission(DefaultPermissions.OWNERS)) return "permission_owner"; + else if (permissions.hasPermission(DefaultPermissions.ADMINS)) return "permission_admin"; + else if (permissions.hasPermission(DefaultPermissions.GAMEMASTERS)) return "permission_gamemaster"; + else if (permissions.hasPermission(DefaultPermissions.MODERATORS)) return "permission_moderator"; + else return "permission_player"; } @@ -175,12 +171,15 @@ public String formatPerms() { private void printPlugins() { plugins.sort(String.CASE_INSENSITIVE_ORDER); - plugins.replaceAll(this::formatName); + List pluginTexts = new ArrayList<>(); + for (String plugin : plugins) { + pluginTexts.add(formatName(plugin)); + } if (!plugins.isEmpty()) { - info("Plugins (%d): %s ", plugins.size(), String.join(", ", plugins)); + info("plugins", plugins.size(), Texts.join(pluginTexts, Texts.DEFAULT_SEPARATOR_TEXT)); } else { - error("No plugins found."); + error("no_plugins"); } tick = false; @@ -237,7 +236,7 @@ private void onReadPacket(PacketEvent.Receive event) { Suggestions matches = packet.getSuggestions(); if (matches.isEmpty()) { - error("An error occurred while trying to find plugins."); + error("plugins"); return; } @@ -249,18 +248,18 @@ private void onReadPacket(PacketEvent.Receive event) { printPlugins(); } } catch (Exception e) { - error("An error occurred while trying to find plugins."); + error("plugins"); } } - private String formatName(String name) { + private Text formatName(String name) { if (ANTICHEAT_LIST.contains(name.toLowerCase())) { - return String.format("%s%s(default)", Formatting.RED, name); + return Text.literal(name).formatted(Formatting.RED); } else if (Strings.CI.contains(name, "exploit") || Strings.CI.contains(name, "cheat") || Strings.CI.contains(name, "illegal")) { - return String.format("%s%s(default)", Formatting.RED, name); + return Text.literal(name).formatted(Formatting.RED); } - return String.format("(highlight)%s(default)", name); + return ChatUtils.highlight(name); } } diff --git a/src/main/resources/assets/meteor-client/language/en_us.json b/src/main/resources/assets/meteor-client/language/en_us.json index cff1d492e4..fd8518ab51 100644 --- a/src/main/resources/assets/meteor-client/language/en_us.json +++ b/src/main/resources/assets/meteor-client/language/en_us.json @@ -28,7 +28,7 @@ "command.damage.exception.invulnerable": "You are invulnerable.", "command.disconnect": "Disconnect", "command.disconnect.description": "Disconnect from the server", - "command.disconnect.disconnection_message": "[%1$s] Disconnected by user.", + "command.disconnect.disconnection_message": "[%s] Disconnected by user.", "command.dismount": "Dismount", "command.dismount.description": "Dismounts you from entity you are riding.", "command.drop": "Drop", @@ -77,33 +77,33 @@ "command.locate": "Locate", "command.locate.description": "Locates structures", "command.locate.error.no_map_icons": "Couldn't locate the map icons!", - "command.locate.error.no_buried_treasure_map": "You need to hold a (highlight)buried treasure map(default)!", + "command.locate.error.no_buried_treasure_map": "You need to hold a %s!", "command.locate.error.cant_locate_buried_treasure": "Couldn't locate the buried treasure!", - "command.locate.error.no_woodland_explorer_map": "You need to hold a (highlight)woodland explorer map(default)!", + "command.locate.error.no_woodland_explorer_map": "You need to hold a %s!", "command.locate.error.cant_locate_mansion": "Couldn't locate the mansion!", "command.locate.error.cant_locate_monument": "Couldn't locate the monument!", - "command.locate.error.no_monument_found": "No monument found. Try using an (highlight)ocean explorer map(default) for more success.", - "command.locate.error.ocean_explorer_no_baritone": "Locating this structure without an (highlight)ocean explorer map(default) requires Baritone.", - "command.locate.error.no_stronghold_found": "No stronghold found nearby. You can use (highlight)Ender Eyes(default) for more success.", + "command.locate.error.no_monument_found": "No monument found. Try using an %s for more success.", + "command.locate.error.ocean_explorer_no_baritone": "Locating this structure without an %s requires Baritone.", + "command.locate.error.no_stronghold_found": "No stronghold found nearby. You can use %s for more success.", "command.locate.error.no_eyes_of_ender": "No Eyes of Ender found in hotbar.", "command.locate.error.not_in_nether": "You need to be in the nether to locate a nether fortress.", "command.locate.error.no_baritone": "Locating this structure requires Baritone.", "command.locate.error.cant_locate_nether_fortress": "No nether fortress found.", "command.locate.error.not_in_end": "You need to be in the end to locate an end city.", "command.locate.error.cant_locate_end_city": "No end city found.", - "command.locate.error.no_lodestone_compass": "You need to hold a (highlight)lodestone(default) compass!", - "command.locate.error.no_lodestone_compass_data": "Couldn't get the components data. Are you holding a (highlight)lodestone(default) compass?", + "command.locate.error.no_lodestone_compass": "You need to hold a %s!", + "command.locate.error.no_lodestone_compass_data": "Couldn't get the components data. Are you holding a %s?", "command.locate.error.no_lodestone": "Couldn't get the lodestone's target!", "command.locate.error.missing_position_data": "Missing position data", "command.locate.error.unable_to_calculate": "Unable to calculate intersection.", - "command.locate.info.buried_treasure": "Buried Treasure located at %1$s.", - "command.locate.info.mansion": "Mansion located at %1$s.", - "command.locate.info.monument": "Monument located at %1$s.", + "command.locate.info.buried_treasure": "Buried Treasure located at %s.", + "command.locate.info.mansion": "Mansion located at %s.", + "command.locate.info.monument": "Monument located at %s.", "command.locate.info.first_eye": "Please throw the first Eye of Ender.", - "command.locate.info.stronghold": "Stronghold located at %1$s.", - "command.locate.info.nether_fortress": "Fortress located at %1$s.", - "command.locate.info.end_city": "End city located at %1$s.", - "command.locate.info.lodestone": "Lodestone located at %1$s.", + "command.locate.info.stronghold": "Stronghold located at %s.", + "command.locate.info.nether_fortress": "Fortress located at %s.", + "command.locate.info.end_city": "End city located at %s.", + "command.locate.info.lodestone": "Lodestone located at %s.", "command.locate.info.first_eye_saved": "First Eye of Ender's trajectory saved.", "command.locate.info.second_eye_saved": "Second Eye of Ender's trajectory saved.", "command.locate.info.eye_different_location": "Please throw the second Eye Of Ender from a different location.", @@ -123,20 +123,40 @@ "command.name-history.inaccurate": "This name history entry is not accurate according to laby.net", "command.nbt": "NBT", "command.nbt.description": "Modifies NBT data for an item, example: .nbt add {display:{Name:'{\"text\":\"$cRed Name\"}'}}", + "command.nbt.error.not_creative": "Creative mode only.", + "command.nbt.error.no_item": "You must hold an item in your main hand.", + "command.nbt.info.copy_tooltip": "Copy the NBT data to your clipboard.", + "command.nbt.info.copy": "%s %s data copied!", + "command.nbt.info.count": "Set mainhand stack count to %d.", "command.notebot": "Notebot", "command.notebot.description": "Allows you load notebot files", + "command.notebot.error.invalid_song": "Invalid song.", + "command.notebot.error.invalid_path": "'%s' is not a valid path.", + "command.notebot.error.cant_create_file": "Couldn't create the file.", + "command.notebot.error.bruteforce": "Error while bruteforcing a note level! Sound: %s Pitch: %.3f", + "command.notebot.error.instrument": "Can't find the instrument from sound! Sound: %s", + "command.notebot.info.recording_started": "Recording started", + "command.notebot.info.recording_cancelled": "Recording cancelled", + "command.notebot.info.song_saved": "Song saved.", "command.peek": "Peek", "command.peek.description": "Lets you see what's inside storage block items.", + "command.peek.error.cant_peek": "You must be holding a storage block or looking at an item frame.", "command.profiles": "Profiles", "command.profiles.description": "Loads and saves profiles.", - "command.profiles.info.loaded": "Loaded profile (highlight)%s(default).", - "command.profiles.info.saved": "Saved profile (highlight)%s(default).", - "command.profiles.info.deleted": "Deleted profile (highlight)%s(default).", + "command.profiles.info.loaded": "Loaded profile %s.", + "command.profiles.info.saved": "Saved profile %s.", + "command.profiles.info.deleted": "Deleted profile %s.", "command.reload": "Reload", "command.reload.description": "Reloads many systems.", "command.reload.warning.reloading": "Reloading systems, this may take a while.", "command.reset": "Reset", "command.reset.description": "Resets specified settings.", + "command.reset.info.module": "Reset all settings.", + "command.reset.info.modules": "Reset all module settings.", + "command.reset.info.gui": "Reset all GUI settings.", + "command.reset.info.bind": "Reset bind.", + "command.reset.info.binds": "Reset all binds.", + "command.reset.info.hud": "Reset all elements.", "command.rotation": "Rotation", "command.rotation.description": "Modifies your rotation.", "command.save-map": "Save Map", @@ -148,6 +168,27 @@ "command.say.description": "Sends messages in chat.", "command.server": "Server", "command.server.description": "Prints server information", + "command.server.error.cant_obtain_info": "Couldn't obtain any server information.", + "command.server.error.no_plugins": "No plugins found.", + "command.server.error.plugins": "An error occurred while trying to find plugins.", + "command.server.info.tps": "Current TPS: %s.", + "command.server.info.singleplayer": "Singleplayer", + "command.server.info.version": "Version: %s", + "command.server.info.copy": "Copy to clipboard", + "command.server.info.ip": "IP: %s", + "command.server.info.port": "Port: %d", + "command.server.info.type": "Type: %s", + "command.server.info.unknown": "unknown", + "command.server.info.motd": "Motd: %s", + "command.server.info.protocol_version": "Protocol version: %d", + "command.server.info.difficulty": "Difficulty: %s (Local: %.2f)", + "command.server.info.day": "Day: %d", + "command.server.info.permission_owner": "Permission level: 4 (Owner)", + "command.server.info.permission_admin": "Permission level: 3 (Admin)", + "command.server.info.permission_gamemaster": "Permission level: 2 (Gamemaster)", + "command.server.info.permission_moderator": "Permission level: 1 (Moderator)", + "command.server.info.permission_player": "Permission level: 0 (Player)", + "command.server.info.plugins": "Plugins (%d): %s", "command.settings": "Settings", "command.settings.description": "Allows you to view and change module settings.", "command.spectate": "Spectate", From e4b3bc532b17d157bcee0af9b2e3ce385fbffa07 Mon Sep 17 00:00:00 2001 From: crosby-moe <32882447+crosby-moe@users.noreply.github.com> Date: Thu, 5 Feb 2026 10:03:01 -0500 Subject: [PATCH 08/14] map some modules --- .../meteorclient/systems/modules/Module.java | 8 ++--- .../systems/modules/combat/AnchorAura.java | 2 +- .../systems/modules/misc/BookBot.java | 14 +++----- .../systems/modules/misc/Notifier.java | 32 +++++++++++-------- .../modules/render/WaypointsModule.java | 5 +-- .../assets/meteor-client/language/en_us.json | 10 ++++++ 6 files changed, 40 insertions(+), 31 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/Module.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/Module.java index fe201d007a..e33a4422d8 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/Module.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/Module.java @@ -118,7 +118,7 @@ public void disable() { public void sendToggledMsg() { if (Config.get().chatFeedback.get() && chatFeedback) { ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.sendMsgRaw(this.hashCode(), Formatting.GRAY, "Toggled (highlight)%s(default) %s(default).", null /* todo translatable Text */, isActive() ? Formatting.GREEN + "on" : Formatting.RED + "off"); + ChatUtils.sendMsg(this.hashCode(), Formatting.GRAY, "module.base.toggled", this.getTitleText(), isActive() ? Text.literal("on").formatted(Formatting.GREEN) : Text.literal("off").formatted(Formatting.RED)); } } @@ -129,7 +129,7 @@ public void info(Text message) { public void info(String messageKey, Object... args) { ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.infoPrefix(this.getTranslationKey(), messageKey, args); + ChatUtils.infoPrefix(this.getTranslationKey(), this.getTranslationKey() + ".info." + messageKey, args); } public void infoRaw(String message, Object... args) { @@ -139,7 +139,7 @@ public void infoRaw(String message, Object... args) { public void warning(String messageKey, Object... args) { ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.warningPrefix(this.getTranslationKey(), messageKey, args); + ChatUtils.warningPrefix(this.getTranslationKey(), this.getTranslationKey() + ".warning." + messageKey, args); } public void warningRaw(String message, Object... args) { @@ -149,7 +149,7 @@ public void warningRaw(String message, Object... args) { public void error(String messageKey, Object... args) { ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.errorPrefix(this.getTranslationKey(), messageKey, args); + ChatUtils.errorPrefix(this.getTranslationKey(), this.getTranslationKey() + ".error." + messageKey, args); } public void errorRaw(String message, Object... args) { diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AnchorAura.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AnchorAura.java index 4ec0336548..f905143086 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AnchorAura.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AnchorAura.java @@ -251,7 +251,7 @@ public void onDeactivate() { @EventHandler private void onTick(TickEvent.Pre event) { if (mc.world.getRegistryKey() == World.NETHER) { - error("You can't blow up respawn anchors in this dimension, disabling."); + error("wrong_dimension"); toggle(); return; } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/BookBot.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/BookBot.java index 9e8734dc42..d963c0a1b7 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/BookBot.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/BookBot.java @@ -16,6 +16,7 @@ import meteordevelopment.meteorclient.settings.*; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; +import meteordevelopment.meteorclient.utils.misc.MeteorTranslations; import meteordevelopment.meteorclient.utils.player.FindItemResult; import meteordevelopment.meteorclient.utils.player.InvUtils; import meteordevelopment.orbit.EventHandler; @@ -218,15 +219,10 @@ private void onTick(TickEvent.Post event) { // Handle the file being empty if (file.length() == 0) { - MutableText message = Text.literal(""); - message.append(Text.literal("The bookbot file is empty! ").formatted(Formatting.RED)); - message.append(Text.literal("Click here to edit it.") - .setStyle(Style.EMPTY - .withFormatting(Formatting.UNDERLINE, Formatting.RED) - .withClickEvent(new ClickEvent.OpenFile(file.getAbsolutePath())) - ) - ); - info(message); + error("file_empty", MeteorClient.translatable(this.getTranslationKey() + ".click_to_edit_file").setStyle(Style.EMPTY + .withFormatting(Formatting.UNDERLINE, Formatting.RED) + .withClickEvent(new ClickEvent.OpenFile(file.getAbsolutePath())) + )); toggle(); return; } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/Notifier.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/Notifier.java index cc6dc6fd3e..058604173a 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/Notifier.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/Notifier.java @@ -190,17 +190,17 @@ private void onEntityAdded(EntityAddedEvent event) { if (!event.entity.getUuid().equals(mc.player.getUuid()) && entities.get().contains(event.entity.getType()) && visualRange.get() && this.event.get() != Event.Despawn) { if (event.entity instanceof PlayerEntity) { if ((!visualRangeIgnoreFriends.get() || !Friends.get().isFriend(((PlayerEntity) event.entity))) && (!visualRangeIgnoreFakes.get() || !(event.entity instanceof FakePlayerEntity))) { - ChatUtils.sendMsgRaw(event.entity.getId() + 100, Formatting.GRAY, "(highlight)%s(default) has entered your visual range!", event.entity.getName().getString()); + ChatUtils.sendMsg(event.entity.getId() + 100, Formatting.GRAY, this.getTranslationKey() + ".info.entered_visual_range", event.entity.getName().getString()); if (visualMakeSound.get()) mc.world.playSoundFromEntity(mc.player, mc.player, SoundEvents.ENTITY_EXPERIENCE_ORB_PICKUP, SoundCategory.AMBIENT, 3.0F, 1.0F); } } else { - MutableText text = Text.literal(event.entity.getType().getName().getString()).formatted(Formatting.WHITE); - text.append(Text.literal(" has spawned at ").formatted(Formatting.GRAY)); - text.append(formatCoords(event.entity.getEntityPos())); - text.append(Text.literal(".").formatted(Formatting.GRAY)); - info(text); + info( + "spawned", + Text.literal(event.entity.getType().getName().getString()).formatted(Formatting.WHITE), + formatCoords(event.entity.getEntityPos()) + ); } } @@ -214,17 +214,17 @@ private void onEntityRemoved(EntityRemovedEvent event) { if (!event.entity.getUuid().equals(mc.player.getUuid()) && entities.get().contains(event.entity.getType()) && visualRange.get() && this.event.get() != Event.Spawn) { if (event.entity instanceof PlayerEntity) { if ((!visualRangeIgnoreFriends.get() || !Friends.get().isFriend(((PlayerEntity) event.entity))) && (!visualRangeIgnoreFakes.get() || !(event.entity instanceof FakePlayerEntity))) { - ChatUtils.sendMsgRaw(event.entity.getId() + 100, Formatting.GRAY, "(highlight)%s(default) has left your visual range!", event.entity.getName().getString()); + ChatUtils.sendMsg(event.entity.getId() + 100, Formatting.GRAY, this.getTranslationKey() + ".info.left_visual_range", event.entity.getName().getString()); if (visualMakeSound.get()) mc.world.playSoundFromEntity(mc.player, mc.player, SoundEvents.ENTITY_EXPERIENCE_ORB_PICKUP, SoundCategory.AMBIENT, 3.0F, 1.0F); } } else { - MutableText text = Text.literal(event.entity.getType().getName().getString()).formatted(Formatting.WHITE); - text.append(Text.literal(" has despawned at ").formatted(Formatting.GRAY)); - text.append(formatCoords(event.entity.getEntityPos())); - text.append(Text.literal(".").formatted(Formatting.GRAY)); - info(text); + info( + "despawned", + Text.literal(event.entity.getType().getName().getString()).formatted(Formatting.WHITE), + formatCoords(event.entity.getEntityPos()) + ); } } @@ -236,7 +236,13 @@ private void onEntityRemoved(EntityRemovedEvent event) { if (pearl.getOwner() != null && pearl.getOwner() instanceof PlayerEntity p) { double d = pearlStartPosMap.get(i).distanceTo(e.getEntityPos()); if ((!Friends.get().isFriend(p) || !pearlIgnoreFriends.get()) && (!p.equals(mc.player) || !pearlIgnoreOwn.get())) { - info("(highlight)%s's(default) pearl landed at %d, %d, %d (highlight)(%.1fm away, travelled %.1fm)(default).", pearl.getOwner().getName().getString(), pearl.getBlockPos().getX(), pearl.getBlockPos().getY(), pearl.getBlockPos().getZ(), pearl.distanceTo(mc.player), d); + info( + "pearl_landed", + Text.literal(pearl.getOwner().getName().getString()).formatted(Formatting.WHITE), + ChatUtils.formatCoords(pearl.getEntityPos()), + String.format("%.1f", pearl.distanceTo(mc.player)), + String.format("%.1f", d) + ); } } pearlStartPosMap.remove(i); diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/WaypointsModule.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/WaypointsModule.java index 2991aea436..075cb0e1a9 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/WaypointsModule.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/WaypointsModule.java @@ -171,10 +171,7 @@ private void onOpenScreen(OpenScreenEvent event) { public void addDeath(Vec3d deathPos) { String time = dateFormat.format(new Date()); if (dpChat.get()) { - MutableText text = Text.literal("Died at "); - text.append(formatCoords(deathPos)); - text.append(String.format(" on %s.", time)); - info(text); + info("death", formatCoords(deathPos), time); } // Create waypoint diff --git a/src/main/resources/assets/meteor-client/language/en_us.json b/src/main/resources/assets/meteor-client/language/en_us.json index fd8518ab51..715c07a8a0 100644 --- a/src/main/resources/assets/meteor-client/language/en_us.json +++ b/src/main/resources/assets/meteor-client/language/en_us.json @@ -835,6 +835,7 @@ "module.base.copy-config": "Copy config", "module.base.paste-config": "Paste config", "module.base.from": "From: ", + "module.base.toggled": "Toggled %1$s %2$s.", "module.air-jump": "Air Jump", "module.air-jump.description": "Lets you jump in the air.", @@ -1075,6 +1076,11 @@ "module.notifier.joins/leaves.notification-delay.description": "How long to wait in ticks before posting the next join/leave notification in your chat.", "module.notifier.joins/leaves.simple-notifications": "Simple Notifications", "module.notifier.joins/leaves.simple-notifications.description": "Display join/leave notifications without a prefix, to reduce chat clutter.", + "module.notifier.info.despawned": "%1$s has despawned at %2$.", + "module.notifier.info.spawned": "%1$s has spawned at %2$.", + "module.notifier.info.entered_visual_range": "%s has entered your visual range!", + "module.notifier.info.left_visual_range": "%s has left your visual range!", + "module.notifier.info.pearl_landed": "%1$s's pearl landed at %2$s (%3$sm away, travelled %4$sm).", "module.item-physics": "Item Physics", "module.item-physics.description": "Applies physics to items on the ground.", @@ -1357,6 +1363,8 @@ "module.book-bot.general.append-count.description": "Whether to append the number of the book to the title.", "module.book-bot.general.word-wrap": "Word Wrap", "module.book-bot.general.word-wrap.description": "Prevents words from being cut in the middle of lines.", + "module.book-bot.error.file_empty": "The bookbot file is empty!", + "module.book-bot.click_to_edit_file": "Click here to edit it.", "module.auto-gap": "Auto Gap", "module.auto-gap.description": "Automatically eats Gaps or E-Gaps.", @@ -3520,6 +3528,7 @@ "module.waypoints.death-position.max-death-positions.description": "The amount of death positions to save, 0 to disable", "module.waypoints.death-position.chat": "Chat", "module.waypoints.death-position.chat.description": "Send a chat message with your position once you die", + "module.waypoints.info.death": "Died at %1$s on %2$s.", "module.auto-web": "Auto Web", "module.auto-web.description": "Automatically places webs on other players.", @@ -3947,6 +3956,7 @@ "module.anchor-aura.render.side-color.description": "The side color for positions to be placed.", "module.anchor-aura.render.line-color": "Line Color", "module.anchor-aura.render.line-color.description": "The line color for positions to be placed.", + "module.anchor-aura.error.wrong_dimension": "You can't blow up respawn anchors in this dimension, disabling.", "module.anti-void": "Anti Void", "module.anti-void.description": "Attempts to prevent you from falling into the void.", From 45f0779ae6401b5231a0857b41c42371431ed493 Mon Sep 17 00:00:00 2001 From: crosby-moe <32882447+crosby-moe@users.noreply.github.com> Date: Thu, 5 Feb 2026 10:10:29 -0500 Subject: [PATCH 09/14] oops! wrong choice --- .../commands/commands/NotebotCommand.java | 2 +- .../commands/commands/ServerCommand.java | 4 +-- .../text/MeteorTranslatableTextComponent.java | 25 +++---------------- .../assets/meteor-client/language/en_us.json | 16 ++++++------ 4 files changed, 15 insertions(+), 32 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/NotebotCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/NotebotCommand.java index 6eba86f857..03c3537bd7 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/NotebotCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/NotebotCommand.java @@ -198,7 +198,7 @@ private Note getNote(PlaySoundS2CPacket soundPacket) { } if (noteLevel == -1) { - error("bruteforce", soundPacket.getSound().value(), pitch); + error("bruteforce", soundPacket.getSound().value(), String.format("%.3f", pitch)); return null; } diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/ServerCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/ServerCommand.java index a781970756..1f87b249ad 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/ServerCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/ServerCommand.java @@ -145,12 +145,12 @@ private void basicInfo() { info("protocol_version", server.protocolVersion); info("difficulty", mc.world.getDifficulty().getTranslatableName(), - new LocalDifficulty( + String.format("%.2f", new LocalDifficulty( mc.world.getDifficulty(), mc.world.getTimeOfDay(), mc.world.getChunk(mc.player.getBlockPos()).getInhabitedTime(), DimensionType.MOON_SIZES[mc.world.getEnvironmentAttributes().getAttributeValue(EnvironmentAttributes.MOON_PHASE_VISUAL, mc.player.getBlockPos()).getIndex()] // lol - ).getLocalDifficulty() + ).getLocalDifficulty()) ); info("day", mc.world.getTimeOfDay() / 24000L); info(formatPerms()); diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MeteorTranslatableTextComponent.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MeteorTranslatableTextComponent.java index 1f89367989..f99b3ab4b5 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MeteorTranslatableTextComponent.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MeteorTranslatableTextComponent.java @@ -117,9 +117,8 @@ public String toString() { private static final StringVisitable LITERAL_PERCENT_SIGN = StringVisitable.plain("%"); private static final StringVisitable NULL_ARGUMENT = StringVisitable.plain("null"); - // %, optional position argument (\d$), string format (s) || percent literal (%|$) || number format ([-+.]? \d* [df]) - @SuppressWarnings("RegExpRedundantEscape") // then why does it IllegalArgumentException when i remove it dipshit - private static final Pattern ARG_FORMAT = Pattern.compile("%(?:(\\d+)\\$)?([s%]|$|[-+\\.]?\\d*[df])"); + // %, optional position argument (\d$), string format (s) || percent literal (%|$) + private static final Pattern ARG_FORMAT = Pattern.compile("%(?:(\\d+)\\$)?([s%]|$)"); private void forEachPart(String translation, Consumer partsConsumer) { Matcher matcher = ARG_FORMAT.matcher(translation); @@ -158,24 +157,8 @@ private void forEachPart(String translation, Consumer partsCons : argument == null ? NULL_ARGUMENT : StringVisitable.plain(argument.toString()); partsConsumer.accept(visitableArgument); - } else if (argument instanceof StringVisitable) { - if (argument instanceof MutableText mutableText && mutableText.getSiblings().isEmpty() && mutableText.getContent() instanceof PlainTextContent content) { - try { // attempt to use formatting - String format = "%" + string; - partsConsumer.accept(StringVisitable.styled(String.format(format, content.string()), mutableText.getStyle())); - } catch (IllegalFormatException e) { - throw new TranslationException(new TranslatableTextContent(this.key, this.fallback, this.args), index); - } - } else { // cant use format strings on non-constant/complex arguments - throw new TranslationException(new TranslatableTextContent(this.key, this.fallback, this.args), "Cant use complex format string with Text"); - } - } else { // attempt to use formatting - try { - String format = "%" + string; - partsConsumer.accept(StringVisitable.plain(String.format(format, argument))); - } catch (IllegalFormatException e) { - throw new TranslationException(new TranslatableTextContent(this.key, this.fallback, this.args), index); - } + } else { + throw new TranslationException(new TranslatableTextContent(this.key, this.fallback, this.args), "Unsupported format: '" + string2 + "'"); } } diff --git a/src/main/resources/assets/meteor-client/language/en_us.json b/src/main/resources/assets/meteor-client/language/en_us.json index 715c07a8a0..8c987ee54e 100644 --- a/src/main/resources/assets/meteor-client/language/en_us.json +++ b/src/main/resources/assets/meteor-client/language/en_us.json @@ -108,7 +108,7 @@ "command.locate.info.second_eye_saved": "Second Eye of Ender's trajectory saved.", "command.locate.info.eye_different_location": "Please throw the second Eye Of Ender from a different location.", "command.locate.warning.canceled": "Locate canceled", - "command.locate.warning.false_positive": "Only %d block(s) found. This search might be a false positive.", + "command.locate.warning.false_positive": "Only %s block(s) found. This search might be a false positive.", "command.macro": "Macro", "command.macro.description": "Allows you to execute macros.", "command.macro.error.none_scheduled": "No macros are currently scheduled.", @@ -127,13 +127,13 @@ "command.nbt.error.no_item": "You must hold an item in your main hand.", "command.nbt.info.copy_tooltip": "Copy the NBT data to your clipboard.", "command.nbt.info.copy": "%s %s data copied!", - "command.nbt.info.count": "Set mainhand stack count to %d.", + "command.nbt.info.count": "Set mainhand stack count to %s.", "command.notebot": "Notebot", "command.notebot.description": "Allows you load notebot files", "command.notebot.error.invalid_song": "Invalid song.", "command.notebot.error.invalid_path": "'%s' is not a valid path.", "command.notebot.error.cant_create_file": "Couldn't create the file.", - "command.notebot.error.bruteforce": "Error while bruteforcing a note level! Sound: %s Pitch: %.3f", + "command.notebot.error.bruteforce": "Error while bruteforcing a note level! Sound: %1$s Pitch: %2$s", "command.notebot.error.instrument": "Can't find the instrument from sound! Sound: %s", "command.notebot.info.recording_started": "Recording started", "command.notebot.info.recording_cancelled": "Recording cancelled", @@ -176,19 +176,19 @@ "command.server.info.version": "Version: %s", "command.server.info.copy": "Copy to clipboard", "command.server.info.ip": "IP: %s", - "command.server.info.port": "Port: %d", + "command.server.info.port": "Port: %s", "command.server.info.type": "Type: %s", "command.server.info.unknown": "unknown", "command.server.info.motd": "Motd: %s", - "command.server.info.protocol_version": "Protocol version: %d", - "command.server.info.difficulty": "Difficulty: %s (Local: %.2f)", - "command.server.info.day": "Day: %d", + "command.server.info.protocol_version": "Protocol version: %s", + "command.server.info.difficulty": "Difficulty: %1$s (Local: %2$s)", + "command.server.info.day": "Day: %s", "command.server.info.permission_owner": "Permission level: 4 (Owner)", "command.server.info.permission_admin": "Permission level: 3 (Admin)", "command.server.info.permission_gamemaster": "Permission level: 2 (Gamemaster)", "command.server.info.permission_moderator": "Permission level: 1 (Moderator)", "command.server.info.permission_player": "Permission level: 0 (Player)", - "command.server.info.plugins": "Plugins (%d): %s", + "command.server.info.plugins": "Plugins (%1$s): %2$s", "command.settings": "Settings", "command.settings.description": "Allows you to view and change module settings.", "command.spectate": "Spectate", From 2580a96631bde342432da1730168a9d8c426dfc8 Mon Sep 17 00:00:00 2001 From: crosby-moe <32882447+crosby-moe@users.noreply.github.com> Date: Thu, 5 Feb 2026 10:11:22 -0500 Subject: [PATCH 10/14] 'TranslatableTextContent', not 'TranslatableTextComponent' --- .../java/meteordevelopment/meteorclient/MeteorClient.java | 6 +++--- ...tComponent.java => MeteorTranslatableTextContent.java} | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) rename src/main/java/meteordevelopment/meteorclient/utils/misc/text/{MeteorTranslatableTextComponent.java => MeteorTranslatableTextContent.java} (95%) diff --git a/src/main/java/meteordevelopment/meteorclient/MeteorClient.java b/src/main/java/meteordevelopment/meteorclient/MeteorClient.java index 65a16e6b19..4f97de9dd5 100644 --- a/src/main/java/meteordevelopment/meteorclient/MeteorClient.java +++ b/src/main/java/meteordevelopment/meteorclient/MeteorClient.java @@ -27,7 +27,7 @@ import meteordevelopment.meteorclient.utils.misc.Version; import meteordevelopment.meteorclient.utils.misc.input.KeyAction; import meteordevelopment.meteorclient.utils.misc.input.KeyBinds; -import meteordevelopment.meteorclient.utils.misc.text.MeteorTranslatableTextComponent; +import meteordevelopment.meteorclient.utils.misc.text.MeteorTranslatableTextContent; import meteordevelopment.meteorclient.utils.network.OnlinePlayers; import meteordevelopment.orbit.EventBus; import meteordevelopment.orbit.EventHandler; @@ -201,10 +201,10 @@ public static Identifier identifier(String path) { } public static MutableText translatable(String key, Object... args) { - return MutableText.of(new MeteorTranslatableTextComponent(key, args)); + return MutableText.of(new MeteorTranslatableTextContent(key, args)); } public static MutableText translatable(String key, String fallback, Object... args) { - return MutableText.of(new MeteorTranslatableTextComponent(key, fallback, args)); + return MutableText.of(new MeteorTranslatableTextContent(key, fallback, args)); } } diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MeteorTranslatableTextComponent.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MeteorTranslatableTextContent.java similarity index 95% rename from src/main/java/meteordevelopment/meteorclient/utils/misc/text/MeteorTranslatableTextComponent.java rename to src/main/java/meteordevelopment/meteorclient/utils/misc/text/MeteorTranslatableTextContent.java index f99b3ab4b5..cd7cc39f9a 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MeteorTranslatableTextComponent.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MeteorTranslatableTextContent.java @@ -21,7 +21,7 @@ import static meteordevelopment.meteorclient.MeteorClient.mc; -public class MeteorTranslatableTextComponent implements TextContent { +public class MeteorTranslatableTextContent implements TextContent { private static final boolean DEBUG_MISSING_ENTRIES = FabricLoader.getInstance().isDevelopmentEnvironment() || Boolean.getBoolean("meteor.lang.debug"); private final String key; @Nullable @@ -32,7 +32,7 @@ public class MeteorTranslatableTextComponent implements TextContent { private String cachedLanguage; private List translations = ImmutableList.of(); - public MeteorTranslatableTextComponent(String key, @Nullable String fallback, Object... args) { + public MeteorTranslatableTextContent(String key, @Nullable String fallback, Object... args) { this.key = key; this.fallback = fallback; this.args = args; @@ -47,7 +47,7 @@ public MeteorTranslatableTextComponent(String key, @Nullable String fallback, Ob this.styledArgs = hasStyledArgs; } - public MeteorTranslatableTextComponent(String key, Object... args) { + public MeteorTranslatableTextContent(String key, Object... args) { this(key, null, args); } @@ -105,7 +105,7 @@ public MapCodec getCodec() { @Override public boolean equals(@Nullable Object o) { if (this == o) return true; - if (!(o instanceof MeteorTranslatableTextComponent component)) return false; + if (!(o instanceof MeteorTranslatableTextContent component)) return false; return Objects.equals(this.key, component.key) && Objects.equals(this.fallback, component.fallback) && Arrays.equals(this.args, component.args); } From a62131c1b93c50234c62a6eb4053e70647f8ef6e Mon Sep 17 00:00:00 2001 From: crosby-moe <32882447+crosby-moe@users.noreply.github.com> Date: Thu, 5 Feb 2026 17:19:37 -0500 Subject: [PATCH 11/14] `MessageBuilder` initial impl --- .../meteorclient/gui/GuiTheme.java | 6 + .../meteorclient/gui/MessageFormatter.java | 28 +++ .../gui/themes/meteor/MeteorGuiTheme.java | 18 ++ .../themes/meteor/MeteorMessageFormatter.java | 92 +++++++ .../utils/misc/text/MessageBuilder.java | 27 ++ .../utils/misc/text/MessageBuilderImpl.java | 237 ++++++++++++++++++ .../utils/misc/text/MessageKind.java | 13 + .../text/MeteorTranslatableTextContent.java | 7 + .../meteorclient/utils/player/ChatUtils.java | 9 + 9 files changed, 437 insertions(+) create mode 100644 src/main/java/meteordevelopment/meteorclient/gui/MessageFormatter.java create mode 100644 src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/MeteorMessageFormatter.java create mode 100644 src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageBuilder.java create mode 100644 src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageBuilderImpl.java create mode 100644 src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageKind.java diff --git a/src/main/java/meteordevelopment/meteorclient/gui/GuiTheme.java b/src/main/java/meteordevelopment/meteorclient/gui/GuiTheme.java index 6481d0e6ee..8b4f3e5862 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/GuiTheme.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/GuiTheme.java @@ -31,6 +31,8 @@ import net.minecraft.client.gui.screen.Screen; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NbtCompound; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; import net.minecraft.util.math.BlockPos; import java.util.HashMap; @@ -279,6 +281,10 @@ public WidgetScreen proxiesScreen() { public abstract TextRenderer textRenderer(); + public abstract MessageFormatter messageFormatter(); + + public abstract Text getChatPrefix(); + public abstract double scale(double value); public abstract boolean categoryIcons(); diff --git a/src/main/java/meteordevelopment/meteorclient/gui/MessageFormatter.java b/src/main/java/meteordevelopment/meteorclient/gui/MessageFormatter.java new file mode 100644 index 0000000000..b53453e9bf --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/gui/MessageFormatter.java @@ -0,0 +1,28 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.gui; + +import meteordevelopment.meteorclient.utils.misc.text.MessageKind; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.Vec3i; + +public interface MessageFormatter { + Text formatPlayerName(PlayerEntity player); + Text formatEntityName(Entity entity); + + Text formatCoords(Vec3i blockPos); + Text formatCoords(Vec3d pos); + + Text formatHighlight(MutableText text); + Text formatDecimal(double decimal); + + Text formatPrefix(Text prefix); + Text formatMessage(MutableText message, MessageKind messageKind); +} diff --git a/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/MeteorGuiTheme.java b/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/MeteorGuiTheme.java index 86b1819ed9..60578c6dda 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/MeteorGuiTheme.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/MeteorGuiTheme.java @@ -5,8 +5,10 @@ package meteordevelopment.meteorclient.gui.themes.meteor; +import meteordevelopment.meteorclient.MeteorClient; import meteordevelopment.meteorclient.gui.DefaultSettingsWidgetFactory; import meteordevelopment.meteorclient.gui.GuiTheme; +import meteordevelopment.meteorclient.gui.MessageFormatter; import meteordevelopment.meteorclient.gui.WidgetScreen; import meteordevelopment.meteorclient.gui.renderer.packer.GuiTexture; import meteordevelopment.meteorclient.gui.themes.meteor.widgets.*; @@ -31,6 +33,9 @@ import meteordevelopment.meteorclient.utils.render.color.Color; import meteordevelopment.meteorclient.utils.render.color.SettingColor; import net.minecraft.client.util.MacWindowUtil; +import net.minecraft.text.Style; +import net.minecraft.text.Text; +import net.minecraft.text.TextColor; import static meteordevelopment.meteorclient.MeteorClient.mc; @@ -161,6 +166,9 @@ public class MeteorGuiTheme extends GuiTheme { private final Setting starscriptKeywords = color(sgStarscript, "starscript-keywords", new SettingColor(204, 120, 50)); private final Setting starscriptAccessedObjects = color(sgStarscript, "starscript-accessed-objects", new SettingColor(152, 118, 170)); + private final MessageFormatter messageFormatter = new MeteorMessageFormatter(); + private final Text chatPrefix = Text.literal(MeteorClient.NAME).setStyle(Style.EMPTY.withColor(TextColor.fromRgb(MeteorClient.ADDON.color.getPacked()))); + public MeteorGuiTheme() { super("Meteor"); @@ -361,6 +369,16 @@ public TextRenderer textRenderer() { return TextRenderer.get(); } + @Override + public MessageFormatter messageFormatter() { + return this.messageFormatter; + } + + @Override + public Text getChatPrefix() { + return this.chatPrefix; + } + @Override public double scale(double value) { double scaled = value * scale.get(); diff --git a/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/MeteorMessageFormatter.java b/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/MeteorMessageFormatter.java new file mode 100644 index 0000000000..6ab7ffefe5 --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/MeteorMessageFormatter.java @@ -0,0 +1,92 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.gui.themes.meteor; + +import meteordevelopment.meteorclient.gui.MessageFormatter; +import meteordevelopment.meteorclient.pathing.NopPathManager; +import meteordevelopment.meteorclient.pathing.PathManagers; +import meteordevelopment.meteorclient.utils.misc.text.MessageKind; +import meteordevelopment.meteorclient.utils.misc.text.RunnableClickEvent; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.text.HoverEvent; +import net.minecraft.text.MutableText; +import net.minecraft.text.Style; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.Vec3i; + +import java.text.DecimalFormat; + +public class MeteorMessageFormatter implements MessageFormatter { + private final DecimalFormat decimalFormat = new DecimalFormat("0.0##"); + + @Override + public Text formatPlayerName(PlayerEntity player) { + return player.getName(); + } + + @Override + public Text formatEntityName(Entity entity) { + return Text.literal(entity.getName().getString()); + } + + @Override + public Text formatCoords(Vec3i blockPos) { + return formatCoords(blockPos.getX(), blockPos.getY(), blockPos.getZ()); + } + + @Override + public Text formatCoords(Vec3d pos) { + return formatCoords((int) Math.round(pos.getX()), (int) Math.round(pos.getY()), (int) Math.round(pos.getZ())); + } + + private Text formatCoords(int x, int y, int z) { + Style style = Style.EMPTY.withFormatting(Formatting.WHITE).withUnderline(true); + + if (!(PathManagers.get() instanceof NopPathManager)) { + style = style.withBold(true) + .withHoverEvent(new HoverEvent.ShowText( + Text.literal("Set as pathing goal") + )) + .withClickEvent(new RunnableClickEvent( + () -> PathManagers.get().moveTo(new BlockPos(x, y, z)) + )); + } + + return Text.literal(x + ", " + y + ", " + z).setStyle(style); + } + + @Override + public Text formatHighlight(MutableText text) { + return text.formatted(Formatting.WHITE); + } + + @Override + public Text formatDecimal(double decimal) { + return Text.literal(this.decimalFormat.format(decimal)); + } + + @Override + public Text formatPrefix(Text prefix) { + return Text.empty().formatted(Formatting.GRAY) + .append("[") + .append(prefix) + .append("] "); + } + + @Override + public Text formatMessage(MutableText message, MessageKind messageKind) { + return switch (messageKind) { + case Passthrough -> message; + case Info -> message.formatted(Formatting.GRAY); + case Warning -> message.formatted(Formatting.YELLOW); + case Error -> message.formatted(Formatting.RED); + }; + } +} diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageBuilder.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageBuilder.java new file mode 100644 index 0000000000..8ed7d5a4aa --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageBuilder.java @@ -0,0 +1,27 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.utils.misc.text; + +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; + +public interface MessageBuilder { + MessageBuilder setId(int id); + MessageBuilder setKind(MessageKind kind); + MessageBuilder overrideClientPrefix(Class holder); + + MessageBuilder prefix(MutableText prefix); + MessageBuilder prefix(String prefix); + MessageBuilder prefix(String prefix, Formatting prefixColor); + + MessageBuilder body(MutableText body); + MessageBuilder body(String body, Object... args); + MessageBuilder content(String translationKey, Object... args); + + Text build(); + void send(); +} diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageBuilderImpl.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageBuilderImpl.java new file mode 100644 index 0000000000..3ad4e5bcc8 --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageBuilderImpl.java @@ -0,0 +1,237 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.utils.misc.text; + +import meteordevelopment.meteorclient.gui.GuiTheme; +import meteordevelopment.meteorclient.gui.GuiThemes; +import meteordevelopment.meteorclient.gui.MessageFormatter; +import meteordevelopment.meteorclient.mixininterface.IChatHud; +import meteordevelopment.meteorclient.systems.config.Config; +import meteordevelopment.meteorclient.utils.player.ChatUtils; +import net.minecraft.block.Block; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.effect.StatusEffect; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; +import net.minecraft.text.MutableText; +import net.minecraft.text.StringVisitable; +import net.minecraft.text.Style; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; +import net.minecraft.util.Pair; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.Vec3i; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.function.Supplier; + +import static meteordevelopment.meteorclient.MeteorClient.mc; + +public class MessageBuilderImpl implements MessageBuilder { + private final GuiTheme theme = GuiThemes.get(); + private final MessageFormatter formatter = this.theme.messageFormatter(); + + private int id = 0; + private MessageKind kind; + private @Nullable Class topLevelPrefix; + private @Nullable Text messagePrefix; + private @Nullable MutableText messageBody; + private Object[] args; + + private boolean hasStyledArgs = false; + private boolean closed = false; + + /* Builder functions */ + + @Override + public MessageBuilder setId(int id) { + assertOpen(); + this.id = id; + return this; + } + + @Override + public MessageBuilder setKind(MessageKind kind) { + assertOpen(); + this.kind = kind; + return this; + } + + @Override + public MessageBuilder overrideClientPrefix(Class holder) { + assertOpen(); + this.topLevelPrefix = holder; + return this; + } + + @Override + public MessageBuilder prefix(MutableText prefix) { + assertOpen(); + this.messagePrefix = prefix; + return this; + } + + @Override + public MessageBuilder prefix(String prefix) { + assertOpen(); + this.messagePrefix = Text.literal(prefix); + return this; + } + + @Override + public MessageBuilder prefix(String prefix, Formatting prefixColor) { + assertOpen(); + this.messagePrefix = Text.literal(prefix).formatted(prefixColor); + return this; + } + + @Override + public MessageBuilder body(MutableText body) { + assertOpen(); + this.messageBody = body; + return this; + } + + @Override + public MessageBuilder body(String body, Object... args) { + assertOpen(); + processArgs(args); + this.messageBody = Text.literal(String.format(body, args)); + return this; + } + + @Override + public MessageBuilder content(String translationKey, Object... args) { + assertOpen(); + processArgs(args); + this.messageBody = MutableText.of(new MeteorTranslatableTextContent( + translationKey, null, args, this.hasStyledArgs + )); + return this; + } + + /* Terminal Functions */ + + @Override + public Text build() { + closed = true; + if (this.messageBody == null) { + throw new IllegalArgumentException("Message body cannot be empty!"); + } else if (this.kind == null) { + throw new IllegalArgumentException("Message cannot have a kind!"); + } + + MutableText message = Text.empty() + .append(this.formatter.formatPrefix(this.getPrefix())); + + if (this.messagePrefix != null) { + message.append(this.formatter.formatPrefix(this.messagePrefix)); + } + + message.append(this.formatter.formatMessage(this.messageBody, this.kind)); + + return message; + } + + @Override + public void send() { + if (mc.world == null) return; + + Text message = this.build(); + int messageId = Config.get().deleteChatFeedback.get() ? this.id : 0; + + if (mc.isOnThread()) { + ((IChatHud) mc.inGameHud.getChatHud()).meteor$add(message, messageId); + } else { + mc.execute(() -> ((IChatHud) mc.inGameHud.getChatHud()).meteor$add(message, messageId)); + } + } + + /* Internal Functions */ + + private void processArgs(Object[] args) { + hasStyledArgs = false; + + for (int i = 0; i < args.length; i++) { + Object arg = args[i]; + args[i] = switch (arg) { + // theme-dependent formatting + case PlayerEntity player -> { hasStyledArgs = true; yield this.formatter.formatPlayerName(player); } + case Entity entity -> { hasStyledArgs = true; yield this.formatter.formatEntityName(entity); } + case Vec3i vec -> { hasStyledArgs = true; yield this.formatter.formatCoords(vec); } + case Vec3d vec -> { hasStyledArgs = true; yield this.formatter.formatCoords(vec); } + case Float f -> { hasStyledArgs = true; yield this.formatter.formatDecimal(f); } + case Double d -> { hasStyledArgs = true; yield this.formatter.formatDecimal(d); } + + // accept common objects as parameters + case StatusEffect statusEffect -> stripStyle(statusEffect.getName()); + case Item item -> stripStyle(item.getName()); + case Block block -> stripStyle(block.getName()); + case EntityType type -> stripStyle(type.getName()); + + case StringVisitable stringVisitable -> { hasStyledArgs = true; yield stringVisitable; } + default -> String.valueOf(arg); + }; + } + } + + private Text stripStyle(Text text) { + if (text instanceof MutableText mutable) { + mutable.setStyle(Style.EMPTY); + for (Text sibling : mutable.getSiblings()) { + stripStyle(sibling); + } + } + return text; + } + + private Text getPrefix() { + List>> customPrefixes = ChatUtils.getCustomPrefixes(); + if (customPrefixes.isEmpty()) { + return this.theme.getChatPrefix(); + } + + String className = null; + if (topLevelPrefix != null) { + className = topLevelPrefix.getName(); + } else { + boolean foundClass = false; + for (StackTraceElement element : Thread.currentThread().getStackTrace()) { + if (foundClass) { + if (!element.getClassName().equals(MessageBuilderImpl.class.getName())) { + className = element.getClassName(); + break; + } + } else { + if (element.getClassName().equals(MessageBuilderImpl.class.getName())) { + foundClass = true; + } + } + } + } + + if (className == null) { + return this.theme.getChatPrefix(); + } + + for (Pair> pair : customPrefixes) { + if (className.startsWith(pair.getLeft())) { + @Nullable Text prefix = pair.getRight().get(); + return prefix != null ? prefix : this.theme.getChatPrefix(); + } + } + + return this.theme.getChatPrefix(); + } + + private void assertOpen() { + if (this.closed) { + throw new IllegalStateException("Cannot use MessageBuilder after building message."); + } + } +} diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageKind.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageKind.java new file mode 100644 index 0000000000..cc408539bf --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageKind.java @@ -0,0 +1,13 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.utils.misc.text; + +public enum MessageKind { + Passthrough, + Info, + Warning, + Error +} diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MeteorTranslatableTextContent.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MeteorTranslatableTextContent.java index cd7cc39f9a..d35960379c 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MeteorTranslatableTextContent.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MeteorTranslatableTextContent.java @@ -51,6 +51,13 @@ public MeteorTranslatableTextContent(String key, Object... args) { this(key, null, args); } + public MeteorTranslatableTextContent(String key, @Nullable String fallback, Object[] args, boolean styledArgs) { + this.key = key; + this.fallback = fallback; + this.args = args; + this.styledArgs = styledArgs; + } + private void updateTranslations() { if (!mc.options.language.equals(this.cachedLanguage)) { cachedLanguage = mc.options.language; diff --git a/src/main/java/meteordevelopment/meteorclient/utils/player/ChatUtils.java b/src/main/java/meteordevelopment/meteorclient/utils/player/ChatUtils.java index dc0be270fc..f566e8b767 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/player/ChatUtils.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/player/ChatUtils.java @@ -7,6 +7,7 @@ import com.mojang.brigadier.StringReader; import meteordevelopment.meteorclient.MeteorClient; +import meteordevelopment.meteorclient.gui.GuiTheme; import meteordevelopment.meteorclient.mixininterface.IChatHud; import meteordevelopment.meteorclient.pathing.BaritoneUtils; import meteordevelopment.meteorclient.systems.config.Config; @@ -42,6 +43,10 @@ public static void init() { .append("] "); } + /** + * @deprecated use {@link GuiTheme#getChatPrefix()} + */ + @Deprecated public static Text getMeteorPrefix() { return PREFIX; } @@ -73,6 +78,10 @@ public static void forceNextPrefixClass(Class klass) { forcedPrefixClassName = klass.getName(); } + public static List>> getCustomPrefixes() { + return customPrefixes; + } + // Player /** From c20dccf88050069d73e9dcdbeaf548c958311f55 Mon Sep 17 00:00:00 2001 From: Crosby <32882447+crosby-moe@users.noreply.github.com> Date: Fri, 6 Feb 2026 22:29:45 -0500 Subject: [PATCH 12/14] the good, the bad and the ugly --- .../utils/misc/text/MessageBuilder.java | 8 ++- .../utils/misc/text/MessageBuilderImpl.java | 66 +++++++++++++------ .../utils/misc/text/MessageKind.java | 14 ++-- 3 files changed, 61 insertions(+), 27 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageBuilder.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageBuilder.java index 8ed7d5a4aa..bd7e7a64fa 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageBuilder.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageBuilder.java @@ -10,9 +10,14 @@ import net.minecraft.util.Formatting; public interface MessageBuilder { + static MessageBuilder create() { + return new MessageBuilderImpl(); + } + MessageBuilder setId(int id); MessageBuilder setKind(MessageKind kind); - MessageBuilder overrideClientPrefix(Class holder); + MessageBuilder setTranslationContext(String translationContext); + MessageBuilder setSource(Object source); MessageBuilder prefix(MutableText prefix); MessageBuilder prefix(String prefix); @@ -20,7 +25,6 @@ public interface MessageBuilder { MessageBuilder body(MutableText body); MessageBuilder body(String body, Object... args); - MessageBuilder content(String translationKey, Object... args); Text build(); void send(); diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageBuilderImpl.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageBuilderImpl.java index 3ad4e5bcc8..1feda4cfb5 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageBuilderImpl.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageBuilderImpl.java @@ -10,6 +10,7 @@ import meteordevelopment.meteorclient.gui.MessageFormatter; import meteordevelopment.meteorclient.mixininterface.IChatHud; import meteordevelopment.meteorclient.systems.config.Config; +import meteordevelopment.meteorclient.utils.misc.MeteorTranslations; import meteordevelopment.meteorclient.utils.player.ChatUtils; import net.minecraft.block.Block; import net.minecraft.entity.Entity; @@ -37,12 +38,15 @@ public class MessageBuilderImpl implements MessageBuilder { private final MessageFormatter formatter = this.theme.messageFormatter(); private int id = 0; - private MessageKind kind; - private @Nullable Class topLevelPrefix; + private @Nullable MessageKind kind; + private @Nullable Object source; private @Nullable Text messagePrefix; - private @Nullable MutableText messageBody; + private @Nullable MutableText messageBodyText; + private @Nullable String messageBody; private Object[] args; + private @Nullable String translationContext; + private boolean hasStyledArgs = false; private boolean closed = false; @@ -63,9 +67,16 @@ public MessageBuilder setKind(MessageKind kind) { } @Override - public MessageBuilder overrideClientPrefix(Class holder) { + public MessageBuilder setTranslationContext(String translationContext) { + assertOpen(); + this.translationContext = translationContext; + return this; + } + + @Override + public MessageBuilder setSource(Object source) { assertOpen(); - this.topLevelPrefix = holder; + this.source = source; return this; } @@ -93,7 +104,7 @@ public MessageBuilder prefix(String prefix, Formatting prefixColor) { @Override public MessageBuilder body(MutableText body) { assertOpen(); - this.messageBody = body; + this.messageBodyText = body; return this; } @@ -101,17 +112,8 @@ public MessageBuilder body(MutableText body) { public MessageBuilder body(String body, Object... args) { assertOpen(); processArgs(args); - this.messageBody = Text.literal(String.format(body, args)); - return this; - } - - @Override - public MessageBuilder content(String translationKey, Object... args) { - assertOpen(); - processArgs(args); - this.messageBody = MutableText.of(new MeteorTranslatableTextContent( - translationKey, null, args, this.hasStyledArgs - )); + this.messageBody = body; + this.args = args; return this; } @@ -119,8 +121,10 @@ public MessageBuilder content(String translationKey, Object... args) { @Override public Text build() { + assertOpen(); closed = true; - if (this.messageBody == null) { + + if (this.messageBody == null || this.messageBodyText == null) { throw new IllegalArgumentException("Message body cannot be empty!"); } else if (this.kind == null) { throw new IllegalArgumentException("Message cannot have a kind!"); @@ -133,7 +137,8 @@ public Text build() { message.append(this.formatter.formatPrefix(this.messagePrefix)); } - message.append(this.formatter.formatMessage(this.messageBody, this.kind)); + MutableText bodyText = this.messageBodyText != null ? this.messageBodyText : this.createMessageBody(this.messageBody, this.kind); + message.append(this.formatter.formatMessage(bodyText, this.kind)); return message; } @@ -197,8 +202,8 @@ private Text getPrefix() { } String className = null; - if (topLevelPrefix != null) { - className = topLevelPrefix.getName(); + if (source != null) { + className = source.getClass().getName(); } else { boolean foundClass = false; for (StackTraceElement element : Thread.currentThread().getStackTrace()) { @@ -229,6 +234,25 @@ private Text getPrefix() { return this.theme.getChatPrefix(); } + private MutableText createMessageBody(String messageBody, MessageKind kind) { + MeteorTranslations.MeteorLanguage language = MeteorTranslations.getCurrentLanguage(); + + if (language.hasTranslation(messageBody)) { + return MutableText.of(new MeteorTranslatableTextContent( + messageBody, null, this.args, this.hasStyledArgs + )); + } else if (this.translationContext != null && kind != MessageKind.Passthrough) { + String computedTranslationKey = this.translationContext + "." + kind.key + "." + messageBody; + if (language.hasTranslation(computedTranslationKey)) { + return MutableText.of(new MeteorTranslatableTextContent( + computedTranslationKey, null, this.args, this.hasStyledArgs + )); + } + } + + return Text.literal(messageBody); + } + private void assertOpen() { if (this.closed) { throw new IllegalStateException("Cannot use MessageBuilder after building message."); diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageKind.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageKind.java index cc408539bf..a7e0f0ae2c 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageKind.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageKind.java @@ -6,8 +6,14 @@ package meteordevelopment.meteorclient.utils.misc.text; public enum MessageKind { - Passthrough, - Info, - Warning, - Error + Passthrough(null), + Info("info"), + Warning("warning"), + Error("error"); + + public String key; + + MessageKind(String key) { + this.key = key; + } } From f9e8373ddef4fb2051ee0d1f7987a25294e607f8 Mon Sep 17 00:00:00 2001 From: Crosby <32882447+crosby-moe@users.noreply.github.com> Date: Sat, 14 Feb 2026 01:32:40 -0500 Subject: [PATCH 13/14] huge module feedback update --- .../meteorclient/gui/MessageFormatter.java | 8 +- .../themes/meteor/MeteorMessageFormatter.java | 32 ++- .../meteorclient/systems/modules/Module.java | 52 ++-- .../utils/misc/text/MessageBuilder.java | 112 +++++++- .../utils/misc/text/MessageBuilderImpl.java | 142 ++++------- .../text/MeteorTranslatableTextContent.java | 154 +---------- .../utils/misc/text/RichPlainTextContent.java | 41 +++ .../utils/misc/text/RichTextContent.java | 152 +++++++++++ .../meteorclient/utils/player/ChatUtils.java | 240 ++---------------- 9 files changed, 440 insertions(+), 493 deletions(-) create mode 100644 src/main/java/meteordevelopment/meteorclient/utils/misc/text/RichPlainTextContent.java create mode 100644 src/main/java/meteordevelopment/meteorclient/utils/misc/text/RichTextContent.java diff --git a/src/main/java/meteordevelopment/meteorclient/gui/MessageFormatter.java b/src/main/java/meteordevelopment/meteorclient/gui/MessageFormatter.java index b53453e9bf..3e43722472 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/MessageFormatter.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/MessageFormatter.java @@ -5,6 +5,7 @@ package meteordevelopment.meteorclient.gui; +import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.misc.text.MessageKind; import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; @@ -13,6 +14,8 @@ import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3i; +import java.util.Optional; + public interface MessageFormatter { Text formatPlayerName(PlayerEntity player); Text formatEntityName(Entity entity); @@ -20,9 +23,10 @@ public interface MessageFormatter { Text formatCoords(Vec3i blockPos); Text formatCoords(Vec3d pos); - Text formatHighlight(MutableText text); + Text formatHighlight(Text text); Text formatDecimal(double decimal); Text formatPrefix(Text prefix); - Text formatMessage(MutableText message, MessageKind messageKind); + Text formatToggleFeedback(Text clientPrefix, Text featurePrefix, Module module, boolean enabled); + Text formatMessage(Text clientPrefix, Optional featurePrefix, Text message, MessageKind messageKind); } diff --git a/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/MeteorMessageFormatter.java b/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/MeteorMessageFormatter.java index 6ab7ffefe5..e79e47e28a 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/MeteorMessageFormatter.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/MeteorMessageFormatter.java @@ -5,9 +5,11 @@ package meteordevelopment.meteorclient.gui.themes.meteor; +import meteordevelopment.meteorclient.MeteorClient; import meteordevelopment.meteorclient.gui.MessageFormatter; import meteordevelopment.meteorclient.pathing.NopPathManager; import meteordevelopment.meteorclient.pathing.PathManagers; +import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.misc.text.MessageKind; import meteordevelopment.meteorclient.utils.misc.text.RunnableClickEvent; import net.minecraft.entity.Entity; @@ -22,6 +24,7 @@ import net.minecraft.util.math.Vec3i; import java.text.DecimalFormat; +import java.util.Optional; public class MeteorMessageFormatter implements MessageFormatter { private final DecimalFormat decimalFormat = new DecimalFormat("0.0##"); @@ -63,8 +66,8 @@ private Text formatCoords(int x, int y, int z) { } @Override - public Text formatHighlight(MutableText text) { - return text.formatted(Formatting.WHITE); + public Text formatHighlight(Text text) { + return Text.empty().formatted(Formatting.WHITE).append(text); } @Override @@ -81,12 +84,27 @@ public Text formatPrefix(Text prefix) { } @Override - public Text formatMessage(MutableText message, MessageKind messageKind) { + public Text formatToggleFeedback(Text clientPrefix, Text featurePrefix, Module module, boolean enabled) { + Text feedback = MeteorClient.translatable( + "module.base.toggled", + module.getTitleText(), + enabled ? Text.literal("on").formatted(Formatting.GREEN) : Text.literal("off").formatted(Formatting.RED) + ); + + return this.formatMessage(clientPrefix, Optional.of(featurePrefix), feedback, MessageKind.Passthrough); + } + + @Override + public Text formatMessage(Text clientPrefix, Optional featurePrefix, Text message, MessageKind messageKind) { + MutableText formattedMessage = Text.empty().append(clientPrefix); + featurePrefix.ifPresent(formattedMessage::append); + formattedMessage.append(message); + return switch (messageKind) { - case Passthrough -> message; - case Info -> message.formatted(Formatting.GRAY); - case Warning -> message.formatted(Formatting.YELLOW); - case Error -> message.formatted(Formatting.RED); + case Passthrough -> formattedMessage; + case Info -> formattedMessage.formatted(Formatting.GRAY); + case Warning -> formattedMessage.formatted(Formatting.YELLOW); + case Error -> formattedMessage.formatted(Formatting.RED); }; } } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/Module.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/Module.java index e33a4422d8..58701f5916 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/Module.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/Module.java @@ -9,6 +9,7 @@ import meteordevelopment.meteorclient.addons.AddonManager; import meteordevelopment.meteorclient.addons.MeteorAddon; import meteordevelopment.meteorclient.gui.GuiTheme; +import meteordevelopment.meteorclient.gui.GuiThemes; import meteordevelopment.meteorclient.gui.widgets.WWidget; import meteordevelopment.meteorclient.settings.Settings; import meteordevelopment.meteorclient.systems.config.Config; @@ -16,6 +17,8 @@ import meteordevelopment.meteorclient.utils.misc.ISerializable; import meteordevelopment.meteorclient.utils.misc.Keybind; import meteordevelopment.meteorclient.utils.misc.MeteorTranslations; +import meteordevelopment.meteorclient.utils.misc.text.MessageBuilder; +import meteordevelopment.meteorclient.utils.misc.text.MessageKind; import meteordevelopment.meteorclient.utils.player.ChatUtils; import meteordevelopment.meteorclient.utils.render.color.Color; import net.minecraft.client.MinecraftClient; @@ -23,7 +26,6 @@ import net.minecraft.nbt.NbtElement; import net.minecraft.text.MutableText; import net.minecraft.text.Text; -import net.minecraft.util.Formatting; import org.jetbrains.annotations.NotNull; import java.util.Objects; @@ -117,44 +119,34 @@ public void disable() { public void sendToggledMsg() { if (Config.get().chatFeedback.get() && chatFeedback) { - ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.sendMsg(this.hashCode(), Formatting.GRAY, "module.base.toggled", this.getTitleText(), isActive() ? Text.literal("on").formatted(Formatting.GREEN) : Text.literal("off").formatted(Formatting.RED)); + GuiTheme theme = GuiThemes.get(); + ChatUtils.sendMsg(this.hashCode(), theme.messageFormatter().formatToggleFeedback( + theme.messageFormatter().formatPrefix(ChatUtils.getPrefix(this, theme)), + theme.messageFormatter().formatPrefix(this.getTitleText()), + this, + this.isActive() + )); } } - public void info(Text message) { - ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.sendMsg(this.getTranslationKey(), message); + public MessageBuilder info(Text message) { + return MessageBuilder.create().setSource(this).setTranslationContext(this.getTranslationKey()) + .body(message).setKind(MessageKind.Info); } - public void info(String messageKey, Object... args) { - ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.infoPrefix(this.getTranslationKey(), this.getTranslationKey() + ".info." + messageKey, args); + public MessageBuilder info(String message, Object... args) { + return MessageBuilder.create().setSource(this).setTranslationContext(this.getTranslationKey()) + .body(message, args).setKind(MessageKind.Info); } - public void infoRaw(String message, Object... args) { - ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.infoPrefixRaw(this.getTranslationKey(), message, args); + public MessageBuilder warning(String message, Object... args) { + return MessageBuilder.create().setSource(this).setTranslationContext(this.getTranslationKey()) + .body(message, args).setKind(MessageKind.Warning); } - public void warning(String messageKey, Object... args) { - ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.warningPrefix(this.getTranslationKey(), this.getTranslationKey() + ".warning." + messageKey, args); - } - - public void warningRaw(String message, Object... args) { - ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.warningPrefixRaw(this.getTranslationKey(), message, args); - } - - public void error(String messageKey, Object... args) { - ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.errorPrefix(this.getTranslationKey(), this.getTranslationKey() + ".error." + messageKey, args); - } - - public void errorRaw(String message, Object... args) { - ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.errorPrefixRaw(this.getTranslationKey(), message, args); + public MessageBuilder error(String message, Object... args) { + return MessageBuilder.create().setSource(this).setTranslationContext(this.getTranslationKey()) + .body(message, args).setKind(MessageKind.Error); } public boolean isActive() { diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageBuilder.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageBuilder.java index bd7e7a64fa..bfaf3e952d 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageBuilder.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageBuilder.java @@ -5,27 +5,133 @@ package meteordevelopment.meteorclient.utils.misc.text; -import net.minecraft.text.MutableText; import net.minecraft.text.Text; import net.minecraft.util.Formatting; +import java.util.function.Supplier; + public interface MessageBuilder { static MessageBuilder create() { return new MessageBuilderImpl(); } + static Text highlight(Object argument) { + return MessageBuilderImpl.highlight(argument); + } + + /** + * Sets the id associated with this message. There can only be a single message with a given id in chat. + * + * @return this builder + * @throws IllegalStateException if this builder is already closed. + */ MessageBuilder setId(int id); + + /** + * Sets the kind of message you want to send, for use in styling. Use {@link MessageKind#Passthrough} to avoid + * the formatter to send the message body as-is, with no additional styling. + * + * @return this builder + * @throws IllegalStateException if this builder is already closed. + */ MessageBuilder setKind(MessageKind kind); + + /** + * Sets the context to be used for translation keys within this builder. If this is set, it will automatically + * attempt to resolve translations using the key {@code "${context}.${kind}.${body}"}. + * + * @return this builder + * @throws IllegalStateException if this builder is already closed. + */ MessageBuilder setTranslationContext(String translationContext); + + /** + * Sets the source of this builder. If set, the Meteor Client prefix will be replaced based on + * {@link meteordevelopment.meteorclient.utils.player.ChatUtils#registerCustomPrefix(String, Supplier)}. + * + * @return this builder + * @throws IllegalStateException if this builder is already closed. + */ MessageBuilder setSource(Object source); - MessageBuilder prefix(MutableText prefix); + /** + * Sets the prefix to show in front of the message. This can optionally be styled, but should not contain any + * decorations such as brackets as those will be added by the formatter. + * + * @return this builder + * @throws IllegalStateException if this builder is already closed. + */ + MessageBuilder prefix(Text prefix); + + /** + * Sets the prefix to show in front of the message. This should not contain any decorations such as brackets as + * those will be added by the formatter. + * + * @return this builder + * @throws IllegalStateException if this builder is already closed. + */ MessageBuilder prefix(String prefix); + + /** + * Sets the prefix to show in front of the message. This should not contain any decorations such as brackets as + * those will be added by the formatter. The prefix color is a suggestion, the formatter is allowed to override it. + * + * @return this builder + * @throws IllegalStateException if this builder is already closed. + */ MessageBuilder prefix(String prefix, Formatting prefixColor); - MessageBuilder body(MutableText body); + /** + * Sets the message body. + * + * @return this builder + * @throws IllegalStateException if this builder is already closed. + */ + MessageBuilder body(Text body); + + /** + * Sets the message body. + * + * @param body the message body. If this is a valid Meteor Client translation key, the message body will instead be + * the translated text. If {@link MessageBuilder#setTranslationContext(String)} is set and + * {@link MessageBuilder#setKind(MessageKind)} is not set to {@link MessageKind#Passthrough}, the + * message body will also attempt to resolve the key made using the format + * {@code "${context}.${kind}.${body}"}. For example, + * {@code builder.setKind(MessageKind.Info).setTranslationContext("example").body("test")} would result + * in the key {@code "example.info.test"}. Otherwise, the message body will simply be passed in plain + * text. + * @param args the arguments that will be used to replace the format specifiers in the body. This builder supports + * many special argument types:
    + *
  • {@link Text} — Keeps the styling.
  • + *
  • {@link net.minecraft.entity.player.PlayerEntity} — Uses the player's name.
  • + *
  • {@link net.minecraft.entity.Entity} — Uses the entity's display name.
  • + *
  • {@link net.minecraft.util.math.BlockPos} — Formatted coordinate display.
  • + *
  • {@link net.minecraft.util.math.Vec3d} — Formatted coordinate display.
  • + *
  • {@link Float} & {@link Double} — Truncates some decimals.
  • + *
  • {@link net.minecraft.entity.effect.StatusEffect} — Uses the status effect's display name.
  • + *
  • {@link net.minecraft.item.Item} — Uses the item's display name.
  • + *
  • {@link net.minecraft.block.Block} — Uses the block's display name.
  • + *
  • {@link net.minecraft.entity.EntityType} — Uses the entity type's display name.
  • + *
Otherwise the argument will be passed through {@link String#valueOf(Object)}. + * @return this builder + * @throws IllegalStateException if this builder is already closed. + */ MessageBuilder body(String body, Object... args); + /** + * Builds the message and closes this builder. + * + * @return the built message + * @throws IllegalArgumentException if the message has no body or no kind. + * @throws IllegalStateException if this builder is already closed. + */ Text build(); + + /** + * Sends the message in chat and closes this builder. + * + * @throws IllegalArgumentException if the message has no body or no kind. + * @throws IllegalStateException if this builder is already closed. + */ void send(); } diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageBuilderImpl.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageBuilderImpl.java index 1feda4cfb5..4c8a68632f 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageBuilderImpl.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MessageBuilderImpl.java @@ -8,7 +8,6 @@ import meteordevelopment.meteorclient.gui.GuiTheme; import meteordevelopment.meteorclient.gui.GuiThemes; import meteordevelopment.meteorclient.gui.MessageFormatter; -import meteordevelopment.meteorclient.mixininterface.IChatHud; import meteordevelopment.meteorclient.systems.config.Config; import meteordevelopment.meteorclient.utils.misc.MeteorTranslations; import meteordevelopment.meteorclient.utils.player.ChatUtils; @@ -19,19 +18,14 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Item; import net.minecraft.text.MutableText; -import net.minecraft.text.StringVisitable; import net.minecraft.text.Style; import net.minecraft.text.Text; import net.minecraft.util.Formatting; -import net.minecraft.util.Pair; import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3i; import org.jetbrains.annotations.Nullable; -import java.util.List; -import java.util.function.Supplier; - -import static meteordevelopment.meteorclient.MeteorClient.mc; +import java.util.Optional; public class MessageBuilderImpl implements MessageBuilder { private final GuiTheme theme = GuiThemes.get(); @@ -41,13 +35,12 @@ public class MessageBuilderImpl implements MessageBuilder { private @Nullable MessageKind kind; private @Nullable Object source; private @Nullable Text messagePrefix; - private @Nullable MutableText messageBodyText; + private @Nullable Text messageBodyText; private @Nullable String messageBody; private Object[] args; private @Nullable String translationContext; - private boolean hasStyledArgs = false; private boolean closed = false; /* Builder functions */ @@ -81,7 +74,7 @@ public MessageBuilder setSource(Object source) { } @Override - public MessageBuilder prefix(MutableText prefix) { + public MessageBuilder prefix(Text prefix) { assertOpen(); this.messagePrefix = prefix; return this; @@ -102,7 +95,7 @@ public MessageBuilder prefix(String prefix, Formatting prefixColor) { } @Override - public MessageBuilder body(MutableText body) { + public MessageBuilder body(Text body) { assertOpen(); this.messageBodyText = body; return this; @@ -124,68 +117,66 @@ public Text build() { assertOpen(); closed = true; - if (this.messageBody == null || this.messageBodyText == null) { + if (this.messageBody == null && this.messageBodyText == null) { throw new IllegalArgumentException("Message body cannot be empty!"); } else if (this.kind == null) { throw new IllegalArgumentException("Message cannot have a kind!"); } - MutableText message = Text.empty() - .append(this.formatter.formatPrefix(this.getPrefix())); - - if (this.messagePrefix != null) { - message.append(this.formatter.formatPrefix(this.messagePrefix)); - } - - MutableText bodyText = this.messageBodyText != null ? this.messageBodyText : this.createMessageBody(this.messageBody, this.kind); - message.append(this.formatter.formatMessage(bodyText, this.kind)); + Text bodyText = this.messageBodyText != null ? this.messageBodyText : this.createMessageBody(this.messageBody, this.kind); - return message; + return this.formatter.formatMessage( + this.formatter.formatPrefix(ChatUtils.getPrefix(this.source, this.theme)), + Optional.ofNullable(this.messagePrefix).map(this.formatter::formatPrefix), + bodyText, + this.kind + ); } @Override public void send() { - if (mc.world == null) return; - Text message = this.build(); int messageId = Config.get().deleteChatFeedback.get() ? this.id : 0; - if (mc.isOnThread()) { - ((IChatHud) mc.inGameHud.getChatHud()).meteor$add(message, messageId); - } else { - mc.execute(() -> ((IChatHud) mc.inGameHud.getChatHud()).meteor$add(message, messageId)); - } + ChatUtils.sendMsg(messageId, message); } /* Internal Functions */ - private void processArgs(Object[] args) { - hasStyledArgs = false; + public static Text highlight(Object arg) { + MessageFormatter formatter = GuiThemes.get().messageFormatter(); + Text processed = processArg(formatter, arg); + return formatter.formatHighlight(processed); + } + private void processArgs(Object[] args) { for (int i = 0; i < args.length; i++) { - Object arg = args[i]; - args[i] = switch (arg) { - // theme-dependent formatting - case PlayerEntity player -> { hasStyledArgs = true; yield this.formatter.formatPlayerName(player); } - case Entity entity -> { hasStyledArgs = true; yield this.formatter.formatEntityName(entity); } - case Vec3i vec -> { hasStyledArgs = true; yield this.formatter.formatCoords(vec); } - case Vec3d vec -> { hasStyledArgs = true; yield this.formatter.formatCoords(vec); } - case Float f -> { hasStyledArgs = true; yield this.formatter.formatDecimal(f); } - case Double d -> { hasStyledArgs = true; yield this.formatter.formatDecimal(d); } - - // accept common objects as parameters - case StatusEffect statusEffect -> stripStyle(statusEffect.getName()); - case Item item -> stripStyle(item.getName()); - case Block block -> stripStyle(block.getName()); - case EntityType type -> stripStyle(type.getName()); - - case StringVisitable stringVisitable -> { hasStyledArgs = true; yield stringVisitable; } - default -> String.valueOf(arg); - }; + args[i] = processArg(this.formatter, args[i]); } } - private Text stripStyle(Text text) { + private static Text processArg(MessageFormatter formatter, Object arg) { + return switch (arg) { + // theme-dependent formatting + case PlayerEntity player -> formatter.formatPlayerName(player); + case Entity entity -> formatter.formatEntityName(entity); + case Vec3i vec -> formatter.formatCoords(vec); + case Vec3d vec -> formatter.formatCoords(vec); + case Float f -> formatter.formatDecimal(f); + case Double d -> formatter.formatDecimal(d); + + // accept common objects as parameters + case StatusEffect statusEffect -> stripStyle(statusEffect.getName()); + case Item item -> stripStyle(item.getName()); + case Block block -> stripStyle(block.getName()); + case EntityType type -> stripStyle(type.getName()); + + case Text text -> text; + default -> Text.literal(String.valueOf(arg)); + }; + } + + private static Text stripStyle(Text text) { if (text instanceof MutableText mutable) { mutable.setStyle(Style.EMPTY); for (Text sibling : mutable.getSiblings()) { @@ -195,62 +186,27 @@ private Text stripStyle(Text text) { return text; } - private Text getPrefix() { - List>> customPrefixes = ChatUtils.getCustomPrefixes(); - if (customPrefixes.isEmpty()) { - return this.theme.getChatPrefix(); - } - - String className = null; - if (source != null) { - className = source.getClass().getName(); - } else { - boolean foundClass = false; - for (StackTraceElement element : Thread.currentThread().getStackTrace()) { - if (foundClass) { - if (!element.getClassName().equals(MessageBuilderImpl.class.getName())) { - className = element.getClassName(); - break; - } - } else { - if (element.getClassName().equals(MessageBuilderImpl.class.getName())) { - foundClass = true; - } - } - } - } - - if (className == null) { - return this.theme.getChatPrefix(); - } - - for (Pair> pair : customPrefixes) { - if (className.startsWith(pair.getLeft())) { - @Nullable Text prefix = pair.getRight().get(); - return prefix != null ? prefix : this.theme.getChatPrefix(); - } - } - - return this.theme.getChatPrefix(); - } - private MutableText createMessageBody(String messageBody, MessageKind kind) { MeteorTranslations.MeteorLanguage language = MeteorTranslations.getCurrentLanguage(); if (language.hasTranslation(messageBody)) { return MutableText.of(new MeteorTranslatableTextContent( - messageBody, null, this.args, this.hasStyledArgs + messageBody, null, this.args )); } else if (this.translationContext != null && kind != MessageKind.Passthrough) { String computedTranslationKey = this.translationContext + "." + kind.key + "." + messageBody; if (language.hasTranslation(computedTranslationKey)) { return MutableText.of(new MeteorTranslatableTextContent( - computedTranslationKey, null, this.args, this.hasStyledArgs + computedTranslationKey, null, this.args )); } } - return Text.literal(messageBody); + if (this.args.length == 0) { + return Text.literal(messageBody); + } else { + return MutableText.of(new RichPlainTextContent(messageBody, this.args)); + } } private void assertOpen() { diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MeteorTranslatableTextContent.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MeteorTranslatableTextContent.java index d35960379c..5f27f02e81 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MeteorTranslatableTextContent.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/MeteorTranslatableTextContent.java @@ -5,108 +5,44 @@ package meteordevelopment.meteorclient.utils.misc.text; -import com.google.common.collect.ImmutableList; -import com.mojang.serialization.MapCodec; -import meteordevelopment.meteorclient.MeteorClient; import meteordevelopment.meteorclient.utils.misc.MeteorTranslations; -import meteordevelopment.meteorclient.utils.player.ChatUtils; -import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.text.*; import org.jetbrains.annotations.Nullable; -import java.util.*; -import java.util.function.Consumer; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import java.util.Arrays; +import java.util.Objects; import static meteordevelopment.meteorclient.MeteorClient.mc; -public class MeteorTranslatableTextContent implements TextContent { - private static final boolean DEBUG_MISSING_ENTRIES = FabricLoader.getInstance().isDevelopmentEnvironment() || Boolean.getBoolean("meteor.lang.debug"); +public class MeteorTranslatableTextContent extends RichTextContent { private final String key; - @Nullable - private final String fallback; - private final Object[] args; - private final boolean styledArgs; + private final @Nullable String fallback; private String cachedLanguage; - private List translations = ImmutableList.of(); public MeteorTranslatableTextContent(String key, @Nullable String fallback, Object... args) { + super(args); this.key = key; this.fallback = fallback; - this.args = args; - - boolean hasStyledArgs = false; - for (Object o : args) { - if (o instanceof Text) { - hasStyledArgs = true; - break; - } - } - this.styledArgs = hasStyledArgs; } public MeteorTranslatableTextContent(String key, Object... args) { this(key, null, args); } - public MeteorTranslatableTextContent(String key, @Nullable String fallback, Object[] args, boolean styledArgs) { - this.key = key; - this.fallback = fallback; - this.args = args; - this.styledArgs = styledArgs; - } - - private void updateTranslations() { - if (!mc.options.language.equals(this.cachedLanguage)) { - cachedLanguage = mc.options.language; - if (styledArgs) { - String template = fallback == null ? MeteorTranslations.translate(key) : MeteorTranslations.translate(key, fallback); - - try { - ImmutableList.Builder builder = ImmutableList.builder(); - this.forEachPart(template, builder::add); - this.translations = builder.build(); - } catch (TranslationException e) { - if (DEBUG_MISSING_ENTRIES) { - MeteorClient.LOG.warn("Error translating text", e); - } - this.translations = ImmutableList.of(StringVisitable.plain(template)); - } - } else { - String template = fallback == null ? MeteorTranslations.translate(key, args) : MeteorTranslations.translate(key, fallback, args); - - this.translations = ImmutableList.of(ChatUtils.formatMsg(template, Style.EMPTY)); - } - } - } - @Override - public Optional visit(StringVisitable.StyledVisitor visitor, Style style) { - updateTranslations(); - - for (StringVisitable stringVisitable : translations) { - Optional result = stringVisitable.visit(visitor, style); - if (result.isPresent()) return result; - } - return Optional.empty(); + protected boolean shouldUpdate() { + return !mc.options.language.equals(this.cachedLanguage); } @Override - public Optional visit(StringVisitable.Visitor visitor) { - updateTranslations(); - - for (StringVisitable stringVisitable : translations) { - Optional result = stringVisitable.visit(visitor); - if (result.isPresent()) return result; - } - return Optional.empty(); + protected void update(String template) { + cachedLanguage = mc.options.language; + super.update(template); } @Override - public MapCodec getCodec() { - return null; + protected String getTemplate() { + return fallback == null ? MeteorTranslations.translate(key) : MeteorTranslations.translate(key, fallback); } @Override @@ -118,70 +54,6 @@ public boolean equals(@Nullable Object o) { @Override public String toString() { - return "MeteorTranslatableTextComponent[key=" + key + ", fallback=" + fallback + ", args=" + Arrays.toString(args) + "]"; - } - - - private static final StringVisitable LITERAL_PERCENT_SIGN = StringVisitable.plain("%"); - private static final StringVisitable NULL_ARGUMENT = StringVisitable.plain("null"); - // %, optional position argument (\d$), string format (s) || percent literal (%|$) - private static final Pattern ARG_FORMAT = Pattern.compile("%(?:(\\d+)\\$)?([s%]|$)"); - - private void forEachPart(String translation, Consumer partsConsumer) { - Matcher matcher = ARG_FORMAT.matcher(translation); - - try { - int argPosition = 0; - int charIndex = 0; - - while (matcher.find(charIndex)) { - int start = matcher.start(); - int end = matcher.end(); - if (start > charIndex) { - String string = translation.substring(charIndex, start); - if (string.indexOf(37) != -1) { - throw new IllegalArgumentException(string); - } - - partsConsumer.accept(StringVisitable.plain(string)); - } - - String string = matcher.group(2); - String string2 = translation.substring(start, end); - if ("%".equals(string) && "%%".equals(string2)) { - partsConsumer.accept(LITERAL_PERCENT_SIGN); - } else { - String positionArgument = matcher.group(1); - int index = positionArgument != null ? Integer.parseInt(positionArgument) - 1 : argPosition++; - if (index < 0 || index >= this.args.length) { - throw new TranslationException(new TranslatableTextContent(this.key, this.fallback, this.args), index); - } - - Object argument = this.args[index]; - - if (string.equals("s")) { // fast path - StringVisitable visitableArgument = argument instanceof StringVisitable visitable ? visitable - : argument == null ? NULL_ARGUMENT : StringVisitable.plain(argument.toString()); - - partsConsumer.accept(visitableArgument); - } else { - throw new TranslationException(new TranslatableTextContent(this.key, this.fallback, this.args), "Unsupported format: '" + string2 + "'"); - } - } - - charIndex = end; - } - - if (charIndex < translation.length()) { - String string4 = translation.substring(charIndex); - if (string4.indexOf(37) != -1) { - throw new IllegalArgumentException(); - } - - partsConsumer.accept(StringVisitable.plain(string4)); - } - } catch (IllegalArgumentException e) { - throw new TranslationException(new TranslatableTextContent(this.key, this.fallback, this.args), e); - } + return "MeteorTranslatableTextContent[key=" + key + ", fallback=" + fallback + ", args=" + Arrays.toString(args) + "]"; } } diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/text/RichPlainTextContent.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/RichPlainTextContent.java new file mode 100644 index 0000000000..5a741411d7 --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/RichPlainTextContent.java @@ -0,0 +1,41 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.utils.misc.text; + +import java.util.Arrays; +import java.util.Objects; + +public class RichPlainTextContent extends RichTextContent { + private final String template; + + public RichPlainTextContent(String template, Object... args) { + super(args); + this.template = template; + this.update(template); + } + + @Override + protected boolean shouldUpdate() { + return false; + } + + @Override + protected String getTemplate() { + return this.template; + } + + @Override + public String toString() { + return "RichPlainTextContent[template=" + this.template + ", args=" + Arrays.toString(this.args) + "]"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof RichPlainTextContent component)) return false; + return Objects.equals(this.template, component.template) && Arrays.equals(this.args, component.args); + } +} diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/text/RichTextContent.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/RichTextContent.java new file mode 100644 index 0000000000..1eac8ce06f --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/text/RichTextContent.java @@ -0,0 +1,152 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.utils.misc.text; + +import com.google.common.collect.ImmutableList; +import com.mojang.serialization.MapCodec; +import meteordevelopment.meteorclient.MeteorClient; +import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.text.*; + +import java.util.List; +import java.util.Locale; +import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public abstract class RichTextContent implements TextContent { + private static final boolean DEBUG_MISSING_ENTRIES = FabricLoader.getInstance().isDevelopmentEnvironment() || Boolean.getBoolean("meteor.lang.debug"); + protected final Object[] args; + + private List parts = ImmutableList.of(); + + protected RichTextContent(Object... args) { + this.args = args; + } + + protected abstract boolean shouldUpdate(); + + protected abstract String getTemplate(); + + protected void update(String template) { + try { + ImmutableList.Builder builder = ImmutableList.builder(); + this.forEachPart(template, builder); + this.parts = builder.build(); + } catch (IllegalArgumentException e) { + if (DEBUG_MISSING_ENTRIES) { + MeteorClient.LOG.warn("Error formatting text", e); + } + this.parts = ImmutableList.of(StringVisitable.plain(template)); + } + } + + @Override + public Optional visit(StringVisitable.StyledVisitor visitor, Style style) { + if (this.shouldUpdate()) { + this.update(this.getTemplate()); + } + + for (StringVisitable stringVisitable : this.parts) { + Optional result = stringVisitable.visit(visitor, style); + if (result.isPresent()) return result; + } + return Optional.empty(); + } + + @Override + public Optional visit(StringVisitable.Visitor visitor) { + if (this.shouldUpdate()) { + this.update(this.getTemplate()); + } + + for (StringVisitable stringVisitable : this.parts) { + Optional result = stringVisitable.visit(visitor); + if (result.isPresent()) return result; + } + return Optional.empty(); + } + + @Override + public MapCodec getCodec() { + return null; + } + + private static final StringVisitable LITERAL_PERCENT_SIGN = StringVisitable.plain("%"); + private static final StringVisitable NULL_ARGUMENT = StringVisitable.plain("null"); + // %, optional position argument (\d$), string format (s) || percent literal (%|$) + private static final Pattern ARG_FORMAT = Pattern.compile("%(?:(\\d+)\\$)?([s%]|$)"); + + private void forEachPart(String template, ImmutableList.Builder builder) { + Matcher matcher = ARG_FORMAT.matcher(template); + + try { + int argPosition = 0; + int charIndex = 0; + + while (matcher.find(charIndex)) { + int start = matcher.start(); + int end = matcher.end(); + if (start > charIndex) { + String string = template.substring(charIndex, start); + if (string.indexOf(37) != -1) { + throw new IllegalArgumentException(string); + } + + builder.add(StringVisitable.plain(string)); + } + + String string = matcher.group(2); + String format = template.substring(start, end); + if ("%".equals(string) && "%%".equals(format)) { + builder.add(LITERAL_PERCENT_SIGN); + } else { + String positionArgument = matcher.group(1); + int index = positionArgument != null ? Integer.parseInt(positionArgument) - 1 : argPosition++; + if (index < 0 || index >= this.args.length) { + throw exception(template, index); + } + + Object argument = this.args[index]; + + if (string.equals("s")) { + StringVisitable visitableArgument = argument instanceof StringVisitable visitable ? visitable + : argument == null ? NULL_ARGUMENT : StringVisitable.plain(argument.toString()); + + builder.add(visitableArgument); + } else { + throw exception(template, "Unsupported format: '" + format + "'"); + } + } + + charIndex = end; + } + + if (charIndex < template.length()) { + String rest = template.substring(charIndex); + if (rest.indexOf(37) != -1) { + throw new IllegalArgumentException(); + } + + builder.add(StringVisitable.plain(rest)); + } + } catch (IllegalArgumentException e) { + throw exception(template, e); + } + } + + private static IllegalArgumentException exception(String template, String cause) { + return new IllegalArgumentException(String.format(Locale.ROOT, "Error parsing: %s: %s", template, cause)); + } + + private static IllegalArgumentException exception(String template, int index) { + return new IllegalArgumentException(String.format(Locale.ROOT, "Invalid index %d requested for %s", index, template)); + } + + private static IllegalArgumentException exception(String template, Throwable cause) { + return new IllegalArgumentException(String.format(Locale.ROOT, "Error while parsing: %s", template), cause); + } +} diff --git a/src/main/java/meteordevelopment/meteorclient/utils/player/ChatUtils.java b/src/main/java/meteordevelopment/meteorclient/utils/player/ChatUtils.java index f566e8b767..b452fe5c86 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/player/ChatUtils.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/player/ChatUtils.java @@ -5,18 +5,14 @@ package meteordevelopment.meteorclient.utils.player; -import com.mojang.brigadier.StringReader; import meteordevelopment.meteorclient.MeteorClient; import meteordevelopment.meteorclient.gui.GuiTheme; import meteordevelopment.meteorclient.mixininterface.IChatHud; -import meteordevelopment.meteorclient.pathing.BaritoneUtils; -import meteordevelopment.meteorclient.systems.config.Config; import meteordevelopment.meteorclient.utils.PostInit; -import meteordevelopment.meteorclient.utils.misc.text.MeteorClickEvent; +import meteordevelopment.meteorclient.utils.misc.text.MessageBuilderImpl; import net.minecraft.text.*; import net.minecraft.util.Formatting; import net.minecraft.util.Pair; -import net.minecraft.util.math.Vec3d; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -27,7 +23,6 @@ public class ChatUtils { private static final List>> customPrefixes = new ArrayList<>(); - private static String forcedPrefixClassName; private static Text PREFIX; @@ -74,14 +69,6 @@ public static void unregisterCustomPrefix(String packageName) { customPrefixes.removeIf(pair -> pair.getLeft().equals(packageName)); } - public static void forceNextPrefixClass(Class klass) { - forcedPrefixClassName = klass.getName(); - } - - public static List>> getCustomPrefixes() { - return customPrefixes; - } - // Player /** @@ -101,232 +88,51 @@ public static void sendPlayerMsg(String message, boolean addToHistory) { else mc.player.networkHandler.sendChatMessage(message); } - // Default - - public static void info(String messageKey, Object... args) { - sendMsg(Formatting.GRAY, messageKey, args); - } - - public static void infoRaw(String message, Object... args) { - sendMsgRaw(Formatting.GRAY, message, args); - } - - public static void infoPrefix(String prefix, String messageKey, Object... args) { - sendMsg(0, prefix, Formatting.LIGHT_PURPLE, Formatting.GRAY, messageKey, args); - } - - public static void infoPrefixRaw(String prefix, String message, Object... args) { - sendMsgRaw(0, prefix, Formatting.LIGHT_PURPLE, Formatting.GRAY, message, args); - } - - // Warning - - public static void warning(String messageKey, Object... args) { - sendMsg(Formatting.YELLOW, messageKey, args); - } - - public static void warningRaw(String message, Object... args) { - sendMsgRaw(Formatting.YELLOW, message, args); - } - - public static void warningPrefix(String prefix, String messageKey, Object... args) { - sendMsg(0, prefix, Formatting.LIGHT_PURPLE, Formatting.YELLOW, messageKey, args); - } - - public static void warningPrefixRaw(String prefix, String message, Object... args) { - sendMsgRaw(0, prefix, Formatting.LIGHT_PURPLE, Formatting.YELLOW, message, args); - } - - // Error - - public static void error(String messageKey, Object... args) { - sendMsg(Formatting.RED, messageKey, args); - } - - public static void errorRaw(String message, Object... args) { - sendMsgRaw(Formatting.RED, message, args); - } - - public static void errorPrefix(String prefix, String messageKey, Object... args) { - sendMsg(0, prefix, Formatting.LIGHT_PURPLE, Formatting.RED, messageKey, args); - } - - public static void errorPrefixRaw(String prefix, String message, Object... args) { - sendMsgRaw(0, prefix, Formatting.LIGHT_PURPLE, Formatting.RED, message, args); - } - - // Misc - - public static void sendMsg(Text message) { - sendMsg(null, message); - } - - public static void sendMsg(String prefix, Text message) { - sendMsg(0, prefix, Formatting.LIGHT_PURPLE, message); - } - - public static void sendMsg(Formatting color, String messageKey, Object... args) { - sendMsg(0, null, null, color, messageKey, args); - } - - public static void sendMsgRaw(Formatting color, String message, Object... args) { - sendMsgRaw(0, null, null, color, message, args); - } - - public static void sendMsg(int id, Formatting color, String messageKey, Object... args) { - sendMsg(id, null, null, color, messageKey, args); - } - - public static void sendMsgRaw(int id, Formatting color, String message, Object... args) { - sendMsgRaw(id, null, null, color, message, args); - } - - public static void sendMsgRaw(int id, @Nullable String prefixKey, @Nullable Formatting prefixColor, Formatting messageColor, String messageContent, Object... args) { - MutableText message = formatMsg(String.format(messageContent, args), Style.EMPTY.withFormatting(messageColor)); - sendMsg(id, prefixKey, prefixColor, message); - } - - public static void sendMsg(int id, @Nullable String prefixKey, @Nullable Formatting prefixColor, Formatting messageColor, String messageContentKey, Object... args) { - MutableText message = MeteorClient.translatable(messageContentKey, args).setStyle(Style.EMPTY.withFormatting(messageColor)); - sendMsg(id, prefixKey, prefixColor, message); - } - - public static void sendMsg(int id, @Nullable String prefixKey, @Nullable Formatting prefixColor, String messageContent, Formatting messageColor) { - MutableText message = formatMsg(messageContent, Style.EMPTY.withFormatting(messageColor)); - sendMsg(id, prefixKey, prefixColor, message); - } - - public static void sendMsg(int id, @Nullable String prefixKey, @Nullable Formatting prefixColor, Text msg) { + public static void sendMsg(int id, Text message) { if (mc.world == null) return; - MutableText message = Text.empty(); - message.append(getPrefix()); - if (prefixKey != null) message.append(getCustomPrefix(prefixKey, prefixColor)); - message.append(msg); - - if (!Config.get().deleteChatFeedback.get()) id = 0; - - final int finalId = id; // Intellij copes about using non-final args in lambdas - mc.execute(() -> ((IChatHud) mc.inGameHud.getChatHud()).meteor$add(message, finalId)); - } - - private static MutableText getCustomPrefix(String prefixKey, Formatting prefixColor) { - MutableText prefix = Text.empty(); - prefix.setStyle(prefix.getStyle().withFormatting(Formatting.GRAY)); - - prefix.append("["); - - MutableText moduleTitle = MeteorClient.translatable(prefixKey); - moduleTitle.setStyle(moduleTitle.getStyle().withFormatting(prefixColor)); - prefix.append(moduleTitle); - - prefix.append("] "); - - return prefix; + if (mc.isOnThread()) { + ((IChatHud) mc.inGameHud.getChatHud()).meteor$add(message, id); + } else { + mc.execute(() -> ((IChatHud) mc.inGameHud.getChatHud()).meteor$add(message, id)); + } } - private static Text getPrefix() { + public static Text getPrefix(@Nullable Object source, GuiTheme theme) { if (customPrefixes.isEmpty()) { - forcedPrefixClassName = null; - return PREFIX; + return theme.getChatPrefix(); } - boolean foundChatUtils = false; String className = null; - - if (forcedPrefixClassName != null) { - className = forcedPrefixClassName; - forcedPrefixClassName = null; + if (source != null) { + className = source.getClass().getName(); } else { + boolean foundClass = false; for (StackTraceElement element : Thread.currentThread().getStackTrace()) { - if (foundChatUtils) { - if (!element.getClassName().equals(ChatUtils.class.getName())) { + if (foundClass) { + if (!element.getClassName().equals(MessageBuilderImpl.class.getName())) { className = element.getClassName(); break; } } else { - if (element.getClassName().equals(ChatUtils.class.getName())) foundChatUtils = true; + if (element.getClassName().equals(MessageBuilderImpl.class.getName())) { + foundClass = true; + } } } } - if (className == null) return PREFIX; + if (className == null) { + return theme.getChatPrefix(); + } for (Pair> pair : customPrefixes) { if (className.startsWith(pair.getLeft())) { - Text prefix = pair.getRight().get(); - return prefix != null ? prefix : PREFIX; - } - } - - return PREFIX; - } - - public static MutableText formatMsg(String message, Style defaultStyle) { - StringReader reader = new StringReader(message); - MutableText text = Text.empty(); - Style style = defaultStyle; - StringBuilder result = new StringBuilder(); - boolean formatting = false; - while (reader.canRead()) { - char c = reader.read(); - if (c == '(') { - text.append(Text.literal(result.toString()).setStyle(style)); - result.setLength(0); - result.append(c); - formatting = true; - } else { - result.append(c); - - if (formatting && c == ')') { - switch (result.toString()) { - case "(default)" -> { - style = defaultStyle; - result.setLength(0); - } - case "(highlight)" -> { - style = style.withFormatting(Formatting.WHITE); - result.setLength(0); - } - case "(underline)" -> { - style = style.withFormatting(Formatting.UNDERLINE); - result.setLength(0); - } - case "(bold)" -> { - style = style.withFormatting(Formatting.BOLD); - result.setLength(0); - } - } - formatting = false; - } + @Nullable Text prefix = pair.getRight().get(); + return prefix != null ? prefix : theme.getChatPrefix(); } } - if (!result.isEmpty()) text.append(Text.literal(result.toString()).setStyle(style)); - - return text; - } - - public static MutableText highlight(Object object) { - return Text.literal(String.valueOf(object)).formatted(Formatting.WHITE); - } - - public static MutableText formatCoords(Vec3d pos) { - String coordsString = String.format("(highlight)(underline)%.0f, %.0f, %.0f(default)", pos.x, pos.y, pos.z); - MutableText coordsText = formatMsg(coordsString, Style.EMPTY.withFormatting(Formatting.GRAY)); - - if (BaritoneUtils.IS_AVAILABLE) { - Style style = coordsText.getStyle().withFormatting(Formatting.BOLD) - .withHoverEvent(new HoverEvent.ShowText( - Text.literal("Set as Baritone goal") - )) - .withClickEvent(new MeteorClickEvent( - String.format("%sgoto %d %d %d", BaritoneUtils.getPrefix(), (int) pos.x, (int) pos.y, (int) pos.z) - )); - - coordsText.setStyle(style); - } - - return coordsText; + return theme.getChatPrefix(); } } From d49a839325cb6bddcd6d5a88eec9be0f57532416 Mon Sep 17 00:00:00 2001 From: Crosby <32882447+crosby-moe@users.noreply.github.com> Date: Sat, 14 Feb 2026 16:28:10 -0500 Subject: [PATCH 14/14] do some impl with new messagebuilder api --- .../meteorclient/commands/Command.java | 42 +++------ .../commands/commands/BindCommand.java | 4 +- .../commands/commands/BindsCommand.java | 6 +- .../commands/commands/CommandsCommand.java | 9 +- .../commands/commands/FakePlayerCommand.java | 10 +-- .../commands/commands/FriendsCommand.java | 20 ++--- .../commands/commands/InputCommand.java | 24 +++-- .../commands/commands/LocateCommand.java | 80 ++++++++--------- .../commands/commands/ModulesCommand.java | 11 +-- .../commands/commands/NameHistoryCommand.java | 6 +- .../commands/commands/ProfilesCommand.java | 7 +- .../commands/commands/ResetCommand.java | 16 ++-- .../commands/commands/ServerCommand.java | 43 +++++---- .../commands/commands/SwarmCommand.java | 26 +++--- .../meteorclient/mixin/BookScreenMixin.java | 4 +- .../mixin/ClientPlayNetworkHandlerMixin.java | 4 +- .../systems/modules/misc/BetterChat.java | 3 +- .../systems/modules/misc/Notifier.java | 90 +++++++++---------- .../modules/misc/swarm/SwarmConnection.java | 11 +-- .../systems/modules/misc/swarm/SwarmHost.java | 11 +-- .../modules/misc/swarm/SwarmWorker.java | 15 ++-- .../modules/render/WaypointsModule.java | 6 +- 22 files changed, 216 insertions(+), 232 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/commands/Command.java b/src/main/java/meteordevelopment/meteorclient/commands/Command.java index 76be9caabf..f49260cb26 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/Command.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/Command.java @@ -11,7 +11,8 @@ import com.mojang.brigadier.builder.RequiredArgumentBuilder; import meteordevelopment.meteorclient.MeteorClient; import meteordevelopment.meteorclient.systems.config.Config; -import meteordevelopment.meteorclient.utils.player.ChatUtils; +import meteordevelopment.meteorclient.utils.misc.text.MessageBuilder; +import meteordevelopment.meteorclient.utils.misc.text.MessageKind; import net.minecraft.client.MinecraftClient; import net.minecraft.command.CommandRegistryAccess; import net.minecraft.command.CommandSource; @@ -81,39 +82,24 @@ public String toString(String... args) { return base.toString(); } - public void info(Text message) { - ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.sendMsg(translationKey, message); + public MessageBuilder info(Text message) { + return MessageBuilder.create().setSource(this).setTranslationContext(this.translationKey) + .body(message).setKind(MessageKind.Info); } - public void info(String messageKey, Object... args) { - ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.infoPrefix(translationKey, translationKey + ".info." + messageKey, args); + public MessageBuilder info(String message, Object... args) { + return MessageBuilder.create().setSource(this).setTranslationContext(this.translationKey) + .body(message, args).setKind(MessageKind.Info); } - public void infoRaw(String message, Object... args) { - ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.infoPrefixRaw(translationKey, message, args); + public MessageBuilder warning(String message, Object... args) { + return MessageBuilder.create().setSource(this).setTranslationContext(this.translationKey) + .body(message, args).setKind(MessageKind.Warning); } - public void warning(String messageKey, Object... args) { - ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.warningPrefix(translationKey, translationKey + ".warning." + messageKey, args); - } - - public void warningRaw(String message, Object... args) { - ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.warningPrefixRaw(translationKey, message, args); - } - - public void error(String messageKey, Object... args) { - ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.errorPrefix(translationKey, translationKey + ".error." + messageKey, args); - } - - public void errorRaw(String message, Object... args) { - ChatUtils.forceNextPrefixClass(getClass()); - ChatUtils.errorPrefixRaw(translationKey, message, args); + public MessageBuilder error(String message, Object... args) { + return MessageBuilder.create().setSource(this).setTranslationContext(this.translationKey) + .body(message, args).setKind(MessageKind.Error); } public MutableText translatable(String string, Object... args) { diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/BindCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/BindCommand.java index 9556c94a4f..058b6ec40f 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/BindCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/BindCommand.java @@ -10,7 +10,6 @@ import meteordevelopment.meteorclient.commands.arguments.ModuleArgumentType; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.systems.modules.Modules; -import meteordevelopment.meteorclient.utils.player.ChatUtils; import net.minecraft.command.CommandSource; public class BindCommand extends Command { @@ -25,8 +24,7 @@ public void build(LiteralArgumentBuilder builder) { Modules.get().setModuleToBind(module); Modules.get().awaitKeyRelease(); - ChatUtils.forceNextPrefixClass(module.getClass()); - ChatUtils.infoPrefix(module.getTranslationKey(), this.translationKey + ".info.press_key"); + this.info("press_key").prefix(module.getTitleText()).send(); return SINGLE_SUCCESS; })); diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/BindsCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/BindsCommand.java index aa19887cf3..2e289805ae 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/BindsCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/BindsCommand.java @@ -9,7 +9,7 @@ import meteordevelopment.meteorclient.commands.Command; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.systems.modules.Modules; -import meteordevelopment.meteorclient.utils.player.ChatUtils; +import meteordevelopment.meteorclient.utils.misc.text.MessageBuilder; import net.minecraft.command.CommandSource; import net.minecraft.text.HoverEvent; import net.minecraft.text.MutableText; @@ -31,7 +31,7 @@ public void build(LiteralArgumentBuilder builder) { .filter(module -> module.keybind.isSet()) .toList(); - ChatUtils.info(translationKey + ".info.bound_modules", ChatUtils.highlight(modules.size())); + this.info("bound_modules", MessageBuilder.highlight(modules.size())).send(); for (Module module : modules) { HoverEvent hoverEvent = new HoverEvent.ShowText(getTooltip(module)); @@ -47,7 +47,7 @@ public void build(LiteralArgumentBuilder builder) { key.setStyle(key.getStyle().withHoverEvent(hoverEvent)); text.append(key.formatted(Formatting.GRAY)); - ChatUtils.sendMsg(text); + this.info(text).send(); } return SINGLE_SUCCESS; diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/CommandsCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/CommandsCommand.java index ca5e1de059..82387ed49c 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/CommandsCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/CommandsCommand.java @@ -9,6 +9,7 @@ import meteordevelopment.meteorclient.commands.Command; import meteordevelopment.meteorclient.commands.Commands; import meteordevelopment.meteorclient.systems.config.Config; +import meteordevelopment.meteorclient.utils.misc.text.MessageBuilder; import meteordevelopment.meteorclient.utils.player.ChatUtils; import net.minecraft.command.CommandSource; import net.minecraft.text.ClickEvent; @@ -25,11 +26,11 @@ public CommandsCommand() { @Override public void build(LiteralArgumentBuilder builder) { builder.executes(context -> { - ChatUtils.info(translationKey + ".info.commands", ChatUtils.highlight(Commands.COMMANDS.size())); + this.info("commands", MessageBuilder.highlight(Commands.COMMANDS.size())).send(); - MutableText commands = Text.literal(""); + MutableText commands = Text.empty(); Commands.COMMANDS.forEach(command -> commands.append(getCommandText(command))); - ChatUtils.sendMsg(commands); + this.info(commands).send(); return SINGLE_SUCCESS; }); @@ -37,7 +38,7 @@ public void build(LiteralArgumentBuilder builder) { private MutableText getCommandText(Command command) { // Hover tooltip - MutableText tooltip = Text.literal(""); + MutableText tooltip = Text.empty(); tooltip.append(command.getTitle().formatted(Formatting.BLUE, Formatting.BOLD)).append("\n"); diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/FakePlayerCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/FakePlayerCommand.java index 8dd8213bc2..fcf404ac34 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/FakePlayerCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/FakePlayerCommand.java @@ -13,7 +13,7 @@ import meteordevelopment.meteorclient.systems.modules.player.FakePlayer; import meteordevelopment.meteorclient.utils.entity.fakeplayer.FakePlayerEntity; import meteordevelopment.meteorclient.utils.entity.fakeplayer.FakePlayerManager; -import meteordevelopment.meteorclient.utils.player.ChatUtils; +import meteordevelopment.meteorclient.utils.misc.text.MessageBuilder; import net.minecraft.command.CommandSource; public class FakePlayerCommand extends Command { @@ -43,12 +43,12 @@ public void build(LiteralArgumentBuilder builder) { .executes(context -> { FakePlayerEntity fp = FakePlayerArgumentType.get(context); if (fp == null || !FakePlayerManager.contains(fp)) { - error("not_found"); + this.error("not_found").send(); return SINGLE_SUCCESS; } FakePlayerManager.remove(fp); - info("removed", fp.getName().getString()); + this.info("removed", MessageBuilder.highlight(fp)).send(); return SINGLE_SUCCESS; }) @@ -64,8 +64,8 @@ public void build(LiteralArgumentBuilder builder) { builder.then(literal("list") .executes(context -> { - info("fake_players", ChatUtils.highlight(FakePlayerManager.count())); - FakePlayerManager.forEach(fp -> info("(highlight)%s".formatted(fp.getName().getString()))); + this.info("fake_players", MessageBuilder.highlight(FakePlayerManager.count())).send(); + FakePlayerManager.forEach(fp -> this.info(MessageBuilder.highlight(fp)).send()); return SINGLE_SUCCESS; }) ); diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/FriendsCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/FriendsCommand.java index 83d7ec38c7..4eeac79c4a 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/FriendsCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/FriendsCommand.java @@ -12,9 +12,8 @@ import meteordevelopment.meteorclient.commands.arguments.PlayerListEntryArgumentType; import meteordevelopment.meteorclient.systems.friends.Friend; import meteordevelopment.meteorclient.systems.friends.Friends; -import meteordevelopment.meteorclient.utils.player.ChatUtils; +import meteordevelopment.meteorclient.utils.misc.text.MessageBuilder; import net.minecraft.command.CommandSource; -import net.minecraft.util.Formatting; public class FriendsCommand extends Command { public FriendsCommand() { @@ -30,7 +29,7 @@ public void build(LiteralArgumentBuilder builder) { Friend friend = new Friend(profile.name(), profile.id()); if (Friends.get().add(friend)) { - ChatUtils.sendMsg(friend.hashCode(), Formatting.GRAY, translationKey + ".info.added", friend.getName()); + this.info("added", friend.getName()).setId(friend.hashCode()).send(); } else error("already_friends"); @@ -44,14 +43,14 @@ public void build(LiteralArgumentBuilder builder) { .executes(context -> { Friend friend = FriendArgumentType.get(context); if (friend == null) { - error("not_friends"); + this.error("not_friends").send(); return SINGLE_SUCCESS; } if (Friends.get().remove(friend)) { - ChatUtils.sendMsg(friend.hashCode(), Formatting.GRAY, translationKey + ".info.removed", friend.getName()); + this.info("removed", friend.getName()).setId(friend.hashCode()).send(); } - else error("failed"); + else this.error("failed").send(); return SINGLE_SUCCESS; }) @@ -59,10 +58,9 @@ public void build(LiteralArgumentBuilder builder) { ); builder.then(literal("list").executes(context -> { - info("friends", ChatUtils.highlight(Friends.get().count())); - Friends.get().forEach(friend -> ChatUtils.infoRaw("(highlight)%s".formatted(friend.getName()))); - return SINGLE_SUCCESS; - }) - ); + this.info("friends", MessageBuilder.highlight(Friends.get().count())).send(); + Friends.get().forEach(friend -> this.info(MessageBuilder.highlight(friend.getName())).send()); + return SINGLE_SUCCESS; + })); } } diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/InputCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/InputCommand.java index 1a17bd4ebf..01bdf65640 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/InputCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/InputCommand.java @@ -12,11 +12,11 @@ import meteordevelopment.meteorclient.commands.Command; import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.mixin.KeyBindingAccessor; -import meteordevelopment.meteorclient.utils.player.ChatUtils; +import meteordevelopment.meteorclient.utils.misc.text.MessageBuilder; import meteordevelopment.orbit.EventHandler; import net.minecraft.client.option.KeyBinding; -import net.minecraft.client.resource.language.I18n; import net.minecraft.command.CommandSource; +import net.minecraft.text.Text; import java.util.ArrayList; import java.util.List; @@ -81,9 +81,9 @@ public void build(LiteralArgumentBuilder builder) { } builder.then(literal("clear").executes(ctx -> { - if (activeHandlers.isEmpty()) warning("no_handlers"); + if (activeHandlers.isEmpty()) this.warning("no_handlers").send(); else { - info("cleared_handlers"); + this.info("cleared_handlers").send(); activeHandlers.forEach(MeteorClient.EVENT_BUS::unsubscribe); activeHandlers.clear(); } @@ -91,12 +91,18 @@ public void build(LiteralArgumentBuilder builder) { })); builder.then(literal("list").executes(ctx -> { - if (activeHandlers.isEmpty()) warning("no_handlers"); + if (activeHandlers.isEmpty()) this.warning("no_handlers").send(); else { - info("active_handlers"); + this.info("active_handlers").send(); for (int i = 0; i < activeHandlers.size(); i++) { KeypressHandler handler = activeHandlers.get(i); - info("keypress_handler", ChatUtils.highlight(i), ChatUtils.highlight(I18n.translate(handler.key.getId())), ChatUtils.highlight(handler.ticks), ChatUtils.highlight(handler.totalTicks)); + this.info( + "keypress_handler", + MessageBuilder.highlight(i), + MessageBuilder.highlight(Text.translatable(handler.key.getId())), + MessageBuilder.highlight(handler.ticks), + MessageBuilder.highlight(handler.key.getId()) + ).send(); } } return SINGLE_SUCCESS; @@ -104,9 +110,9 @@ public void build(LiteralArgumentBuilder builder) { builder.then(literal("remove").then(argument("index", IntegerArgumentType.integer(0)).executes(ctx -> { int index = IntegerArgumentType.getInteger(ctx, "index"); - if (index >= activeHandlers.size()) warning("out_of_range"); + if (index >= activeHandlers.size()) this.warning("out_of_range").send(); else { - info("removed_handler"); + this.info("removed_handler").send(); MeteorClient.EVENT_BUS.unsubscribe(activeHandlers.get(index)); activeHandlers.remove(index); } diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/LocateCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/LocateCommand.java index b580a71c75..9d123b2f65 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/LocateCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/LocateCommand.java @@ -13,7 +13,7 @@ import meteordevelopment.meteorclient.events.packets.PacketEvent; import meteordevelopment.meteorclient.pathing.BaritoneUtils; import meteordevelopment.meteorclient.pathing.PathManagers; -import meteordevelopment.meteorclient.utils.player.ChatUtils; +import meteordevelopment.meteorclient.utils.misc.text.MessageBuilder; import meteordevelopment.meteorclient.utils.player.InvUtils; import meteordevelopment.orbit.EventHandler; import net.minecraft.block.Block; @@ -28,9 +28,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.network.packet.s2c.play.EntitySpawnS2CPacket; -import net.minecraft.text.MutableText; import net.minecraft.text.Text; -import net.minecraft.util.Formatting; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; @@ -80,25 +78,25 @@ public void build(LiteralArgumentBuilder builder) { if (stack.getItem() != Items.FILLED_MAP || stack.get(DataComponentTypes.ITEM_NAME) == null || !stack.get(DataComponentTypes.ITEM_NAME).getString().equals(Text.translatable("filled_map.buried_treasure").getString())) { - error("no_buried_treasure_map", Text.translatable("filled_map.buried_treasure").formatted(Formatting.WHITE)); + this.error("no_buried_treasure_map", MessageBuilder.highlight(Text.translatable("filled_map.buried_treasure"))).send(); return SINGLE_SUCCESS; } MapDecorationsComponent mapDecorationsComponent = stack.get(DataComponentTypes.MAP_DECORATIONS); if (mapDecorationsComponent == null) { - error("no_map_icons"); + this.error("no_map_icons").send(); return SINGLE_SUCCESS; } for (MapDecorationsComponent.Decoration decoration : mapDecorationsComponent.decorations().values()) { if (decoration.type().value().assetId().toString().equals("minecraft:red_x")) { Vec3d coords = new Vec3d(decoration.x(), 62, decoration.z()); - info("buried_treasure", ChatUtils.formatCoords(coords)); + this.info("buried_treasure", coords).send(); return SINGLE_SUCCESS; } } - error("cant_locate_buried_treasure"); + this.error("cant_locate_buried_treasure").send(); return SINGLE_SUCCESS; })); @@ -107,25 +105,25 @@ public void build(LiteralArgumentBuilder builder) { if (stack.getItem() != Items.FILLED_MAP || stack.get(DataComponentTypes.ITEM_NAME) == null || !stack.get(DataComponentTypes.ITEM_NAME).getString().equals(Text.translatable("filled_map.mansion").getString())) { - error("no_woodland_explorer_map", Text.translatable("filled_map.mansion").formatted(Formatting.WHITE)); + this.error("no_woodland_explorer_map", MessageBuilder.highlight(Text.translatable("filled_map.mansion"))).send(); return SINGLE_SUCCESS; } MapDecorationsComponent mapDecorationsComponent = stack.get(DataComponentTypes.MAP_DECORATIONS); if (mapDecorationsComponent == null) { - error("no_map_icons"); + this.error("no_map_icons").send(); return SINGLE_SUCCESS; } for (MapDecorationsComponent.Decoration decoration : mapDecorationsComponent.decorations().values()) { if (decoration.type().value().assetId().toString().equals("minecraft:woodland_mansion")) { Vec3d coords = new Vec3d(decoration.x(), 62, decoration.z()); - info("mansion", ChatUtils.formatCoords(coords)); + this.info("mansion", coords).send(); return SINGLE_SUCCESS; } } - error("cant_locate_mansion"); + this.error("cant_locate_mansion").send(); return SINGLE_SUCCESS; })); @@ -137,19 +135,19 @@ public void build(LiteralArgumentBuilder builder) { MapDecorationsComponent mapDecorationsComponent = stack.get(DataComponentTypes.MAP_DECORATIONS); if (mapDecorationsComponent == null) { - error("no_map_icons"); + this.error("no_map_icons").send(); return SINGLE_SUCCESS; } for (MapDecorationsComponent.Decoration decoration : mapDecorationsComponent.decorations().values()) { if (decoration.type().value().assetId().toString().equals("minecraft:ocean_monument")) { Vec3d coords = new Vec3d(decoration.x(), 62, decoration.z()); - info("monument", ChatUtils.formatCoords(coords)); + this.info("monument", coords).send(); return SINGLE_SUCCESS; } } - error("cant_locate_monument"); + this.error("cant_locate_monument").send(); return SINGLE_SUCCESS; } @@ -157,14 +155,14 @@ public void build(LiteralArgumentBuilder builder) { if (BaritoneUtils.IS_AVAILABLE) { Vec3d coords = findByBlockList(monumentBlocks); if (coords == null) { - error("no_monument_found", Text.translatable("filled_map.monument").formatted(Formatting.WHITE)); + this.error("no_monument_found", MessageBuilder.highlight(Text.translatable("filled_map.monument"))).send(); return SINGLE_SUCCESS; } - info("monument", ChatUtils.formatCoords(coords)); + this.info("monument", coords).send(); return SINGLE_SUCCESS; } - error("ocean_explorer_no_baritone", Text.translatable("filled_map.monument").formatted(Formatting.WHITE)); + this.error("ocean_explorer_no_baritone", MessageBuilder.highlight(Text.translatable("filled_map.monument"))).send(); return SINGLE_SUCCESS; })); @@ -178,16 +176,16 @@ public void build(LiteralArgumentBuilder builder) { secondStart = null; secondEnd = null; MeteorClient.EVENT_BUS.subscribe(this); - info("first_eye"); + this.info("first_eye").send(); } else if (BaritoneUtils.IS_AVAILABLE) { Vec3d coords = findByBlockList(strongholdBlocks); if (coords == null) { - error("no_stronghold_found", Text.translatable("item.minecraft.ender_eye").formatted(Formatting.WHITE)); + this.error("no_stronghold_found", MessageBuilder.highlight(Text.translatable("item.minecraft.ender_eye"))).send(); return SINGLE_SUCCESS; } - info("stronghold", ChatUtils.formatCoords(coords)); + this.info("stronghold", coords).send(); } else { - error("no_eyes_of_ender"); + this.error("no_eyes_of_ender").send(); } return SINGLE_SUCCESS; @@ -197,22 +195,22 @@ public void build(LiteralArgumentBuilder builder) { builder.then(literal("nether_fortress").executes(s -> { if (mc.world.getRegistryKey() != World.NETHER) { - error("not_in_nether"); + this.error("not_in_nether").send(); return SINGLE_SUCCESS; } if (!BaritoneUtils.IS_AVAILABLE) { - error("no_baritone"); + this.error("no_baritone").send(); return SINGLE_SUCCESS; } Vec3d coords = findByBlockList(netherFortressBlocks); if (coords == null) { - error("cant_locate_nether_fortress"); + this.error("cant_locate_nether_fortress").send(); return SINGLE_SUCCESS; } - info("nether_fortress", ChatUtils.formatCoords(coords)); + this.info("nether_fortress", coords).send(); return SINGLE_SUCCESS; })); @@ -220,22 +218,22 @@ public void build(LiteralArgumentBuilder builder) { builder.then(literal("end_city").executes(s -> { if (mc.world.getRegistryKey() != World.END) { - error("not_in_end"); + this.error("not_in_end").send(); return SINGLE_SUCCESS; } if (!BaritoneUtils.IS_AVAILABLE) { - error("no_baritone"); + this.error("no_baritone").send(); return SINGLE_SUCCESS; } Vec3d coords = findByBlockList(endCityBlocks); if (coords == null) { - error("cant_locate_end_city"); + this.error("cant_locate_end_city").send(); return SINGLE_SUCCESS; } - info("end_city", ChatUtils.formatCoords(coords)); + this.info("end_city", coords).send(); return SINGLE_SUCCESS; })); @@ -244,28 +242,28 @@ public void build(LiteralArgumentBuilder builder) { builder.then(literal("lodestone").executes(s -> { ItemStack stack = mc.player.getInventory().getSelectedStack(); if (stack.getItem() != Items.COMPASS) { - error("no_lodestone_compass", Text.translatable("item.minecraft.lodestone_compass").formatted(Formatting.WHITE)); + this.error("no_lodestone_compass", MessageBuilder.highlight(Text.translatable("item.minecraft.lodestone_compass"))).send(); return SINGLE_SUCCESS; } ComponentMap components = stack.getComponents(); if (components == null) { - error("no_lodestone_compass_data", Text.translatable("item.minecraft.lodestone_compass").formatted(Formatting.WHITE)); + this.error("no_lodestone_compass_data", MessageBuilder.highlight(Text.translatable("item.minecraft.lodestone_compass"))).send(); return SINGLE_SUCCESS; } LodestoneTrackerComponent lodestoneTrackerComponent = components.get(DataComponentTypes.LODESTONE_TRACKER); if (lodestoneTrackerComponent == null) { - error("no_lodestone_compass_data", Text.translatable("item.minecraft.lodestone_compass").formatted(Formatting.WHITE)); + this.error("no_lodestone_compass_data", MessageBuilder.highlight(Text.translatable("item.minecraft.lodestone_compass"))).send(); return SINGLE_SUCCESS; } if (lodestoneTrackerComponent.target().isEmpty()) { - error("no_lodestone"); + this.error("no_lodestone").send(); return SINGLE_SUCCESS; } Vec3d coords = Vec3d.of(lodestoneTrackerComponent.target().get().pos()); - info("lodestone", ChatUtils.formatCoords(coords)); + this.info("lodestone", coords).send(); return SINGLE_SUCCESS; })); @@ -276,7 +274,7 @@ public void build(LiteralArgumentBuilder builder) { } private void cancel() { - warning("canceled"); + this.warning("canceled").send(); MeteorClient.EVENT_BUS.unsubscribe(this); } @@ -286,7 +284,7 @@ private void cancel() { return null; } if (posList.size() < 3) { - warning("false_positive", posList.size()); + this.warning("false_positive", posList.size()).send(); } return new Vec3d(posList.getFirst().getX(), posList.getFirst().getY(), posList.getFirst().getZ()); } @@ -315,11 +313,11 @@ private void firstPosition(double x, double y, double z) { } private void lastPosition(double x, double y, double z) { - info(this.firstEnd == null ? "first_eye_saved" : "second_eye_saved"); + this.info(this.firstEnd == null ? "first_eye_saved" : "second_eye_saved").send(); Vec3d pos = new Vec3d(x, y, z); if (this.firstEnd == null) { this.firstEnd = pos; - info("eye_different_location"); + this.info("eye_different_location").send(); } else { this.secondEnd = pos; findStronghold(); @@ -330,7 +328,7 @@ private void findStronghold() { PathManagers.get().stop(); if (this.firstStart == null || this.firstEnd == null || this.secondStart == null || this.secondEnd == null) { - error("missing_position_data"); + this.error("missing_position_data").send(); cancel(); return; } @@ -339,7 +337,7 @@ private void findStronghold() { final double[] end = new double[]{this.firstStart.x, this.firstStart.z, this.firstEnd.x, this.firstEnd.z}; final double[] intersection = calcIntersection(start, end); if (Double.isNaN(intersection[0]) || Double.isNaN(intersection[1]) || Double.isInfinite(intersection[0]) || Double.isInfinite(intersection[1])) { - error("unable_to_calculate"); + this.error("unable_to_calculate").send(); cancel(); return; } @@ -347,7 +345,7 @@ private void findStronghold() { MeteorClient.EVENT_BUS.unsubscribe(this); Vec3d coords = new Vec3d(intersection[0], 0, intersection[1]); - info("stronghold", ChatUtils.formatCoords(coords)); + this.info("stronghold", coords).send(); } private double[] calcIntersection(double[] line, double[] line2) { diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/ModulesCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/ModulesCommand.java index b6d28610c4..8bb38fed64 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/ModulesCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/ModulesCommand.java @@ -6,10 +6,11 @@ package meteordevelopment.meteorclient.commands.commands; import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import meteordevelopment.meteorclient.MeteorClient; import meteordevelopment.meteorclient.commands.Command; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.systems.modules.Modules; -import meteordevelopment.meteorclient.utils.player.ChatUtils; +import meteordevelopment.meteorclient.utils.misc.text.MessageBuilder; import net.minecraft.command.CommandSource; import net.minecraft.text.HoverEvent; import net.minecraft.text.MutableText; @@ -24,12 +25,12 @@ public ModulesCommand() { @Override public void build(LiteralArgumentBuilder builder) { builder.executes(context -> { - ChatUtils.infoRaw("--- Modules ((highlight)%d(default)) ---", Modules.get().getCount()); + this.info("--- Modules (%s) ---", MessageBuilder.highlight(Modules.get().getCount())).send(); Modules.loopCategories().forEach(category -> { - MutableText categoryMessage = Text.literal(""); + MutableText categoryMessage = Text.empty(); Modules.get().getGroup(category).forEach(module -> categoryMessage.append(getModuleText(module))); - ChatUtils.sendMsg(category.translationKey, categoryMessage); + this.info(categoryMessage).prefix(MeteorClient.translatable(category.translationKey)).send(); }); return SINGLE_SUCCESS; @@ -38,7 +39,7 @@ public void build(LiteralArgumentBuilder builder) { private MutableText getModuleText(Module module) { // Hover tooltip - MutableText tooltip = Text.literal(""); + MutableText tooltip = Text.empty(); tooltip.append(module.getTitleText().formatted(Formatting.BLUE, Formatting.BOLD)).append("\n"); tooltip.append(Text.literal(module.name).formatted(Formatting.GRAY)).append("\n\n"); diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/NameHistoryCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/NameHistoryCommand.java index 306cd7fb74..e855e13c29 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/NameHistoryCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/NameHistoryCommand.java @@ -44,7 +44,7 @@ public void build(LiteralArgumentBuilder builder) { if (history == null) { return; } else if (history.username_history == null || history.username_history.length == 0) { - error("error_fetching_name"); + this.error("error_fetching_name").send(); } String name = lookUpTarget.getProfile().name(); @@ -66,7 +66,7 @@ public void build(LiteralArgumentBuilder builder) { )) ); - info(initial.append(Text.literal(" Username History:").formatted(Formatting.GRAY))); // todo map + this.info(initial.append(Text.literal(" Username History:").formatted(Formatting.GRAY))).send(); // todo map for (Name entry : history.username_history) { MutableText nameText = Text.literal(entry.name); @@ -90,7 +90,7 @@ public void build(LiteralArgumentBuilder builder) { nameText.append(text); } - ChatUtils.sendMsg(nameText); + this.info(nameText).send(); } }); diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/ProfilesCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/ProfilesCommand.java index c3237e36e6..2bdc0f180f 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/ProfilesCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/ProfilesCommand.java @@ -10,6 +10,7 @@ import meteordevelopment.meteorclient.commands.arguments.ProfileArgumentType; import meteordevelopment.meteorclient.systems.profiles.Profile; import meteordevelopment.meteorclient.systems.profiles.Profiles; +import meteordevelopment.meteorclient.utils.misc.text.MessageBuilder; import meteordevelopment.meteorclient.utils.player.ChatUtils; import net.minecraft.command.CommandSource; @@ -26,7 +27,7 @@ public void build(LiteralArgumentBuilder builder) { if (profile != null) { profile.load(); - info("loaded", ChatUtils.highlight(profile.name.get())); + this.info("loaded", MessageBuilder.highlight(profile.name.get())).send(); } return SINGLE_SUCCESS; @@ -37,7 +38,7 @@ public void build(LiteralArgumentBuilder builder) { if (profile != null) { profile.save(); - info("saved", ChatUtils.highlight(profile.name.get())); + this.info("saved", MessageBuilder.highlight(profile.name.get())).send(); } return SINGLE_SUCCESS; @@ -48,7 +49,7 @@ public void build(LiteralArgumentBuilder builder) { if (profile != null) { Profiles.get().remove(profile); - info("deleted", ChatUtils.highlight(profile.name.get())); + this.info("deleted", MessageBuilder.highlight(profile.name.get())).send(); } return SINGLE_SUCCESS; diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/ResetCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/ResetCommand.java index badda137ad..c029a10ffb 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/ResetCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/ResetCommand.java @@ -13,7 +13,7 @@ import meteordevelopment.meteorclient.systems.hud.Hud; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.systems.modules.Modules; -import meteordevelopment.meteorclient.utils.player.ChatUtils; +import meteordevelopment.meteorclient.utils.misc.MeteorTranslations; import net.minecraft.command.CommandSource; public class ResetCommand extends Command { @@ -28,38 +28,36 @@ public void build(LiteralArgumentBuilder builder) { .then(argument("module", ModuleArgumentType.create()).executes(context -> { Module module = context.getArgument("module", Module.class); module.settings.forEach(group -> group.forEach(Setting::reset)); - ChatUtils.forceNextPrefixClass(module.getClass()); - ChatUtils.infoPrefix(module.getTranslationKey(), "command.reset.info.module"); + module.info("command.reset.info.module").send(); return SINGLE_SUCCESS; })) .then(literal("all").executes(context -> { Modules.get().getAll().forEach(module -> module.settings.forEach(group -> group.forEach(Setting::reset))); - ChatUtils.infoPrefix("tab.modules", "command.reset.info.modules"); + this.info("modules").prefix(MeteorTranslations.translate("tab.modules")).send(); // todo maybe auto-translate prefix too? return SINGLE_SUCCESS; })) ).then(literal("gui").executes(context -> { GuiThemes.get().clearWindowConfigs(); GuiThemes.get().settings.reset(); - ChatUtils.info("command.reset.info.gui"); + this.info("gui").send(); return SINGLE_SUCCESS; })).then(literal("bind") .then(argument("module", ModuleArgumentType.create()).executes(context -> { Module module = context.getArgument("module", Module.class); module.keybind.reset(); - ChatUtils.forceNextPrefixClass(module.getClass()); - ChatUtils.infoPrefix(module.getTranslationKey(), "command.reset.info.bind"); + module.info("command.reset.info.bind").send(); return SINGLE_SUCCESS; })) .then(literal("all").executes(context -> { Modules.get().getAll().forEach(module -> module.keybind.reset()); - ChatUtils.infoPrefix("tab.modules", "command.reset.info.binds"); + this.info("binds").prefix(MeteorTranslations.translate("tab.modules")).send(); return SINGLE_SUCCESS; })) ).then(literal("hud").executes(context -> { Hud.get().resetToDefaultElements(); - ChatUtils.infoPrefix("tab.hud", "command.reset.info.hud"); + this.info("hud").prefix(MeteorTranslations.translate("tab.hud")).send(); return SINGLE_SUCCESS; })); } diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/ServerCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/ServerCommand.java index 1f87b249ad..f714f62b0f 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/ServerCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/ServerCommand.java @@ -13,7 +13,7 @@ import meteordevelopment.meteorclient.events.packets.PacketEvent; import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.mixin.ClientPlayNetworkHandlerAccessor; -import meteordevelopment.meteorclient.utils.player.ChatUtils; +import meteordevelopment.meteorclient.utils.misc.text.MessageBuilder; import meteordevelopment.meteorclient.utils.world.TickRate; import meteordevelopment.orbit.EventHandler; import net.minecraft.client.network.ServerAddress; @@ -25,7 +25,6 @@ import net.minecraft.network.packet.c2s.play.RequestCommandCompletionsC2SPacket; import net.minecraft.network.packet.s2c.play.CommandSuggestionsS2CPacket; import net.minecraft.network.packet.s2c.play.CommandTreeS2CPacket; -import net.minecraft.screen.ScreenTexts; import net.minecraft.server.integrated.IntegratedServer; import net.minecraft.text.*; import net.minecraft.util.Formatting; @@ -87,7 +86,7 @@ public void build(LiteralArgumentBuilder builder) { if (tps > 17.0f) color = Formatting.GREEN; else if (tps > 12.0f) color = Formatting.YELLOW; else color = Formatting.RED; - info("tps", Text.literal(String.format("%.2f", tps)).formatted(color)); + this.info("tps", Text.literal(String.format("%.2f", tps)).formatted(color)).send(); return SINGLE_SUCCESS; })); } @@ -96,8 +95,8 @@ private void basicInfo() { if (mc.isIntegratedServerRunning()) { IntegratedServer server = mc.getServer(); - info("singleplayer"); - if (server != null) info("version", server.getVersion()); + this.info("singleplayer").send(); + if (server != null) this.info("version", server.getVersion()).send(); return; } @@ -105,7 +104,7 @@ private void basicInfo() { ServerInfo server = mc.getCurrentServerEntry(); if (server == null) { - error("cant_obtain_info"); + this.error("cant_obtain_info").send(); return; } @@ -136,14 +135,14 @@ private void basicInfo() { ); ipText.append(ipv4Text); } - info("ip", ipText); - - info("port", ServerAddress.parse(server.address).getPort()); - info("type", mc.getNetworkHandler().getBrand() != null ? mc.getNetworkHandler().getBrand() : MeteorClient.translatable("command.server.info.unknown")); - info("motd", server.label != null ? server.label.getString() : MeteorClient.translatable("command.server.info.unknown")); - info("version", server.version.getString()); - info("protocol_version", server.protocolVersion); - info("difficulty", + this.info("ip", ipText).send(); + + this.info("port", ServerAddress.parse(server.address).getPort()).send(); + this.info("type", mc.getNetworkHandler().getBrand() != null ? mc.getNetworkHandler().getBrand() : MeteorClient.translatable("command.server.info.unknown")).send(); + this.info("motd", server.label != null ? server.label.getString() : MeteorClient.translatable("command.server.info.unknown")).send(); + this.info("version", server.version.getString()).send(); + this.info("protocol_version", server.protocolVersion).send(); + this.info("difficulty", mc.world.getDifficulty().getTranslatableName(), String.format("%.2f", new LocalDifficulty( mc.world.getDifficulty(), @@ -151,9 +150,9 @@ private void basicInfo() { mc.world.getChunk(mc.player.getBlockPos()).getInhabitedTime(), DimensionType.MOON_SIZES[mc.world.getEnvironmentAttributes().getAttributeValue(EnvironmentAttributes.MOON_PHASE_VISUAL, mc.player.getBlockPos()).getIndex()] // lol ).getLocalDifficulty()) - ); - info("day", mc.world.getTimeOfDay() / 24000L); - info(formatPerms()); + ).send(); + this.info("day", mc.world.getTimeOfDay() / 24000L).send(); + this.info(formatPerms()).send(); } public String formatPerms() { @@ -177,9 +176,9 @@ private void printPlugins() { } if (!plugins.isEmpty()) { - info("plugins", plugins.size(), Texts.join(pluginTexts, Texts.DEFAULT_SEPARATOR_TEXT)); + this.info("plugins", plugins.size(), Texts.join(pluginTexts, Texts.DEFAULT_SEPARATOR_TEXT)).send(); } else { - error("no_plugins"); + this.error("no_plugins").send(); } tick = false; @@ -236,7 +235,7 @@ private void onReadPacket(PacketEvent.Receive event) { Suggestions matches = packet.getSuggestions(); if (matches.isEmpty()) { - error("plugins"); + this.error("plugins").send(); return; } @@ -248,7 +247,7 @@ private void onReadPacket(PacketEvent.Receive event) { printPlugins(); } } catch (Exception e) { - error("plugins"); + this.error("plugins").send(); } } @@ -260,6 +259,6 @@ else if (Strings.CI.contains(name, "exploit") || Strings.CI.contains(name, "chea return Text.literal(name).formatted(Formatting.RED); } - return ChatUtils.highlight(name); + return MessageBuilder.highlight(name); } } diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/SwarmCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/SwarmCommand.java index cc2281657b..fbf7678609 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/SwarmCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/SwarmCommand.java @@ -22,6 +22,7 @@ import meteordevelopment.meteorclient.systems.modules.misc.swarm.SwarmConnection; import meteordevelopment.meteorclient.systems.modules.misc.swarm.SwarmWorker; import meteordevelopment.meteorclient.systems.modules.world.InfinityMiner; +import meteordevelopment.meteorclient.utils.misc.text.MessageBuilder; import meteordevelopment.meteorclient.utils.misc.text.MeteorClickEvent; import meteordevelopment.meteorclient.utils.player.ChatUtils; import net.minecraft.command.CommandSource; @@ -69,11 +70,11 @@ public void build(LiteralArgumentBuilder builder) { pendingConnection = new ObjectIntImmutablePair<>(ip, port); - info("Are you sure you want to connect to '%s:%s'?", ip, port); - info(Text.literal("Click here to confirm").setStyle(Style.EMPTY + this.info("Are you sure you want to connect to '%s:%s'?", ip, port).send(); + this.info(Text.literal("Click here to confirm").setStyle(Style.EMPTY .withFormatting(Formatting.UNDERLINE, Formatting.GREEN) .withClickEvent(new MeteorClickEvent(".swarm join confirm")) - )); + )).send(); return SINGLE_SUCCESS; }) @@ -81,7 +82,7 @@ public void build(LiteralArgumentBuilder builder) { ) .then(literal("confirm").executes(ctx -> { if (pendingConnection == null) { - error("No pending swarm connections."); + this.error("No pending swarm connections.").send(); return SINGLE_SUCCESS; } @@ -95,9 +96,9 @@ public void build(LiteralArgumentBuilder builder) { pendingConnection = null; try { - info("Connected to (highlight)%s.", swarm.worker.getConnection()); + this.info("Connected to %s.", MessageBuilder.highlight(swarm.worker.getConnection())).send(); } catch (NullPointerException e) { - error("Error connecting to swarm host."); + this.error("Error connecting to swarm host.").send(); swarm.close(); swarm.toggle(); } @@ -111,19 +112,22 @@ public void build(LiteralArgumentBuilder builder) { if (swarm.isActive()) { if (swarm.isHost()) { if (swarm.host.getConnectionCount() > 0) { - ChatUtils.infoRaw("--- Swarm Connections (highlight)(%s/%s)(default) ---", swarm.host.getConnectionCount(), swarm.host.getConnections().length); + + this.info("--- Swarm Connections (%s/%s) ---", MessageBuilder.highlight(swarm.host.getConnectionCount()), MessageBuilder.highlight(swarm.host.getConnections().length)).send(); for (int i = 0; i < swarm.host.getConnections().length; i++) { SwarmConnection connection = swarm.host.getConnections()[i]; - if (connection != null) ChatUtils.infoRaw("(highlight)Worker %s(default): %s.", i, connection.getConnection()); + if (connection != null) { + this.info("%s: %s.", MessageBuilder.highlight("Worker " + i), connection.getConnection()).send(); + } } } else { - warning("No active connections"); + this.warning("No active connections").send(); } } else if (swarm.isWorker()) { - info("Connected to (highlight)%s", swarm.worker.getConnection()); + this.info("Connected to %s.", MessageBuilder.highlight(swarm.worker.getConnection())).send(); } } else { @@ -140,7 +144,7 @@ else if (swarm.isWorker()) { swarm.host.sendMessage(context.getInput() + " " + mc.player.getName().getString()); } else if (swarm.isWorker()) { - error("The follow host command must be used by the host."); + this.error("The follow host command must be used by the host.").send(); } } else { diff --git a/src/main/java/meteordevelopment/meteorclient/mixin/BookScreenMixin.java b/src/main/java/meteordevelopment/meteorclient/mixin/BookScreenMixin.java index 1936238b0f..8112f2cb86 100644 --- a/src/main/java/meteordevelopment/meteorclient/mixin/BookScreenMixin.java +++ b/src/main/java/meteordevelopment/meteorclient/mixin/BookScreenMixin.java @@ -8,7 +8,7 @@ import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream; import meteordevelopment.meteorclient.gui.GuiThemes; import meteordevelopment.meteorclient.gui.screens.EditBookTitleAndAuthorScreen; -import meteordevelopment.meteorclient.utils.player.ChatUtils; +import meteordevelopment.meteorclient.utils.misc.text.MessageBuilder; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.BookScreen; import net.minecraft.client.gui.widget.ButtonWidget; @@ -73,7 +73,7 @@ private void onInit(CallbackInfo info) { long size = MemoryUtil.memLengthUTF8(encoded, true); if (size > available) { - ChatUtils.errorRaw("Could not copy to clipboard: Out of memory."); + MessageBuilder.error("Could not copy to clipboard: Out of memory.").send(); } else { GLFW.glfwSetClipboardString(mc.getWindow().getHandle(), encoded); } diff --git a/src/main/java/meteordevelopment/meteorclient/mixin/ClientPlayNetworkHandlerMixin.java b/src/main/java/meteordevelopment/meteorclient/mixin/ClientPlayNetworkHandlerMixin.java index 3a7af0fe64..9da04675a3 100644 --- a/src/main/java/meteordevelopment/meteorclient/mixin/ClientPlayNetworkHandlerMixin.java +++ b/src/main/java/meteordevelopment/meteorclient/mixin/ClientPlayNetworkHandlerMixin.java @@ -27,7 +27,7 @@ import meteordevelopment.meteorclient.systems.modules.Modules; import meteordevelopment.meteorclient.systems.modules.movement.Velocity; import meteordevelopment.meteorclient.systems.modules.render.NoRender; -import meteordevelopment.meteorclient.utils.player.ChatUtils; +import meteordevelopment.meteorclient.utils.misc.text.MessageBuilder; import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientCommonNetworkHandler; import net.minecraft.client.network.ClientConnectionState; @@ -150,7 +150,7 @@ private void onSendChatMessage(String message, CallbackInfo ci, @Local(argsOnly try { Commands.dispatch(message.substring(Config.get().prefix.get().length())); } catch (CommandSyntaxException e) { - ChatUtils.errorRaw(e.getMessage()); + MessageBuilder.error(e.getMessage()).send(); } client.inGameHud.getChatHud().addToMessageHistory(message); diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/BetterChat.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/BetterChat.java index ac4f510c41..72e280f63d 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/BetterChat.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/BetterChat.java @@ -23,7 +23,6 @@ import meteordevelopment.meteorclient.utils.Utils; import meteordevelopment.meteorclient.utils.misc.text.MeteorClickEvent; import meteordevelopment.meteorclient.utils.misc.text.TextVisitor; -import meteordevelopment.meteorclient.utils.player.ChatUtils; import meteordevelopment.orbit.EventHandler; import net.minecraft.client.gl.RenderPipelines; import net.minecraft.client.gui.DrawContext; @@ -296,7 +295,7 @@ private void onMessageSend(SendMessageEvent event) { MutableText sendButton = getSendButton(message); warningMessage.append(sendButton); - ChatUtils.sendMsg(warningMessage); + this.info(warningMessage).send(); event.cancel(); return; diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/Notifier.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/Notifier.java index 058604173a..459ce8682c 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/Notifier.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/Notifier.java @@ -18,7 +18,7 @@ import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.entity.fakeplayer.FakePlayerEntity; -import meteordevelopment.meteorclient.utils.player.ChatUtils; +import meteordevelopment.meteorclient.utils.misc.text.MessageBuilder; import meteordevelopment.meteorclient.utils.player.PlayerUtils; import meteordevelopment.orbit.EventHandler; import net.minecraft.client.network.PlayerListEntry; @@ -32,7 +32,6 @@ import net.minecraft.network.packet.s2c.play.PlayerRemoveS2CPacket; import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundEvents; -import net.minecraft.text.MutableText; import net.minecraft.text.Text; import net.minecraft.util.Formatting; import net.minecraft.util.collection.ArrayListDeque; @@ -40,8 +39,6 @@ import java.util.*; -import static meteordevelopment.meteorclient.utils.player.ChatUtils.formatCoords; - public class Notifier extends Module { private final SettingGroup sgTotemPops = settings.createGroup("totem-pops"); private final SettingGroup sgVisualRange = settings.createGroup("visual-range"); @@ -175,7 +172,7 @@ public class Notifier extends Module { private final Object2IntMap totemPopMap = new Object2IntOpenHashMap<>(); private final Object2IntMap chatIdMap = new Object2IntOpenHashMap<>(); private final Map pearlStartPosMap = new HashMap<>(); - private final ArrayListDeque messageQueue = new ArrayListDeque<>(); + private final ArrayListDeque messageQueue = new ArrayListDeque<>(); private final Random random = new Random(); @@ -190,17 +187,17 @@ private void onEntityAdded(EntityAddedEvent event) { if (!event.entity.getUuid().equals(mc.player.getUuid()) && entities.get().contains(event.entity.getType()) && visualRange.get() && this.event.get() != Event.Despawn) { if (event.entity instanceof PlayerEntity) { if ((!visualRangeIgnoreFriends.get() || !Friends.get().isFriend(((PlayerEntity) event.entity))) && (!visualRangeIgnoreFakes.get() || !(event.entity instanceof FakePlayerEntity))) { - ChatUtils.sendMsg(event.entity.getId() + 100, Formatting.GRAY, this.getTranslationKey() + ".info.entered_visual_range", event.entity.getName().getString()); + this.info("entered_visual_range", event.entity).setId(event.entity.getId() + 100).send(); if (visualMakeSound.get()) mc.world.playSoundFromEntity(mc.player, mc.player, SoundEvents.ENTITY_EXPERIENCE_ORB_PICKUP, SoundCategory.AMBIENT, 3.0F, 1.0F); } } else { - info( + this.info( "spawned", - Text.literal(event.entity.getType().getName().getString()).formatted(Formatting.WHITE), - formatCoords(event.entity.getEntityPos()) - ); + MessageBuilder.highlight(event.entity.getType()), + event.entity.getEntityPos() + ).send(); } } @@ -214,17 +211,17 @@ private void onEntityRemoved(EntityRemovedEvent event) { if (!event.entity.getUuid().equals(mc.player.getUuid()) && entities.get().contains(event.entity.getType()) && visualRange.get() && this.event.get() != Event.Spawn) { if (event.entity instanceof PlayerEntity) { if ((!visualRangeIgnoreFriends.get() || !Friends.get().isFriend(((PlayerEntity) event.entity))) && (!visualRangeIgnoreFakes.get() || !(event.entity instanceof FakePlayerEntity))) { - ChatUtils.sendMsg(event.entity.getId() + 100, Formatting.GRAY, this.getTranslationKey() + ".info.left_visual_range", event.entity.getName().getString()); + this.info("left_visual_range", event.entity).setId(event.entity.getId() + 100).send(); if (visualMakeSound.get()) mc.world.playSoundFromEntity(mc.player, mc.player, SoundEvents.ENTITY_EXPERIENCE_ORB_PICKUP, SoundCategory.AMBIENT, 3.0F, 1.0F); } } else { - info( + this.info( "despawned", - Text.literal(event.entity.getType().getName().getString()).formatted(Formatting.WHITE), - formatCoords(event.entity.getEntityPos()) - ); + MessageBuilder.highlight(event.entity.getType()), + event.entity.getEntityPos() + ).send(); } } @@ -236,13 +233,13 @@ private void onEntityRemoved(EntityRemovedEvent event) { if (pearl.getOwner() != null && pearl.getOwner() instanceof PlayerEntity p) { double d = pearlStartPosMap.get(i).distanceTo(e.getEntityPos()); if ((!Friends.get().isFriend(p) || !pearlIgnoreFriends.get()) && (!p.equals(mc.player) || !pearlIgnoreOwn.get())) { - info( + this.info( "pearl_landed", - Text.literal(pearl.getOwner().getName().getString()).formatted(Formatting.WHITE), - ChatUtils.formatCoords(pearl.getEntityPos()), - String.format("%.1f", pearl.distanceTo(mc.player)), - String.format("%.1f", d) - ); + MessageBuilder.highlight(pearl.getOwner()), + pearl.getEntityPos(), + pearl.distanceTo(mc.player), + d + ).send(); } } pearlStartPosMap.remove(i); @@ -308,7 +305,11 @@ private void onReceivePacket(PacketEvent.Receive event) { double distance = PlayerUtils.distanceTo(entity); if (totemsDistanceCheck.get() && distance > totemsDistance.get()) return; - ChatUtils.sendMsgRaw(getChatId(entity), Formatting.GRAY, "(highlight)%s (default)popped (highlight)%d (default)%s.", entity.getName().getString(), pops, pops == 1 ? "totem" : "totems"); + if (pops == 1) { + this.info("popped_singular", MessageBuilder.highlight(entity)).setId(getChatId(entity)).send(); + } else { + this.info("popped_multiple", MessageBuilder.highlight(entity), MessageBuilder.highlight(pops)).setId(getChatId(entity)).send(); + } } } default -> {} @@ -322,9 +323,9 @@ private void onTick(TickEvent.Post event) { while (timer >= notificationDelay.get() && !messageQueue.isEmpty()) { timer = 0; if (simpleNotifications.get()) { - mc.player.sendMessage(messageQueue.removeFirst(), false); + mc.player.sendMessage(messageQueue.removeFirst().build(), false); // todo maybe remove client prefix? } else { - ChatUtils.sendMsg(messageQueue.removeFirst()); + messageQueue.removeFirst().send(); } } } @@ -337,7 +338,12 @@ private void onTick(TickEvent.Post event) { if (player.deathTime > 0 || player.getHealth() <= 0) { int pops = totemPopMap.removeInt(player.getUuid()); - ChatUtils.sendMsgRaw(getChatId(player), Formatting.GRAY, "(highlight)%s (default)died after popping (highlight)%d (default)%s.", player.getName().getString(), pops, pops == 1 ? "totem" : "totems"); + if (pops == 1) { + this.info("died_after_popping_singular", MessageBuilder.highlight(player)).setId(getChatId(player)).send(); + } else { + this.info("died_after_popping_multiple", MessageBuilder.highlight(player), MessageBuilder.highlight(pops)).setId(getChatId(player)).send(); + } + chatIdMap.removeInt(player.getUuid()); } } @@ -353,18 +359,13 @@ private void createJoinNotifications(PlayerListS2CPacket packet) { if (entry.profile() == null) continue; if (simpleNotifications.get()) { - messageQueue.addLast(Text.literal( - Formatting.GRAY + "[" - + Formatting.GREEN + "+" - + Formatting.GRAY + "] " - + entry.profile().name() - )); + messageQueue.addLast(this.info( + "[%s] %s", + Text.literal("+").formatted(Formatting.GREEN), + MessageBuilder.highlight(entry.profile().name()) + ).removePrefix()); } else { - messageQueue.addLast(Text.literal( - Formatting.WHITE - + entry.profile().name() - + Formatting.GRAY + " joined." - )); + messageQueue.addLast(this.info("joined", MessageBuilder.highlight(entry.profile().name()))); } } } @@ -377,18 +378,13 @@ private void createLeaveNotification(PlayerRemoveS2CPacket packet) { if (toRemove == null) continue; if (simpleNotifications.get()) { - messageQueue.addLast(Text.literal( - Formatting.GRAY + "[" - + Formatting.RED + "-" - + Formatting.GRAY + "] " - + toRemove.getProfile().name() - )); + messageQueue.addLast(this.info( + "[%s] %s", + Text.literal("-").formatted(Formatting.GREEN), + MessageBuilder.highlight(toRemove.getProfile().name()) + ).removePrefix()); } else { - messageQueue.addLast(Text.literal( - Formatting.WHITE - + toRemove.getProfile().name() - + Formatting.GRAY + " left." - )); + messageQueue.addLast(this.info("left", MessageBuilder.highlight(toRemove.getProfile().name()))); } } } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmConnection.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmConnection.java index 75e78ca881..a4795dcd79 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmConnection.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmConnection.java @@ -5,7 +5,8 @@ package meteordevelopment.meteorclient.systems.modules.misc.swarm; -import meteordevelopment.meteorclient.utils.player.ChatUtils; +import meteordevelopment.meteorclient.MeteorClient; +import meteordevelopment.meteorclient.utils.misc.text.MessageBuilder; import java.io.DataOutputStream; import java.io.IOException; @@ -22,7 +23,7 @@ public SwarmConnection(Socket socket) { @Override public void run() { - ChatUtils.infoPrefixRaw("module.swarm", "New worker connected on %s.", getIp(socket.getInetAddress().getHostAddress())); + MessageBuilder.info("New worker connected on %s.", getIp(socket.getInetAddress().getHostAddress())).prefix(MeteorClient.translatable("module.swarm")).send(); try { DataOutputStream out = new DataOutputStream(socket.getOutputStream()); @@ -33,7 +34,7 @@ public void run() { out.writeUTF(messageToSend); out.flush(); } catch (Exception e) { - ChatUtils.errorPrefixRaw("module.swarm", "Encountered error when sending command."); + MessageBuilder.error("Encountered error when sending command.").prefix(MeteorClient.translatable("module.swarm")).send(); e.printStackTrace(); } @@ -43,7 +44,7 @@ public void run() { out.close(); } catch (IOException e) { - ChatUtils.infoPrefixRaw("module.swarm", "Error creating a connection with %s on port %s.", getIp(socket.getInetAddress().getHostAddress()), socket.getPort()); + MessageBuilder.info("Error creating a connection with %s on port %s.", getIp(socket.getInetAddress().getHostAddress()), socket.getPort()).prefix(MeteorClient.translatable("module.swarm")).send(); e.printStackTrace(); } } @@ -55,7 +56,7 @@ public void disconnect() { e.printStackTrace(); } - ChatUtils.infoPrefixRaw("module.swarm", "Worker disconnected on ip: %s.", socket.getInetAddress().getHostAddress()); + MessageBuilder.info("Worker disconnected on ip: %s.", socket.getInetAddress().getHostAddress()).prefix(MeteorClient.translatable("module.swarm")).send(); interrupt(); } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmHost.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmHost.java index 89fe3a17f5..1e25259758 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmHost.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmHost.java @@ -5,8 +5,9 @@ package meteordevelopment.meteorclient.systems.modules.misc.swarm; +import meteordevelopment.meteorclient.MeteorClient; +import meteordevelopment.meteorclient.utils.misc.text.MessageBuilder; import meteordevelopment.meteorclient.utils.network.MeteorExecutor; -import meteordevelopment.meteorclient.utils.player.ChatUtils; import java.io.IOException; import java.net.ServerSocket; @@ -21,7 +22,7 @@ public SwarmHost(int port) { socket = new ServerSocket(port); } catch (IOException e) { socket = null; - ChatUtils.errorPrefixRaw("module.swarm", "Couldn't start a server on port %s.", port); + MessageBuilder.error("Couldn't start a server on port %s.", port).prefix(MeteorClient.translatable("module.swarm")).send(); e.printStackTrace(); } @@ -30,14 +31,14 @@ public SwarmHost(int port) { @Override public void run() { - ChatUtils.infoPrefixRaw("module.swarm", "Listening for incoming connections on port %s.", socket.getLocalPort()); + MessageBuilder.info("Listening for incoming connections on port %s.", socket.getLocalPort()).prefix(MeteorClient.translatable("module.swarm")).send(); while (!isInterrupted()) { try { Socket connection = socket.accept(); assignConnectionToSubServer(connection); } catch (IOException e) { - ChatUtils.errorPrefixRaw("module.swarm", "Error making a connection to worker."); + MessageBuilder.error("Error making a connection to worker.").prefix(MeteorClient.translatable("module.swarm")).send(); e.printStackTrace(); } } @@ -63,7 +64,7 @@ public void disconnect() { e.printStackTrace(); } - ChatUtils.infoPrefixRaw("module.swarm", "Server closed on port %s.", socket.getLocalPort()); + MessageBuilder.info("Server closed on port %s.", socket.getLocalPort()).prefix(MeteorClient.translatable("module.swarm")).send(); interrupt(); } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmWorker.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmWorker.java index 249750cb07..9ec035b5b4 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmWorker.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/swarm/SwarmWorker.java @@ -5,9 +5,10 @@ package meteordevelopment.meteorclient.systems.modules.misc.swarm; +import meteordevelopment.meteorclient.MeteorClient; import meteordevelopment.meteorclient.commands.Commands; import meteordevelopment.meteorclient.pathing.PathManagers; -import meteordevelopment.meteorclient.utils.player.ChatUtils; +import meteordevelopment.meteorclient.utils.misc.text.MessageBuilder; import net.minecraft.block.Block; import java.io.DataInputStream; @@ -23,7 +24,7 @@ public SwarmWorker(String ip, int port) { socket = new Socket(ip, port); } catch (Exception e) { socket = null; - ChatUtils.warningPrefixRaw("module.swarm", "Server not found at %s on port %s.", ip, port); + MessageBuilder.warning("Server not found at %s on port %s.", ip, port).prefix(MeteorClient.translatable("module.swarm")).send(); e.printStackTrace(); } @@ -32,7 +33,7 @@ public SwarmWorker(String ip, int port) { @Override public void run() { - ChatUtils.infoPrefixRaw("module.swarm", "Connected to Swarm host on at %s on port %s.", getIp(socket.getInetAddress().getHostAddress()), socket.getPort()); + MessageBuilder.info("Connected to Swarm host on at %s on port %s.", getIp(socket.getInetAddress().getHostAddress()), socket.getPort()).prefix(MeteorClient.translatable("module.swarm")).send(); try { DataInputStream in = new DataInputStream(socket.getInputStream()); @@ -42,12 +43,12 @@ public void run() { String read = in.readUTF(); if (read.startsWith("swarm")) { - ChatUtils.infoPrefixRaw("module.swarm", "Received command: (highlight)%s", read); + MessageBuilder.info("Received command: %s", MessageBuilder.highlight(read)).prefix(MeteorClient.translatable("module.swarm")).send(); try { Commands.dispatch(read); } catch (Exception e) { - ChatUtils.errorPrefixRaw("module.swarm", "Error fetching command."); + MessageBuilder.error("Error fetching command.").prefix(MeteorClient.translatable("module.swarm")).send(); e.printStackTrace(); } } @@ -55,7 +56,7 @@ public void run() { in.close(); } catch (IOException e) { - ChatUtils.errorPrefixRaw("module.swarm", "Error in connection to host."); + MessageBuilder.error("Error in connection to host.").prefix(MeteorClient.translatable("module.swarm")).send(); e.printStackTrace(); disconnect(); } @@ -70,7 +71,7 @@ public void disconnect() { PathManagers.get().stop(); - ChatUtils.infoPrefixRaw("module.swarm", "Disconnected from host."); + MessageBuilder.info("Disconnected from host.").prefix(MeteorClient.translatable("module.swarm")).send(); interrupt(); } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/WaypointsModule.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/WaypointsModule.java index 075cb0e1a9..4f00004e4b 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/WaypointsModule.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/WaypointsModule.java @@ -30,8 +30,6 @@ import meteordevelopment.orbit.EventHandler; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.DeathScreen; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import org.joml.Vector3d; @@ -41,8 +39,6 @@ import java.util.Date; import java.util.List; -import static meteordevelopment.meteorclient.utils.player.ChatUtils.formatCoords; - public class WaypointsModule extends Module { private static final Color GRAY = new Color(200, 200, 200); private static final Color TEXT = new Color(255, 255, 255); @@ -171,7 +167,7 @@ private void onOpenScreen(OpenScreenEvent event) { public void addDeath(Vec3d deathPos) { String time = dateFormat.format(new Date()); if (dpChat.get()) { - info("death", formatCoords(deathPos), time); + info("death", deathPos, time); } // Create waypoint