Command Nodes - LilBroCodes/commander GitHub Wiki

Command Nodes

Command nodes are the building blocks of your command structure in Commander. This page explains the different types of nodes available and how to use them effectively.

Node Hierarchy

All command nodes in Commander extend the abstract ExecutorNode<T> class, which provides common functionality like:

  • Name and description management
  • Permission handling
  • Basic execution and tab completion interfaces

From this base class, Commander provides three specialized node types:

  1. CommandGroupNode - For organizing subcommands
  2. CommandActionNode - For executing commands with parameters
  3. CommandHybridNode - A combination that can both execute and contain subcommands

CommandGroupNode

CommandGroupNode is used to create command categories and organize subcommands. It doesn't execute any command logic itself but delegates to its child nodes.

Creating a CommandGroupNode

CommandGroupNode rootNode = new CommandGroupNode(
    "mycommand",      // Command name
    "My command",     // Description
    "MyPlugin"        // Plugin name
);

Adding Child Nodes

// Create child nodes
CommandActionNode subCommand1 = new CommandActionNode(...);
CommandGroupNode subCommand2 = new CommandGroupNode(...);

// Add them to the parent
rootNode.addChild(subCommand1);
rootNode.addChild(subCommand2);

Behavior

When a user executes a command that corresponds to a CommandGroupNode:

  1. Commander checks if any arguments were provided
  2. If no arguments were provided, it displays an error message
  3. If arguments were provided, it looks for a child node with a matching name
  4. If a matching child is found, it delegates execution to that child
  5. If no matching child is found, it displays an error message

CommandActionNode

CommandActionNode is used for executable commands with typed parameters. It parses and validates the provided arguments, then executes the command logic.

Creating a CommandActionNode

// Define parameters
List<TypedParameter> parameters = List.of(
    new TypedParameter("player", ParameterType.STRING),
    new TypedParameter("amount", ParameterType.INT)
);

// Create the node
CommandActionNode actionNode = new CommandActionNode(
    "give",            // Command name
    "Give items",      // Description
    "MyPlugin",        // Plugin name
    parameters,        // Parameter definitions
    (sender, args) -> {
        // Command logic
        String playerName = (String) args.get(0);
        int amount = (int) args.get(1);
        
        // Do something with the parameters
        sender.sendMessage("Giving " + amount + " items to " + playerName);
    }
);

Behavior

When a user executes a command that corresponds to a CommandActionNode:

  1. Commander checks if the correct number of arguments were provided
  2. It attempts to parse each argument according to its expected type
  3. If parsing fails, it displays an appropriate error message
  4. If parsing succeeds, it executes the command logic with the parsed values

CommandHybridNode

CommandHybridNode is a combination of both CommandGroupNode and CommandActionNode. It can both execute command logic and contain child nodes.

Creating a CommandHybridNode

// Create the node
CommandHybridNode hybridNode = new CommandHybridNode(
    "home",            // Command name
    "Home commands",   // Description
    "MyPlugin",        // Plugin name
    (sender, args) -> {
        // Command logic when no subcommand is provided
        sender.sendMessage("Teleporting to your default home");
        // Teleport logic here
    }
);

// Add child nodes
CommandActionNode setHomeNode = new CommandActionNode(...);
hybridNode.addChild(setHomeNode);

Behavior

When a user executes a command that corresponds to a CommandHybridNode:

  1. Commander checks if any arguments were provided
  2. If no arguments were provided, it executes the node's command logic
  3. If arguments were provided, it behaves like a CommandGroupNode and looks for a matching child node

Common Node Methods

All node types inherit these methods from ExecutorNode<T>:

  • getName() - Gets the node's name
  • getDescription() - Gets the node's description
  • getPluginName() - Gets the plugin name
  • getPermission() - Gets the node's permission
  • setPermission(String) - Sets the node's permission
  • withPermission(String) - Sets the permission and returns the node for chaining
  • hasPermission(CommandSender) - Checks if a sender has permission to use this node

Best Practices

Organizing Commands

  • Use CommandGroupNode for categories and organization
  • Keep your command tree balanced and intuitive
  • Use descriptive names and helpful descriptions
  • Consider using CommandHybridNode for commands that have both a default action and subcommands

Permissions

  • Set appropriate permissions for each node
  • Use a consistent permission naming scheme
  • Consider using permission hierarchies (e.g., myplugin.admin.*)

Examples

Simple Command with Subcommands

// Root command
CommandGroupNode rootNode = new CommandGroupNode(
    "myplugin",
    "MyPlugin commands",
    "MyPlugin"
);

// Help subcommand (automatically provided by Commander)

// Version subcommand
CommandActionNode versionNode = new CommandActionNode(
    "version",
    "Show plugin version",
    "MyPlugin",
    List.of(),
    (sender, args) -> {
        sender.sendMessage("MyPlugin version 1.0.0");
    }
);

rootNode.addChild(versionNode);

Command with Parameters and Tab Completion

// Define parameters with tab completion
List<TypedParameter> parameters = List.of(
    new TypedParameter("player", ParameterType.STRING, () -> {
        // Return a list of online player names for tab completion
        return Bukkit.getOnlinePlayers().stream()
            .map(Player::getName)
            .collect(Collectors.toList());
    }),
    new TypedParameter("amount", ParameterType.INT)
);

// Create the command
CommandActionNode giveNode = new CommandActionNode(
    "give",
    "Give items to a player",
    "MyPlugin",
    parameters,
    (sender, args) -> {
        String playerName = (String) args.get(0);
        int amount = (int) args.get(1);
        
        // Command logic
    }
);

Next Steps

Now that you understand command nodes, check out these pages for more information: