Advertisement
Guest User

Untitled

a guest
Feb 11th, 2016
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 22.78 KB | None | 0 0
  1. import java.io.PrintWriter;
  2. import java.io.StringWriter;
  3. import java.lang.annotation.ElementType;
  4. import java.lang.annotation.Retention;
  5. import java.lang.annotation.RetentionPolicy;
  6. import java.lang.annotation.Target;
  7. import java.lang.reflect.Constructor;
  8. import java.lang.reflect.Field;
  9. import java.lang.reflect.InvocationTargetException;
  10. import java.lang.reflect.Method;
  11. import java.util.ArrayList;
  12. import java.util.Arrays;
  13. import java.util.HashMap;
  14. import java.util.List;
  15. import java.util.Map.Entry;
  16. import java.util.TreeMap;
  17. import java.util.regex.Matcher;
  18. import java.util.regex.Pattern;
  19.  
  20. import org.apache.commons.lang.StringUtils;
  21. import org.apache.commons.lang.time.StopWatch;
  22. import org.bukkit.Bukkit;
  23. import org.bukkit.ChatColor;
  24. import org.bukkit.OfflinePlayer;
  25. import org.bukkit.command.Command;
  26. import org.bukkit.command.CommandExecutor;
  27. import org.bukkit.command.CommandMap;
  28. import org.bukkit.command.CommandSender;
  29. import org.bukkit.command.PluginCommand;
  30. import org.bukkit.command.TabCompleter;
  31. import org.bukkit.entity.Player;
  32. import org.bukkit.plugin.Plugin;
  33. import org.bukkit.plugin.java.JavaPlugin;
  34.  
  35. import net.md_5.bungee.api.chat.ClickEvent;
  36. import net.md_5.bungee.api.chat.ComponentBuilder;
  37. import net.md_5.bungee.api.chat.HoverEvent;
  38.  
  39. /**
  40. * Register a command with the command system!
  41. * <br><br>
  42. * Handles arguments, argument type handling, predictions, tab completion, sub-sub-sub-commands, error handling, help pages, and more!
  43. * <br><br>
  44. * CommandManager manager = new CommandManager(plugin, "Help Tag", "command", "permission node");
  45. *
  46. * @author Stumblinbear
  47. */
  48. public class CommandManager implements TabCompleter, CommandExecutor {
  49. static boolean GLOBAL_DEBUG = false;
  50. @Cmd(cmd = "debug",
  51. args = "[bool]",
  52. argTypes = { Arg.ArgBoolean.class },
  53. help = "Toggle debug mode.",
  54. longhelp = "Toggle debug mode. Shows information on command usage.",
  55. only = CommandOnly.OP,
  56. permission = "debug")
  57. public static CommandFinished cmdToggleDebugMode(CommandSender sender, Object[] args) {
  58. GLOBAL_DEBUG = (args.length != 0 ? (Boolean)args[0] : !GLOBAL_DEBUG);
  59. sender.sendMessage(ChatColor.YELLOW + "Debug mode is now: " + (GLOBAL_DEBUG ? ChatColor.GREEN + "ON" : ChatColor.RED + "OFF"));
  60. return CommandFinished.DONE;
  61. }
  62.  
  63. private static HashMap<Class<? extends AbstractArg<?>>, AbstractArg<?>> argInstances = new HashMap<Class<? extends AbstractArg<?>>, AbstractArg<?>>();
  64.  
  65. private ArrayList<Cmd> commands = new ArrayList<Cmd>();
  66. private ArrayList<Method> commandMethods = new ArrayList<Method>();
  67.  
  68. String tag;
  69. String command;
  70. String permissionScheme;
  71.  
  72. public CommandManager(JavaPlugin plugin, String tag, String permissionScheme, String command, String... aliases) {
  73. this.tag = tag;
  74. this.command = command;
  75. this.permissionScheme = permissionScheme;
  76.  
  77. // Used to inject the command without using plugin.yml
  78. try {
  79. final Field bukkitCommandMap = Bukkit.getServer().getClass().getDeclaredField("commandMap");
  80.  
  81. bukkitCommandMap.setAccessible(true);
  82. CommandMap commandMap = (CommandMap)bukkitCommandMap.get(Bukkit.getServer());
  83.  
  84. Constructor<PluginCommand> c = PluginCommand.class.getDeclaredConstructor(String.class, Plugin.class);
  85. c.setAccessible(true);
  86.  
  87. PluginCommand pluginCommand = c.newInstance(command, plugin);
  88. pluginCommand.setTabCompleter(this);
  89. pluginCommand.setExecutor(this);
  90. if(aliases.length > 0)
  91. pluginCommand.setAliases(Arrays.asList(aliases));
  92. commandMap.register(command, pluginCommand);
  93.  
  94. loadCommandClass(this.getClass());
  95. } catch(Exception e) { e.printStackTrace(); }
  96. }
  97.  
  98. /**
  99. * Parses classes for @Cmd annotations.
  100. */
  101. public CommandManager loadCommandClass(Class<?> commandClass) {
  102. try {
  103. for(Method method : commandClass.getMethods()) {
  104. if(method.isAnnotationPresent(Cmd.class)) {
  105. Cmd cmd = method.getAnnotation(Cmd.class);
  106. commands.add(cmd);
  107. commandMethods.add(method);
  108. }
  109. }
  110. } catch(SecurityException e) {
  111. e.printStackTrace();
  112. }
  113.  
  114. return this;
  115. }
  116.  
  117. @Override
  118. public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
  119. List<String> predictions = new ArrayList<String>();
  120. String token = (args.length == 0 ? "" : args[args.length - 1]);
  121.  
  122. for(Cmd c : commands) {
  123. List<String> cmdPredictions = getPredicted(c, token, args.length - 1);
  124. // Prevent duplicate entries
  125. if(cmdPredictions != null) {
  126. for(String str : cmdPredictions) {
  127. if(!predictions.contains(str))
  128. predictions.add(str);
  129. }
  130. }
  131. }
  132.  
  133. return predictions;
  134. }
  135.  
  136. /**
  137. * Get a prediction of the next command argument.
  138. */
  139. private List<String> getPredicted(Cmd c, String token, int i) {
  140. String[] cmdArg = c.cmd().split(" ");
  141. // If no token, return all possible commands.
  142. if(token == "")
  143. return Arrays.asList(new String[] { cmdArg[0] });
  144. // If the amount of args is more than available, or it doesn't start with the token.
  145. if(i >= cmdArg.length) {
  146. int argNum = i - cmdArg.length;
  147. if(argNum >= c.argTypes().length)
  148. return null;
  149. else{
  150. if(!argInstances.containsKey(c.argTypes()[argNum]))
  151. try {
  152. argInstances.put(c.argTypes()[argNum], c.argTypes()[argNum].newInstance());
  153. } catch (Exception e) { }
  154. AbstractArg<?> absArg = argInstances.get(c.argTypes()[argNum]);
  155. return absArg.getPredictions();
  156. }
  157. // If it doesn't start with the token.
  158. }else if(!cmdArg[i].startsWith(token))
  159. return null;
  160. // It must be a match!
  161. return Arrays.asList(new String[] { cmdArg[i] });
  162. }
  163.  
  164. @Override
  165. public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
  166. StopWatch sw = null;
  167. if(GLOBAL_DEBUG) {
  168. sw = new StopWatch();
  169. sw.start();
  170. }
  171.  
  172. CommandFinished finishedType = runCommand(sender, args);
  173. if(finishedType.shouldPrint()) {
  174. sender.sendMessage(ChatColor.RED + finishedType.getErrorString());
  175.  
  176. // Do our best to predict which command was going to be used.
  177. if(finishedType == CommandFinished.COMMAND) {
  178. // TreeMaps automatically sort by numbers.
  179. TreeMap<Double, Cmd> possible = new TreeMap<Double, Cmd>();
  180. for(Cmd c : commands) {
  181. // Reduce arg array to the shortest one.
  182. String[] fixedArgs = new String[c.cmd().split(" ").length];
  183. for(int i = 0; i < (args.length > fixedArgs.length ? fixedArgs.length : args.length); i++)
  184. fixedArgs[i] = args[i];
  185.  
  186. // Combine the arguments.
  187. String cmdArgs = StringUtils.join(fixedArgs, " ");
  188.  
  189. // Use Levenshtein Distance to get how similar the two strings are to each other. Calculate percentage with the value returned.
  190. possible.put((1D - (StringUtils.getLevenshteinDistance(cmdArgs, c.cmd()) / (Math.max(cmdArgs.length(), c.cmd().length()) * 1D))) * 100D, c);
  191. }
  192.  
  193. // Are there even any predictions?
  194. if(possible.size() > 0) {
  195. // Get the last entry. (The one with the highest possibility)
  196. Entry<Double, Cmd> entry = possible.pollLastEntry();
  197. sender.sendMessage("");
  198. // Allow players to click the command in chat to add it to their chat input.
  199. if(sender instanceof Player) {
  200. ((Player)sender).spigot().sendMessage(new ComponentBuilder(" Did you mean: ").color(net.md_5.bungee.api.ChatColor.GOLD)
  201. .append("/" + label + " " + entry.getValue().cmd()).color(net.md_5.bungee.api.ChatColor.GRAY)
  202. .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(StringUtils.join((entry.getValue().longhelp().equals("") ? entry.getValue().help() : entry.getValue().longhelp()).split("(?<=\\G.........................)"), "\n")).create()))
  203. .event(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/" + label + " " + entry.getValue().cmd()))
  204. .append("? We're " + ((int)(entry.getKey() * 10) / 10D) + "% sure.").reset().color(net.md_5.bungee.api.ChatColor.GOLD).create());
  205. }else
  206. sender.sendMessage(ChatColor.GOLD + " Did you mean: " + ChatColor.GRAY + "/" + label + " " + entry.getValue().cmd() + ChatColor.GOLD + "? We're " + ((int)(entry.getKey() * 10) / 10D) + "% sure.");
  207. sender.sendMessage("");
  208. }
  209. }
  210. }
  211.  
  212. if(GLOBAL_DEBUG && sw != null) {
  213. sw.stop();
  214. sender.sendMessage(ChatColor.YELLOW + "Command took " + sw.getTime() + " milliseconds to complete.");
  215. }
  216. return true;
  217. }
  218.  
  219. /**
  220. * Find the best command to run and do so.
  221. */
  222. public CommandFinished runCommand(CommandSender sender, String[] args) {
  223. try {
  224. // Display help if no args, or they use the help command
  225. if(args.length == 0 || args[0].equalsIgnoreCase("help"))
  226. return displayHelp(sender, args.length == 0 ? null : args);
  227. else{
  228. Cmd bestFit = null;
  229. int bestFit_i = 0;
  230. int bestFit_args = -1;
  231.  
  232. // Loop through commands until a suitable one is found
  233. for(int i = 0; i < commands.size(); i++) {
  234. Cmd cmd = commands.get(i);
  235.  
  236. // Split the base command and check for a match
  237. String[] cmds = cmd.cmd().split(" ");
  238. if(args.length >= cmds.length) {
  239. boolean valid = true;
  240. for(int j = 0; j < cmds.length; j++) {
  241. if(!cmds[j].equalsIgnoreCase(args[j])) {
  242. valid = false;
  243. break;
  244. }
  245. }
  246.  
  247. if(!valid)
  248. continue;
  249. }else
  250. continue;
  251.  
  252. // Check if it's better than the best fit.
  253. if(cmd.cmd().split(" ").length > bestFit_args) {
  254. bestFit = cmd;
  255. bestFit_i = i;
  256. bestFit_args = cmd.cmd().split(" ").length;
  257. }else
  258. continue;
  259. }
  260.  
  261. if(bestFit != null) {
  262. // Check the "only" argument
  263. if(sender instanceof Player) {
  264. if(bestFit.only() == CommandOnly.CONSOLE)
  265. return CommandFinished.NOPLAYER;
  266. }else if(bestFit.only() == CommandOnly.PLAYER)
  267. return CommandFinished.NOCONSOLE;
  268.  
  269. // Check for the "op" argument and permission argument
  270. if((bestFit.only() == CommandOnly.OP ? !sender.isOp() : false) ||
  271. (bestFit.permission() != "" ? !sender.hasPermission(permissionScheme + "." + bestFit.permission()) : false))
  272. return CommandFinished.PERMISSION;
  273.  
  274. // Split up the args; arguments in quotes count as a single argument.
  275. List<Object> cmdArgList = new ArrayList<Object>();
  276. Matcher m = Pattern.compile("(?:([^\"]\\S*)|\"(.+?)\")\\s*").matcher(StringUtils.join(args, " ").replaceFirst(bestFit.cmd(), "").trim());
  277. for(int j = 0; m.find(); j++) {
  278. // Apply the requested argument type.
  279. Class<? extends AbstractArg<?>> requestedType = (j < bestFit.argTypes().length ? bestFit.argTypes()[j] : Arg.ArgString.class);
  280. // Cache the instance.
  281. if(!argInstances.containsKey(requestedType))
  282. argInstances.put(requestedType, requestedType.newInstance());
  283. AbstractArg<?> absArg = argInstances.get(requestedType);
  284. try {
  285. Object arg = absArg.parseArg(m.group(1) != null ? m.group(1) : m.group(2));
  286. if(arg == null)
  287. // Some argument parsers don't throw an exception. Just an extra precaution.
  288. throw new CommandException(absArg.getFailure() + " (" + m.group(1) != null ? m.group(1) : m.group(2) + ")");
  289. cmdArgList.add(arg);
  290. } catch(Exception e) {
  291. return CommandFinished.CUSTOM.replace(absArg.getFailure() + " (" + (m.group(1) != null ? m.group(1) : m.group(2)) + ")");
  292. }
  293. }
  294.  
  295. // Check that all the required arguments have been fulfilled.
  296. Object[] cmdArgsPassed = cmdArgList.toArray(new Object[cmdArgList.size()]);
  297. if(StringUtils.countMatches(bestFit.args(), "<") > cmdArgsPassed.length)
  298. return CommandFinished.BADCOMMAND.replace(command + " " + bestFit.cmd() + " " + bestFit.args());
  299.  
  300. // Run the command :D
  301. return (CommandFinished)commandMethods.get(bestFit_i).invoke(null, new Object[] { sender, (cmdArgsPassed != null ? cmdArgsPassed : null) });
  302. }
  303. }
  304. } catch(InvocationTargetException e) {
  305. e.getCause().printStackTrace();
  306. if(e.getCause() instanceof CommandException)
  307. return CommandFinished.CUSTOM.replace(e.getCause().getMessage());
  308. if(GLOBAL_DEBUG)
  309. Bukkit.broadcastMessage(ChatColor.RED + "Error: " + getTrace(e));
  310. return CommandFinished.EXCEPTION;
  311. } catch (Exception e) {
  312. e.printStackTrace();
  313. if(GLOBAL_DEBUG)
  314. Bukkit.broadcastMessage(ChatColor.RED + "Error: " + getTrace(e));
  315. return CommandFinished.EXCEPTION;
  316. }
  317.  
  318. return CommandFinished.COMMAND.replace(command);
  319. }
  320.  
  321. /**
  322. * Display the help menu.
  323. */
  324. public CommandFinished displayHelp(CommandSender sender, String[] args) {
  325. ArrayList<String> helpList = new ArrayList<String>(); // The help message buffer
  326. boolean specific = false; // If "help <command>"
  327. int perPage = 8; // How many commands to show per page
  328. int page = 0; // Which page
  329.  
  330. if(args != null && args.length != 1) {
  331. try {
  332. page = Integer.parseInt(args[1]) - 1;
  333. if(page < 0) // Negative pages are bad juju.
  334. page = 0;
  335. } catch(Exception e) { specific = true; } // If this fails, it's probably a string. Check for a specific command.
  336. }
  337.  
  338. String cmdLabel = null; // The label of the specific command.
  339.  
  340. if(specific && args.length != 1) {
  341. perPage = 4; // Reduce the amount to show per page.
  342. cmdLabel = StringUtils.join(args, " ").split(" ", 2)[1]; // Because args = "help <command>" cut out "help".
  343. }
  344.  
  345. for(Cmd cmd : commands) {
  346. // If looking for specific commands and it isn't the one we're looking for
  347. if(specific && !cmd.cmd().startsWith(cmdLabel))
  348. continue;
  349.  
  350. // Should it even show?
  351. if(cmd.showInHelp()) {
  352. // If it can't be used, don't show it! Simple! :D
  353. boolean canUse = cmd.permission().equals("") ? true : (sender.hasPermission(permissionScheme + "." + cmd.permission()));
  354.  
  355. // Is it op-only?
  356. if(cmd.only() == CommandOnly.OP)
  357. canUse = (cmd.permission().equals("") ? sender.isOp() : canUse);
  358.  
  359. if(canUse)
  360. helpList.add(ChatColor.GOLD + "/" + command + " " + cmd.cmd() + (cmd.args() != "" ? " " + cmd.args() : "") + ": " + ChatColor.WHITE + (specific ? (cmd.longhelp().equals("") ? cmd.help() : cmd.longhelp()) : cmd.help()));
  361. }
  362. }
  363.  
  364. // Make sure there's something to show.
  365. boolean badPage = true;
  366. if(helpList.size() >= page * perPage) {
  367. for(int j = 0; j < perPage; j++) {
  368. if(helpList.size() > (j + page * perPage)) {
  369. if(j == 0)
  370. sender.sendMessage(ChatColor.YELLOW + "--------- " + ChatColor.WHITE + tag + " Help (" + (page + 1) + "/" + (int)Math.ceil(helpList.size() / (perPage * 1F)) + ")" + ChatColor.YELLOW + " ---------------------");
  371. sender.sendMessage(helpList.get((j + page * perPage)));
  372. badPage = false;
  373. }
  374. }
  375. }
  376.  
  377. if(badPage) {
  378. if(specific)
  379. return CommandFinished.CUSTOM.replace("Command unrecognized.");
  380. else
  381. return CommandFinished.CUSTOM.replace("Page " + (page + 1) + " does not exist in help.");
  382. }else if(helpList.size() > (page + 1) * perPage)
  383. sender.sendMessage(ChatColor.WHITE + "Use " + ChatColor.YELLOW + "/" + command + " help " + (page + 2) + ChatColor.WHITE + " to see more help.");
  384. return CommandFinished.DONE;
  385. }
  386.  
  387. /**
  388. * Returns the string version of an exception. Helps with in-game error checking.
  389. */
  390. private String getTrace(Exception e) {
  391. StringWriter sw = new StringWriter();
  392. PrintWriter pw = new PrintWriter(sw);
  393. e.printStackTrace(pw);
  394. return sw.toString();
  395. }
  396.  
  397. @Target(ElementType.METHOD)
  398. @Retention(RetentionPolicy.RUNTIME)
  399. /**
  400. * Attach to a function to denote it as a command. You must register the class it is in as a command class before it will be used.
  401. */
  402. public static @interface Cmd {
  403. /**
  404. * Takes in any amount of subcommands. The command handler always chooses the best-fit command.
  405. * <br><br>
  406. * Example:
  407. * <br>
  408. * cmd = "sub1 sub2 sub3 sub4 sub5"
  409. */
  410. String cmd() default "";
  411.  
  412. /**
  413. * The arguments for the command. Required arguments must be enclosed in <>'s
  414. * <br><br>
  415. * Example:
  416. * <br>
  417. * args = "<arg1> <arg2> [arg3]"
  418. * <br>
  419. * Argument 1 and 2 are required; the third is optional.
  420. */
  421. String args() default "";
  422.  
  423. /**
  424. * Specifies the type that an argument should be. Default is Arg.ArgString.
  425. * <br><br>
  426. * Example:
  427. * <br>
  428. * argTypes = { Arg.ArgInteger, Arg.ArgString, Arg.ArgPlayer }
  429. * <ul>
  430. * <li>Argument 1 <i>must</i> be an integer.</li>
  431. * <li>Argument 2 <i>must</i> be a string(anything).</li>
  432. * <li>Argument 3 <i>must</i> be an online player.</li>
  433. * </ul>
  434. */
  435. Class<? extends AbstractArg<?>>[] argTypes() default { };
  436.  
  437. /**
  438. * The text to show next to a command when a user does /cmd help.
  439. */
  440. String help() default "Default help thingy... :(";
  441.  
  442. /**
  443. * The text to show next to a command when a user does /cmd help <command>.
  444. * <br><br>
  445. * Use to give more information about the command.
  446. */
  447. String longhelp() default "";
  448.  
  449. /**
  450. * Should the command be shown in help at all?
  451. */
  452. boolean showInHelp() default true;
  453.  
  454. /**
  455. * Specifies if the command should be restricted to CONSOLE, OP, or PLAYERS. Otherwise, ALL.
  456. */
  457. CommandOnly only() default CommandOnly.ALL;
  458.  
  459. /**
  460. * The permission node to use.
  461. * <br><br>
  462. * Example:
  463. * <br>
  464. * new CommandManager(plugin, "Test", "testnode", "test");
  465. * <br>
  466. * permission = "edit"
  467. * <br>
  468. * This setup would require a player to have testnode.edit to use the command.
  469. */
  470. String permission() default "";
  471. }
  472.  
  473. /**
  474. * Used to define who is allowed to use a command.
  475. */
  476. public static enum CommandOnly {
  477. /**
  478. * Only players can use the command.
  479. */
  480. PLAYER,
  481. /**
  482. * Only op players can use the command. Can be overridden by a matched permission.
  483. */
  484. OP,
  485. /**
  486. * Only the console can use the command.
  487. */
  488. CONSOLE,
  489. /**
  490. * Anyone can use the command, given their permissions match.
  491. */
  492. ALL
  493. }
  494.  
  495. /**
  496. * This can be used to immediately throw an error without returning a <code>CommandFinished</code>.
  497. * It'll display the specified error.
  498. */
  499. public static class CommandException extends Exception {
  500. private static final long serialVersionUID = 1L;
  501.  
  502. public CommandException(String message) {
  503. super(message);
  504. }
  505. }
  506.  
  507. /**
  508. * A set of command errors.
  509. */
  510. public static enum CommandFinished {
  511. /** Finished correctly */
  512. DONE(false, "Done"),
  513. /** Command does not exist */
  514. COMMAND(true, "Command does not exist. Use /%s for help."),
  515. /** Command does not exist */
  516. BADCOMMAND(true, "Bad command usage: /%s "),
  517. /** Console not allowed to use */
  518. NOCONSOLE(true, "This command cannot be run from the console."),
  519. /** Player not allowed to use */
  520. NOPLAYER(true, "This command cannot be run by players."),
  521. /** Player does not exist */
  522. EXISTPLAYER(true, "That player does not exist."),
  523. /** Incorrect permissions */
  524. PERMISSION(true, "Insufficient permissions."),
  525.  
  526. HOLDBLOCK(true, "You must be holding a block."),
  527. HOLDITEM(true, "You must be holding an item."),
  528.  
  529. LONGSTRING(true, "String cannot be longer than %s!"),
  530.  
  531. /** Custom error */
  532. CUSTOM(true, "%s"),
  533. EXCEPTION(true, "An exception occured. Please contact a member of staff and tell them!");
  534.  
  535. private boolean shouldPrint;
  536. private String errorString;
  537. private String extraString;
  538.  
  539. CommandFinished(boolean par1ShouldPrint, String par1Error) {
  540. shouldPrint = par1ShouldPrint;
  541. errorString = par1Error;
  542. }
  543.  
  544. public boolean shouldPrint() {
  545. return shouldPrint;
  546. }
  547.  
  548. public String getErrorString() {
  549. if(extraString != null)
  550. return errorString.replace("%s", extraString);
  551. else
  552. return errorString;
  553. }
  554.  
  555. public CommandFinished replace(String theString) {
  556. extraString = theString;
  557. return this;
  558. }
  559. }
  560.  
  561. /*
  562. * Arguments
  563. */
  564. public static interface IArgParse<T> {
  565. T parseArg(String arg);
  566.  
  567. List<String> getPredictions();
  568.  
  569. String getFailure();
  570. }
  571.  
  572. public static abstract class AbstractArg<T> implements IArgParse<T> {
  573. public AbstractArg() { }
  574. }
  575.  
  576. public static class Arg {
  577. public static class ArgArray extends AbstractArg<List<String>> {
  578. public List<String> parseArg(String arg) {
  579. List<String> list = new ArrayList<String>();
  580. for(String str : arg.split(","))
  581. list.add(str);
  582. return list;
  583. }
  584.  
  585. public String getFailure() {
  586. return "Argument failure.";
  587. }
  588.  
  589. public List<String> getPredictions() { return null; }
  590. }
  591.  
  592. public static class ArgBoolean extends AbstractArg<Boolean> {
  593. public Boolean parseArg(String arg) {
  594. if(arg.equalsIgnoreCase("true") || arg.equalsIgnoreCase("yes") || arg.equalsIgnoreCase("on") || arg.equalsIgnoreCase("1"))
  595. return true;
  596. if(arg.equalsIgnoreCase("false") || arg.equalsIgnoreCase("no") || arg.equalsIgnoreCase("off") || arg.equalsIgnoreCase("0"))
  597. return false;
  598. return null;
  599. }
  600.  
  601. public String getFailure() {
  602. return "Argument not a valid boolean.";
  603. }
  604.  
  605. public List<String> getPredictions() { return Arrays.asList(new String[] { "true", "false" }); }
  606. }
  607.  
  608. public static class ArgByte extends AbstractArg<Byte> {
  609. public Byte parseArg(String arg) {
  610. return Byte.valueOf(arg);
  611. }
  612.  
  613. public String getFailure() {
  614. return "Argument not a valid byte.";
  615. }
  616.  
  617. public List<String> getPredictions() { return Arrays.asList(new String[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15" }); }
  618. }
  619.  
  620. public static class ArgDouble extends AbstractArg<Double> {
  621. public Double parseArg(String arg) {
  622. return Double.valueOf(arg);
  623. }
  624.  
  625. public String getFailure() {
  626. return "Argument not a real number.";
  627. }
  628.  
  629. public List<String> getPredictions() { return null; }
  630. }
  631.  
  632. public static class ArgFloat extends AbstractArg<Float> {
  633. public Float parseArg(String arg) {
  634. return Float.valueOf(arg);
  635. }
  636.  
  637. public String getFailure() {
  638. return "Argument not a floating point number.";
  639. }
  640.  
  641. public List<String> getPredictions() { return null; }
  642. }
  643.  
  644. public static class ArgInteger extends AbstractArg<Integer> {
  645. public Integer parseArg(String arg) {
  646. return Integer.valueOf(arg);
  647. }
  648.  
  649. public String getFailure() {
  650. return "Argument not an integer.";
  651. }
  652.  
  653. public List<String> getPredictions() { return null; }
  654. }
  655.  
  656. public static class ArgPlayer extends AbstractArg<OfflinePlayer> {
  657. public Player parseArg(String arg) {
  658. return Bukkit.getPlayer(arg);
  659. }
  660.  
  661. public String getFailure() {
  662. return CommandFinished.EXISTPLAYER.getErrorString();
  663. }
  664.  
  665. public List<String> getPredictions() {
  666. List<String> players = new ArrayList<String>();
  667. for(Player p : Bukkit.getOnlinePlayers())
  668. players.add(p.getName());
  669. return players;
  670. }
  671. }
  672.  
  673. public static class ArgOfflinePlayer extends AbstractArg<OfflinePlayer> {
  674. @SuppressWarnings("deprecation")
  675. public OfflinePlayer parseArg(String arg) {
  676. return Bukkit.getOfflinePlayer(arg);
  677. }
  678.  
  679. public String getFailure() {
  680. return CommandFinished.EXISTPLAYER.getErrorString();
  681. }
  682.  
  683. public List<String> getPredictions() {
  684. List<String> players = new ArrayList<String>();
  685. for(Player p : Bukkit.getOnlinePlayers())
  686. players.add(p.getName());
  687. return players;
  688. }
  689. }
  690.  
  691. public static class ArgString extends AbstractArg<String> {
  692. public String parseArg(String arg) {
  693. return arg;
  694. }
  695.  
  696. public String getFailure() {
  697. return "Could not parse string.";
  698. }
  699.  
  700. public List<String> getPredictions() { return null; }
  701. }
  702. }
  703. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement