Skip to content

Repository files navigation

CommandRoute


A lightweight library that provides a modern command tree for Nukkit-MOT

Should I use CommandRoute?

It depends on what you're building.

  • If you're building a command with many subcommands and executors, CommandRoute is a great choice.
  • If you're building a simple, small command, the legacy command API is probably enough.

Installation


Add JitPack to your repositories:

repositories {
    maven("https://jitpack.io")
}

Add the dependency:

dependencies {
    implementation("com.github.Kanelucky:CommandRoute:0.1.0")
}

Usage


public class TestCommand extends BaseCommand {
    public TestCommand() {
        super("mycommand", "TestCommand", "/mycommand");
        this.enableCommandTree();
    }

    @Override
    protected void buildCommandTree(RouteTree tree) {
        tree.getRoot()
            .then(RouteNode.literal("info")
                    .permission("mycommand.info", "LOL")
                           .exec(context -> {
                               context.getSender().sendMessage("CommandRoute!");
                               return CommandResult.success();
        }));
        tree.getRoot()
            .then(RouteNode.literal("send")
                           .then(RouteNode.argument("player", new PlayersArgument())
                                          .then(RouteNode.argument("message", new StringArgument())
                                                  .suggest(List.of("i", "forgot"))
                                                         .exec(context -> {
                                                             // Extract arguments by name
                                                             List<Player> players = context.getArg("player");
                                                             String msg = context.getArg("message");
                                                             for (Player player : players) {
                                                                 player.sendMessage(msg);
                                                             }
                                                             return CommandResult.success();
                                                         }))));
        tree.getRoot()
                .then(RouteNode.literal("give")
                        .then(RouteNode.argument("player", new PlayersArgument())
                                .then(RouteNode.argument("item", new ItemArgument())
                                        .exec(ctx-> {
                                            Item items = ctx.getArg("item");
                                            List<Player> players = ctx.getArg("player");
                                            for (Player player : players) {
                                                player.giveItem(items);
                                            }
                                            return CommandResult.success();
                                        }))));
    }
}

Building Routes (RouteNode options)

The RouteNode class provides a builder-like pattern to construct routing nodes:

RouteNode.literal(String name): Matches a fixed keyword/subcommand name in the argument chain (e.g. /mycommand ban).

RouteNode.argument(String name, ArgumentType<?> argument): Matches a typed input argument (e.g. PlayersArgument(), IntegerArgument(), ItemArgument()).

.then(RouteNode child): Chains a sub-node/argument after the current node.

.exec(Function<CommandContext, CommandResult> executor): Marks the node as executable. If player input ends at this node, this block executes.

.senderType(SenderType senderType): Restricts execution to specific senders (SenderType.PLAYER, SenderType.CONSOLE, or SenderType.ANY).

.permission(String permission): Restricts execution to players with the specified permission.

.permission(String permission, String message): Restricts execution to players with the specified permission and sends the given message if access is denied.

.optional(boolean optional): Marks the node parameter as optional.

.suggest(List<String> customList): Overrides client tab-complete suggestions with a custom list.

.suggest(boolean visible): Enables or disables client tab completion.

Execution Results (CommandResult)

Your route executors must return a CommandResult:

CommandResult.success(): Indicates successful execution.

CommandResult.fail(): Indicates command failure.

CommandResult.fail("Error message"): Fails the command and automatically sends the specified error message to the command sender.

Arguments

CommandRoute currently provides 4 built-in argument types:

  • IntegerArgument
  • ItemArgument
  • PlayersArgument
  • StringArgument

If you need additional argument types, you can create your own by implementing ArgumentType<T> or EnumArgumentType<T>.

public class ExampleArgument implements ArgumentType<Entity> {

    @Override
    public Entity parse(CommandContext context, String[] args, int index) {
        if (index >= args.length) {
            throw new IllegalArgumentException("Missing entity argument.");
        }

        String input = args[index];

        Entity entity = context.getSender()
                .getServer()
                .getPlayerExact(input);

        if (entity == null) {
            throw new IllegalArgumentException("Entity not found: " + input);
        }

        return entity;
    }

    @Override
    public CommandParamType getNetworkType() {
        return CommandParamType.TARGET;
    }
}

Note!

  • ArgumentType<T> is used for arguments that accept arbitrary input and parse it into an object.
  • EnumArgumentType<T> is used for arguments with predefined values, providing automatic Bedrock tab completion and client-side validation.

License

This project is licensed under MIT License. Please see the LICENSE file for details.

Credit

About

A lightweight library that provides a modern command tree for Nukkit-MOT

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages