Argument Parsing

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 args.<T>getOne(String key) (T is the value type). Optional and weak arguments may return Optional.absent().

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 args.<T>getAll(String key) method to get the Collection of possible matches. Otherwise, the context object will throw an exception!

Tip

You can use the onlyOne element to limit the amount of returned values to a single one, so you can safely use args.<T>getOne(String key).

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 setArguments() 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() element.

Example: Building a Command with Multiple Arguments

import org.spongepowered.api.text.Texts;
import org.spongepowered.api.entity.player.Player;
import org.spongepowered.api.util.command.CommandException;
import org.spongepowered.api.util.command.CommandResult;
import org.spongepowered.api.util.command.CommandSource;
import org.spongepowered.api.util.command.args.CommandContext;
import org.spongepowered.api.util.command.args.GenericArguments;
import org.spongepowered.api.util.command.spec.CommandExecutor;
import org.spongepowered.api.util.command.spec.CommandSpec;

CommandSpec myCommandSpec = CommandSpec.builder()
        .description(Texts.of("Send a message to a player"))
        .permission("myplugin.command.message")

        .arguments(
                GenericArguments.onlyOne(GenericArguments.player(Texts.of("player"), this.game)),
                GenericArguments.remainingJoinedStrings(Texts.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(Texts.of(message));

                return CommandResult.success();
            }
        })
        .build();

game.getCommandDispatcher().register(plugin, myCommandSpec, "message", "msg", "m");

Overview of the GenericArguments command elements

Command Element Description Value Type & Amount
none Expects no arguments. This is the default behavior of a CommandSpec.  
Java Base Types
string Require an argument to be a string. one String
remainingJoinedStrings Concatenates all remaining arguments separated by spaces (useful for message commands). one String
bool Require an argument to be a boolean. one Boolean
integer Require an argument to be an integer. one Integer
Game Objects
player Expect an argument to represent an online player. May return multiple players! multiple Player instances
playerOrSource Like player, but returns the sender of the command if no matching player was found. multiple Player instances
world Expect an argument to represent a world (also includes unloaded worlds). multiple WorldProperties
dimension Expect an argument to represent a dimension (END, NETHER, OVERWORLD). multiple DimensionType instances
location Expect an argument to represent a Location. one Location
vector3d Expect an argument to represent a Vector3d. one Vector3d
catalogedElement Expect an argument that is a member of the specified catalog type. multiple matching elements of the specified catalog type
Matchers
choices Return an argument that allows selecting from a limited set of values. one specified value
literal Expect a literal sequence of arguments (e.g. "i", "luv", "u": /cmd i luv u). Throws an error if the arguments do not match. one specified value
enumValue Require the argument to be a key under the provided enum. multiple matching elements of the specified enum

Utilities

Can be wrapped around command elements. The value type is inherited from the wrapped element.

seq Builds a sequence of command elements (e.g. /cmd <arg1> <arg2> <arg3>). inherited
repeated Require a given command element to be provided a certain number of times. multiple inherited
allOf Require all remaining args to match the provided command element. multiple inherited
optional Make the provided command element optional. Throws an error if the argument is of invalid format and there are no more args. inherited
optionalWeak Make the provided command element optional. Does not throw an error if the argument is of invalid format and there are no more args. inherited
firstParsing Returns a command element that matches the first of the provided elements that parses (useful for command overloading, e.g. /settime <day|night|<number>>). inherited
onlyOne Restricts the given command element to only insert one value into the context at the provided key. inherited
flags

Returns a builder for command flags (e.g. /cmd [-a] [-b <value>]).

See Flags

Short Flag: one Boolean

Long Flag: one String

Value Flag: inherited

requiringPermission Requires the command sender to have the specified permission in order to use the given command argument inherited

Tip

See the documentation for GenericArguments for more information.

Flags

Coming soon...

Custom Command Elements

It is possible to create custom command elements (e.g. a URL parser or a Vector2i element) by extending the abstract CommandElement class.

The parseValue method should fetch a raw argument string with args.next() and convert it to an object. The method should throw an ArgumentParseException if the parsing fails

The complete method should use args.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 java.util.Collections;
import java.util.List;

import org.spongepowered.api.text.Texts;
import com.flowpowered.math.vector.Vector2i;
import org.spongepowered.api.util.command.CommandSource;
import org.spongepowered.api.util.command.args.ArgumentParseException;
import org.spongepowered.api.util.command.args.CommandArgs;
import org.spongepowered.api.util.command.args.CommandContext;
import org.spongepowered.api.text.Text;
import org.spongepowered.api.util.command.args.CommandElement;

public class Vector2iCommandElement extends CommandElement {

    protected Vector2iCommandElement(Text key) {
        super(key);
    }

    @Override
    protected Object parseValue(CommandSource source, CommandArgs args) throws ArgumentParseException {

        // <x> <y>

        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 args.createError(Texts.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 Texts.of("<x> <y>");
    }
}

Example: Vector2i command element usage

import org.spongepowered.api.text.Texts;
import org.spongepowered.api.entity.player.Player;
import org.spongepowered.api.util.command.spec.CommandSpec;

// /plottp <x> <y>
CommandSpec myCommandSpec = CommandSpec.builder()
        .setDescription(Texts.of("Teleport to a plot"))
        .setPermission("myplugin.command.plot.tp")

        .setArguments(new Vector2iCommandElement(Texts.of("coordinates")))

        .setExecutor(new MyCommandExecutor())
        .build();

Tip

Look at the source code of the GenericArguments class for more examples.