Skip to content

Creating commands

Maarten Magits edited this page May 23, 2021 · 5 revisions

Recapitulating

If you are following the getting started tutorial, you should currently have something like this inside of your main class:

public class MyPlugin extends JavaPlugin {
    @Override
    public void onEnable() {
        MmCommandHandler handler = new MmCommandHandler();
        handler.useHelp()
                .generateTabCompletions()
                // ...
                .helpPropertyValueSpacer("&7: &d");
        Bukkit.getPluginCommand().setExecutor(handler);
    }
}

Now it is time to start adding some functionality to this handler.

Creating a command class

The command functionality will be implemented in a separate class. The new class will have to extend the MmCommand class for the handler to recognize it. Additionally, the information about the command will be stored in the MmCommandSignature annotation. This annotation must be present at class level. Your command class should look something like this:

@MmCommandSignature()
public class MyCommand extends MmCommand {
   @Override
   public void onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String label, String[] args) {
      
   }

   @Override
   public @Nullable List<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String label, String[] args) {
       return null;
   }
}

The implementation of onCommand() and onTabComplete() are up to the developer.

Annotation parameters

The MmCommandSignature annotation holds all the metadata for your command. A little breakdown of the available parameters (* are required):

  • name()*: the name of the command. Used in /base name
  • type()*: a MmCommandType indicating who has access to this command. Can be either:
    • PLAYER_ONLY
    • CONSOLE_ONLY
    • PLAYER_CONSOLE
    • ALL
    • SUB_COMMAND
  • description(): a (preferably short) description of what the command does. (default "")
  • aliases(): a list of aliases that can be used for this command (default {})
  • permission(): a permission node the executor should have to execute this command (default "")
  • arguments(): a string describing the format the arguments to this command should be passed in (default "")

A "say" command that is executable by players and console, displays a message in chat, has aliases "tell" and "narrate", requires permission node "myplugin.say" and takes a string as argument can be translated into the following annotation:

@MmCommandSignature(
        name = "say",
        type = MmCommandType.PLAYER_CONSOLE,
        description = "post a message in chat"
        aliases = {"tell", "narrate"},
        permission = "myplugin.say",
        arguments = "<message>"
)

onCommand() and onTabComplete()

The onCommand() and onTabComplete methods must be overridden in your command class. They determine the functionality of the command. The parameters they get passed are as follows:

  • commandSender: A CommandSender who executed the command. This argument is validated against the commandtype so for example, if the command type (in the MmCommandSignature) is MmCommandType.PLAYER, it is safe to directly cast sender to an instance of Player.
  • command: The base command that was executed determined by the first word that comes after the /.
  • label: The alias of the base command that was used.
  • args: The remaining arguments that did not get matched against a subcommand.

Example

After creating your first command, your main class should remain unchanged and your command class should look something along the lines of this:

@MmCommandSignature(
        name = "say",
        type = MmCommandType.PLAYER_CONSOLE,
        description = "post a message in chat"
        aliases = {"tell", "narrate"},
        permission = "myplugin.say",
        arguments = "<message>"
)
public class MyCommand extends MmCommand {
    @Override
    public void onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, String[] strings) {
        Bukkit.broadcastMessage(String.join(" ", strings));
    }

    @Override
    public @Nullable List<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, String[] strings) {
        return new ArrayList<>();
    }
}

Additional notes

  • Returning null as result of the onTabComplete() method can have varying results. If your MmCommandHandler is setup to not generate tab completions for subcommands, this will default to the default tabcomplete handler meaning that it will suggest online player names. If the handler has the generateTabCompletions option enabled, returning null will make the MmCommandHandler append any subcommands to a new list and use that list to suggest completions. If no subcommands are registered, no completions will be suggested.
  • If you want to return "no completions", return an empty list. Not null.

Clone this wiki locally