2013-12-06 10:28:03 -06:00
|
|
|
package com.graywolf336.jail;
|
|
|
|
|
2013-12-27 10:37:32 -06:00
|
|
|
import java.io.ByteArrayInputStream;
|
|
|
|
import java.io.ByteArrayOutputStream;
|
|
|
|
import java.io.IOException;
|
2013-12-06 15:56:46 -06:00
|
|
|
import java.util.LinkedList;
|
2013-12-24 12:28:40 -06:00
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
import java.util.regex.Matcher;
|
|
|
|
import java.util.regex.Pattern;
|
2013-12-06 15:56:46 -06:00
|
|
|
|
2013-12-27 10:37:32 -06:00
|
|
|
import org.bukkit.Bukkit;
|
2013-12-06 15:56:46 -06:00
|
|
|
import org.bukkit.ChatColor;
|
|
|
|
import org.bukkit.Material;
|
2013-12-31 13:20:39 -06:00
|
|
|
import org.bukkit.entity.Player;
|
2013-12-27 10:37:32 -06:00
|
|
|
import org.bukkit.inventory.Inventory;
|
2013-12-06 15:56:46 -06:00
|
|
|
import org.bukkit.inventory.ItemStack;
|
2013-12-27 18:19:47 -06:00
|
|
|
import org.bukkit.inventory.PlayerInventory;
|
2013-12-06 15:56:46 -06:00
|
|
|
import org.bukkit.inventory.meta.ItemMeta;
|
2013-12-06 10:28:03 -06:00
|
|
|
import org.bukkit.util.Vector;
|
2013-12-27 10:37:32 -06:00
|
|
|
import org.bukkit.util.io.BukkitObjectInputStream;
|
|
|
|
import org.bukkit.util.io.BukkitObjectOutputStream;
|
|
|
|
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
|
2013-12-06 10:28:03 -06:00
|
|
|
|
2013-12-31 13:20:39 -06:00
|
|
|
import com.graywolf336.jail.beans.Prisoner;
|
|
|
|
|
2013-12-28 19:50:55 -06:00
|
|
|
/**
|
|
|
|
* Provides a variety of methods, static, that are used throughout the plugin.
|
|
|
|
*
|
|
|
|
* @author graywolf336
|
|
|
|
* @since 2.x.x
|
|
|
|
* @version 3.0.0
|
|
|
|
*/
|
2013-12-06 10:28:03 -06:00
|
|
|
public class Util {
|
2013-12-24 18:45:50 -06:00
|
|
|
private final static Pattern DURATION_PATTERN = Pattern.compile("^(\\d+)\\s*(m(?:inute)?s?|h(?:ours?)?|d(?:ays?)?|s(?:econd)?s?)?$", Pattern.CASE_INSENSITIVE);
|
2013-12-06 10:28:03 -06:00
|
|
|
|
|
|
|
/** Checks if the first {@link Vector} is inside the other two. */
|
|
|
|
public static boolean isInsideAB(Vector point, Vector first, Vector second) {
|
|
|
|
boolean x = isInside(point.getBlockX(), first.getBlockX(), second.getBlockX());
|
|
|
|
boolean y = isInside(point.getBlockY(), first.getBlockY(), second.getBlockY());
|
|
|
|
boolean z = isInside(point.getBlockZ(), first.getBlockZ(), second.getBlockZ());
|
|
|
|
|
|
|
|
return x && y && z;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if two numbers are inside a point, or something.
|
2013-12-28 19:50:55 -06:00
|
|
|
*
|
2013-12-06 10:28:03 -06:00
|
|
|
* <p />
|
|
|
|
*
|
|
|
|
* @param loc The location.
|
|
|
|
* @param first The first point
|
|
|
|
* @param second The second point
|
2013-12-28 19:50:55 -06:00
|
|
|
* @return true if they are inside, false if not.
|
2013-12-06 10:28:03 -06:00
|
|
|
*/
|
|
|
|
private static boolean isInside(int loc, int first, int second) {
|
|
|
|
int point1 = 0;
|
|
|
|
int point2 = 0;
|
|
|
|
if (first < second) {
|
|
|
|
point1 = first;
|
|
|
|
point2 = second;
|
|
|
|
} else {
|
|
|
|
point2 = first;
|
|
|
|
point1 = second;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (point1 <= loc) && (loc <= point2);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Returns a colorful message from the color codes. */
|
|
|
|
public static String getColorfulMessage(String message) {
|
|
|
|
return message.replaceAll("(?i)&([0-9abcdefklmnor])", "\u00A7$1");
|
|
|
|
}
|
2013-12-06 15:56:46 -06:00
|
|
|
|
2013-12-28 19:50:55 -06:00
|
|
|
/** Returns the wand used throughout the different creation steps. */
|
2013-12-06 15:56:46 -06:00
|
|
|
public static ItemStack getWand() {
|
|
|
|
ItemStack wand = new ItemStack(Material.WOOD_SWORD);
|
|
|
|
ItemMeta meta = wand.getItemMeta();
|
|
|
|
meta.setDisplayName(ChatColor.AQUA + "Jail Wand");
|
|
|
|
LinkedList<String> lore = new LinkedList<String>();
|
|
|
|
lore.add(ChatColor.BLUE + "The wand for creating");
|
|
|
|
lore.add(ChatColor.BLUE + "a jail or cell.");
|
|
|
|
meta.setLore(lore);
|
|
|
|
wand.setItemMeta(meta);
|
|
|
|
|
|
|
|
return wand;
|
|
|
|
}
|
2013-12-24 12:28:40 -06:00
|
|
|
|
2013-12-24 18:06:38 -06:00
|
|
|
/**
|
|
|
|
* Converts a string like '20minutes' into the appropriate amount of milliseconds.
|
|
|
|
*
|
|
|
|
* @param time The string to convert.
|
|
|
|
* @return The time in milliseconds that is converted.
|
|
|
|
* @throws Exception if there are no matches
|
|
|
|
*/
|
2013-12-24 12:28:40 -06:00
|
|
|
public static Long getTime(String time) throws Exception {
|
|
|
|
Long t = 10L;
|
|
|
|
Matcher match = DURATION_PATTERN.matcher(time);
|
|
|
|
|
|
|
|
if (match.matches()) {
|
|
|
|
String units = match.group(2);
|
|
|
|
if ("seconds".equals(units) || "second".equals(units) || "s".equals(units))
|
|
|
|
t = TimeUnit.MILLISECONDS.convert(Long.valueOf(match.group(1)), TimeUnit.SECONDS);
|
2013-12-24 19:36:14 -06:00
|
|
|
else if ("minutes".equals(units) || "minute".equals(units) || "mins".equals(units) || "min".equals(units) || "m".equals(units))
|
2013-12-24 12:28:40 -06:00
|
|
|
t = TimeUnit.MILLISECONDS.convert(Long.valueOf(match.group(1)), TimeUnit.MINUTES);
|
|
|
|
else if ("hours".equals(units) || "hour".equals(units) || "h".equals(units))
|
|
|
|
t = TimeUnit.MILLISECONDS.convert(Long.valueOf(match.group(1)), TimeUnit.HOURS);
|
|
|
|
else if ("days".equals(units) || "day".equals(units) || "d".equals(units))
|
|
|
|
t = TimeUnit.MILLISECONDS.convert(Long.valueOf(match.group(1)), TimeUnit.DAYS);
|
2013-12-24 19:36:14 -06:00
|
|
|
else {
|
|
|
|
try {
|
|
|
|
t = TimeUnit.MILLISECONDS.convert(Long.parseLong(time), TimeUnit.MINUTES);
|
|
|
|
}catch(NumberFormatException e) {
|
|
|
|
throw new Exception("Invalid format.");
|
|
|
|
}
|
|
|
|
}
|
2013-12-24 12:28:40 -06:00
|
|
|
}else {
|
2013-12-24 19:36:14 -06:00
|
|
|
throw new Exception("Invalid format.");
|
2013-12-24 12:28:40 -06:00
|
|
|
}
|
|
|
|
|
2013-12-24 18:45:50 -06:00
|
|
|
return Long.valueOf(t);
|
2013-12-24 12:28:40 -06:00
|
|
|
}
|
2013-12-27 10:37:32 -06:00
|
|
|
|
2013-12-27 18:19:47 -06:00
|
|
|
/**
|
|
|
|
* Converts the player inventory to a String array of Base64 strings. First string is the content and second string is the armor.
|
|
|
|
*
|
|
|
|
* @param playerInventory to turn into an array of strings.
|
|
|
|
* @return Array of strings: [ main content, armor content ]
|
|
|
|
* @throws IllegalStateException
|
|
|
|
*/
|
|
|
|
public static String[] playerInventoryToBase64(PlayerInventory playerInventory) throws IllegalStateException {
|
|
|
|
//get the main content part, this doesn't return the armor
|
|
|
|
String content = toBase64(playerInventory);
|
|
|
|
String armor = itemStackArrayToBase64(playerInventory.getArmorContents());
|
|
|
|
|
|
|
|
return new String[] { content, armor };
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* A method to serialize an {@link ItemStack} array to Base64 String.
|
|
|
|
*
|
|
|
|
* <p />
|
|
|
|
*
|
|
|
|
* Based off of {@link #toBase64(Inventory)}.
|
|
|
|
*
|
|
|
|
* @param items to turn into a Base64 String.
|
|
|
|
* @return Base64 string of the items.
|
|
|
|
* @throws IllegalStateException
|
|
|
|
*/
|
|
|
|
public static String itemStackArrayToBase64(ItemStack[] items) throws IllegalStateException {
|
|
|
|
try {
|
|
|
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
|
|
|
BukkitObjectOutputStream dataOutput = new BukkitObjectOutputStream(outputStream);
|
|
|
|
|
|
|
|
// Write the size of the inventory
|
|
|
|
dataOutput.writeInt(items.length);
|
|
|
|
|
|
|
|
// Save every element in the list
|
|
|
|
for (int i = 0; i < items.length; i++) {
|
|
|
|
dataOutput.writeObject(items[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Serialize that array
|
|
|
|
dataOutput.close();
|
|
|
|
return Base64Coder.encodeLines(outputStream.toByteArray());
|
|
|
|
} catch (Exception e) {
|
|
|
|
throw new IllegalStateException("Unable to save item stacks.", e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-27 10:37:32 -06:00
|
|
|
/**
|
|
|
|
* A method to serialize an inventory to Base64 string.
|
|
|
|
*
|
|
|
|
* <p />
|
|
|
|
*
|
|
|
|
* Special thanks to Comphenix in the Bukkit forums or also known
|
|
|
|
* as aadnk on GitHub.
|
|
|
|
*
|
|
|
|
* <a href="https://gist.github.com/aadnk/8138186">Original Source</a>
|
|
|
|
*
|
|
|
|
* @param inventory to serialize
|
|
|
|
* @return Base64 string of the provided inventory
|
|
|
|
* @throws IllegalStateException
|
|
|
|
*/
|
|
|
|
public static String toBase64(Inventory inventory) throws IllegalStateException {
|
|
|
|
try {
|
|
|
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
|
|
|
BukkitObjectOutputStream dataOutput = new BukkitObjectOutputStream(outputStream);
|
|
|
|
|
|
|
|
// Write the size of the inventory
|
|
|
|
dataOutput.writeInt(inventory.getSize());
|
|
|
|
|
|
|
|
// Save every element in the list
|
|
|
|
for (int i = 0; i < inventory.getSize(); i++) {
|
|
|
|
dataOutput.writeObject(inventory.getItem(i));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Serialize that array
|
|
|
|
dataOutput.close();
|
|
|
|
return Base64Coder.encodeLines(outputStream.toByteArray());
|
|
|
|
} catch (Exception e) {
|
|
|
|
throw new IllegalStateException("Unable to save item stacks.", e);
|
2013-12-27 18:19:47 -06:00
|
|
|
}
|
2013-12-27 10:37:32 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* A method to get an {@link Inventory} from an encoded, Base64, string.
|
|
|
|
*
|
|
|
|
* <p />
|
|
|
|
*
|
|
|
|
* Special thanks to Comphenix in the Bukkit forums or also known
|
|
|
|
* as aadnk on GitHub.
|
|
|
|
*
|
|
|
|
* <a href="https://gist.github.com/aadnk/8138186">Original Source</a>
|
|
|
|
*
|
|
|
|
* @param data Base64 string of data containing an inventory.
|
|
|
|
* @return Inventory created from the Base64 string.
|
|
|
|
* @throws IOException
|
|
|
|
*/
|
|
|
|
public static Inventory fromBase64(String data) throws IOException {
|
2013-12-28 15:08:24 -06:00
|
|
|
if(data.isEmpty()) Bukkit.getServer().createInventory(null, 0);
|
|
|
|
|
2013-12-27 10:37:32 -06:00
|
|
|
try {
|
|
|
|
ByteArrayInputStream inputStream = new ByteArrayInputStream(Base64Coder.decodeLines(data));
|
|
|
|
BukkitObjectInputStream dataInput = new BukkitObjectInputStream(inputStream);
|
|
|
|
Inventory inventory = Bukkit.getServer().createInventory(null, dataInput.readInt());
|
|
|
|
|
|
|
|
// Read the serialized inventory
|
|
|
|
for (int i = 0; i < inventory.getSize(); i++) {
|
|
|
|
inventory.setItem(i, (ItemStack) dataInput.readObject());
|
|
|
|
}
|
|
|
|
|
|
|
|
dataInput.close();
|
|
|
|
return inventory;
|
|
|
|
} catch (ClassNotFoundException e) {
|
|
|
|
throw new IOException("Unable to decode class type.", e);
|
|
|
|
}
|
|
|
|
}
|
2013-12-27 18:19:47 -06:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets an array of ItemStacks from Base64 string.
|
|
|
|
*
|
|
|
|
* <p />
|
|
|
|
*
|
|
|
|
* Base off of {@link #fromBase64(String)}.
|
|
|
|
*
|
|
|
|
* @param data Base64 string to convert to ItemStack array.
|
|
|
|
* @return ItemStack array created from the Base64 string.
|
|
|
|
* @throws IOException
|
|
|
|
*/
|
|
|
|
public static ItemStack[] itemStackArrayFromBase64(String data) throws IOException {
|
2013-12-28 15:08:24 -06:00
|
|
|
if(data.isEmpty()) return new ItemStack[] {};
|
|
|
|
|
2013-12-27 18:19:47 -06:00
|
|
|
try {
|
|
|
|
ByteArrayInputStream inputStream = new ByteArrayInputStream(Base64Coder.decodeLines(data));
|
|
|
|
BukkitObjectInputStream dataInput = new BukkitObjectInputStream(inputStream);
|
|
|
|
ItemStack[] items = new ItemStack[dataInput.readInt()];
|
|
|
|
|
|
|
|
// Read the serialized inventory
|
|
|
|
for (int i = 0; i < items.length; i++) {
|
|
|
|
items[i] = (ItemStack) dataInput.readObject();
|
|
|
|
}
|
|
|
|
|
|
|
|
dataInput.close();
|
|
|
|
return items;
|
|
|
|
} catch (ClassNotFoundException e) {
|
|
|
|
throw new IOException("Unable to decode class type.", e);
|
|
|
|
}
|
|
|
|
}
|
2013-12-31 13:20:39 -06:00
|
|
|
|
|
|
|
public static 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();
|
|
|
|
Bukkit.getLogger().severe("Unable to restore " + player.getName() + "'s inventory.");
|
|
|
|
}
|
|
|
|
}
|
2013-12-06 10:28:03 -06:00
|
|
|
}
|