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 (entiers, booléens, 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 à 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 !

Astuce

Vous pouvez utiliser l’élément GenericArguments#onlyOne(CommandElement) pour limiter le nombre de valeurs renvoyées à une seule valeur, donc vous vous pouvez utilisez prudemment args.<T>getOne(String key).

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…). C’est possible de transmettre plus d’un``CommandElement`` à la méthode, ainsi vous pouvez 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;

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");

Vue d’ensemble des éléments de commande du GenericArguments

Élément de Commande

Description

Type de Valeur & Quantité

none

N’attend aucun argument. C’est le comportement par défaut d’un CommandSpec.

Types de Base Java

string

Requiert à ce qu’un argument soit une chaîne de caractère.

un String

remainingJoinedStrings

Concatène tous les autres arguments séparés par des espaces (utile pour les commandes de message).

un String

bool

Requiert à ce qu’un argument soit un booléen.

un Boolean

integer

Nécessite un argument de type entier.

un Integer

doubleNum

Nécessite un argument de type double.

un Double

Objets de Jeu

player

Attend un argument représentant un joueur connecté. Peut renvoyer plusieurs joueurs !

plusieurs instances de Player

playerOrSource

Comme player, mais renvoie l’expéditeur de la commande si aucun joueur n’est trouvé.

plusieurs instances de Player

userOrSource

Comme playerOrSource, mais retourne un utilisateur au lieu d’un joueur.

plusieurs instances de User

world

Attend un argument représentant un monde (inclut également les mondes non chargés).

plusieurs WorldProperties

dimension

Attend un argument représentant une dimension (END, NETHER, OVERWORLD).

plusieurs instances de DimensionType

location

Attend un argument représentant une Location.

une Location

vector3d

Attend un argument du type Vector3d.

un Vector3d

catalogedElement

Attend un argument qui est membre d’un CatalogType spécifique.

plusieurs éléments correspondants à ce catalogue de type spécifique

Comparateurs

choices

Renvoie un argument qui permet de choisir parmi un ensemble de valeurs.

une valeur spécifiée

literal

Attend une séquence littérale d’arguments (ex: "i", "luv", "u": /cmd i luv u). Génère une erreur si les arguments ne correspondent pas.

une valeur spécifiée

enumValue

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é.

seq

Génère une séquence d’éléments de commande (ex: /cmd <arg1> <arg2> <arg3>).

hérité

repeated

Nécessite qu’un élément de commande donné soit fourni un certain nombre de fois.

hérité plusieurs fois

allOf

Nécessite que tous les arguments restants correspondent à l’élément de commande fourni.

hérité plusieurs fois

optional

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é

optionalWeak

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é

firstParsing

Retourne un élément de commande qui correspond au premier des éléments qui a été analysé (utile pour la surcharge de commandes, comme /settime <day|night|<number>>).

hérité

onlyOne

Restreint l’élément de commande donné à n’insérer qu’une valeur dans le contexte à la clé donnée.

hérité

flags

Retourne un builder pour les flags de commande (par exemple: /cmd [-a] [-b <value>]).

Voir Command Flags

Flag Court: un Boolean

Flag Long: un String

Valeur du Flag: hérité

requiringPermission

Demande à ce que celui ayant envoyé la commande a une permission spécifique afin d’utiliser l’argument de commande donné

hérité

Astuce

Voir les Javadocs de GenericArguments pour plus d’informations.

É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 {
    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>");
    }
}

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

Regardez le code source de la classe GenericArguments pour plus d’exemples.