package com.graywolf336.jail; import com.graywolf336.jail.beans.AnyCell; import com.graywolf336.jail.beans.Cell; import com.graywolf336.jail.beans.Jail; import com.graywolf336.jail.beans.NoCell; import com.graywolf336.jail.beans.Prisoner; import com.graywolf336.jail.enums.Lang; import com.graywolf336.jail.enums.Settings; import com.graywolf336.jail.events.OfflinePrisonerJailedEvent; import com.graywolf336.jail.events.PrePrisonerReleasedEvent; import com.graywolf336.jail.events.PrisonerJailedEvent; import com.graywolf336.jail.events.PrisonerReleasedEvent; import com.graywolf336.jail.events.PrisonerTransferredEvent; import com.graywolf336.jail.exceptions.AsyncUnJailingNotSupportedException; import com.graywolf336.jail.exceptions.JailRequiredException; import com.graywolf336.jail.exceptions.PrisonerAlreadyJailedException; import com.graywolf336.jail.exceptions.PrisonerRequiredException; import com.graywolf336.jail.interfaces.ICell; import org.bukkit.GameMode; import org.bukkit.Material; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import java.util.ArrayList; import java.util.List; import java.util.UUID; /** * Provides methods, non-statically, that do the preparing of jails, jailing, etc. * *
* *
*
* In this we do the following: *
*
* If you're wanting to unjail a prisoner, see the {@link #unJail(Jail, ICell, Player, Prisoner, CommandSender)} method.
*
* @param prisoner to be released.
*/
public void schedulePrisonerRelease(Prisoner prisoner) {
releases.add(prisoner);
}
private void releaseScheduledPrisoners() {
ArrayList
*
* Throws an exception if either the jail is null or the prisoner is null.
*
* @param jail where the prisoner is located at
* @param cell which the prisoner is in, can be null
* @param player instance for the prisoner we're unjailing
* @param prisoner data where everything resides
* @param sender The {@link CommandSender} who unjailed this player, can be null.
* @throws AsyncUnJailingNotSupportedException when this method is called via a thread that is not the primary thread.
* @throws JailRequiredException when the jail provided is null.
* @throws PrisonerRequiredException when the provided prisoner data is null.
*/
public void unJail(final Jail jail, ICell cell, final Player player, final Prisoner prisoner, final CommandSender sender) throws AsyncUnJailingNotSupportedException, JailRequiredException, PrisonerRequiredException {
if (!pl.getServer().isPrimaryThread()) {
throw new AsyncUnJailingNotSupportedException();
}
//Do some checks of whether the passed params are null.
if (jail == null) {
throw new JailRequiredException("unjailing a prisoner");
}
if (cell instanceof NoCell) {
cell = null;
} else if (cell instanceof AnyCell) {
cell = null;
}
if (prisoner == null) {
throw new PrisonerRequiredException("unjailing a prisoner");
}
//Throw the custom event which is called before we start releasing them
PrePrisonerReleasedEvent preEvent = new PrePrisonerReleasedEvent(jail, cell, prisoner, player);
pl.getServer().getPluginManager().callEvent(preEvent);
//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 in a vehicle, let's unmount
//them so we can possibly teleport them
if (player.isInsideVehicle()) {
player.getVehicle().eject();
player.eject();
}
//Now, let's restore their inventory if we can store it but
//first up is clearing their inventory...if we can store it
boolean store = pl.getConfig().getBoolean(Settings.JAILEDSTOREINVENTORY.getPath(), true);
if (store) {
player.closeInventory();
player.getInventory().setArmorContents(null);
player.getInventory().clear();
}
//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 (store) {
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 {
Util.restoreInventory(player, prisoner);
}
} else {
//Clear out the cell's chest just in case
//they decided to store something there
if (cell.hasChest()) {
cell.getChest().getInventory().clear();
}
}
pl.getJailIO().removePrisoner(jail, (Cell) cell, prisoner);
cell.removePrisoner();
} else {
if (store) {
Util.restoreInventory(player, prisoner);
}
pl.getJailIO().removePrisoner(jail, prisoner);
jail.removePrisoner(prisoner);
}
//In case we had set their sleeping state to be ignored
//let's enable their sleeping state taking place again
player.setSleepingIgnored(false);
pl.getServer().getScheduler().runTaskLater(pl, () -> {
//If the config has us teleporting them back to their
//previous position then let's do that
boolean tpd = false;
if (pl.getConfig().getBoolean(Settings.RELEASETOPREVIOUSPOSITION.getPath(), false)) {
if (prisoner.getPreviousLocation() != null) {
tpd = player.teleport(prisoner.getPreviousLocation());
}
}
//If they haven't already been teleported and the config has us to teleport on release,
//then we teleport players to the jail's free spot
if (!tpd && 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());
}
}, 5);
//Get the commands to execute prisoners are unjailed
//replace all of the %p% so that the commands can have a player name in them
for (String command : pl.getConfig().getStringList(Settings.COMMANDSONRELEASE.getPath())) {
command = command.replaceAll("%p%", player.getName());
command = command.replaceAll("%player%", player.getName());
command = command.replaceAll("%uuid%", player.getUniqueId().toString());
command = command.replaceAll("%reason%", prisoner.getReason());
pl.getServer().dispatchCommand(pl.getServer().getConsoleSender(), command);
}
//Remove the scoreboard to them if it is enabled
if (pl.getConfig().getBoolean(Settings.SCOREBOARDENABLED.getPath())) {
pl.getScoreBoardManager().removeScoreBoard(player);
}
//Call the prisoner released event as we have released them.
PrisonerReleasedEvent event = new PrisonerReleasedEvent(jail, cell == null ? null : (Cell) cell, prisoner, player);
pl.getServer().getPluginManager().callEvent(event);
player.sendMessage(Lang.UNJAILED.get());
if (sender != null) {
sender.sendMessage(Lang.UNJAILSUCCESS.get(player.getName()));
}
}
/**
* Forcefully unjails a {@link Prisoner prisoner} from {@link Jail}.
*
*
*
* This method forcefully removes all the references to this prisoner,
* meaning if they're offline the following won't happened:
*
* But if they're online, it goes through the regular unjailing methods.
*
*
*
* @param prisoner to release
* @param sender who is releasing the prisoner, can be null
* @throws PrisonerRequiredException when the prisoner data doesn't exist.
* @throws JailRequiredException when the prisoner isn't jailed
*/
public void forceRelease(Prisoner prisoner, CommandSender sender) throws JailRequiredException, PrisonerRequiredException {
Jail j = pl.getJailManager().getJailPrisonerIsIn(prisoner);
forceUnJail(j, j.getCellPrisonerIsIn(prisoner.getUUID()), pl.getServer().getPlayer(prisoner.getUUID()), prisoner, sender);
}
/**
* Forcefully unjails a {@link Prisoner prisoner} from {@link Jail}.
*
*
*
*
* This method forcefully removes all the references to this prisoner,
* meaning if they're offline the following won't happened:
*
* But if they're online, it goes through the regular unjailing methods.
*
*
*
* @param jail the prisoner is in
* @param cell the prisoner is in, can be null
* @param player of the prisoner, if this is null then the player won't be teleported when they come back on.
* @param prisoner to release and remove data
* @param sender who is releasing the prisoner, can be null
* @throws JailRequiredException when the provided jail is null.
* @throws PrisonerRequiredException when the provided prisoner data is null.
*/
public void forceUnJail(Jail jail, Cell cell, Player player, Prisoner prisoner, CommandSender sender) throws JailRequiredException, PrisonerRequiredException {
if (jail == null) {
throw new JailRequiredException("jailing a prisoner");
}
if (prisoner == null) {
throw new PrisonerRequiredException("jailing a prisoner");
}
if (player == null) {
//Player is offline, we just forcefully remove them from the database
pl.getJailIO().removePrisoner(jail, cell, prisoner);
if (cell == null) {
jail.removePrisoner(prisoner);
} else {
cell.removePrisoner();
}
//Call the prisoner released event as we have released them.
PrisonerReleasedEvent event = new PrisonerReleasedEvent(jail, cell, prisoner, player);
pl.getServer().getPluginManager().callEvent(event);
if (sender != null) {
sender.sendMessage(Lang.FORCEUNJAILED.get(prisoner.getLastKnownName()));
}
} else {
try {
unJail(jail, cell, player, prisoner, sender);
} catch (Exception e) {
releasePrisoner(player, prisoner);
}
}
}
/**
* Transfers the prisoner from one jail, or cell, to another jail, and/or cell.
*
* @param originJail The jail where they are coming from.
* @param originCell The cell where they are coming from.
* @param targetJail The jail we're transferring them from.
* @param targetCell The cell we're putting them into.
* @param prisoner The prisoner data we're handling.
*/
public void transferPrisoner(Jail originJail, Cell originCell, Jail targetJail, Cell targetCell, Prisoner prisoner) {
Player player = pl.getServer().getPlayer(prisoner.getUUID());
//If there is no origin cell, then we need to basically just put them to their targetJail
if (originCell == null) {
//But first thing is first, let's check if there is a targetCell we're putting them in
if (targetCell == null) {
//There is no cell, so we're just going to be putting them into
//the target jail and that's it
targetJail.addPrisoner(prisoner);
//Now then let's remove them from their old jail
originJail.removePrisoner(prisoner);
//If the player is not online, trigger them to be teleported when they
//come online again
if (player == null) {
//Set them to have an action on offline pending, so it gets triggered
prisoner.setOfflinePending(true);
//Now let's set them to be transferred when they come online next
prisoner.setToBeTransferred(true);
} else {
prisoner.setTeleporting(true);
player.teleport(targetJail.getTeleportIn());
prisoner.setTeleporting(false);
player.sendMessage(Lang.TRANSFERRED.get(targetJail.getName()));
}
} else {
//They are set to go to the targetCell, so handle accordingly
targetCell.setPrisoner(prisoner);
//If the player is not online, trigger them to be teleported when they
//come online again
if (player == null) {
//Set them to have an action on offline pending, so it gets triggered
prisoner.setOfflinePending(true);
//Now let's set them to be transferred when they come online next
prisoner.setToBeTransferred(true);
} else {
prisoner.setTeleporting(true);
player.teleport(targetCell.getTeleport());
prisoner.setTeleporting(false);
player.sendMessage(Lang.TRANSFERRED.get(targetJail.getName()));
}
}
} else {
//They are being transferred from a cell, so we need to handle getting the inventory
//and all that sort of stuff from the old cell before we transfer them over to the new cell
//If they're not being sent to a cell any more, handle that differently as well
if (targetCell == null) {
//Add them to the target jail
targetJail.addPrisoner(prisoner);
//Next, remove them from the cell
originCell.removePrisoner();
//If the cell they came from has any items from their inventory,
//let's get it all and store it
if (originCell.hasChest()) {
//Convert the inventory to base64 string and store it in the prisoner's file
prisoner.setInventory(Util.toBase64(originCell.getChest().getInventory()));
//Clear the origin cell's inventory so nothing is left behind
originCell.getChest().getInventory().clear();
}
} else {
//They are being transferred to a cell in another cell,
//we aren't going to do any sanity checks as we hope the method that is
//calling this one does those sanity checks for us.
//Set the cell's prisoner to this one
targetCell.setPrisoner(prisoner);
//Remove the prisoner from the old one
originCell.removePrisoner();
//Check if the origin cell has a chest, put all the player's inventory into it
if (originCell.hasChest()) {
//If the targetCell has a chest
if (targetCell.hasChest()) {
//Loop through the origin's chest inventory and add it to the target cell's chest
for (ItemStack i : originCell.getChest().getInventory().getContents())
if (i != null) {
targetCell.getChest().getInventory().addItem(i);
}
//Clear the origin cell's chest as it is clear now
originCell.getChest().getInventory().clear();
} else {
//targetCell has no chest so we aren't going to try and put anything into it
//Convert the inventory to base64 string and store it in the prisoner's file
prisoner.setInventory(Util.toBase64(originCell.getChest().getInventory()));
//Clear the origin cell's inventory so nothing is left behind
originCell.getChest().getInventory().clear();
}
}
}
}
//Update the signs of both cells
if (originCell != null) {
originCell.updateSigns();
}
if (targetCell != null) {
targetCell.updateSigns();
}
//Throw our custom event PrisonerTransferredEvent to say it was successful
PrisonerTransferredEvent event = new PrisonerTransferredEvent(originJail, originCell, targetJail, targetCell, prisoner, player);
pl.getServer().getPluginManager().callEvent(event);
}
}
*
*
*
*