Command Framework

Command argument basics

CommandArguments is an utility class for Command Framework and includes the basic parameters related Bukkit commands and bunch of useful methods to improve your code.

Basic Methods

    // We have created a basic command named "example"
    @Command(
            name = "example"
    )
    public void exampleCommandMethod(CommandArguments arguments) {
        // To get command sender use CommandArguments#getSender method
        CommandSender sender = arguments.getSender();

        // To check who is the sender
        if (arguments.isSenderPlayer()) {
            // now sender is player
        } else {
            // and now sender is console
        }

        // To get as Bukkit's command use CommandArguments#getCommand method
        // After that you can be able to get command's name, description, permission, etc.
        org.bukkit.command.Command command = arguments.getCommand();

        // To get label of command use CommandArguments#getLabel method
        String label = arguments.getLabel();

        // To get arguments of command use CommandArguments#getArguments() method
        // and don't forget these arguments is not all the parts of default arguments
        // because they'll be splitted after sub-command parts
        String[] args = arguments.getArguments();
       
       // To get specific argument without receiving argument array
       // There is no exception during this operation but also don't forget
       // that method can be null if index is out of bounds.
       String firstArgument = arguments.getArgument(0);

       // To get arguments array is empty or not without receiving array.
       boolean isArgsEmpty = arguments.isArgumentsEmpty();

       // To send message to command sender without receivingits object
       arguments.sendMessage("Hey there!");
 
       // To check if command sender has permission without receiving sender object
       if (arguments.hasPermission("command.framework") {
           // sender has the given permission
       } else {
           // sender has not the given permission
       }

       // To get arguments length without receiving string array
       int argumentsLength = arguments.getLength();
    }

Useful Methods

    // We have created a basic command named "example"
    @Command(
            name = "example"
    )
    public void exampleCommandMethod(CommandArguments arguments) {
       // Gets player from the given name, in Optional type
       Optional<Player> playerFromName = arguments.getPlayer("Despical");
       playerFromName.ifPresent(player -> player.sendMessage("Hello World!"));

       // Gets player from the given argument index, in this case first argument
       Optional<Player> playerFromArgs = arguments.getPlayer(0);
       playerFromArgs .ifPresent(player -> player.sendMessage("Hello World!"));

      // Assume that our arguments array is = ["example", "array", "with", "multiple", "arguments"]
      
      String concatenatedArgs = arguments.concatenateArguments();
      // concatenatedArgs will be equals to = "example array with multiple arguments"

      // from index is inclusive, to index is exclusive
      String concatenatedArgs = arguments.concatenateRangeOf(1, 4);
      // concatenatedArgs will be equals to = "array with multiple arguments"

      // Checks if the first argument is numeric or not.
      // Does not checks for bounds so should be careful about the overflowing.
      // This method will return false for non-positive or floating decimals.
      boolean isNumeric = arguments.isNumeric(0); // Method takes string values as well other than argument indexes.

      // This method checks if the first argument is an integer or not,
      // checks for bounds so it can throw exception if the integer limit is exceed in both positive or negative ways.
      // And will return false if the given argument is a floating point.
      boolean isInteger = arguments.isInteger(0); // Method takes string values as well other than argument indexes.

      // This method checks if the first argument is a floating decimal or not,
      // checks for bounds so it can throw exception if the double limit is exceed in both positive or negative ways.
      // And will return true if the given argument is an integer.
      boolean isFloatingDecimal = arguments.isFloatingDecimal(0); // Method takes string values as well other than argument indexes.
}

Registering Commands

Create an CommandFramework object using the constructor then register the commands using CommandFramework#registerCommands method, then framework will register all the methods that have Command or Completer annotations and CommandArguments parameter as a command in the class.

public class ExampleClass extends JavaPlugin {

    // Don't forget to shade framework in to your project
    private CommandFramework commandFramework;

    @Override
    public void onEnable() {
        // Initialize the framework before using
        commandFramework = new CommandFramework(this);

        // Then this will register all the @Command methods as a command
        // so there is no necessity to add command to your plugin.yml
        commandFramework.registerCommands(this);
    }
}

Creating Command

Before creating commands, you must create a method body, then annotate the Command and don't forget to add CommandArguments as a parameter to your method. If you don't know what are the attributes that you can change, take a look at Commands page.

    // Before creating command the method must only have
    // CommandArguments parameter and also @Command annotation
    @Command(
            name = "example",
            aliases = {"firstAlias", "secondAlias"},
            permission = "example.permission",
            desc = "Sends an example message to sender",
            usage = "/example",
            min = 1,
            max = 5,
            onlyOp = false, // this option will ignore permission if it is set
            // be careful if you are using non-thread safe operations
            // and if you want to enable option below
            async = false,
            senderType = Command.SenderType.CONSOLE
    )
    public void exampleCommand(CommandArguments arguments) {
        // And here it's all done, you've created command with properties above!
        arguments.sendMessage("This is how you can create a example command using framework.");
    }
}

Creating Sub Command

Sub commands are separated by dots. For example if command is "one.two.three" then "one" will be the first part of the command, "two" is the second and "three" is the third. So the command will be "one two three <other arguments if there are>" and the command arguments will be splitted after sub commands like if the command is "one two three four five" then the command arguments will be [four, five].

    // Before creating command the method must only have
    // CommandArguments parameter and also @Command annotation
    @Command(
            name = "example.subcommand"
    )
    public void exampleSubCommandMethod(CommandArguments arguments) {
        // we've created a sub command named "example subcommand"
        // and now you can write your code here
    }
}

Creating Tab Completions

Before creating a tab completion, create a method body with List<String> return type or any other implementation of it but List is recommended and do not use the raw type. Then annotate the Completer and don't forget to add CommandArguments as a parameter to your method. Tab completions also support sub commands as the normal commands too. For example command's name can be "command.subcommand" and command will be "command subcommand <completions>"

    // Aliases don't need to be same as the target command's
    @Completer(
               name = "example",
               aliases = {"firstAlias", "secondAlias"}
    )
    public List<String> exampleCommandCompletion(CommandArguments arguments) {
        // and we've created a tab completion for the target command
        return Arrays.asList("first", "second", "third");
    }

Creating Commands Without Arguments

    @Command(
            name = "nocommandargs"
    )
    public void noCommandArgsTest() {
        Logger.getLogger(this.getClass().getSimpleName()).info("This command is running without any parameters.");
    }

Creating Commands With Cooldowns

public class ExampleClass extends JavaPlugin {

    // Don't forget to shade framework in to your project
    private CommandFramework commandFramework;

    @Override
    public void onEnable() {
        // Initialize the framework before using
        commandFramework = new CommandFramework(this);
        // Then this will register all the @Command methods as a command
        // so there is no necessity to add command to your plugin.yml
        commandFramework.registerCommands(this);
    }
	@Command(
		name = "test"
	)
	@Cooldown(
		cooldown = 10,
		timeUnit = TimeUnit.SECONDS, // default is seconds
		bypassPerm = "cooldown.bypass",
		overrideConsole = true
	)
	public void testCommand(CommandArguments arguments) {
		arguments.sendMessage("Test message.");
	}
}

Example Usage

public class ExampleClass extends JavaPlugin {

	@Override
	public void onEnable() {
		// Initialize the framework before using
		// Don't forget to shade framework in to your project
		CommandFramework commandFramework = new CommandFramework(this);
		// Adding custom parameters without @Param and @Default annotations.
		// Now all String type objects will return first argument.
		commandFramework.addCustomParameter("String", arguments -> arguments.getArgument(0));
		// Adding custom parameters to use with @Param and optionally with @Default annotations.
		commandFramework.addCustomParameter("secondAsInt", arguments -> arguments.getLength() > 1 ? arguments.getArgumentAsInt(1) : null);
		// Then this will register all the @Command methods as a command
		// so there is no necessity to add command to your plugin.yml
		commandFramework.registerCommands(this);
	}

	// Before creating command the method must only have
	// CommandArguments parameter and also @Command annotation
	@Command(
		name = "example",
		aliases = {"firstAlias", "secondAlias"},
		permission = "example.permission",
		desc = "Sends an example message to sender",
		usage = "/example",
		min = 1,
		max = 5,
		onlyOp = false, // this option will ignore permission if it is set
		// be careful if you are using non-thread safe operations
		// and if you want to enable option below
		async = false,
		senderType = Command.SenderType.CONSOLE
	)
	@Cooldown(
		cooldown = 10,
		timeUnit = TimeUnit.SECONDS,
		bypassPerm = "command.cooldownBypass",
		overrideConsole = true // console will now be affected by cooldown
	)
	public void exampleCommand(CommandArguments arguments) {
		// CommandArguments class contains basic things related Bukkit commands
		// And here it's all done, you've created command with properties above!
		arguments.sendMessage("This is how you can create a example command using framework.");
	}

	@Command(
		name = "noParams"
	)
	public void commandWithoutParameters() {
		Bukkit.getConsoleSender().sendMessage("This command is running without any parameters.");
	}

	@Command(
		name = "customParamWithoutAnnotations",
		min = 1
	)
	// See CommandFramework#addCustomParameter method above.
	public void customParamCommand(String firstParameter, CommandArguments arguments) {
		// CommandArguments parameter can be added to anywhere in method as a parameter.
		arguments.sendMessage("First parameter is " + firstParameter);
	}

	@Command(
		name = "customParams",
		min = 1
	)
	// If command is executed with only one argument then the default value will be accepted.
	// Otherwise, the given argument will be converted to specified type, in this case an int.
	// If parameter is not annotated by @Default then command will throw an exception on execution.
	// See the wiki page for creating custom parameters using @Param and @Default annotations.
	public void customParamsCommand(CommandArguments arguments,
									@Param("secondAsInt")
									@Default("50")
									int secondArg) {
		arguments.sendMessage("Second argument as integer is " + secondArg);
	}

	@Command(
		name = "confirmationTest"
	)
	@Confirmation(
		message = "Are you sure, if so, please execute command again to confirm.",
		expireAfter = 10,
		bypassPerm = "confirmation.bypass",
		timeUnit = TimeUnit.SECONDS,
		overrideConsole = true
	)
	public void confirmationCommand(CommandArguments arguments) {
		arguments.sendMessage("Confirmation successful.");
	}

	// Aliases don't need to be same with the command above
	@Completer(
		name = "example",
		aliases = {"firstAlias", "secondAlias"}
	)
	public List<String> exampleCommandCompletion(/*CommandArguments arguments*/ /*no need to use in this case which is also supported*/) {
		return Arrays.asList("first", "second", "third");
	}
}

Last updated