protected Arguments verifyArgs( MethodWrapper mwrapper, MCCommand cmd, CommandSender sender, Command command, String label, String[] args, int startIndex) throws IllegalArgumentException { if (DEBUG) { Log.info( " method=" + mwrapper.method.getName() + " verifyArgs " + cmd + " sender=" + sender + ", label=" + label + " args=" + args); for (String arg : args) { Log.info(" -- arg=" + arg); } for (Class<?> t : mwrapper.method.getParameterTypes()) { Log.info(" -- type=" + t); } } final int paramLength = mwrapper.method.getParameterTypes().length; /// Check our permissions if (!cmd.perm().isEmpty() && !sender.hasPermission(cmd.perm()) && !(cmd.admin() && hasAdminPerms(sender))) throw new IllegalArgumentException("You don't have permission to use this command"); /// Verify min number of arguments if (args.length < cmd.min()) { throw new IllegalArgumentException("You need at least " + cmd.min() + " arguments"); } /// Verfiy max number of arguments if (args.length > cmd.max()) { throw new IllegalArgumentException("You need less than " + cmd.max() + " arguments"); } /// Verfiy max number of arguments if (cmd.exact() != -1 && args.length != cmd.exact()) { throw new IllegalArgumentException("You need exactly " + cmd.exact() + " arguments"); } final boolean isPlayer = sender instanceof Player; final boolean isOp = (isPlayer && sender.isOp()) || sender == null || sender instanceof ConsoleCommandSender; if (cmd.op() && !isOp) throw new IllegalArgumentException("You need to be op to use this command"); if (cmd.admin() && !isOp && (isPlayer && !hasAdminPerms(sender))) throw new IllegalArgumentException("You need to be an Admin to use this command"); Class<?> types[] = mwrapper.method.getParameterTypes(); // /// In game check if (types[0] == Player.class && !isPlayer) { throw new IllegalArgumentException(ONLY_INGAME); } int strIndex = startIndex /*skip the label*/, objIndex = 1; Arguments newArgs = new Arguments(); // / Our return value Object[] objs = new Object[paramLength]; // / Our new array of castable arguments newArgs.args = objs; // / Set our return object with the new castable arguments objs[0] = verifySender(sender, types[0]); AtomicBoolean usedString = new AtomicBoolean(); for (int i = 1; i < types.length; i++) { Class<?> clazz = types[i]; usedString.set(false); try { if (CommandSender.class == clazz) { objs[objIndex] = sender; } else if (String[].class == clazz) { objs[objIndex] = args; } else if (Object[].class == clazz) { objs[objIndex] = args; } else { String str = strIndex < args.length ? args[strIndex] : null; objs[objIndex] = verifyArg(clazz, command, str, usedString); if (objs[objIndex] == null) { throw new IllegalArgumentException("Argument " + args[strIndex] + " can not be null"); } } if (DEBUG) Log.info( " " + objIndex + " : " + strIndex + " " + (args.length > strIndex ? args[strIndex] : null) + " <-> " + objs[objIndex] + " !!!!!!!!!!!!!!!!!!!!!!!!!!! Cs = " + clazz.getCanonicalName()); if (usedString.get()) { strIndex++; } } catch (ArrayIndexOutOfBoundsException e) { throw new IllegalArgumentException("You didnt supply enough arguments for this method"); } objIndex++; } /// Verify alphanumeric if (cmd.alphanum().length > 0) { for (int index : cmd.alphanum()) { if (index >= args.length) throw new IllegalArgumentException("String Index out of range. "); if (!args[index].matches("[a-zA-Z0-9_]*")) { throw new IllegalArgumentException( "argument '" + args[index] + "' can only be alphanumeric with underscores"); } } } return newArgs; /// Success }
public void help(CommandSender sender, Command command, String[] args) { Integer page = 1; if (args != null && args.length > 1) { try { page = Integer.valueOf(args[1]); } catch (Exception e) { sendMessage( sender, ChatColor.RED + " " + args[1] + " is not a number, showing help for page 1."); } } List<String> available = new ArrayList<String>(); List<String> unavailable = new ArrayList<String>(); List<String> onlyop = new ArrayList<String>(); Set<Method> dups = new HashSet<Method>(); for (MethodWrapper mw : usage) { if (!dups.add(mw.method)) continue; MCCommand cmd = mw.getCommand(); final String use = "&6/" + command.getName() + " " + mw.usage; if (cmd.op() && !sender.isOp()) continue; else if (cmd.admin() && !hasAdminPerms(sender)) continue; else if (!cmd.perm().isEmpty() && !sender.hasPermission(cmd.perm())) unavailable.add(use); else available.add(use); } int npages = available.size() + unavailable.size(); if (sender.isOp()) npages += onlyop.size(); npages = (int) Math.ceil((float) npages / LINES_PER_PAGE); if (page > npages || page <= 0) { if (npages <= 0) { sendMessage(sender, "&4There are no methods for this command"); } else { sendMessage(sender, "&4That page doesnt exist, try 1-" + npages); } return; } if (command != null && command.getAliases() != null && !command.getAliases().isEmpty()) { String aliases = StringUtils.join(command.getAliases(), ", "); sendMessage( sender, "&eShowing page &6" + page + "/" + npages + "&6 : /" + command.getName() + " help <page number>"); sendMessage(sender, "&e command &6" + command.getName() + "&e has aliases: &6" + aliases); } else { sendMessage( sender, "&eShowing page &6" + page + "/" + npages + "&6 : /cmd help <page number>"); } int i = 0; for (String use : available) { i++; if (i < (page - 1) * LINES_PER_PAGE || i >= page * LINES_PER_PAGE) continue; sendMessage(sender, use); } for (String use : unavailable) { i++; if (i < (page - 1) * LINES_PER_PAGE || i >= page * LINES_PER_PAGE) continue; sendMessage(sender, ChatColor.RED + "[Insufficient Perms] " + use); } if (sender.isOp()) { for (String use : onlyop) { i++; if (i < (page - 1) * LINES_PER_PAGE || i >= page * LINES_PER_PAGE) continue; sendMessage(sender, ChatColor.AQUA + "[OP only] &6" + use); } } }
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { TreeMap<Integer, MethodWrapper> methodmap = null; /// No method to handle, show some help if ((args.length == 0 && !methods.containsKey(DEFAULT_CMD)) || (args.length > 0 && (args[0].equals("?") || args[0].equals("help")))) { showHelp(sender, command, args); return true; } final int length = args.length; final String cmd = length > 0 ? args[0].toLowerCase() : null; final String subcmd = length > 1 ? args[1].toLowerCase() : null; int startIndex = 0; /// check for subcommands if (subcmd != null && subCmdMethods.containsKey(cmd) && subCmdMethods.get(cmd).containsKey(subcmd)) { methodmap = subCmdMethods.get(cmd).get(subcmd); startIndex = 2; } if (methodmap == null && cmd != null) { // / Find our method, and verify all the annotations methodmap = methods.get(cmd); if (methodmap != null) startIndex = 1; } if (methodmap == null) { // / our last attempt methodmap = methods.get(DEFAULT_CMD); } if (methodmap == null || methodmap.isEmpty()) { return sendMessage( sender, "&cThat command does not exist!&6 /" + command.getLabel() + " help &c for help"); } MCCommand mccmd = null; List<CommandException> errs = null; boolean success = false; for (MethodWrapper mwrapper : methodmap.values()) { mccmd = mwrapper.method.getAnnotation(MCCommand.class); final boolean isOp = sender == null || sender.isOp() || sender instanceof ConsoleCommandSender; if (mccmd.op() && !isOp || mccmd.admin() && !hasAdminPerms(sender)) // / no op, no pass continue; Arguments newArgs = null; try { newArgs = verifyArgs(mwrapper, mccmd, sender, command, label, args, startIndex); Object completed = mwrapper.method.invoke(mwrapper.obj, newArgs.args); if (completed != null && completed instanceof Boolean) { success = (Boolean) completed; if (!success) { String usage = mwrapper.usage; if (usage != null && !usage.isEmpty()) { sendMessage(sender, usage); } } } else { success = true; } break; /// success on one } catch ( IllegalArgumentException e) { // / One of the arguments wasn't correct, store the message if (errs == null) errs = new ArrayList<CommandException>(); errs.add(new CommandException(e, mwrapper)); } catch (Exception e) { // / Just all around bad logInvocationError(e, mwrapper, newArgs); } } /// and handle all errors if (!success && errs != null && !errs.isEmpty()) { HashSet<String> usages = new HashSet<String>(); for (CommandException e : errs) { usages.add( ChatColor.GOLD + command.getLabel() + " " + e.mw.usage + " &c:" + e.err.getMessage()); } for (String msg : usages) { sendMessage(sender, msg); } } return true; }