diff --git a/src/main/java/com/graywolf336/jail/JailMain.java b/src/main/java/com/graywolf336/jail/JailMain.java index 94e5b25..2bf0d44 100644 --- a/src/main/java/com/graywolf336/jail/JailMain.java +++ b/src/main/java/com/graywolf336/jail/JailMain.java @@ -7,6 +7,7 @@ import org.bukkit.plugin.java.JavaPlugin; import com.graywolf336.jail.beans.Jail; import com.graywolf336.jail.command.CommandHandler; +import com.graywolf336.jail.command.JailHandler; import com.graywolf336.jail.enums.Settings; import com.graywolf336.jail.listeners.BlockListener; import com.graywolf336.jail.listeners.EntityListener; @@ -24,6 +25,7 @@ import com.graywolf336.jail.listeners.ProtectionListener; public class JailMain extends JavaPlugin { private CommandHandler cmdHand; private HandCuffManager hcm; + private JailHandler jh; private JailIO io; private JailManager jm; private JailTimer jt; @@ -41,6 +43,7 @@ public class JailMain extends JavaPlugin { io.loadJails(); cmdHand = new CommandHandler(this); + jh = new JailHandler(this); pm = new PrisonerManager(this); PluginManager plm = this.getServer().getPluginManager(); @@ -103,7 +106,12 @@ public class JailMain extends JavaPlugin { * Send the command off to the CommandHandler class, that way this main class doesn't get clogged up. */ public boolean onCommand(CommandSender sender, Command command, String commandLabel, String[] args) { - cmdHand.handleCommand(jm, sender, command.getName().toLowerCase(), args); + if(command.getName().equalsIgnoreCase("jail")) { + jh.handleCommand(jm, sender, args); + }else { + cmdHand.handleCommand(jm, sender, command.getName().toLowerCase(), args); + } + return true;//Always return true here, that way we can handle the help and command usage ourself. } diff --git a/src/main/java/com/graywolf336/jail/PrisonerManager.java b/src/main/java/com/graywolf336/jail/PrisonerManager.java index 927e5b9..f72b02b 100644 --- a/src/main/java/com/graywolf336/jail/PrisonerManager.java +++ b/src/main/java/com/graywolf336/jail/PrisonerManager.java @@ -389,4 +389,17 @@ public class PrisonerManager { player.sendMessage(pl.getJailIO().getLanguageString(LangString.UNJAILED)); } + + public void forceUnJail(Jail jail, Cell cell, Player player, Prisoner prisoner) { + if(player == null) { + //Player is offline, we just forcefully remove them from the database + pl.getJailIO().removePrisoner(jail, cell, prisoner); + }else { + try { + unJail(jail, cell, player, prisoner); + } catch (Exception e) { + releasePrisoner(player, prisoner); + } + } + } } diff --git a/src/main/java/com/graywolf336/jail/command/CommandHandler.java b/src/main/java/com/graywolf336/jail/command/CommandHandler.java index 07b36e3..8af4a6c 100644 --- a/src/main/java/com/graywolf336/jail/command/CommandHandler.java +++ b/src/main/java/com/graywolf336/jail/command/CommandHandler.java @@ -15,10 +15,8 @@ import com.graywolf336.jail.command.commands.HandCuffCommand; import com.graywolf336.jail.command.commands.JailCheckCommand; import com.graywolf336.jail.command.commands.JailClearCommand; import com.graywolf336.jail.command.commands.JailClearForceCommand; -import com.graywolf336.jail.command.commands.JailCommand; import com.graywolf336.jail.command.commands.JailCreateCommand; import com.graywolf336.jail.command.commands.JailListCellsCommand; -import com.graywolf336.jail.command.commands.JailListCommand; import com.graywolf336.jail.command.commands.JailMuteCommand; import com.graywolf336.jail.command.commands.JailReloadCommand; import com.graywolf336.jail.command.commands.JailRemoveCellCommand; @@ -156,10 +154,8 @@ public class CommandHandler { load(JailCheckCommand.class); load(JailClearCommand.class); load(JailClearForceCommand.class); - load(JailCommand.class); load(JailCreateCommand.class); load(JailListCellsCommand.class); - load(JailListCommand.class); load(JailMuteCommand.class); load(JailReloadCommand.class); load(JailRemoveCellCommand.class); diff --git a/src/main/java/com/graywolf336/jail/command/JailHandler.java b/src/main/java/com/graywolf336/jail/command/JailHandler.java new file mode 100644 index 0000000..6553511 --- /dev/null +++ b/src/main/java/com/graywolf336/jail/command/JailHandler.java @@ -0,0 +1,167 @@ +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.beust.jcommander.JCommander; +import com.beust.jcommander.ParameterException; + +import com.graywolf336.jail.JailMain; +import com.graywolf336.jail.JailManager; +import com.graywolf336.jail.command.jcommands.JailFoundation; +import com.graywolf336.jail.command.jcommands.ListJails; +import com.graywolf336.jail.command.subcommands.JailCommand; +import com.graywolf336.jail.command.subcommands.JailListCommand; +import com.graywolf336.jail.enums.LangString; + +public class JailHandler { + private LinkedHashMap commands; + + public JailHandler(JailMain plugin) { + commands = new LinkedHashMap(); + loadCommands(); + + plugin.getLogger().info("Loaded " + commands.size() + " sub-commands of /jail."); + } + + public void handleCommand(JailManager jm, CommandSender sender, String... args) { + if(args.length == 0) { + parseCommand(jm, sender, getMatches("jail").get(0), args); + }else { + JailFoundation foundation = new JailFoundation(); + JCommander jc = new JCommander(foundation); + + //Now let's add the subcommands + jc.addCommand("list", new ListJails()); + + try { + jc.parse(args); + + List matches = getMatches(jc.getParsedCommand()); + + if(matches.size() == 0) { + //There should only be one for /jail + parseCommand(jm, sender, getMatches("jail").get(0), args); + } else if(matches.size() > 1) { + for(Command c : matches) + showUsage(sender, c); + }else { + parseCommand(jm, sender, matches.get(0), args); + } + }catch(ParameterException e) { + parseCommand(jm, sender, getMatches("jail").get(0), args); + } + } + } + + /** + * Handles the given command and checks that the command is in valid form. + * + *

+ * + * It checks in the following order: + *

    + *
  1. If they have permission for it, if they don't then we send them a message stating so.
  2. + *
  3. If the command needs a player instance, if so we send a message stating that.
  4. + *
  5. If the required minimum arguments have been passed, if not sends the usage.
  6. + *
  7. If the required maximum arguments have been passed (if there is a max, -1 if no max), if not sends the usage.
  8. + *
  9. Then executes, upon failed execution it sends the usage command.
  10. + *
+ * + * @param jailmanager The instance of {@link JailManager}. + * @param sender The sender of the command. + * @param command The name of the command. + * @param args The arguments passed to the command. + */ + public boolean parseCommand(JailManager jailmanager, CommandSender sender, Command c, String[] args) { + 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 false; + } + + // 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 false; + } + + // Now, let's check the size of the arguments passed. If it is shorter than the minimum required args, let's show the usage. + // The reason we are subtracting one is because the command is now `/jail ` and the subcommand is viewed as an argument + if(args.length - 1 < i.minimumArgs()) { + showUsage(sender, c); + return false; + } + + // 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. + // The reason we are subtracting one is because the command is now `/jail ` and the subcommand is viewed as an argument + if(i.maxArgs() != -1 && i.maxArgs() < args.length - 1) { + showUsage(sender, c); + return false; + } + + // 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 false; + }else { + return true; + } + } catch (Exception e) { + e.printStackTrace(); + jailmanager.getPlugin().getLogger().severe("An error occured while handling the command: " + i.usage()); + showUsage(sender, c); + return false; + } + } + + 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()); + } + + private void loadCommands() { + load(JailCommand.class); + load(JailListCommand.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(); + } + } +} diff --git a/src/main/java/com/graywolf336/jail/command/commands/UnjailCommand.java b/src/main/java/com/graywolf336/jail/command/commands/UnjailCommand.java index c29f6a4..7c006f9 100644 --- a/src/main/java/com/graywolf336/jail/command/commands/UnjailCommand.java +++ b/src/main/java/com/graywolf336/jail/command/commands/UnjailCommand.java @@ -6,6 +6,7 @@ import org.bukkit.entity.Player; import com.graywolf336.jail.JailManager; import com.graywolf336.jail.beans.Jail; +import com.graywolf336.jail.beans.Prisoner; import com.graywolf336.jail.command.Command; import com.graywolf336.jail.command.CommandInfo; import com.graywolf336.jail.enums.LangString; @@ -25,18 +26,26 @@ public class UnjailCommand implements Command { //Check if the player is jailed if(jm.isPlayerJailed(args[0])) { Jail j = jm.getJailPlayerIsIn(args[0]); + Prisoner pris = j.getPrisoner(args[0]); Player p = jm.getPlugin().getServer().getPlayerExact(args[0]); //Check if the player is on the server or not if(p == null) { - //The player is not, so we'll set the remaining time to zero and do it when they login next - j.getPrisoner(args[0]).setRemainingTime(0L); - j.getPrisoner(args[0]).setOfflinePending(true); - sender.sendMessage(jm.getPlugin().getJailIO().getLanguageString(LangString.WILLBEUNJAILED, args[0])); + //Check if the player has offline pending and their remaining time is above 0, if so then + //forceably unjail them + if(pris.isOfflinePending() && pris.getRemainingTime() != 0L) { + jm.getPlugin().getPrisonerManager().forceUnJail(j, j.getCellPrisonerIsIn(args[0]), p, pris); + sender.sendMessage(jm.getPlugin().getJailIO().getLanguageString(LangString.FORCEUNJAILED, args[0])); + }else { + //The player is not, so we'll set the remaining time to zero and do it when they login next + pris.setRemainingTime(0L); + pris.setOfflinePending(true); + sender.sendMessage(jm.getPlugin().getJailIO().getLanguageString(LangString.WILLBEUNJAILED, args[0])); + } }else { //Player is online, so let's try unjailing them try { - jm.getPlugin().getPrisonerManager().unJail(j, j.getCellPrisonerIsIn(args[0]), p, j.getPrisoner(args[0])); + jm.getPlugin().getPrisonerManager().unJail(j, j.getCellPrisonerIsIn(args[0]), p, pris); } catch (Exception e) { sender.sendMessage(ChatColor.RED + e.getMessage()); } diff --git a/src/main/java/com/graywolf336/jail/command/jcommands/JailFoundation.java b/src/main/java/com/graywolf336/jail/command/jcommands/JailFoundation.java new file mode 100644 index 0000000..8b595eb --- /dev/null +++ b/src/main/java/com/graywolf336/jail/command/jcommands/JailFoundation.java @@ -0,0 +1,8 @@ +package com.graywolf336.jail.command.jcommands; + +import com.beust.jcommander.Parameter; + +public class JailFoundation { + @Parameter(names = { "-v", "-verbose" }) + public boolean verbose = false; +} diff --git a/src/main/java/com/graywolf336/jail/command/parameters/JailParameters.java b/src/main/java/com/graywolf336/jail/command/jcommands/Jailing.java similarity index 73% rename from src/main/java/com/graywolf336/jail/command/parameters/JailParameters.java rename to src/main/java/com/graywolf336/jail/command/jcommands/Jailing.java index 138c023..967a712 100644 --- a/src/main/java/com/graywolf336/jail/command/parameters/JailParameters.java +++ b/src/main/java/com/graywolf336/jail/command/jcommands/Jailing.java @@ -1,4 +1,4 @@ -package com.graywolf336.jail.command.parameters; +package com.graywolf336.jail.command.jcommands; import java.util.ArrayList; import java.util.List; @@ -12,26 +12,26 @@ import com.beust.jcommander.Parameter; * @version 1.0.1 * @since 3.0.0 */ -public class JailParameters { +public class Jailing { @Parameter private List parameters = new ArrayList(); - @Parameter(names = { "-p", "-player", "-prisoner" }, description = "The name of the player we are jailing.", required = true) + @Parameter(names = { "-player", "-p", "-prisoner" }, description = "The name of the player we are jailing.") private String player = ""; - @Parameter(names = { "-t", "-time", "-length" }, description = "The length of the jailing sentence.") + @Parameter(names = { "-time", "-t", "-length" }, description = "The length of the jailing sentence.") private String time = ""; - @Parameter(names = { "-j", "-jail", "-prison" }, description = "The jail we are sending the player to.") + @Parameter(names = { "-jail", "-j", "-prison" }, description = "The jail we are sending the player to.") private String jail = ""; - @Parameter(names = { "-c", "-cell" }, description = "The cell in the jail we are sending them to.") + @Parameter(names = { "-cell", "-c"}, description = "The cell in the jail we are sending them to.") private String cell = ""; - @Parameter(names = { "-m", "-muted" }, description = "Whether they can talk or not.") + @Parameter(names = { "-muted", "-m" }, description = "Whether they can talk or not.") private boolean muted = false; - @Parameter(names = { "-r", "-reason" }, description = "The reason this player is being jailed for.", variableArity = true) + @Parameter(names = { "-reason", "-r" }, description = "The reason this player is being jailed for.", variableArity = true) private List reason = new ArrayList(); /** Returns the parameters. */ diff --git a/src/main/java/com/graywolf336/jail/command/jcommands/ListJails.java b/src/main/java/com/graywolf336/jail/command/jcommands/ListJails.java new file mode 100644 index 0000000..c3b4497 --- /dev/null +++ b/src/main/java/com/graywolf336/jail/command/jcommands/ListJails.java @@ -0,0 +1,13 @@ +package com.graywolf336.jail.command.jcommands; + +import java.util.ArrayList; +import java.util.List; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; + +@Parameters(commandDescription = "Lists all the jails in the system.") +public class ListJails { + @Parameter + private List parameters = new ArrayList(); +} diff --git a/src/main/java/com/graywolf336/jail/command/commands/JailCommand.java b/src/main/java/com/graywolf336/jail/command/subcommands/JailCommand.java similarity index 89% rename from src/main/java/com/graywolf336/jail/command/commands/JailCommand.java rename to src/main/java/com/graywolf336/jail/command/subcommands/JailCommand.java index 9b249f2..fb9bc05 100644 --- a/src/main/java/com/graywolf336/jail/command/commands/JailCommand.java +++ b/src/main/java/com/graywolf336/jail/command/subcommands/JailCommand.java @@ -1,4 +1,8 @@ -package com.graywolf336.jail.command.commands; +package com.graywolf336.jail.command.subcommands; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; @@ -13,7 +17,7 @@ import com.graywolf336.jail.beans.Jail; import com.graywolf336.jail.beans.Prisoner; import com.graywolf336.jail.command.Command; import com.graywolf336.jail.command.CommandInfo; -import com.graywolf336.jail.command.parameters.JailParameters; +import com.graywolf336.jail.command.jcommands.Jailing; import com.graywolf336.jail.enums.LangString; import com.graywolf336.jail.enums.Settings; import com.graywolf336.jail.events.PrePrisonerJailedEvent; @@ -24,7 +28,7 @@ import com.graywolf336.jail.events.PrePrisonerJailedEvent; needsPlayer = false, pattern = "jail|j", permission = "jail.command.jail", - usage = "/jail [-p name] (-t time) (-j JailName) (-c CellName) (-m Muted) (-r A reason for jailing)" + usage = "/jail [name] (-t time) (-j JailName) (-c CellName) (-m Muted) (-r A reason for jailing)" ) public class JailCommand implements Command { @@ -46,10 +50,14 @@ public class JailCommand implements Command { return true; } - JailParameters params = new JailParameters(); + //This is just to add the -p param so jCommander doesn't blow up + List arguments = new LinkedList(Arrays.asList(args)); + arguments.add(0, "-p"); + + Jailing params = new Jailing(); try { - new JCommander(params, args); + new JCommander(params, arguments.toArray(new String[arguments.size()])); }catch(ParameterException e) { sender.sendMessage(ChatColor.RED + e.getMessage()); return true; diff --git a/src/main/java/com/graywolf336/jail/command/commands/JailListCommand.java b/src/main/java/com/graywolf336/jail/command/subcommands/JailListCommand.java similarity index 88% rename from src/main/java/com/graywolf336/jail/command/commands/JailListCommand.java rename to src/main/java/com/graywolf336/jail/command/subcommands/JailListCommand.java index 11dedb1..a53c597 100644 --- a/src/main/java/com/graywolf336/jail/command/commands/JailListCommand.java +++ b/src/main/java/com/graywolf336/jail/command/subcommands/JailListCommand.java @@ -1,4 +1,4 @@ -package com.graywolf336.jail.command.commands; +package com.graywolf336.jail.command.subcommands; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; @@ -13,9 +13,9 @@ import com.graywolf336.jail.enums.LangString; maxArgs = 0, minimumArgs = 0, needsPlayer = false, - pattern = "jaillist|jl", + pattern = "list|l", permission = "jail.command.jaillist", - usage = "/jaillist" + usage = "/jail list" ) public class JailListCommand implements Command { public boolean execute(JailManager jm, CommandSender sender, String... args) { diff --git a/src/main/java/com/graywolf336/jail/enums/LangString.java b/src/main/java/com/graywolf336/jail/enums/LangString.java index d320b52..3a43396 100644 --- a/src/main/java/com/graywolf336/jail/enums/LangString.java +++ b/src/main/java/com/graywolf336/jail/enums/LangString.java @@ -38,6 +38,8 @@ public enum LangString { CELLNOTEMPTY ("jailing"), /** The message sent when someone is jailed without a reason. */ DEFAULTJAILEDREASON ("jailing"), + /** The message sent when someone is unjailed yet they never came online and so they were forcefully unjailed. */ + FORCEUNJAILED ("jailing"), /** The message sent when players are jailed without a reason. */ JAILED ("jailing"), /** The message sent when players are jailed with a reason. */ diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index 2f9add0..01f5195 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -32,6 +32,7 @@ language: cantbejailed: '&cThat player can not be jailed.' cellnotempty: '&cThe destination cell, %0%, already has a prisoner in it.' defaultjailedreason: 'Breaking the rules.' + forceunjailed: '&c%0% was jailed but never came online and was forcefully unjailed.' jailed: '&cYou have been jailed!' jailedwithreason: '&cYou have been jailed for: %0%' muted: '&cStop talking, you are in jail.' diff --git a/src/test/java/test/java/com/graywolf336/jail/TestCommandParams.java b/src/test/java/test/java/com/graywolf336/jail/TestCommandParams.java index 5afa135..a22f3ee 100644 --- a/src/test/java/test/java/com/graywolf336/jail/TestCommandParams.java +++ b/src/test/java/test/java/com/graywolf336/jail/TestCommandParams.java @@ -6,14 +6,13 @@ import org.junit.Test; import com.beust.jcommander.JCommander; import com.beust.jcommander.ParameterException; - -import com.graywolf336.jail.command.parameters.JailParameters; +import com.graywolf336.jail.command.jcommands.Jailing; public class TestCommandParams { @Test public void TestJailCommand() { - JailParameters jail = new JailParameters(); + Jailing jail = new Jailing(); //"/jail [-p name] (-t time) (-j JailName) (-c CellName) (-m Muted) (-r A reason for jailing)" String[] params = { "-p", "graywolf336", "-t", "30", "-j", "den", "-c", "cell_01", "-m", "-r", "He", "was", "a", "very", "bad", "boy." }; new JCommander(jail, params); @@ -28,8 +27,8 @@ public class TestCommandParams { @Test(expected=ParameterException.class) public void TestFailedJailCommand() { - JailParameters jail = new JailParameters(); - String[] params = { "-t", "30", "-j", "den", "-c", "cell_01", "-m", "-r", "He", "was", "a", "very", "bad", "boy." }; + Jailing jail = new Jailing(); + String[] params = { "-t", "30", "-j", "den", "-c", "cell_01", "-m true", "-r", "He", "was", "a", "very", "bad", "boy." }; new JCommander(jail, params); } diff --git a/src/test/java/test/java/com/graywolf336/jail/TestJailCommandInfo.java b/src/test/java/test/java/com/graywolf336/jail/TestJailCommandInfo.java index 8076c5f..4e67b2f 100644 --- a/src/test/java/test/java/com/graywolf336/jail/TestJailCommandInfo.java +++ b/src/test/java/test/java/com/graywolf336/jail/TestJailCommandInfo.java @@ -99,4 +99,15 @@ public class TestJailCommandInfo { verify(sender).sendMessage(ChatColor.GREEN + "First, you must select jail cuboid. Select the first point of the cuboid by right clicking on the block with your wooden sword. DO NOT FORGET TO MARK THE FLOOR AND CEILING TOO!"); verify(sender).sendMessage(ChatColor.AQUA + "--------------------------------------"); } + + @Test + public void testJailingCommand() { + Command command = mock(Command.class); + when(command.getName()).thenReturn("jail"); + String[] args = { "graywolf336", "-t", "30", "-j", "den", "-c", "cell_01", "-m", "-r", "He", "was", "a", "very", "bad", "boy." }; + + CommandSender sender = creator.getPlayerCommandSender(); + assertTrue(main.onCommand(sender, command, "jail", args)); + verify(sender).sendMessage(ChatColor.RED + "There are currently no jails."); + } }