From 365006e6b90a08a30fffac59f84df937a1fa8916 Mon Sep 17 00:00:00 2001 From: Wyvest <45589059+Wyvest@users.noreply.github.com> Date: Sat, 11 Jun 2022 12:37:05 +0700 Subject: implement help command --- .../polyfrost/oneconfig/test/TestCommand_Test.java | 34 +++++++++-- .../oneconfig/utils/commands/CommandManager.java | 68 +++++++++++++++++++--- .../utils/commands/annotations/Optional.java | 12 ---- 3 files changed, 88 insertions(+), 26 deletions(-) delete mode 100644 src/main/java/cc/polyfrost/oneconfig/utils/commands/annotations/Optional.java (limited to 'src/main/java/cc/polyfrost/oneconfig') diff --git a/src/main/java/cc/polyfrost/oneconfig/test/TestCommand_Test.java b/src/main/java/cc/polyfrost/oneconfig/test/TestCommand_Test.java index b4a1d9e..33ed5b7 100644 --- a/src/main/java/cc/polyfrost/oneconfig/test/TestCommand_Test.java +++ b/src/main/java/cc/polyfrost/oneconfig/test/TestCommand_Test.java @@ -6,18 +6,18 @@ import cc.polyfrost.oneconfig.utils.commands.annotations.Name; import cc.polyfrost.oneconfig.utils.commands.annotations.SubCommand; import cc.polyfrost.oneconfig.libs.universal.UChat; -@Command(value = "test", aliases = {"t"}) +@Command(value = "test", aliases = {"t"}, description = "Description of the test command") public class TestCommand_Test { - @Main + @Main(description = "The main command.") private static void main() { // /test UChat.chat("Main command"); } - @SubCommand(value = "subcommand", aliases = {"s"}) + @SubCommand(value = "subcommand", aliases = {"s"}, description = "Subcommand 1.") private static class TestSubCommand { - @Main(priority = 999) + @Main(priority = 999, description = "Description of method") private static void main(int a, float b, @Name("named c") String c) { // /test subcommand UChat.chat("Integer main: " + a + " " + b + " " + c); } @@ -32,8 +32,32 @@ public class TestCommand_Test { @Main private static void main(String a, String b, @Name("named c") String c) { // /test subcommand subsubcommand - UChat.chat(a + " " + b + " " + c); + joinAndChat(a, b, c); } } } + + @SubCommand(value = "subcommand2", aliases = {"s2"}) + private static class TestSubCommand2 { + @Main + private static void main(boolean a, boolean b, boolean c, boolean d, boolean e, boolean f, int hgshrs, boolean jrwjhrw) { + joinAndChat(a, b, c, d, e, f, hgshrs, jrwjhrw); + } + } + + @SubCommand(value = "subcommand3", aliases = {"s3"}) + private static class TestSubCommand3 { + @Main + private static void main() { + UChat.chat("subcommand 3"); + } + } + + private static void joinAndChat(Object... stuff) { + StringBuilder builder = new StringBuilder(); + for (Object thing : stuff) { + builder.append(thing).append(" "); + } + UChat.chat(builder.toString().trim()); + } } diff --git a/src/main/java/cc/polyfrost/oneconfig/utils/commands/CommandManager.java b/src/main/java/cc/polyfrost/oneconfig/utils/commands/CommandManager.java index e0f4779..004f427 100644 --- a/src/main/java/cc/polyfrost/oneconfig/utils/commands/CommandManager.java +++ b/src/main/java/cc/polyfrost/oneconfig/utils/commands/CommandManager.java @@ -1,9 +1,6 @@ package cc.polyfrost.oneconfig.utils.commands; -import cc.polyfrost.oneconfig.utils.commands.annotations.Command; -import cc.polyfrost.oneconfig.utils.commands.annotations.Greedy; -import cc.polyfrost.oneconfig.utils.commands.annotations.Main; -import cc.polyfrost.oneconfig.utils.commands.annotations.SubCommand; +import cc.polyfrost.oneconfig.utils.commands.annotations.*; import cc.polyfrost.oneconfig.utils.commands.arguments.*; import cc.polyfrost.oneconfig.libs.universal.ChatColor; import cc.polyfrost.oneconfig.libs.universal.UChat; @@ -105,7 +102,7 @@ public class CommandManager { @Override public List addTabCompletionOptions(ICommandSender sender, String[] args, BlockPos pos) { - return handleTabCompletion(root, args); + return handleTabCompletion(root, annotation, args); } }); } @@ -124,7 +121,7 @@ public class CommandManager { } } else { if (annotation.helpCommand() && args[0].equalsIgnoreCase("help")) { - //UChat.chat(sendHelpCommand(root)); + UChat.chat(sendHelpCommand(root)); } else { List commands = new ArrayList<>(); int depth = 0; @@ -173,13 +170,13 @@ public class CommandManager { } } - private List handleTabCompletion(InternalCommand root, String[] args) { + private List handleTabCompletion(InternalCommand root, Command annotation, String[] args) { try { Set> commands = new HashSet<>(); for (InternalCommand command : root.children) { loopThroughCommandsTab(commands, 0, command, args); } - if (!commands.isEmpty()) { + if (!commands.isEmpty() || annotation.helpCommand()) { List> validCommands = new ArrayList<>(); // command, depth, and all processed params for (Pair pair : commands) { InternalCommand.InternalCommandInvoker invoker = pair.getLeft(); @@ -215,7 +212,7 @@ public class CommandManager { validCommands.add(new ImmutableTriple<>(pair.getLeft(), depth, currentParam)); } } - if (!validCommands.isEmpty()) { + if (!validCommands.isEmpty() || annotation.helpCommand()) { Set completions = new HashSet<>(); for (Triple valid : validCommands) { if (valid.getMiddle() == args.length) { @@ -242,6 +239,11 @@ public class CommandManager { } } + if (args.length == 1 && annotation.helpCommand()) { + if ("help".startsWith(args[0].toLowerCase(Locale.ENGLISH))) { + completions.add("help"); + } + } return new ArrayList<>(completions); } } @@ -331,6 +333,54 @@ public class CommandManager { } } + //TODO: someone make the help command actually look nice lmao + private String sendHelpCommand(InternalCommand root) { + StringBuilder builder = new StringBuilder(); + builder.append(ChatColor.GOLD).append("Help for ").append(ChatColor.BOLD).append(root.name).append(ChatColor.RESET).append(ChatColor.GOLD).append(":\n"); + if (!root.description.isEmpty()) { + builder.append("\n").append(ChatColor.GOLD).append("Description: ").append(ChatColor.BOLD).append(root.description); + } + for (InternalCommand command : root.children) { + runThroughCommandsHelp(root.name, command, builder); + } + builder.append("\n").append(ChatColor.GOLD).append("Aliases: ").append(ChatColor.BOLD); + int index = 0; + for (String alias : root.aliases) { + ++index; + builder.append(alias).append(index < root.aliases.length ? ", " : ""); + } + builder.append("\n"); + return builder.toString(); + } + + private void runThroughCommandsHelp(String append, InternalCommand command, StringBuilder builder) { + if (!command.invokers.isEmpty()) { + Class declaringClass = command.invokers.get(0).method.getDeclaringClass(); + if (declaringClass.isAnnotationPresent(SubCommand.class)) { + String description = declaringClass.getAnnotation(SubCommand.class).description(); + if (!description.isEmpty()) { + builder.append("\n").append(ChatColor.GOLD).append("Description: ").append(ChatColor.BOLD).append(description); + } + } + } + for (InternalCommand.InternalCommandInvoker invoker : command.invokers) { + builder.append("\n").append(ChatColor.GOLD).append("/").append(append).append(" ").append(command.name); + for (Parameter parameter : invoker.method.getParameters()) { + String name = parameter.getName(); + if (parameter.isAnnotationPresent(Name.class)) { + name = parameter.getAnnotation(Name.class).value(); + } + builder.append(" <").append(name).append(">"); + } + if (!command.description.trim().isEmpty()) { + builder.append(": ").append(ChatColor.BOLD).append(command.description); + } + } + for (InternalCommand subCommand : command.children) { + runThroughCommandsHelp(append + " " + command.name, subCommand, builder); + } + } + private void addToInvokers(Class[] classes, InternalCommand parent) { for (Class clazz : classes) { if (clazz.isAnnotationPresent(SubCommand.class)) { diff --git a/src/main/java/cc/polyfrost/oneconfig/utils/commands/annotations/Optional.java b/src/main/java/cc/polyfrost/oneconfig/utils/commands/annotations/Optional.java deleted file mode 100644 index 4dbe8b5..0000000 --- a/src/main/java/cc/polyfrost/oneconfig/utils/commands/annotations/Optional.java +++ /dev/null @@ -1,12 +0,0 @@ -package cc.polyfrost.oneconfig.utils.commands.annotations; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.PARAMETER}) -public @interface Optional { - -} -- cgit