# Create a subcommand

## Summary

1. [Admin subcommand](#admin-subcommand)
2. [Player subcommand](#player-subcommand)
3. [Register your command](#register-your-command)
4. [Tab completion](#tab-completion)

## Admin subcommand

To add your own admin subcommand, you need to create a class that extends [`AdminCommandBase`](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/admin/AdminCommandBase.html). This class requires three methods to be overide: [`getName()`](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/admin/AdminCommand.html#getName\(\)), [`getPermission()`](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/admin/AdminCommand.html#getPermission\(\)) and [`execute(CommandSender sender, String[] args)`](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/admin/AdminCommand.html#execute\(org.bukkit.command.CommandSender,java.lang.String\[]\)). Here is an example of implementation:

```java
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`](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/admin/AdminCommandBase.html) class itself inherits from a [`AdminMessages`](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/admin/AdminMessages.html) 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.

| Method                                                                                                                                                                                             | Associated message     |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- |
| [help(CommandSender sender)](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/admin/AdminMessages.html#help\(org.bukkit.command.CommandSender\))                   | admin\_help            |
| [invalidPlayer(CommandSender sender)](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/admin/AdminMessages.html#invalidPlayer\(org.bukkit.command.CommandSender\)) | invalid\_player        |
| [invalidQuest(CommandSender sender)](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/admin/AdminMessages.html#invalidQuest\(org.bukkit.command.CommandSender\))   | invalid\_quest\_amount |
| [invalidAmount(CommandSender sender)](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/admin/AdminMessages.html#invalidAmount\(org.bukkit.command.CommandSender\)) | invalid\_amount        |

The [`AdminCommandBase`](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/admin/AdminCommandBase.html) class also provides two methods for retrieving a player and parse a quest identifier, [getTargetPlayer(...)](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/admin/AdminCommandBase.html#getTargetPlayer\(org.bukkit.command.CommandSender,java.lang.String\)) and [parseQuestIndex(...)](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/admin/AdminCommandBase.html#parseQuestIndex\(org.bukkit.command.CommandSender,java.lang.String\)).

```java
    /**
     * 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`](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/player/PlayerCommandBase.html). This class requires three methods to be overide: [`getName()`](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/player/PlayerCommand.html#getName\(\)), [`getPermission()`](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/player/PlayerCommand.html#getPermission\(\)) and [`execute(Player player, String[] args)`](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/player/PlayerCommand.html#execute\(org.bukkit.entity.Player,java.lang.String\[]\)). Here is an example of implementation:

```java
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`](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/player/PlayerCommandBase.html) class itself inherits from a [`PlayerMessages`](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/player/PlayerMessages.html) 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.

| Method                                                                                                                                                                                                      | Associated message       |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
| [help(CommandSender)](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/player/PlayerMessages.html#help\(org.bukkit.command.CommandSender\))                                 | player\_help             |
| [noPermission(CommandSender)](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/player/PlayerMessages.html#noPermission\(org.bukkit.command.CommandSender\))                 | no\_permission           |
| [noPermissionCategory(CommandSender)](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/player/PlayerMessages.html#noPermissionCategory\(org.bukkit.command.CommandSender\)) | no\_permission\_category |
| [playerOnly(CommandSender)](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/player/PlayerMessages.html#playerOnly\(org.bukkit.command.CommandSender\))                     | player\_only             |
| [invalidCategory(CommandSender)](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/player/PlayerMessages.html#invalidCategory\(org.bukkit.command.CommandSender\))           | invalid\_category        |

## Register your command

You can register your command in the `onEnable()` method of your main class, by retrieving the [`AdminCommandRegistry`](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/admin/AdminCommandRegistry.html) or [`PlayerCommandRegistry`](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/admin/PlayerCommandRegistry.html), dependeing of the type of command.

```java
@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)` ](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/admin/AdminCommandCompleter.html#onTabComplete\(org.bukkit.command.CommandSender,java.lang.String\[]\))method, which is included in both [`AdminCommandBase`](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/admin/AdminCommandBase.html) and [`PlayerCommandBase`](https://odailyquests.ordwen-dev.com/javadoc/com/ordwen/odailyquests/api/commands/player/PlayerCommandBase.html). 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.

```java
@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();
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ordwenplugins.gitbook.io/odailyquests/api/create-a-subcommand.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
