命令标志

命令标志在想要定义额外的不应属于正常的命令参数的参数时很有帮助。

若要创建一个命令标志,我们需要首先创建一个命令标志的 Builder。我们只需要简单地使用 GenericArguments 提供的 GenericArguments#flags() 方法就可以获取这一 Builder。然后我们就可以指定什么样的标志是我们想要的。注意标志被指定为一个参数。

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."));
}

长标志

作为诸如上面的内容中用到的短标志的扩展,我们也可以使用长标志。如果想要使用长标志,只需要在指定标志的字符串之前添加一条横线 - ,就像下面这样:

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 字符串中。

未知标志行为

现在如果我们不想指定特定的标志,但仍然想要处理它们?我们可以通过设置未知标志行为的方式去解决这件事:

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();

这样我们就指定了对于任何拥有附加值的短标志的行为。如果未指定,那么使用未知标志就会抛出一个异常。可以指定的未知标志行为包括 ERRORACCEPT_NONVALUEACCEPT_VALUE 、和 IGNORE 。请注意使用未知标志的默认行为是 ERROR