This library allows you to use the PicoCLI command framework with Minecraft Forge.
Add this to your dependencies in build.gradle
:
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
compile 'com.github.Rubydesic:MinecraftPicocli:master-SNAPSHOT'
}
To start, make a PicoCLI command. For example, a very basic echo command might look like this:
@Command(name = "command", aliases = {"cmd", "mycommand"})
public class MyCommand implements Runnable {
@Inject
ICommandSender sender;
@Parameters(index = "0")
String echo;
@Override
public void run() {
sender.sendMessage(new TextComponentString("You said " + echo));
}
}
Now, simply register your command as you would any other using the FMLServerStartingEvent
@EventHandler
public void onServerStart(FMLServerStartingEvent event) {
ServerCommandManager manager =
(ServerCommandManager) event.getServer().getCommandManager();
manager.registerCommand(new PicocliCommandBase<>(MyCommand.class));
}
Try out your command:
/command "hello there, buddy"
> You said hello there buddy
Let's say you want to autocomplete a player name. First, you'll need an autocompletion class that implements Iterable<String>
:
public class AutocompleterPlayername implements Iterable<String> {
@Inject
ICommandSender sender;
@Override
public Iterator<String> iterator() {
return sender.playerEntities // List<EntityPlayer>
.stream() // Stream<EntityPlayer>
.map(EntityPlayer::getName) // Stream<String>
.iterator(); // Iterator<String>
}
}
Perfect. Here's how you use this autocompletion class in your command so that the playerName
parameter is autocompleted:
@Command(name = "isplayeronground")
public class MyCommand implements Runnable {
@Inject
ICommandSender sender;
@Parameters(index = "0", completionCandidates = AutocompleterPlayername.class)
String playerName;
@Override
public void run() {
EntityPlayer player = sender.getEntityWorld().getPlayerEntityByName(playerName);
sender.sendMessage(new TextComponentString(player.onGround ? "Yes" : "No"));
}
}
Try it out:
/isplayeronground Rub<tab>
/isplayeronground Rubydesic
> Yes
Every class constructed by PicoCLI (autocompletion classes, converter classes, command classes) will have the ICommandSender
associated with it passed in two different ways.
-
Constructor injection
public class MyCommandOrConverterOrWhatever { ICommandSender sender; MyCommandOrConverterOrWhatever(ICommandSender sender) { this.sender = sender; } }
-
Field injection using @Inject annotation
public class MyCommandOrConverterOrWhatever { @Inject ICommandSender sender; }
NOTE: The constructor is called BEFORE the field injection is performed