diff --git a/README.md b/README.md index bd9d90d..0d58750 100644 --- a/README.md +++ b/README.md @@ -20,13 +20,14 @@ Done * Config value ``jailing.jail.broadcastJailing`` is now used * Config value ``jailing.jail.logToConsole`` is now used * Config value ``jailing.jail.deleteInventory`` is now used -* Config value ``jailing.release.backToPreviousPosition`` is now used +* Config value ``jailing.release.backToPreviousPosition`` is now used on jail and unjail * Config value ``jailing.release.restorePreviousGameMode`` is now used * Config value ``jailing.jail.gameMode`` is now used * Config value ``jailing.during.ignoreSleeping`` is now used in one part * Config value ``jailing.jail.commands`` is now used * Config value ``jailing.during.maxFoodLevel`` is now used in one part * Config value ``jailing.during.minFoodLevel`` is now used in one part +* Config value ``jailing.release.teleport`` is used in unjailing [Jail 3.0 JavaDoc](http://ci.graywolf336.com/job/Jail/javadoc) ==== \ No newline at end of file diff --git a/src/main/java/com/graywolf336/jail/PrisonerManager.java b/src/main/java/com/graywolf336/jail/PrisonerManager.java index ff8131e..f774629 100644 --- a/src/main/java/com/graywolf336/jail/PrisonerManager.java +++ b/src/main/java/com/graywolf336/jail/PrisonerManager.java @@ -1,6 +1,9 @@ package com.graywolf336.jail; +import java.io.IOException; + import org.bukkit.GameMode; +import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; @@ -113,7 +116,7 @@ public class PrisonerManager { prisoner.setOfflinePending(false); //We are getting ready to teleport them, so set it to true so that - //the *future* move checkers won't be cancelling our moving. + //the *future* move checkers won't be canceling our moving. prisoner.setTeleporting(true); //If their reason is empty send proper message, else send other proper message @@ -252,4 +255,128 @@ public class PrisonerManager { //Save the data, as we have changed it pl.getJailIO().saveJail(jail); } + + /** + * Unjails a prisoner from jail, removing all their data. + * + * TODO: Finish this documentation + * + * @param jail + * @param cell + * @param player + * @param prisoner + * @throws Exception + */ + public void unJail(Jail jail, Cell cell, Player player, Prisoner prisoner) throws Exception { + //Do some checks of whether the passed params are null. + if(jail == null) + throw new Exception("The jail can not be null."); + + if(prisoner == null) + throw new Exception("Prisoner data can not be null."); + + //We are getting ready to teleport them, so set it to true so that + //the *future* move checkers won't be canceling our moving. + prisoner.setTeleporting(true); + + //In case they have somehow got on a vehicle, let's unmount + //them so we can possibly teleport them + if(player.isInsideVehicle()) { + player.getVehicle().eject(); + player.getPassenger().eject(); + player.eject(); + } + + //In case we had set their sleeping state to be ignored + //let's enable their sleeping state taking place again + player.setSleepingIgnored(false); + + //If the config has us teleporting them back to their previous position + //then let's do that, but if it doesn't yet it has the teleport on release + //then let's teleport them to the free teleport location + if(pl.getConfig().getBoolean(Settings.RELEASETOPREVIOUSPOSITION.getPath(), false)) { + player.teleport(prisoner.getPreviousLocation()); + }else if(pl.getConfig().getBoolean(Settings.TELEPORTONRELEASE.getPath(), true)) { + player.teleport(jail.getTeleportFree()); + } + + //If we are to restore their previous gamemode and we have it stored, + //then by all means let's restore it + if(pl.getConfig().getBoolean(Settings.RESTOREPREVIOUSGAMEMODE.getPath(), false)) { + player.setGameMode(prisoner.getPreviousGameMode()); + } + + //Now, let's restore their inventory + //if the cell isn't null, let's check if the cell has a chest and if so then try out best to restore + //the prisoner's inventory from that + if(cell != null) { + if(cell.hasChest()) { + Inventory chest = cell.getChest().getInventory(); + + for (ItemStack item : chest.getContents()) { + if (item == null || item.getType() == Material.AIR) continue; + + if(item.getType().toString().toLowerCase().contains("helmet") && (player.getInventory().getHelmet() == null || player.getInventory().getHelmet().getType() == Material.AIR)) { + player.getInventory().setHelmet(item); + } else if(item.getType().toString().toLowerCase().contains("chestplate") && (player.getInventory().getChestplate() == null || player.getInventory().getChestplate().getType() == Material.AIR)) { + player.getInventory().setChestplate(item); + } else if(item.getType().toString().toLowerCase().contains("leg") && (player.getInventory().getLeggings() == null || player.getInventory().getLeggings().getType() == Material.AIR)) { + player.getInventory().setLeggings(item); + } else if(item.getType().toString().toLowerCase().contains("boots") && (player.getInventory().getBoots() == null || player.getInventory().getBoots().getType() == Material.AIR)) { + player.getInventory().setBoots(item); + } else if (player.getInventory().firstEmpty() == -1) { + player.getWorld().dropItem(player.getLocation(), item); + } else { + player.getInventory().addItem(item); + } + } + + chest.clear(); + }else { + restoreInventory(player, prisoner); + } + + cell.removePrisoner(); + }else { + restoreInventory(player, prisoner); + jail.removePrisoner(prisoner); + } + + pl.getJailIO().saveJail(jail); + } + + private void restoreInventory(Player player, Prisoner prisoner) { + try { + Inventory content = Util.fromBase64(prisoner.getInventory()); + ItemStack[] armor = Util.itemStackArrayFromBase64(prisoner.getArmor()); + + for(ItemStack item : armor) { + if(item == null) + continue; + else if(item.getType().toString().toLowerCase().contains("helmet")) + player.getInventory().setHelmet(item); + else if(item.getType().toString().toLowerCase().contains("chestplate")) + player.getInventory().setChestplate(item); + else if(item.getType().toString().toLowerCase().contains("leg")) + player.getInventory().setLeggings(item); + else if(item.getType().toString().toLowerCase().contains("boots")) + player.getInventory().setBoots(item); + else if (player.getInventory().firstEmpty() == -1) + player.getWorld().dropItem(player.getLocation(), item); + else + player.getInventory().addItem(item); + } + + for(ItemStack item : content.getContents()) { + if(item == null) continue; + else if(player.getInventory().firstEmpty() == -1) + player.getWorld().dropItem(player.getLocation(), item); + else + player.getInventory().addItem(item); + } + } catch (IOException e) { + e.printStackTrace(); + pl.getLogger().severe("Unable to restore " + player.getName() + "'s inventory."); + } + } } diff --git a/src/main/java/com/graywolf336/jail/Util.java b/src/main/java/com/graywolf336/jail/Util.java index 20e1fca..db5ea00 100644 --- a/src/main/java/com/graywolf336/jail/Util.java +++ b/src/main/java/com/graywolf336/jail/Util.java @@ -207,6 +207,8 @@ public class Util { * @throws IOException */ public static Inventory fromBase64(String data) throws IOException { + if(data.isEmpty()) Bukkit.getServer().createInventory(null, 0); + try { ByteArrayInputStream inputStream = new ByteArrayInputStream(Base64Coder.decodeLines(data)); BukkitObjectInputStream dataInput = new BukkitObjectInputStream(inputStream); @@ -236,6 +238,8 @@ public class Util { * @throws IOException */ public static ItemStack[] itemStackArrayFromBase64(String data) throws IOException { + if(data.isEmpty()) return new ItemStack[] {}; + try { ByteArrayInputStream inputStream = new ByteArrayInputStream(Base64Coder.decodeLines(data)); BukkitObjectInputStream dataInput = new BukkitObjectInputStream(inputStream); diff --git a/src/main/java/com/graywolf336/jail/beans/Jail.java b/src/main/java/com/graywolf336/jail/beans/Jail.java index 6061419..30e7621 100644 --- a/src/main/java/com/graywolf336/jail/beans/Jail.java +++ b/src/main/java/com/graywolf336/jail/beans/Jail.java @@ -134,6 +134,11 @@ public class Jail { this.nocellPrisoners.add(p); } + /** Removes a prisoner from this jail, doesn't remove it from the cell. */ + public void removePrisoner(Prisoner p) { + this.nocellPrisoners.remove(p); + } + /** Adds a cell to the Jail. */ public void addCell(Cell cell, boolean save) { if(save) plugin.getJailIO().saveJail(this); diff --git a/src/main/java/com/graywolf336/jail/beans/Prisoner.java b/src/main/java/com/graywolf336/jail/beans/Prisoner.java index dceb69f..4b748ce 100644 --- a/src/main/java/com/graywolf336/jail/beans/Prisoner.java +++ b/src/main/java/com/graywolf336/jail/beans/Prisoner.java @@ -35,7 +35,7 @@ public class Prisoner { this.offlinePending = false; this.teleporting = false; this.previousPosition = null; - this.previousGameMode = null; + this.previousGameMode = GameMode.SURVIVAL; this.inventory = ""; this.armor = ""; } diff --git a/src/main/java/com/graywolf336/jail/command/CommandHandler.java b/src/main/java/com/graywolf336/jail/command/CommandHandler.java index 30ed8ba..90d9a4d 100644 --- a/src/main/java/com/graywolf336/jail/command/CommandHandler.java +++ b/src/main/java/com/graywolf336/jail/command/CommandHandler.java @@ -21,6 +21,7 @@ import com.graywolf336.jail.command.commands.JailListCommand; import com.graywolf336.jail.command.commands.JailRemoveCellCommand; import com.graywolf336.jail.command.commands.JailStopCommand; import com.graywolf336.jail.command.commands.JailVersionCommand; +import com.graywolf336.jail.command.commands.UnjailCommand; /** * Where all the commands are registered at and handled, processed, at. @@ -147,6 +148,7 @@ public class CommandHandler { load(JailRemoveCellCommand.class); load(JailStopCommand.class); load(JailVersionCommand.class); + load(UnjailCommand.class); } private void load(Class c) { diff --git a/src/main/java/com/graywolf336/jail/command/commands/UnjailCommand.java b/src/main/java/com/graywolf336/jail/command/commands/UnjailCommand.java new file mode 100644 index 0000000..0dadccd --- /dev/null +++ b/src/main/java/com/graywolf336/jail/command/commands/UnjailCommand.java @@ -0,0 +1,41 @@ +package com.graywolf336.jail.command.commands; + +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.graywolf336.jail.JailManager; +import com.graywolf336.jail.beans.Jail; +import com.graywolf336.jail.command.Command; +import com.graywolf336.jail.command.CommandInfo; + +@CommandInfo( + maxArgs = 1, + minimumArgs = 1, + needsPlayer = false, + pattern = "unjail|uj", + permission = "jail.command.unjail", + usage = "/unjail [player]" + ) +public class UnjailCommand implements Command { + + public boolean execute(JailManager jm, CommandSender sender, String... args) { + if(jm.isPlayerJailed(args[0])) { + Player p = jm.getPlugin().getServer().getPlayerExact(args[0]); + if(p == null) { + sender.sendMessage(ChatColor.RED + "Offline unjailing is not implemented yet."); + }else { + Jail j = jm.getJailPlayerIsIn(args[0]); + try { + jm.getPlugin().getPrisonerManager().unJail(j, j.getCellPrisonerIsIn(args[0]), p, j.getPrisoner(args[0])); + } catch (Exception e) { + sender.sendMessage(ChatColor.RED + e.getMessage()); + } + } + }else { + sender.sendMessage(ChatColor.RED + "That player is not jailed."); + } + + return true; + } +} diff --git a/src/main/java/com/graywolf336/jail/enums/Settings.java b/src/main/java/com/graywolf336/jail/enums/Settings.java index b8a5c9d..4b3d7d9 100644 --- a/src/main/java/com/graywolf336/jail/enums/Settings.java +++ b/src/main/java/com/graywolf336/jail/enums/Settings.java @@ -15,6 +15,7 @@ public enum Settings { MINFOODLEVEL("jailing.during.minFoodLevel"), RELEASETOPREVIOUSPOSITION("jailing.release.backToPreviousPosition"), RESTOREPREVIOUSGAMEMODE("jailing.release.restorePreviousGameMode"), + TELEPORTONRELEASE("jailing.release.teleport"), UPDATENOTIFICATIONS("system.updateNotifications"); private String path;