# Commands

The command system is very flexible and efficient. It allows you to create commands without registering them in a plugin.yml and a few cool features to reduce boilerplate.

## Creating a Command

To create a command, you will need to create a class which extends <mark style="color:green;">`games.negative.alumina.command.Command`</mark>, which is easily mistaken for <mark style="color:red;">`org.bukkit.command.Command`</mark>, so be sure you're importing the correct one!

<details>

<summary>Example</summary>

```java
public class ExampleCommand extends Command {
    
    public ExampleCommand() {
        super(
                CommandProperties.builder()
                        .name("example") // main command label
                        .aliases(List.of("myexamplecommand")) // command aliases
                        .permissions(List.of(new Permission("example.permission"))) // command permissions
                        .playerOnly(true) // Only players can execute this command
                        //.consoleOnly(true) // Only console can execute this command
                        .description("This is an example command") // command description
                        .usage("/example mine") // command usage
                        .params(List.of("message")) // command (required) parameters
                        .smartTabComplete(true) // Smart tab completion
                .build());
    }

    @Override
    public void execute(@NotNull Context context) {
        // We can use context to get the player who executed the command
        // and we can use orElseThrow() because we have
        // player-only enabled, so the player will always be present
        Player player = context.player().orElseThrow();

        // Alternatively we can get the command sender
        // if we're not sure if the command sender is a player
        CommandSender sender = context.sender();

        // We can also get "argument" 0 from the context
        // because we have a required parameter, so the check if
        // the argument is present is not needed here as its done
        // in the background.
        String message = context.argument(0).orElseThrow();
        
        player.sendMessage(Component.text(message));
    }
    
}
```

</details>

## Understanding `CommandProperties`

The CommandProperties class is a builder for the command system, which gives you a lot of flexibility when designing your command properties with a vast array of options!

Here is a detailed description of all CommandProperties methods:

<table><thead><tr><th width="232">Method</th><th>Description</th></tr></thead><tbody><tr><td><code>name()</code></td><td>The name of the command.</td></tr><tr><td><code>description()</code></td><td>The description of the command.</td></tr><tr><td><code>usage()</code></td><td>The usage of the command.</td></tr><tr><td><code>aliases()</code></td><td>The aliases of the command.</td></tr><tr><td><code>permissions()</code></td><td>A list of permissions that only require the executor to have at least one to be allowed to use the command.</td></tr><tr><td><code>params()</code></td><td>A list of required parameters, or "arguments," for the command to execute correctly. The command will fail to execute if the executor has not completed the required parameters in their command.</td></tr><tr><td><code>shortcuts()</code></td><td>Used in subcommands to allow the subcommand to also be a primary command. An example is <strong>Essentials</strong> with <code>/gamemode creative</code> and <code>/gmc</code>. <code>/gmc</code> being a "shortcut".</td></tr><tr><td><code>playerOnly()</code></td><td>When true, the command becomes "player only," meaning it can only be executed by players.</td></tr><tr><td><code>consoleOnly()</code></td><td>When true, the command becomes "console-only," meaning it can only be executed by non-player objects like the Console.</td></tr><tr><td><code>smartTabComplete()</code></td><td>When true, the command automatically takes all subcommands, parameters, etc, into account and displays your command in tab-completion.</td></tr></tbody></table>

## Creating a SubCommand

There are two ways of making a subcommand, so we will display how to do both.

### Injection

Injecting a SubCommand is an alternative to creating a class to add a SubCommand, especially if the SubCommand is very short in lines of code; it will save time compared to creating an entirely new class for five lines of code, for example.

<details>

<summary>Example</summary>

```java
public class ExampleCommand extends Command {

    public ExampleCommand() {
        super(CommandProperties.builder().name("example").build());
        
        injectSubCommand(CommandProperties.builder().name("epic").build(), context -> {
            CommandSender sender = context.sender();
            
            sender.sendMessage(Component.text("This is an epic injected subcommand!"));
        });
    }

    @Override
    public void execute(@NotNull Context context) {
        // Main command logic here!
    }

}
```

</details>

### Class

In what is considered the "normal" way of creating SubCommands, you need to create an entirely separate class to run your command logic. Then, in the constructor of your main command class, you register the subcommand.

#### Creating SubCommand class

Creating a subcommand class is exactly like a regular command!

<details>

<summary>Example</summary>

```java
public class ExampleSubCommand extends Command {
    
    public ExampleSubCommand() {
        super(CommandProperties.builder().name("amazingness").build());
    }

    @Override
    public void execute(@NotNull Context context) {
        // Subcommand logic here!
    }
    
}
```

</details>

#### Registering a SubCommand

As stated before, to register a subcommand, you just invoke the addSubCommand method in the main command class. *Fun fact: You can also add subcommands to subcommand classes! It's a subcommand ception!*

<details>

<summary>Example</summary>

```java
public class ExampleCommand extends Command {

    public ExampleCommand() {
        super(CommandProperties.builder().name("example").build());

        addSubCommand(new ExampleSubCommand());
    }

    @Override
    public void execute(@NotNull Context context) {
        // Main command logic here!
    }

}
```

</details>

## Custom Tab Completion

If you wish to add your custom tab completion logic, you're able to do so by overriding the <mark style="color:green;">`onTabComplete()`</mark> method!

<details>

<summary>Example</summary>

```java
public class ExampleCommand extends Command {

    public ExampleCommand() {
        super(CommandProperties.builder().name("example").build());
    }

    @Override
    public void execute(@NotNull Context context) {
        // Main command logic here!
    }

    @Override
    public List<String> onTabComplete(@NotNull TabContext context) {
        // If the current index is 1, and the previous argument is "hello"
        if (context.index() == 1 && context.argument(0).orElseThrow().equalsIgnoreCase("hello"))
            return List.of("hi!");

        return List.of();
    }
}
```

</details>

## Registering a Command

To register a command, you must go to your main class and invoke the <mark style="color:green;">`registerCommand()`</mark> method.&#x20;

<details>

<summary>Example</summary>

```java
public class ExamplePlugin extends AluminaPlugin {
    
    @Override
    public void load() {
        
    }

    @Override
    public void enable() {

        registerCommand(new ExampleCommand());
        
    }

    @Override
    public void disable() {

    }
    
}
```

</details>


---

# 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://wiki.ericlmao.com/projects/alumina/commands.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.
