Create a subcommand
Since version 3.0 it is possible to create your own subcommands using the plugin API.
Summary
Admin subcommand
To add your own admin subcommand, you need to create a class that extends AdminCommandBase
. This class requires three methods to be overide: getName()
, getPermission()
and execute(CommandSender sender, String[] args)
. Here is an example of implementation:
public class MyAdminCommand extends AdminCommandBase {
@Override
public String getName() {
return "hello";
}
@Override
public String getPermission() {
return "odailyquests.admin.hello";
}
@Override
public void execute(CommandSender sender, String[] args) {
if (args.length == 2 && args[1] != null) {
final Player target = getTargetPlayer(sender, args[1]);
if (target == null) return;
sendHelloMessage(sender, target);
} else {
help(sender);
}
}
private void sendHelloMessage(CommandSender sender, Player target) {
target.sendMessage("Hello from " + sender.getName() + "!");
sender.sendMessage("You greeted " + target.getName() + ".");
}
}
In this case, the command will be /dqa hello <target>
. It will require the odailyquests.admin.hello
permission. You don't need to check that the user has permission, ODailyQuests takes care of that for you! It will use the value returned by the getPermission()
method.
The AdminCommandBase
class itself inherits from a AdminMessages
class, which contains utility methods to avoid duplication of code, which you can also use. They all return messages present in the messages.yml
file.
admin_help
invalid_player
invalid_quest_amount
invalid_amount
The AdminCommandBase
class also provides two methods for retrieving a player and parse a quest identifier, getTargetPlayer(...) and parseQuestIndex(...).
/**
* Retrieves a player instance by their exact name.
*
* If the player is not found (offline or name mismatch), sends an "invalid player" message
* to the sender and returns null.
*
* @param sender the command sender (used to send feedback in case of an invalid player)
* @param playerName the exact name of the target player
* @return the target Player if found, or null otherwise
*/
protected Player getTargetPlayer(CommandSender sender, String playerName)
/**
* Parses an integer value from a string argument.
*
* If the argument is not a valid number, sends an "invalid quest index" message
* to the sender and returns -1 as a fallback.
*
* @param sender the command sender (used to send feedback in case of invalid input)
* @param arg the string to parse as an integer
* @return the parsed integer value, or -1 if the input was invalid
*/
protected int parseQuestIndex(CommandSender sender, String arg);
Player subcommand
To add your own player subcommand, you need to create a class that extends PlayerCommandBase
. This class requires three methods to be overide: getName()
, getPermission()
and execute(Player player, String[] args)
. Here is an example of implementation:
public class MyPlayerCommand extends PlayerCommandBase {
@Override
public String getName() {
return "hello";
}
@Override
public String getPermission() {
return "odailyquests.hello";
}
@Override
public void execute(CommandSender sender, String[] args) {
if (!(sender instanceof Player player)) {
playerOnly(sender);
return;
}
sender.sendMessage("Hello from my custom command!");
}
}
In this case, the command will be /dq hello
. It will require the odailyquests.hello
permission. You don't need to check that the user has permission, ODailyQuests takes care of that for you! It will use the value returned by the getPermission()
method.
The PlayerCommandBase
class itself inherits from a PlayerMessages
class, which contains utility methods to avoid duplication of code, which you can also use. They all return messages present in the messages.yml
file.
player_help
no_permission
no_permission_category
player_only
invalid_category
Register your command
You can register your command in the onEnable()
method of your main class, by retrieving the AdminCommandRegistry
or PlayerCommandRegistry
, dependeing of the type of command.
@Override
public void onEnable() {
AdminCommandRegistry adminRegistry = API.getAdminCommandRegistry();
adminRegistry.registerCommand(new MyAdminCommand());
PlayerCommandRegistry playerRegistry = API.getPlayerCommandRegistry();
playerRegistry.registerCommand(new MyPlayerCommand());
}
Tab completion
Depending on how you use it, you'll probably want to add auto completion to your commands. You can do this by overriding the onTabComplete(CommandSender sender, String[] args)
method, which is included in both AdminCommandBase
and PlayerCommandBase
. By default, this method returns an empty list.
Note that if you want to return the players' nicknames, you'll have to return null instead of an empty list. This is a specific Bukkit behaviour.
Here is an example of tab completion for our MyAdminCommand
class.
@Override
public List<String> onTabComplete(@NotNull CommandSender sender, String[] args) {
// Suggest "hello" if it's the first argument after the command
if (args.length == 2) {
return List.of("hello");
}
// Suggest player names if the second argument is "hello"
if (args.length == 3 && args[1].equalsIgnoreCase("hello")) {
// Returning null makes Bukkit auto-complete with online player names
return null;
}
return Collections.emptyList();
}
Last updated