Флаги команд

Флаги команд полезны для указания дополнительных параметров при выполнении команды, при этом они не будут являться аргументами команд.

Для создания флага нам сначала нужен конструктор. Мы можем просто использовать метод GenericArguments#flags(), класса GenericArguments, чтобы получить его. Оттуда мы можем указать, какой тип флага мы хотели бы создать. Обратите внимание, что флаги указываются в качестве аргумента.

import org.spongepowered.api.command.args.GenericArguments;
import org.spongepowered.api.command.spec.CommandSpec;

CommandSpec myCommand = CommandSpec.builder()
    .executor(new MyCommand())
    .arguments(GenericArguments.flags().flag("s").buildWith(GenericArguments.none()))
    .build();

Это создаст флаг команды, поэтому, когда игрок выполнит /our-command -s, флаг s станет истинным. Обратите внимание, что конструктор с GenericArguments#none() не даст команде иметь какие-либо аргументы. Если вы хотите, чтобы команда имела и агрументы, и флаги, то вы должны указать свои аргументы в методе CommandFlags.Builder#buildWith(CommandElement).

Теперь, когда мы указали, что команда может выполняться с флагом, мы можем получить его значение. Для простого логического флага, который мы указали выше, мы можем просто проверить, существует ли он. В примере ниже мы проверяем, имеет ли класс CommandContext нашей команды значение s.

import org.spongepowered.api.text.Text;

if (args.hasAny("s")) {
    src.sendMessage(Text.of("The command flag s was specified!"));
}

Флаги прав

Пока что наши флаги великолепны, но что, если мы хотим, чтобы игроку требовалось разрешение на использование флага? Мы можем использовать метод CommandFlags.Builder#permissionFlag(String, String…) в нашем конструкторе команд. Это потребует у игрока наличия специального разрешения на выполнение команды с флагом. Пример этого ниже:

CommandSpec myCommand = CommandSpec.builder()
        .executor(new MyCommand())
        .arguments(GenericArguments.flags().permissionFlag("myplugin.command.flag",
            "s").buildWith(GenericArguments.none()))
        .build();

Если у игрока не будет права myplugin.command.flag, то он не сможет выполнить команду с флагом s.

Флаги, содержащие значения

Логические значения нередко могут нам помочь, но что, если мы хотим, чтобы флаги использовались для хранения, например, чисел или строк? Для этого используются флаги, хранящие значения. Всё, что нам нужно - использовать метод CommandFlags.Builder#valueFlag(CommandElement, String…) в конструкторе флага. Используя метод valueFlag(), мы можем определить, значение какого типа флаг должен хранить, например число или строку. Создать флаг, хранящий целое число, можно следующим образом:

CommandSpec myCommand = CommandSpec.builder()
        .executor(new MyCommand())
        .arguments(GenericArguments.flags().valueFlag(GenericArguments
                .integer(Text.of("value")), "s").buildWith(GenericArguments.none()))
        .build();

Вы можете заменить GenericArguments#integer(Text) на любой другой тип, который вам понадобится, например на GenericArguments#string(Text).

Получить значение, хранящееся в флаге, можно таким же образом, как и любой другой аргумент команды. Всё, что нам необходимо - проверить, существует ли оно, прежде чем его извлечь:

import java.util.Optional;

Optional<Integer> optional = args.<Integer>getOne("value");
if (optional.isPresent()) {
    int value = optional.get().intValue();
} else {
    src.sendMessage(Text.of("The value flag was not specified."));
}

Длинные флаги

As an alternative to short flags like the ones we have been using above, we can also use long flags. Using a long flag, you can specify a value along with the flag using equals in the command. To create a long flag, simply prefix your normal flag with a dash -, like so:

CommandSpec myCommand = CommandSpec.builder()
        .executor(new MyCommand())
        .arguments(GenericArguments.flags().flag("-myflag")
            .buildWith(GenericArguments.none()))
        .build();

Мы можем получить значение, указанное с нашим флагом, точно так же, как и в случае с флагами, хранящими значение:

Optional<String> optional = args.<String>getOne("myflag");
if (optional.isPresent()) {
    String value = optional.get();
}

Тогда, если пользователь введет /our-command --myflag=Flag_Value, Flag_Value будет храниться в строке value.

Unknown Flag Behavior

А что, если мы не хотим указывать конкретный флаг для нашей команды, но при этом хотим принимать неизвестные флаги? Тогда мы можем установить поведение при вводе неизвестного флага для нашей команды:

import org.spongepowered.api.command.args.CommandFlags;

CommandSpec myCommand = CommandSpec.builder()
            .executor(new MyCommand())
            .arguments(GenericArguments.flags()
                    .setUnknownShortFlagBehavior(
                        CommandFlags.UnknownFlagBehavior.ACCEPT_VALUE)
                    .buildWith(GenericArguments.none()))
            .build();

Таким образом, мы можем сделать так, чтобы короткий флаг с определенным значением был принят. Без этой меры использование неизвестного короткого флага сгенерирует исключение. Существует несколько вариантов поведения при вводе неизвестного флага, например ERROR, ACCEPT_NONVALUE, ACCEPT_VALUE,``IGNORE``. Обратите внимание, что стандартным поведением при вводе неизвестного флага является ERROR.