Дочерние команды

Построитель CommandSpec поддерживает иерархию команд, например, такого вида:

  • /mail (родительская команда)

    • /mail send (дочерняя команда)

    • /mail read (дочерняя команда)

Каждая дочерняя команда является отдельным объектом типа CommandSpec и может быть создана таким же образом, как и любая другая команда.

import org.spongepowered.api.text.Text;
import org.spongepowered.api.command.spec.CommandSpec;

// /mail read
CommandSpec readCmd = CommandSpec.builder()
    .permission("myplugin.mail.read")
    .description(Text.of("Read your inbox"))
    .executor(...)
    .build();

// /mail send
CommandSpec sendCmd = CommandSpec.builder()
    .permission("myplugin.mail.send")
    .description(Text.of("Send a mail"))
    .arguments(...)
    .executor(...)
    .build();

Вместо того, чтобы регистрировать их в службе команд, дочерние команды регистрируются в своей родительской команде с помощью метода CommandSpec.Builder#child(CommandCallable, String…). Они зарегистрированы в списке псевдонимов. Первый предоставленный псевдоним является основным и появится в сообщении об использовании.

import org.spongepowered.api.Sponge;

PluginContainer plugin = ...;

CommandSpec mailCommandSpec = CommandSpec.builder()
    .permission("myplugin.mail.base")
    .description(Text.of("Send and receive mails"))
    .child(readCmd, "read", "r", "inbox")
    .child(sendCmd, "send", "s", "write")
    .build();

Sponge.getCommandManager().register(plugin, mailCommandSpec, "mail", "email");

Резервный исполнитель

Если у команды есть дочерние команды, её исполнитель CommandExecutor, задающийся через CommandSpec.Builder#executor(CommandExecutor), и связанный с ним набор аргументов CommandSpec.Builder#arguments(CommandElement) задавать необязательно. Поведение при возникновении ошибки в выборке и парсинге аргументов дочерних команд зависит от того, существует ли у родительской команды исполнитель.

Если родительский исполнитель не был установлен, если не было возможности найти запрошенную дочернюю команду, или парсинг аргументов невозможен, тогда будет вызвано исключение ArgumentParseException.

Если для родительской команды задан исполнитель, он используется в том случае, если первый аргумент команды не соответствует ни одному из псевдонимов дочерних команд (иначе говоря, он используется как резервный исполнитель). Если дочерняя команда выбрана, но парсинг ее аргументов невозможен, то, в зависимости от результата CommandSpec.Builder#childArgumentParseExceptionFallback(boolean), может произойти один из следующих случаев:

  • true (по умолчанию): ArgumentParseException отбрасывается и выполняется родительская команда. Если парсинг её аргументов невозможен, возвращается ошибка, связанная с родительской командой. Это поведение идентично таковому в предыдущих версиях API, где исключения разбора аргументов дочерних команд не отображаются.

  • false: исполнитель родительской команды не исполняется и генерируется ошибка ArgumentParseException. Она возвращается из дочерней команды, парсинг аргументов которой провалился. При этом исполнение некоторых комбинаций родительской команды и аргументов может быть предотвращено (если первый аргумент родительской команды такой же, как и дочерняя команда).

В любом случае, если парсинг аргументов происходит успешно, но исполнитель дочерней команды генерирует исключение, резервный исполнитель (если он определен) не будет задействован и будет показано сообщение об ошибке исполнителя дочерней команды.