引数のパース
The Command Builder API comes with a powerful argument parser. It converts the string input to java base types (integers, booleans, strings) or game objects (players, worlds, block types, …). The parser supports optional arguments and flags. It also handles TAB completion of arguments.
The parsed arguments are stored in the CommandContext object. If the parser returns a single object, obtain
it with CommandContext#getOne(String). Optional and weak arguments may return Optional.empty()
.
Many of the parsers may return more than one object (e.g. multiple players with a matching username). In that case, you
must use the CommandContext#getAll(String) 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 syntax. Example: /tell @a Who took the cookies?
ちなみに
You can use the GenericArguments#onlyOne(CommandElement) element to restrict the amount of returned values
to a single one, so you can safely use args.<T>getOne(String)
. However the user will still get a message, if they
try to select more than one value.
To create a new CommandElement (argument), use the GenericArguments factory class. Many command elements require a short text key, which is displayed in error and help messages.
Apply the CommandElement
to the command builder with the CommandSpec.Builder#arguments(CommandElement…)
method. It is possible to pass more than one CommandElement
to the method, thus chaining multiple arguments (e.g.
/msg <player> <msg>
). This has the same effect as wrapping the CommandElement
objects in a
GenericArguments#seq(CommandElement…) element.
例: 複数の引数を指定して、コマンドをビルド
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;
PluginContainer plugin = ...;
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((CommandSource src, CommandContext args) -> {
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
コマンドエレメントの概要
コマンドエレメント |
説明 |
値の型と数 |
---|---|---|
|
Expects no arguments. This is the default behavior of a |
|
Java 基底クラス |
||
|
引数が文字列であることを要求します。 |
1つの |
|
Concatenates all remaining arguments separated by spaces (useful for message commands). |
1つの |
|
引数が真偽値であることを要求します。 |
1つの |
|
引数が整数であることを要求します。 |
1つの |
|
引数が実数型であることを要求します。 |
1つの |
ゲームオブジェクト |
||
|
Expect an argument to represent an online player. May return multiple players! |
複数の |
|
Like |
複数の |
|
Like |
multiple |
|
Expect an argument to represent a world (also includes unloaded worlds). |
複数の |
|
Expect an argument to represent a dimension ( |
複数の |
|
|
1つの |
|
|
1つの |
|
Expect an argument that is a member of the specified CatalogType. |
multiple matching elements of the specified catalog type |
Matchers |
||
|
Return an argument that allows selecting from a limited set of values. |
1つの指定された値 |
|
Expect a literal sequence of arguments (e.g. |
1つの指定された値 |
|
Require the argument to be a key under the provided enum. |
multiple matching elements of the specified enum |
ユーティリティ Can be wrapped around command elements. The value type is inherited from the wrapped element. |
||
|
Builds a sequence of command elements (e.g. |
継承します |
|
Require a given command element to be provided a certain number of times. |
複数を継承します |
|
Require all remaining args to match the provided command element. |
複数を継承します |
|
Make the provided command element optional. Throws an error if the argument is of invalid format and there are no more args. |
継承します |
|
Make the provided command element optional. Does not throw an error if the argument is of invalid format and there are no more args. |
継承します |
|
Returns a command element that matches the first of the provided elements that parses
(useful for command overloading, e.g. |
継承します |
|
Restricts the given command element to only insert one value into the context at the provided key. |
継承します |
|
Returns a builder for command flags (e.g. コマンドフラグ を参照してください。 |
Short Flag: one Long Flag: one Value Flag: inherited |
|
Requires the command sender to have the specified permission in order to use the given command argument |
継承します |
|
Requires the command sender to have the specified permission in order to use the given command argument. Does not throw an error if the user does not have the permission. |
継承します |
ちなみに
See the Javadocs for GenericArguments for more information.
警告
Don’t expect that a CommandElement
s will only ever return a single value, a lot of them support multiple return
values; some might even support regular expressions or use a command selector. This is intentional as it makes
commands easier to use. Example: /tell @a BanditPlayer has the cookies!
. If you want to make sure to only get a
single value use GenericArguments#onlyOne(CommandElement)
.
カスタムコマンドエレメント
It is possible to create custom command elements (e.g. a URL parser or a Vector2i
element) by extending the abstract
CommandElement
class.
The CommandElement#parseValue(CommandSource, CommandArgs) method should fetch a raw argument string with CommandArgs#next() and convert it to an object. The method should throw an ArgumentParseException if the parsing fails.
The CommandElement#complete(CommandSource, CommandArgs, CommandContext) method should use CommandArgs#peek() to read the next raw argument. It returns a list of suggestions for TAB completion.
Example: Vector2i
command element definition
The parser in this example reads two input arguments and converts them to a vector.
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 {
protected Vector2iCommandElement(Text key) {
super(key);
}
@Override
protected Object parseValue(CommandSource source, CommandArgs args) throws ArgumentParseException {
String xInput = args.next();
int x = parseInt(xInput, args);
String yInput = args.next();
int y = parseInt(yInput, args);
return new Vector2i(x, y);
}
private int parseInt(String input, CommandArgs args) throws ArgumentParseException {
try {
return Integer.parseInt(input);
} catch(NumberFormatException e) {
throw args.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();
ちなみに
Look at the source code
of the GenericArguments
class for more examples.
Using Selectors in Custom Command Elements
Sponge provides support for parsing selectors, meaning that you can make use of them in your custom elements. There are two steps in using selectors, parsing (getting a Selector from the string) and resolving (getting a set of Entity objects selected by the selector).
To parse a selector string, use the Selector#parse(String) method, passing the entire selector,
including the @
symbol. This will turn the string into a Selector
object that can be queried or resolved.
Note that if the string is not a valid selector, an IllegalArgumentException will be thrown.
To resolve this selector, use Selector#resolve(CommandSource). This will return a set of Entity
objects selected by the selector.
The following parseValue
method from the CommandElement
class attempts to parse a selector and return a set of
entities based on the location of the CommandSource
. If the passed string does not start with @
, an exception
will be thrown indicating that the passed argument is not a selector.
@Override
protected Object parseValue(CommandSource source, CommandArgs args) throws ArgumentParseException {
String nextArg = args.next();
if (nextArg.startsWith("@")) {
Set<Entity> selectedEntities;
try {
selectedEntities = Selector.parse(nextArg).resolve(source);
} catch (IllegalArgumentException e) {
throw args.createError(Text.of("Could not parse selector."));
}
if (selectedEntities.isEmpty()) {
throw args.createError(Text.of("No entities selected."));
}
return selectedEntities;
}
throw args.createError(Text.of("Not a selector."));
}
ちなみに
Look at the SelectorCommandElement source code
for an example of how selector parsing is performed in the standard Sponge CommandElements
.