diff --git a/ShopChest/src/main/java/de/epiceric/shopchest/ShopChest.java b/ShopChest/src/main/java/de/epiceric/shopchest/ShopChest.java index b281931..2db6c94 100644 --- a/ShopChest/src/main/java/de/epiceric/shopchest/ShopChest.java +++ b/ShopChest/src/main/java/de/epiceric/shopchest/ShopChest.java @@ -23,15 +23,16 @@ import net.milkbowl.vault.economy.Economy; import net.milkbowl.vault.permission.Permission; import org.bukkit.Bukkit; import org.bukkit.World; +import org.bukkit.entity.Entity; import org.bukkit.entity.Item; import org.bukkit.entity.Player; import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.plugin.java.JavaPlugin; -import org.bukkit.scheduler.BukkitTask; -import java.io.IOException; -import java.io.Reader; +import java.io.*; +import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Calendar; public class ShopChest extends JavaPlugin { @@ -47,6 +48,8 @@ public class ShopChest extends JavaPlugin { private String latestVersion = ""; private String downloadLink = ""; private ShopUtils shopUtils; + private File debugLogFile; + private FileWriter fw; /** * @return An instance of ShopChest @@ -83,19 +86,42 @@ public class ShopChest extends JavaPlugin { public void onEnable() { instance = this; - if (getServer().getPluginManager().getPlugin("Vault") == null) { - getLogger().severe("Could not find plugin 'Vault'!"); + config = new Config(this); + + if (config.enable_debug_log) { + debugLogFile = new File(getDataFolder(), "debug.txt"); + + try { + if (!debugLogFile.exists()) { + debugLogFile.createNewFile(); + } + + new PrintWriter(debugLogFile).close(); + + fw = new FileWriter(debugLogFile, true); + } catch (IOException e) { + e.printStackTrace(); + } + } + + debug("Enabling ShopChest version " + getDescription().getVersion()); + + if (!getServer().getPluginManager().isPluginEnabled("Vault")) { + debug("Could not find plugin \"Vault\""); + getLogger().severe("Could not find plugin \"Vault\""); getServer().getPluginManager().disablePlugin(this); return; } if (!setupEconomy()) { + debug("Could not find any Vault economy dependency!"); getLogger().severe("Could not find any Vault economy dependency!"); getServer().getPluginManager().disablePlugin(this); return; } if (!setupPermissions()) { + debug("Could not find any Vault permission dependency!"); getLogger().severe("Could not find any Vault permission dependency!"); getServer().getPluginManager().disablePlugin(this); return; @@ -110,18 +136,22 @@ public class ShopChest extends JavaPlugin { case "v1_10_R1": break; default: + debug("Incompatible Server Version: " + Utils.getServerVersion()); getLogger().severe("Incompatible Server Version: " + Utils.getServerVersion() + "!"); getServer().getPluginManager().disablePlugin(this); return; } - config = new Config(this); + debug("Loading utils and extras..."); + LanguageUtils.load(); saveResource("item_names.txt", true); shopUtils = new ShopUtils(this); try { + debug("Initializing Metrics..."); + Metrics metrics = new Metrics(this); Graph shopType = metrics.createGraph("Shop Type"); shopType.addPlotter(new Plotter("Normal") { @@ -181,13 +211,16 @@ public class ShopChest extends JavaPlugin { metrics.start(); } catch (IOException e) { + debug("Metrics: Failed to submit stats"); getLogger().severe("Could not submit stats."); } if (config.database_type == Database.DatabaseType.SQLite) { + debug("Using database type: SQLite"); getLogger().info("Using SQLite"); database = new SQLite(this); } else { + debug("Using database type: MySQL"); getLogger().info("Using MySQL"); database = new MySQL(this); } @@ -196,6 +229,8 @@ public class ShopChest extends JavaPlugin { Bukkit.getScheduler().runTaskTimer(this, new Runnable() { @Override public void run() { + debug("Auto reloading shops..."); + ShopReloadEvent event = new ShopReloadEvent(Bukkit.getConsoleSender()); Bukkit.getServer().getPluginManager().callEvent(event); @@ -204,8 +239,8 @@ public class ShopChest extends JavaPlugin { }, config.auto_reload_time * 20, config.auto_reload_time * 20); } - lockette = getServer().getPluginManager().getPlugin("Lockette") != null; - lwc = getServer().getPluginManager().getPlugin("LWC") != null; + lockette = getServer().getPluginManager().isPluginEnabled("Lockette"); + lwc = getServer().getPluginManager().isPluginEnabled("LWC"); Bukkit.getScheduler().runTaskAsynchronously(this, new Runnable() { @Override @@ -264,13 +299,17 @@ public class ShopChest extends JavaPlugin { }); try { - Commands.registerCommand(new Commands(this, config.main_command_name, "Manage Shops.", "", new ArrayList()), this); + debug("Trying to register command \"/" + config.main_command_name + "\""); + ShopCommand.registerCommand(new ShopCommand(this, config.main_command_name, "Manage Shops.", "", new ArrayList()), this); } catch (Exception e) { + debug("Failed to register command"); + debug(e); e.printStackTrace(); } initializeShops(); + debug("Registering listeners..."); getServer().getPluginManager().registerEvents(new HologramUpdateListener(this), this); getServer().getPluginManager().registerEvents(new ItemProtectListener(this), this); getServer().getPluginManager().registerEvents(new ShopInteractListener(this), this); @@ -278,34 +317,107 @@ public class ShopChest extends JavaPlugin { getServer().getPluginManager().registerEvents(new ChestProtectListener(this), this); getServer().getPluginManager().registerEvents(new ItemCustomNameListener(), this); - if (getServer().getPluginManager().getPlugin("ClearLag") != null) + if (getServer().getPluginManager().isPluginEnabled("ClearLag")) getServer().getPluginManager().registerEvents(new ClearLagListener(), this); - if (getServer().getPluginManager().getPlugin("LWC") != null) - new LWCMagnetListener(this).initializeListener(); + if (lwc) new LWCMagnetListener(this).initializeListener(); } @Override public void onDisable() { - for (Shop shop : shopUtils.getShops()) { - shopUtils.removeShop(shop, false); + debug("Disabling ShopChest..."); + + int highestId = database.getHighestID(); + + for (int i = 1; i <= highestId; i++) { + for (Shop shop : shopUtils.getShops()) { + if (shop.getID() == i) { + shopUtils.removeShop(shop, false); + debug("Removed shop (#" + shop.getID() + ")"); + } + } } for (World world : Bukkit.getWorlds()) { - for (Item item : world.getEntitiesByClass(Item.class)) { - if (item.hasMetadata("shopItem")) { - item.remove(); + for (Entity entity : world.getEntities()) { + if (entity instanceof Item) { + Item item = (Item) entity; + if (item.hasMetadata("shopItem")) { + if (item.isValid()) { + debug("Removing not removed shop item (#" + + (item.hasMetadata("shopId") ? item.getMetadata("shopId").get(0).asString() : "?") + ")"); + + item.remove(); + } + } } } } + + if (config.enable_debug_log) { + for (World world : Bukkit.getWorlds()) { + for (Entity entity : world.getEntities()) { + if (entity instanceof Item) { + Item item = (Item) entity; + if (item.hasMetadata("shopItem")) { + if (item.isValid()) { + debug("Shop item still valid (#" + + (item.hasMetadata("shopId") ? item.getMetadata("shopId").get(0).asString() : "?") + ")"); + } + } + } + } + } + } + + if (fw != null && config.enable_debug_log) { + try { + fw.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } } + /** + * Print a message to the /plugins/ShopChest/debug.txt file + * @param message Message to print + */ + public void debug(String message) { + if (config.enable_debug_log) { + try { + Calendar c = Calendar.getInstance(); + String timestamp = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss").format(c.getTime()); + fw.write(String.format("[%s] %s\r\n", timestamp, message)); + fw.flush(); + } catch (IOException e) { + getLogger().severe("Failed to print debug message."); + e.printStackTrace(); + } + } + } + + /** + * Print a {@link Throwable}'s stacktrace to the /plugins/ShopChest/debug.txt file + * @param throwable {@link Throwable} whose stacktrace will be printed + */ + public void debug(Throwable throwable) { + if (config.enable_debug_log) { + PrintWriter pw = new PrintWriter(fw); + throwable.printStackTrace(pw); + pw.flush(); + } + } + + /** * Initializes the shops */ private void initializeShops() { + debug("Initializing Shops..."); int count = shopUtils.reloadShops(false); - getLogger().info("Initialized " + String.valueOf(count) + " Shops"); + getLogger().info("Initialized " + count + " Shops"); + debug("Initialized " + count + " Shops"); } /** @@ -403,13 +515,13 @@ public class ShopChest extends JavaPlugin { } /** - * Provides a reader for a text file located inside the jar. + *

Provides a reader for a text file located inside the jar.

* The returned reader will read text with the UTF-8 charset. * @param file the filename of the resource to load - * @return null if getResource(String) returns null - * @throws IllegalArgumentException - if file is null + * @return null if {@link #getResource(String)} returns null + * @throws IllegalArgumentException if file is null */ - public Reader getTextResourceP(String file) throws IllegalArgumentException { + public Reader _getTextResource(String file) throws IllegalArgumentException { return getTextResource(file); } } diff --git a/ShopChest/src/main/java/de/epiceric/shopchest/Commands.java b/ShopChest/src/main/java/de/epiceric/shopchest/ShopCommand.java similarity index 88% rename from ShopChest/src/main/java/de/epiceric/shopchest/Commands.java rename to ShopChest/src/main/java/de/epiceric/shopchest/ShopCommand.java index e656c7b..068de55 100644 --- a/ShopChest/src/main/java/de/epiceric/shopchest/Commands.java +++ b/ShopChest/src/main/java/de/epiceric/shopchest/ShopCommand.java @@ -30,13 +30,13 @@ import org.bukkit.inventory.ItemStack; import java.lang.reflect.Method; import java.util.List; -public class Commands extends BukkitCommand { +class ShopCommand extends BukkitCommand { private ShopChest plugin; private Permission perm; private ShopUtils shopUtils; - public Commands(ShopChest plugin, String name, String description, String usageMessage, List aliases) { + ShopCommand(ShopChest plugin, String name, String description, String usageMessage, List aliases) { super(name, description, usageMessage, aliases); this.plugin = plugin; this.perm = plugin.getPermission(); @@ -50,7 +50,9 @@ public class Commands extends BukkitCommand { * @param plugin Instance of ShopChest * @throws ReflectiveOperationException */ - public static void registerCommand(Command command, ShopChest plugin) throws ReflectiveOperationException { + static void registerCommand(Command command, ShopChest plugin) throws ReflectiveOperationException { + plugin.debug("Registering command " + command.getName()); + Method commandMap = plugin.getServer().getClass().getMethod("getCommandMap"); Object cmdmap = commandMap.invoke(plugin.getServer()); Method register = cmdmap.getClass().getMethod("register", String.class, Command.class); @@ -119,6 +121,7 @@ public class Commands extends BukkitCommand { } } else if (args[0].equalsIgnoreCase("limits")) { if (perm.has(p, "shopchest.limits")) { + plugin.debug(p.getName() + " is viewing his shop limits: " + shopUtils.getShopAmount(p) + "/" + shopUtils.getShopLimit(p)); p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.OCCUPIED_SHOP_SLOTS, new LocalizedMessage.ReplacedRegex(Regex.LIMIT, String.valueOf(shopUtils.getShopLimit(p))), new LocalizedMessage.ReplacedRegex(Regex.AMOUNT, String.valueOf(shopUtils.getShopAmount(p))))); @@ -130,6 +133,8 @@ public class Commands extends BukkitCommand { } else if (args[0].equalsIgnoreCase("config")) { if (perm.has(p, "shopchest.config")) { if (args.length >= 4) { + plugin.debug(p.getName() + " is changing the configuration"); + String property = args[2]; String value = args[3]; @@ -177,6 +182,8 @@ public class Commands extends BukkitCommand { * @param player The command executor */ private void checkUpdates(Player player) { + plugin.debug(player.getName() + " is checking for updates"); + player.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.UPDATE_CHECKING)); UpdateChecker uc = new UpdateChecker(ShopChest.getInstance()); @@ -230,11 +237,18 @@ public class Commands extends BukkitCommand { * @param player The command executor */ private void reload(Player player) { + plugin.debug(player.getName() + " is reloading the shops"); + ShopReloadEvent event = new ShopReloadEvent(player); Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) return; + if (event.isCancelled()){ + plugin.debug("Reload event cancelled"); + return; + } - player.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.RELOADED_SHOPS, new LocalizedMessage.ReplacedRegex(Regex.AMOUNT, String.valueOf(shopUtils.reloadShops(true))))); + int count = shopUtils.reloadShops(true); + plugin.debug(player.getName() + " is reloaded " + count + " shops"); + player.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.RELOADED_SHOPS, new LocalizedMessage.ReplacedRegex(Regex.AMOUNT, String.valueOf(count)))); } /** @@ -244,6 +258,8 @@ public class Commands extends BukkitCommand { * @param p The command executor */ private void create(String[] args, ShopType shopType, Player p) { + plugin.debug(p.getName() + " wants to create a shop"); + int amount; double buyPrice, sellPrice; @@ -258,6 +274,8 @@ public class Commands extends BukkitCommand { } } + plugin.debug(p.getName() + " has not reached the limit"); + try { amount = Integer.parseInt(args[1]); buyPrice = Double.parseDouble(args[2]); @@ -267,6 +285,8 @@ public class Commands extends BukkitCommand { return; } + plugin.debug(p.getName() + " has entered the numbers correctly"); + boolean buyEnabled = !(buyPrice <= 0), sellEnabled = !(sellPrice <= 0); if (!buyEnabled && !sellEnabled) { @@ -274,11 +294,15 @@ public class Commands extends BukkitCommand { return; } + plugin.debug(p.getName() + " has enabled buying, selling or both"); + if (p.getItemInHand().getType().equals(Material.AIR)) { p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NO_ITEM_IN_HAND)); return; } + plugin.debug(p.getName() + " has an item in his hand"); + for (String item : plugin.getShopChestConfig().blacklist) { ItemStack itemStack; @@ -295,6 +319,8 @@ public class Commands extends BukkitCommand { } } + plugin.debug(p.getName() + "'s item is not on the blacklist"); + for (String key : plugin.getShopChestConfig().minimum_prices) { ItemStack itemStack; @@ -323,6 +349,8 @@ public class Commands extends BukkitCommand { } } + plugin.debug(p.getName() + "'s prices are higher than the minimum"); + if (sellEnabled && buyEnabled) { if (plugin.getShopChestConfig().buy_greater_or_equal_sell) { if (buyPrice < sellPrice) { @@ -332,6 +360,8 @@ public class Commands extends BukkitCommand { } } + plugin.debug(p.getName() + "'s buy price is high enough"); + ItemStack itemStack = new ItemStack(p.getItemInHand().getType(), amount, p.getItemInHand().getDurability()); itemStack.setItemMeta(p.getItemInHand().getItemMeta()); @@ -342,6 +372,8 @@ public class Commands extends BukkitCommand { } } + plugin.debug(p.getName() + "'s item is not broken (or broken items are allowed through config)"); + double creationPrice = (shopType == ShopType.NORMAL) ? plugin.getShopChestConfig().shop_creation_price_normal : plugin.getShopChestConfig().shop_creation_price_admin; if (creationPrice > 0) { if (plugin.getEconomy().getBalance(p) < creationPrice) { @@ -350,12 +382,17 @@ public class Commands extends BukkitCommand { } } - ShopPreCreateEvent event = new ShopPreCreateEvent(p, Shop.createImaginaryShop(p, itemStack, buyPrice, sellPrice, shopType)); + plugin.debug(p.getName() + " can pay the creation price"); + + ShopPreCreateEvent event = new ShopPreCreateEvent(p, Shop.createImaginaryShop(p, itemStack, null, buyPrice, sellPrice, shopType)); Bukkit.getPluginManager().callEvent(event); if (!event.isCancelled()) { ClickType.setPlayerClickType(p, new ClickType(EnumClickType.CREATE, itemStack, buyPrice, sellPrice, shopType)); + plugin.debug(p.getName() + " can now click a chest"); p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.CLICK_CHEST_CREATE)); + } else { + plugin.debug("Shop pre create event cancelled"); } } @@ -364,10 +401,16 @@ public class Commands extends BukkitCommand { * @param p The command executor */ private void remove(Player p) { + plugin.debug(p.getName() + " wants to remove a shop"); + ShopPreRemoveEvent event = new ShopPreRemoveEvent(p); Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) return; + if (event.isCancelled()) { + plugin.debug("Shop pre remove event cancelled"); + return; + } + plugin.debug(p.getName() + " can now click a chest"); p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.CLICK_CHEST_REMOVE)); ClickType.setPlayerClickType(p, new ClickType(EnumClickType.REMOVE)); } @@ -377,10 +420,16 @@ public class Commands extends BukkitCommand { * @param p The command executor */ private void info(Player p) { + plugin.debug(p.getName() + " wants to retrieve information"); + ShopPreInfoEvent event = new ShopPreInfoEvent(p); Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) return; + if (event.isCancelled()) { + plugin.debug("Shop pre info event cancelled"); + return; + } + plugin.debug(p.getName() + " can now click a chest"); p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.CLICK_CHEST_INFO)); ClickType.setPlayerClickType(p, new ClickType(EnumClickType.INFO)); } @@ -390,6 +439,8 @@ public class Commands extends BukkitCommand { * @param player Player who will receive the message */ private void sendBasicHelpMessage(Player player) { + plugin.debug("Sending basic help message to " + player.getName()); + player.sendMessage(ChatColor.GREEN + "/" + plugin.getShopChestConfig().main_command_name + " create [normal|admin] - " + LanguageUtils.getMessage(LocalizedMessage.Message.COMMAND_DESC_CREATE)); player.sendMessage(ChatColor.GREEN + "/" + plugin.getShopChestConfig().main_command_name + " remove - " + LanguageUtils.getMessage(LocalizedMessage.Message.COMMAND_DESC_REMOVE)); player.sendMessage(ChatColor.GREEN + "/" + plugin.getShopChestConfig().main_command_name + " info - " + LanguageUtils.getMessage(LocalizedMessage.Message.COMMAND_DESC_INFO)); diff --git a/ShopChest/src/main/java/de/epiceric/shopchest/config/Config.java b/ShopChest/src/main/java/de/epiceric/shopchest/config/Config.java index 10a6614..432ab65 100644 --- a/ShopChest/src/main/java/de/epiceric/shopchest/config/Config.java +++ b/ShopChest/src/main/java/de/epiceric/shopchest/config/Config.java @@ -76,6 +76,9 @@ public class Config { /** Whether shops should be protected by explosions **/ public boolean explosion_protection; + /** Whether the debug log file should be created **/ + public boolean enable_debug_log; + /** Whether admin shops should be excluded of the shop limits **/ public boolean exclude_admin_shops; @@ -265,6 +268,7 @@ public class Config { blacklist = (plugin.getConfig().getStringList("blacklist") == null) ? new ArrayList() : plugin.getConfig().getStringList("blacklist"); buy_greater_or_equal_sell = plugin.getConfig().getBoolean("buy-greater-or-equal-sell"); hopper_protection = plugin.getConfig().getBoolean("hopper-protection"); + enable_debug_log = plugin.getConfig().getBoolean("enable-debug-log"); explosion_protection = plugin.getConfig().getBoolean("explosion-protection"); exclude_admin_shops = plugin.getConfig().getBoolean("shop-limits.exclude-admin-shops"); show_shop_items = plugin.getConfig().getBoolean("show-shop-items"); @@ -304,10 +308,10 @@ public class Config { if (!langConfigFile.exists()) { if (!langDefaultFile.exists()) { try { - Reader r = plugin.getTextResourceP("lang/" + langConfigFile.getName()); + Reader r = plugin._getTextResource("lang/" + langConfigFile.getName()); if (r == null) { - r = plugin.getTextResourceP("lang/en_US.lang"); + r = plugin._getTextResource("lang/en_US.lang"); plugin.getLogger().info("Using locale \"en_US\" (Streamed from jar file)"); } else { plugin.getLogger().info("Using locale \"" + langConfigFile.getName().substring(0, langConfigFile.getName().length() - 5) + "\" (Streamed from jar file)"); diff --git a/ShopChest/src/main/java/de/epiceric/shopchest/language/LanguageUtils.java b/ShopChest/src/main/java/de/epiceric/shopchest/language/LanguageUtils.java index 24811b2..6fb45eb 100644 --- a/ShopChest/src/main/java/de/epiceric/shopchest/language/LanguageUtils.java +++ b/ShopChest/src/main/java/de/epiceric/shopchest/language/LanguageUtils.java @@ -904,6 +904,7 @@ public class LanguageUtils { messages.add(new LocalizedMessage(LocalizedMessage.Message.HOLOGRAM_SELL, langConfig.getString("message.hologram.only-sell", "Sell %SELL-PRICE%"), Regex.SELL_PRICE)); messages.add(new LocalizedMessage(LocalizedMessage.Message.NO_PERMISSION_CREATE, langConfig.getString("message.noPermission.create", "&cYou don't have permission to create a shop."))); messages.add(new LocalizedMessage(LocalizedMessage.Message.NO_PERMISSION_CREATE_ADMIN, langConfig.getString("message.noPermission.create-admin", "&cYou don't have permission to create an admin shop."))); + messages.add(new LocalizedMessage(LocalizedMessage.Message.NO_PERMISSION_CREATE_PROTECTED, langConfig.getString("message.noPermission.create-protected", "&cYou don't have permission to create a shop on a protected chest."))); messages.add(new LocalizedMessage(LocalizedMessage.Message.NO_PERMISSION_OPEN_OTHERS, langConfig.getString("message.noPermission.open-others", "&cYou don't have permission to open this chest."))); messages.add(new LocalizedMessage(LocalizedMessage.Message.NO_PERMISSION_BUY, langConfig.getString("message.noPermission.buy", "&cYou don't have permission to buy something."))); messages.add(new LocalizedMessage(LocalizedMessage.Message.NO_PERMISSION_SELL, langConfig.getString("message.noPermission.sell", "&cYou don't have permission to sell something."))); diff --git a/ShopChest/src/main/java/de/epiceric/shopchest/language/LocalizedMessage.java b/ShopChest/src/main/java/de/epiceric/shopchest/language/LocalizedMessage.java index ff4a96f..83740e1 100644 --- a/ShopChest/src/main/java/de/epiceric/shopchest/language/LocalizedMessage.java +++ b/ShopChest/src/main/java/de/epiceric/shopchest/language/LocalizedMessage.java @@ -101,6 +101,7 @@ public class LocalizedMessage { HOLOGRAM_SELL, NO_PERMISSION_CREATE, NO_PERMISSION_CREATE_ADMIN, + NO_PERMISSION_CREATE_PROTECTED, NO_PERMISSION_OPEN_OTHERS, NO_PERMISSION_BUY, NO_PERMISSION_SELL, diff --git a/ShopChest/src/main/java/de/epiceric/shopchest/listeners/ChestProtectListener.java b/ShopChest/src/main/java/de/epiceric/shopchest/listeners/ChestProtectListener.java index 19ca265..47e5242 100644 --- a/ShopChest/src/main/java/de/epiceric/shopchest/listeners/ChestProtectListener.java +++ b/ShopChest/src/main/java/de/epiceric/shopchest/listeners/ChestProtectListener.java @@ -67,6 +67,7 @@ public class ChestProtectListener implements Listener { @EventHandler public void onBlockPlace(BlockPlaceEvent e) { + Block b = e.getBlockPlaced(); if (b.getType().equals(Material.CHEST) || b.getType().equals(Material.TRAPPED_CHEST)) { @@ -79,6 +80,8 @@ public class ChestProtectListener implements Listener { Chest l = (Chest) dc.getLeftSide(); if (shopUtils.isShop(r.getLocation()) || shopUtils.isShop(l.getLocation())) { + plugin.debug(e.getPlayer().getName() + " tried to extend a shop to a double chest"); + if (b.getRelative(BlockFace.UP).getType() == Material.AIR) { Shop shop; diff --git a/ShopChest/src/main/java/de/epiceric/shopchest/listeners/ItemProtectListener.java b/ShopChest/src/main/java/de/epiceric/shopchest/listeners/ItemProtectListener.java index 7774bef..2bdf8e3 100644 --- a/ShopChest/src/main/java/de/epiceric/shopchest/listeners/ItemProtectListener.java +++ b/ShopChest/src/main/java/de/epiceric/shopchest/listeners/ItemProtectListener.java @@ -38,9 +38,7 @@ public class ItemProtectListener implements Listener { @EventHandler(priority = EventPriority.HIGH) public void onItemPickup(InventoryPickupItemEvent e) { - if (e.getInventory().getType().equals(InventoryType.HOPPER)) { - if (e.getItem().hasMetadata("shopItem")) e.setCancelled(true); - } + if (e.getItem().hasMetadata("shopItem")) e.setCancelled(true); } @EventHandler(priority = EventPriority.HIGH) diff --git a/ShopChest/src/main/java/de/epiceric/shopchest/listeners/LWCMagnetListener.java b/ShopChest/src/main/java/de/epiceric/shopchest/listeners/LWCMagnetListener.java index 6b33d6c..7960ef4 100644 --- a/ShopChest/src/main/java/de/epiceric/shopchest/listeners/LWCMagnetListener.java +++ b/ShopChest/src/main/java/de/epiceric/shopchest/listeners/LWCMagnetListener.java @@ -29,10 +29,10 @@ public class LWCMagnetListener { }); } catch (ClassNotFoundException ex) { + plugin.debug("Using not recommended version of LWC"); plugin.getLogger().warning("Shop items can be sucked up by the magnet flag of a protected chest of LWC."); plugin.getLogger().warning("Use 'LWC Unofficial - Entity locking' v1.7.3 or later by 'Me_Goes_RAWR' to prevent this."); } - ; } diff --git a/ShopChest/src/main/java/de/epiceric/shopchest/listeners/ShopInteractListener.java b/ShopChest/src/main/java/de/epiceric/shopchest/listeners/ShopInteractListener.java index 30c5ea9..8b64a9d 100644 --- a/ShopChest/src/main/java/de/epiceric/shopchest/listeners/ShopInteractListener.java +++ b/ShopChest/src/main/java/de/epiceric/shopchest/listeners/ShopInteractListener.java @@ -79,6 +79,7 @@ public class ShopInteractListener implements Listener { if (plugin.hasLockette()) { if (Lockette.isProtected(b)) { if (!Lockette.isOwner(b, p) || !Lockette.isUser(b, p, true)) { + p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NO_PERMISSION_CREATE_PROTECTED)); ClickType.removePlayerClickType(p); break; } @@ -89,6 +90,7 @@ public class ShopInteractListener implements Listener { if (LWC.getInstance().getPhysicalDatabase().loadProtection(b.getLocation().getWorld().getName(), b.getX(), b.getY(), b.getZ()) != null) { Protection protection = LWC.getInstance().getPhysicalDatabase().loadProtection(b.getLocation().getWorld().getName(), b.getX(), b.getY(), b.getZ()); if (!protection.isOwner(p) || !protection.isRealOwner(p)) { + p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NO_PERMISSION_CREATE_PROTECTED)); ClickType.removePlayerClickType(p); break; } @@ -120,10 +122,8 @@ public class ShopInteractListener implements Listener { e.setCancelled(true); if (shopUtils.isShop(b.getLocation())) { - Shop shop = shopUtils.getShop(b.getLocation()); info(p, shop); - } else { p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.CHEST_NO_SHOP)); } @@ -135,7 +135,6 @@ public class ShopInteractListener implements Listener { e.setCancelled(true); if (shopUtils.isShop(b.getLocation())) { - Shop shop = shopUtils.getShop(b.getLocation()); if (shop.getVendor().getUniqueId().equals(p.getUniqueId()) || perm.has(p, "shopchest.removeOther")) { @@ -163,6 +162,7 @@ public class ShopInteractListener implements Listener { if (!shop.getVendor().getUniqueId().equals(p.getUniqueId())) { if (perm.has(p, "shopchest.openOther")) { p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.OPENED_SHOP, new LocalizedMessage.ReplacedRegex(Regex.VENDOR, shop.getVendor().getName()))); + plugin.debug(p.getName() + " is opening " + shop.getVendor().getName() + "'s shop (#" + shop.getID() + ")" ); e.setCancelled(false); } else { p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NO_PERMISSION_OPEN_OTHERS)); @@ -245,28 +245,28 @@ public class ShopInteractListener implements Listener { * @param shopType Type of the shop */ private void create(Player executor, Location location, ItemStack product, double buyPrice, double sellPrice, ShopType shopType) { + plugin.debug(executor.getName() + " is creating new shop..."); + int id = database.getNextFreeID(); - - if (id == 0) { - executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.ERROR_OCCURRED, new LocalizedMessage.ReplacedRegex(Regex.ERROR, "Could not connect to database"))); - return; - } - double creationPrice = (shopType == ShopType.NORMAL) ? plugin.getShopChestConfig().shop_creation_price_normal : plugin.getShopChestConfig().shop_creation_price_admin; - ShopCreateEvent event = new ShopCreateEvent(executor, Shop.createImaginaryShop(executor, product, buyPrice, sellPrice,shopType), creationPrice); + ShopCreateEvent event = new ShopCreateEvent(executor, Shop.createImaginaryShop(executor, product, location, buyPrice, sellPrice,shopType), creationPrice); Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) return; - + if (event.isCancelled()) { + plugin.debug("Create event cancelled (#" + id + ")"); + return; + } EconomyResponse r = plugin.getEconomy().withdrawPlayer(executor, creationPrice); if (!r.transactionSuccess()) { + plugin.debug("Economy transaction failed: " + r.errorMessage); executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.ERROR_OCCURRED, new LocalizedMessage.ReplacedRegex(Regex.ERROR, r.errorMessage))); return; } Shop shop = new Shop(id, plugin, executor, product, location, buyPrice, sellPrice, shopType); + plugin.debug("Shop created (#" + id + ")"); shopUtils.addShop(shop, true); executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.SHOP_CREATED)); @@ -282,11 +282,16 @@ public class ShopInteractListener implements Listener { * @param shop Shop to be removed */ private void remove(Player executor, Shop shop) { + plugin.debug(executor.getName() + " is removing shop (#" + shop.getID() + ")"); ShopRemoveEvent event = new ShopRemoveEvent(executor, shop); Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) return; + if (event.isCancelled()) { + plugin.debug("Remove event cancelled (#" + shop.getID() + ")"); + return; + } shopUtils.removeShop(shop, true); + plugin.debug("Removed shop (#" + shop.getID() + ")"); executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.SHOP_REMOVED)); } @@ -296,10 +301,13 @@ public class ShopInteractListener implements Listener { * @param shop Shop from which the information will be retrieved */ private void info(Player executor, Shop shop) { + plugin.debug(executor.getName() + " is retrieving shop info (#" + shop.getID() + ")"); ShopInfoEvent event = new ShopInfoEvent(executor, shop); Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) return; - + if (event.isCancelled()) { + plugin.debug("Info event cancelled (#" + shop.getID() + ")"); + return; + } Chest c = (Chest) shop.getLocation().getBlock().getState(); int amount = Utils.getAmount(c.getInventory(), shop.getProduct()); @@ -373,7 +381,9 @@ public class ShopInteractListener implements Listener { * @param shop Shop, from which the player buys */ private void buy(Player executor, Shop shop) { + plugin.debug(executor.getName() + " is buying (#" + shop.getID() + ")"); if (econ.getBalance(executor) >= shop.getBuyPrice()) { + plugin.debug(executor.getName() + " has enough money (#" + shop.getID() + ")"); Block b = shop.getLocation().getBlock(); Chest c = (Chest) b.getState(); @@ -414,6 +424,7 @@ public class ShopInteractListener implements Listener { } if (freeAmount >= product.getAmount()) { + plugin.debug(executor.getName() + " has enough inventory space (#" + shop.getID() + ")"); EconomyResponse r = econ.withdrawPlayer(executor, shop.getBuyPrice()); EconomyResponse r2 = (shop.getShopType() != ShopType.ADMIN) ? econ.depositPlayer(shop.getVendor(), shop.getBuyPrice()) : null; @@ -427,6 +438,7 @@ public class ShopInteractListener implements Listener { if (event.isCancelled()) { econ.depositPlayer(executor, shop.getBuyPrice()); econ.withdrawPlayer(shop.getVendor(), shop.getBuyPrice()); + plugin.debug("Buy event cancelled (#" + shop.getID() + ")"); return; } @@ -437,6 +449,8 @@ public class ShopInteractListener implements Listener { new LocalizedMessage.ReplacedRegex(Regex.ITEM_NAME, LanguageUtils.getItemName(product)), new LocalizedMessage.ReplacedRegex(Regex.BUY_PRICE, String.valueOf(shop.getBuyPrice())), new LocalizedMessage.ReplacedRegex(Regex.VENDOR, shop.getVendor().getName()))); + plugin.debug(executor.getName() + " successfully bought (#" + shop.getID() + ")"); + if (shop.getVendor().isOnline()) { shop.getVendor().getPlayer().sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.SOMEONE_BOUGHT, new LocalizedMessage.ReplacedRegex(Regex.AMOUNT, String.valueOf(product.getAmount())), new LocalizedMessage.ReplacedRegex(Regex.ITEM_NAME, LanguageUtils.getItemName(product)), new LocalizedMessage.ReplacedRegex(Regex.BUY_PRICE, String.valueOf(shop.getBuyPrice())), @@ -444,6 +458,7 @@ public class ShopInteractListener implements Listener { } } else { + plugin.debug("Economy transaction failed: " + r2.errorMessage + " (#" + shop.getID() + ")"); executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.ERROR_OCCURRED, new LocalizedMessage.ReplacedRegex(Regex.ERROR, r2.errorMessage))); } } else { @@ -452,6 +467,7 @@ public class ShopInteractListener implements Listener { if (event.isCancelled()) { econ.depositPlayer(executor, shop.getBuyPrice()); + plugin.debug("Buy event cancelled (#" + shop.getID() + ")"); return; } @@ -459,8 +475,11 @@ public class ShopInteractListener implements Listener { executor.updateInventory(); executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.BUY_SUCESS_ADMIN, new LocalizedMessage.ReplacedRegex(Regex.AMOUNT, String.valueOf(product.getAmount())), new LocalizedMessage.ReplacedRegex(Regex.ITEM_NAME, LanguageUtils.getItemName(product)), new LocalizedMessage.ReplacedRegex(Regex.BUY_PRICE, String.valueOf(shop.getBuyPrice())))); + + plugin.debug(executor.getName() + " successfully bought (#" + shop.getID() + ")"); } } else { + plugin.debug("Economy transaction failed: " + r.errorMessage + " (#" + shop.getID() + ")"); executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.ERROR_OCCURRED, new LocalizedMessage.ReplacedRegex(Regex.ERROR, r.errorMessage))); } } else { @@ -477,7 +496,10 @@ public class ShopInteractListener implements Listener { * @param shop Shop, to which the player sells */ private void sell(Player executor, Shop shop) { + plugin.debug(executor.getName() + " is selling (#" + shop.getID() + ")"); + if (econ.getBalance(shop.getVendor()) >= shop.getSellPrice() || shop.getShopType() == ShopType.ADMIN) { + plugin.debug("Vendor has enough money (#" + shop.getID() + ")"); Block block = shop.getLocation().getBlock(); Chest chest = (Chest) block.getState(); @@ -505,6 +527,7 @@ public class ShopInteractListener implements Listener { } if (freeAmount >= product.getAmount()) { + plugin.debug("Chest has enough inventory space (#" + shop.getID() + ")"); EconomyResponse r = econ.depositPlayer(executor, shop.getSellPrice()); EconomyResponse r2 = (shop.getShopType() != ShopType.ADMIN) ? econ.withdrawPlayer(shop.getVendor(), shop.getSellPrice()) : null; @@ -518,6 +541,7 @@ public class ShopInteractListener implements Listener { if (event.isCancelled()) { econ.withdrawPlayer(executor, shop.getBuyPrice()); econ.depositPlayer(shop.getVendor(), shop.getBuyPrice()); + plugin.debug("Sell event cancelled (#" + shop.getID() + ")"); return; } @@ -528,6 +552,8 @@ public class ShopInteractListener implements Listener { new LocalizedMessage.ReplacedRegex(Regex.ITEM_NAME, LanguageUtils.getItemName(product)), new LocalizedMessage.ReplacedRegex(Regex.SELL_PRICE, String.valueOf(shop.getSellPrice())), new LocalizedMessage.ReplacedRegex(Regex.VENDOR, shop.getVendor().getName()))); + plugin.debug(executor.getName() + " successfully sold (#" + shop.getID() + ")"); + if (shop.getVendor().isOnline()) { shop.getVendor().getPlayer().sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.SOMEONE_SOLD, new LocalizedMessage.ReplacedRegex(Regex.AMOUNT, String.valueOf(product.getAmount())), new LocalizedMessage.ReplacedRegex(Regex.ITEM_NAME, LanguageUtils.getItemName(product)), new LocalizedMessage.ReplacedRegex(Regex.SELL_PRICE, String.valueOf(shop.getSellPrice())), @@ -535,6 +561,7 @@ public class ShopInteractListener implements Listener { } } else { + plugin.debug("Economy transaction failed: " + r2.errorMessage + " (#" + shop.getID() + ")"); executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.ERROR_OCCURRED, new LocalizedMessage.ReplacedRegex(Regex.ERROR, r2.errorMessage))); } @@ -544,6 +571,7 @@ public class ShopInteractListener implements Listener { if (event.isCancelled()) { econ.withdrawPlayer(executor, shop.getBuyPrice()); + plugin.debug("Sell event cancelled (#" + shop.getID() + ")"); return; } @@ -551,9 +579,12 @@ public class ShopInteractListener implements Listener { executor.updateInventory(); executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.SELL_SUCESS_ADMIN, new LocalizedMessage.ReplacedRegex(Regex.AMOUNT, String.valueOf(product.getAmount())), new LocalizedMessage.ReplacedRegex(Regex.ITEM_NAME, LanguageUtils.getItemName(product)), new LocalizedMessage.ReplacedRegex(Regex.SELL_PRICE, String.valueOf(shop.getSellPrice())))); + + plugin.debug(executor.getName() + " successfully sold (#" + shop.getID() + ")"); } } else { + plugin.debug("Economy transaction failed: " + r.errorMessage + " (#" + shop.getID() + ")"); executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.ERROR_OCCURRED, new LocalizedMessage.ReplacedRegex(Regex.ERROR, r.errorMessage))); } @@ -573,6 +604,8 @@ public class ShopInteractListener implements Listener { * @return Whether all items were added to the inventory */ private boolean addToInventory(Inventory inventory, ItemStack itemStack) { + plugin.debug("Adding items to inventory..."); + HashMap inventoryItems = new HashMap<>(); int amount = itemStack.getAmount(); int added = 0; @@ -629,6 +662,8 @@ public class ShopInteractListener implements Listener { * @return Whether all items were removed from the inventory */ private boolean removeFromInventory(Inventory inventory, ItemStack itemStack) { + plugin.debug("Removing items from inventory..."); + HashMap inventoryItems = new HashMap<>(); int amount = itemStack.getAmount(); int removed = 0; diff --git a/ShopChest/src/main/java/de/epiceric/shopchest/shop/Shop.java b/ShopChest/src/main/java/de/epiceric/shopchest/shop/Shop.java index 080624a..290b064 100644 --- a/ShopChest/src/main/java/de/epiceric/shopchest/shop/Shop.java +++ b/ShopChest/src/main/java/de/epiceric/shopchest/shop/Shop.java @@ -51,7 +51,9 @@ public class Shop { if (b.getType() != Material.CHEST && b.getType() != Material.TRAPPED_CHEST) { try { plugin.getShopUtils().removeShop(this, plugin.getShopChestConfig().remove_shop_on_error); - throw new Exception("No Chest found at specified Location: " + b.getX() + "; " + b.getY() + "; " + b.getZ()); + Exception e = new Exception("No Chest found at specified Location: " + b.getX() + "; " + b.getY() + "; " + b.getZ()); + plugin.debug(e); + throw e; } catch (Exception ex) { ex.printStackTrace(); return; @@ -59,7 +61,9 @@ public class Shop { } else if ((b.getRelative(BlockFace.UP).getType() != Material.AIR) && plugin.getShopChestConfig().show_shop_items) { try { plugin.getShopUtils().removeShop(this, plugin.getShopChestConfig().remove_shop_on_error); - throw new Exception("No space above chest at specified Location: " + b.getX() + "; " + b.getY() + "; " + b.getZ()); + Exception e = new Exception("No space above chest at specified Location: " + b.getX() + "; " + b.getY() + "; " + b.getZ()); + plugin.debug(e); + throw e; } catch (Exception ex) { ex.printStackTrace(); return; @@ -70,11 +74,11 @@ public class Shop { if (item == null || item.isDead()) createItem(); } - private Shop(OfflinePlayer vendor, ItemStack product, double buyPrice, double sellPrice, ShopType shopType) { + private Shop(OfflinePlayer vendor, ItemStack product, Location location, double buyPrice, double sellPrice, ShopType shopType) { this.id = 0; this.vendor = vendor; this.product = product; - this.location = null; + this.location = location; this.buyPrice = buyPrice; this.sellPrice = sellPrice; this.shopType = shopType; @@ -85,6 +89,8 @@ public class Shop { */ public void removeHologram() { if (hologram != null && hologram.exists()) { + plugin.debug("Removing hologram (#" + id + ")"); + for (Player p : Bukkit.getOnlinePlayers()) { hologram.hidePlayer(p); } @@ -97,8 +103,10 @@ public class Shop { * Removes the floating item of the shop */ public void removeItem() { - if (item != null && !item.isDead()) + if (item != null) { + plugin.debug("Removing shop item (#" + id + ")"); item.remove(); + } } /** @@ -107,6 +115,8 @@ public class Shop { */ private void createItem() { if (plugin.getShopChestConfig().show_shop_items) { + plugin.debug("Creating item (#" + id + ")"); + Item item; Location itemLocation; ItemStack itemStack; @@ -121,6 +131,7 @@ public class Shop { item = location.getWorld().dropItem(itemLocation, itemStack); item.setVelocity(new Vector(0, 0, 0)); item.setMetadata("shopItem", new FixedMetadataValue(plugin, true)); + item.setMetadata("shopId", new FixedMetadataValue(plugin, id)); item.setCustomNameVisible(false); item.setPickupDelay(Integer.MAX_VALUE); @@ -132,6 +143,8 @@ public class Shop { * Creates the hologram of the shop */ private void createHologram() { + plugin.debug("Creating hologram (#" + id + ")"); + boolean doubleChest; Chest[] chests = new Chest[2]; @@ -293,8 +306,8 @@ public class Shop { /** * @return A shop, which is not really a shop. It's just for "storing" the data (used in some events). */ - public static Shop createImaginaryShop(OfflinePlayer vendor, ItemStack product, double buyPrice, double sellPrice, ShopType shopType) { - return new Shop(vendor, product, buyPrice, sellPrice, shopType); + public static Shop createImaginaryShop(OfflinePlayer vendor, ItemStack product, Location location, double buyPrice, double sellPrice, ShopType shopType) { + return new Shop(vendor, product, location, buyPrice, sellPrice, shopType); } public enum ShopType { diff --git a/ShopChest/src/main/java/de/epiceric/shopchest/sql/Database.java b/ShopChest/src/main/java/de/epiceric/shopchest/sql/Database.java index adbcb12..6914f29 100644 --- a/ShopChest/src/main/java/de/epiceric/shopchest/sql/Database.java +++ b/ShopChest/src/main/java/de/epiceric/shopchest/sql/Database.java @@ -57,6 +57,14 @@ public abstract class Database { PreparedStatement ps = connection.prepareStatement("SELECT * FROM shop_list"); ResultSet rs = ps.executeQuery(); + + int count = 0; + while (rs.next()) { + if (rs.getString("vendor") != null) count++; + } + plugin.debug("Initialized database with " + count + " entries"); + + close(ps, rs); } catch (SQLException ex) { @@ -68,13 +76,11 @@ public abstract class Database { * @return Lowest possible ID which is not used (> 0) */ public int getNextFreeID() { - for (int i = 1; i < getHighestID() + 1; i++) { + int highestId = getHighestID(); + for (int i = 1; i <= highestId + 1; i++) { if (get(i, ShopInfo.X) == null) { + plugin.debug("Next free id: " + i); return i; - } else { - if (i == getHighestID()) { - return i + 1; - } } } @@ -88,7 +94,7 @@ public abstract class Database { PreparedStatement ps = null; ResultSet rs = null; - int highestID = 1; + int highestID = 0; try { ps = connection.prepareStatement("SELECT * FROM shop_list;"); @@ -100,6 +106,7 @@ public abstract class Database { } } + plugin.debug("Highest used ID: " + highestID); return highestID; } catch (SQLException ex) { @@ -121,6 +128,7 @@ public abstract class Database { try { ps = connection.prepareStatement("DELETE FROM shop_list WHERE id = " + shop.getID() + ";"); + plugin.debug("Removing shop from database (#" + shop.getID() + ")"); ps.executeUpdate(); } catch (SQLException ex) { ex.printStackTrace(); @@ -148,10 +156,14 @@ public abstract class Database { switch (shopInfo) { case SHOP: + plugin.debug("Getting Shop... (#" + id + ")"); + Shop shop = plugin.getShopUtils().getShop((Location) get(id, ShopInfo.LOCATION)); - if (shop != null) + if (shop != null) { + plugin.debug("Shop already exists, returning existing one (#" + id + ")."); return shop; - else { + } else { + plugin.debug("Creating new shop... (#" + id + ")"); return new Shop(id, plugin, (OfflinePlayer) get(id, ShopInfo.VENDOR), (ItemStack) get(id, ShopInfo.PRODUCT), @@ -161,24 +173,43 @@ public abstract class Database { (ShopType) get(id, ShopInfo.SHOPTYPE)); } case VENDOR: - return Bukkit.getOfflinePlayer(UUID.fromString(rs.getString("vendor"))); + String vendor = rs.getString("vendor"); + plugin.debug("Getting vendor: " + vendor + " (#" + id + ")"); + return Bukkit.getOfflinePlayer(UUID.fromString(vendor)); case PRODUCT: - return Utils.decode(rs.getString("product")); + String product = rs.getString("product"); + plugin.debug("Getting product: " + product + " (#" + id + ")"); + return Utils.decode(product); case WORLD: - return Bukkit.getWorld(rs.getString("world")); + String world = rs.getString("world"); + plugin.debug("Getting world: " + world + " (#" + id + ")"); + return Bukkit.getWorld(world); case X: - return rs.getInt("x"); + int x = rs.getInt("x"); + plugin.debug("Getting x: " + x + " (#" + id + ")"); + return x; case Y: - return rs.getInt("y"); + int y = rs.getInt("y"); + plugin.debug("Getting y: " + y + " (#" + id + ")"); + return y; case Z: - return rs.getInt("z"); + int z = rs.getInt("z"); + plugin.debug("Getting z: " + z + " (#" + id + ")"); + return z; case LOCATION: + plugin.debug("Getting location... (#" + id + ")"); return new Location((World) get(id, ShopInfo.WORLD), (int) get(id, ShopInfo.X), (int) get(id, ShopInfo.Y), (int) get(id, ShopInfo.Z)); case BUYPRICE: - return rs.getDouble("buyprice"); + double buyprice = rs.getDouble("buyprice"); + plugin.debug("Getting buyprice: " + buyprice + " (#" + id + ")"); + return buyprice; case SELLPRICE: - return rs.getDouble("sellprice"); + double sellprice = rs.getDouble("sellprice"); + plugin.debug("Getting sellprice: " + sellprice + " (#" + id + ")"); + return sellprice; case SHOPTYPE: + ShopType shopType = ShopType.valueOf(rs.getString("shoptype")); + plugin.debug("Getting shoptype: " + rs.getString("shoptype") + " (#" + id + ")"); String shoptype = rs.getString("shoptype"); if (shoptype.equals("INFINITE")) { @@ -200,6 +231,8 @@ public abstract class Database { } } + plugin.debug("Shop with ID not found, returning null. (#" + id + ")"); + } catch (SQLException ex) { ex.printStackTrace(); } finally { @@ -230,6 +263,8 @@ public abstract class Database { ps.setDouble(9, shop.getSellPrice()); ps.setString(10, shop.getShopType().toString()); + plugin.debug("Adding shop to database (#" + shop.getID() + ")"); + ps.executeUpdate(); } catch (SQLException ex) { ex.printStackTrace(); @@ -238,28 +273,6 @@ public abstract class Database { } } - /** - * @return Whether ShopChest is connected to the database - */ - private boolean isConnected() { - PreparedStatement ps = null; - ResultSet rs = null; - - boolean connected = false; - - try { - ps = connection.prepareStatement("SELECT * FROM shop_list"); - rs = ps.executeQuery(); - connected = true; - } catch (SQLException e) { - connected = false; - } finally { - close(ps, rs); - } - - return connected; - } - /** * Closes a {@link PreparedStatement} and a {@link ResultSet} * @param ps {@link PreparedStatement} to close diff --git a/ShopChest/src/main/java/de/epiceric/shopchest/sql/MySQL.java b/ShopChest/src/main/java/de/epiceric/shopchest/sql/MySQL.java index d5fe3c0..50b7127 100644 --- a/ShopChest/src/main/java/de/epiceric/shopchest/sql/MySQL.java +++ b/ShopChest/src/main/java/de/epiceric/shopchest/sql/MySQL.java @@ -21,7 +21,7 @@ public class MySQL extends Database { Class.forName("com.mysql.jdbc.Driver"); String connectUrl = "jdbc:mysql://" + plugin.getShopChestConfig().database_mysql_host + ":" + plugin.getShopChestConfig().database_mysql_port + "/" + plugin.getShopChestConfig().database_mysql_database + "?autoReconnect=true"; - plugin.getLogger().info("Connecting to MySQL Server \"" + connectUrl + "\" as user \"" + plugin.getShopChestConfig().database_mysql_username + "\""); + plugin.debug("Connecting to MySQL Server \"" + connectUrl + "\" as user \"" + plugin.getShopChestConfig().database_mysql_username + "\""); connection = DriverManager.getConnection(connectUrl, plugin.getShopChestConfig().database_mysql_username, plugin.getShopChestConfig().database_mysql_password); diff --git a/ShopChest/src/main/java/de/epiceric/shopchest/utils/ShopUtils.java b/ShopChest/src/main/java/de/epiceric/shopchest/utils/ShopUtils.java index 36471fc..8fc6f72 100644 --- a/ShopChest/src/main/java/de/epiceric/shopchest/utils/ShopUtils.java +++ b/ShopChest/src/main/java/de/epiceric/shopchest/utils/ShopUtils.java @@ -12,10 +12,8 @@ import org.bukkit.entity.Item; import org.bukkit.entity.Player; import org.bukkit.inventory.InventoryHolder; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.UUID; +import java.util.*; +import java.util.logging.Level; public class ShopUtils { @@ -69,15 +67,20 @@ public class ShopUtils { */ public void addShop(Shop shop, boolean addToDatabase) { InventoryHolder ih = shop.getInventoryHolder(); + plugin.debug("Adding shop... (#" + shop.getID() + ")"); if (ih instanceof DoubleChest) { DoubleChest dc = (DoubleChest) ih; Chest r = (Chest) dc.getRightSide(); Chest l = (Chest) dc.getLeftSide(); + plugin.debug("Added shop as double chest. (#" + shop.getID() + ")"); + shopLocation.put(r.getLocation(), shop); shopLocation.put(l.getLocation(), shop); } else { + plugin.debug("Added shop as single chest. (#" + shop.getID() + ")"); + shopLocation.put(shop.getLocation(), shop); } @@ -92,6 +95,8 @@ public class ShopUtils { * @param removeFromDatabase Whether the shop should also be removed from the database */ public void removeShop(Shop shop, boolean removeFromDatabase) { + plugin.debug("Removing shop (#" + shop.getID() + ")"); + InventoryHolder ih = shop.getInventoryHolder(); if (ih instanceof DoubleChest) { @@ -200,10 +205,19 @@ public class ShopUtils { * @return Amount of shops, which were reloaded */ public int reloadShops(boolean reloadConfig) { + plugin.debug("Reloading shops..."); + if (reloadConfig) plugin.getShopChestConfig().reload(false, true); - for (Shop shop : getShops()) { - removeShop(shop, false); + int highestId = plugin.getShopDatabase().getHighestID(); + + for (int i = 1; i <= highestId; i++) { + for (Shop shop : getShops()) { + if (shop.getID() == i) { + removeShop(shop, false); + plugin.debug("Removed shop (#" + shop.getID() + ")"); + } + } } for (World world : Bukkit.getWorlds()) { @@ -211,19 +225,41 @@ public class ShopUtils { if (entity instanceof Item) { Item item = (Item) entity; if (item.hasMetadata("shopItem")) { - item.remove(); + if (item.isValid()) { + plugin.debug("Removing not removed shop item (#" + + (item.hasMetadata("shopId") ? item.getMetadata("shopId").get(0).asString() : "?") + ")"); + + item.remove(); + } + } + } + } + } + + for (World world : Bukkit.getWorlds()) { + for (Entity entity : world.getEntities()) { + if (entity instanceof Item) { + Item item = (Item) entity; + if (item.hasMetadata("shopItem")) { + if (item.isValid()) { + plugin.debug("Shop item still valid (#" + + (item.hasMetadata("shopId") ? item.getMetadata("shopId").get(0).asString() : "?") + ")"); + } } } } } int count = 0; - for (int id = 1; id < plugin.getShopDatabase().getHighestID() + 1; id++) { + for (int id = 1; id <= highestId; id++) { try { + plugin.debug("Trying to add shop. (#" + id + ")"); Shop shop = (Shop) plugin.getShopDatabase().get(id, Database.ShopInfo.SHOP); addShop(shop, false); } catch (Exception e) { + plugin.debug("Error while adding shop (#" + id + "):"); + plugin.debug(e); continue; } diff --git a/ShopChest/src/main/java/de/epiceric/shopchest/utils/UpdateChecker.java b/ShopChest/src/main/java/de/epiceric/shopchest/utils/UpdateChecker.java index c0c4411..52403ae 100644 --- a/ShopChest/src/main/java/de/epiceric/shopchest/utils/UpdateChecker.java +++ b/ShopChest/src/main/java/de/epiceric/shopchest/utils/UpdateChecker.java @@ -24,6 +24,8 @@ public class UpdateChecker { */ public UpdateCheckerResult check() { try { + plugin.debug("Checking for updates..."); + URL url = new URL("http://textuploader.com/all1l/raw"); URLConnection conn = url.openConnection(); conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0"); @@ -40,12 +42,17 @@ public class UpdateChecker { version = line.split("\\|")[0]; link = url + "download?version=" + line.split("\\|")[1]; - if (plugin.getDescription().getVersion().equals(version)) + if (plugin.getDescription().getVersion().equals(version)) { + plugin.debug("No update found"); return UpdateCheckerResult.FALSE; - else + } else { + plugin.debug("Update found: " + version); return UpdateCheckerResult.TRUE; + } } catch (Exception e) { + plugin.debug("Failed to check for updates"); + plugin.debug(e); return UpdateCheckerResult.ERROR; } } diff --git a/ShopChest/src/main/java/de/epiceric/shopchest/utils/Utils.java b/ShopChest/src/main/java/de/epiceric/shopchest/utils/Utils.java index 3418790..6643e17 100644 --- a/ShopChest/src/main/java/de/epiceric/shopchest/utils/Utils.java +++ b/ShopChest/src/main/java/de/epiceric/shopchest/utils/Utils.java @@ -51,7 +51,7 @@ public class Utils { } /** - * @return The current server version with revision number (e.g. 1_9_R2, 1_10_R1) + * @return The current server version with revision number (e.g. v1_9_R2, v1_10_R1) */ public static String getServerVersion() { String packageName = Bukkit.getServer().getClass().getPackage().getName(); diff --git a/ShopChest/src/main/resources/config.yml b/ShopChest/src/main/resources/config.yml index ff9d2da..91e27e9 100644 --- a/ShopChest/src/main/resources/config.yml +++ b/ShopChest/src/main/resources/config.yml @@ -14,6 +14,10 @@ language-file: "en_US" # Set whether the floating shop items on top of the chest should be shown show-shop-items: true +# Set whether a debug log file should be created. +# The file may get large! Please enable this setting when reporting bugs. +enable-debug-log: false + # Set whether players should be allowed to sell/buy broken items allow-broken-items: false diff --git a/ShopChest/src/main/resources/lang/de_DE.lang b/ShopChest/src/main/resources/lang/de_DE.lang index 31a5253..36cfd40 100644 --- a/ShopChest/src/main/resources/lang/de_DE.lang +++ b/ShopChest/src/main/resources/lang/de_DE.lang @@ -57,6 +57,7 @@ message.hologram.only-buy=Kauf %BUY-PRICE% message.hologram.only-sell=Verkauf %SELL-PRICE% message.noPermission.create=&cDu hast keine Berechtigung einen Shop zu erstellen. message.noPermission.create-admin=&cDu hast keine Berechtigung einen Admin-Shop zu erstellen. +message.noPermission.create-protected=&cDu hast keine Berechtigung einen Shop auf einer gesicherten Truhe zu erstellen. message.noPermission.open-others=&cDu hast keine Berechtigung diesen Shop zu öffnen. message.noPermission.buy=&cDu hast keine Berechtigung etwas zu kaufen. message.noPermission.sell=&cDu hast keine Berechtigung etwas zu verkaufen. diff --git a/ShopChest/src/main/resources/lang/en_US.lang b/ShopChest/src/main/resources/lang/en_US.lang index 8ae4e32..6068c64 100644 --- a/ShopChest/src/main/resources/lang/en_US.lang +++ b/ShopChest/src/main/resources/lang/en_US.lang @@ -203,6 +203,9 @@ message.noPermission.create=&cYou don't have permission to create a shop. # Set the message when a not permitted player tries to create an admin shop. message.noPermission.create-admin=&cYou don't have permission to create an admin shop. +# Set the message when a not permitted player tries to create a shop on a protected chest. +message.noPermission.create-protected=&cYou don't have permission to create a shop on a protected chest. + # Set the message when a not permitted player tries to open another player's shop. message.noPermission.open-others=&cYou don't have permission to open this chest.