Uniform

A cross-platform wrapper library for making Brigadier commands

GPL-3.0 License

Stars
3
Committers
4

Uniform is cross-platform wrapper for making Brigadier commands, based on BrigadierWrapper by Tofaa2, which itself was inspired by EmortalMC's command-system.

Compatibility

Versions are available on maven in the format net.william278.uniform:ARTIFACT:VERSION. See below for a table of supported platforms.

Note that Uniform versions omit the v prefix. Fabric versions are suffixed with the target Minecraft version (e.g. 1.2.1+1.21) and also require Fabric API installed on the server. Sponge versions are suffixed with the target Sponge API version (e.g. 1.2.1+11).

Example: To target Uniform on Bukkit, the artifact is net.william278.uniform:uniform-bukkit:1.2.1 (check that this version is up-to-date – make sure you target the latest available!).

Setup

Uniform is available on Maven. You can browse the Javadocs here.

First, add the Maven repository to your build.gradle file:

repositories {
    maven { url "https://repo.william278.net/releases" }
}

Then, add the dependency itself. Replace VERSION with the latest release version. (e.g., 1.2.1) and PLATFORM with the platform you are targeting (e.g., paper). If you want to target pre-release "snapshot" versions (not recommended), you should use the /snapshots repository instead.

dependencies {
    implementation "net.william278.uniform:uniform-PLATFORM:VERSION"
}

Using Maven/something else? There's instructions on how to include Uniform on the repo browser.

Basic use

Uniform lets you create commands either natively per-platform, or cross-platform (by compiling against uniform-common in a common module, then implementing uniform-PLATFORM in each platform, getting the platform specific Uniform manager instance and registering your commands).

Check example-plugin for a full example of a cross-platform command being registered on Paper.

Cross-platform commands

Cross-platform commands can be created by registering Command objects; you can create these from @CommandNode annotated objects, or by extending Command and providing these yourself.

Using annotations

You can use the @CommandNode annotations to easily create cross-platform Brigadier commands (since: v1.2). This is the recommended way to create commands.

@CommandNode(
        value = "helloworld",
        aliases = {"hello", "hi"},
        description = "A simple hello world command",
        permission = @PermissionNode(
                value = "example.command.helloworld",
                defaultValue = Permission.Default.TRUE
        )
)
public class AnnotatedCommand {

    @Syntax
    public void execute(CommandUser user) {
        user.getAudience().sendMessage(Component.text("Hello, world!"));
    }

    @Syntax
    public void pongMessage(
            CommandUser user,
            @Argument(name = "message", parser = Argument.StringArg.class) String message
    ) {
        user.getAudience().sendMessage(Component.text("Hello, " + message, NamedTextColor.GREEN));
    }
    
    @CommandNode(
            value = "subcommand",
            aliases = {"sub", "hi"}
    )
    static class SubCommand {
        @Syntax
        public void execute(CommandUser user) {
            user.getAudience().sendMessage(Component.text("Subcommand executed!"));
        }
    }

}

By extending the Command class.

You can also extend the Command class to create a Command object you can register. You'll want to use BaseCommand#getUser to get a platform-agnostic User from which you can acquire the adventure Audience to send messages to.

public class ExampleCrossPlatCommand extends Command {
    public ExampleCrossPlatCommand() {
        super("example", "cross-platform");
    }

    @Override
    public <S> void provide(@NotNull BaseCommand<S> command) {
        // What gets executed when no args are passed. 
        // For tidiness, feel free to delegate this stuff to methods!
        command.setDefaultExecutor((context) -> {
            // Use command.getUser(context.getSource()) to get the user
            final Audience user = command.getUser(context.getSource()).getAudience();
            user.sendMessage(Component.text("Hello, world!"));
        });

        // Add syntax to the command
        command.addSyntax((context) -> {
            final Audience user = command.getUser(ctx.getSource()).getAudience();
            user.sendMessage(Component.text("Woah!!!!"));
            String arg = context.getArgument("message", String.class);
            user.sendMessage(MiniMessage.miniMessage().deserialize(arg));
        }, stringArg("message"));

        // Sub-commands, too
        command.addSubCommand("subcommand", (sub) -> {
            sub.setDefaultExecutor((context) -> {
                final Audience user = sub.getUser(context.getSource()).getAudience();
                user.sendMessage(Component.text("Subcommand executed!"));
            });
        });
    }
}

Platform-specific commands

If you need platform-specific features, extend the platform-specific PlatformCommand class and add your Brigadier syntax.

public class ExampleCommand extends PaperCommand {
    public ExampleCommand() {
        super("example", "platform-specific");
        command.setDefaultExecutor((context) -> {
            context.getSource().getBukkitSender().sendMessage("Hello, world!");
        });
        addSyntax((context) -> {
            context.getSource().getBukkitSender().sendMessage("Woah!!!!");
            String arg = context.getArgument("message", String.class);
            context.getSource().getBukkitSender()
                .sendMessage(MiniMessage.miniMessage().deserialize(arg));
        }, stringArg("message"));
    }
}

Registering

Then, register the command with the platform-specific Uniform instance (e.g. FabricUniform.getInstance(), PaperUniform.getInstance(), etc...)

Building

To build Uniform, run clean build in the root directory. The output JARs will be in target/.

License

Uniform is licensed under GPL v3 as it derives from BrigadierWrapper. See LICENSE for more information.