Skip to content

Instantly share code, notes, and snippets.

@dumptruckman
Last active January 24, 2023 17:22
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dumptruckman/6d5fb33b662ce91e2d232b22a19201d3 to your computer and use it in GitHub Desktop.
Save dumptruckman/6d5fb33b662ce91e2d232b22a19201d3 to your computer and use it in GitHub Desktop.
Simple Sub Commands
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin;
import java.util.HashMap;
import java.util.Map;
/**
* A simple class for implementing sub commands.
*
* Just register one of these as the executor for your plugin's root command and then register sub commands to this
* CommandBase with {@link #registerSubCommand(String, CommandExecutor)}.
*
* @param <P> The implementing plugin.
*/
public abstract class CommandBase<P extends Plugin> implements CommandExecutor {
private final Map<String, CommandExecutor> subCommands = new HashMap<>();
private final P plugin;
/**
* Creates a new CommandBase for the given plugin.
*
* @param plugin The plugin that owns this command.
*/
public CommandBase(P plugin) {
this.plugin = plugin;
}
/**
* Returns the plugin that owns this command.
*/
public P getPlugin() {
return plugin;
}
/**
* Registers a sub command to this command.
*
* @param label The label for the sub command.
* @param subCommand The sub command to register which can either be a plain CommandExecutor or another
* CommandBase if further command nesting is desired.
*/
public void registerSubCommand(String label, CommandExecutor subCommand) {
subCommands.put(label.toLowerCase(), subCommand);
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (args.length > 0) {
CommandExecutor child = subCommands.get(args[0].toLowerCase());
if (child != null) {
label = args[0];
String[] newArgs = new String[args.length - 1];
System.arraycopy(args, 1, newArgs, 0, newArgs.length);
return child.onCommand(sender, command, label, newArgs);
}
}
return runCommand(sender, command, label, args);
}
/**
* Executes the given commands and returns its success.
*
* Note that the success returned may propagate up to the root command.
*
* @param sender Source of the command.
* @param rootCommand The top level command that was executed.
* @param label Alias of the command that was used - the sub command label being used.
* @param args Arguments for the sub command.
* @return true if a valid command, false otherwise.
*/
public abstract boolean runCommand(CommandSender sender, Command rootCommand, String label, String[] args);
}
/*
* EXAMPLE USAGE
*/
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.java.JavaPlugin;
public class Example extends JavaPlugin {
@Override
public void onEnable() {
// Anonymous implementation of "/check" root command.
CommandBase<Example> checkCommand = new CommandBase<Example>(this) {
@Override
public boolean runCommand(CommandSender sender, Command rootCommand, String label, String[] args) {
sender.sendMessage("The root command does nothing! Use a sub command.");
return false;
}
};
CheckThisCommand checkThisCommand = new CheckThisCommand(this);
// Register "/check this" with the root "/check" command.
checkCommand.registerSubCommand("this", checkThisCommand);
// Register "/check this out" with the sub command "/check this".
checkThisCommand.registerSubCommand("out", new CheckThisOutCommand());
// Register "/check" command executor with Bukkit.
getCommand("check").setExecutor(checkCommand);
}
private static class CheckThisCommand extends CommandBase<Example> {
public CheckThisCommand(Example plugin) {
super(plugin);
}
@Override
public boolean runCommand(CommandSender sender, Command rootCommand, String label, String[] args) {
sender.sendMessage("I'm the first sub command. Fuck year!");
return true;
}
}
private static class CheckThisOutCommand implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
sender.sendMessage("I'm a leaf, get it?");
// returning false will cause the root commands description to be sent to the sender.
return false;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment