diff --git a/src/main/java/de/epiceric/shopchest/command/ShopCommand.java b/src/main/java/de/epiceric/shopchest/command/ShopCommand.java index 1fa5b10..c437781 100644 --- a/src/main/java/de/epiceric/shopchest/command/ShopCommand.java +++ b/src/main/java/de/epiceric/shopchest/command/ShopCommand.java @@ -231,7 +231,7 @@ public class ShopCommand { CommandMap commandMap = (CommandMap) commandMapObject; pluginCommand.unregister(commandMap); - Field fKnownCommands = commandMap.getClass().getDeclaredField("knownCommands"); + Field fKnownCommands = SimpleCommandMap.class.getDeclaredField("knownCommands"); fKnownCommands.setAccessible(true); Object knownCommandsObject = fKnownCommands.get(commandMap); diff --git a/src/main/java/de/epiceric/shopchest/command/ShopCommandExecutor.java b/src/main/java/de/epiceric/shopchest/command/ShopCommandExecutor.java index eca599e..79571f2 100644 --- a/src/main/java/de/epiceric/shopchest/command/ShopCommandExecutor.java +++ b/src/main/java/de/epiceric/shopchest/command/ShopCommandExecutor.java @@ -38,6 +38,7 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import java.util.ArrayList; +import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.stream.Stream; @@ -544,27 +545,34 @@ class ShopCommandExecutor implements CommandExecutor { plugin.debug(sender.getName() + " is removing all shops of " + vendor.getName()); - List shops = new ArrayList<>(); + plugin.getShopUtils().getShops(vendor, new Callback>(plugin) { + @Override + public void onResult(Collection result) { + List shops = new ArrayList<>(result); - for (Shop shop : shopUtils.getShops()) { - if (shop.getVendor().getUniqueId().equals(vendor.getUniqueId())) { - shops.add(shop); + ShopRemoveAllEvent event = new ShopRemoveAllEvent(sender, vendor, shops); + Bukkit.getPluginManager().callEvent(event); + if (event.isCancelled()){ + plugin.debug("Remove all event cancelled"); + return; + } + + for (Shop shop : shops) { + shopUtils.removeShop(shop, true); + } + + sender.sendMessage(LanguageUtils.getMessage(Message.ALL_SHOPS_REMOVED, + new Replacement(Placeholder.AMOUNT, String.valueOf(shops.size())), + new Replacement(Placeholder.VENDOR, vendor.getName()))); } - } - ShopRemoveAllEvent event = new ShopRemoveAllEvent(sender, vendor, shops); - Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()){ - plugin.debug("Remove all event cancelled"); - return; - } + @Override + public void onError(Throwable throwable) { + sender.sendMessage(LanguageUtils.getMessage(Message.ERROR_OCCURRED, + new Replacement(Placeholder.ERROR, "Failed to get player's shops"))); + } + }); - for (Shop shop : shops) { - shopUtils.removeShop(shop, true); - } - - sender.sendMessage(LanguageUtils.getMessage(Message.ALL_SHOPS_REMOVED, - new Replacement(Placeholder.AMOUNT, String.valueOf(shops.size())), - new Replacement(Placeholder.VENDOR, vendor.getName()))); + } } diff --git a/src/main/java/de/epiceric/shopchest/command/ShopTabCompleter.java b/src/main/java/de/epiceric/shopchest/command/ShopTabCompleter.java index a50d6ac..b9c89ab 100644 --- a/src/main/java/de/epiceric/shopchest/command/ShopTabCompleter.java +++ b/src/main/java/de/epiceric/shopchest/command/ShopTabCompleter.java @@ -2,14 +2,18 @@ package de.epiceric.shopchest.command; import de.epiceric.shopchest.ShopChest; import de.epiceric.shopchest.config.Config; + +import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; class ShopTabCompleter implements TabCompleter { @@ -29,6 +33,7 @@ class ShopTabCompleter implements TabCompleter { List townyShopPlots = Arrays.asList("ARENA", "COMMERCIAL", "EMBASSY", "FARM", "INN", "JAIL", "RESIDENTIAL", "SPLEEF", "WILDS"); Set configValues = plugin.getConfig().getKeys(true); + List playerNames = Bukkit.getOnlinePlayers().stream().map(Player::getName).collect(Collectors.toList()); ArrayList returnCompletions = new ArrayList<>(); @@ -45,6 +50,18 @@ class ShopTabCompleter implements TabCompleter { } else { return configSubCommands; } + } else if (args[0].equals("removeall")) { + if (!args[1].equals("")) { + for (String name : playerNames) { + if (name.startsWith(args[1])) { + returnCompletions.add(name); + } + } + + return returnCompletions; + } else { + return playerNames; + } } } else if (args.length == 3) { if (args[0].equals("config")) { diff --git a/src/main/java/de/epiceric/shopchest/sql/Database.java b/src/main/java/de/epiceric/shopchest/sql/Database.java index 64630dc..f59fa83 100644 --- a/src/main/java/de/epiceric/shopchest/sql/Database.java +++ b/src/main/java/de/epiceric/shopchest/sql/Database.java @@ -403,6 +403,63 @@ public abstract class Database { }.runTaskAsynchronously(plugin); } + /** + * Get all shops of a player, including admin shops + * + * @param callback Callback that returns a set of shops of the given player + */ + public void getShops(UUID playerUuid, final Callback> callback) { + new BukkitRunnable(){ + @Override + public void run() { + try (Connection con = dataSource.getConnection(); + PreparedStatement ps = con.prepareStatement("SELECT * FROM " + tableShops + " WHERE vendor = ?")) { + ps.setString(1, playerUuid.toString()); + ResultSet rs = ps.executeQuery(); + + plugin.debug("Getting a player's shops from database"); + + Set result = new HashSet<>(); + while (rs.next()) { + int id = rs.getInt("id"); + + plugin.debug("Getting Shop... (#" + id + ")"); + + int x = rs.getInt("x"); + int y = rs.getInt("y"); + int z = rs.getInt("z"); + + World world = plugin.getServer().getWorld(rs.getString("world")); + Location location = new Location(world, x, y, z); + OfflinePlayer vendor = Bukkit.getOfflinePlayer(UUID.fromString(rs.getString("vendor"))); + ItemStack itemStack = Utils.decode(rs.getString("product")); + int amount = rs.getInt("amount"); + ShopProduct product = new ShopProduct(itemStack, amount); + double buyPrice = rs.getDouble("buyprice"); + double sellPrice = rs.getDouble("sellprice"); + ShopType shopType = ShopType.valueOf(rs.getString("shoptype")); + + plugin.debug("Initializing new shop... (#" + id + ")"); + + result.add(new Shop(id, plugin, vendor, product, location, buyPrice, sellPrice, shopType)); + } + + if (callback != null) { + callback.callSyncResult(result); + } + } catch (SQLException ex) { + if (callback != null) { + callback.callSyncError(ex); + } + + plugin.getLogger().severe("Failed to get player's shops from database"); + plugin.debug("Failed to get player's shops from database"); + plugin.debug(ex); + } + } + }.runTaskAsynchronously(plugin); + } + /** * Get all shops from the database that are located in the given chunks * diff --git a/src/main/java/de/epiceric/shopchest/utils/ShopUtils.java b/src/main/java/de/epiceric/shopchest/utils/ShopUtils.java index 6675c7b..3735e0c 100644 --- a/src/main/java/de/epiceric/shopchest/utils/ShopUtils.java +++ b/src/main/java/de/epiceric/shopchest/utils/ShopUtils.java @@ -133,22 +133,24 @@ public class ShopUtils { public void removeShop(Shop shop, boolean removeFromDatabase, Callback callback) { plugin.debug("Removing shop (#" + shop.getID() + ")"); - InventoryHolder ih = shop.getInventoryHolder(); + if (shop.isCreated()) { + InventoryHolder ih = shop.getInventoryHolder(); - if (ih instanceof DoubleChest) { - DoubleChest dc = (DoubleChest) ih; - Chest r = (Chest) dc.getRightSide(); - Chest l = (Chest) dc.getLeftSide(); + if (ih instanceof DoubleChest) { + DoubleChest dc = (DoubleChest) ih; + Chest r = (Chest) dc.getRightSide(); + Chest l = (Chest) dc.getLeftSide(); - shopLocation.remove(r.getLocation()); - shopLocation.remove(l.getLocation()); - } else { - shopLocation.remove(shop.getLocation()); + shopLocation.remove(r.getLocation()); + shopLocation.remove(l.getLocation()); + } else { + shopLocation.remove(shop.getLocation()); + } + + shop.removeItem(); + shop.removeHologram(); } - shop.removeItem(); - shop.removeHologram(); - if (removeFromDatabase) { if (shop.getShopType() != ShopType.ADMIN) { playerShopAmount.compute(shop.getVendor().getUniqueId(), (uuid, amount) -> amount == null ? new Counter() : amount.decrement()); @@ -268,6 +270,34 @@ public class ShopUtils { return playerShopAmount.getOrDefault(p.getUniqueId(), new Counter()).get(); } + /** + * Get all shops of a player from the database without loading them + * @param p Player, whose shops should be get + * @param callback Callback that returns a collection of the given player's shops + */ + public void getShops(OfflinePlayer p, Callback> callback) { + plugin.getShopDatabase().getShops(p.getUniqueId(), new Callback>(plugin) { + @Override + public void onResult(Collection result) { + Set shops = new HashSet<>(); + for (Shop playerShop : result) { + Shop loadedShop = getShop(playerShop.getLocation()); + if (loadedShop != null && loadedShop.equals(playerShop)) { + shops.add(loadedShop); + } else { + shops.add(playerShop); + } + } + if (callback != null) callback.onResult(shops); + } + + @Override + public void onError(Throwable throwable) { + if (callback != null) callback.onError(throwable); + } + }); + } + /** * Loads the amount of shops for each player * @param callback Callback that returns the amount of shops for each player