-
-
Notifications
You must be signed in to change notification settings - Fork 7
Using Chimera Commands
A command can be either a Literal
(recommended) or LiteralCommandNode
. Both represent a literal command that can contain any number of subcommands and arguments. For brevity sake, only Literal
is used in the example below.
Literal
is a Chimera exclusive LiteralCommandNode
subclass that supports aliases, optional children and modification of otherwise non-modifiable fields.
A Literal
can be built using a builder created using either Literal.of(name)
or the more verbose Literal.<CommandSender>builder(name)
.
import com.karuslabs.commons.command.tree.nodes.Literal;
Literal<CommandSender> tell = Literal.of("tell").alias("t")
.then(arguments) // covered in the next section
.build();
An argument can be either an Argument
(recommended) or ArgumentCommandNode
. Both represent a variable argument that can be parsed into a type based on its ArgumentType
.
Argument
is a Chimera exclusive ArgumentCommandNode
subclass that supports optional children and modification of otherwise non-modifiable fields.
An Argument
can be built using a builder created using either Argument.of(name, type)
or the more verbose Argument.<CommandSender>builder(name, type)
.
In this example, we will create two arguments using different inbuilt ArgumentType
s. Inbuilt types provided by Chimera provide suggestions by default. Creating a custom ArgumentType
is beyond the scope of this guide. For brevity sake, only Argument
is used in the example below.
import com.karuslabs.commons.command.tree.nodes.Argument;
import com.karuslabs.commons.command.types.PlayersType;
import com.mojang.brigadier.arguments.StringArgumentType;
Argument.Builder<CommandSender, List<Player>> players = Argument.of("players", new PlayersType()); // Inbuilt players type provided by Chimera
Argument.Builder<CommandSender, String> message = Argument.of("message", StringArgumentType.string()) // Inbuilt string type provided by Mojang
.suggests((context, builder) -> builder.suggest("\"Hello World!\"").buildFuture());
Argument<CommandSender, List<Player>> arguments = players.then(message).build(); // Chains player and message
The commands created in the previous sections will not do nothing if executed as we did not define any behaviour for them. Behaviour can be attached to the commands using either Executable<T>
(recommended) or Command<T>
.
Executable<T>
is a Chimera exclusive Command<T>
subinterface that supports optional arguments and returns an integer indicating success.
A Executable<T>
or Command<T>
of the last command or argument will be always be executed, i.e. if the user entered "a b c"
, c
will be executed. Given the same commands and if the user entered "a b"
instead, b
will be executed.
In this examples, we edit the code snippets from the previous sections to attach an Executable<CommandSender>
.
import com.karuslabs.commons.command.Executable;
Literal<CommandSender> tell = Literal.of("tell").alias("t")
.executes(context -> context.getSource().sendMessage("Hello darkness my old friend")) // <-- Add this
.then(message)
.build();
Argument.Builder<CommandSender, List<Player>> players = Argument.of("players", new PlayersType());
Argument.Builder<CommandSender, String> message = Argument.of("message", StringArgumentType.string())
.executes(context -> { // <-- Add this
CommandSender sender = context.getSource();
List<Player> recipents = context.getArgument("players", List.class);
String entered = context.getArgument("message", String.class);
recipents.forEach(p -> p.sendMessage(sender + " says: " + entered));
})
.suggests((context, builder) -> builder.suggest("\"Hello World!\"").buildFuture());
After creating a command, its arguments and attaching behaviour to it, the command must be registered to a Dispatcher
. A Dispatcher
is the entry point of the framework to which commands are registered.
Registered commands are not immediately available if registered after YourPlugin.onLoad()
and YourPlugin.onEnable()
. In such cases, Dispatcher.update()
must be manually called.
import com.karuslabs.commons.command.Dispatcher;
Dispatcher dispatcher = Dispatcher.of(yourPlugin);
dispatcher.getRoot().addChild(tell);
dispatcher.update(); // Only needed if we added "tell" after YourPlugin.onLoad() and YourPlugin.onEnable() has been called.
After finishing this guide, the tell
command should look something like this.
import com.karuslabs.commons.command.Dispatcher;
import com.karuslabs.commons.command.Executable;
import com.karuslabs.commons.command.tree.nodes.Literal;
import com.karuslabs.commons.command.tree.nodes.Argument;
import com.karuslabs.commons.command.types.PlayersType;
import com.mojang.brigadier.arguments.StringArgumentType;
Argument.Builder<CommandSender, List<Player>> players = Argument.of("players", new PlayersType()); // Inbuilt players type provided by Chimera
Argument.Builder<CommandSender, String> message = Argument.of("message", StringArgumentType.string()) // Inbuilt string type provided by Mojang
.executes(context -> {
CommandSender sender = context.getSource();
List<Player> recipents = context.getArgument("players", List.class);
String entered = context.getArgument("message", String.class);
recipents.forEach(p -> p.sendMessage(sender.getName() + " says: " + entered));
})
.suggests((context, builder) -> builder.suggest("\"Hello World!\"").buildFuture());
Argument<CommandSender, List<Player>> arguments = players.then(message).build();
Literal<CommandSender> tell = Literal.of("tell").alias("t")
.executes(context -> context.getSource().sendMessage("Hello darkness my old friend"))
.then(arguments)
.build();
Dispatcher dispatcher = Dispatcher.of(yourPlugin);
dispatcher.getRoot().addChild(tell);
dispatcher.update(); // Only needed if we added "tell" after YourPlugin.onLoad() and YourPlugin.onEnable() has been called.
Testing the tell
command in-game will yield the following.