Analyse des Arguments
L’API de Construction de Commandes est dotée d’un analyseur d’arguments très puissant. Il convertit les caractères entrés en types de java de base (integers, booleans, strings) ou en objets du jeu (joueurs, mondes, types de blocs, …). L’analyseur supporte les arguments optionnels et les flags. Il supporte également la complétion des arguments a l’aide de la touche TAB.
L’analyseur d’arguments est stocké dans l’objet CommandContext. Si l’analyseur renvoie un seul objet, on peut l’obtenir avec CommandContext#getOne(String). Les arguments optionnels ou faibles peuvent renvoyer Optional.empty()
.
Un certain nombre d’analyseurs peuvent retourner plus d’un objet (ex: plusieurs joueurs avec un pseudo correspondant). Dans ce cas, vous devez utiliser la méthode CommandContext#getAll(string) pour obtenir la Collection
des correspondances possibles. Autrement, l’objet contexte va renvoyer une exception !
Lors de la création d’une commande, considérez le cas où l’argument peut retourner plusieurs valeurs, par exemple, si un argument joueur peut supporter plusieurs joueurs en utilisant un sélecteur. Si vous supportez plusieurs valeurs, les utilisateurs doivent taper une seule commande et peuvent utiliser une syntaxe de commande plus simple. Exemple : /tell @a Qui a pris les cookies ?
Astuce
Vouss pouvez utiliser l’élément GenericArguments#onlyOne(CommandElement) pour restreindre le nombre de valeurs retournées à une seule valeur, afin que vous puissiez utiliser en toute sécurité args.<T>getOne(String)
. Cependant l’utilisateur aura toujours un message si il essaie de sélectionner plus d’une valeur.
Pour créer un nouveau CommandElement (argument), utilisez la classe GenericArguments. De nombreux éléments de commande nécessitent un court mot-clé, qui est affiché en cas d’erreurs ou demandes d’aide.
Appliquez le CommandElement
à un constructeur de commandes avec la méthode CommandSpec.Builder#arguments(CommandElement…). Il est possible de transmettre plus d’un``CommandElement`` à la méthode, ce qui vous permet d’enchaîner les arguments (ex : /msg <player> <msg>
). Ceci a le même effet que d’inclure les objets du CommandElement
dans un élément GenericArguments#seq(CommandElement…).
Exemple: Construction d’une Commande à Arguments Multiples
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");
Vue d’ensemble des éléments de commande du GenericArguments
Élément de Commande |
Description |
Type de Valeur & Quantité |
---|---|---|
|
N’attend aucun argument. C’est le comportement par défaut d’un |
|
Types de Base Java |
||
|
Requiert à ce qu’un argument soit une chaîne de caractère. |
un |
|
Concatène tous les autres arguments séparés par des espaces (utile pour les commandes de message). |
un |
|
Requiert à ce qu’un argument soit un booléen. |
un |
|
Nécessite un argument de type entier. |
un |
|
Nécessite un argument de type double. |
un |
Objets de Jeu |
||
|
Attend un argument représentant un joueur connecté. Peut renvoyer plusieurs joueurs ! |
plusieurs instances de |
|
Comme |
plusieurs instances de |
|
Comme |
plusieurs instances de |
|
Attend un argument représentant un monde (inclut également les mondes non chargés). |
plusieurs |
|
Attend un argument représentant une dimension ( |
plusieurs instances de |
|
Attend un argument représentant une |
une |
|
Attend un argument du type |
un |
|
Attend un argument qui est membre d’un CatalogType spécifique. |
plusieurs éléments correspondants à ce catalogue de type spécifique |
Comparateurs |
||
|
Renvoie un argument qui permet de choisir parmi un ensemble de valeurs. |
une valeur spécifiée |
|
Attend une séquence littérale d’arguments (ex: |
une valeur spécifiée |
|
Nécessite que l’argument soit une clef sous forme d’une énumération donnée. |
plusieurs éléments correspondants à l’énumération spécifiée |
Utilitaires Peut être encapsulé autour des éléments de commande. Le type de valeur est hérité de l’élément encapsulé. |
||
|
Génère une séquence d’éléments de commande (ex: |
hérité |
|
Nécessite qu’un élément de commande donné soit fourni un certain nombre de fois. |
hérité plusieurs fois |
|
Nécessite que tous les arguments restants correspondent à l’élément de commande fourni. |
hérité plusieurs fois |
|
Rend l’élément de commande donné optionnel. Lance une erreur si l’argument est d’un format invalide et qu’il n’y a pas plus d’argument. |
hérité |
|
Rend l’élément de commande donné optionnel. Ne lance pas d’erreur si l’argument est d’un format invalide et qu’il n’y a pas plus d’argument. |
hérité |
|
Retourne un élément de commande qui correspond au premier des éléments analysés (utile pour remplacer une commande, par exemple |
hérité |
|
Restreint l’élément de commande donné à n’insérer qu’une valeur dans le contexte à la clé donnée. |
hérité |
|
Retourne un builder pour les flags de commande (par exemple: Voir Command Flags |
Flag Court: un Flag Long: un Valeur du Flag: hérité |
|
Demande à ce que celui ayant envoyé la commande a une permission spécifique afin d’utiliser l’argument de commande donné |
hérité |
|
Nécessite que l’expéditeur de la commande ait la permission spécifiée pour utiliser l’argument donné. Ne lance pas d’erreur si l’utilisateur n’a pas la permission. |
hérité |
Astuce
Voir les Javadocs de GenericArguments pour plus d’informations.
Avertissement
Ne vous attendez pas à ce que les CommandElement
s ne retournent qu’une seule valeur, un grand nombre d’entre eux supporte plusieurs valeurs de retour; certains peuvent même supporter les expressions régulières ou utiliser un sélecteur de commande. C’est intentionnel car ça simplifie l’utilisation des commande. Exemple : /tell @a BanditPlayer a les cookies !
. Si vous voulez être sûr de ne récupérer qu’une seule valeur, utilisez GenericArguments#onlyOne(CommandElement)
.
Éléments de Commandes Personnalisés
Il est possible de créer un élément de commande personnalisé (comme un parser d’URL ou un élément Vector2i
) en héritant de la classe abstraite CommandElement
.
La méthode CommandElement#parseValue(CommandSource, CommandArgs) doit récupérer une chaîne d’arguments brute avec CommandArgs#next() et la convertir en objet. La méthode doit générer une ArgumentParseException si l’analyse échoue.
La méthode CommandElement#complete(CommandSource, CommandArgs, CommandContext) doit utiliser CommandArgs#peek() pour lire l’argument brut suivant. Il retourne une liste de suggestions pour l’autocomplétion (tab).
Exemple : Définition de l’élément de commande Vector2i
L’analyseur dans cet exemple lit les deux arguments d’entrée et les convertit en un vecteur.
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>");
}
}
Exemple : Utilisation de l’élément de commande 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();
Astuce
Jetez un œil au code source de la classe GenericArguments
pour plus d’exemples.
Utiliser des Sélecteurs dans les Éléments de Commandes Personnalisés
Sponge prend en charge l’analyse des sélecteurs, ce qui signifie que vous pouvez les utiliser dans vos éléments personnalisés. Il y a deux étapes dans l’utilisation des sélecteurs, l’analyse (récupérer un Selector à partir de la chaîne) et la résolution (récupérer un ensemble d’objets Entity sélectionnés par le sélecteur).
Pour analyser un string sélecteur, utilisez la méthode Selector#parse(String), en passant le sélecteur entier, y compris le symbole @
. Cela va transformer le string en objet Selector
qui peut être consultée ou résolue. Notez que si le string n’est pas un sélecteur valide, une IllegalArgumentException sera levée.
Pour résoudre ce sélecteur, utilisez Selector#resolve(CommandSource). Cela va retourner un ensemble d’objets Entity
sélectionnés par le sélecteur.
La méthode suivante parseValue
de la classe CommandElement
essaie d’analyser un sélecteur et retourne un ensemble d’entités basé sur la position de la CommandSource
. Si la chaîne passée ne commence pas par @
, une exception sera levée indiquant que l’argument passé n’est pas un sélecteur.
@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."));
}
Astuce
Regardez le code source de SelectorCommandElement pour un exemple de comment l’analyse de sélecteur est effectuée dans le CommandElements
standard de Sponge.