Uniform is cross-platform wrapper for making Brigadier commands, based on BrigadierWrapper
by Tofaa2, which itself was inspired by EmortalMC's command-system
.
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!).
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.
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 can be created by registering Command
objects; you can create these from @CommandNode
annotated objects, or by extending Command
and providing these yourself.
You can use the @CommandNode
annotations to easily create cross-platform Brigadier commands (since: v1.2). This is the recommended way to create commands.
This is useful for creating commands with not so many subcommands and arguments.
@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!"));
}
}
}
You can use the builder available for paper and fabric (PaperCommand and FabricCommand) to create commands This is mostly useful for creating commands with many subcommands and arguments
public class WhicheverClass {
public PaperCommand getBuiltCommand() {
return PaperCommand.builder("helloworld")
.setDescription("A simple hello world command")
.setAliases(List.of("hello", "hi"))
.setPermission(new Permission("example.command.helloworld", Permission.Default.TRUE))
.addSubCommand(messageSubCommand())
.build();
}
private PaperCommand messageSubCommand() {
return PaperCommand.builder("message")
.setDescription("Echoes message")
.addStringArgument("message", ((commandContext, suggestionsBuilder) -> {
//Here is for suggestions but you can skip this part
return suggestionsBuilder.suggest("Message content...").buildFuture();
}))
.execute(commandContext -> {
String message = commandContext.getArgument("message", String.class);
commandContext.getSource().getSender()
.sendMessage(Component.text("Hello, " + message, NamedTextColor.GREEN));
}, "message") //Specify the arguments used in the correct order
.execute(commandContext -> {
commandContext.getSource().getSender().sendMessage("Missing argument 'message'");
})
.build();
}
}
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!"));
});
});
}
}
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"));
}
}
Then, register the command with the platform-specific Uniform instance (e.g. FabricUniform.getInstance()
, PaperUniform.getInstance()
, etc...)
To build Uniform, run clean build
in the root directory. The output JARs will be in target/
.
Uniform is licensed under GPL v3 as it derives from BrigadierWrapper. See LICENSE for more information.