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

Commands

tr808axm edited this page Dec 3, 2017 · 3 revisions

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.

For developers: Implementing commands

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 {
    ...
}

Core properties

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:

  1. 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 with rc!makemerich at it's start (look at the Prefixes page (coming soon) for more details about the rc! in front of your alias). Your command can (and must provide) an array of aliases. An array can be initialized in-line with new 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.
  2. 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 be TOOLS 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
  3. 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.
  4. 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 jokes Quick tips about how you won't get rich would suit better in this case.
  5. 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 ( ). Use a clear and brief language. You do not need to include the prefix or the major command alias as the customized server-specific prefix and the alias are automatically attached to the beginning of the String. <business> [why I want to get rich...] would become rc!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, so makemerich 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.

Executor method

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:

  1. 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.
  1. 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. The execute(...) 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.

Registering your CommandHandler

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.