Skip to content

CommandReceiver.java

Recursive G edited this page Jul 26, 2019 · 3 revisions

The CommandReceiver provided an easy way to construct command handler.
Simply extends CommandReceiver and you are done!
All NyaaCat plugins use CommandReceiver extensively, You can consule any of those plugins for usages.

CommandHandler Registration

You should and only should register your main command handler this way

commandHandler = new CommandHandler(this, i18n);
getCommand("nyaautils").setExecutor(commandHandler);
getCommand("nyaautils").setTabCompleter((TabCompleter) commandHandler);

Argument Escaping

Command line is automatically parsed by CommandReceiver.Arguments class.
Arguments are separated by space, extra spaces between arguments are allowed.
Singe argument containing special characters should be embraced by `
Backslash \ is used as the escape character but it is only valid inside the backquote
For example

/examplecommand first  `second` `thir\`d` `fourt\\h` ``

contains five arguments:

  • first
  • second
  • thir`d
  • fourt\h
  • an empty string

Named Arguments

CommandReceiver.Arguments supports named arguments in this form key:value.
Check our testcases for examples

Subcommands

A subcommand handler is a field or a method inside a command handler class.
It should be annotated with @SubCommand annotation.

If it's a field, an object will be automatically created according to the declared type.
The field type should be (or be a subclass of) CommandReceiver.
The plugin main class object and localization object will be passed to the constructor.
Your constructor signature should be compatable with the objects' types.
A common constructor looks like this:

public <NameOfThisClass>(PluginMainClass plugin, ILocalizer i18n);

If the subcommand handler a method, it should be in this form

public void commandName(CommandSender sender, Arguments args);

Localization Integration

The CommandReceiver is designed to work together with a localization object. Usually an instance of LanguageRepository provided by the same plugin. So players can get appropriate prompts or helps at the right time.

If you do not want to use LanguageRepository provided by NyaaCore, you may want to implement ILocalizer to enable CommandReceivers provide meaningful messages.

Each subcommand is automatically linked to a set of descriptions in the language file.

  • manual.<subCommand>.<subsubCommand>.description
  • manual.<subCommand>.<subsubCommand>.usage

These are the language keys will be passed into ILocalizer object. You can refer to this language file for examples.

Specially, the help subcommand is provided for every CommandReceiver since the method is defined in CommandReceiver it self. So you may want to define the description and usage info for help command for every SubCommand handler.

The abstract method getHelpPrefix is needed to help one subcommand determine the correct command prefix for itself, because each subcommand do not have information about its parent commands. A command handler annotated with @SubCommand(value="subcmd") should return subcmd as its helpPrefix. The main command handler should return an empty string.

Default sub command example

           +-----------> class Sub1
           |            +----------+
           |            | a        | M3
           |            | <def>    | M4
           |            | help     |
           |            +----------+
class Root |
+--------+ |
| sub1   +-^         +-> class Sub2        +-----> class Sub2A
| sub2   +-----------+  +----------+       |      +-----------+
| sub3   | M1           | b        | M5    |      | b         | M6
| <def>  | M2           | <def>    +-------+      | c         | M7
| help   |              | help     |              | <def>     | M8
+--------+              +----------+              | help      |
                                                  +-----------+
  • /nct sub1 a calls M3 with no argument
  • /nct sub1 b calls M4 with argument: b
  • /nct sub2 a calls M8 with argument: a
  • /nct sub2 b calls M5 with no argument
  • /nct sub2 c calls M7 with no argument
  • /nct sub3 a calls M1 with argument: a
  • /nct sub4 a calls M2 with arguments: sub4 and a
  • You have no way to call M6.
  • Sub2A is kind of "inlined" into Sub2

Advanced: Customize subcommand dispatch

By default, CommandReceiver picks the first argument and search for matching subcommand handler.
It will print the help message then return if no suitable handler is found.
If you want to customize this behavior, you can override the acceptCommand method.
Example