Paramenterverarbeitung
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.
Die Analysierten Argumente werden im CommandContext Objekt gespeichert. Wenn der Parser ein einzelnes Objekt zurückgibt, kann man es mit CommandContext#getOne(String). Optionale und schwache Argumente können Optional.empty()
zurückgeben.
Viele der Parser können mehr als ein Objekt (z.B. mehrere Spieler mit einem übereinstimmendem Usernamen) zurückgeben. In diesem Fall muss man die CommandContext#getAll(String) Methode benutzen, um die Collection
mit möglichen übereinstimmungen zu bekommen.
Andernfalls wirft das Content Objekt eine 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?
Tipp
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.
Um ein neues CommandElement (Argument) zu erstellen, benutze die GenericArguments Factory Klasse. Viele Befehlselemente benötigen einen kurzen Text key, welcher in einer Error- und Hilfenachricht angezeigt wird.
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.
Beispiel: Erstellen eines Befehls mit mehreren Argumenten
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");
Übersicht über die GenericArguments
(vielseitigen) Befehlselemente
Befehlselemente |
Beschreibung |
Werttyp und Betrag |
---|---|---|
|
Erwartet keine Argumente. Dies ist das Standardverhalten einer |
|
Java-Basis-Typen |
||
|
Erwartet von einem Argument ein String zu sein. |
ein |
|
Verbindet die verbleibenden, durch Leerzeichen getrennten, Argumente (Nützlich für Nachrichten Befehle). |
ein |
|
Erwartet von einem Argument ein Boolean zu sein. |
ein |
|
Erwartet von einem Argument ein Integer zu sein. |
ein |
|
Erwartet von einem Argument ein Double zu sein. |
ein |
Spielobjekte |
||
|
Erwartet von einem Argument einen Online Spieler zu sein. Kann mehrere Spieler zurückliefern! |
mehrere |
|
Ähnlich wie |
mehrere |
|
Ähnlich wie |
mehrere |
|
Erwartet von einem Argument eine Welt zu sein (enthält auch nicht geladende Welten). |
mehrere |
|
Erwartet von einem Argument eine Dimension ( |
mehrere |
|
Erwartet von einem Argument eine |
one |
|
Erwartet von einem Argument ein |
ein |
|
Erwartet von einem Argument, dass es Teil des angegeben CatalogTypen ist. |
mehrere passende Elemente des angegebenen |
Suche |
||
|
Gibt ein Argument aus einer begrenzten Anzahl von Möglichkeiten zurück. |
ein angegebener Wert |
|
Erwartet die wörtliche Abfolge von Argumenten (z.B. |
ein angegebener Wert |
|
Erwartet ein Argument, dass der Schlüssel zu dem angegebenen Enum ist. |
mehrere passenden Elemente des angegebenen Enums |
Hilfen Können um ein Befehlselement gewickelt werden. Die Art des Wertes wird von dem umwickelten Element abgeleitet. |
||
|
Baut eine Sequenz von Befehlselementen (z.B. |
geerbt |
|
Erfordert, dass das angegebene Befehlselement mindestens eine bestimmte Anzahl von Malen auftaucht. |
mehrere Werte passend zum Umwickelten |
|
Erwartet, dass alle folgenden Argumente zu dem angegeben Befehlselement passen. |
mehrere Werte passend zum Umwickelten |
|
Macht das angegebene Befehlselement optional. Wirft einen Fehler, wenn das Argument das falsche Format hat und es keine weiteren Argumente gibt. |
geerbt |
|
Macht das angegebene Befehlselement optional. Wirft keinen Fehler, wenn das Argument das falsche Format hat und es keine weiteren Argumente gibt. |
geerbt |
|
Gibt ein Befehlselement zurück, dass dem ersten passenden Element entspricht (Nützlich zum Übersteuern von Befehlen, z.B. |
geerbt |
|
Beschränkt das gegebene Befehlselement darauf, mit dem angegebenen Schlüssel nur einen Wert in den Kontext zu setzen. |
geerbt |
|
Liefert einen Builder zur Erstellung von Befehlsoptionen (z.B. Siehe Befehlsoptionen |
Befehlsoption: ein Befehlsoption mit Wert: ein Befehlsoption mit Wert: wie das Eingebettete |
|
Erfordert von der Befehlsquelle die entsprechende Berechtigung zu haben, um das gegebene Befehlsargument verwenden zu können |
geerbt |
|
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. |
geerbt |
Tipp
Schau dir die Javadocs von GenericArguments an, wenn du weitere Informationen brauchst.
Warnung
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)
.
Benutzerdefinierte Befehlselemente
Es ist möglich, benutzerdefinierte Befehlselemente (z.B. einen URL Parser oder ein Vector2i
Element) zu erstellen, indem die abstrakte CommandElement
Klasse erweitert wird.
Die CommandElement#parseValue(CommandSource, CommandArgs) Methode sollte einen bisher unverarbeitetes String Argument mit Hilfe von CommandArgs#next() holen und dieses in das gewünschte Objekt konvertieren. Die Methode sollte im Falle eines Fehlschlages eine ArgumentParseException werden.
Die CommandElement#complete(CommandSource, CommandArgs, CommandContext) Methode sollte CommandArgs#peek() verwenden, um das nächste unverarbeitete Argument auszulesen. Sie gibt eine Liste von Vorschlägen für die TAB-Autovervollständigung aus.
Beispiel: Definition des Vector2i
Befehlselementes
Der Parser in diesem Beispiel liest zwei Eingabe-Argumente und konvertiert diese in einen Vektor.
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>");
}
}
Beispiel: Verwendung des Vector2i
Befehlselementes
// /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();
Tipp
Wirf einen Blick auf den Quellcode der GenericArguments
-Klasse für weitere Beispiele.
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."));
}
Tipp
Look at the SelectorCommandElement source code
for an example of how selector parsing is performed in the standard Sponge CommandElements
.