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 games.negative.alumina.command.Command, which is easily mistaken for org.bukkit.command.Command, so be sure you're importing the correct one!

Example
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));
    }
    
}

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:

MethodDescription

name()

The name of the command.

description()

The description of the command.

usage()

The usage of the command.

aliases()

The aliases of the command.

permissions()

A list of permissions that only require the executor to have at least one to be allowed to use the command.

params()

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.

shortcuts()

Used in subcommands to allow the subcommand to also be a primary command. An example is Essentials with /gamemode creative and /gmc. /gmc being a "shortcut".

playerOnly()

When true, the command becomes "player only," meaning it can only be executed by players.

consoleOnly()

When true, the command becomes "console-only," meaning it can only be executed by non-player objects like the Console.

smartTabComplete()

When true, the command automatically takes all subcommands, parameters, etc, into account and displays your command in tab-completion.

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.

Example
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!
    }

}

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!

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

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

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!

Example
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!
    }

}

Custom Tab Completion

If you wish to add your custom tab completion logic, you're able to do so by overriding the onTabComplete() method!

Example
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();
    }
}

Registering a Command

To register a command, you must go to your main class and invoke the registerCommand() method.

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

    @Override
    public void enable() {

        registerCommand(new ExampleCommand());
        
    }

    @Override
    public void disable() {

    }
    
}

Last updated