-
Notifications
You must be signed in to change notification settings - Fork 0
The Command Manager
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.
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();
});
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);
});
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));
}
}