package com.graywolf336.jail.command; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map.Entry; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import com.graywolf336.jail.JailMain; import com.graywolf336.jail.JailManager; import com.graywolf336.jail.command.commands.HandCuffCommand; import com.graywolf336.jail.command.commands.ToggleJailDebugCommand; import com.graywolf336.jail.command.commands.UnHandCuffCommand; import com.graywolf336.jail.command.commands.UnJailForceCommand; import com.graywolf336.jail.command.commands.UnJailCommand; import com.graywolf336.jail.enums.LangString; /** * Where all the commands are registered at and handled, processed, at. * * @author graywolf336 * @since 3.0.0 * @version 1.0.2 * */ public class CommandHandler { private LinkedHashMap commands; public CommandHandler(JailMain plugin) { commands = new LinkedHashMap(); loadCommands(); plugin.debug("Loaded " + commands.size() + " commands."); } /** * Handles the given command and checks that the command is in valid form. * *

* * It checks in the following order: *

    *
  1. If the command is registered or not.
  2. *
  3. If more than one command matches the command's name and sends the usage for each one.
  4. *
  5. If they have permission for it, if they don't then we send them a message stating so.
  6. *
  7. If the command needs a player instance, if so we send a message stating that.
  8. *
  9. If the required minimum arguments have been passed, if not sends the usage.
  10. *
  11. If the required maximum arguments have been passed (if there is a max, -1 if no max), if not sends the usage.
  12. *
  13. Then executes, upon failed execution it sends the usage command.
  14. *
* * @param jailmanager The instance of {@link JailManager}. * @param sender The sender of the command. * @param commandLine The name of the command. * @param args The arguments passed to the command. */ public void handleCommand(JailManager jailmanager, CommandSender sender, String commandLine, String[] args) { List matches = getMatches(commandLine); //If no matches were found, send them the unknown command message. if(matches.size() == 0) { if(commandLine.startsWith("jail")) { String j = commandLine.substring(0, 4); String a0 = commandLine.substring(4, commandLine.length()); ArrayList args2 = new ArrayList(); for(String s : args) args2.add(s); args2.add(a0); if(jailmanager.getPlugin().onCommand(sender, null, j, args2.toArray(new String[args2.size()]))) return; } sender.sendMessage(jailmanager.getPlugin().getJailIO().getLanguageString(LangString.UNKNOWNCOMMAND, commandLine)); return; } //If more than one command was found, send them each command's help message. if(matches.size() > 1) { for(Command c : matches) showUsage(sender, c); return; } Command c = matches.get(0); CommandInfo i = c.getClass().getAnnotation(CommandInfo.class); // First, let's check if the sender has permission for the command. if(!sender.hasPermission(i.permission())) { sender.sendMessage(jailmanager.getPlugin().getJailIO().getLanguageString(LangString.NOPERMISSION)); return; } // Next, let's check if we need a player and then if the sender is actually a player if(i.needsPlayer() && !(sender instanceof Player)) { sender.sendMessage(jailmanager.getPlugin().getJailIO().getLanguageString(LangString.PLAYERCONTEXTREQUIRED)); return; } // Now, let's check the size of the arguments passed. If it is shorter than the minimum required args, let's show the usage. if(args.length < i.minimumArgs()) { showUsage(sender, c); return; } // Then, if the maximumArgs doesn't equal -1, we need to check if the size of the arguments passed is greater than the maximum args. if(i.maxArgs() != -1 && i.maxArgs() < args.length) { showUsage(sender, c); return; } // Since everything has been checked and we're all clear, let's execute it. // But if get back false, let's show the usage message. try { if(!c.execute(jailmanager, sender, args)) { showUsage(sender, c); return; } } catch (Exception e) { e.printStackTrace(); jailmanager.getPlugin().getLogger().severe("An error occured while handling the command: " + i.usage()); showUsage(sender, c); } } private List getMatches(String command) { List result = new ArrayList(); for(Entry entry : commands.entrySet()) { if(command.matches(entry.getKey())) { result.add(entry.getValue()); } } return result; } /** * Shows the usage information to the sender, if they have permission. * * @param sender The sender of the command * @param command The command to send usage of. */ private void showUsage(CommandSender sender, Command command) { CommandInfo info = command.getClass().getAnnotation(CommandInfo.class); if(!sender.hasPermission(info.permission())) return; sender.sendMessage(info.usage()); } /** Loads all the commands into the hashmap. */ private void loadCommands() { load(HandCuffCommand.class); load(ToggleJailDebugCommand.class); load(UnHandCuffCommand.class); load(UnJailCommand.class); load(UnJailForceCommand.class); } private void load(Class c) { CommandInfo info = c.getAnnotation(CommandInfo.class); if(info == null) return; try { commands.put(info.pattern(), c.newInstance()); }catch(Exception e) { e.printStackTrace(); } } }