diff --git a/src/main/java/emu/grasscutter/commands/CommandMap.java b/src/main/java/emu/grasscutter/commands/CommandMap.java index aa9f47f54..5a70aeb45 100644 --- a/src/main/java/emu/grasscutter/commands/CommandMap.java +++ b/src/main/java/emu/grasscutter/commands/CommandMap.java @@ -63,6 +63,23 @@ public final class CommandMap { return this; } + /** + * Returns a list of all registered commands. + * @return All command handlers as a list. + */ + public List getHandlers() { + return new LinkedList<>(this.commands.values()); + } + + /** + * Returns a handler by label/alias. + * @param label The command label. + * @return The command handler. + */ + public CommandHandler getHandler(String label) { + return this.commands.get(label); + } + /** * Invoke a command handler with the given arguments. * @param player The player invoking the command or null for the server console. diff --git a/src/main/java/emu/grasscutter/commands/ServerCommands.java b/src/main/java/emu/grasscutter/commands/ServerCommands.java index 5b2148b67..fc1e9b142 100644 --- a/src/main/java/emu/grasscutter/commands/ServerCommands.java +++ b/src/main/java/emu/grasscutter/commands/ServerCommands.java @@ -6,6 +6,7 @@ import emu.grasscutter.game.Account; import emu.grasscutter.game.GenshinPlayer; import java.util.List; +import java.util.stream.Collectors; /** * A container for server-related commands. @@ -57,7 +58,7 @@ public final class ServerCommands { @Override public void execute(GenshinPlayer player, List args) { if(args.size() < 2) { - CommandHandler.sendMessage(null, "Usage: sendmessage "); return; + CommandHandler.sendMessage(player, "Usage: sendmessage "); return; } try { @@ -66,13 +67,13 @@ public final class ServerCommands { GenshinPlayer targetPlayer = Grasscutter.getGameServer().getPlayerByUid(target); if(targetPlayer == null) { - CommandHandler.sendMessage(null, "Player not found."); return; + CommandHandler.sendMessage(player, "Player not found."); return; } targetPlayer.sendMessage(player, message); - CommandHandler.sendMessage(null, "Message sent."); + CommandHandler.sendMessage(player, "Message sent."); } catch (NumberFormatException ignored) { - CommandHandler.sendMessage(null, "Invalid player ID."); + CommandHandler.sendMessage(player, "Invalid player ID."); } } } @@ -118,4 +119,53 @@ public final class ServerCommands { } } } + + @Command(label = "help", + usage = "Usage: help [command]") + public static class HelpCommand implements CommandHandler { + + @Override + public void execute(List args) { + List handlers = CommandMap.getInstance().getHandlers(); + List annotations = handlers.stream() + .map(handler -> handler.getClass().getAnnotation(Command.class)) + .collect(Collectors.toList()); + + if(args.size() < 1) { + StringBuilder builder = new StringBuilder("Available commands:\n"); + annotations.forEach(annotation -> builder.append(annotation.usage()).append("\n")); + CommandHandler.sendMessage(null, builder.toString()); + } else { + String command = args.get(0); + CommandHandler handler = CommandMap.getInstance().getHandler(command); + if(handler == null) { + CommandHandler.sendMessage(null, "Command not found."); return; + } + + Command annotation = handler.getClass().getAnnotation(Command.class); + CommandHandler.sendMessage(null, annotation.usage()); + } + } + + @Override + public void execute(GenshinPlayer player, List args) { + List handlers = CommandMap.getInstance().getHandlers(); + List annotations = handlers.stream() + .map(handler -> handler.getClass().getAnnotation(Command.class)) + .collect(Collectors.toList()); + + if(args.size() < 1) { + annotations.forEach(annotation -> player.dropMessage(annotation.usage())); + } else { + String command = args.get(0); + CommandHandler handler = CommandMap.getInstance().getHandler(command); + if(handler == null) { + CommandHandler.sendMessage(player, "Command not found."); return; + } + + Command annotation = handler.getClass().getAnnotation(Command.class); + CommandHandler.sendMessage(player, annotation.usage()); + } + } + } }