commodore
commodore is a utility for using Minecraft's 1.13 brigadier library in Bukkit plugins. It allows you to easily register command completion data for your plugin's commands.
If you have questions, feel free to ask in Discord.
Example
Approaches to registering completion data
commodore supports:
- Registering completions using brigadier's
LiteralCommandNode
builder API - Registering completions using commodore's
.commodore
file format
For example, implementing completions for Minecraft's /time
command:
LiteralCommandNode
builder API
Using brigadier's LiteralCommandNode<?> timeCommand = LiteralArgumentBuilder.literal("time")
.then(LiteralArgumentBuilder.literal("set")
.then(LiteralArgumentBuilder.literal("day"))
.then(LiteralArgumentBuilder.literal("noon"))
.then(LiteralArgumentBuilder.literal("night"))
.then(LiteralArgumentBuilder.literal("midnight"))
.then(RequiredArgumentBuilder.argument("time", IntegerArgumentType.integer())))
.then(LiteralArgumentBuilder.literal("add")
.then(RequiredArgumentBuilder.argument("time", IntegerArgumentType.integer())))
.then(LiteralArgumentBuilder.literal("query")
.then(LiteralArgumentBuilder.literal("daytime"))
.then(LiteralArgumentBuilder.literal("gametime"))
.then(LiteralArgumentBuilder.literal("day"))
).build();
commodore.register(bukkitCommand, timeCommand);
.commodore
file format
Using commodore's time {
set {
day;
noon;
night;
midnight;
time brigadier:integer;
}
add {
time brigadier:integer;
}
query {
daytime;
gametime;
day;
}
}
// assuming the file above is stored as "time.commodore" in the plugin jar
LiteralCommandNode<?> timeCommand = CommodoreFileFormat.parse(plugin.getResource("time.commodore"));
commodore.register(bukkitCommand, timeCommand);
Using the .commodore
file format is recommended. In my opinion it is much easier to read/understand/update than the Node Builder API provided by brigadier.
Another example of a .commodore
file can be found here, for the LuckPerms plugin commands. The corresponding code used to register the completions is here.
Usage
This guide assumes your plugin is built using Maven or Gradle though.
1) Configure your build script to shade commodore into your plugin jar
Maven
You need to add (or merge) the following sections into your pom.xml
file.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>me.lucko:commodore</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>me.lucko.commodore</pattern>
<!-- vvv Replace with the package of your plugin vvv -->
<shadedPattern>com.yourdomain.yourplugin.commodore</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>me.lucko</groupId>
<artifactId>commodore</artifactId>
<!-- vvv Replace with the latest commodore version vvv -->
<version>{version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>minecraft-repo</id>
<url>https://libraries.minecraft.net/</url>
</repository>
</repositories>
Gradle
You need to add (or merge) the following sections into your build.gradle
file.
plugins {
id 'com.github.johnrengelman.shadow' version '6.1.0'
}
repositories {
mavenCentral()
maven { url 'https://libraries.minecraft.net/' }
}
dependencies {
/* vvv Replace with the latest commodore version vvv */
implementation 'me.lucko:commodore:{version}'
}
shadowJar {
dependencies {
exclude(dependency('com.mojang:brigadier'))
}
/* vvv Replace with the package of your plugin vvv */
relocate 'me.lucko.commodore', 'com.yourdomain.yourplugin.commodore'
}
Replace {version}
with the latest version:
2) Setup commodore in your plugin
package me.lucko.example;
import com.mojang.brigadier.arguments.BoolArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import me.lucko.commodore.Commodore;
import me.lucko.commodore.CommodoreProvider;
import org.bukkit.command.PluginCommand;
import org.bukkit.plugin.java.JavaPlugin;
public class TestPlugin extends JavaPlugin {
@Override
public void onEnable() {
// register your command executor as normal.
PluginCommand command = getCommand("mycommand");
command.setExecutor(new MyCommandExecutor());
// check if brigadier is supported
if (CommodoreProvider.isSupported()) {
// get a commodore instance
Commodore commodore = CommodoreProvider.getCommodore(this);
// register your completions.
registerCompletions(commodore, command);
}
}
// You will need to put this method inside another class to prevent classloading
// errors when your plugin loads on pre 1.13 versions.
private static void registerCompletions(Commodore commodore, PluginCommand command) {
commodore.register(command, LiteralArgumentBuilder.literal("mycommand")
.then(RequiredArgumentBuilder.argument("some-argument", StringArgumentType.string()))
.then(RequiredArgumentBuilder.argument("some-other-argument", BoolArgumentType.bool()))
);
}
}
The com.mojang.brigadier
packages will be automatically imported into your classpath when you add the commodore dependency, but they should not be shaded into your plugins jar file.