API
Maven¶
Add the following repository to your pom.xml
<!-- Bundabrg's Repo -->
<repository>
<id>bundabrg-repo</id>
<url>https://repo.worldguard.com.au/repository/maven-public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
Bukkit/Spigot/Paper¶
<dependency>
<groupId>au.com.grieve.bcf</groupId>
<artifactId>bukkit</artifactId>
<version>1.4.1</version>
</dependency>
Bungeecord¶
<dependency>
<groupId>au.com.grieve.bcf</groupId>
<artifactId>bungeecord</artifactId>
<version>1.4.1</version>
</dependency>
Standalone¶
<dependency>
<groupId>au.com.grieve.bcf</groupId>
<artifactId>terminalconsole</artifactId>
<version>1.4.1</version>
</dependency>
Note
Don't forget to check what the latest verison is as these documents may be out of date.
Shade the library into your own code by adding in your pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<relocations>
<relocation>
<pattern>au.com.grieve.bcf</pattern>
<shadedPattern>${project.groupId}.${project.artifactId}.bcf</shadedPattern>
</relocation>
</relocations>
</configuration>
</plugin>
</plugins>
</build>
Command Class¶
To create a command extend from an appropriate BaseCommand class and annotate with @Command. For a Bukkit plugin use BukkitCommand
, Bungeecord
uses BungeeCommand
and Standalone Console uses TerminalCommand
.
Example
@Command("mycmd")
public class MainCommand extends BukkitCommand {
@Arg("list")
public void doList(CommandSender sender) {
sender.spigot().sendMessage(
new ComponentBuilder("Reached List").color(ChatColor.GREEN).create()
);
}
}
You can of course (and are encouraged) to break out your Command classes into multiple groups of commands and then combine them as subcommands of one primary Command This can also be an effective way to allow 3rd parties to add commands under your plugin.
Command Manager¶
Bukkit/Bungeecord¶
During your plugin initialization you need to setup a new Command Manager instance. For Bukkit
use a BukkitCommandManager
, for Bungeecord use BungeeCommandManager
, passing your own plugin as a parameter.
Then register each of your Command classes with the manager, passing the class type as a parameter. You can also
register sub commands of another class by using registerSubCommand
. You use the class of the command you are creating
a subcommand underneath.
Example
public final class MyPlugin extends JavaPlugin {
@Getter
private BukkitCommandManager bcf;
@Override
public void onEnable() {
// Setup Command Manager
bcf = new BukkitCommandManager(this);
// Register Commands
bcf.registerCommand(new MainCommand());
// Register Subcommands
bcf.registerSubCommand(MainCommand.class, new MySubCommand());
bcf.registerSubCommand(MainCommand.class, new MyOtherSubCommand());
bcf.registerSubCommand(MyOtherSubCommand.class, new MySubSubCommand());
}
}
Standalone¶
First you need to extend TerminalConsole
to define how your console works. You can change up completions are done
by modifying the buildReader
method. In the example below it uses TailTipsWidgets, part of jline-console
to display
fancy auto-completions.
Example
public class MyConsole extends TerminalConsole {
@Override
protected boolean isRunning() {
return true;
}
@Override
protected void shutdown() {
}
@Override
protected LineReader buildReader(LineReaderBuilder builder) {
LineReader reader = super.buildReader(builder);
Map<String, CmdDesc> tailTips = new HashMap<>();
TailTipWidgets widgets = new TailTipWidgets(reader, tailTips);
widgets.enable();
return reader;
}
}
In your main function instantiate the above class and pass it as a parameter to TerminalManager
to add
command completion.
Then register each of your Command classes with the manager, passing the class type as a parameter. You can also
register sub commands of another class by using registerSubCommand
. You use the class of the command you are creating
a subcommand underneath.
You then execute the start
method on your TerminalConsole class which will not return until it is shut down or the
user breaks out.
Example
public class Standalone {
public static void main(String[] args) {
MyConsle console = new MyConsole();
TerminalCommandManager bcf = new TerminalCommandManager(console);
// Register Commands
bcf.registerCommand(new MainCommand());
// Register Subcommands
bcf.registerSubCommand(MainCommand.class, new MySubCommand());
bcf.registerSubCommand(MainCommand.class, new MyOtherSubCommand());
bcf.registerSubCommand(MyOtherSubCommand.class, new MySubSubCommand());
// Listen forever
console.start();
}
}
Parser¶
You may wish to add your own custom parser. Either the built-in ones are not sufficient, or you have some custom arguments that need to be parsed in a special way.
Note
If you do write a Parser that may be useful to others then please to send a PR to have it included as a built-in type. `
A parser can be though of as having the following attributes:
-
It will be provided a list of input words available to it at its position in the
@Arg
command string and must consume 0 or more of them. -
If possible it should be able to use partial input to provide command completion
-
It should be able to validate its input and return a concrete object
A custom parser should extend Parser
or a class derived from this.
The parser is registered by calling the registerParser
method on the CommandManager
and from that point its name
prefixed with @
can be used in an @Arg
string.
Example
bcf.registerParser("myparser", MyParser.class);
Overrides¶
The three important methods to provide are:
-
parse
- Consume input words -
compete
- Return list of completions for the input -
result
- Return a concrete object for the input
parse¶
Definition
public void parse(List<String> input, boolean defaults) throws ParserRequiredArgumentException {
...
}
Provided a list of words from input available at this parsers point in the @Arg
string. Any input
for this parser must be removed from the head of the list with any remaining items being available
for the calling process.
If defaults
is set to false
then no action that forgives missing input should be allowed. This means
even if a default is set missing input should cause an error.
Any required input that is missing (and not provided another way like through a default
parameter) must
throw a ParserRequiredArgumentException
Important
As most Parsers only consume 1 input a custom parser that also only consumes 1 input should extend
SingleParser
which handles this method for you. Make use of getInput()
to get the consumed
input.
complete¶
Definition
protected List<String> complete() {
...
}
Return a list of completions for the consumed input ideally filtering it by what has been entered and limiting it to a maximum of 20 items. If no completions are available then return an empty list.
The results are cached.
result¶
Definition
protected Object result() throws ParserInvalidResultException {
...
}
Return a concrete Object for the input consumed. If there is no valid result for the input then
this must throw a ParserInvalidResultException
which will cause it to be rejected as a valid
command candidate.
The results are cached.