Skip to content
This repository has been archived by the owner on May 21, 2020. It is now read-only.

The Command Manager

Xemiru / Marc Tellerva edited this page Nov 2, 2017 · 6 revisions

The CommandManager object is the main entrypoint for any command execution. It's pretty lightweight; all you need to really do is instantiate it, give it commands and then let it go. User input should be funneled through handleCommand (and completeCommand if you're also implementing parameter completion).

CommandManager manager = new CommandManager();
manager.addCommands(myCommand, myOtherCommand);

String userInput = // ... ;
manager.handleCommand(userInput);

The handleCommand and completeCommand methods also have two overloads, adding the ability to use a context factory function and to supply your own set of commands. The context factory is important for custom environments who need to add extra data to context objects, as this allows you to either return your own context object or modify the one given to the factory.

See Custom Properties for information on assigning custom properties for CommandContext objects.

Pre-executors

The command manager allows you to set a pre-executor which runs right before a command's executor. The pre-executor receives the CommandContext object that the CommandExecutor will receive and allows extra checks to be made prior to the execution of a command. Should the pre-executor return a non-empty Optional<String>, it is assumed that the pre-executor does not want the command to be ran. The system will throw a CommandException with the message contained by the Optional if it is not being dry-ran, otherwise the command silently fails.

cm.setPreExecutor(ctx -> {
    String user = ctx.getCustom("user");
    int permission = ctx.getCustom("permission");
    if(permission < 99) return Optional.of("Missing permissions.");
    return Optional.empty();
});

Output redirection

Command output goes through the CommandManager object's sendMessage and sendErrorMessage methods. These default to simply printing out to the standard output and error streams, though should you need this behavior changed, you can set the message handlers using setMessageHandler and setErrorMessageHandler.

manager.setMessageHandler(message -> {
    // Prepend "Commands: " to each message from commands!
    System.out.println("Commands: " + message);
});

Help commands

The stock help command is controlled mostly by the HelpGenerator set on the CommandManager. By default, it uses an instance of DefaultHelpGenerator. This can be changed to customize the output of help messages to the needs of your project by writing your own implementation of HelpGenerator.

public class DefaultHelpGenerator implements HelpGenerator {

    @Override
    public int getPageSize() {
        return 0;
    }

    @Override
    public Comparator<String> getSorter() {
        return String::compareToIgnoreCase;
    }

    @Override
    public void sendHelp(CommandContext context, TreeMap<String, Optional<String>> help, int page, int maxPage) {
        if (page > 0) context.sendMessage(String.format("Command List (page %d of %d)", page, maxPage));
        for (String cmd : help.keySet())
            context.sendMessage(String.format("%s\t%s", cmd,
                help.get(cmd).orElse("This command has no short description.")));
    }

    @Override
    public void sendFullHelp(CommandContext context, HelpGenerator.HelpInfo info) {
        context.sendMessage(String.format("Command: %s", info.getName()));
        context.sendMessage(String.format("Aliases: %s", info.getAliases().orElse("(no aliases)")));
        context.sendMessage(String.format("Syntax: %s", info.getSyntax()));
        context.sendMessage("");
        context.sendMessage(info.getDescription().orElse("This command has no description."));
    }

    @Override
    public CommandException createError(CommandContext ctx, String input) {
        return new CommandException("That command crashed when we tried to ask it about itself. Oops.");
    }

    @Override
    public CommandException createErrorUnknown(CommandContext ctx, String input) {
        return new CommandException(String.format("Couldn't find command %s. Try 'help'.", input));
    }

}
Clone this wiki locally