引數剖析

命令生成器(Command Builder)的 API 附带了一个非常强大的参数解析器。它把字符串输入转换为 Java 的基本类型(整数、布尔值、字符串)或游戏中的对象(玩家、世界、方块类型等)。这一解析器支持可选参数和标志,它同时也可以处理使用 TAB 的参数自动补全。

解析过的参数存储在 CommandContext 对象中。如果解析器返回了单个对象,可以通过 CommandContext#getOne(String) 获取。可选参数和弱参数可能会返回 Optional.empty()

很多解析器可能会返回多个对象(例如匹配用户名的多个玩家)。在这种情况下,你必须使用 CommandContext#getAll(String) 以获取所有可能的匹配项对应的 Collection否则上下文对象会抛出异常

小訣竅

你可以使用 GenericArguments#onlyOne(CommandElement) 限制返回数量只有一个,这样你就可以安全地使用 args.<T>getOne(String) 了。

若要创建一个新的 CommandElement (参数),请使用 GenericArguments 这一工厂类(Factory Class)。许多 CommandElement 都需要一段短文本用于显示帮助或错误信息。

使用 CommandSpec.Builder#arguments(CommandElement…)CommandElement 应用到命令生成器上。这一方法可以传入多个 CommandElement ,这样就可以解析多个参数(例如 /msg <player> <msg> )。传入多个参数等价于使用 GenericArguments#seq(CommandElement…) 把多个参数包装起来。

範例:建立一個具有多個引數的指令

import org.spongepowered.api.Sponge;
import org.spongepowered.api.text.Text;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.command.CommandException;
import org.spongepowered.api.command.CommandResult;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.command.args.CommandContext;
import org.spongepowered.api.command.args.GenericArguments;
import org.spongepowered.api.command.spec.CommandExecutor;
import org.spongepowered.api.command.spec.CommandSpec;

CommandSpec myCommandSpec = CommandSpec.builder()
        .description(Text.of("Send a message to a player"))
        .permission("myplugin.command.message")

        .arguments(
                GenericArguments.onlyOne(GenericArguments.player(Text.of("player"))),
                GenericArguments.remainingJoinedStrings(Text.of("message")))

        .executor(new CommandExecutor() {
            @Override
            public CommandResult execute(CommandSource src, CommandContext args) throws CommandException {

                Player player = args.<Player>getOne("player").get();
                String message = args.<String>getOne("message").get();

                player.sendMessage(Text.of(message));

                return CommandResult.success();
            }
        })
        .build();

Sponge.getCommandManager().register(plugin, myCommandSpec, "message", "msg", "m");

對於 GenericArguments 指令元素的概述

指令元素

說明

值的型態與數量

none

期望没有参数,这也是 CommandSpec 的默认行为。

Java 基本型態

string

期望一个表示字符串的参数。

一個 String

remainingJoinedStrings

把所有剩余的参数使用空格连接起来(对于消息命令来说十分有用)。

一個 String

bool

期望一个表示布尔值的参数。

一個 Boolean

integer

期望一个表示整数的参数。

一個 Integer

doubleNum

期望一个表示浮点数的参数。

一個 Double

遊戲物件

player

期望一个表示在线玩家的参数,并 可能返回多个玩家

多個 Player 實例

playerOrSource

player 类似,但在没有找到匹配的玩家时返回命令的执行者。

多個 Player 實例

userOrSource

playerOrSource 类似,只不过返回一个用户( User )而不是玩家。

多個 User 實例

world

期望一个表示世界的参数(包括尚未加载的世界)。

多個 WorldProperties

dimension

期望一个表示维度的参数(如 ENDNETHER 、和 OVERWORLD )。

多個 DimensionType 實例

location

期望一个表示坐标( Location )的参数。

一個 Location

vector3d

期望一个表示坐标( Vector3d )的参数。

一個 Vector3d

catalogedElement

期望一个表示特定 CatalogType 成员的参数。

多个匹配特定索引类型(Catalog Type)的实例

匹配器

choices

返回一个允许从一组特定的值中选定的参数。

一个特定的值

literal

期望一个表示特定文本序列的参数(例如 "i", "luv", "u" 表示 /cmd i luv u ),如果不匹配则抛出一个异常。

一个特定的值

enumValue

期望一个表示给定枚举类型的值的参数。

多个匹配给定枚举的元素

辅助元素

用于把若干命令元素包装起来。其值类型是从被包装元素继承的。

seq

生成一串命令元素的序列(例如 /cmd <arg1> <arg2> <arg3> )。

繼承

repeated

期望一个表示重复数次的命令元素。

多個繼承

allOf

期望所有剩余的参数匹配给定命令元素。

多個繼承

optional

使给定的命令元素可选。如果参数的格式无效或并没有更多的参数,将抛出一个异常。

繼承

optionalWeak

使给定的命令元素可选。如果参数的格式无效或并没有更多的参数,将不会抛出一个异常。

繼承

firstParsing

返回给定命令元素中第一个可解析的元素(对像是 /settime <day|night|<number> 这种命令重载的情况有用)。

繼承

onlyOne

限制给定命令元素,使其只允许在给定上下文插入仅仅一个。

繼承

flags

返回一个标志(Flag)生成器(例如 /cmd [-a] [-b <value>] )。

請參閱 指令旗標

短旗標(Short Flag):一個 Boolean

長旗標(Long Flag):一個 String

數值旗標(Value Flag):繼承

requiringPermission

要求命令执行者拥有使用给定命令参数的特定权限

繼承

小訣竅

详见 GenericArguments 以获取更详细的信息。

自定義指令元素

可以通过继承 CommandElement 类创建自定义命令元素(如解析 URL 或者一个 Vector2i 元素)。

CommandElement#parseValue(CommandSource, CommandArgs) 方法需要通过 CommandArgs#next() 方法获取没有处理过的字符串并将其转换为一个对象(Object),如果转换出错,应抛出一个 ArgumentParseException 异常。

CommandElement#complete(CommandSource, CommandArgs, CommandContext) 方法应使用 CommandArgs#peek() 方法读取下一个未处理过的参数。其返回一个 TAB 自动补全的列表。

範例:Vector2i 指令元素定義

在这一示例中,解析器读取两个传入的参数并将其转换为一个 Vector2i

import com.flowpowered.math.vector.Vector2i;
import org.spongepowered.api.command.args.ArgumentParseException;
import org.spongepowered.api.command.args.CommandArgs;
import org.spongepowered.api.text.Text;
import org.spongepowered.api.command.args.CommandElement;

import java.util.Collections;
import java.util.List;

public class Vector2iCommandElement extends CommandElement {
    CommandArgs errorargs;

    protected Vector2iCommandElement(Text key) {
        super(key);
    }

    @Override
    protected Object parseValue(CommandSource source, CommandArgs args) throws ArgumentParseException {

        // <x> <y>
        errorargs=args;

        String xInput = args.next();
        int x = parseInt(xInput);

        String yInput = args.next();
        int y = parseInt(yInput);

        return new Vector2i(x, y);
    }

    private int parseInt(String input) throws ArgumentParseException {
        try {
            return Integer.parseInt(input);
        } catch(NumberFormatException e) {
            throw errorargs.createError(Text.of("'" + input + "' is not a valid number!"));
        }
    }

    @Override
    public List<String> complete(CommandSource src, CommandArgs args, CommandContext context) {
        return Collections.emptyList();
    }

    @Override
    public Text getUsage(CommandSource src) {
        return Text.of("<x> <y>");
    }
}

範例:Vector2i 指令元素用法

// /plottp <x> <y>
CommandSpec myCommandSpec = CommandSpec.builder()
        .description(Text.of("Teleport to a plot"))
        .permission("myplugin.command.plot.tp")

        .arguments(new Vector2iCommandElement(Text.of("coordinates")))

        .executor(new MyCommandExecutor())
        .build();

小訣竅

更多範例請參閱 GenericArguments class 的 原始碼