Skip to content

Annotated Commands

Mazen edited this page Apr 17, 2024 · 12 revisions

Command Annotations

Registering a command through annotations is simple and easy, just follow the steps below

Initializing AnnotationParser

In your main class, create a AnnotationParser field and initialize it using your command manager instance

private SpigotCommandManager commandManager;
private AnnotationParser<CommandSender> parser;

@Override
public void onEnable() {

   commandManager = new SpigotCommandManager(this);
   parser = new AnnotationParser<>(commandManager);
}

Creating the command class

To create a valid class for annotation parser to register as a command you must include the annotation @Command at the top of the class

import io.github.mqzn.commands.annotations.Command;

@Command(name = "test", executionType = CommandExecutionRequirement.Type.ASYNC, permission = "", description = "", aliases = "t", requirements = CustomCommandRequirement.class)
public class TestAnnotationCommand  {
	
}

Since version 1.1.5, you can now specify each command's execution-type to be async or sync instead of a general execution-type in older versions. You can set the command requirements using the classes that implement CommandRequirement

Command Cooldown

You can easily set cooldown for a command using the annotation @Cooldown here's an example:

@Command(name = "testc")
@Cooldown(value = 5, unit = TimeUnit.SECONDS) //5 seconds
public class TestAnnotationCommand {

}

Default Execution Annotation

Annotate a void method with @Default , in which that method must have only 2 parameters which are the sender parameter and the raw args parameter.

@Default
public void defaultExecution(@NotNull CommandSender sender, @NotNull CommandArgs args) {
   //default execution
}

Creating Annotated syntax

Simply by creating a void method and annotating it with @ExecutionMeta then fill the params of the annotation
FIRST PARAMETER MUST BE THE TYPE OF THE COMMAND SENDER !
SECOND PARAMETER MUST BE CommandArgs

Custom Command Senders

To declare your own command sender, it's really simple ! all what you have to do is set the senderType in the annotation @ExecutionMeta to the class type of the sender you want and MAKE SURE that the first parameter of your syntax methd is the same type of the sender type declared in the annotation, otherwise it could cause issues.

Using this custom sender class:

public class CustomSender {


	@NotNull
	private final CommandSender sender;

	public CustomSender(@NotNull CommandSender sender) {
		this.sender = sender;
	}

	public void sendWoo() {
		sender.sendMessage("WOOOOOOO");
	}

}

To demonstrate a simple example on how to achieve this:

@Command(name = "testc", executionType = CommandExecutionRequirement.Type.ASYNC) //execution-type by default is SYNC
public class TestAnnotationCommand {

	@ExecutionMeta(syntax = "testasub", senderType = CustomSender.class)
	public void testASub(@NotNull CustomSender sender, @NotNull CommandArgs args) {
		sender.sendWoo();
	}


}

Syntax Arguments

To create arguments properly, you must do two things: 1- make sure the syntax in the annotation @ExecutionMeta is properly matching with the parameters also check if the argument id(in the @Arg of the parameter is matching with it's name in the syntax (Argument literals should NOT considered into the parameters, where a literal an argument that has 1 only value)

Example:

@ExecutionMeta(syntax = "print <value>", permission = "test.print", description = "Prints a value in console !")
public void print(@NotNull CommandSender sender, @NotNull CommandArgs rawArgs, @NotNull @Arg(id="value") String value) {
   sender.sendMessage("Printed value '" + value + "'");
}

In the syntax, the 'print' arg is a literal, while '' isn't !

Greedy Syntax Arguments

Some times you need to specify an argument that is greedy (can consume the arguments after it) here's an example :

@ExecutionMeta(syntax = "broadcast <message>", permission = "test.broadcast", description = "Broadcasts a message !")
public void broadcast(@NotNull CommandSender sender, @NotNull CommandArgs rawArgs, @NotNull @Arg(id="message") @Greedy String message) {

   //broadcasting the message
   Bukkit.broadcastMessage(message);
}

Syntax Numerical Argument Ranges

You can specify a range to the numerical parameter argument in your command method, by annotating the parameter with @Range

here's an example:

@ExecutionMeta(syntax = "setprice <price>")
public void setPrice(@NotNull CommandSender sender, @NotNull CommandArgs rawArgs, @Arg(id="price") @Range(min = "1.0", max = "101.5") double price) {
   sender.sendMessage("Changed price to " + price);
}

Syntax Flags

In your command method, add a parameter with type boolean and annotate that parameter with the annotation @Flag and specify the flag name

@ExecutionMeta(syntax = "print <value>", permission = "test.print", description = "Prints a value in console !")
public void print(@NotNull CommandSender sender, @NotNull CommandArgs rawArgs,
 @NotNull @Arg(id="value") String value, @Flag(name = "silent") boolean silent) {
   String msg = "Printed value '" + value + "'";

   if(silent)
     sender.sendMessage(msg);
   else
     Bukkit.broadcastMessage(msg);

}

in this example, you have declared that a flag with the name 'silent' can be present/used the boolean param to allow you to check if the flag is present !

Registering the command

You can easily register the command by calling AnnotationParser#parse example:

parser.parse(new YourAnnotatedCommand());