From 5908eb67fa8e3aa31da00807ce14d8becce1609b Mon Sep 17 00:00:00 2001 From: Acrobot Date: Fri, 8 Jun 2012 15:28:36 +0200 Subject: [PATCH] - Added API (let's start with simple things first) - Copied utilities from ChestShop-4 - Made code really, really nicer to read - Made every external plugin's wrapper a listener, so it listens to events instead of being hard-coded. --- com/Acrobot/Breeze/Utils/BlockUtil.java | 19 + com/Acrobot/Breeze/Utils/InventoryUtil.java | 110 +++++ com/Acrobot/Breeze/Utils/MaterialUtil.java | 431 ++++++++++++++++++ com/Acrobot/Breeze/Utils/MessageUtil.java | 30 ++ com/Acrobot/Breeze/Utils/NumberUtil.java | 128 ++++++ com/Acrobot/Breeze/Utils/PriceUtil.java | 58 +++ com/Acrobot/Breeze/Utils/StringUtil.java | 54 +++ com/Acrobot/ChestShop/ChestShop.java | 35 +- com/Acrobot/ChestShop/Commands/ItemInfo.java | 82 ++-- com/Acrobot/ChestShop/Config/Config.java | 7 +- com/Acrobot/ChestShop/Config/Language.java | 6 +- com/Acrobot/ChestShop/Config/Property.java | 8 +- .../ChestShop/Containers/AdminChest.java | 10 +- .../ChestShop/Containers/Container.java | 12 +- .../{MinecraftChest.java => ShopChest.java} | 30 +- com/Acrobot/ChestShop/DB/Generator.java | 7 +- com/Acrobot/ChestShop/DB/Queue.java | 7 +- com/Acrobot/ChestShop/Dependencies.java | 19 +- com/Acrobot/ChestShop/Economy/EcoPlugin.java | 12 +- com/Acrobot/ChestShop/Economy/Economy.java | 10 +- .../ChestShop/Events/ItemInfoEvent.java | 37 ++ .../BuildPermissionEvent.java | 2 +- .../{ => Protection}/ProtectBlockEvent.java | 2 +- .../ProtectionCheckEvent.java | 2 +- .../ChestShop/Events/ShopCreatedEvent.java | 2 +- .../ChestShop/Events/TransactionEvent.java | 86 ++++ com/Acrobot/ChestShop/Items/DataValue.java | 106 ----- com/Acrobot/ChestShop/Items/Items.java | 126 ----- com/Acrobot/ChestShop/Items/Odd.java | 23 - .../BlockBreak.java} | 12 +- .../BlockPlace.java} | 7 +- .../EntityExplode.java} | 2 +- .../ChestShop/Listeners/Block/SignChange.java | 198 ++++++++ .../ChestShop/Listeners/ItemInfoListener.java | 70 +++ .../Listeners/Player/PlayerConnect.java | 28 ++ .../Listeners/Player/PlayerInteract.java | 150 ++++++ .../Listeners/Player/ShortNameSaver.java | 16 + .../Transaction/EmptyShopDeleter.java | 35 ++ .../Transaction/TransactionLogger.java | 79 ++++ .../Transaction/TransactionMessageSender.java | 95 ++++ .../ChestShop/Listeners/playerInteract.java | 121 ----- .../ChestShop/Listeners/signChange.java | 225 --------- com/Acrobot/ChestShop/Logging/Logging.java | 81 ---- com/Acrobot/ChestShop/Plugins/ChestShop.java | 13 +- com/Acrobot/ChestShop/Plugins/Deadbolt.java | 7 +- .../Plugins/LightweightChestProtection.java | 31 +- com/Acrobot/ChestShop/Plugins/Lockette.java | 2 +- .../ChestShop/Plugins/SimpleChestLock.java | 2 +- com/Acrobot/ChestShop/Plugins/Towny.java | 2 +- .../ChestShop/Plugins/WorldGuardBuilding.java | 2 +- .../Plugins/WorldGuardProtection.java | 2 +- com/Acrobot/ChestShop/Security.java | 23 +- com/Acrobot/ChestShop/Shop/Shop.java | 359 ++++++++------- .../ChestShop/Shop/ShopManagement.java | 48 -- .../ChestShop/Signs/ChestShopSign.java | 65 +++ .../ChestShop/Signs/restrictedSign.java | 48 +- com/Acrobot/ChestShop/Utils/uBlock.java | 30 +- com/Acrobot/ChestShop/Utils/uEnchantment.java | 56 --- com/Acrobot/ChestShop/Utils/uInventory.java | 144 ------ com/Acrobot/ChestShop/Utils/uNumber.java | 44 -- com/Acrobot/ChestShop/Utils/uSign.java | 109 ----- com/lennardf1989/bukkitex/Database.java | 4 +- .../register/payment/forChestShop/Method.java | 88 ++-- .../payment/forChestShop/Methods.java | 68 +-- plugin.yml | 2 +- 65 files changed, 2208 insertions(+), 1521 deletions(-) create mode 100644 com/Acrobot/Breeze/Utils/BlockUtil.java create mode 100644 com/Acrobot/Breeze/Utils/InventoryUtil.java create mode 100644 com/Acrobot/Breeze/Utils/MaterialUtil.java create mode 100644 com/Acrobot/Breeze/Utils/MessageUtil.java create mode 100644 com/Acrobot/Breeze/Utils/NumberUtil.java create mode 100644 com/Acrobot/Breeze/Utils/PriceUtil.java create mode 100644 com/Acrobot/Breeze/Utils/StringUtil.java rename com/Acrobot/ChestShop/Containers/{MinecraftChest.java => ShopChest.java} (53%) create mode 100644 com/Acrobot/ChestShop/Events/ItemInfoEvent.java rename com/Acrobot/ChestShop/Events/{ => Protection}/BuildPermissionEvent.java (96%) rename com/Acrobot/ChestShop/Events/{ => Protection}/ProtectBlockEvent.java (94%) rename com/Acrobot/ChestShop/Events/{ => Protection}/ProtectionCheckEvent.java (94%) create mode 100644 com/Acrobot/ChestShop/Events/TransactionEvent.java delete mode 100644 com/Acrobot/ChestShop/Items/DataValue.java delete mode 100644 com/Acrobot/ChestShop/Items/Items.java delete mode 100644 com/Acrobot/ChestShop/Items/Odd.java rename com/Acrobot/ChestShop/Listeners/{blockBreak.java => Block/BlockBreak.java} (93%) rename com/Acrobot/ChestShop/Listeners/{blockPlace.java => Block/BlockPlace.java} (84%) rename com/Acrobot/ChestShop/Listeners/{entityExplode.java => Block/EntityExplode.java} (94%) create mode 100644 com/Acrobot/ChestShop/Listeners/Block/SignChange.java create mode 100644 com/Acrobot/ChestShop/Listeners/ItemInfoListener.java create mode 100644 com/Acrobot/ChestShop/Listeners/Player/PlayerConnect.java create mode 100644 com/Acrobot/ChestShop/Listeners/Player/PlayerInteract.java create mode 100644 com/Acrobot/ChestShop/Listeners/Player/ShortNameSaver.java create mode 100644 com/Acrobot/ChestShop/Listeners/Transaction/EmptyShopDeleter.java create mode 100644 com/Acrobot/ChestShop/Listeners/Transaction/TransactionLogger.java create mode 100644 com/Acrobot/ChestShop/Listeners/Transaction/TransactionMessageSender.java delete mode 100644 com/Acrobot/ChestShop/Listeners/playerInteract.java delete mode 100644 com/Acrobot/ChestShop/Listeners/signChange.java delete mode 100644 com/Acrobot/ChestShop/Logging/Logging.java delete mode 100644 com/Acrobot/ChestShop/Shop/ShopManagement.java create mode 100644 com/Acrobot/ChestShop/Signs/ChestShopSign.java delete mode 100644 com/Acrobot/ChestShop/Utils/uEnchantment.java delete mode 100644 com/Acrobot/ChestShop/Utils/uInventory.java delete mode 100644 com/Acrobot/ChestShop/Utils/uNumber.java delete mode 100644 com/Acrobot/ChestShop/Utils/uSign.java diff --git a/com/Acrobot/Breeze/Utils/BlockUtil.java b/com/Acrobot/Breeze/Utils/BlockUtil.java new file mode 100644 index 0000000..fbb9cf3 --- /dev/null +++ b/com/Acrobot/Breeze/Utils/BlockUtil.java @@ -0,0 +1,19 @@ +package com.Acrobot.Breeze.Utils; + +import org.bukkit.block.Block; +import org.bukkit.block.Sign; + +/** + * @author Acrobot + */ +public class BlockUtil { + /** + * Checks if the block is a sign + * + * @param block Block to check + * @return Is this block a sign? + */ + public static boolean isSign(Block block) { + return block.getState() instanceof Sign; + } +} diff --git a/com/Acrobot/Breeze/Utils/InventoryUtil.java b/com/Acrobot/Breeze/Utils/InventoryUtil.java new file mode 100644 index 0000000..5e99442 --- /dev/null +++ b/com/Acrobot/Breeze/Utils/InventoryUtil.java @@ -0,0 +1,110 @@ +package com.Acrobot.Breeze.Utils; + +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author Acrobot + */ +public class InventoryUtil { + /** + * Returns the amount of the item inside the inventory + * + * @param item Item to check + * @param inventory inventory + * @return amount of the item + */ + public static int getAmount(ItemStack item, Inventory inventory) { + if (!inventory.contains(item.getType())) { + return 0; + } + + HashMap items = inventory.all(item.getType()); + int itemAmount = 0; + + for (ItemStack iStack : items.values()) { + if (!MaterialUtil.equals(iStack, item)) { + continue; + } + + itemAmount += iStack.getAmount(); + } + + return itemAmount; + } + + /** + * Checks if the item fits the inventory + * + * @param item Item to check + * @param inventory inventory + * @return Does item fit inside inventory? + */ + public static boolean fits(ItemStack item, Inventory inventory) { + int left = item.getAmount(); + + for (ItemStack iStack : inventory.getContents()) { + if (left <= 0) { + return true; + } + + if (MaterialUtil.isEmpty(iStack)) { + left -= inventory.getMaxStackSize(); + continue; + } + + if (!MaterialUtil.equals(iStack, item)) { + continue; + } + + left -= (iStack.getMaxStackSize() - iStack.getAmount()); + } + + return left <= 0; + } + + /** + * Adds an item to the inventory + * + * @param item Item to add + * @param inventory Inventory + * @return Number of leftover items + */ + public static int add(ItemStack item, Inventory inventory) { + Map leftovers = inventory.addItem(item); + + return countItems(leftovers); + } + + /** + * Removes an item from the inventory + * + * @param item Item to remove + * @param inventory Inventory + * @return Number of items that couldn't be removed + */ + public static int remove(ItemStack item, Inventory inventory) { + Map leftovers = inventory.removeItem(item); + + return countItems(leftovers); + } + + /** + * Counts leftovers from a map + * + * @param items Leftovers + * @return Number of leftovers + */ + private static int countItems(Map items) { + int totalLeft = 0; + + for (int left : items.keySet()) { + totalLeft += left; + } + + return totalLeft; + } +} diff --git a/com/Acrobot/Breeze/Utils/MaterialUtil.java b/com/Acrobot/Breeze/Utils/MaterialUtil.java new file mode 100644 index 0000000..37b4129 --- /dev/null +++ b/com/Acrobot/Breeze/Utils/MaterialUtil.java @@ -0,0 +1,431 @@ +package com.Acrobot.Breeze.Utils; + +import info.somethingodd.bukkit.OddItem.OddItem; +import org.bukkit.CoalType; +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.TreeSpecies; +import org.bukkit.entity.EntityType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.material.*; + +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author Acrobot + */ +public class MaterialUtil { + private static final Pattern DURABILITY = Pattern.compile(":(\\d)*"); + private static final Pattern ENCHANTMENT = Pattern.compile("-([0-9a-zA-Z])*"); + + /** + * Checks if the itemStack is empty or null + * + * @param item Item to check + * @return Is the itemStack empty? + */ + public static boolean isEmpty(ItemStack item) { + return item == null || item.getType() == Material.AIR; + } + + /** + * Checks if the itemStacks are equal, ignoring their amount + * + * @param one first itemStack + * @param two second itemStack + * @return Are they equal? + */ + public static boolean equals(ItemStack one, ItemStack two) { + if (one.getType() != two.getType()) { + return false; + } + + if (one.getDurability() != two.getDurability()) { + return false; + } + + return one.getEnchantments().equals(two.getEnchantments()); + } + + /** + * Gives you a Material from a String (doesn't have to be fully typed in) + * + * @param name Name of the material + * @return Material found + */ + public static Material getMaterial(String name) { + Material material = Material.matchMaterial(name); + + if (material != null) { + return material; + } + + name = name.toUpperCase().replace(" ", "_"); + + short length = Short.MAX_VALUE; + + for (Material currentMaterial : Material.values()) { + String matName = currentMaterial.name(); + + if (matName.startsWith(name) && matName.length() < length) { + length = (short) matName.length(); + material = currentMaterial; + } + } + + return material; + } + + /** + * Returns item's name + * + * @param itemStack ItemStack to name + * @return ItemStack's name + */ + public static String getName(ItemStack itemStack) { + return getName(itemStack, true); + } + + /** + * Returns item's name + * + * @param itemStack ItemStack to name + * @param showDataValue Should we also show the data value? + * @return ItemStack's name + */ + public static String getName(ItemStack itemStack, boolean showDataValue) { + String dataName = DataValue.name(itemStack); + + if (dataName != null && showDataValue) { + return StringUtil.capitalizeFirstLetter(dataName + '_' + itemStack.getType(), '_'); + } else { + return StringUtil.capitalizeFirstLetter(itemStack.getType().toString(), '_'); + } + } + + /** + * Returns item's name, just like on the sign + * + * @param itemStack ItemStack to name + * @return ItemStack's name + */ + public static String getSignName(ItemStack itemStack) { + StringBuilder name = new StringBuilder(15); + + name.append(itemStack.getType().name()); + + if (itemStack.getDurability() != 0) { + name.append(':').append(itemStack.getDurability()); + } + + if (!itemStack.getEnchantments().isEmpty()) { + name.append('-').append(MaterialUtil.Enchantment.encodeEnchantment(itemStack)); + } + + return name.toString(); + } + + /** + * Gives you an ItemStack from a String + * + * @param itemName Item name + * @return ItemStack + */ + public static ItemStack getItem(String itemName) { + ItemStack itemStack = Odd.getFromString(itemName); + + if (itemStack != null) { + return itemStack; + } + + String[] split = itemName.trim().split(":|-"); + + if (split.length == 0) { + return null; + } + + Material material = getMaterial(split[0]); + + boolean onlyPartiallyChecked = false; + + if (material == null) { + int index = split[0].indexOf(' '); + if (index == -1) { + return null; + } + + material = getMaterial(split[0].substring(index + 1)); + + if (material == null) { + return null; + } + + onlyPartiallyChecked = true; + } + + itemStack = new ItemStack(material, 1); + + short durability = getDurability(itemName); + + if (durability == 0 && onlyPartiallyChecked) { + String[] spaces = itemName.split(" "); + if (spaces.length != 0) { + durability = DataValue.get(spaces[0], material); + } + } + + itemStack.setDurability(durability); + + Map enchantments = getEnchantments(itemName); + + if (!enchantments.isEmpty()) { + itemStack.addEnchantments(enchantments); + } + + return itemStack; + } + + /** + * Returns the durability from a string + * + * @param itemName Item name + * @return Durability found + */ + public static short getDurability(String itemName) { + Matcher m = DURABILITY.matcher(itemName); + + if (!m.find()) { + return 0; + } + + String data = m.group(); + + if (data == null || data.isEmpty()) { + return 0; + } + + data = data.substring(1); + + return NumberUtil.isInteger(data) ? Short.valueOf(data) : 0; + } + + /** + * Returns enchantments from a string + * + * @param itemName Item name + * @return Enchantments found + */ + public static Map getEnchantments(String itemName) { + Matcher m = ENCHANTMENT.matcher(itemName); + + if (!m.find()) { + return new HashMap(); + } + + String group = m.group().substring(1); + return Enchantment.getEnchantments(group); + } + + public static class Enchantment { + /** + * Returns enchantments this itemName contains + * + * @param base32 The encoded enchantment + * @return Enchantments found + */ + public static Map getEnchantments(String base32) { + if (base32 == null) { + return new HashMap(); + } + + Map map = new HashMap(); + + StringBuilder integer = new StringBuilder(String.valueOf(Integer.parseInt(base32, 32))); + + while (integer.length() % 3 != 0) { + integer.insert(0, '0'); + } + + for (int i = 0; i < integer.length() / 3; i++) { + String item = integer.substring(i * 3, i * 3 + 3); + + org.bukkit.enchantments.Enchantment enchantment = org.bukkit.enchantments.Enchantment.getById(Integer.parseInt(item.substring(0, 2))); + + if (enchantment == null) { + continue; + } + + int level = Integer.parseInt(item.substring(2)); + + if (level > enchantment.getMaxLevel() || level < enchantment.getStartLevel()) { + continue; + } + + map.put(enchantment, level); + } + + return map; + } + + /** + * Encodes enchantments + * They are being encoded in a string like XXL (XXLXXL), where L is the enchantment level and XX is the ID + * Then the string is being encoded in base-32 string + * + * @param enchantments Enchantments to encode + * @return Encoded enchantments + */ + public static String encodeEnchantment(Map enchantments) { + int integer = 0; + + for (Map.Entry entry : enchantments.entrySet()) { + integer = integer * 1000 + (entry.getKey().getId()) * 10 + entry.getValue(); + } + + return integer != 0 ? Integer.toString(integer, 32) : null; + } + + /** + * Encodes enchantments + * They are being encoded in a string like XXL (XXLXXL), where L is the enchantment level and XX is the ID + * Then the string is being encoded in base-32 string + * + * @param item Item to encode + * @return Encoded enchantments + */ + public static String encodeEnchantment(ItemStack item) { + return encodeEnchantment(item.getEnchantments()); + } + } + + public static class DataValue { + /** + * Gets the data value from a string + * + * @param type Data Value string + * @param material Material + * @return data value + */ + public static byte get(String type, Material material) { + if (material == null || material.getData() == null) { + return 0; + } + + type = type.toUpperCase().replace(" ", "_"); + + MaterialData materialData = material.getNewData((byte) 0); + + if (materialData instanceof TexturedMaterial) { + TexturedMaterial texturedMaterial = (TexturedMaterial) materialData; + + for (Material mat : texturedMaterial.getTextures()) { + if (mat.name().startsWith(type) && !mat.equals(material)) { + return (byte) texturedMaterial.getTextures().indexOf(mat); + } + } + } else if (materialData instanceof Colorable) { + DyeColor color; + + try { + color = DyeColor.valueOf(type); + } catch (IllegalArgumentException exception) { + return 0; + } + + if (material == Material.INK_SACK) { + color = DyeColor.getByData((byte) (15 - color.getData())); + } + + return color.getData(); + } else if (materialData instanceof Tree) { + try { + return TreeSpecies.valueOf(type).getData(); + } catch (IllegalArgumentException ex) { + return 0; + } + } else if (materialData instanceof SpawnEgg) { + try { + EntityType entityType = EntityType.valueOf(type); + + return (byte) entityType.getTypeId(); + } catch (IllegalArgumentException ex) { + return 0; + } + } else if (materialData instanceof Coal) { + try { + return CoalType.valueOf(type).getData(); + } catch (IllegalArgumentException ex) { + return 0; + } + } + + return 0; + } + + /** + * Returns a string with the DataValue + * + * @param itemStack ItemStack to describe + * @return Data value string + */ + public static String name(ItemStack itemStack) { + MaterialData data = itemStack.getData(); + + if (data == null) { + return null; + } + + if (data instanceof TexturedMaterial) { + return ((TexturedMaterial) data).getMaterial().name(); + } else if (data instanceof Colorable) { + return ((Colorable) data).getColor().name(); + } else if (data instanceof Tree) { + //TreeSpecies specie = TreeSpecies.getByData((byte) (data.getData() & 3)); //This works, but not as intended + TreeSpecies specie = ((Tree) data).getSpecies(); + return (specie != null && specie != TreeSpecies.GENERIC ? specie.name() : null); + } else if (data instanceof SpawnEgg) { + EntityType type = ((SpawnEgg) data).getSpawnedType(); + return (type != null ? type.name() : null); + } else if (data instanceof Coal) { + CoalType coal = ((Coal) data).getType(); + return (coal != null && coal != CoalType.COAL ? coal.name() : null); + } else { + return null; + } + } + } + + public static class Odd { + private static boolean isInitialized = false; + + /** + * Returns the item stack from OddItem plugin + * + * @param itemName Item name to parse + * @return itemStack that was parsed + */ + public static ItemStack getFromString(String itemName) { + if (!isInitialized) { + return null; + } + + String name = itemName.replace(':', ';'); + + try { + return OddItem.getItemStack(name); + } catch (Exception ex) { + return null; + } + } + + /** + * Lets the class know that it's safe to use the OddItem methods now + */ + public static void initialize() { + isInitialized = true; + } + } +} diff --git a/com/Acrobot/Breeze/Utils/MessageUtil.java b/com/Acrobot/Breeze/Utils/MessageUtil.java new file mode 100644 index 0000000..8b6bcdd --- /dev/null +++ b/com/Acrobot/Breeze/Utils/MessageUtil.java @@ -0,0 +1,30 @@ +package com.Acrobot.Breeze.Utils; + +import com.Acrobot.ChestShop.Config.Config; +import com.Acrobot.ChestShop.Config.Language; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +/** + * @author Acrobot + */ +public class MessageUtil { + public static void sendMessage(CommandSender sender, Language message) { + String toSend = Config.getLocal(message); + + sender.sendMessage(toSend); + } + + public static boolean sendMessage(String playerName, Language message) { + Player player = Bukkit.getPlayer(playerName); + + if (player != null) { + sendMessage(player, message); + } else { + return false; + } + + return true; + } +} diff --git a/com/Acrobot/Breeze/Utils/NumberUtil.java b/com/Acrobot/Breeze/Utils/NumberUtil.java new file mode 100644 index 0000000..4a3f6f1 --- /dev/null +++ b/com/Acrobot/Breeze/Utils/NumberUtil.java @@ -0,0 +1,128 @@ +package com.Acrobot.Breeze.Utils; + +/** + * @author Acrobot + */ +public class NumberUtil { + /** + * Checks if the string is a integer + * + * @param string string to check + * @return Is the string integer? + */ + public static boolean isInteger(String string) { + try { + Integer.parseInt(string); + return true; + } catch (NumberFormatException e) { + return false; + } + } + + /** + * Checks if the string is a float + * + * @param string string to check + * @return Is the string float? + */ + public static boolean isFloat(String string) { + try { + Float.parseFloat(string); + return true; + } catch (NumberFormatException e) { + return false; + } + } + + /** + * Checks if the string is a double + * + * @param string string to check + * @return Is the string double? + */ + public static boolean isDouble(String string) { + try { + Double.parseDouble(string); + return true; + } catch (NumberFormatException e) { + return false; + } + } + + /** + * Checks if the string is a short + * + * @param string string to check + * @return Is the string short? + */ + public static boolean isShort(String string) { + try { + Short.parseShort(string); + return true; + } catch (NumberFormatException e) { + return false; + } + } + + /** + * Rounds the number up to two digit points (Can be inaccurate due to using decimal-points) + * + * @param number Number to round + * @return Rounded number + */ + public static double roundUp(double number) { + return Math.ceil(number * 100) / 100; + } + + /** + * Converts the number (in seconds) to timer-like format, like 2:00 (minutes:seconds) + * + * @param number Number of seconds + * @return Formatted string + */ + public static String toTime(int number) { + int minutes = number / 60; + String seconds = Integer.toString(number % 60); + + if (seconds.length() != 2) { + seconds = '0' + seconds; + } + + return minutes + ":" + seconds; + } + + /** + * Converts a number to roman + * + * @param number number to convert + * @return Converted number + */ + public static String toRoman(int number) { + if (number < 1 || number > 9) { + throw new IllegalArgumentException("The number must be in range 1-9 (This is only for enchantment level decoration)"); + } + + switch (number) { + case 1: + return "I"; + case 2: + return "II"; + case 3: + return "III"; + case 4: + return "IV"; + case 5: + return "V"; + case 6: + return "VI"; + case 7: + return "VII"; + case 8: + return "VIII"; + case 9: + return "IX"; + default: + return Integer.toString(number); + } + } +} diff --git a/com/Acrobot/Breeze/Utils/PriceUtil.java b/com/Acrobot/Breeze/Utils/PriceUtil.java new file mode 100644 index 0000000..0eb0300 --- /dev/null +++ b/com/Acrobot/Breeze/Utils/PriceUtil.java @@ -0,0 +1,58 @@ +package com.Acrobot.Breeze.Utils; + +/** + * @author Acrobot + */ +public class PriceUtil { + public static final double NO_PRICE = -1; + public static final double FREE = 0; + + public static final String FREE_TEXT = "free"; + + /** + * Gets the price from the text + * @param text Text to check + * @param indicator Price indicator (for example, B for buy) + * @return price + */ + public static double get(String text, char indicator) { + String[] split = text.replace(" ", "").toLowerCase().split(":"); + String character = String.valueOf(indicator); + + for (String part : split) { + if (!part.contains(character)) { + continue; + } + + part = part.replace(character, ""); + + if (part.equals(FREE_TEXT)) { + return FREE; + } + + if (NumberUtil.isDouble(part)) { + return Double.valueOf(part); + } + } + + return NO_PRICE; + } + + /** + * Gets the buy price from te text + * @param text Text to check + * @return Buy price + */ + public static double getBuyPrice(String text) { + return get(text, 'b'); + } + + /** + * Gets the sell price from te text + * @param text Text to check + * @return Sell price + */ + public static double getSellPrice(String text) { + return get(text, 's'); + } +} diff --git a/com/Acrobot/Breeze/Utils/StringUtil.java b/com/Acrobot/Breeze/Utils/StringUtil.java new file mode 100644 index 0000000..3efea65 --- /dev/null +++ b/com/Acrobot/Breeze/Utils/StringUtil.java @@ -0,0 +1,54 @@ +package com.Acrobot.Breeze.Utils; + +/** + * @author Acrobot + */ +public class StringUtil { + + /** + * Capitalizes every first letter of a word + * + * @param string String to reformat + * @param separator Word separator + * @return Reformatted string + */ + public static String capitalizeFirstLetter(String string, char separator) { + string = string.toLowerCase(); + + String[] split = string.split(Character.toString(separator)); + StringBuilder total = new StringBuilder(string.length()); + + for (String s : split) { + total.append(Character.toUpperCase(s.charAt(0))).append(s.substring(1)).append(' '); + } + + return total.toString().trim(); + } + + /** + * Capitalizes every first letter of a word + * + * @param string String to reformat + * @return Reformatted string + * @see com.Acrobot.Breeze.Utils.StringUtil#capitalizeFirstLetter(String, char) + */ + public static String capitalizeFirstLetter(String string) { + return capitalizeFirstLetter(string, ' '); + } + + /** + * Joins a String array + * + * @param array array to join + * @return Joined array + */ + public static String joinArray(String[] array) { + StringBuilder b = new StringBuilder(array.length * 15); + + for (String str : array) { + b.append(str).append(' '); + } + + return b.toString(); + } +} diff --git a/com/Acrobot/ChestShop/ChestShop.java b/com/Acrobot/ChestShop/ChestShop.java index eaddc78..3886af3 100644 --- a/com/Acrobot/ChestShop/ChestShop.java +++ b/com/Acrobot/ChestShop/ChestShop.java @@ -7,10 +7,21 @@ import com.Acrobot.ChestShop.Config.Property; import com.Acrobot.ChestShop.DB.Generator; import com.Acrobot.ChestShop.DB.Queue; import com.Acrobot.ChestShop.DB.Transaction; -import com.Acrobot.ChestShop.Listeners.*; +import com.Acrobot.ChestShop.Listeners.Block.BlockBreak; +import com.Acrobot.ChestShop.Listeners.Block.BlockPlace; +import com.Acrobot.ChestShop.Listeners.Block.EntityExplode; +import com.Acrobot.ChestShop.Listeners.Block.SignChange; +import com.Acrobot.ChestShop.Listeners.ItemInfoListener; +import com.Acrobot.ChestShop.Listeners.Player.PlayerConnect; +import com.Acrobot.ChestShop.Listeners.Player.PlayerInteract; +import com.Acrobot.ChestShop.Listeners.Player.ShortNameSaver; +import com.Acrobot.ChestShop.Listeners.Transaction.EmptyShopDeleter; +import com.Acrobot.ChestShop.Listeners.Transaction.TransactionLogger; +import com.Acrobot.ChestShop.Listeners.Transaction.TransactionMessageSender; import com.Acrobot.ChestShop.Logging.FileFormatter; import com.avaje.ebean.EbeanServer; import com.lennardf1989.bukkitex.Database; +import org.bukkit.Bukkit; import org.bukkit.Server; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.event.Event; @@ -60,7 +71,7 @@ public class ChestShop extends JavaPlugin { setupDB(); } if (Config.getBoolean(Property.GENERATE_STATISTICS_PAGE)) { - File htmlFolder = new File(dataFolder, "HTML"); + File htmlFolder = new File(Config.getString(Property.STATISTICS_PAGE_PATH)); scheduleTask(new Generator(htmlFolder), 300L, (long) Config.getDouble(Property.STATISTICS_PAGE_GENERATION_INTERVAL) * 20L); } if (Config.getBoolean(Property.LOG_TO_FILE)) { @@ -122,8 +133,18 @@ public class ChestShop extends JavaPlugin { registerEvent(new BlockBreak()); registerEvent(new BlockPlace()); registerEvent(new SignChange()); - registerEvent(new PlayerInteract(Config.getInteger(Property.SHOP_INTERACTION_INTERVAL))); registerEvent(new EntityExplode()); + registerEvent(new PlayerConnect()); + + registerEvent(new ItemInfoListener()); + + registerEvent(new EmptyShopDeleter()); + registerEvent(new TransactionLogger()); + registerEvent(new TransactionMessageSender()); + + registerEvent(new ShortNameSaver()); + + registerEvent(new PlayerInteract(Config.getInteger(Property.SHOP_INTERACTION_INTERVAL))); } public void registerEvent(Listener listener) { @@ -206,10 +227,6 @@ public class ChestShop extends JavaPlugin { return description.getSoftDepend(); } - public static PluginManager getPluginManager() { - return pluginManager; - } - public static void registerListener(Listener listener) { plugin.registerEvent(listener); } @@ -217,4 +234,8 @@ public class ChestShop extends JavaPlugin { public static void callEvent(Event event) { pluginManager.callEvent(event); } + + public static void scheduleRepeating(Runnable runnable, int delay) { + Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, runnable, 0, delay); + } } diff --git a/com/Acrobot/ChestShop/Commands/ItemInfo.java b/com/Acrobot/ChestShop/Commands/ItemInfo.java index 5424aec..24bedfd 100644 --- a/com/Acrobot/ChestShop/Commands/ItemInfo.java +++ b/com/Acrobot/ChestShop/Commands/ItemInfo.java @@ -1,76 +1,72 @@ package com.Acrobot.ChestShop.Commands; -import com.Acrobot.ChestShop.Config.Config; +import com.Acrobot.Breeze.Utils.MaterialUtil; +import com.Acrobot.Breeze.Utils.MessageUtil; +import com.Acrobot.Breeze.Utils.StringUtil; +import com.Acrobot.ChestShop.ChestShop; import com.Acrobot.ChestShop.Config.Language; -import com.Acrobot.ChestShop.Items.Items; -import com.Acrobot.ChestShop.Utils.uEnchantment; -import com.Acrobot.ChestShop.Utils.uSign; +import com.Acrobot.ChestShop.Events.ItemInfoEvent; import org.bukkit.ChatColor; -import org.bukkit.Material; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.Player; +import org.bukkit.entity.HumanEntity; import org.bukkit.inventory.ItemStack; -import java.util.Map; - /** * @author Acrobot */ public class ItemInfo implements CommandExecutor { public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { ItemStack item; + if (args.length == 0) { - if (!(sender instanceof Player)) return false; - item = ((Player) sender).getItemInHand(); + if (!(sender instanceof HumanEntity)) { + return false; + } + + item = ((HumanEntity) sender).getItemInHand(); } else { - item = Items.getItemStack(joinArray(args)); + item = MaterialUtil.getItem(StringUtil.joinArray(args)); } - if (item == null || item.getType() == Material.AIR) return false; + if (MaterialUtil.isEmpty(item)) { + return false; + } - String durability = (item.getDurability() != 0 ? ChatColor.DARK_GREEN + ":" + item.getDurability() : ""); - String ench = uEnchantment.getEnchantment(item); - String enchantment = (ench != null ? ChatColor.DARK_AQUA + "-" + ench : ""); + String durability = getDurability(item); + String enchantment = getEnchantment(item); - sender.sendMessage(Config.getLocal(Language.iteminfo)); - String itemname = Items.getName(item); - sender.sendMessage(ChatColor.GRAY + itemname + ChatColor.WHITE + " " - + item.getTypeId() + durability + enchantment + ChatColor.WHITE); + MessageUtil.sendMessage(sender, Language.iteminfo); + sender.sendMessage(getNameAndID(item) + durability + enchantment + ChatColor.WHITE); - Map map = item.getEnchantments(); - for (Map.Entry e : map.entrySet()) - sender.sendMessage(ChatColor.DARK_GRAY + uSign.capitalizeFirstLetter(e.getKey().getName()) + ' ' + intToRoman(e.getValue())); + ItemInfoEvent event = new ItemInfoEvent(sender, item); + ChestShop.callEvent(event); return true; - } - private static String intToRoman(int integer) { - switch (integer) { - case 1: - return "I"; - case 2: - return "II"; - case 3: - return "III"; - case 4: - return "IV"; - case 5: - return "V"; - default: - return Integer.toString(integer); + private static String getNameAndID(ItemStack item) { + String itemName = MaterialUtil.getName(item); + + return ChatColor.GRAY + itemName + ChatColor.WHITE + " " + item.getTypeId(); + } + + private static String getDurability(ItemStack item) { + if (item.getDurability() != 0) { + return ChatColor.DARK_GREEN + ":" + Integer.toString(item.getDurability()); + } else { + return ""; } } + private static String getEnchantment(ItemStack item) { + String encodedEnchantments = MaterialUtil.Enchantment.encodeEnchantment(item); - private static String joinArray(String[] array) { - StringBuilder b = new StringBuilder(array.length); - for (String s : array) { - b.append(s).append(' '); + if (encodedEnchantments != null) { + return ChatColor.DARK_AQUA + "-" + encodedEnchantments; + } else { + return ""; } - return b.toString(); } } diff --git a/com/Acrobot/ChestShop/Config/Config.java b/com/Acrobot/ChestShop/Config/Config.java index 0ca2356..2eaf92e 100644 --- a/com/Acrobot/ChestShop/Config/Config.java +++ b/com/Acrobot/ChestShop/Config/Config.java @@ -3,6 +3,7 @@ package com.Acrobot.ChestShop.Config; import com.Acrobot.ChestShop.ChestShop; import com.Acrobot.ChestShop.Utils.uName; import com.nijikokun.register.payment.forChestShop.Methods; +import org.bukkit.ChatColor; import java.io.File; @@ -10,8 +11,8 @@ import java.io.File; * @author Acrobot */ public class Config { - public static BreezeConfiguration normalConfig; - public static BreezeConfiguration languageConfig; + private static BreezeConfiguration normalConfig; + private static BreezeConfiguration languageConfig; public static void setup() { File configFolder = ChestShop.getFolder(); @@ -53,7 +54,7 @@ public class Config { } private static String getColored(String msg) { - return msg.replaceAll("&([0-9a-fk-or])", "\u00A7$1"); + return ChatColor.translateAlternateColorCodes('&', msg); } public static String getLocal(Language lang) { diff --git a/com/Acrobot/ChestShop/Config/Language.java b/com/Acrobot/ChestShop/Config/Language.java index 358b720..1900a29 100644 --- a/com/Acrobot/ChestShop/Config/Language.java +++ b/com/Acrobot/ChestShop/Config/Language.java @@ -48,7 +48,7 @@ public enum Language { private final String text; - private static final Map values = new LinkedHashMap(); + private static final Map LANGUAGE_STRINGS = new LinkedHashMap(); private Language(String def) { text = def; @@ -63,12 +63,12 @@ public enum Language { } public static Map getValues() { - return values; + return LANGUAGE_STRINGS; } static { for (Language property : Language.values()) { - values.put(property.name(), property.getValue()); + LANGUAGE_STRINGS.put(property.name(), property.getValue()); } } } diff --git a/com/Acrobot/ChestShop/Config/Property.java b/com/Acrobot/ChestShop/Config/Property.java index 721bcaa..9fef851 100644 --- a/com/Acrobot/ChestShop/Config/Property.java +++ b/com/Acrobot/ChestShop/Config/Property.java @@ -31,8 +31,6 @@ public enum Property { ALLOW_MULTIPLE_SHOPS_AT_ONE_BLOCK(false, "Do you want to allow other players to build a shop on a block where there's one already?"), ALLOW_PARTIAL_TRANSACTIONS(true, "Can shops be used even when the seller doesn't have enough items? (The price will be scaled adequatly to the item amount)\n"), - STACK_UNSTACKABLES(false, "If true, ALL things (including food, etc.) will stack up to 64\n"), - SHOW_MESSAGE_OUT_OF_STOCK(true, "Do you want to show \"Out of stock\" messages?"), SHOW_TRANSACTION_INFORMATION_CLIENT(true, "Do you want to show \"You bought/sold... \" messages?"), SHOW_TRANSACTION_INFORMATION_OWNER(true, "Do you want to show \"Somebody bought/sold... \" messages?\n"), @@ -67,7 +65,7 @@ public enum Property { private final Object value; private final String comment; - private static final Map values = new LinkedHashMap(); + private static final Map PROPERTIES = new LinkedHashMap(); private Property(Object value, String comment) { this.value = value; @@ -83,12 +81,12 @@ public enum Property { } public static Map getValues() { - return values; + return PROPERTIES; } static { for (Property property : Property.values()) { - values.put(property.name(), property.getValue()); + PROPERTIES.put(property.name(), property.getValue()); } } } diff --git a/com/Acrobot/ChestShop/Containers/AdminChest.java b/com/Acrobot/ChestShop/Containers/AdminChest.java index 44888b4..1ededd7 100644 --- a/com/Acrobot/ChestShop/Containers/AdminChest.java +++ b/com/Acrobot/ChestShop/Containers/AdminChest.java @@ -10,21 +10,21 @@ public class AdminChest implements Container { return false; } - public void addItem(ItemStack item, int amount) { + public void addItem(ItemStack item) { } - public void removeItem(ItemStack item, short durability, int amount) { + public void removeItem(ItemStack item) { } - public int amount(ItemStack item, short durability) { + public int amount(ItemStack item) { return Integer.MAX_VALUE; } - public boolean hasEnough(ItemStack item, int amount, short durability) { + public boolean hasEnough(ItemStack item) { return true; } - public boolean fits(ItemStack item, int amount, short durability) { + public boolean fits(ItemStack item) { return true; } } diff --git a/com/Acrobot/ChestShop/Containers/Container.java b/com/Acrobot/ChestShop/Containers/Container.java index ada618f..671b1ef 100644 --- a/com/Acrobot/ChestShop/Containers/Container.java +++ b/com/Acrobot/ChestShop/Containers/Container.java @@ -6,15 +6,15 @@ import org.bukkit.inventory.ItemStack; * @author Acrobot */ public interface Container { - public boolean isEmpty(); + boolean isEmpty(); - public void addItem(ItemStack item, int amount); + void addItem(ItemStack item); - public void removeItem(ItemStack item, short durability, int amount); + void removeItem(ItemStack item); - public int amount(ItemStack item, short durability); + int amount(ItemStack item); - public boolean hasEnough(ItemStack item, int amount, short durability); + boolean hasEnough(ItemStack item); - public boolean fits(ItemStack item, int amount, short durability); + boolean fits(ItemStack item); } diff --git a/com/Acrobot/ChestShop/Containers/MinecraftChest.java b/com/Acrobot/ChestShop/Containers/ShopChest.java similarity index 53% rename from com/Acrobot/ChestShop/Containers/MinecraftChest.java rename to com/Acrobot/ChestShop/Containers/ShopChest.java index 3a1ee1c..b71093c 100644 --- a/com/Acrobot/ChestShop/Containers/MinecraftChest.java +++ b/com/Acrobot/ChestShop/Containers/ShopChest.java @@ -1,7 +1,7 @@ package com.Acrobot.ChestShop.Containers; +import com.Acrobot.Breeze.Utils.InventoryUtil; import com.Acrobot.ChestShop.Utils.uBlock; -import com.Acrobot.ChestShop.Utils.uInventory; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.Chest; @@ -11,11 +11,11 @@ import org.bukkit.inventory.ItemStack; /** * @author Acrobot */ -public class MinecraftChest implements Container { +public class ShopChest implements Container { private final Chest chest; - private final BlockFace[] neighborFaces = new BlockFace[]{BlockFace.EAST, BlockFace.NORTH, BlockFace.WEST, BlockFace.SOUTH}; + private static final BlockFace[] NEIGHBOR_FACES = new BlockFace[]{BlockFace.EAST, BlockFace.NORTH, BlockFace.WEST, BlockFace.SOUTH}; - public MinecraftChest(Chest chest) { + public ShopChest(Chest chest) { this.chest = chest; } @@ -29,24 +29,24 @@ public class MinecraftChest implements Container { return true; } - public void addItem(ItemStack item, int amount) { - uInventory.add(chest.getInventory(), item, amount); + public void addItem(ItemStack item) { + InventoryUtil.add(item, chest.getInventory()); } - public void removeItem(ItemStack item, short durability, int amount) { - uInventory.remove(chest.getInventory(), item, amount, durability); + public void removeItem(ItemStack item) { + InventoryUtil.remove(item, chest.getInventory()); } - public int amount(ItemStack item, short durability) { - return uInventory.amount(chest.getInventory(), item, durability); + public int amount(ItemStack item) { + return InventoryUtil.getAmount(item, chest.getInventory()); } - public boolean hasEnough(ItemStack item, int amount, short durability) { - return amount(item, durability) >= amount; + public boolean hasEnough(ItemStack item) { + return amount(item) >= item.getAmount(); } - public boolean fits(ItemStack item, int amount, short durability) { - return uInventory.fits(chest.getInventory(), item, amount, durability) <= 0; + public boolean fits(ItemStack item) { + return InventoryUtil.fits(item, chest.getInventory()); } public Sign findShopSign() { @@ -62,7 +62,7 @@ public class MinecraftChest implements Container { private Chest getNeighbor() { Block chestBlock = chest.getBlock(); - for (BlockFace chestFace : neighborFaces) { + for (BlockFace chestFace : NEIGHBOR_FACES) { Block relative = chestBlock.getRelative(chestFace); if (relative.getState() instanceof Chest) { diff --git a/com/Acrobot/ChestShop/DB/Generator.java b/com/Acrobot/ChestShop/DB/Generator.java index 88fee90..841a9db 100644 --- a/com/Acrobot/ChestShop/DB/Generator.java +++ b/com/Acrobot/ChestShop/DB/Generator.java @@ -1,8 +1,7 @@ package com.Acrobot.ChestShop.DB; +import com.Acrobot.Breeze.Utils.StringUtil; import com.Acrobot.ChestShop.ChestShop; -import com.Acrobot.ChestShop.Logging.Logging; -import com.Acrobot.ChestShop.Utils.uSign; import com.avaje.ebean.ExpressionList; import org.bukkit.Material; @@ -125,7 +124,7 @@ public class Generator implements Runnable { double sold = generateTotalSold(itemID); Material material = Material.getMaterial(itemID); - String matName = uSign.capitalizeFirstLetter(material.name(), '_'); + String matName = StringUtil.capitalizeFirstLetter(material.name(), '_'); int maxStackSize = material.getMaxStackSize(); @@ -162,7 +161,7 @@ public class Generator implements Runnable { fileEnd(generationTime); } catch (Exception e) { - Logging.log("Couldn't generate statistics page!"); + ChestShop.getBukkitLogger().severe("Couldn't generate statistics page!"); e.printStackTrace(); } } diff --git a/com/Acrobot/ChestShop/DB/Queue.java b/com/Acrobot/ChestShop/DB/Queue.java index bfa2560..e00a9ab 100644 --- a/com/Acrobot/ChestShop/DB/Queue.java +++ b/com/Acrobot/ChestShop/DB/Queue.java @@ -6,15 +6,16 @@ import com.Acrobot.ChestShop.Config.Property; import javax.persistence.OptimisticLockException; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** * @author Acrobot */ public class Queue implements Runnable { - private static final ArrayList queue = new ArrayList(); + private static final List queue = Collections.synchronizedList(new ArrayList()); - public synchronized static void addToQueue(Transaction t) { + public static void addToQueue(Transaction t) { queue.add(t); } @@ -35,7 +36,7 @@ public class Queue implements Runnable { } } - public synchronized static List getOld() throws OptimisticLockException { + public static List getOld() throws OptimisticLockException { return ChestShop .getDB() .find(Transaction.class) diff --git a/com/Acrobot/ChestShop/Dependencies.java b/com/Acrobot/ChestShop/Dependencies.java index c291a2b..2f53b97 100644 --- a/com/Acrobot/ChestShop/Dependencies.java +++ b/com/Acrobot/ChestShop/Dependencies.java @@ -1,34 +1,37 @@ package com.Acrobot.ChestShop; +import com.Acrobot.Breeze.Utils.MaterialUtil; import com.Acrobot.ChestShop.Config.Config; import com.Acrobot.ChestShop.Config.Property; import com.Acrobot.ChestShop.Economy.Economy; import com.Acrobot.ChestShop.Economy.NoProvider; import com.Acrobot.ChestShop.Economy.Register; import com.Acrobot.ChestShop.Economy.Vault; -import com.Acrobot.ChestShop.Items.Odd; import com.Acrobot.ChestShop.Plugins.*; import com.griefcraft.lwc.LWC; import com.nijikokun.register.payment.forChestShop.Method; import com.nijikokun.register.payment.forChestShop.Methods; import com.sk89q.worldguard.bukkit.WorldGuardPlugin; import com.webkonsept.bukkit.simplechestlock.SCL; +import org.bukkit.Bukkit; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.RegisteredServiceProvider; /** * @author Acrobot */ public class Dependencies { - public static void load() { initializeSecurity(); - for (Object plugin : ChestShop.getDependencies()) { - Plugin pl = ChestShop.getPluginManager().getPlugin((String) plugin); - if (pl != null) { - initializePlugin((String) plugin, pl); + PluginManager pluginManager = Bukkit.getPluginManager(); + + for (Object dependency : ChestShop.getDependencies()) { + Plugin plugin = pluginManager.getPlugin((String) dependency); + if (plugin != null) { + initializePlugin((String) dependency, plugin); } } loadRegister(); @@ -43,7 +46,7 @@ public class Dependencies { return; } - Method method = Methods.load(ChestShop.getPluginManager()); + Method method = Methods.load(); if (method == null) { Economy.economy = new NoProvider(); return; @@ -60,7 +63,7 @@ public class Dependencies { } else if (name.equals("Deadbolt")) { ChestShop.registerListener(new Deadbolt()); } else if (name.equals("OddItem")) { - Odd.isInitialized = true; + MaterialUtil.Odd.initialize(); } else if (name.equals("Towny")) { if (!Config.getBoolean(Property.TOWNY_INTEGRATION)) { return; diff --git a/com/Acrobot/ChestShop/Economy/EcoPlugin.java b/com/Acrobot/ChestShop/Economy/EcoPlugin.java index c107a1e..53daf02 100644 --- a/com/Acrobot/ChestShop/Economy/EcoPlugin.java +++ b/com/Acrobot/ChestShop/Economy/EcoPlugin.java @@ -4,15 +4,15 @@ package com.Acrobot.ChestShop.Economy; * @author Acrobot */ public interface EcoPlugin { - public boolean hasAccount(String player); + boolean hasAccount(String player); - public void add(String player, double amount); + void add(String player, double amount); - public void subtract(String player, double amount); + void subtract(String player, double amount); - public boolean hasEnough(String player, double amount); + boolean hasEnough(String player, double amount); - public double balance(String player); + double balance(String player); - public String format(double amount); + String format(double amount); } diff --git a/com/Acrobot/ChestShop/Economy/Economy.java b/com/Acrobot/ChestShop/Economy/Economy.java index 2dc8d13..9b8aac6 100644 --- a/com/Acrobot/ChestShop/Economy/Economy.java +++ b/com/Acrobot/ChestShop/Economy/Economy.java @@ -4,6 +4,8 @@ import com.Acrobot.ChestShop.Config.Config; import com.Acrobot.ChestShop.Config.Property; import com.Acrobot.ChestShop.Utils.uName; +import static com.Acrobot.Breeze.Utils.NumberUtil.roundUp; + /** * @author Acrobot * Economy management @@ -31,7 +33,7 @@ public class Economy { amount -= tax; } - economy.add(uName.getName(name), amount); + economy.add(uName.getName(name), roundUp(amount)); } public static double getTax(Property tax, double price) { @@ -43,7 +45,7 @@ public class Economy { return; } - economy.subtract(uName.getName(name), amount); + economy.subtract(uName.getName(name), roundUp(amount)); } public static boolean hasEnough(String name, double amount) { @@ -51,7 +53,7 @@ public class Economy { return true; } - return economy.hasEnough(uName.getName(name), amount); + return economy.hasEnough(uName.getName(name), roundUp(amount)); } public static double balance(String name) { @@ -59,6 +61,6 @@ public class Economy { } public static String formatBalance(double amount) { - return economy.format(amount); + return economy.format(roundUp(amount)); } } diff --git a/com/Acrobot/ChestShop/Events/ItemInfoEvent.java b/com/Acrobot/ChestShop/Events/ItemInfoEvent.java new file mode 100644 index 0000000..ed865ad --- /dev/null +++ b/com/Acrobot/ChestShop/Events/ItemInfoEvent.java @@ -0,0 +1,37 @@ +package com.Acrobot.ChestShop.Events; + +import org.bukkit.command.CommandSender; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; + +/** + * @author Acrobot + */ +public class ItemInfoEvent extends Event { + private static final HandlerList handlers = new HandlerList(); + + private CommandSender sender; + private ItemStack item; + + public ItemInfoEvent(CommandSender sender, ItemStack item) { + this.sender = sender; + this.item = item; + } + + public CommandSender getSender() { + return sender; + } + + public ItemStack getItem() { + return item; + } + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/com/Acrobot/ChestShop/Events/BuildPermissionEvent.java b/com/Acrobot/ChestShop/Events/Protection/BuildPermissionEvent.java similarity index 96% rename from com/Acrobot/ChestShop/Events/BuildPermissionEvent.java rename to com/Acrobot/ChestShop/Events/Protection/BuildPermissionEvent.java index f07e237..eaf9641 100644 --- a/com/Acrobot/ChestShop/Events/BuildPermissionEvent.java +++ b/com/Acrobot/ChestShop/Events/Protection/BuildPermissionEvent.java @@ -1,4 +1,4 @@ -package com.Acrobot.ChestShop.Events; +package com.Acrobot.ChestShop.Events.Protection; import org.bukkit.Location; import org.bukkit.entity.Player; diff --git a/com/Acrobot/ChestShop/Events/ProtectBlockEvent.java b/com/Acrobot/ChestShop/Events/Protection/ProtectBlockEvent.java similarity index 94% rename from com/Acrobot/ChestShop/Events/ProtectBlockEvent.java rename to com/Acrobot/ChestShop/Events/Protection/ProtectBlockEvent.java index 2396a41..7fad105 100644 --- a/com/Acrobot/ChestShop/Events/ProtectBlockEvent.java +++ b/com/Acrobot/ChestShop/Events/Protection/ProtectBlockEvent.java @@ -1,4 +1,4 @@ -package com.Acrobot.ChestShop.Events; +package com.Acrobot.ChestShop.Events.Protection; import org.bukkit.block.Block; import org.bukkit.event.Event; diff --git a/com/Acrobot/ChestShop/Events/ProtectionCheckEvent.java b/com/Acrobot/ChestShop/Events/Protection/ProtectionCheckEvent.java similarity index 94% rename from com/Acrobot/ChestShop/Events/ProtectionCheckEvent.java rename to com/Acrobot/ChestShop/Events/Protection/ProtectionCheckEvent.java index 06c85c4..fd0d0ca 100644 --- a/com/Acrobot/ChestShop/Events/ProtectionCheckEvent.java +++ b/com/Acrobot/ChestShop/Events/Protection/ProtectionCheckEvent.java @@ -1,4 +1,4 @@ -package com.Acrobot.ChestShop.Events; +package com.Acrobot.ChestShop.Events.Protection; import org.bukkit.block.Block; import org.bukkit.entity.Player; diff --git a/com/Acrobot/ChestShop/Events/ShopCreatedEvent.java b/com/Acrobot/ChestShop/Events/ShopCreatedEvent.java index 4c2ea78..594e3ce 100644 --- a/com/Acrobot/ChestShop/Events/ShopCreatedEvent.java +++ b/com/Acrobot/ChestShop/Events/ShopCreatedEvent.java @@ -21,7 +21,7 @@ public class ShopCreatedEvent extends Event { this.player = player; this.sign = sign; this.chest = chest; - this.signLines = signLines; + this.signLines = signLines.clone(); } public String[] getSignLines() { diff --git a/com/Acrobot/ChestShop/Events/TransactionEvent.java b/com/Acrobot/ChestShop/Events/TransactionEvent.java new file mode 100644 index 0000000..193ff63 --- /dev/null +++ b/com/Acrobot/ChestShop/Events/TransactionEvent.java @@ -0,0 +1,86 @@ +package com.Acrobot.ChestShop.Events; + +import com.Acrobot.ChestShop.Containers.Container; +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; + +/** + * @author Acrobot + */ +public class TransactionEvent extends Event { + private static final HandlerList handlers = new HandlerList(); + + private Container container; + private Sign sign; + + private Player client; + private String owner; + + private ItemStack item; + private int itemAmount; + private double price; + + private Type transactionType; + + public TransactionEvent(Type transactionType, Container container, Sign sign, Player client, String owner, ItemStack item, int itemAmount, double price) { + this.container = container; + this.sign = sign; + + this.client = client; + this.owner = owner; + + this.item = item; + this.itemAmount = itemAmount; + + this.transactionType = transactionType; + this.price = price; + } + + public Type getTransactionType() { + return transactionType; + } + + public Container getContainer() { + return container; + } + + public Sign getSign() { + return sign; + } + + public Player getClient() { + return client; + } + + public String getOwner() { + return owner; + } + + public ItemStack getItem() { + return item; + } + + public int getItemAmount() { + return itemAmount; + } + + public double getPrice() { + return price; + } + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + public enum Type { + BUY, + SELL + } +} diff --git a/com/Acrobot/ChestShop/Items/DataValue.java b/com/Acrobot/ChestShop/Items/DataValue.java deleted file mode 100644 index 6adb841..0000000 --- a/com/Acrobot/ChestShop/Items/DataValue.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.Acrobot.ChestShop.Items; - -import org.bukkit.CoalType; -import org.bukkit.DyeColor; -import org.bukkit.Material; -import org.bukkit.TreeSpecies; -import org.bukkit.entity.EntityType; -import org.bukkit.inventory.ItemStack; -import org.bukkit.material.*; - -public class DataValue { - /** - * Gets the data value from a string - * - * @param type Data Value string - * @param material Material - * @return data value - */ - public static byte get(String type, Material material) { - if (material == null || material.getData() == null) { - return 0; - } - - type = type.toUpperCase().replace(" ", "_"); - - MaterialData materialData = material.getNewData((byte) 0); - - if (materialData instanceof TexturedMaterial) { - TexturedMaterial texturedMaterial = (TexturedMaterial) materialData; - - for (Material mat : texturedMaterial.getTextures()) { - if (mat.name().startsWith(type)) { - return (byte) texturedMaterial.getTextures().indexOf(mat); - } - } - } else if (materialData instanceof Colorable) { - DyeColor color; - - try { - color = DyeColor.valueOf(type); - } catch (IllegalArgumentException exception) { - return 0; - } - - if (material == Material.INK_SACK) { - color = DyeColor.getByData((byte) (15 - color.getData())); - } - - return color.getData(); - } else if (materialData instanceof Tree) { - try { - return TreeSpecies.valueOf(type).getData(); - } catch (IllegalArgumentException ex) { - return 0; - } - } else if (materialData instanceof SpawnEgg) { - try { - EntityType entityType = EntityType.valueOf(type); - - return (byte) entityType.getTypeId(); - } catch (IllegalArgumentException ex) { - return 0; - } - } else if (materialData instanceof Coal) { - try { - return CoalType.valueOf(type).getData(); - } catch (IllegalArgumentException ex) { - return 0; - } - } - - return 0; - } - - /** - * Returns a string with the DataValue - * - * @param itemStack ItemStack to describe - * @return Data value string - */ - public static String name(ItemStack itemStack) { - MaterialData data = itemStack.getData(); - - if (data == null) { - return null; - } - - if (data instanceof TexturedMaterial) { - return ((TexturedMaterial) data).getMaterial().name(); - } else if (data instanceof Colorable) { - return ((Colorable) data).getColor().name(); - } else if (data instanceof Tree) { - //TreeSpecies specie = TreeSpecies.getByData((byte) (data.getData() & 3)); //This works, but not as intended - TreeSpecies specie = ((Tree) data).getSpecies(); - return (specie != null && specie != TreeSpecies.GENERIC ? specie.name() : null); - } else if (data instanceof SpawnEgg) { - EntityType type = ((SpawnEgg) data).getSpawnedType(); - return (type != null ? type.name() : null); - } else if (data instanceof Coal) { - CoalType coal = ((Coal) data).getType(); - return (coal != null && coal != CoalType.COAL ? coal.name() : null); - } else { - return null; - } - } -} \ No newline at end of file diff --git a/com/Acrobot/ChestShop/Items/Items.java b/com/Acrobot/ChestShop/Items/Items.java deleted file mode 100644 index e3c8fd2..0000000 --- a/com/Acrobot/ChestShop/Items/Items.java +++ /dev/null @@ -1,126 +0,0 @@ -package com.Acrobot.ChestShop.Items; - -import com.Acrobot.ChestShop.Utils.uEnchantment; -import com.Acrobot.ChestShop.Utils.uNumber; -import com.Acrobot.ChestShop.Utils.uSign; -import org.bukkit.Material; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.inventory.ItemStack; - -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * @author Acrobot - * Manages ItemStack names and ID's - */ -public class Items { - private static final Pattern Durability = Pattern.compile(":(\\d)*"); - private static final Pattern Enchant = Pattern.compile("-([0-9a-zA-Z])*"); - - public static Material getMaterial(String itemName) { - if (uNumber.isInteger(itemName)) return Material.getMaterial(Integer.parseInt(itemName)); - itemName = itemName.replace(" ", "_"); - Material finalMaterial = Material.getMaterial(itemName.toUpperCase()); - if (finalMaterial != null) return finalMaterial; - - int length = 256; - itemName = itemName.toLowerCase().replace("_", ""); - for (Material currentMaterial : Material.values()) { - String materialName = currentMaterial.name().toLowerCase().replace("_", ""); - if (materialName.startsWith(itemName) && (materialName.length() < length)) { - length = materialName.length(); - finalMaterial = currentMaterial; - } - } - return finalMaterial; - } - - public static String getName(ItemStack is) { - return getName(is, true); - } - - public static String getName(ItemStack is, boolean showData) { - String name = DataValue.name(is); - return uSign.capitalizeFirstLetter((name != null && showData ? name + '_' : "") + is.getType()); - } - - public static String getSignName(ItemStack is) { - return is.getType().name() - + (is.getDurability() > 0 ? ":" + is.getDurability() : "") - + (!is.getEnchantments().isEmpty() ? '-' + uEnchantment.encodeEnchantment(is.getEnchantments()) : ""); - } - - public static ItemStack getItemStack(String itemName) { - ItemStack toReturn = getFromOddItem(itemName); - if (toReturn != null) return toReturn; - - if (itemName == null) itemName = ""; - String[] split = itemName.split(":|-"); - - if (split.length == 0) return null; - String first = split[0]; - - String[] space = first.split(" "); - if (space.length == 0) return null; - - Material material = getMaterial(first); - - for (int i = (space.length > 1 ? 1 : 0); i >= 0 && material == null; i--) { - material = getMaterial(space[i]); - } - - if (material == null) return null; - - toReturn = new ItemStack(material, 1); - toReturn = addEnchantments(toReturn, itemName); - toReturn = addDurability(toReturn, itemName); - - short data = getDataFromWord(space[0], material); - if (data != 0) toReturn.setDurability(data); - - return toReturn; - } - - private static ItemStack addDurability(ItemStack toReturn, String itemName) { - Matcher m = Durability.matcher(itemName); - if (!m.find()) return toReturn; - - String data = m.group(); - if (data == null || data.isEmpty()) return toReturn; - data = data.substring(1); - if (uNumber.isShort(data)) toReturn.setDurability(Short.valueOf(data)); - - return toReturn; - } - - private static Map getEnchantment(String itemName) { - return uEnchantment.decodeEnchantment(itemName); - } - - private static Map getEnchant(String original) { - Matcher m = Enchant.matcher(original); - if (!m.find()) return new HashMap(); - String group = m.group().substring(1); - return getEnchantment(group); - } - - private static ItemStack addEnchantments(ItemStack is, String itemname) { - try { - is.addEnchantments(getEnchant(itemname)); - } catch (Exception ignored) { - } - return is; - } - - private static ItemStack getFromOddItem(String itemName) { - return !Odd.isInitialized() ? null : Odd.returnItemStack(itemName.replace(":", ";")); - } - - private static short getDataFromWord(String name, Material material) { - return DataValue.get(name, material); - } - -} diff --git a/com/Acrobot/ChestShop/Items/Odd.java b/com/Acrobot/ChestShop/Items/Odd.java deleted file mode 100644 index 744194e..0000000 --- a/com/Acrobot/ChestShop/Items/Odd.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.Acrobot.ChestShop.Items; - -import info.somethingodd.bukkit.OddItem.OddItem; -import org.bukkit.inventory.ItemStack; - -/** - * @author Acrobot - */ -public class Odd { - public static boolean isInitialized; - - public static boolean isInitialized() { - return isInitialized; - } - - public static ItemStack returnItemStack(String name) { - try { - return OddItem.getItemStack(name); - } catch (Exception ignored) { - return null; - } - } -} diff --git a/com/Acrobot/ChestShop/Listeners/blockBreak.java b/com/Acrobot/ChestShop/Listeners/Block/BlockBreak.java similarity index 93% rename from com/Acrobot/ChestShop/Listeners/blockBreak.java rename to com/Acrobot/ChestShop/Listeners/Block/BlockBreak.java index b9266d8..829e2a8 100644 --- a/com/Acrobot/ChestShop/Listeners/blockBreak.java +++ b/com/Acrobot/ChestShop/Listeners/Block/BlockBreak.java @@ -1,14 +1,14 @@ -package com.Acrobot.ChestShop.Listeners; +package com.Acrobot.ChestShop.Listeners.Block; +import com.Acrobot.Breeze.Utils.BlockUtil; import com.Acrobot.ChestShop.Config.Config; import com.Acrobot.ChestShop.Config.Language; import com.Acrobot.ChestShop.Config.Property; import com.Acrobot.ChestShop.Economy.Economy; import com.Acrobot.ChestShop.Permission; -import com.Acrobot.ChestShop.Signs.restrictedSign; +import com.Acrobot.ChestShop.Signs.RestrictedSign; import com.Acrobot.ChestShop.Utils.uBlock; import com.Acrobot.ChestShop.Utils.uName; -import com.Acrobot.ChestShop.Utils.uSign; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; @@ -33,9 +33,9 @@ public class BlockBreak implements Listener { public static boolean cancellingBlockBreak(Block block, Player player) { if (block == null) return false; - if (uSign.isSign(block)) block.getState().update(); //Show the text immediately + if (BlockUtil.isSign(block)) block.getState().update(); //Show the text immediately - if (restrictedSign(block)) return !restrictedSign.canDestroy(player, uBlock.findRestrictedSign(block)); + if (restrictedSign(block)) return !RestrictedSign.canDestroy(player, uBlock.findRestrictedSign(block)); Sign sign = uBlock.findValidShopSign(block, (player != null ? uName.stripName(player.getName()) : null)); if (!isCorrectSign(sign, block)) return false; //It's not a correct shop sign, so don't cancel it @@ -94,7 +94,7 @@ public class BlockBreak implements Listener { private static Block getRetractBlock(BlockPistonRetractEvent event) { Block block = getRetractLocationBlock(event); - return (block != null && !uSign.isSign(block) ? block : null); + return (block != null && !BlockUtil.isSign(block) ? block : null); } //Those are fixes for CraftBukkit's piston bug, where piston appears not to be a piston. diff --git a/com/Acrobot/ChestShop/Listeners/blockPlace.java b/com/Acrobot/ChestShop/Listeners/Block/BlockPlace.java similarity index 84% rename from com/Acrobot/ChestShop/Listeners/blockPlace.java rename to com/Acrobot/ChestShop/Listeners/Block/BlockPlace.java index d8908dd..ceaf592 100644 --- a/com/Acrobot/ChestShop/Listeners/blockPlace.java +++ b/com/Acrobot/ChestShop/Listeners/Block/BlockPlace.java @@ -1,10 +1,11 @@ -package com.Acrobot.ChestShop.Listeners; +package com.Acrobot.ChestShop.Listeners.Block; +import com.Acrobot.Breeze.Utils.BlockUtil; import com.Acrobot.ChestShop.Config.Config; import com.Acrobot.ChestShop.Config.Language; import com.Acrobot.ChestShop.Security; +import com.Acrobot.ChestShop.Signs.ChestShopSign; import com.Acrobot.ChestShop.Utils.uBlock; -import com.Acrobot.ChestShop.Utils.uSign; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.Chest; @@ -21,7 +22,7 @@ public class BlockPlace implements Listener { public static void onBlockPlace(BlockPlaceEvent event) { Block block = event.getBlockAgainst(); - if (uSign.isSign(block) && uSign.isValid((Sign) block.getState())) { + if (BlockUtil.isSign(block) && ChestShopSign.isValid((Sign) block.getState())) { event.setCancelled(true); return; } diff --git a/com/Acrobot/ChestShop/Listeners/entityExplode.java b/com/Acrobot/ChestShop/Listeners/Block/EntityExplode.java similarity index 94% rename from com/Acrobot/ChestShop/Listeners/entityExplode.java rename to com/Acrobot/ChestShop/Listeners/Block/EntityExplode.java index 8b56735..a22b2bd 100644 --- a/com/Acrobot/ChestShop/Listeners/entityExplode.java +++ b/com/Acrobot/ChestShop/Listeners/Block/EntityExplode.java @@ -1,4 +1,4 @@ -package com.Acrobot.ChestShop.Listeners; +package com.Acrobot.ChestShop.Listeners.Block; import com.Acrobot.ChestShop.Config.Config; import com.Acrobot.ChestShop.Config.Property; diff --git a/com/Acrobot/ChestShop/Listeners/Block/SignChange.java b/com/Acrobot/ChestShop/Listeners/Block/SignChange.java new file mode 100644 index 0000000..e1f7a3e --- /dev/null +++ b/com/Acrobot/ChestShop/Listeners/Block/SignChange.java @@ -0,0 +1,198 @@ +package com.Acrobot.ChestShop.Listeners.Block; + +import com.Acrobot.Breeze.Utils.MaterialUtil; +import com.Acrobot.Breeze.Utils.NumberUtil; +import com.Acrobot.Breeze.Utils.PriceUtil; +import com.Acrobot.Breeze.Utils.StringUtil; +import com.Acrobot.ChestShop.ChestShop; +import com.Acrobot.ChestShop.Config.Config; +import com.Acrobot.ChestShop.Config.Language; +import com.Acrobot.ChestShop.Config.MaxPrice; +import com.Acrobot.ChestShop.Config.Property; +import com.Acrobot.ChestShop.Economy.Economy; +import com.Acrobot.ChestShop.Events.Protection.BuildPermissionEvent; +import com.Acrobot.ChestShop.Events.ShopCreatedEvent; +import com.Acrobot.ChestShop.Permission; +import com.Acrobot.ChestShop.Security; +import com.Acrobot.ChestShop.Signs.ChestShopSign; +import com.Acrobot.ChestShop.Utils.uBlock; +import com.Acrobot.ChestShop.Utils.uName; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.Chest; +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.SignChangeEvent; +import org.bukkit.inventory.ItemStack; + +import static com.Acrobot.ChestShop.Config.Language.*; +import static com.Acrobot.ChestShop.Config.Property.SHOP_CREATION_PRICE; +import static com.Acrobot.ChestShop.Signs.ChestShopSign.*; + +/** + * @author Acrobot + */ +public class SignChange implements Listener { + @EventHandler(ignoreCancelled = true) + public static void onSignChange(SignChangeEvent event) { + Block signBlock = event.getBlock(); + String[] line = event.getLines(); + + ItemStack stock = MaterialUtil.getItem(line[ITEM_LINE]); + + if (!ChestShopSign.isValidPreparedSign(line)) { + return; + } + + if (stock == null) { + sendMessageAndExit(INCORRECT_ITEM_ID, event); + return; + } + + Player player = event.getPlayer(); + boolean isAdmin = Permission.has(player, Permission.ADMIN); + + if (!playerCanUseName(player, line[NAME_LINE])) { + event.setLine(NAME_LINE, uName.stripName(player.getName())); + } + + String formattedPrice = formatPriceLine(line[PRICE_LINE]); + + if (formattedPrice == null) { + sendMessageAndExit(YOU_CANNOT_CREATE_SHOP, event); + return; + } + + event.setLine(PRICE_LINE, formattedPrice); + event.setLine(ITEM_LINE, formatItemLine(line[ITEM_LINE], stock)); + + Chest connectedChest = uBlock.findConnectedChest(signBlock); + + if (!isAdminShop(line[NAME_LINE])) { + if (connectedChest == null) { + sendMessageAndExit(NO_CHEST_DETECTED, event); + return; + } + + if (!isAdmin && !Security.canPlaceSign(player, (Sign) signBlock.getState())) { + sendMessageAndExit(CANNOT_CREATE_SHOP_HERE, event); + return; + } + + BuildPermissionEvent bEvent = new BuildPermissionEvent(player, connectedChest.getLocation(), signBlock.getLocation()); + ChestShop.callEvent(bEvent); + + if (!bEvent.isAllowed()) { + sendMessageAndExit(CANNOT_CREATE_SHOP_HERE, event); + return; + } + + if (!Security.canAccess(player, connectedChest.getBlock())) { + sendMessageAndExit(CANNOT_ACCESS_THE_CHEST, event); + return; + } + } + + double buyPrice = PriceUtil.getBuyPrice(formattedPrice); + double sellPrice = PriceUtil.getSellPrice(formattedPrice); + + if (!isAdmin && (!canCreateShop(player, stock.getType(), buyPrice, sellPrice) || !MaxPrice.canCreate(buyPrice, sellPrice, stock.getType()))) { + sendMessageAndExit(YOU_CANNOT_CREATE_SHOP, event); + return; + } + + float shopCreationPrice = Config.getFloat(SHOP_CREATION_PRICE); + if (shopCreationPrice != 0 && !ChestShopSign.isAdminShop(line[NAME_LINE]) && !Permission.has(player, Permission.NOFEE)) { + if (!Economy.hasEnough(player.getName(), shopCreationPrice)) { + sendMessageAndExit(NOT_ENOUGH_MONEY, event); + return; + } + + Economy.subtract(player.getName(), shopCreationPrice); + + player.sendMessage(Config.getLocal(SHOP_CREATED) + " - " + Economy.formatBalance(shopCreationPrice)); + } else { + player.sendMessage(Config.getLocal(SHOP_CREATED)); + } + + ShopCreatedEvent sEvent = new ShopCreatedEvent(player, (Sign) signBlock.getState(), connectedChest, event.getLines()); + ChestShop.callEvent(sEvent); + } + + private static boolean canCreateShop(Player player, Material mat, double buyPrice, double sellPrice) { + if (Config.getBoolean(Property.BLOCK_SHOPS_WITH_SELL_PRICE_HIGHER_THAN_BUY_PRICE)) { + if (buyPrice != -1 && sellPrice != -1 && sellPrice > buyPrice) { + return false; + } + } + return canCreateShop(player, mat, buyPrice != -1, sellPrice != -1) && MaxPrice.canCreate(buyPrice, sellPrice, mat); + } + + private static boolean canCreateShop(Player player, Material material, boolean buy, boolean sell) { + if (Permission.has(player, Permission.SHOP_CREATION_ID + Integer.toString(material.getId()))) { + return true; + } + + if (buy && !Permission.has(player, Permission.SHOP_CREATION_BUY)) return false; + return !(sell && !Permission.has(player, Permission.SHOP_CREATION_SELL)); + } + + private static String formatPriceLine(String thirdLine) { + String line = thirdLine.toUpperCase(); + String[] split = line.split(":"); + + if (NumberUtil.isFloat(split[0])) { + line = "B " + line; + } + if (split.length == 2 && NumberUtil.isFloat(split[1])) { + line += " S"; + } + + if (line.length() > 15) { + line = line.replace(" ", ""); + } + + return (line.length() > 15 ? null : line); + } + + private static String formatItemLine(String line, ItemStack itemStack) { + String[] split = line.split(":|-", 2); + StringBuilder formatted = new StringBuilder(15); + String itemName = MaterialUtil.getName(itemStack, false); + + short dataLength = (short) (line.length() - split[0].length()); + + if (itemName.length() > (15 - dataLength)) { + itemName = itemName.substring(0, 15 - dataLength); + } + + if (MaterialUtil.getItem(itemName).getType() != itemStack.getType()) { + itemName = String.valueOf(itemStack.getTypeId()); + } + + formatted.append(itemName); + if (split.length == 2) { + int dataValuePos = line.indexOf(split[1], split[0].length()); + formatted.append(line.charAt(dataValuePos - 1)).append(split[1]); + } + + return StringUtil.capitalizeFirstLetter(formatted.toString()); + } + + private static boolean playerCanUseName(Player player, String name) { + return !name.isEmpty() && (uName.canUseName(player, name) || Permission.has(player, Permission.ADMIN)); + } + + private static void sendMessageAndExit(Language message, SignChangeEvent event) { + event.getPlayer().sendMessage(Config.getLocal(message)); + + dropSign(event); + } + + private static void dropSign(SignChangeEvent event) { + event.setCancelled(true); + event.getBlock().breakNaturally(); + } +} diff --git a/com/Acrobot/ChestShop/Listeners/ItemInfoListener.java b/com/Acrobot/ChestShop/Listeners/ItemInfoListener.java new file mode 100644 index 0000000..848c871 --- /dev/null +++ b/com/Acrobot/ChestShop/Listeners/ItemInfoListener.java @@ -0,0 +1,70 @@ +package com.Acrobot.ChestShop.Listeners; + +import com.Acrobot.ChestShop.Events.ItemInfoEvent; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.command.CommandSender; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.Potion; +import org.bukkit.potion.PotionEffect; + +import java.util.Map; + +import static com.Acrobot.Breeze.Utils.NumberUtil.toRoman; +import static com.Acrobot.Breeze.Utils.NumberUtil.toTime; +import static com.Acrobot.Breeze.Utils.StringUtil.capitalizeFirstLetter; + +/** + * @author Acrobot + */ +public class ItemInfoListener implements Listener { + @EventHandler + public static void addEnchantment(ItemInfoEvent event) { + ItemStack item = event.getItem(); + CommandSender sender = event.getSender(); + + Map enchantments = item.getEnchantments(); + + for (Map.Entry enchantment : enchantments.entrySet()) { + sender.sendMessage(ChatColor.DARK_GRAY + capitalizeFirstLetter(enchantment.getKey().getName(), '_') + ' ' + toRoman(enchantment.getValue())); + } + } + + @EventHandler + public static void addPotionInfo(ItemInfoEvent event) { + ItemStack item = event.getItem(); + + if (item.getType() != Material.POTION || item.getDurability() == 0) { + return; + } + + Potion potion = Potion.fromItemStack(item); + + StringBuilder message = new StringBuilder(50); + + message.append(ChatColor.GRAY); + + if (potion.getType() == null) { + return; + } + + if (potion.isSplash()) { + message.append("Splash "); + } + + message.append("Potion of "); + message.append(capitalizeFirstLetter(potion.getType().name(), '_')); + message.append(toRoman(potion.getLevel())); + + CommandSender sender = event.getSender(); + + sender.sendMessage(message.toString()); + + for (PotionEffect effect : potion.getEffects()) { + sender.sendMessage(ChatColor.DARK_GRAY + capitalizeFirstLetter(effect.getType().getName(), '_') + ' ' + toTime(effect.getDuration() / 20)); + } + } +} diff --git a/com/Acrobot/ChestShop/Listeners/Player/PlayerConnect.java b/com/Acrobot/ChestShop/Listeners/Player/PlayerConnect.java new file mode 100644 index 0000000..010b514 --- /dev/null +++ b/com/Acrobot/ChestShop/Listeners/Player/PlayerConnect.java @@ -0,0 +1,28 @@ +package com.Acrobot.ChestShop.Listeners.Player; + +import com.Acrobot.ChestShop.ChestShop; +import com.Acrobot.ChestShop.Permission; +import com.Acrobot.ChestShop.Signs.ChestShopSign; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerLoginEvent; + +/** + * @author Acrobot + */ +public class PlayerConnect implements Listener { + @EventHandler + public static void onPlayerJoin(PlayerLoginEvent event) { + String name = event.getPlayer().getName(); + + if (name != null && ChestShopSign.isAdminShop(name)) { + if (Permission.has(event.getPlayer(), Permission.ADMIN)) { + return; + } + + event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "Oh no you don't. (ChestShop logged your IP to server log!)"); + + ChestShop.getBukkitLogger().severe(event.getAddress() + " tried to log in on Admin Shop's account!"); + } + } +} diff --git a/com/Acrobot/ChestShop/Listeners/Player/PlayerInteract.java b/com/Acrobot/ChestShop/Listeners/Player/PlayerInteract.java new file mode 100644 index 0000000..4782f03 --- /dev/null +++ b/com/Acrobot/ChestShop/Listeners/Player/PlayerInteract.java @@ -0,0 +1,150 @@ +package com.Acrobot.ChestShop.Listeners.Player; + +import com.Acrobot.Breeze.Utils.BlockUtil; +import com.Acrobot.ChestShop.Config.Config; +import com.Acrobot.ChestShop.Config.Language; +import com.Acrobot.ChestShop.Permission; +import com.Acrobot.ChestShop.Plugins.ChestShop; +import com.Acrobot.ChestShop.Security; +import com.Acrobot.ChestShop.Shop.Shop; +import com.Acrobot.ChestShop.Signs.ChestShopSign; +import com.Acrobot.ChestShop.Signs.RestrictedSign; +import com.Acrobot.ChestShop.Utils.uBlock; +import org.bukkit.ChatColor; +import org.bukkit.GameMode; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.Chest; +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.Inventory; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import static com.Acrobot.ChestShop.Config.Language.ACCESS_DENIED; +import static com.Acrobot.ChestShop.Config.Property.*; +import static org.bukkit.event.block.Action.LEFT_CLICK_BLOCK; +import static org.bukkit.event.block.Action.RIGHT_CLICK_BLOCK; + +/** + * @author Acrobot + */ +public class PlayerInteract implements Listener { + private static final Map TIME_OF_THE_LATEST_CLICK = new HashMap(); + private static final String ITEM_NOT_RECOGNISED = ChatColor.RED + "[Shop] The item is not recognised!"; + + private final int transactionBlockInterval; + + public PlayerInteract(int transactionInterval) { + this.transactionBlockInterval = transactionInterval; + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onPlayerInteract(PlayerInteractEvent event) { + Action action = event.getAction(); + if (!playerClickedBlock(action)) { + return; + } + + Block block = event.getClickedBlock(); + Player player = event.getPlayer(); + + if (Config.getBoolean(USE_BUILT_IN_PROTECTION) && block.getType() == Material.CHEST) { + if (!canOpenOtherShops(player) && !ChestShop.canAccess(player, block)) { + player.sendMessage(Config.getLocal(ACCESS_DENIED)); + event.setCancelled(true); + return; + } + } + + if (!BlockUtil.isSign(block)) return; + Sign sign = (Sign) block.getState(); + + if (player.getItemInHand() != null && player.getItemInHand().getType() == Material.SIGN) return; + if (!ChestShopSign.isValid(sign) || !enoughTimeHasPassed(player) || player.isSneaking()) return; + + if (Config.getBoolean(IGNORE_CREATIVE_MODE) && player.getGameMode() == GameMode.CREATIVE) { + event.setCancelled(true); + return; + } + + TIME_OF_THE_LATEST_CLICK.put(player.getUniqueId(), System.currentTimeMillis()); + + if (action == RIGHT_CLICK_BLOCK) { + event.setCancelled(true); + } + + if (ChestShopSign.canAccess(player, sign)) { + if (!Config.getBoolean(ALLOW_SIGN_CHEST_OPEN)) { + return; + } + + if (action != LEFT_CLICK_BLOCK || !Config.getBoolean(ALLOW_LEFT_CLICK_DESTROYING)) { + showChestGUI(player, block); + } + return; + } + + if (RestrictedSign.isRestrictedShop(sign) && !RestrictedSign.canAccess(sign, player)) { + player.sendMessage(Config.getLocal(ACCESS_DENIED)); + return; + } + + Action buy = (Config.getBoolean(REVERSE_BUTTONS) ? LEFT_CLICK_BLOCK : RIGHT_CLICK_BLOCK); + + Shop shop = Shop.getShopFromSign(sign); + + if (shop == null) { + player.sendMessage(ITEM_NOT_RECOGNISED); + return; + } + + if (action == buy) { + shop.sellToPlayer(player); + } else { + shop.buyFromPlayer(player); + } + } + + private boolean enoughTimeHasPassed(Player player) { + UUID uniqueID = player.getUniqueId(); + + return !TIME_OF_THE_LATEST_CLICK.containsKey(uniqueID) || (System.currentTimeMillis() - TIME_OF_THE_LATEST_CLICK.get(uniqueID)) >= transactionBlockInterval; + } + + private static boolean playerClickedBlock(Action action) { + return action == LEFT_CLICK_BLOCK || action == RIGHT_CLICK_BLOCK; + } + + + private static boolean canOpenOtherShops(Player player) { + return Permission.has(player, Permission.ADMIN) || Permission.has(player, Permission.MOD); + } + + private static void showChestGUI(Player player, Block block) { + Chest chest = uBlock.findConnectedChest(block); + + if (chest == null) { + player.sendMessage(Config.getLocal(Language.NO_CHEST_DETECTED)); + return; + } + + if (!canOpenOtherShops(player) && !Security.canAccess(player, block)) { + return; + } + + if (chest.getBlock().getType() != Material.CHEST) { + return; //To prevent people from breaking the chest and instantly clicking the sign + } + + Inventory chestInv = chest.getInventory(); + player.openInventory(chestInv); + } +} diff --git a/com/Acrobot/ChestShop/Listeners/Player/ShortNameSaver.java b/com/Acrobot/ChestShop/Listeners/Player/ShortNameSaver.java new file mode 100644 index 0000000..59c9296 --- /dev/null +++ b/com/Acrobot/ChestShop/Listeners/Player/ShortNameSaver.java @@ -0,0 +1,16 @@ +package com.Acrobot.ChestShop.Listeners.Player; + +import com.Acrobot.ChestShop.Events.ShopCreatedEvent; +import com.Acrobot.ChestShop.Utils.uName; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +/** + * @author Acrobot + */ +public class ShortNameSaver implements Listener { + @EventHandler + public static void onShopCreated(ShopCreatedEvent event) { + uName.saveName(event.getPlayer().getName()); + } +} diff --git a/com/Acrobot/ChestShop/Listeners/Transaction/EmptyShopDeleter.java b/com/Acrobot/ChestShop/Listeners/Transaction/EmptyShopDeleter.java new file mode 100644 index 0000000..c15306d --- /dev/null +++ b/com/Acrobot/ChestShop/Listeners/Transaction/EmptyShopDeleter.java @@ -0,0 +1,35 @@ +package com.Acrobot.ChestShop.Listeners.Transaction; + +import com.Acrobot.ChestShop.Config.Config; +import com.Acrobot.ChestShop.Config.Property; +import com.Acrobot.ChestShop.Containers.Container; +import com.Acrobot.ChestShop.Events.TransactionEvent; +import org.bukkit.Material; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.inventory.ItemStack; + +/** + * @author Acrobot + */ +public class EmptyShopDeleter implements Listener { + @EventHandler + public static void onTransaction(TransactionEvent event) { + if (event.getTransactionType() != TransactionEvent.Type.BUY) { + return; + } + + if (shopShouldBeRemoved(event.getContainer())) { + event.getSign().getBlock().setType(Material.AIR); + event.getContainer().addItem(new ItemStack(Material.SIGN, 1)); + } + } + + private static boolean shopShouldBeRemoved(Container container) { + return Config.getBoolean(Property.REMOVE_EMPTY_SHOPS) && shopIsEmpty(container); + } + + private static boolean shopIsEmpty(Container container) { + return container.isEmpty(); + } +} diff --git a/com/Acrobot/ChestShop/Listeners/Transaction/TransactionLogger.java b/com/Acrobot/ChestShop/Listeners/Transaction/TransactionLogger.java new file mode 100644 index 0000000..b06c177 --- /dev/null +++ b/com/Acrobot/ChestShop/Listeners/Transaction/TransactionLogger.java @@ -0,0 +1,79 @@ +package com.Acrobot.ChestShop.Listeners.Transaction; + +import com.Acrobot.ChestShop.ChestShop; +import com.Acrobot.ChestShop.Config.Config; +import com.Acrobot.ChestShop.DB.Queue; +import com.Acrobot.ChestShop.DB.Transaction; +import com.Acrobot.ChestShop.Events.TransactionEvent; +import org.bukkit.Location; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.inventory.ItemStack; + +import static com.Acrobot.Breeze.Utils.MaterialUtil.getSignName; +import static com.Acrobot.ChestShop.Config.Property.GENERATE_STATISTICS_PAGE; +import static com.Acrobot.ChestShop.Config.Property.LOG_TO_DATABASE; +import static com.Acrobot.ChestShop.Events.TransactionEvent.Type.BUY; + +/** + * @author Acrobot + */ +public class TransactionLogger implements Listener { + @EventHandler + public static void onTransaction(TransactionEvent event) { + StringBuilder message = new StringBuilder(70); + + message.append(event.getClient().getName()); + + if (event.getTransactionType() == BUY) { + message.append(" bought "); + } else { + message.append(" sold "); + } + + message.append(event.getItemAmount()).append(' '); + message.append(getSignName(event.getItem())).append(" for "); + message.append(event.getPrice()); + + if (event.getTransactionType() == BUY) { + message.append(" from "); + } else { + message.append(" to "); + } + + message.append(event.getOwner()).append(' '); + + message.append(locationToString(event.getSign().getLocation())); + + ChestShop.getBukkitLogger().info(message.toString()); + } + + @EventHandler + public static void onTransactionLogToDB(TransactionEvent event) { + if (!Config.getBoolean(LOG_TO_DATABASE) && !Config.getBoolean(GENERATE_STATISTICS_PAGE)) { + return; + } + + Transaction transaction = new Transaction(); + ItemStack item = event.getItem(); + + transaction.setAmount(event.getItemAmount()); + + transaction.setItemID(item.getTypeId()); + transaction.setItemDurability(item.getDurability()); + + transaction.setPrice((float) event.getPrice()); + + transaction.setShopOwner(event.getOwner()); + transaction.setShopUser(event.getClient().getName()); + + transaction.setSec(System.currentTimeMillis() / 1000); + transaction.setBuy(event.getTransactionType() == BUY); + + Queue.addToQueue(transaction); + } + + private static String locationToString(Location loc) { + return '[' + loc.getWorld().getName() + "] " + loc.getBlockX() + ", " + loc.getBlockY() + ", " + loc.getBlockZ(); + } +} diff --git a/com/Acrobot/ChestShop/Listeners/Transaction/TransactionMessageSender.java b/com/Acrobot/ChestShop/Listeners/Transaction/TransactionMessageSender.java new file mode 100644 index 0000000..b790e48 --- /dev/null +++ b/com/Acrobot/ChestShop/Listeners/Transaction/TransactionMessageSender.java @@ -0,0 +1,95 @@ +package com.Acrobot.ChestShop.Listeners.Transaction; + +import com.Acrobot.Breeze.Utils.StringUtil; +import com.Acrobot.ChestShop.Config.Config; +import com.Acrobot.ChestShop.Config.Language; +import com.Acrobot.ChestShop.Economy.Economy; +import com.Acrobot.ChestShop.Events.TransactionEvent; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; + +import static com.Acrobot.ChestShop.Config.Language.*; +import static com.Acrobot.ChestShop.Config.Property.SHOW_TRANSACTION_INFORMATION_CLIENT; +import static com.Acrobot.ChestShop.Config.Property.SHOW_TRANSACTION_INFORMATION_OWNER; + +/** + * @author Acrobot + */ +public class TransactionMessageSender implements Listener { + @EventHandler(priority = EventPriority.MONITOR) + public static void onTransaction(TransactionEvent event) { + if (event.getTransactionType() == TransactionEvent.Type.BUY) { + sendBuyMessage(event); + } else { + sendSellMessage(event); + } + } + + protected static void sendBuyMessage(TransactionEvent event) { + String itemName = StringUtil.capitalizeFirstLetter(event.getItem().getType().name()); + String owner = event.getOwner(); + + Player player = event.getClient(); + + int amount = event.getItemAmount(); + String price = Economy.formatBalance(event.getPrice()); + + if (Config.getBoolean(SHOW_TRANSACTION_INFORMATION_CLIENT)) { + String message = formatMessage(YOU_BOUGHT_FROM_SHOP, itemName, price, amount); + message = message.replace("%owner", owner); + + player.sendMessage(message); + } + + if (Config.getBoolean(SHOW_TRANSACTION_INFORMATION_OWNER)) { + String message = formatMessage(SOMEBODY_BOUGHT_FROM_YOUR_SHOP, itemName, price, amount); + message = message.replace("%buyer", player.getName()); + + sendMessageToOwner(message, event); + } + } + + protected static void sendSellMessage(TransactionEvent event) { + String itemName = StringUtil.capitalizeFirstLetter(event.getItem().getType().name()); + String owner = event.getOwner(); + + Player player = event.getClient(); + + int amount = event.getItemAmount(); + String price = Economy.formatBalance(event.getPrice()); + + if (Config.getBoolean(SHOW_TRANSACTION_INFORMATION_CLIENT)) { + String message = formatMessage(YOU_SOLD_TO_SHOP, itemName, price, amount); + message = message.replace("%buyer", owner); + + player.sendMessage(message); + } + + if (Config.getBoolean(SHOW_TRANSACTION_INFORMATION_OWNER)) { + String message = formatMessage(SOMEBODY_SOLD_TO_YOUR_SHOP, itemName, price, amount); + message = message.replace("%seller", player.getName()); + + sendMessageToOwner(message, event); + } + } + + private static void sendMessageToOwner(String message, TransactionEvent event) { + String owner = event.getOwner(); + + Player player = Bukkit.getPlayer(owner); + + if (player != null) { + player.sendMessage(message); + } + } + + private static String formatMessage(Language message, String item, String price, int amount) { + return Config.getLocal(message) + .replace("%amount", String.valueOf(amount)) + .replace("%item", item) + .replace("%price", price); + } +} diff --git a/com/Acrobot/ChestShop/Listeners/playerInteract.java b/com/Acrobot/ChestShop/Listeners/playerInteract.java deleted file mode 100644 index 992834d..0000000 --- a/com/Acrobot/ChestShop/Listeners/playerInteract.java +++ /dev/null @@ -1,121 +0,0 @@ -package com.Acrobot.ChestShop.Listeners; - -import com.Acrobot.ChestShop.Config.Config; -import com.Acrobot.ChestShop.Config.Language; -import com.Acrobot.ChestShop.Config.Property; -import com.Acrobot.ChestShop.Permission; -import com.Acrobot.ChestShop.Plugins.ChestShop; -import com.Acrobot.ChestShop.Security; -import com.Acrobot.ChestShop.Shop.ShopManagement; -import com.Acrobot.ChestShop.Signs.restrictedSign; -import com.Acrobot.ChestShop.Utils.uBlock; -import com.Acrobot.ChestShop.Utils.uSign; -import org.bukkit.GameMode; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.block.Chest; -import org.bukkit.block.Sign; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.block.Action; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.inventory.Inventory; - -import java.util.HashMap; - -/** - * @author Acrobot - */ -public class PlayerInteract implements Listener { - private static final HashMap timeOfTheLatestSignClick = new HashMap(); - public int transactionBlockInterval = 100; - - public PlayerInteract(int transactionInterval) { - this.transactionBlockInterval = transactionInterval; - } - - @EventHandler(priority = EventPriority.HIGHEST) - public void onPlayerInteract(PlayerInteractEvent event) { - Action action = event.getAction(); - if (!playerClickedBlock(action)) { - return; - } - - Block block = event.getClickedBlock(); - Player player = event.getPlayer(); - - if (Config.getBoolean(Property.USE_BUILT_IN_PROTECTION) && block.getType() == Material.CHEST) { - if (!hasAdminPermissions(player) && !ChestShop.canAccess(player, block)) { - player.sendMessage(Config.getLocal(Language.ACCESS_DENIED)); - event.setCancelled(true); - return; - } - } - - if (!uSign.isSign(block)) return; - Sign sign = (Sign) block.getState(); - - if (player.getItemInHand() != null && player.getItemInHand().getType() == Material.SIGN) return; - if (!uSign.isValid(sign) || !enoughTimeHasPassed(player) || player.isSneaking()) return; - - if (Config.getBoolean(Property.IGNORE_CREATIVE_MODE) && player.getGameMode() == GameMode.CREATIVE) { - event.setCancelled(true); - return; - } - - timeOfTheLatestSignClick.put(player, System.currentTimeMillis()); - - if (action == Action.RIGHT_CLICK_BLOCK) event.setCancelled(true); - - if (uSign.canAccess(player, sign)) { - if (!Config.getBoolean(Property.ALLOW_SIGN_CHEST_OPEN)) { - return; - } - - if (action != Action.LEFT_CLICK_BLOCK || !Config.getBoolean(Property.ALLOW_LEFT_CLICK_DESTROYING)) { - showChestGUI(player, block); - } - return; - } - - if (restrictedSign.isRestrictedShop(sign) && !restrictedSign.canAccess(sign, player)) { - player.sendMessage(Config.getLocal(Language.ACCESS_DENIED)); - return; - } - - Action buy = (Config.getBoolean(Property.REVERSE_BUTTONS) ? Action.LEFT_CLICK_BLOCK : Action.RIGHT_CLICK_BLOCK); - - if (action == buy) ShopManagement.buy(sign, player); - else ShopManagement.sell(sign, player); - } - - private boolean enoughTimeHasPassed(Player player) { - return !timeOfTheLatestSignClick.containsKey(player) || (System.currentTimeMillis() - timeOfTheLatestSignClick.get(player)) >= transactionBlockInterval; - } - - private static boolean playerClickedBlock(Action action) { - return action == Action.LEFT_CLICK_BLOCK || action == Action.RIGHT_CLICK_BLOCK; - } - - - private static boolean hasAdminPermissions(Player player) { - return Permission.has(player, Permission.ADMIN) || Permission.has(player, Permission.MOD); - } - - private static void showChestGUI(Player player, Block block) { - Chest chest = uBlock.findConnectedChest(block); - if (chest == null) { //Sorry, no chest found - player.sendMessage(Config.getLocal(Language.NO_CHEST_DETECTED)); - return; - } - - if (!hasAdminPermissions(player) && !Security.canAccess(player, block)) { - return; - } - - Inventory chestInv = chest.getInventory(); - player.openInventory(chestInv); - } -} diff --git a/com/Acrobot/ChestShop/Listeners/signChange.java b/com/Acrobot/ChestShop/Listeners/signChange.java deleted file mode 100644 index 9393a81..0000000 --- a/com/Acrobot/ChestShop/Listeners/signChange.java +++ /dev/null @@ -1,225 +0,0 @@ -package com.Acrobot.ChestShop.Listeners; - -import com.Acrobot.ChestShop.ChestShop; -import com.Acrobot.ChestShop.Config.Config; -import com.Acrobot.ChestShop.Config.Language; -import com.Acrobot.ChestShop.Config.MaxPrice; -import com.Acrobot.ChestShop.Config.Property; -import com.Acrobot.ChestShop.Economy.Economy; -import com.Acrobot.ChestShop.Events.BuildPermissionEvent; -import com.Acrobot.ChestShop.Events.ShopCreatedEvent; -import com.Acrobot.ChestShop.Items.Items; -import com.Acrobot.ChestShop.Permission; -import com.Acrobot.ChestShop.Security; -import com.Acrobot.ChestShop.Signs.restrictedSign; -import com.Acrobot.ChestShop.Utils.uBlock; -import com.Acrobot.ChestShop.Utils.uName; -import com.Acrobot.ChestShop.Utils.uNumber; -import com.Acrobot.ChestShop.Utils.uSign; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.block.Chest; -import org.bukkit.block.Sign; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.block.SignChangeEvent; -import org.bukkit.inventory.ItemStack; - -/** - * @author Acrobot - */ -public class SignChange implements Listener { - @EventHandler - public static void onSignChange(SignChangeEvent event) { - Block signBlock = event.getBlock(); - String[] line = event.getLines(); - - boolean isAlmostReady = uSign.isValidPreparedSign(line); - - Player player = event.getPlayer(); - ItemStack stock = Items.getItemStack(line[3]); - Material mat = stock == null ? null : stock.getType(); - - boolean playerIsAdmin = Permission.has(player, Permission.ADMIN); - - if (isAlmostReady) { - if (mat == null) { - player.sendMessage(Config.getLocal(Language.INCORRECT_ITEM_ID)); - dropSign(event); - return; - } - } else { - if (restrictedSign.isRestricted(line)) { - if (!restrictedSign.hasPermission(player, line)) { - player.sendMessage(Config.getLocal(Language.ACCESS_DENIED)); - dropSign(event); - return; - } - Block secondSign = signBlock.getRelative(BlockFace.DOWN); - if (!playerIsAdmin && (!uSign.isSign(secondSign) || !uSign.isValid((Sign) secondSign.getState()) - || !uSign.canAccess(player, (Sign) secondSign))) dropSign(event); - } - return; - } - - if (!playerCanUseName(player, line[0])) { - event.setLine(0, uName.stripName(player.getName())); - } - - String thirdLine = formatThirdLine(line[2]); - if (thirdLine == null) { - dropSign(event); - player.sendMessage(Config.getLocal(Language.YOU_CANNOT_CREATE_SHOP)); - return; - } - event.setLine(2, thirdLine); - event.setLine(3, formatFourthLine(line[3], stock)); - - Chest chest = uBlock.findConnectedChest(signBlock); - - boolean isAdminShop = uSign.isAdminShop(event.getLine(0)); - if (!isAdminShop) { - if (chest == null) { - player.sendMessage(Config.getLocal(Language.NO_CHEST_DETECTED)); - dropSign(event); - return; - } else if (!playerIsAdmin) { - if (!Security.canPlaceSign(player, (Sign) signBlock.getState())) { - player.sendMessage(Config.getLocal(Language.CANNOT_CREATE_SHOP_HERE)); - dropSign(event); - return; - } - - Block chestBlock = chest.getBlock(); - BuildPermissionEvent bEvent = new BuildPermissionEvent(player, chest.getLocation(), signBlock.getLocation()); - - ChestShop.callEvent(bEvent); - - if (!bEvent.isAllowed()) { - player.sendMessage(Config.getLocal(Language.CANNOT_CREATE_SHOP_HERE)); - dropSign(event); - return; - } - - if (!Security.canAccess(player, chestBlock)) { - player.sendMessage(Config.getLocal(Language.CANNOT_ACCESS_THE_CHEST)); - dropSign(event); - return; - } - } - } - - double buyPrice = uSign.buyPrice(thirdLine); - double sellPrice = uSign.sellPrice(thirdLine); - - if (!playerIsAdmin && (!canCreateShop(player, mat, buyPrice != -1, sellPrice != -1) || !MaxPrice.canCreate(buyPrice, sellPrice, mat))) { - player.sendMessage(Config.getLocal(Language.YOU_CANNOT_CREATE_SHOP)); - dropSign(event); - return; - } - - float shopCreationPrice = Config.getFloat(Property.SHOP_CREATION_PRICE); - boolean paid = shopCreationPrice != 0 && !isAdminShop && !Permission.has(player, Permission.NOFEE); - if (paid) { - if (!Economy.hasEnough(player.getName(), shopCreationPrice)) { - player.sendMessage(Config.getLocal(Language.NOT_ENOUGH_MONEY)); - dropSign(event); - return; - } - - Economy.subtract(player.getName(), shopCreationPrice); - } - - if (Config.getBoolean(Property.PROTECT_SIGN_WITH_LWC)) { - if (!Security.protect(player.getName(), signBlock)) player.sendMessage(Config.getLocal(Language.NOT_ENOUGH_PROTECTIONS)); - } - if (Config.getBoolean(Property.PROTECT_CHEST_WITH_LWC) && chest != null && Security.protect(player.getName(), chest.getBlock())) { - player.sendMessage(Config.getLocal(Language.PROTECTED_SHOP)); - } - - uName.saveName(player.getName()); - player.sendMessage(Config.getLocal(Language.SHOP_CREATED) + (paid ? " - " + Economy.formatBalance(shopCreationPrice) : "")); - - ShopCreatedEvent sEvent = new ShopCreatedEvent(player, (Sign) signBlock.getState(), chest, event.getLines()); - ChestShop.callEvent(sEvent); - } - - private static boolean canCreateShop(Player player, Material mat, double buyPrice, double sellPrice) { - if (Config.getBoolean(Property.BLOCK_SHOPS_WITH_SELL_PRICE_HIGHER_THAN_BUY_PRICE)) { - if (buyPrice != -1 && sellPrice != -1 && sellPrice > buyPrice) { - return false; - } - } - return canCreateShop(player, mat, buyPrice != -1, sellPrice != -1) && MaxPrice.canCreate(buyPrice, sellPrice, mat); - } - - private static boolean canCreateShop(Player player, Material material, boolean buy, boolean sell) { - if (Permission.has(player, Permission.SHOP_CREATION_ID + Integer.toString(material.getId()))) { - return true; - } - - if (buy && !Permission.has(player, Permission.SHOP_CREATION_BUY)) return false; - if (sell && !Permission.has(player, Permission.SHOP_CREATION_SELL)) return false; - - return true; - } - - private static String formatThirdLine(String thirdLine) { - String line = thirdLine.toUpperCase(); - String[] split = line.split(":"); - - if (uNumber.isFloat(split[0])) { - line = "B " + line; - } - if (split.length == 2 && uNumber.isFloat(split[1])) { - line = line + " S"; - } - - if (line.length() > 15) { - line.replace(" ", ""); - } - - return (line.length() > 15 ? null : line); - } - - private static String formatFourthLine(String line, ItemStack itemStack) { - StringBuilder formatted = new StringBuilder(15); - - String[] split = line.split(":|-", 2); - String itemName = Items.getName(itemStack, false); - - short dataLength = (short) (line.length() - split[0].length()); - - if (itemName.length() > (15 - dataLength)) { - itemName = itemName.substring(0, 15 - dataLength); - } - - if (Items.getItemStack(itemName).getType() != itemStack.getType()) { - itemName = String.valueOf(itemStack.getTypeId()); - } - - formatted.append(itemName); - if (split.length == 2) { - formatted.append(line.charAt(line.indexOf(split[1]) - 1)).append(split[1]); - } - - return uSign.capitalizeFirstLetter(formatted.toString(), ' '); - } - - private static boolean playerCanUseName(Player player, String name) { - return !name.isEmpty() && (uName.canUseName(player, name) || Permission.has(player, Permission.ADMIN)); - } - - private static void sendMessageAndExit(Player player, Language message, SignChangeEvent event) { - player.sendMessage(Config.getLocal(message)); - - dropSign(event); - } - - private static void dropSign(SignChangeEvent event) { - event.setCancelled(true); - event.getBlock().breakNaturally(); - } -} diff --git a/com/Acrobot/ChestShop/Logging/Logging.java b/com/Acrobot/ChestShop/Logging/Logging.java deleted file mode 100644 index 42b0b62..0000000 --- a/com/Acrobot/ChestShop/Logging/Logging.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.Acrobot.ChestShop.Logging; - -import com.Acrobot.ChestShop.ChestShop; -import com.Acrobot.ChestShop.Config.Config; -import com.Acrobot.ChestShop.Config.Property; -import com.Acrobot.ChestShop.DB.Queue; -import com.Acrobot.ChestShop.DB.Transaction; -import com.Acrobot.ChestShop.Items.Items; -import com.Acrobot.ChestShop.Shop.Shop; -import org.bukkit.Location; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; - -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * @author Acrobot - */ -public class Logging { - private static final Logger logger = ChestShop.getBukkitLogger(); - - public static void log(String string) { - logger.log(Level.INFO, string); - } - - public static void logTransaction(boolean playerIsBuyingFromShop, Shop shop, double price, Player player) { - StringBuilder builder = new StringBuilder(player.getName()); - - if (playerIsBuyingFromShop) { - builder.append(" bought "); - } else { - builder.append(" sold "); - } - - builder.append(shop.stockAmount).append(' '); - builder.append(Items.getSignName(shop.stock)).append(" for "); - builder.append(price); - - if (playerIsBuyingFromShop) { - builder.append(" from "); - } else { - builder.append(" to "); - } - - builder.append(shop.owner).append(" at "); - builder.append(locationToString(shop.sign.getLocation())); - - log(builder.toString()); - - if (weShouldLogToDB()) { - logToDatabase(playerIsBuyingFromShop, shop, price, player); - } - } - - private static boolean weShouldLogToDB() { - return Config.getBoolean(Property.LOG_TO_DATABASE) || Config.getBoolean(Property.GENERATE_STATISTICS_PAGE); - } - - private static String locationToString(Location loc) { - return '[' + loc.getWorld().getName() + "] " + loc.getBlockX() + ", " + loc.getBlockY() + ", " + loc.getBlockZ(); - } - - private static void logToDatabase(boolean isBuying, Shop shop, double price, Player player) { - Transaction transaction = new Transaction(); - - transaction.setAmount(shop.stockAmount); - transaction.setBuy(isBuying); - - ItemStack stock = shop.stock; - - transaction.setItemDurability(stock.getDurability()); - transaction.setItemID(stock.getTypeId()); - transaction.setPrice((float) price); - transaction.setSec(System.currentTimeMillis() / 1000); - transaction.setShopOwner(shop.owner); - transaction.setShopUser(player.getName()); - - Queue.addToQueue(transaction); - } -} diff --git a/com/Acrobot/ChestShop/Plugins/ChestShop.java b/com/Acrobot/ChestShop/Plugins/ChestShop.java index f0251e3..4b523ee 100644 --- a/com/Acrobot/ChestShop/Plugins/ChestShop.java +++ b/com/Acrobot/ChestShop/Plugins/ChestShop.java @@ -1,9 +1,10 @@ package com.Acrobot.ChestShop.Plugins; -import com.Acrobot.ChestShop.Containers.MinecraftChest; -import com.Acrobot.ChestShop.Events.ProtectionCheckEvent; +import com.Acrobot.Breeze.Utils.BlockUtil; +import com.Acrobot.ChestShop.Containers.ShopChest; +import com.Acrobot.ChestShop.Events.Protection.ProtectionCheckEvent; +import com.Acrobot.ChestShop.Signs.ChestShopSign; import com.Acrobot.ChestShop.Utils.uName; -import com.Acrobot.ChestShop.Utils.uSign; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.Chest; @@ -39,7 +40,7 @@ public class ChestShop implements Listener { if (isSign(block)) { Sign sign = (Sign) block.getState(); - if (!uSign.isValid(sign)) { + if (!ChestShopSign.isValid(sign)) { return true; } @@ -49,7 +50,7 @@ public class ChestShop implements Listener { } if (isChest(block)) { - MinecraftChest chest = new MinecraftChest((Chest) block.getState()); + ShopChest chest = new ShopChest((Chest) block.getState()); Sign sign = chest.findShopSign(); @@ -66,7 +67,7 @@ public class ChestShop implements Listener { } private static boolean isSign(Block block) { - return uSign.isSign(block); + return BlockUtil.isSign(block); } private static boolean canBeProtected(Block block) { diff --git a/com/Acrobot/ChestShop/Plugins/Deadbolt.java b/com/Acrobot/ChestShop/Plugins/Deadbolt.java index fc00fdd..8fa18f9 100644 --- a/com/Acrobot/ChestShop/Plugins/Deadbolt.java +++ b/com/Acrobot/ChestShop/Plugins/Deadbolt.java @@ -1,7 +1,6 @@ package com.Acrobot.ChestShop.Plugins; -import com.Acrobot.ChestShop.Events.ProtectionCheckEvent; -import com.Acrobot.ChestShop.Utils.uName; +import com.Acrobot.ChestShop.Events.Protection.ProtectionCheckEvent; import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.event.Event; @@ -25,9 +24,7 @@ public class Deadbolt implements Listener { return; } - String shortPlayerName = uName.shortenName(player); - - if (!com.daemitus.deadbolt.Deadbolt.getAllNames(block).contains(shortPlayerName)) { + if (!com.daemitus.deadbolt.Deadbolt.isAuthorized(player, block)) { event.setResult(Event.Result.DENY); } } diff --git a/com/Acrobot/ChestShop/Plugins/LightweightChestProtection.java b/com/Acrobot/ChestShop/Plugins/LightweightChestProtection.java index 2ccd54a..f5f7f15 100644 --- a/com/Acrobot/ChestShop/Plugins/LightweightChestProtection.java +++ b/com/Acrobot/ChestShop/Plugins/LightweightChestProtection.java @@ -1,17 +1,27 @@ package com.Acrobot.ChestShop.Plugins; -import com.Acrobot.ChestShop.Events.ProtectBlockEvent; -import com.Acrobot.ChestShop.Events.ProtectionCheckEvent; +import com.Acrobot.ChestShop.Config.Config; +import com.Acrobot.ChestShop.Events.Protection.ProtectBlockEvent; +import com.Acrobot.ChestShop.Events.Protection.ProtectionCheckEvent; +import com.Acrobot.ChestShop.Events.ShopCreatedEvent; +import com.Acrobot.ChestShop.Security; import com.griefcraft.lwc.LWC; import com.griefcraft.model.Protection; import com.griefcraft.modules.limits.LimitsV2; import org.bukkit.Bukkit; import org.bukkit.block.Block; +import org.bukkit.block.Chest; +import org.bukkit.block.Sign; import org.bukkit.entity.Player; import org.bukkit.event.Event; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; +import static com.Acrobot.ChestShop.Config.Language.NOT_ENOUGH_PROTECTIONS; +import static com.Acrobot.ChestShop.Config.Language.PROTECTED_SHOP; +import static com.Acrobot.ChestShop.Config.Property.PROTECT_CHEST_WITH_LWC; +import static com.Acrobot.ChestShop.Config.Property.PROTECT_SIGN_WITH_LWC; + /** * @author Acrobot */ @@ -24,6 +34,23 @@ public class LightweightChestProtection implements Listener { limitsModule = new LimitsV2(); } + @EventHandler + public static void onShopCreation(ShopCreatedEvent event) { + Player player = event.getPlayer(); + Sign sign = event.getSign(); + Chest connectedChest = event.getChest(); + + if (Config.getBoolean(PROTECT_SIGN_WITH_LWC)) { + if (!Security.protect(player.getName(), sign.getBlock())) { + player.sendMessage(Config.getLocal(NOT_ENOUGH_PROTECTIONS)); + } + } + + if (Config.getBoolean(PROTECT_CHEST_WITH_LWC) && connectedChest != null && Security.protect(player.getName(), connectedChest.getBlock())) { + player.sendMessage(Config.getLocal(PROTECTED_SHOP)); + } + } + @EventHandler public void onProtectionCheck(ProtectionCheckEvent event) { if (event.getResult() == Event.Result.DENY) { diff --git a/com/Acrobot/ChestShop/Plugins/Lockette.java b/com/Acrobot/ChestShop/Plugins/Lockette.java index 4b0c534..b349a30 100644 --- a/com/Acrobot/ChestShop/Plugins/Lockette.java +++ b/com/Acrobot/ChestShop/Plugins/Lockette.java @@ -1,6 +1,6 @@ package com.Acrobot.ChestShop.Plugins; -import com.Acrobot.ChestShop.Events.ProtectionCheckEvent; +import com.Acrobot.ChestShop.Events.Protection.ProtectionCheckEvent; import com.Acrobot.ChestShop.Utils.uName; import org.bukkit.block.Block; import org.bukkit.entity.Player; diff --git a/com/Acrobot/ChestShop/Plugins/SimpleChestLock.java b/com/Acrobot/ChestShop/Plugins/SimpleChestLock.java index 7b6640c..d1fc371 100644 --- a/com/Acrobot/ChestShop/Plugins/SimpleChestLock.java +++ b/com/Acrobot/ChestShop/Plugins/SimpleChestLock.java @@ -1,6 +1,6 @@ package com.Acrobot.ChestShop.Plugins; -import com.Acrobot.ChestShop.Events.ProtectionCheckEvent; +import com.Acrobot.ChestShop.Events.Protection.ProtectionCheckEvent; import com.webkonsept.bukkit.simplechestlock.SCL; import org.bukkit.block.Block; import org.bukkit.entity.Player; diff --git a/com/Acrobot/ChestShop/Plugins/Towny.java b/com/Acrobot/ChestShop/Plugins/Towny.java index 3074872..9389a21 100644 --- a/com/Acrobot/ChestShop/Plugins/Towny.java +++ b/com/Acrobot/ChestShop/Plugins/Towny.java @@ -2,7 +2,7 @@ package com.Acrobot.ChestShop.Plugins; import com.Acrobot.ChestShop.Config.Config; import com.Acrobot.ChestShop.Config.Property; -import com.Acrobot.ChestShop.Events.BuildPermissionEvent; +import com.Acrobot.ChestShop.Events.Protection.BuildPermissionEvent; import com.palmergames.bukkit.towny.exceptions.NotRegisteredException; import com.palmergames.bukkit.towny.object.TownBlockOwner; import com.palmergames.bukkit.towny.object.TownBlockType; diff --git a/com/Acrobot/ChestShop/Plugins/WorldGuardBuilding.java b/com/Acrobot/ChestShop/Plugins/WorldGuardBuilding.java index 3adf47c..b5934a4 100644 --- a/com/Acrobot/ChestShop/Plugins/WorldGuardBuilding.java +++ b/com/Acrobot/ChestShop/Plugins/WorldGuardBuilding.java @@ -3,7 +3,7 @@ package com.Acrobot.ChestShop.Plugins; import com.Acrobot.ChestShop.ChestShop; import com.Acrobot.ChestShop.Config.Config; import com.Acrobot.ChestShop.Config.Property; -import com.Acrobot.ChestShop.Events.BuildPermissionEvent; +import com.Acrobot.ChestShop.Events.Protection.BuildPermissionEvent; import com.sk89q.worldedit.bukkit.BukkitUtil; import com.sk89q.worldguard.bukkit.WorldGuardPlugin; import com.sk89q.worldguard.protection.ApplicableRegionSet; diff --git a/com/Acrobot/ChestShop/Plugins/WorldGuardProtection.java b/com/Acrobot/ChestShop/Plugins/WorldGuardProtection.java index bb28848..aa43821 100644 --- a/com/Acrobot/ChestShop/Plugins/WorldGuardProtection.java +++ b/com/Acrobot/ChestShop/Plugins/WorldGuardProtection.java @@ -1,6 +1,6 @@ package com.Acrobot.ChestShop.Plugins; -import com.Acrobot.ChestShop.Events.ProtectionCheckEvent; +import com.Acrobot.ChestShop.Events.Protection.ProtectionCheckEvent; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.bukkit.BukkitUtil; import com.sk89q.worldguard.LocalPlayer; diff --git a/com/Acrobot/ChestShop/Security.java b/com/Acrobot/ChestShop/Security.java index 5589cf5..79ae160 100644 --- a/com/Acrobot/ChestShop/Security.java +++ b/com/Acrobot/ChestShop/Security.java @@ -1,12 +1,13 @@ package com.Acrobot.ChestShop; +import com.Acrobot.Breeze.Utils.BlockUtil; import com.Acrobot.ChestShop.Config.Config; import com.Acrobot.ChestShop.Config.Property; -import com.Acrobot.ChestShop.Events.ProtectBlockEvent; -import com.Acrobot.ChestShop.Events.ProtectionCheckEvent; +import com.Acrobot.ChestShop.Events.Protection.ProtectBlockEvent; +import com.Acrobot.ChestShop.Events.Protection.ProtectionCheckEvent; +import com.Acrobot.ChestShop.Signs.ChestShopSign; import com.Acrobot.ChestShop.Utils.uBlock; import com.Acrobot.ChestShop.Utils.uName; -import com.Acrobot.ChestShop.Utils.uSign; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; @@ -18,8 +19,8 @@ import org.bukkit.event.Event; * @author Acrobot */ public class Security { - private static final BlockFace[] faces = {BlockFace.UP, BlockFace.EAST, BlockFace.WEST, BlockFace.NORTH, BlockFace.SOUTH}; - private static final BlockFace[] blockFaces = {BlockFace.UP, BlockFace.DOWN, BlockFace.EAST, BlockFace.WEST, BlockFace.NORTH, BlockFace.SOUTH}; + private static final BlockFace[] SIGN_CONNECTION_FACES = {BlockFace.UP, BlockFace.EAST, BlockFace.WEST, BlockFace.NORTH, BlockFace.SOUTH}; + private static final BlockFace[] BLOCKS_AROUND = {BlockFace.UP, BlockFace.DOWN, BlockFace.EAST, BlockFace.WEST, BlockFace.NORTH, BlockFace.SOUTH}; public static boolean protect(String playerName, Block block) { ProtectBlockEvent event = new ProtectBlockEvent(block, playerName); @@ -40,8 +41,8 @@ public class Security { } private static boolean canBePlaced(Player player, Block signBlock) { - for (BlockFace bf : blockFaces) { - Block block = signBlock.getRelative(bf); + for (BlockFace face : BLOCKS_AROUND) { + Block block = signBlock.getRelative(face); if (block.getType() != Material.CHEST) { continue; @@ -58,13 +59,15 @@ public class Security { String shortName = uName.stripName(p.getName()); if (Config.getBoolean(Property.ALLOW_MULTIPLE_SHOPS_AT_ONE_BLOCK)) return false; - for (BlockFace bf : faces) { + for (BlockFace bf : SIGN_CONNECTION_FACES) { Block block = baseBlock.getRelative(bf); - if (!uSign.isSign(block)) continue; + if (!BlockUtil.isSign(block)) { + continue; + } Sign s = (Sign) block.getState(); - if (uSign.isValid(s) && !block.equals(signBlock) && uBlock.getAttachedFace(s).equals(baseBlock) && !s.getLine(0).equals(shortName)) + if (ChestShopSign.isValid(s) && !block.equals(signBlock) && uBlock.getAttachedFace(s).equals(baseBlock) && !s.getLine(0).equals(shortName)) return true; } return false; diff --git a/com/Acrobot/ChestShop/Shop/Shop.java b/com/Acrobot/ChestShop/Shop/Shop.java index db3443b..12d28ea 100644 --- a/com/Acrobot/ChestShop/Shop/Shop.java +++ b/com/Acrobot/ChestShop/Shop/Shop.java @@ -1,215 +1,185 @@ package com.Acrobot.ChestShop.Shop; +import com.Acrobot.Breeze.Utils.InventoryUtil; +import com.Acrobot.Breeze.Utils.MaterialUtil; +import com.Acrobot.Breeze.Utils.PriceUtil; +import com.Acrobot.Breeze.Utils.StringUtil; import com.Acrobot.ChestShop.ChestShop; import com.Acrobot.ChestShop.Config.Config; import com.Acrobot.ChestShop.Config.Language; import com.Acrobot.ChestShop.Config.Property; +import com.Acrobot.ChestShop.Containers.AdminChest; import com.Acrobot.ChestShop.Containers.Container; +import com.Acrobot.ChestShop.Containers.ShopChest; import com.Acrobot.ChestShop.Economy.Economy; -import com.Acrobot.ChestShop.Logging.Logging; +import com.Acrobot.ChestShop.Events.TransactionEvent; import com.Acrobot.ChestShop.Permission; -import com.Acrobot.ChestShop.Utils.uInventory; -import com.Acrobot.ChestShop.Utils.uSign; +import com.Acrobot.ChestShop.Signs.ChestShopSign; +import com.Acrobot.ChestShop.Utils.uBlock; import org.bukkit.Material; +import org.bukkit.block.Chest; import org.bukkit.block.Sign; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import static com.Acrobot.Breeze.Utils.PriceUtil.*; +import static com.Acrobot.ChestShop.Config.Language.*; +import static com.Acrobot.ChestShop.Config.Property.ALLOW_PARTIAL_TRANSACTIONS; +import static com.Acrobot.ChestShop.Config.Property.SHOW_MESSAGE_OUT_OF_STOCK; +import static com.Acrobot.ChestShop.Events.TransactionEvent.Type.BUY; +import static com.Acrobot.ChestShop.Events.TransactionEvent.Type.SELL; +import static com.Acrobot.ChestShop.Signs.ChestShopSign.*; + /** * @author Acrobot */ public class Shop { - private final short durability; - private final Container chest; + private final Container container; + private final String owner; - public final ItemStack stock; - public int stockAmount; - public final String owner; - public final Sign sign; + private int stockAmount; + private ItemStack stock; + + private final Sign sign; + + public Shop(Container container, ItemStack stock, Sign sign) { + this.container = container; + this.owner = sign.getLine(NAME_LINE); + + this.stock = stock; + this.stockAmount = stock.getAmount(); - public Shop(Container chest, Sign sign, ItemStack... itemStacks) { - this.stock = itemStacks[0]; - this.durability = stock.getDurability(); - this.chest = chest; - this.owner = sign.getLine(0); - this.stockAmount = uSign.itemAmount(sign.getLine(1)); this.sign = sign; } - public void buyItemFrom(Player player) { - double buyPrice = uSign.buyPrice(sign.getLine(2)); + public void buyFromPlayer(Player player) { + Language message = sell(player); - if (chest == null) { - sendMessage(player, Language.NO_CHEST_DETECTED); - return; - } - if (Double.compare(buyPrice, 0.01D) < 0) { - sendMessage(player, Language.NO_BUYING_HERE); - return; + sendMessage(player, message); + } + + public void sellToPlayer(Player player) { + Language message = buy(player); + + sendMessage(player, message); + } + + private Language buy(Player player) { + double price = getBuyPrice(sign.getLine(PRICE_LINE)); + + if (price == NO_PRICE) { + return NO_BUYING_HERE; } - if (!Permission.has(player, Permission.BUY) && !Permission.has(player, Permission.BUY_ID + Integer.toString(stock.getTypeId()))) { - sendMessage(player, Language.NO_PERMISSION); - return; + if (container == null) { + return NO_CHEST_DETECTED; } + + if (!hasPermission(player, stock.getType(), true)) { + return NO_PERMISSION; + } + String playerName = player.getName(); + String itemName = StringUtil.capitalizeFirstLetter(stock.getType().name()); + double balance = Economy.balance(playerName); - if (!Economy.hasEnough(playerName, buyPrice)) { - int items = calculateItemAmount(Economy.balance(playerName), buyPrice); - if (!Config.getBoolean(Property.ALLOW_PARTIAL_TRANSACTIONS) || items < 1) { - sendMessage(player, Language.NOT_ENOUGH_MONEY); - return; + if (!Economy.hasEnough(playerName, price)) { + int possiblePartialItemCount = calculateItemAmount(balance, price); + + if (!partialTransactionAllowed(possiblePartialItemCount)) { + return NOT_ENOUGH_MONEY; } else { - buyPrice = (buyPrice / stockAmount) * items; - stockAmount = items; + price = (price / stockAmount) * possiblePartialItemCount; + stockAmount = possiblePartialItemCount; } } + if (!stockFitsPlayer(player)) { - sendMessage(player, Language.NOT_ENOUGH_SPACE_IN_INVENTORY); - return; + return NOT_ENOUGH_SPACE_IN_INVENTORY; } - String materialName = uSign.capitalizeFirstLetter(stock.getType().name()); + if (!shopHasEnoughItems()) { + int possiblePartialItemCount = getStockAmount(stock); - if (!hasEnoughStock()) { - int items = stockAmount(stock, durability); - if (!Config.getBoolean(Property.ALLOW_PARTIAL_TRANSACTIONS) || items < 1) { - sendMessage(player, Language.NOT_ENOUGH_STOCK); - - if (!Config.getBoolean(Property.SHOW_MESSAGE_OUT_OF_STOCK)) { - return; + if (!partialTransactionAllowed(possiblePartialItemCount)) { + if (Config.getBoolean(SHOW_MESSAGE_OUT_OF_STOCK)) { + sendMessageToOwner(Config.getLocal(NOT_ENOUGH_STOCK_IN_YOUR_SHOP).replace("%material", itemName)); } - sendMessageToOwner(Config.getLocal(Language.NOT_ENOUGH_STOCK_IN_YOUR_SHOP).replace("%material", materialName)); - return; + return NOT_ENOUGH_STOCK; } else { - buyPrice = (buyPrice / stockAmount) * items; - stockAmount = items; + price = (price / stockAmount) * possiblePartialItemCount; + stockAmount = possiblePartialItemCount; } } - Economy.add(getOwnerAccount(), buyPrice); - Economy.subtract(playerName, buyPrice); + Economy.add(getOwnerAccount(), price); + Economy.subtract(playerName, price); - chest.removeItem(stock, durability, stockAmount); - - - String formatedPrice = Economy.formatBalance(buyPrice); - if (Config.getBoolean(Property.SHOW_TRANSACTION_INFORMATION_CLIENT)) { - String message = formatMessage(Language.YOU_BOUGHT_FROM_SHOP, materialName, formatedPrice); - message = message.replace("%owner", owner); - - player.sendMessage(message); - } - - uInventory.add(player.getInventory(), stock, stockAmount); - Logging.logTransaction(true, this, buyPrice, player); - player.updateInventory(); - - if (Config.getBoolean(Property.SHOW_TRANSACTION_INFORMATION_OWNER)) { - String message = formatMessage(Language.SOMEBODY_BOUGHT_FROM_YOUR_SHOP, materialName, formatedPrice); - message = message.replace("%buyer", player.getName()); - - sendMessageToOwner(message); - } - - if (shopShouldBeRemoved()) { - removeShop(); - } - } - - public void sellItemTo(Player player) { - double sellPrice = uSign.sellPrice(sign.getLine(2)); - - if (chest == null) { - sendMessage(player, Language.NO_CHEST_DETECTED); - return; - } - if (Double.compare(sellPrice, 0.01D) < 0) { - sendMessage(player, Language.NO_SELLING_HERE); - return; - } - if (!Permission.has(player, Permission.SELL) && !Permission.has(player, Permission.SELL_ID + Integer.toString(stock.getTypeId()))) { - sendMessage(player, Language.NO_PERMISSION); - return; - } - - String account = getOwnerAccount(); - - if (!Economy.hasEnough(account, sellPrice)) { - int items = calculateItemAmount(Economy.balance(account), sellPrice); - if (!Config.getBoolean(Property.ALLOW_PARTIAL_TRANSACTIONS) || items < 1) { - sendMessage(player, Language.NOT_ENOUGH_MONEY_SHOP); - return; - } else { - sellPrice = (sellPrice / stockAmount) * items; - stockAmount = items; - } - } - if (uInventory.amount(player.getInventory(), stock, durability) < stockAmount) { - int items = uInventory.amount(player.getInventory(), stock, durability); - if (!Config.getBoolean(Property.ALLOW_PARTIAL_TRANSACTIONS) || items < 1) { - sendMessage(player, Language.NOT_ENOUGH_ITEMS_TO_SELL); - return; - } else { - sellPrice = (sellPrice / stockAmount) * items; - stockAmount = items; - } - } - - if (!stockFitsChest(chest)) { - sendMessage(player, Language.NOT_ENOUGH_SPACE_IN_CHEST); - return; - } - - Economy.subtract(account, sellPrice); - Economy.add(player.getName(), sellPrice); - - chest.addItem(stock, stockAmount); - - String materialName = uSign.capitalizeFirstLetter(stock.getType().name()); - String formatedBalance = Economy.formatBalance(sellPrice); - - if (Config.getBoolean(Property.SHOW_TRANSACTION_INFORMATION_CLIENT)) { - String message = formatMessage(Language.YOU_SOLD_TO_SHOP, materialName, formatedBalance); - message = message.replace("%buyer", owner); - - player.sendMessage(message); - } - - uInventory.remove(player.getInventory(), stock, stockAmount, durability); - - Logging.logTransaction(false, this, sellPrice, player); + container.removeItem(stock); + InventoryUtil.add(stock, player.getInventory()); player.updateInventory(); - if (Config.getBoolean(Property.SHOW_TRANSACTION_INFORMATION_OWNER)) { - String message = formatMessage(Language.SOMEBODY_SOLD_TO_YOUR_SHOP, materialName, formatedBalance); - message = message.replace("%seller", player.getName()); + TransactionEvent event = new TransactionEvent(BUY, container, sign, player, this.owner, stock, stockAmount, price); + ChestShop.callEvent(event); - sendMessageToOwner(message); + return null; + } + + private Language sell(Player player) { + double price = getSellPrice(sign.getLine(PRICE_LINE)); + + if (container == null) { + return NO_CHEST_DETECTED; + } + if (price == PriceUtil.NO_PRICE) { + return NO_SELLING_HERE; + } + if (!hasPermission(player, stock.getType(), false)) { + return NO_PERMISSION; } - } - private boolean shopShouldBeRemoved() { - return Config.getBoolean(Property.REMOVE_EMPTY_SHOPS) && shopIsEmpty(); - } + String ownerAccount = getOwnerAccount(); - private boolean shopIsEmpty() { - return chest.isEmpty(); - } + if (!Economy.hasEnough(ownerAccount, price)) { + int possiblePartialItemCount = calculateItemAmount(Economy.balance(ownerAccount), price); - private void removeShop() { - sign.getBlock().setType(Material.AIR); + if (!partialTransactionAllowed(possiblePartialItemCount)) { + return NOT_ENOUGH_MONEY_SHOP; + } else { + price = (price / stockAmount) * possiblePartialItemCount; + stockAmount = possiblePartialItemCount; + } + } - chest.addItem(new ItemStack(Material.SIGN, 1), 1); - } + if (!playerHasEnoughItems(player)) { + int possiblePartialItemCount = InventoryUtil.getAmount(stock, player.getInventory()); - private String formatMessage(Language message, String materialName, String price) { - return Config.getLocal(message) - .replace("%amount", String.valueOf(stockAmount)) - .replace("%item", materialName) - .replace("%price", price); + if (!partialTransactionAllowed(possiblePartialItemCount)) { + return NOT_ENOUGH_ITEMS_TO_SELL; + } else { + price = (price / stockAmount) * possiblePartialItemCount; + stockAmount = possiblePartialItemCount; + } + } + + if (!stockFitsChest()) { + return NOT_ENOUGH_SPACE_IN_CHEST; + } + + Economy.subtract(ownerAccount, price); + Economy.add(player.getName(), price); + + container.addItem(stock); + + InventoryUtil.remove(stock, player.getInventory()); + player.updateInventory(); + + TransactionEvent event = new TransactionEvent(SELL, container, sign, player, this.owner, stock, stockAmount, price); + ChestShop.callEvent(event); + + return null; } private String getOwnerAccount() { @@ -217,23 +187,27 @@ public class Shop { } private boolean isAdminShop() { - return uSign.isAdminShop(owner); - } - - private boolean hasEnoughStock() { - return chest.hasEnough(stock, stockAmount, durability); - } - - private int stockAmount(ItemStack item, short durability) { - return chest.amount(item, durability); + return ChestShopSign.isAdminShop(owner); } private boolean stockFitsPlayer(Player player) { - return uInventory.fits(player.getInventory(), stock, stockAmount, durability) <= 0; + return InventoryUtil.fits(stock, player.getInventory()); } - private boolean stockFitsChest(Container chest) { - return chest.fits(stock, stockAmount, durability); + private boolean stockFitsChest() { + return container.fits(stock); + } + + private int getStockAmount(ItemStack item) { + return container.amount(item); + } + + private boolean shopHasEnoughItems() { + return container.hasEnough(stock); + } + + private boolean playerHasEnoughItems(Player player) { + return InventoryUtil.getAmount(stock, player.getInventory()) >= stockAmount; } private int calculateItemAmount(double money, double basePrice) { @@ -241,15 +215,46 @@ public class Shop { } private static void sendMessage(Player player, Language message) { - player.sendMessage(Config.getLocal(message)); + if (message != null) { + player.sendMessage(Config.getLocal(message)); + } } private void sendMessageToOwner(String msg) { - if (!isAdminShop()) { - Player player = ChestShop.getBukkitServer().getPlayer(owner); - if (player != null) { - player.sendMessage(msg); - } + Player player = ChestShop.getBukkitServer().getPlayer(owner); + + if (player != null) { + player.sendMessage(msg); + } + } + + public static Shop getShopFromSign(Sign sign) { + Chest chestMc = uBlock.findConnectedChest(sign); + ItemStack item = MaterialUtil.getItem(sign.getLine(ITEM_LINE)); + + if (item == null) { + return null; + } + + int itemAmount = Integer.parseInt(sign.getLine(QUANTITY_LINE)); + item.setAmount(itemAmount); + + if (ChestShopSign.isAdminShop(sign)) { + return new Shop(new AdminChest(), item, sign); + } else { + return new Shop(chestMc != null ? new ShopChest(chestMc) : null, item, sign); + } + } + + private static boolean partialTransactionAllowed(int itemCount) { + return Config.getBoolean(ALLOW_PARTIAL_TRANSACTIONS) && itemCount > 0; + } + + private static boolean hasPermission(Player player, Material material, boolean buying) { + if (buying) { + return Permission.has(player, Permission.BUY) || Permission.has(player, Permission.BUY_ID + Integer.toString(material.getId())); + } else { + return Permission.has(player, Permission.SELL) || Permission.has(player, Permission.SELL_ID + Integer.toString(material.getId())); } } } diff --git a/com/Acrobot/ChestShop/Shop/ShopManagement.java b/com/Acrobot/ChestShop/Shop/ShopManagement.java deleted file mode 100644 index cd274fe..0000000 --- a/com/Acrobot/ChestShop/Shop/ShopManagement.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.Acrobot.ChestShop.Shop; - -import com.Acrobot.ChestShop.Containers.AdminChest; -import com.Acrobot.ChestShop.Containers.MinecraftChest; -import com.Acrobot.ChestShop.Items.Items; -import com.Acrobot.ChestShop.Utils.uBlock; -import com.Acrobot.ChestShop.Utils.uSign; -import org.bukkit.ChatColor; -import org.bukkit.block.Chest; -import org.bukkit.block.Sign; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; - -/** - * @author Acrobot - */ -public class ShopManagement { - - public static void buy(Sign sign, Player player) { - Shop shop = getShop(sign, player); - if (shop != null) { - shop.buyItemFrom(player); - } - } - - public static void sell(Sign sign, Player player) { - Shop shop = getShop(sign, player); - if (shop != null) { - shop.sellItemTo(player); - } - } - - public static Shop getShop(Sign sign, Player player) { - Chest chestMc = uBlock.findConnectedChest(sign); - ItemStack item = Items.getItemStack(sign.getLine(3)); - - if (item == null) { - player.sendMessage(ChatColor.RED + "[Shop] The item is not recognised!"); - return null; - } - - if (uSign.isAdminShop(sign.getLine(0))) { - return new Shop(new AdminChest(), sign, item); - } else { - return new Shop(chestMc != null ? new MinecraftChest(chestMc) : null, sign, item); - } - } -} diff --git a/com/Acrobot/ChestShop/Signs/ChestShopSign.java b/com/Acrobot/ChestShop/Signs/ChestShopSign.java new file mode 100644 index 0000000..436fa10 --- /dev/null +++ b/com/Acrobot/ChestShop/Signs/ChestShopSign.java @@ -0,0 +1,65 @@ +package com.Acrobot.ChestShop.Signs; + +import com.Acrobot.Breeze.Utils.BlockUtil; +import com.Acrobot.ChestShop.Config.Config; +import com.Acrobot.ChestShop.Utils.uName; +import org.bukkit.block.Block; +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; + +import java.util.regex.Pattern; + +import static com.Acrobot.ChestShop.Config.Property.ADMIN_SHOP_NAME; + +/** + * @author Acrobot + */ +public class ChestShopSign { + public static final byte NAME_LINE = 0; + public static final byte QUANTITY_LINE = 1; + public static final byte PRICE_LINE = 2; + public static final byte ITEM_LINE = 3; + + public static final Pattern[] SHOP_SIGN_PATTERN = { + Pattern.compile("^$|^\\w.+$"), + Pattern.compile("[0-9]+"), + Pattern.compile(".+"), + Pattern.compile("[\\w : -]+") + }; + + public static boolean isAdminShop(String owner) { + return owner.toLowerCase().replace(" ", "").equals(Config.getString(ADMIN_SHOP_NAME).toLowerCase().replace(" ", "")); + } + + public static boolean isAdminShop(Sign sign) { + return isAdminShop(sign.getLine(NAME_LINE)); + } + + public static boolean isValid(Sign sign) { + return isValid(sign.getLines()); + } + + public static boolean isValid(String[] line) { + return isValidPreparedSign(line) && (line[2].contains("B") || line[2].contains("S")) && !line[0].isEmpty(); + } + + public static boolean isValid(Block sign) { + return BlockUtil.isSign(sign) && isValid((Sign) sign.getState()); + } + + public static boolean canAccess(Player player, Sign sign) { + if (player == null) return false; + if (sign == null) return true; + + return uName.canUseName(player, sign.getLine(0)); + } + + public static boolean isValidPreparedSign(String[] lines) { + for (int i = 0; i < 4; i++) { + if (!SHOP_SIGN_PATTERN[i].matcher(lines[i]).matches()) { + return false; + } + } + return lines[2].indexOf(':') == lines[2].lastIndexOf(':'); + } +} diff --git a/com/Acrobot/ChestShop/Signs/restrictedSign.java b/com/Acrobot/ChestShop/Signs/restrictedSign.java index 068f0a0..78aec54 100644 --- a/com/Acrobot/ChestShop/Signs/restrictedSign.java +++ b/com/Acrobot/ChestShop/Signs/restrictedSign.java @@ -1,19 +1,50 @@ package com.Acrobot.ChestShop.Signs; +import com.Acrobot.Breeze.Utils.BlockUtil; +import com.Acrobot.ChestShop.Config.Config; +import com.Acrobot.ChestShop.Config.Language; import com.Acrobot.ChestShop.Permission; -import com.Acrobot.ChestShop.Utils.uSign; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.Sign; import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.SignChangeEvent; /** * @author Acrobot */ -public class restrictedSign { +public class RestrictedSign implements Listener { + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public static void onSignChange(SignChangeEvent event) { + String[] lines = event.getLines(); + Player player = event.getPlayer(); + + if (isRestricted(lines)) { + if (!hasPermission(player, lines)) { + player.sendMessage(Config.getLocal(Language.ACCESS_DENIED)); + dropSignAndCancelEvent(event); + return; + } + Block connectedSign = event.getBlock().getRelative(BlockFace.DOWN); + + if (!Permission.has(player, Permission.ADMIN) || !BlockUtil.isSign(connectedSign) || !ChestShopSign.isValid(connectedSign)) { + dropSignAndCancelEvent(event); + return; + } + + Sign sign = (Sign) connectedSign.getState(); + + if (!ChestShopSign.isValid(sign) || !ChestShopSign.canAccess(player, sign)) { + dropSignAndCancelEvent(event); + } + } + } public static boolean isRestrictedShop(Sign sign) { Block blockUp = sign.getBlock().getRelative(BlockFace.UP); - return uSign.isSign(blockUp) && isRestricted(((Sign) blockUp.getState()).getLines()); + return BlockUtil.isSign(blockUp) && isRestricted(((Sign) blockUp.getState()).getLines()); } public static boolean isRestricted(String[] lines) { @@ -26,18 +57,18 @@ public class restrictedSign { public static boolean canAccess(Sign sign, Player player) { Block blockUp = sign.getBlock().getRelative(BlockFace.UP); - return !uSign.isSign(blockUp) || hasPermission(player, ((Sign) blockUp.getState()).getLines()); + return !BlockUtil.isSign(blockUp) || hasPermission(player, ((Sign) blockUp.getState()).getLines()); } public static boolean canDestroy(Player p, Sign sign) { Sign shopSign = getAssociatedSign(sign); - return uSign.canAccess(p, shopSign); + return ChestShopSign.canAccess(p, shopSign); } public static Sign getAssociatedSign(Sign restricted) { Block down = restricted.getBlock().getRelative(BlockFace.DOWN); - return uSign.isSign(down) ? (Sign) down.getState() : null; + return BlockUtil.isSign(down) ? (Sign) down.getState() : null; } public static boolean hasPermission(Player p, String[] lines) { @@ -52,4 +83,9 @@ public class restrictedSign { } return false; } + + private static void dropSignAndCancelEvent(SignChangeEvent event) { + event.getBlock().breakNaturally(); + event.setCancelled(true); + } } diff --git a/com/Acrobot/ChestShop/Utils/uBlock.java b/com/Acrobot/ChestShop/Utils/uBlock.java index 48b30e1..af4fc0c 100644 --- a/com/Acrobot/ChestShop/Utils/uBlock.java +++ b/com/Acrobot/ChestShop/Utils/uBlock.java @@ -1,6 +1,8 @@ package com.Acrobot.ChestShop.Utils; -import com.Acrobot.ChestShop.Signs.restrictedSign; +import com.Acrobot.Breeze.Utils.BlockUtil; +import com.Acrobot.ChestShop.Signs.ChestShopSign; +import com.Acrobot.ChestShop.Signs.RestrictedSign; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; @@ -12,8 +14,8 @@ import org.bukkit.material.Attachable; * @author Acrobot */ public class uBlock { - private static final BlockFace[] chestFaces = {BlockFace.EAST, BlockFace.NORTH, BlockFace.WEST, BlockFace.SOUTH}; - private static final BlockFace[] shopFaces = {BlockFace.SELF, BlockFace.DOWN, BlockFace.UP, BlockFace.EAST, BlockFace.NORTH, BlockFace.WEST, BlockFace.SOUTH}; + private static final BlockFace[] CHEST_EXTENSION_FACES = {BlockFace.EAST, BlockFace.NORTH, BlockFace.WEST, BlockFace.SOUTH}; + private static final BlockFace[] SHOP_FACES = {BlockFace.SELF, BlockFace.DOWN, BlockFace.UP, BlockFace.EAST, BlockFace.NORTH, BlockFace.WEST, BlockFace.SOUTH}; public static Chest findConnectedChest(Sign sign) { Block block = sign.getBlock(); @@ -21,7 +23,7 @@ public class uBlock { } public static Chest findConnectedChest(Block block) { - for (BlockFace bf : shopFaces) { + for (BlockFace bf : SHOP_FACES) { Block faceBlock = block.getRelative(bf); if (faceBlock.getType() == Material.CHEST) { return (Chest) faceBlock.getState(); @@ -33,16 +35,16 @@ public class uBlock { public static Sign findValidShopSign(Block block, String originalName) { Sign ownerShopSign = null; - for (BlockFace bf : shopFaces) { + for (BlockFace bf : SHOP_FACES) { Block faceBlock = block.getRelative(bf); - if (!uSign.isSign(faceBlock)) { + if (!BlockUtil.isSign(faceBlock)) { continue; } Sign sign = (Sign) faceBlock.getState(); - if (uSign.isValid(sign) && signIsAttachedToBlock(sign, block)) { + if (ChestShopSign.isValid(sign) && signIsAttachedToBlock(sign, block)) { if (!sign.getLine(0).equals(originalName)) { return sign; } else if (ownerShopSign == null) { @@ -55,16 +57,16 @@ public class uBlock { } public static Sign findAnyNearbyShopSign(Block block) { - for (BlockFace bf : shopFaces) { + for (BlockFace bf : SHOP_FACES) { Block faceBlock = block.getRelative(bf); - if (!uSign.isSign(faceBlock)) { + if (!BlockUtil.isSign(faceBlock)) { continue; } Sign sign = (Sign) faceBlock.getState(); - if (uSign.isValid(sign)) { + if (ChestShopSign.isValid(sign)) { return sign; } } @@ -72,16 +74,16 @@ public class uBlock { } public static Sign findRestrictedSign(Block block) { - for (BlockFace bf : shopFaces) { + for (BlockFace bf : SHOP_FACES) { Block faceBlock = block.getRelative(bf); - if (!uSign.isSign(faceBlock)) { + if (!BlockUtil.isSign(faceBlock)) { continue; } Sign sign = (Sign) faceBlock.getState(); - if (restrictedSign.isRestricted(sign) && signIsAttachedToBlock(sign, block)) { + if (RestrictedSign.isRestricted(sign) && signIsAttachedToBlock(sign, block)) { return sign; } } @@ -89,7 +91,7 @@ public class uBlock { } public static Chest findNeighbor(Block block) { - for (BlockFace blockFace : chestFaces) { + for (BlockFace blockFace : CHEST_EXTENSION_FACES) { Block neighborBlock = block.getRelative(blockFace); if (neighborBlock.getType() == Material.CHEST) { return (Chest) neighborBlock.getState(); diff --git a/com/Acrobot/ChestShop/Utils/uEnchantment.java b/com/Acrobot/ChestShop/Utils/uEnchantment.java deleted file mode 100644 index 2a739cb..0000000 --- a/com/Acrobot/ChestShop/Utils/uEnchantment.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.Acrobot.ChestShop.Utils; - -import org.bukkit.enchantments.Enchantment; -import org.bukkit.inventory.ItemStack; - -import java.util.HashMap; -import java.util.Map; - -/** - * @author Acrobot - */ -public class uEnchantment { - public static String getEnchantment(ItemStack item) { - return encodeEnchantment(item.getEnchantments()); - } - - public static String encodeEnchantment(Map map) { - int integer = 0; - for (Map.Entry enchantment : map.entrySet()) { - integer = integer * 1000 + (enchantment.getKey().getId()) * 10 + enchantment.getValue(); - } - - if (integer == 0) return null; - - return Integer.toString(integer, 32); - } - - public static Map decodeEnchantment(String base32) { - Map map = new HashMap(); - - if (base32 == null) { - return map; - } - - StringBuilder integer = new StringBuilder(String.valueOf(Integer.parseInt(base32, 32))); - - while (integer.length() % 3 != 0) { - integer.insert(0, '0'); - } - - String enchantment = integer.toString(); - - for (int i = 0; i < enchantment.length() / 3; i++) { - String item = enchantment.substring(i * 3, i * 3 + 3); - - Enchantment ench = Enchantment.getById(Integer.parseInt(item.substring(0, 2))); - - if (ench == null) continue; - int level = Integer.parseInt(item.substring(2)); - if (ench.getMaxLevel() < level || level < ench.getStartLevel()) continue; - map.put(ench, level); - } - - return map; - } -} diff --git a/com/Acrobot/ChestShop/Utils/uInventory.java b/com/Acrobot/ChestShop/Utils/uInventory.java deleted file mode 100644 index d343954..0000000 --- a/com/Acrobot/ChestShop/Utils/uInventory.java +++ /dev/null @@ -1,144 +0,0 @@ -package com.Acrobot.ChestShop.Utils; - -import com.Acrobot.ChestShop.Config.Config; -import com.Acrobot.ChestShop.Config.Property; -import org.bukkit.Material; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; - -import java.util.HashMap; - -/** - * @author Acrobot - */ -public class uInventory { - - public static int remove(Inventory inv, ItemStack item, int amount, short durability) { - amount = (amount > 0 ? amount : 1); - Material itemMaterial = item.getType(); - - int first = inv.first(itemMaterial); - if (first == -1) return amount; - - for (int slot = first; slot < inv.getSize(); slot++) { - if (amount <= 0) return 0; - - ItemStack currentItem = inv.getItem(slot); - if (currentItem == null || currentItem.getType() == Material.AIR) continue; - - if (equals(currentItem, item, durability)) { - int currentAmount = currentItem.getAmount(); - if (amount == currentAmount) { - currentItem = null; - amount = 0; - } else if (amount < currentAmount) { - currentItem.setAmount(currentAmount - amount); - amount = 0; - } else { - currentItem = null; - amount -= currentAmount; - } - inv.setItem(slot, currentItem); - } - } - return amount; - } - - public static int add(Inventory inv, ItemStack item, int amount) { - amount = (amount > 0 ? amount : 1); - if (Config.getBoolean(Property.STACK_UNSTACKABLES)) return addAndStackTo64(inv, item, amount); - ItemStack itemstack = new ItemStack(item.getType(), amount, item.getDurability()); - itemstack.addEnchantments(item.getEnchantments()); - - HashMap items = inv.addItem(itemstack); - amount = 0; - - for (ItemStack toAdd : items.values()) { - amount += toAdd.getAmount(); - } - - return amount; - } - - public static int addAndStackTo64(Inventory inv, ItemStack item, int amount) { - return addManually(inv, item, amount, 64); - } - - public static int addManually(Inventory inv, ItemStack item, int amount, int max) { - if (amount <= 0) return 0; - - for (int slot = 0; slot < inv.getSize() && amount > 0; slot++) { - ItemStack curItem = inv.getItem(slot); - ItemStack dupe = item.clone(); - - if (curItem == null || curItem.getType() == Material.AIR) { - dupe.setAmount((amount > max ? max : amount)); - dupe.addEnchantments(item.getEnchantments()); - amount -= dupe.getAmount(); - inv.setItem(slot, dupe); - } else if (equals(item, curItem, curItem.getDurability()) && curItem.getAmount() != max) { - int cA = curItem.getAmount(); - int amountAdded = amount > max - cA ? max - cA : amount; - dupe.setAmount(cA + amountAdded); - amount -= amountAdded; - dupe.addEnchantments(item.getEnchantments()); - inv.setItem(slot, dupe); - } - } - - return amount; - } - - public static int amount(Inventory inv, ItemStack item, short durability) { - if (!inv.contains(item.getType())) { - return 0; - } - - HashMap items = inv.all(item.getType()); - - int amount = 0; - - for (ItemStack i : items.values()) { - if (!equals(i, item, durability)) { - continue; - } - - amount += i.getAmount(); - } - return amount; - } - - public static int fits(Inventory inv, ItemStack item, int amount, short durability) { - int maxStackSize = (Config.getBoolean(Property.STACK_UNSTACKABLES) ? 64 : item.getType().getMaxStackSize()); - - int amountLeft = amount; - - for (ItemStack currentItem : inv.getContents()) { - if (amountLeft <= 0) { - return 0; - } - - if (currentItem == null || currentItem.getType() == Material.AIR) { - amountLeft -= maxStackSize; - continue; - } - - int currentAmount = currentItem.getAmount(); - - if (currentAmount == maxStackSize || !equals(currentItem, item, durability)) { - continue; - } - - amountLeft = currentAmount + amountLeft <= maxStackSize ? 0 : amountLeft - (maxStackSize - currentAmount); - } - - return amountLeft; - } - - private static boolean equals(ItemStack i, ItemStack item, short durability) { - return i != null - && i.getType() == item.getType() - && i.getEnchantments().equals(item.getEnchantments()) - && (durability == -1 || i.getDurability() == durability); - } -} diff --git a/com/Acrobot/ChestShop/Utils/uNumber.java b/com/Acrobot/ChestShop/Utils/uNumber.java deleted file mode 100644 index d0344d5..0000000 --- a/com/Acrobot/ChestShop/Utils/uNumber.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.Acrobot.ChestShop.Utils; - -/** - * Checks if string is a numerical value - * - * @author Acrobot - */ -public class uNumber { - public static boolean isInteger(String string) { - try { - Integer.parseInt(string); - return true; - } catch (NumberFormatException e) { - return false; - } - } - - public static boolean isFloat(String string) { - try { - Float.parseFloat(string); - return true; - } catch (NumberFormatException e) { - return false; - } - } - - public static boolean isDouble(String string) { - try { - Double.parseDouble(string); - return true; - } catch (NumberFormatException e) { - return false; - } - } - - public static boolean isShort(String string) { - try { - Short.parseShort(string); - return true; - } catch (NumberFormatException e) { - return false; - } - } -} diff --git a/com/Acrobot/ChestShop/Utils/uSign.java b/com/Acrobot/ChestShop/Utils/uSign.java deleted file mode 100644 index 9e39f97..0000000 --- a/com/Acrobot/ChestShop/Utils/uSign.java +++ /dev/null @@ -1,109 +0,0 @@ -package com.Acrobot.ChestShop.Utils; - -import com.Acrobot.ChestShop.Config.Config; -import com.Acrobot.ChestShop.Config.Property; -import org.bukkit.block.Block; -import org.bukkit.block.Sign; -import org.bukkit.entity.Player; - -import java.util.regex.Pattern; - -/** - * @author Acrobot - */ -public class uSign { - private static final Pattern[] signPattern = { - Pattern.compile("^$|^\\w.+$"), - Pattern.compile("[0-9]+"), - Pattern.compile(".+"), - Pattern.compile("[\\w : -]+") - }; - - public static boolean isSign(Block block) { - return block.getState() instanceof Sign; - } - - public static boolean isAdminShop(String owner) { - return owner.toLowerCase().replace(" ", "").equals(Config.getString(Property.ADMIN_SHOP_NAME).toLowerCase().replace(" ", "")); - } - - public static boolean isValid(Sign sign) { - return isValid(sign.getLines()); - } - - public static boolean isValid(String[] line) { - return isValidPreparedSign(line) && (line[2].contains("B") || line[2].contains("S")) && !line[0].isEmpty(); - } - - public static boolean isValid(Block sign) { - return isSign(sign) && isValid((Sign) sign.getState()); - } - - public static boolean canAccess(Player player, Sign sign) { - if (player == null) return false; - if (sign == null) return true; - - return uName.canUseName(player, sign.getLine(0)); - } - - public static boolean isValidPreparedSign(String[] lines) { - for (int i = 0; i < 4; i++) { - if (!signPattern[i].matcher(lines[i]).matches()) { - return false; - } - } - return lines[2].indexOf(':') == lines[2].lastIndexOf(':'); - } - - public static double buyPrice(String text) { - return getPrice(text, 'b'); - } - - public static double sellPrice(String text) { - return getPrice(text, 's'); - } - - private static double getPrice(String text, char indicator) { - String sign = String.valueOf(indicator); - - text = text.replace(" ", "").toLowerCase(); - - String[] split = text.split(":"); - int part = (text.contains(sign) ? (split[0].contains(sign) ? 0 : 1) : -1); - if (part == -1 || (part == 1 && split.length != 2)) return -1; - - split[part] = split[part].replace(sign, ""); - - if (uNumber.isDouble(split[part])) { - double price = Double.parseDouble(split[part]); - return (price > 0 ? price : -1); - } else if (split[part].equals("free")) { - return 0; - } - - return -1; - } - - public static int itemAmount(String text) { - if (uNumber.isInteger(text)) { - int amount = Integer.parseInt(text); - return (amount >= 1 ? amount : 1); - } else return 1; - } - - public static String capitalizeFirstLetter(String name) { - return capitalizeFirstLetter(name, '_'); - } - - public static String capitalizeFirstLetter(String name, char separator) { - name = name.toLowerCase(); - String[] split = name.split(Character.toString(separator)); - StringBuilder total = new StringBuilder(3); - - for (String s : split) { - total.append(Character.toUpperCase(s.charAt(0))).append(s.substring(1)).append(' '); - } - - return total.toString().trim(); - } -} diff --git a/com/lennardf1989/bukkitex/Database.java b/com/lennardf1989/bukkitex/Database.java index 7656601..9f13c11 100644 --- a/com/lennardf1989/bukkitex/Database.java +++ b/com/lennardf1989/bukkitex/Database.java @@ -313,7 +313,9 @@ public abstract class Database { //Turn all the lines back into a single string StringBuilder newScript = new StringBuilder(5); - for (String newLine : scriptLines) newScript.append(newLine).append('\n'); + for (String newLine : scriptLines) { + newScript.append(newLine).append('\n'); + } //Print the new script System.out.println(newScript); diff --git a/com/nijikokun/register/payment/forChestShop/Method.java b/com/nijikokun/register/payment/forChestShop/Method.java index 16abe93..daa377d 100644 --- a/com/nijikokun/register/payment/forChestShop/Method.java +++ b/com/nijikokun/register/payment/forChestShop/Method.java @@ -23,21 +23,21 @@ public interface Method { * @see #getName() * @see #getVersion() */ - public Object getPlugin(); + Object getPlugin(); /** * Returns the actual name of this method. * * @return String Plugin name. */ - public String getName(); + String getName(); /** * Returns the actual version of this method. * * @return String Plugin version. */ - public String getVersion(); + String getVersion(); /** * Returns the amount of decimal places that get stored @@ -45,7 +45,7 @@ public interface Method { * * @return int for each decimal place */ - public int fractionalDigits(); + int fractionalDigits(); /** * Formats amounts into this payment methods style of currency display. @@ -53,14 +53,14 @@ public interface Method { * @param amount Double * @return String - Formatted Currency Display. */ - public String format(double amount); + String format(double amount); /** * Allows the verification of bank API existence in this payment method. * * @return boolean */ - public boolean hasBanks(); + boolean hasBanks(); /** * Determines the existence of a bank via name. @@ -69,7 +69,7 @@ public interface Method { * @return boolean * @see #hasBanks */ - public boolean hasBank(String bank); + boolean hasBank(String bank); /** * Determines the existence of an account via name. @@ -77,7 +77,7 @@ public interface Method { * @param name Account name * @return boolean */ - public boolean hasAccount(String name); + boolean hasAccount(String name); /** * Check to see if an account name is tied to a bank. @@ -86,7 +86,7 @@ public interface Method { * @param name Account name * @return boolean */ - public boolean hasBankAccount(String bank, String name); + boolean hasBankAccount(String bank, String name); /** * Forces an account creation @@ -94,7 +94,7 @@ public interface Method { * @param name Account name * @return boolean */ - public boolean createAccount(String name); + boolean createAccount(String name); /** * Forces an account creation @@ -103,7 +103,7 @@ public interface Method { * @param balance Initial account balance * @return boolean */ - public boolean createAccount(String name, double balance); + boolean createAccount(String name, double balance); /** * Returns a MethodAccount class for an account name. @@ -111,7 +111,7 @@ public interface Method { * @param name Account name * @return MethodAccount or Null */ - public MethodAccount getAccount(String name); + MethodAccount getAccount(String name); /** @@ -121,7 +121,7 @@ public interface Method { * @param name Account name * @return MethodBankAccount or Null */ - public MethodBankAccount getBankAccount(String bank, String name); + MethodBankAccount getBankAccount(String bank, String name); /** * Checks to verify the compatibility between this Method and a plugin. @@ -130,76 +130,48 @@ public interface Method { * @param plugin Plugin * @return boolean */ - public boolean isCompatible(Plugin plugin); + boolean isCompatible(Plugin plugin); /** * Set Plugin data. * * @param plugin Plugin */ - public void setPlugin(Plugin plugin); + void setPlugin(Plugin plugin); /** * Contains Calculator and Balance functions for Accounts. */ - public interface MethodAccount { - public double balance(); + interface MethodAccount { + double balance(); - public boolean set(double amount); + boolean set(double amount); - public boolean add(double amount); + boolean add(double amount); - public boolean subtract(double amount); + boolean subtract(double amount); - public boolean multiply(double amount); + boolean multiply(double amount); - public boolean divide(double amount); + boolean divide(double amount); - public boolean hasEnough(double amount); + boolean hasEnough(double amount); - public boolean hasOver(double amount); + boolean hasOver(double amount); - public boolean hasUnder(double amount); + boolean hasUnder(double amount); - public boolean isNegative(); + boolean isNegative(); - public boolean remove(); - - @Override - public String toString(); + boolean remove(); } /** * Contains Calculator and Balance functions for Bank Accounts. */ - public interface MethodBankAccount { - public double balance(); + interface MethodBankAccount extends MethodAccount { + String getBankName(); - public String getBankName(); - - public int getBankId(); - - public boolean set(double amount); - - public boolean add(double amount); - - public boolean subtract(double amount); - - public boolean multiply(double amount); - - public boolean divide(double amount); - - public boolean hasEnough(double amount); - - public boolean hasOver(double amount); - - public boolean hasUnder(double amount); - - public boolean isNegative(); - - public boolean remove(); - - @Override - public String toString(); + int getBankId(); } } diff --git a/com/nijikokun/register/payment/forChestShop/Methods.java b/com/nijikokun/register/payment/forChestShop/Methods.java index 336211d..bdc506f 100644 --- a/com/nijikokun/register/payment/forChestShop/Methods.java +++ b/com/nijikokun/register/payment/forChestShop/Methods.java @@ -4,51 +4,51 @@ import com.nijikokun.register.payment.forChestShop.methods.BOSE7; import com.nijikokun.register.payment.forChestShop.methods.EE17; import com.nijikokun.register.payment.forChestShop.methods.iCo5; import com.nijikokun.register.payment.forChestShop.methods.iCo6; +import org.bukkit.Bukkit; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginManager; +import java.util.HashMap; +import java.util.Map; + /** * @author Acrobot */ public class Methods { - private static String preferred; - private static final String[] toLoad = new String[]{ - "iConomy", - "BOSEconomy", - "Essentials", - }; - private static final Method[] methods = new Method[]{ - new iCo5(), - new iCo6(), - new BOSE7(), - new EE17() - }; + private static final Map PLUGINS_TO_LOAD = new HashMap() {{ + put(new iCo5(), "iConomy"); + put(new iCo6(), "iConomy"); + put(new BOSE7(), "BOSEconomy"); + put(new EE17(), "Essentials"); + }}; + private static String preferredPlugin; public static void setPreferred(String plugin) { - preferred = plugin; + preferredPlugin = plugin; } - public static Method load(PluginManager pm) { - if (!preferred.isEmpty()) { - Plugin plugin = pm.getPlugin(preferred); - if (plugin != null) { - Method m = createMethod(plugin); - if (m != null) return m; - } + public static Method load() { + PluginManager pluginManager = Bukkit.getPluginManager(); + + Method preferred = getPreferredMethod(); + if (preferred != null) { + return preferred; } - for (String plugin : toLoad) { - Plugin pl = pm.getPlugin(plugin); - if (pl != null) { - Method m = createMethod(pl); - if (m != null) return m; + for (String pluginName : PLUGINS_TO_LOAD.values()) { + Plugin plugin = pluginManager.getPlugin(pluginName); + if (plugin != null) { + Method method = createMethod(plugin); + if (method != null) { + return method; + } } } return null; } - public static Method createMethod(Plugin plugin) { - for (Method method : methods) { + private static Method createMethod(Plugin plugin) { + for (Method method : PLUGINS_TO_LOAD.keySet()) { if (method.isCompatible(plugin)) { method.setPlugin(plugin); return method; @@ -56,4 +56,18 @@ public class Methods { } return null; } + + private static Method getPreferredMethod() { + if (preferredPlugin.isEmpty()) { + return null; + } + + Plugin plugin = Bukkit.getPluginManager().getPlugin(preferredPlugin); + + if (plugin == null) { + return null; + } + + return createMethod(plugin); + } } diff --git a/plugin.yml b/plugin.yml index 499e9e4..4eef901 100644 --- a/plugin.yml +++ b/plugin.yml @@ -2,7 +2,7 @@ name: ChestShop main: com.Acrobot.ChestShop.ChestShop -version: 3.41 +version: 3.43 TEST BUILD #for CButD dev-url: http://dev.bukkit.org/server-mods/chestshop/