A cross-platform wrapper library for making Brigadier commands
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Go to file
William 072c8a1b88
feat: add `ExecutionScope`
6 months ago
.github feat: make x-plat command registering possible 6 months ago
bukkit fix: NPE fetching usage text 6 months ago
common feat: add `ExecutionScope` 6 months ago
example-plugin feat: add annotation-driven command system (#12) 6 months ago
fabric-1.20.1 feat: register aliases of Fabric commands 6 months ago
fabric-1.21 feat: target Fabric 1.21 6 months ago
gradle/wrapper refactor: redo layout, registration structure 6 months ago
images build: add CI, README, banner, metadata 6 months ago
paper fix: NPE fetching usage text 6 months ago
sponge-11 feat: add annotation-driven command system (#12) 6 months ago
velocity feat: add Permissions API for commands 6 months ago
.gitignore refactor: redo layout, registration structure 6 months ago
HEADER refactor: redo layout, registration structure 6 months ago
LICENSE Initial commit 7 months ago
README.md feat: add `ExecutionScope` 6 months ago
build.gradle feat: add Sponge 11 platform support 6 months ago
gradle.properties feat: add `ExecutionScope` 6 months ago
gradlew fix: make gradlew executable 6 months ago
gradlew.bat refactor: redo layout, registration structure 6 months ago
settings.gradle feat: add Sponge 11 platform support 6 months ago

README.md

Claim Operations Library


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).

Uniform Version Table
Platform Artifact Minecraft ver. Java ver. Uniform ver.
Common uniform-common N/A 17
Supported Platforms
Bukkit / Spigot uniform-bukkit 1.17.1 17
Paper uniform-paper
Velocity (3.3.0) uniform-velocity 1.8.9
Sponge (api 11) uniform-sponge =1.20.6 21
Fabric (1.20.1) uniform-fabric =1.20.1
Fabric (1.21) =1.21
Formerly Supported Platforms
Fabric (1.20.6) uniform-fabric =1.20.6 21 v1.1.8

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.

Gradle setup instructions

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.