参数解析

Minecraft’s Brigadier system includes a powerful argument parser that Sponge can take advantage of. It converts the string input to java base types (integer, booleans, string) or game objects (players, worlds, block types, …). Sponge’s system also supports optional arguments and flags. It also handles suggestions of arguments.

The parsed arguments are stored in the CommandContext object. If the parser returns a single object, obtain it with CommandContext#one(Key). Optional and weak arguments may return Optional.empty()

Many of the parsers may return more than one object; for example, multiple players with a matching username. In that case, you must use the CommandContext#all(Key) method to get the Collection of possible matches. Otherwise, the context object will throw an exception!

When creating a command, consider whether the argument could return multiple values, for example whether a player argument could support multiple players when using a selector. If you support multiple values, the users need to type only one command, and can use an easier command sytax, e.g /tell @a Who took the cookies?

To create a new Parameter (argument), use the Parameter class that will give you many Builder options. Each parameter will need its Builder#key(String) filled out before being built.

Apply the Parameter to the command builder with the Command.Builder#addParameter(Parameter) method. It is possible to pass more than one Parameter to the method, thus chaining multiple arguments. Example /msg <player> <msg>. This has the same effect as wrapping the Parameter objects in a Parameter#seq(Iterable<Parameter>) element.

示例:使用命令生成器生成多个参数的命令

import org.spongepowered.api.command.parameter.CommandContext;
import org.spongepowered.api.command.parameter.Parameter;
import org.spongepowered.api.command.Command;
import org.spongepowered.api.command.CommandResult;
import org.spongepowered.api.entity.living.player.server.ServerPlayer;

public Command.Parameterized createMessageCommand(){
    Parameter.Value<ServerPlayer> playerParameter = Parameter.player().key("player").build();
    Parameter.Value<String> messageParameter = Parameter.remainingJoinedStrings().key("message").build();

    return Command
        .builder()
        .executor((CommandContext context) -> {
            ServerPlayer player = context.requireOne(playerParameter);
            String message = context.requireOne(messageParameter);

            player.sendMessage(Component.text(message));
            return CommandResult.success();
        })
        .addParameter(playerParameter, messageParameter)
        .build();
}

备注

The example above uses CommandContext#requireOne(Parameter.Value<T>), this is for arguments that must be provided. Use CommandContext#one(Parameter.Value<T>) for optional arguments

Overview of the Parameter Command Elements

Parameter

说明

值类型和数量

string

Require the argument to be a string.

一个 String

remainingJoinedStrings

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

一个 String

bool

Require the argument to be a boolean.

一个 Boolean

integer

Require the argument to be a integer.

一个 Integer

rangeInteger

Require the argument to be a integer between two values.

一个 Integer

doubleNumber

Require the argument to be a double.

一个 Double

rangeDouble

Require the argument to be a double between two values

一个 Double

player

Require the argument to be a player. May return multiple players!

multiple ServerPlayer instances

playerOrTarget

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

mutiple ServerPlayer instances

user

Require the argument to be a user. May return multiple users!

多个 User 的实例

world

Require the argument to be a world (only loaded worlds)

multiple ServerWorld instances

location

Require the argument to be a location

one ServerLocation

vector3d

Require the argument to be a vector

一个 Vector3d

rotation

Require the argument to be a vector, but returns the senders rotation if no value was specified

一个 Vector3d

registryElement

Require the argument to be the resoure key of one of the specified elements

multiple matching elements of the specified registry type

choices

Returns an argument that allows selecting from a limited set of values

一个特定的值

literal

Require the argument to match one of the specified literals

one specified literal

enumValue

Require the argument to be a enum

one Enum

seq

Builds a sequence of commands

继承

小技巧

See the Javadocs for Parameter for more information

警告

Don’t expect that a Parameter will only ever return a single value, a lot of them support multiple return values; some might support regular expressions or use command selector. This is intentional as it makes commands easier to use, e.g /tell @a BanditPlayer has cookies!.

Custom Parameter

It is possible to create custom command elements; for example, Vector2i. This is done though the Parameter#builder(Class) method, which returns a Parameter where all data the parameter neededs should be provided. Once done call the build method to build the parameter.

When building a new parameter, only the parser and key are required for build. The parser contains the logic for mapping the String input to the desired value.

Example: Creating a Custom Parameter

In this example we will make a Vector2i parameter. This requires reading two Integers and converting them to a Vector2i.

Parameter.Value<Vector2i> vectorParameter = Parameter
  .builder(Vector2i.class)
  .addParser((
    Parameter.Key<Vector2i> parameterKey,
    ArgumentReader.Mutable reader,
    CommandContext.Builder context) -> {
      int x = reader.parseInt();
      int y = reader.parseInt();
      return new Vector2i(x, y);
  })
  .key("vector")
  .build();

小技巧

When building a new parameter, you can base your parameter on a exsiting parameters. Example: taking Parameter#string() and giving it client suggestions.