-
Notifications
You must be signed in to change notification settings - Fork 8
Commands
Commands are an essential part of the interactions between the user and the bot. Most of them trigger a feature or respond with content generated based on the arguments.
Note: In this chapter, we will explain the new command model. The older model is still functional but deprecated and will not be officially supported.
The central object of your command implementation is an extension of the CommandHandler class.
public class MakeMeRichCommandHandler extends CommandHandler {
...
}
To declare the constant core properties of your class, your class has to call the super-constructor in it's own constructor. This is not optional as the abstract superclass forces you to do that. The super-constructor is declared like the following: CommandHandler(String[] invocationAliases, CommandCategory category, PermissionRequirements permissionRequirements, String description, String parameterUsage)
, so your super-constructor-call has to provide the following properties:
-
invocationAliases: The invocation aliases of a command are the words that will trigger your command. If an invocation alias of your command is
makemerich
, your command will be triggered when a user sends a message withrc!makemerich
at it's start (look at the Prefixes page (coming soon) for more details about therc!
in front of your alias). Your command can (and must provide) an array of aliases. An array can be initialized in-line withnew String[]{"first entry", "second entry", ...}
. For our example, one could either provide an array with only one element (new String[]{"makemerich"}
) or with multiple ones (new String[]{"makemerich", "enrichme"}
) to set multiple invocation aliases. Remember, that the aliases should be meaningful and, mostly, synonymous. -
category: The category does not have a great functional value. It is mostly used for (wait for it...) categorization. Because CommandCategory is an enum, you can only use the predefined values. Sometimes, multiple categories may be fitting for your command, but as you can only specify one category, you should focus on what it should be used for or who it should be useful for. For instance,
make me rich
could be a tool to instantly enrich the command executor (the category would beTOOLS
in this case) or it could be a sarcastic joke generator (FUN
should be the category of choice then). Depending on your import method, you might have to name the enum's class name before the category name:CommandCategory.FUN
-
permissionRequirements: For this parameter, that defines who can invoke the command, you have to create a new PermissionRequirements object. Have a look at the Permissions page (coming soon) for further details. A PermissionRequirements object is created with two parameters: the member permission level and a permission node. We could use
new PermissionRequirements(0, "command.makemerich")
here. -
description: The description should be a short, meaningful text that explains the command's functions and goals briefly.
Makes you rich
would be perfectly fitting if the command made you rich, but as this should tell you jokesQuick tips about how you won't get rich
would suit better in this case. -
parameterUsage: The parameter usage is a functional text that should clarify what arguments are needed to invoke a command and how these arguments should be used (what they do). It is good practice to use
<one-worded-argument-name>
for normal one-word-parameters,[another-one-worded-argument-name]
for optional parameters and<text that can contain whitespaces...>
(or[text that...]
) for arguments that can contain blanks (<business> [why I want to get rich...]
would becomerc!makemerich <business> [why I want to get rich...]
if the prefix was not changed. In our very basic example, we don't need any parameters, somakemerich
is alright.
public MakeMeRichCommandHandler() {
super(new String[]{"makemerich", "enrichme"}, CommandCategory.FUN, new PermissionRequirements(0, "command.makemerich"), "Quick tips about how you won't get rich", "");
}
Note that, to be able to instantiate this command later on, your CommandHandler implementation must be accessible from your instantiating class. All of these properties can be retrieved later with their getters.
The in no view less important part is the executor method.
@Override
protected Message execute(CommandManager.ParsedCommandInvocation parsedCommandInvocation, UserPermissions userPermissions)
{
...
}
It comes with two arguments which will be explained in the following:
- parsedCommandInvocation: The CommandManager.ParsedCommandInvocation object containes the parsed contents of the invoking message. It contains four attributes which can be directly accessed but not replaced.
- Message invocationMessage: This is the discord message that triggered the command execution.
- String serverPrefix: This is prefix that was used in the command invocation. It is contained because it was needed to parse the message and because it provides useful context to the command.
- String invocationCommand: This is the aliases the user wrote in his invoking message.
- String[] args: These are the command arguments (or parameters). They are ordered in the way the user wrote them in his invocation messsage.
-
userPermissions: The UserPermissions object can be used to find out whether several PermissionRequirements (like the ones you provided in your constructor) are met. Note, that (if you haven't overwritten the
call(...)
method) the PermissionRequirements of your command were already checked. Theexecute(...)
method is only called if these were met.
In the main part of your execute(...)
implementation, you are free to use whatever statements you want in order to process the command. But, of course, there are a few guidelines:
- Don't use things that pause the current thread. The command execution is in the event listener thread so halting the thread will also halt the other features that rely on this system.
- Always return a Message or null. The command system will automatically respond to the invoker with Message provided in your return statement. It will send and delete it in a regular schedule. You can return null, this means that the command manager won't respond for you. Returning null is highly unrecommended as you have to handle the sending and deletion of your response yourself. Not responding at all might be confusing as the invoking user does not get a feedback.
To get your command working, you still have to register it. Registering a CommandHandler means routing all of it's aliases to it's execution. It is really simple, just insert commandManager.registerCommandHandler(commandHandlerInstance);
in the registerCommandHandlers()
method in RubiconBot and replace the commandHandlerInstance parameter with an instance of your CommandHandler.
private void registerCommandHandlers() {
// ...other command registrations
commandManager.registerCommandHandler(new MakeMeRichCommandHandler());
}
In theory, you can register commands whenever and from whereever you want but in most cases it is practical to have them bundled together.