Skip to content

Command conditions

Revxrsal edited this page Sep 21, 2021 · 4 revisions

Usage

Command conditions are a very useful way to run pre-execution command checks and validations. These can be permission checks, sender checks, cooldown checks, etc.

Command conditions are also able to check against custom annotations. This can greatly reduce the need to write repetitive checks for commands, and instead replace it with a single annotation.

A condition should throw exceptions when it fails, with this exception being handled by the registered exception handler.

For the sake of simplicity, there are built-in exceptions that can be used to transfer a message to the sender and then signal command execution fail. See CommandErrorException, SendMessageException.

It is important to keep in mind that conditions are run on every command execution. Therefore, most conditions may need to check for custom annotations if they do not want all commands to require a certain condition.

Example

We may want to create a command that can only be executed once in a lifetime.

Let's create our custom @ExecuteOnceInLifetime annotation.

@Target(ElementType.METHOD)  
@Retention(RetentionPolicy.RUNTIME)  
public @interface ExecutableOnceInLifetime {}

Then, we can check for the custom annotation using ExecutableCommand#hasAnnotation(type):

public enum LifetimeExecutionCondition implements CommandCondition {  
    INSTANCE;  
  
    private final Set<UUID> executed = new HashSet<>();  
  
    @Override public void test(CommandActor actor, ExecutableCommand command, List<String> arguments) {  
        if (command.hasAnnotation(ExecutableOnceInLifetime.class)) {  
            if (!executed.add(actor.getUniqueId())) {  
                throw new CommandErrorException("You may not run this command again!");  
            }  
        }  
    }  
}

Finally, we register our condition:

CommandHandler handler = ...;
handler.registerCondition(LifetimeExecutionCondition.INSTANCE);

It should be kept in mind that everything should be registered before registering commands, since certain things may be cached right after a command is registered.