Repository navigation
Command Builder
For a full list of wiki pages, see the Home page.
DPP-Core's CommandBuilder provides a powerful, fluent API for creating complex command structures with minimal boilerplate. It simplifies handling sub-commands, argument parsing, type validation, and tab completion.
To create a command, you first instantiate a CommandBuilder and then use its methods to define the command's behavior. Finally, you register it with a command defined in your plugin.yml.
plugin.yml:
commands:
mycmd:
description: My awesome command.
usage: /<command>In your onEnable method:
import com.darksoldier1404.dppc.builder.command.CommandBuilder;
// ... inside onEnable
CommandBuilder builder = new CommandBuilder(this);
// ... define sub-commands and arguments (see below)
builder.build("mycmd"); // This registers the executor and tab completerThe CommandBuilder is designed around the concept of sub-commands. You can define what happens when a sub-command is executed.
The recommended way to define a sub-command is by using the beginSubCommand method, which returns a SubCommandBuilder instance.
builder.beginSubCommand("set", "/mycmd set <player> <value>")
.withPermission("mycmd.set") // Optional: set a permission
.playerOnly() // Optional: restrict to players only
.withArgument(ArgumentIndex.ARG_0, ArgumentType.PLAYER) // Define the first argument
.withArgument(ArgumentIndex.ARG_1, ArgumentType.INTEGER) // Define the second argument
.executesPlayer((player, args) -> { // Define the executor logic
Player target = args.getPlayer(ArgumentIndex.ARG_0);
int value = args.getInteger(ArgumentIndex.ARG_1);
if (target == null) {
player.sendMessage("Target player not found.");
return false; // Return false to show usage message
}
// Your logic here...
player.sendMessage("You set " + target.getName() + "'s value to " + value);
return true; // Return true on success
});Arguments are defined using the withArgument and withOptionalArgument methods.
-
withArgument(ArgumentIndex index, ArgumentType type): Defines a required argument. -
withOptionalArgument(...): Defines an optional argument.
This enum represents the position of the argument after the sub-command. ARG_0 is the first argument, ARG_1 is the second, and so on.
This enum tells the builder how to parse and tab-complete the argument. The builder handles all the validation and conversion for you.
Available Types:
PLAYER, OFFLINE_PLAYER, BYTE, SHORT, INTEGER, FLOAT, DOUBLE, BOOLEAN, CHAR, STRING, STRING_ARRAY, WORLD, MATERIAL, ENTITY_TYPE
Inside your executor, you receive a CommandArguments object. You can retrieve the parsed and type-safe argument values using its getter methods, such as getPlayer(ArgumentIndex.ARG_0) or getString(ArgumentIndex.ARG_1).
CommandBuilder provides automatic tab completion for most ArgumentTypes (e.g., player names, material names, world names).
You can also provide your own suggestions.
Provide a collection of strings for simple static suggestions.
.withArgument(ArgumentIndex.ARG_0, ArgumentType.STRING, Arrays.asList("easy", "medium", "hard"))Provide a function for dynamic suggestions based on the player or current arguments.
.withArgument(ArgumentIndex.ARG_1, ArgumentType.STRING, (player, args) -> {
// args here is the raw String[] of the command input
if (player.hasPermission("mycmd.admin")) {
return Arrays.asList("admin_option1", "admin_option2");
}
return Arrays.asList("user_option1", "user_option2");
})This example demonstrates a /dps command with multiple sub-commands, permissions, and argument types.
// In your DPlugin class
public void registerCommands() {
CommandBuilder builder = new CommandBuilder(this);
// /dps help
builder.beginSubCommand("help", "/dps help")
.executes((sender, args) -> {
sender.sendMessage("--- DPS Help ---");
sender.sendMessage("/dps reload - Reloads the plugin.");
sender.sendMessage("/dps set <player> <stat> <value> - Sets a player's stat.");
return true;
});
// /dps reload
builder.beginSubCommand("reload", "/dps reload")
.withPermission("dps.admin")
.executes((sender, args) -> {
// your reload logic
sender.sendMessage(getPrefix() + "Plugin reloaded.");
return true;
});
// /dps set <player> <stat> <value>
builder.beginSubCommand("set", "/dps set <player> <stat> <value>")
.withPermission("dps.admin")
.playerOnly()
.withArgument(ArgumentIndex.ARG_0, ArgumentType.PLAYER)
.withArgument(ArgumentIndex.ARG_1, ArgumentType.STRING, Arrays.asList("strength", "agility", "intellect"))
.withArgument(ArgumentIndex.ARG_2, ArgumentType.INTEGER)
.executesPlayer((player, args) -> {
Player target = args.getPlayer(ArgumentIndex.ARG_0);
String stat = args.getString(ArgumentIndex.ARG_1);
Integer value = args.getInteger(ArgumentIndex.ARG_2);
if (target == null || stat == null || value == null) {
return false; // Show usage message
}
// Logic to set the player's stat
player.sendMessage(getPrefix() + "Set " + target.getName() + "'s " + stat + " to " + value + ".");
return true;
});
builder.build("dps");
}