Skip to main content

Commands

About Commands

Commands in Zora are utilised through the Cloud Command Framework. This framework allows for easy creation of commands through annotations.

We use this system alongside some of our own magic to make it exceptionally easy to create commands.

A note on design practices

The Zora command system expects all commands to be grouped under one package tree. In other words, it's best to avoid mixing commands with features, database models etc. and instead keep them in their own seperate and isolated environment.

Creating a Command

A Zora command is created by creating a class that implements the ZoraCommand interface. This interface makes the Zora runtime aware of your command, allowing it to be registered. It also allows very easy access to other subsystems within Zora, such as the Configuration System, the Database Driver, the Message System and the Effects System.

The command system within Zora is intentionally lightweight. By default, Zora does not provide any argument parsing or additional features on top of what is provided by the default Cloud Command Framework. This is to allow developers to build their systems to their own specifications and use cases.

Note that any methods annotated with @CommandMethod must be public, and will be automatically registered (see below) by the Zora runtime. Your IDE will likely provide a warning that the method is unused, but this can be ignored safely.

Example Command

import ltd.redeye.zora.commands.ZoraCommand;

class ExampleCommand implements ZoraCommand {
@CommandMethod("myplugin echo <message>")
public void exampleCommand(CommandSender sender, @Argument("message") @Greedy String message) {
TagResolver resolver = zora().messages().simpleResolver("message", message);
zora().messages().sendMini(sender, "<green>Message: <message>", resolver);
}

@CommandMethod("myplugin ping <player>")
public void exampleCommand(CommandSender sender, @Argument("player") Player player) {
TagResolver resolver = zora().messages().simpleResolver("player", player, "sender", sender);
zora().messages().sendMini(sender, "<green>You pinged <white><player></white>!", resolver);
zora().messages().sendMini(player, "<green>You were pinged by <white><sender></white>!", resolver);
}
}

Utility Methods

The ZoraCommand interface provides several utility methods which can be used to access other Zora subsystems. To access these, simply call the method zora(), followed by any of the following methods:

  • logger() - Returns the SLF4J logger for your plugin.
  • config() - Returns the configuration system for your plugin.
  • database() - Returns the database driver for your plugin.
  • messages() - Returns the message system for your plugin.
  • effects() - Returns the effects system for your plugin.

For example, to access the configuration system, you would use zora().config(). This is abstracted behing the zora() method to prevent overlaps or method name clashes with your own plugin.

Registering Commands

Commands are registered by enabling the command system within the init method of your plugin. Command registration uses reflection to find and map all commands within your plugin. This means that you do not need to manually register commands, and can instead focus on writing them.

In this example, we will register all commands within the com.example.myplugin.commands package, which has the command /myplugin help to list all commands and also allows the type Example to be used within command types.

public class MyPlugin extends ZoraPlugin {
public void init() {
this.commandSystem()
// Register all commands within this package
.registerCommands("com.example.myplugin.commands")
// Set the help command to be /myplugin help. This is optional.
.useHelpCommand("myplugin help")
// Register an argument parser. This method can be used multiple times.
.argumentParser(ExampleArgument.class, new ExampleArgumentParser())
// Construct the command system
.initialise();
}
}

Command Trees (advanced)

All Zora plugins share a single command tree. The rationale behind this is to enable plugins to be able to share a root command.

Let's take an example of a server which has a Zora ban plugin, and a Zora economy plugin. Two commands could be registered in two separate plugins, /zora ban and /zora eco. This would allow server operators to have a single administrative interface, and not get lost trying to find the command for a specific plugin.

Further, this allows for arguments to be shared between plugins -- Zora will ensure there are no namespace clashes within the argument parser registry.

The /zora Command

Zora provides a single command, /zora, which is used to debug and manage the Zora runtime. This command has the permission zora.framework.admin and can be used to see which plugins have successfully initialised with the Zora runtime, and view command trees of specific plugins. Type /zora help for more information in-game.