Here is a simple command handling system that i am going to use in my latest release of pushball. Note, this is not tested so please post below the error or even better a fix if there is an error. Also if im doing something wrong tell me! Command.java Code: package me.sothatsit.pushball.cmd; import java.util.Arrays; import java.util.List; import java.util.ArrayList; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; public class Command{ private String permission; private Handler noPermHandler; private Handler runHandler; private List<String> commandLabels; private List<Command> subCommands; private Command superCommand; public Command(String... commandLabels){ this.commandLabels = new ArrayList<String>(Arrays.asList(commandLabels)); this.subCommands = new ArrayList<Command>(); this.permission = null; this.noPermHandler= null; this.runHandler = null; this.superCommand = null; } //Getters and Setters public void addSubCommand(Command command){this.subCommands.add(command);command.setSuperCommand(this);} public void setPermHanlder(Handler permHandler){this.noPermHandler=permHandler;} public void setRunHandler(Handler runHandler){this.runHandler=runHandler;} public void setPerm(String permission){this.permission=permission;} public void setSuperCommand(Command superCommand){this.superCommand=superCommand;} public Command getSuperCommand(){return superCommand;} public List<String> getLabels(){return commandLabels;} public String getLabel(){if(getLabels().size()>0)return getLabels().get(0);else return "";} public boolean isCommand(String label){ for(String l : commandLabels){ if(l.equalsIgnoreCase(label))return true; } return false; } public boolean checkPerms(CommandSender sender, String[] args){ if(permission == null)return true; else{ if(noPermHandler != null)noPermHandler.run(sender, args); return sender.hasPermission(permission); } } //Run Command method public void run(CommandSender sender, String[] args){ if(checkPerms(sender, args)){ boolean found = false; if(args.length > 0){ for(Command c : subCommands){ if(c.isCommand(args[0])){ c.run(sender, Arrays.copyOfRange(args, 1, args.length)); found = true; } } } if(runHandler != null)runHandler.run(sender, args); else if(!found && subCommands.size() > 0){ String message = this.getLabel()+" "; Command cmd = this; while(cmd.getSuperCommand() != null){ message = cmd.getSuperCommand().getLabel() + " " + message; cmd = cmd.getSuperCommand(); } message = message + "["; for(int i=0; i<subCommands.size(); i++){ Command command = subCommands.get(i); message = message + (i!=0 ? ", " : "") + command.getLabel(); } message = message + "]"; sender.sendMessage(ChatColor.RED+message); } }else{ if(noPermHandler != null)noPermHandler.run(sender, args); else{ sender.sendMessage(ChatColor.RED+"Sorry, you do not have permission to run this command"); } } } public interface Handler{ public void run(CommandSender sender, String[] args); } } How do i use it? This works by you creating an initial command object and then adding sub commands to it, you can add an infinite amount of sub commands. firstly, you must create a base command, this command does not need any command label as you call it yourself in your onCommand method. Code: Command cmd = new Command(); you must then create your sub commands. Code: Command sub1 = new Command("sub1", "sub1aliase", "asManyAliasesAsYouNeed"); Command sub2 = new Command("sub2", "sub2aliase", "asManyAliasesAsYouNeed"); you now must add those sub commands to your main command, note this is the same way you would do it if you were adding another sub command to one of your current sub commands. Code: cmd.addSubCommand(sub1); cmd.addSubCommand(sub2); you now must go into your onCommand method and run the command. Code: public boolean onCommand(CommandSender sender, org.bukkit.command.Command cmd, String label, String[] args){ if(label.equalsIgnoreCase("cmd") || label.equalsIgnoreCase("command"))cmd.run(sender, args); return true; } if you need to use permissions you can set the permissions for each command as well. Code: cmd.setPerm("myplugin.cmd"); sub1.setPerm("myplugin.cmd.sub1"); you can also set the run handler for when the command is run or the perm handler which runs when the permission is not met. if you do not set the perm handler it will simply send "you do not have permission to run this command" to the user. Code: //add perm handler cmd.addPermHandler(new Command.Handler() { public void run(CommandSender sender, String[] args){ //do stuff } }); //add run handler cmd.addRunHandler(new Command.Handler() { public void run(CommandSender sender, String[] args){ //do stuff } }); you can also create classes which implement Command.Handler and use them. Code: public class CommandSub1 implements Command.Handler{ public void run(CommandSender sender, String[] args) { //do stuff } } Code: sub1.setRunHandler(new CommandSub1()); if it cannot find the requested sub command, you run command "/cmd sub3" but there is no sub3, it will send you a message looking like this "cmd [sub1,sub2]" Example Coming Soon! i hope this helps with anyones command handling ~sothatsit
You are checking command labels instead of the command name. That isn't good in most cases :\ Makes it so if people define aliases they won't work.
you must call the base command in the onCommand method and you check there whether the command is what you want... other than that its just checking the args so i cant see whats wrong just found some errors with this although i have updated the post above with a new version with a fix EDIT by Moderator: merged posts, please use the edit button instead of double posting.
What I like to do, is make good use of the Permission object. You can define the permission, who can use it by default, AND the usage. I also use a little hack which adds the command, without using the plugin.yml.
so i should take a Permission object instead of a string? and registering the commands without a plugin.yml sounds interesting, how would you do that
To elaborate a little: Bukkit handles commands by generating a Command object for each command registered in a plugin's manifest file (plugin.yml) and storing these Command objects in a structure called a CommandMap. The CommandMap isn't exposed through the public Bukkit API, because it's treated as an "implementation detail" of the commands API that's subject to change at any time and for any reason; that said, it's perfectly safe to register your own objects in it if you make it accessible using reflection. One project that does something of the sort to enable dynamic command registration is the sk89q-command-framework, whose source code you can examine to get a feel for the internals of the command API that you need to "hack" if you want to dynamically register commands. I also have some experience messing with this stuff, so feel free to ask if you want to learn more.
SoThatsIt That's a really long class for handling commands, just saying. Mine is less that 50 lines, if you remove the white space.