Skip to content

Creating subcommands

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:

public class MyPlugin extends JavaPlugin {
  @Override
  public void onEnable() {
      MmCommandHandler handler = new MmCommandHandler();
      handler.useHelp()
              .generateTabCompletions()
              // ...
              .helpPropertyValueSpacer("&7: &d");
      handler.addCommand(new MyCommand());
      Bukkit.getPluginCommand().setExecutor(handler);
  }
}
@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<>();
  }
}

Creating a subcommand

A subcommand is a special MmCommand that is chained after another MmCommand. It allows developers to create complex tree structures within their commands. Creating one follows a similar pattern as creating a normal command There is only one difference:

  • Subcommands are only valid if the type parameter in the MmCommandSignature is assigned the value of MmCommandType.SUB_COMMAND. This indicates that the subcommand does not run any additional type checks. It inherits the type from the base command it is linked to.

Linking commands

Linking subcommands to other (sub)commands can be achieved by calling the withSubCommand(@NotNull MmCommand command) method on the MmCommand. The method allows the chained addition of commands. Important to remember is that an alias/name must be unique for all subcommands of a MmCommand.

Example

If we were to add two subcommands to our example (bold, italics), who both have their own permission node, description and have no aliases, this might look something like this:

Main class
public class MyPlugin extends JavaPlugin {
  @Override
  public void onEnable() {
      MmCommandHandler handler = new MmCommandHandler();
      handler.useHelp()
              .generateTabCompletions()
              // ...
              .helpPropertyValueSpacer("&7: &d");
      handler.addCommand(new MyCommand()
          .withSubCommand(new MyCommandBold())
          .withSubCommand(new MyCommandItalics())
      );
      Bukkit.getPluginCommand().setExecutor(handler);
  }
}
Command class
@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 List.of("bold", "italics");
  }
}
Bold class
@MmCommandSignature(
      name = "bold",
      type = MmCommandType.SUB_COMMAND,
      description = "post a message in chat in bold"
      permission = "myplugin.say.bold",
      arguments = "<message>"
)
public class MyCommandBold extends MmCommand {
  @Override
  public void onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, String[] strings) {
      Bukkit.broadcastMessage(ChatColor.translateAlternateColorCodes('&', "&l" + String.join(" ", strings)));
  }

  @Override
  public @Nullable List<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, String[] strings) {
      return new ArrayList<>();
  }
}
Bold class
@MmCommandSignature(
      name = "italics",
      type = MmCommandType.SUB_COMMAND,
      description = "post a message in chat in italics"
      permission = "myplugin.say.italics",
      arguments = "<message>"
)
public class MyCommandItalics extends MmCommand {
  @Override
  public void onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, String[] strings) {
      Bukkit.broadcastMessage(ChatColor.translateAlternateColorCodes('&', "&o" + String.join(" ", strings)));
  }

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

Please note that in this example, the tabcompletions for bold and italics were manually added to the command class. If .generateTabCompletions() was called on the handler, this would be done automatically.

Additional notes

  • There is no limit on how many subcommands you can chain to each other. Feel like making a /summon custom monster disguise set special squid name glowsquid <arguments> with every keyword a subcommand? You are free to do so! (not saying you should)
  • Subcommands can be chained to multiple MmCommands. A subcommand 'set' can be both chained to /castles border type set and /castles border set.
  • It is not possible to chain a subcommand to the base command directly. /castles set and /castles border set will require 2 'set' classes.
  • It is not necessary to include the possible subcommands in the arguments of the parent command. In the help menu, a help entry will be added for each combination of subcommands that the executor has permission for automatically.

Clone this wiki locally