From 85d04f2bd48da2c39d47ff16a372db15128dc162 Mon Sep 17 00:00:00 2001 From: cqb13 Date: Fri, 9 Jan 2026 16:23:25 -0500 Subject: [PATCH 1/2] added help command --- .../meteorclient/commands/Commands.java | 1 + .../arguments/CommandArgumentType.java | 78 +++++++++++++++++ .../commands/commands/HelpCommand.java | 85 +++++++++++++++++++ 3 files changed, 164 insertions(+) create mode 100644 src/main/java/meteordevelopment/meteorclient/commands/arguments/CommandArgumentType.java create mode 100644 src/main/java/meteordevelopment/meteorclient/commands/commands/HelpCommand.java diff --git a/src/main/java/meteordevelopment/meteorclient/commands/Commands.java b/src/main/java/meteordevelopment/meteorclient/commands/Commands.java index 8764f20636..c80c9054ad 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/Commands.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/Commands.java @@ -67,6 +67,7 @@ public static void init() { add(new InputCommand()); add(new WaspCommand()); add(new LocateCommand()); + add(new HelpCommand()); COMMANDS.sort(Comparator.comparing(Command::getName)); diff --git a/src/main/java/meteordevelopment/meteorclient/commands/arguments/CommandArgumentType.java b/src/main/java/meteordevelopment/meteorclient/commands/arguments/CommandArgumentType.java new file mode 100644 index 0000000000..a04494b394 --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/commands/arguments/CommandArgumentType.java @@ -0,0 +1,78 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.commands.arguments; + +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import meteordevelopment.meteorclient.commands.Command; +import meteordevelopment.meteorclient.commands.Commands; +import net.minecraft.command.CommandSource; +import net.minecraft.text.Text; + +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; + +public class CommandArgumentType implements ArgumentType { + private static final CommandArgumentType INSTANCE = new CommandArgumentType(); + private static final DynamicCommandExceptionType NO_SUCH_COMMAND = new DynamicCommandExceptionType(name -> Text.literal("Command with name " + name + " doesn't exist.")); + private static final Collection EXAMPLES = Commands.COMMANDS.stream().limit(3).map(Command::getName).collect(Collectors.toList()); + + private CommandArgumentType() { + } + + public static CommandArgumentType create() { + return INSTANCE; + } + + public static Command get(CommandContext context) { + return context.getArgument("command", Command.class); + } + + @Override + public Command parse(StringReader reader) throws CommandSyntaxException { + String name = reader.readString(); + + Command command = Commands.get(name); + + if (command == null) { + for (Command c : Commands.COMMANDS) { + for (String alias : c.getAliases()) { + if (alias.equals(name)) { + command = c; + break; + } + } + if (command != null) break; + } + } + + if (command == null) throw NO_SUCH_COMMAND.create(name); + return command; + } + + @Override + public CompletableFuture listSuggestions(CommandContext context, SuggestionsBuilder builder) { + Set suggestions = new LinkedHashSet<>(); + for (Command c : Commands.COMMANDS) { + suggestions.add(c.getName()); + suggestions.addAll(c.getAliases()); + } + return CommandSource.suggestMatching(suggestions, builder); + } + + @Override + public Collection getExamples() { + return EXAMPLES; + } +} diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/HelpCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/HelpCommand.java new file mode 100644 index 0000000000..cbcd031445 --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/HelpCommand.java @@ -0,0 +1,85 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.commands.commands; + +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.tree.CommandNode; +import meteordevelopment.meteorclient.commands.Command; +import meteordevelopment.meteorclient.commands.Commands; +import meteordevelopment.meteorclient.commands.arguments.CommandArgumentType; +import meteordevelopment.meteorclient.systems.config.Config; +import meteordevelopment.meteorclient.utils.player.ChatUtils; +import net.minecraft.command.CommandSource; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; + +import java.util.Map; + +public class HelpCommand extends Command { + public HelpCommand() { + super("help", "Shows you what a command does."); + } + + @Override + public void build(LiteralArgumentBuilder builder) { + builder.then(argument("command", CommandArgumentType.create()).executes(context -> { + showHelp(CommandArgumentType.get(context)); + return SINGLE_SUCCESS; + })); + + builder.executes(context -> { + showHelp(this); + return SINGLE_SUCCESS; + }); + } + + private void showHelp(Command cmd) { + MutableText msg = Text.literal(""); + + msg.append(Text.literal("Help for ").formatted(Formatting.GRAY).append(Text.literal(cmd.getName()).formatted(Formatting.YELLOW))); + + msg.append(Text.literal("\n")).append(Text.literal("Description: ").formatted(Formatting.GRAY).append(Text.literal(cmd.getDescription()).formatted(Formatting.WHITE))); + + msg.append(Text.literal("\n")).append(Text.literal("Aliases: ").formatted(Formatting.GRAY)); + + if (cmd.getAliases().isEmpty()) { + msg.append(Text.literal("None").formatted(Formatting.DARK_GRAY)); + } else { + msg.append(Text.literal(String.join(", ", cmd.getAliases())).formatted(Formatting.AQUA)); + } + + msg.append(getUsageText(cmd)); + + ChatUtils.sendMsg(msg); + } + + private MutableText getUsageText(Command cmd) { + CommandSource source = mc.getNetworkHandler().getCommandSource(); + CommandNode root = Commands.DISPATCHER.getRoot(); + CommandNode node = root.getChild(cmd.getName()); + + MutableText usagesText = Text.literal(""); + + if (node != null) { + Map, String> usages = Commands.DISPATCHER.getSmartUsage(node, source); + + boolean first = true; + for (String usage : usages.values()) { + if (!first) usagesText.append(Text.literal("\n")); + first = false; + + usagesText.append(Text.literal(Config.get().prefix.get()).formatted(Formatting.DARK_GRAY).append(Text.literal(usage).formatted(Formatting.GREEN))); + } + } + + if (usagesText.getString().isEmpty()) { + usagesText.append(Text.literal(cmd.toString()).formatted(Formatting.GREEN)); + } + + return Text.literal("\nUsage:\n").formatted(Formatting.GRAY).append(usagesText); + } +} From 5157e9786842895bc2ebf8bdb9c54df8768777f5 Mon Sep 17 00:00:00 2001 From: Wide_Cat Date: Wed, 4 Feb 2026 16:19:01 +0000 Subject: [PATCH 2/2] update formatting and reformat code --- .../commands/commands/HelpCommand.java | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/HelpCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/HelpCommand.java index cbcd031445..6e68226c80 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/HelpCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/HelpCommand.java @@ -10,7 +10,6 @@ import meteordevelopment.meteorclient.commands.Command; import meteordevelopment.meteorclient.commands.Commands; import meteordevelopment.meteorclient.commands.arguments.CommandArgumentType; -import meteordevelopment.meteorclient.systems.config.Config; import meteordevelopment.meteorclient.utils.player.ChatUtils; import net.minecraft.command.CommandSource; import net.minecraft.text.MutableText; @@ -39,21 +38,15 @@ public void build(LiteralArgumentBuilder builder) { private void showHelp(Command cmd) { MutableText msg = Text.literal(""); - msg.append(Text.literal("Help for ").formatted(Formatting.GRAY).append(Text.literal(cmd.getName()).formatted(Formatting.YELLOW))); + msg.append(Text.literal("\n ")).append(Text.literal("Description: ").formatted(Formatting.GRAY).append(Text.literal(cmd.getDescription()).formatted(Formatting.WHITE))); - msg.append(Text.literal("\n")).append(Text.literal("Description: ").formatted(Formatting.GRAY).append(Text.literal(cmd.getDescription()).formatted(Formatting.WHITE))); - - msg.append(Text.literal("\n")).append(Text.literal("Aliases: ").formatted(Formatting.GRAY)); - - if (cmd.getAliases().isEmpty()) { - msg.append(Text.literal("None").formatted(Formatting.DARK_GRAY)); - } else { + if (!cmd.getAliases().isEmpty()) { + msg.append(Text.literal("\n ")).append(Text.literal("Aliases: ").formatted(Formatting.GRAY)); msg.append(Text.literal(String.join(", ", cmd.getAliases())).formatted(Formatting.AQUA)); } msg.append(getUsageText(cmd)); - ChatUtils.sendMsg(msg); } @@ -67,19 +60,15 @@ private MutableText getUsageText(Command cmd) { if (node != null) { Map, String> usages = Commands.DISPATCHER.getSmartUsage(node, source); - boolean first = true; for (String usage : usages.values()) { - if (!first) usagesText.append(Text.literal("\n")); - first = false; - - usagesText.append(Text.literal(Config.get().prefix.get()).formatted(Formatting.DARK_GRAY).append(Text.literal(usage).formatted(Formatting.GREEN))); + usagesText.append(Text.literal("\n " + cmd + " ").formatted(Formatting.GREEN)).append(Text.literal(usage).formatted(Formatting.GREEN)); } } if (usagesText.getString().isEmpty()) { - usagesText.append(Text.literal(cmd.toString()).formatted(Formatting.GREEN)); + usagesText.append(Text.literal("\n " + cmd).formatted(Formatting.GREEN)); } - return Text.literal("\nUsage:\n").formatted(Formatting.GRAY).append(usagesText); + return Text.literal("\n Usage:").formatted(Formatting.GRAY).append(usagesText); } }