Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand Down
Original file line number Diff line number Diff line change
@@ -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<Command> {
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<String> 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 <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
Set<String> suggestions = new LinkedHashSet<>();
for (Command c : Commands.COMMANDS) {
suggestions.add(c.getName());
suggestions.addAll(c.getAliases());
}
return CommandSource.suggestMatching(suggestions, builder);
}

@Override
public Collection<String> getExamples() {
return EXAMPLES;
}
}
Original file line number Diff line number Diff line change
@@ -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<CommandSource> 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<CommandSource> root = Commands.DISPATCHER.getRoot();
CommandNode<CommandSource> node = root.getChild(cmd.getName());

MutableText usagesText = Text.literal("");

if (node != null) {
Map<CommandNode<CommandSource>, 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);
}
}