diff --git a/pom.xml b/pom.xml index 8360147..6995dc6 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,4 @@ - + 4.0.0 de.iani.cubeside TreasureChest @@ -10,23 +9,23 @@ - spigotmc-repo - https://hub.spigotmc.org/nexus/content/groups/public + brokkonaut + https://www.iani.de/nexus/content/groups/public + + + papermc + https://repo.papermc.io/repository/maven-public/ jitpack.io https://jitpack.io - - brokko-repo - https://www.iani.de/nexus/content/groups/public - - org.spigotmc - spigot-api - 1.15-R0.1-SNAPSHOT + io.papermc.paper + paper-api + 1.19.3-R0.1-SNAPSHOT provided @@ -41,14 +40,19 @@ 1.7 provided + + de.iani.cubeside + CubesideUtilsBukkit + 1.16-SNAPSHOT + provided + - ${project.name} + TreasureChest - org.apache.maven.plugins maven-compiler-plugin - 3.11.0 + 3.10.1 17 diff --git a/src/main/java/de/iani/treasurechest/ChestInventoryListener.java b/src/main/java/de/iani/treasurechest/ChestInventoryListener.java deleted file mode 100644 index b702859..0000000 --- a/src/main/java/de/iani/treasurechest/ChestInventoryListener.java +++ /dev/null @@ -1,301 +0,0 @@ -package de.iani.treasurechest; - -import de.iani.treasurechest.PlayerTreasureChestContent.LoadState; -import de.iani.treasurechest.database.DatabaseTreasureChestItem; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.logging.Level; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.Sound; -import org.bukkit.block.Block; -import org.bukkit.block.BlockState; -import org.bukkit.block.ShulkerBox; -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.inventory.InventoryAction; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.inventory.InventoryCloseEvent; -import org.bukkit.event.inventory.InventoryDragEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.BlockStateMeta; -import org.bukkit.inventory.meta.Damageable; -import org.bukkit.inventory.meta.ItemMeta; - -public class ChestInventoryListener implements Listener { - private TreasureChest plugin; - - HashMap openInventories = new HashMap<>(); - - public ChestInventoryListener(TreasureChest plugin) { - this.plugin = plugin; - } - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onChestOpen(PlayerInteractEvent e) { - if (plugin.getChestLocation() == null) { - return; - } - Block b = e.getClickedBlock(); - if (e.getAction() == Action.RIGHT_CLICK_BLOCK && b != null && b.getLocation().equals(plugin.getChestLocation())) { - e.setCancelled(true); - if (!e.getPlayer().hasPermission("treasurechest.access")) { - plugin.sendMessage(e.getPlayer(), "Du hast keinen Zugriff auf die Schatztruhe!"); - return; - } - if (openInventories.containsKey(e.getPlayer())) { - return;// ist schon offen? - } - - PlayerTreasureChestContent content = plugin.getData().getChestContent(e.getPlayer().getUniqueId()); - if (content != null && content.getLoadState() != LoadState.LOADED) { - content.loadAsync(); - return; - } - if (content == null || content.isEmpty()) { - plugin.sendMessage(e.getPlayer(), "Deine Schatztruhe ist leer!"); - return; - } - Inventory inventory = plugin.getServer().createInventory(null, 9 * 6, "Schatztruhe"); - OpenInventoryData openInventory = new OpenInventoryData(b.getLocation(), inventory); - - int pos = 0; - for (DatabaseTreasureChestItem item : content.getItems()) { - if (pos < 9 * 6) { - ItemStack di = item.getDisplayItem().clone(); - ItemMeta meta = di.getItemMeta(); - ItemStack[] priceList = item.getPriceItems(); - ArrayList lore = new ArrayList<>(); - if (priceList != null) { - for (ItemStack stack : priceList) { - StringBuilder t = new StringBuilder(); - if (stack.getAmount() > 1) { - t.append(stack.getAmount()).append(" "); - } - t.append(TreasureChest.capitalize(stack.getType().name(), true)); - ItemMeta stackMeta = stack.getItemMeta(); - if (stackMeta instanceof Damageable) { - Damageable damageable = (Damageable) stackMeta; - if (damageable.hasDamage()) { - t.append(':').append(damageable.getDamage()); - } - } - if (stackMeta.hasDisplayName()) { - t.append(" (benanntes Item)"); - } - lore.add(t.toString()); - } - } - if (item.getPriceMoney() > 0) { - lore.add(plugin.formatMoney(item.getPriceMoney())); - } - meta.setLore(lore); - di.setItemMeta(meta); - inventory.setItem(pos, di); - openInventory.setItemAtPosition(pos, item.getId()); - } - pos += 1; - } - - e.getPlayer().openInventory(inventory); - openInventories.put(e.getPlayer(), openInventory); - e.getPlayer().playSound(b.getLocation(), Sound.BLOCK_CHEST_OPEN, 0.5f, 0.9f); - } - } - - @EventHandler(priority = EventPriority.HIGH) - public void onInventoryClick(InventoryClickEvent event) { - OpenInventoryData openInventory = openInventories.get(event.getWhoClicked()); - if (openInventory == null) { - return; - } - - InventoryAction action = event.getAction(); - switch (action) { - case PICKUP_ALL: - case PICKUP_HALF: - case PICKUP_SOME: - case PICKUP_ONE: { - event.setCancelled(true); - if (event.getRawSlot() < event.getView().getTopInventory().getSize() && event.getWhoClicked() instanceof Player) { - Player player = (Player) event.getWhoClicked(); - - ItemStack[] playerInv = player.getInventory().getContents(); - playerInv = Arrays.copyOf(playerInv, 36); - Inventory clonedPlayerInventory = Bukkit.createInventory(null, 36); - clonedPlayerInventory.setContents(playerInv); - - PlayerTreasureChestContent content = plugin.getData().getChestContent(player.getUniqueId()); - Integer entryId = openInventory.getEntryAtPosition(event.getRawSlot()); - if (entryId == null) { - return; - } - TreasureChestItem selectedItem = content.getItem(entryId); - if (selectedItem != null) { - ItemStack[] priceList = selectedItem.getPriceItems(); - int priceMoney = Math.max(selectedItem.getPriceMoney(), 0); - TreasurePayoutEvent payoutEvent = new TreasurePayoutEvent(player, priceList == null || priceList.length == 0 ? Collections.emptyList() : Arrays.asList(priceList), priceMoney); - - int priceCount = payoutEvent.getItems().size(); - if (priceCount > 0) { - ItemStack[] temp = new ItemStack[priceCount]; - for (int i = 0; i < priceCount; i++) { - temp[i] = payoutEvent.getItems().get(i).clone(); - } - if (addItemsToInventory(clonedPlayerInventory, temp) == null) { - plugin.sendMessage(player, "Du hast nicht genügend Platz in deinem Inventar!", true); - return; - } - } - plugin.getServer().getPluginManager().callEvent(payoutEvent); - if (payoutEvent.isCancelled()) { - return; - } - try { - if (!plugin.getDatabase().deleteItem(player.getUniqueId(), entryId)) { - return; - } - } catch (SQLException e) { - plugin.sendMessage(player, ChatColor.DARK_RED + "Datenbankfehler"); - plugin.getLogger().log(Level.SEVERE, "Could not delete item " + entryId + " for " + player.getUniqueId() + ": " + e.getMessage(), e); - return; - } - plugin.sendMessage(player, ChatColor.GRAY + "Du hast folgende Items erhalten:"); - if (priceCount > 0) { - ItemStack[] temp = new ItemStack[priceCount]; - for (int i = 0; i < priceCount; i++) { - temp[i] = payoutEvent.getItems().get(i).clone(); - } - FilledInventory filledInventory = addItemsToInventory(player.getInventory(), temp); - for (ItemStack stack : payoutEvent.getItems()) { - StringBuilder t = new StringBuilder(" "); - if (stack.getAmount() > 1) { - t.append(stack.getAmount()).append(" "); - } - t.append(TreasureChest.capitalize(stack.getType().name(), true)); - ItemMeta stackMeta = stack.getItemMeta(); - if (stackMeta instanceof Damageable) { - Damageable damageable = (Damageable) stackMeta; - if (damageable.hasDamage()) { - t.append(':').append(damageable.getDamage()); - } - } - if (stackMeta.hasDisplayName()) { - t.append(" (").append(stackMeta.getDisplayName()).append(ChatColor.YELLOW).append(")"); - } - plugin.sendMessage(player, t.toString()); - } - if (filledInventory == FilledInventory.ShulkerBox) { - plugin.sendMessage(player, "Die Items wurden in eine leere Shulker-Kiste in deinem Inventar gelegt."); - } - } - int money = payoutEvent.getMoney(); - if (money > 0) { - plugin.giveMoney(player, money); - plugin.sendMessage(player, " " + plugin.formatMoney(money)); - } - - player.playSound(event.getWhoClicked().getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1f, 1f); - content.removeItem(entryId); - openInventory.getInventory().setItem(event.getRawSlot(), null); - openInventory.removeEntryAtPosition(event.getRawSlot()); - player.updateInventory(); - } - } - } - case CLONE_STACK: - case COLLECT_TO_CURSOR: - case DROP_ALL_CURSOR: - case DROP_ALL_SLOT: - case DROP_ONE_CURSOR: - case DROP_ONE_SLOT: - case HOTBAR_MOVE_AND_READD: - case HOTBAR_SWAP: - case UNKNOWN: - default: { - Player player = (Player) event.getWhoClicked(); - player.updateInventory(); - event.setCancelled(true); - return; - } - } - } - - @EventHandler(priority = EventPriority.HIGH) - public void onInventoryDrag(InventoryDragEvent event) { - if (openInventories.containsKey(event.getWhoClicked())) { - event.setCancelled(true); - } - } - - @EventHandler - public void onInventoryClose(InventoryCloseEvent e) { - OpenInventoryData data = openInventories.remove(e.getPlayer()); - if (data != null) { - ((Player) e.getPlayer()).playSound(data.getLocation(), Sound.BLOCK_CHEST_CLOSE, 0.5f, 0.9f); - } - } - - @EventHandler - public void onPlayerQuit(PlayerQuitEvent event) { - openInventories.remove(event.getPlayer()); - } - - private FilledInventory addItemsToInventory(Inventory inventory, ItemStack[] items) { - int itemCount = 0; - for (ItemStack itemStack : items) { - if (itemStack != null && itemStack.getType() != Material.AIR) { - itemCount++; - } - } - - int inventorySpace = 0; - for (ItemStack shulkerItem : inventory.getContents()) { - if (shulkerItem == null || shulkerItem.getType() == Material.AIR) { - inventorySpace++; - } - } - if (inventorySpace >= itemCount) { - inventory.addItem(items); - return FilledInventory.PlayerInventory; - } - - for (ItemStack inventoryItemStack : inventory.getContents()) { - if (inventoryItemStack != null) { - if (inventoryItemStack.getItemMeta() instanceof BlockStateMeta blockStateMeta) { - BlockState blockState = blockStateMeta.getBlockState(); - if (blockState instanceof ShulkerBox shulkerBox) { - ItemStack[] shulkerContents = shulkerBox.getSnapshotInventory().getStorageContents(); - boolean shulkerEmpty = true; - for (ItemStack shulkerItem : shulkerContents) { - if (shulkerItem != null && shulkerItem.getType() != Material.AIR) { - shulkerEmpty = false; - } - } - if (shulkerEmpty) { - shulkerBox.getSnapshotInventory().setStorageContents(items); - blockStateMeta.setBlockState(blockState); - inventoryItemStack.setItemMeta(blockStateMeta); - return FilledInventory.ShulkerBox; - } - } - } - } - } - return null; - } - - private enum FilledInventory { - PlayerInventory, ShulkerBox - } -} diff --git a/src/main/java/de/iani/treasurechest/Converter.java b/src/main/java/de/iani/treasurechest/Converter.java deleted file mode 100644 index bd2664c..0000000 --- a/src/main/java/de/iani/treasurechest/Converter.java +++ /dev/null @@ -1,98 +0,0 @@ -package de.iani.treasurechest; - -import java.io.File; -import java.io.FileFilter; -import java.util.ArrayList; -import java.util.UUID; -import java.util.logging.Level; - -import org.bukkit.Material; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -public class Converter { - - private TreasureChest plugin; - - public Converter(TreasureChest plugin) { - this.plugin = plugin; - } - - public void convertAll() { - File chestContentFolder = new File(this.plugin.getDataFolder(), "content"); - if (!chestContentFolder.isDirectory()) { - return; - } - File[] treasureChestFiles = chestContentFolder.listFiles(new FileFilter() { - @Override - public boolean accept(File pathname) { - return pathname.getName().endsWith(".yml"); - } - }); - plugin.getLogger().info("Konvertiere " + treasureChestFiles.length + " Dateien"); - int i = 0; - for (File file : treasureChestFiles) { - try { - UUID owner = UUID.fromString(file.getName().substring(0, file.getName().length() - 4)); - convertPlayer(owner, file); - } catch (Exception e) { - plugin.getLogger().log(Level.SEVERE, "Could not convert " + file.getName() + ": " + e.getMessage(), e); - } - i++; - if (i % 100 == 0) { - plugin.getLogger().info(i + "/" + treasureChestFiles.length); - } - } - if (chestContentFolder.listFiles().length == 0) { - chestContentFolder.delete(); - } - plugin.getLogger().info(i + "/" + treasureChestFiles.length); - - File uuidFile = new File(plugin.getDataFolder(), "playerUUIDs.yml"); - if (uuidFile.exists()) { - uuidFile.delete(); - } - } - - public void convertPlayer(UUID owner, File file) { - try { - if (file.exists()) { - YamlConfiguration conf = YamlConfiguration.loadConfiguration(file); - - ConfigurationSection prices = conf.getConfigurationSection("prices"); - if (prices != null) { - for (String e : prices.getKeys(false)) { - ConfigurationSection price = prices.getConfigurationSection(e); - if (price != null) { - ItemStack display = price.getItemStack("displayItem"); - if (display == null) { - display = new ItemStack(Material.BEDROCK); - ItemMeta meta = display.getItemMeta(); - meta.setDisplayName("Unset displayitem"); - display.setItemMeta(meta); - } - int priceMoney = price.getInt("priceMoney"); - ArrayList priceItems = new ArrayList<>(); - ConfigurationSection itemPricesSection = price.getConfigurationSection("itemPrices"); - if (itemPricesSection != null) { - for (String pricee : itemPricesSection.getKeys(false)) { - ItemStack priceItem = itemPricesSection.getItemStack(pricee); - if (priceItem != null) { - priceItems.add(priceItem); - } - } - } - TreasureChestItem item = new TreasureChestItem(display, priceItems.toArray(new ItemStack[priceItems.size()]), priceMoney); - plugin.getDatabase().addItem(owner, item); - } - } - } - } - } catch (Exception e) { - plugin.getLogger().log(Level.SEVERE, "Could not load user chest file: " + file.getName(), e); - } - file.delete(); - } -} diff --git a/src/main/java/de/iani/treasurechest/OpenInventoryData.java b/src/main/java/de/iani/treasurechest/OpenInventoryData.java index 03fb34b..6daa0d6 100644 --- a/src/main/java/de/iani/treasurechest/OpenInventoryData.java +++ b/src/main/java/de/iani/treasurechest/OpenInventoryData.java @@ -1,7 +1,6 @@ package de.iani.treasurechest; import java.util.Arrays; - import org.bukkit.Location; import org.bukkit.inventory.Inventory; diff --git a/src/main/java/de/iani/treasurechest/Permissions.java b/src/main/java/de/iani/treasurechest/Permissions.java new file mode 100644 index 0000000..b154d9c --- /dev/null +++ b/src/main/java/de/iani/treasurechest/Permissions.java @@ -0,0 +1,9 @@ +package de.iani.treasurechest; + +public class Permissions { + public static final String SET_CHEST = "treasurechest.setchest"; + public static final String CREATE = "treasurechest.create"; + public static final String GIVE = "treasurechest.give"; + public static final String LIST = "treasurechest.list"; + public static final String REMOVE = "treasurechest.remove"; +} diff --git a/src/main/java/de/iani/treasurechest/PlayerEventListener.java b/src/main/java/de/iani/treasurechest/PlayerEventListener.java deleted file mode 100644 index 915f2c5..0000000 --- a/src/main/java/de/iani/treasurechest/PlayerEventListener.java +++ /dev/null @@ -1,27 +0,0 @@ -package de.iani.treasurechest; - -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerQuitEvent; - -public class PlayerEventListener implements Listener { - private TreasureChest plugin; - - public PlayerEventListener(TreasureChest plugin) { - this.plugin = plugin; - } - - @EventHandler - public void onPlayerJoin(PlayerJoinEvent event) { - plugin.getData().reloadTreasureChest(event.getPlayer().getUniqueId()); - } - - @EventHandler - public void onPlayerQuit(PlayerQuitEvent event) { - plugin.getData().removeActiveItem(event.getPlayer().getUniqueId()); - plugin.getData().unloadTreasureChest(event.getPlayer().getUniqueId()); - plugin.getData().removeListedItems(event.getPlayer().getUniqueId()); - } - -} diff --git a/src/main/java/de/iani/treasurechest/PlayerTreasureChestContent.java b/src/main/java/de/iani/treasurechest/PlayerTreasureChestContent.java index 376ea17..f28e169 100644 --- a/src/main/java/de/iani/treasurechest/PlayerTreasureChestContent.java +++ b/src/main/java/de/iani/treasurechest/PlayerTreasureChestContent.java @@ -1,5 +1,6 @@ package de.iani.treasurechest; +import de.iani.treasurechest.database.DatabaseTreasureChestItem; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; @@ -7,13 +8,8 @@ import java.util.List; import java.util.UUID; import java.util.logging.Level; - import org.bukkit.scheduler.BukkitRunnable; -import de.iani.treasurechest.database.DatabaseTreasureChestItem; -import de.iani.treasurechest.database.TreasureChestDatabase; -import de.iani.treasurechest.worker.WorkEntry; - public class PlayerTreasureChestContent { private final TreasureChest plugin; private final UUID owner; @@ -48,32 +44,29 @@ return; } loadState = LoadState.LOADING; - plugin.getWorkerThread().addWork(new WorkEntry() { - @Override - public void process(TreasureChestDatabase database) { - try { - ArrayList loadedItems = plugin.getDatabase().getPlayerItems(owner); - new BukkitRunnable() { - @Override - public void run() { - items = loadedItems; - itemsById = new HashMap<>(); - for (DatabaseTreasureChestItem i : items) { - itemsById.put(i.getId(), i); - } - loadState = LoadState.LOADED; - - if (loadCallbacks != null) { - for (Runnable r : loadCallbacks) { - r.run(); - } - loadCallbacks = null; - } + plugin.getWorkerThread().addWork(database -> { + try { + ArrayList loadedItems = plugin.getDatabase().getPlayerItems(owner); + new BukkitRunnable() { + @Override + public void run() { + items = loadedItems; + itemsById = new HashMap<>(); + for (DatabaseTreasureChestItem i : items) { + itemsById.put(i.getId(), i); } - }.runTask(plugin); - } catch (SQLException e) { - plugin.getLogger().log(Level.SEVERE, "Could not load treasure chest data for " + owner + ": " + e, e); - } + loadState = LoadState.LOADED; + + if (loadCallbacks != null) { + for (Runnable r : loadCallbacks) { + r.run(); + } + loadCallbacks = null; + } + } + }.runTask(plugin); + } catch (SQLException e) { + plugin.getLogger().log(Level.SEVERE, "Could not load treasure chest data for " + owner + ": " + e, e); } }); } @@ -120,6 +113,8 @@ } public enum LoadState { - NOT_LOADED, LOADING, LOADED + NOT_LOADED, + LOADING, + LOADED } } diff --git a/src/main/java/de/iani/treasurechest/TreasureChest.java b/src/main/java/de/iani/treasurechest/TreasureChest.java index c99cc54..ac68daf 100644 --- a/src/main/java/de/iani/treasurechest/TreasureChest.java +++ b/src/main/java/de/iani/treasurechest/TreasureChest.java @@ -1,12 +1,22 @@ package de.iani.treasurechest; +import de.iani.cubesideutils.bukkit.commands.CommandRouter; import de.iani.playerUUIDCache.CachedPlayer; import de.iani.playerUUIDCache.PlayerUUIDCache; import de.iani.treasurechest.PlayerTreasureChestContent.LoadState; +import de.iani.treasurechest.commands.AddItemCommand; +import de.iani.treasurechest.commands.AddMoneyCommand; +import de.iani.treasurechest.commands.CreateCommand; +import de.iani.treasurechest.commands.GiveCommand; +import de.iani.treasurechest.commands.HelpCommand; +import de.iani.treasurechest.commands.ListCommand; +import de.iani.treasurechest.commands.RemoveCommand; +import de.iani.treasurechest.commands.SetChestCommand; import de.iani.treasurechest.database.DatabaseTreasureChestItem; import de.iani.treasurechest.database.SQLConfig; import de.iani.treasurechest.database.TreasureChestDatabase; -import de.iani.treasurechest.worker.WorkEntry; +import de.iani.treasurechest.listener.ChestInventoryListener; +import de.iani.treasurechest.listener.PlayerEventListener; import de.iani.treasurechest.worker.WorkerThread; import java.sql.SQLException; import java.util.ArrayList; @@ -63,28 +73,25 @@ return; } - new Converter(this).convertAll(); - workerThread = new WorkerThread(this); data = new TreasureChestData(this); - getCommand("treasurechest").setExecutor(new TreasureChestCommandExecutor(this)); + CommandRouter treasurechestCommand = new CommandRouter(getCommand("treasurechest")); + treasurechestCommand.addCommandMapping(new HelpCommand(this)); + treasurechestCommand.addCommandMapping(new HelpCommand(this), "help"); + treasurechestCommand.addCommandMapping(new SetChestCommand(this), "setchest"); + treasurechestCommand.addCommandMapping(new CreateCommand(this), "create"); + treasurechestCommand.addCommandMapping(new AddItemCommand(this), "additem"); + treasurechestCommand.addCommandMapping(new AddMoneyCommand(this), "addmoney"); + treasurechestCommand.addCommandMapping(new GiveCommand(this), "give"); + treasurechestCommand.addCommandMapping(new ListCommand(this), "list"); + treasurechestCommand.addCommandMapping(new RemoveCommand(this), "remove"); getServer().getPluginManager().registerEvents(new ChestInventoryListener(this), this); getServer().getPluginManager().registerEvents(new PlayerEventListener(this), this); - getServer().getScheduler().runTaskTimer(this, new Runnable() { - @Override - public void run() { - createParticles(); - } - }, 1, 1); - getServer().getScheduler().runTaskTimer(this, new Runnable() { - @Override - public void run() { - data.doGC(); - } - }, 8456, 140000); + getServer().getScheduler().runTaskTimer(this, this::createParticles, 1, 1); + getServer().getScheduler().runTaskTimer(this, data::doGC, 8456, 140000); } @Override @@ -137,25 +144,22 @@ items = copied.toArray(new ItemStack[copied.size()]); } TreasureChestItem item = new TreasureChestItem(displayItem, items, money); - workerThread.addWork(new WorkEntry() { - @Override - public void process(TreasureChestDatabase database) { - try { - DatabaseTreasureChestItem added = database.addItem(player, item); - if (added != null) { - new BukkitRunnable() { - @Override - public void run() { - PlayerTreasureChestContent cc = getData().getChestContent(player); - if (cc != null && cc.getLoadState() == LoadState.LOADED) { - cc.addItem(added); - } + workerThread.addWork(database -> { + try { + DatabaseTreasureChestItem added = database.addItem(player, item); + if (added != null) { + new BukkitRunnable() { + @Override + public void run() { + PlayerTreasureChestContent cc = getData().getChestContent(player); + if (cc != null && cc.getLoadState() == LoadState.LOADED) { + cc.addItem(added); } - }.runTask(TreasureChest.this); - } - } catch (SQLException e) { - getLogger().log(Level.SEVERE, "Could not add treasure chest item to database: " + e.getMessage(), e); + } + }.runTask(TreasureChest.this); } + } catch (SQLException e) { + getLogger().log(Level.SEVERE, "Could not add treasure chest item to database: " + e.getMessage(), e); } }); return true; @@ -286,29 +290,6 @@ return Integer.toString(amount); } - public static String capitalize(String s, boolean replaceUnderscores) { - char[] cap = s.toCharArray(); - boolean lastSpace = true; - for (int i = 0; i < cap.length; i++) { - if (cap[i] == '_') { - if (replaceUnderscores) { - cap[i] = ' '; - } - lastSpace = true; - } else if (cap[i] >= '0' && cap[i] <= '9') { - lastSpace = true; - } else { - if (lastSpace) { - cap[i] = Character.toUpperCase(cap[i]); - } else { - cap[i] = Character.toLowerCase(cap[i]); - } - lastSpace = false; - } - } - return new String(cap); - } - public TreasureChestDatabase getDatabase() { return database; } diff --git a/src/main/java/de/iani/treasurechest/TreasureChestCommandExecutor.java b/src/main/java/de/iani/treasurechest/TreasureChestCommandExecutor.java deleted file mode 100644 index 206cf8e..0000000 --- a/src/main/java/de/iani/treasurechest/TreasureChestCommandExecutor.java +++ /dev/null @@ -1,279 +0,0 @@ -package de.iani.treasurechest; - -import java.sql.SQLException; -import java.util.List; -import java.util.Set; -import java.util.logging.Level; - -import org.bukkit.ChatColor; -import org.bukkit.Effect; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; - -import de.iani.playerUUIDCache.CachedPlayer; -import de.iani.treasurechest.PlayerTreasureChestContent.LoadState; -import de.iani.treasurechest.database.DatabaseTreasureChestItem; - -public class TreasureChestCommandExecutor implements CommandExecutor { - private TreasureChest plugin; - - public TreasureChestCommandExecutor(TreasureChest plugin) { - this.plugin = plugin; - } - - @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { - if (args.length == 0) { - displayHelp(sender, label); - } else { - String subcommand = args[0].toLowerCase(); - if (subcommand.equals("setchest")) { - if (!checkPlayer(sender) || !checkPermission(sender, "treasurechest.setchest")) { - return true; - } - Player player = ((Player) sender); - Block target = player.getTargetBlock((Set) null, 5); - plugin.setChestLocation(target == null ? null : target.getLocation()); - if (target != null) { - player.playEffect(target.getLocation(), Effect.MOBSPAWNER_FLAMES, null); - player.playEffect(target.getLocation(), Effect.MOBSPAWNER_FLAMES, null); - player.playEffect(target.getLocation(), Effect.MOBSPAWNER_FLAMES, null); - plugin.sendMessage(sender, "Treasurechest location set!"); - } else { - plugin.sendMessage(sender, "Treasurechest location removed!"); - } - } else if (subcommand.equals("create")) { - if (!checkPlayer(sender) || !checkPermission(sender, "treasurechest.create")) { - return true; - } - Player player = ((Player) sender); - ItemStack inHand = player.getInventory().getItemInMainHand(); - if (inHand == null || inHand.getType() == Material.AIR || inHand.getAmount() == 0) { - plugin.sendMessage(sender, "You have to hold the display item in hand!", true); - return true; - } - TreasureChestItem newItem = new TreasureChestItem(inHand.clone(), null, 0); - plugin.getData().setActiveItem(player.getUniqueId(), newItem); - plugin.sendMessage(sender, "Created a new Treasurechest item!"); - } else if (subcommand.equals("addmoney")) { - if (!checkPlayer(sender) || !checkPermission(sender, "treasurechest.create")) { - return true; - } - if (args.length < 2) { - plugin.sendMessage(sender, "/" + label + " addmoney ", true); - return true; - } - int amount = getIntArgument(args[1], 0); - Player player = ((Player) sender); - TreasureChestItem activeItem = plugin.getData().getActiveItem(player.getUniqueId()); - if (activeItem == null) { - plugin.sendMessage(sender, "You have no active item!", true); - return true; - } - activeItem.setPriceMoney(activeItem.getPriceMoney() + amount); - plugin.sendMessage(sender, "Set the money to " + activeItem.getPriceMoney()); - } else if (subcommand.equals("additem")) { - if (!checkPlayer(sender) || !checkPermission(sender, "treasurechest.create")) { - return true; - } - Player player = ((Player) sender); - ItemStack inHand = player.getInventory().getItemInMainHand(); - if (inHand == null || inHand.getType() == Material.AIR || inHand.getAmount() == 0) { - plugin.sendMessage(sender, "You have to hold the item in hand!", true); - return true; - } - TreasureChestItem activeItem = plugin.getData().getActiveItem(player.getUniqueId()); - if (activeItem == null) { - plugin.sendMessage(sender, "You have no active item!", true); - return true; - } - activeItem.addPriceItem(inHand.clone()); - plugin.sendMessage(sender, "Item added: " + inHand.getAmount() + " " + TreasureChest.capitalize(inHand.getType().name(), true)); - } else if (subcommand.equals("give")) { - if (!checkPlayer(sender) || !checkPermission(sender, "treasurechest.give")) { - return true; - } - if (args.length < 2) { - plugin.sendMessage(sender, "/" + label + " give ", true); - return true; - } - Player player = ((Player) sender); - TreasureChestItem activeItem = plugin.getData().getActiveItem(player.getUniqueId()); - if (activeItem == null) { - plugin.sendMessage(sender, "You have no active item!", true); - return true; - } - - for (int arg = 1; arg < args.length; arg++) { - String nameOrId = args[arg].replace(",", "").trim(); - CachedPlayer target = plugin.getPlayerUUIDCache().getPlayerFromNameOrUUID(nameOrId); - if (target == null) { - plugin.sendMessage(sender, "Unknown player!", true); - } else { - plugin.addItem(target, activeItem.getDisplayItem(), activeItem.getPriceItems(), activeItem.getPriceMoney()); - plugin.sendMessage(sender, "Item given to: " + target.getName()); - } - } - return true; - } else if (subcommand.equals("list")) { - if (!checkPermission(sender, "treasurechest.list")) { - return true; - } - if (args.length < 2) { - plugin.sendMessage(sender, "/" + label + " list ", true); - return true; - } - CachedPlayer target = plugin.getPlayerUUIDCache().getPlayerFromNameOrUUID(args[1], true); - if (target == null) { - plugin.sendMessage(sender, "Unknown player!", true); - return true; - } - - PlayerTreasureChestContent content = plugin.getData().getOrCreateChestContent(target.getUniqueId()); - content.loadAsync(new Runnable() { - @Override - public void run() { - plugin.sendMessage(sender, ChatColor.GRAY + "Preise von " + target.getName() + " (" + target.getUniqueId().toString() + "):"); - List items = content.getItems(); - if (items.isEmpty()) { - plugin.sendMessage(sender, "keine Preise vorhanden"); - } else { - ListedItemsData lid = new ListedItemsData(target.getUniqueId()); - int nr = 1; - for (DatabaseTreasureChestItem i : items) { - plugin.sendMessage(sender, nr + ": " + i.getDisplayItem().getItemMeta().getDisplayName()); - lid.addItem(nr, i.getId()); - nr++; - } - if (sender instanceof Player) { - Player player = ((Player) sender); - plugin.getData().setListedItems(player.getUniqueId(), lid); - } else { - plugin.getData().setListedItems(null, lid); - } - } - } - }); - } else if (subcommand.equals("remove")) { - if (!checkPermission(sender, "treasurechest.remove")) { - return true; - } - if (args.length < 3) { - plugin.sendMessage(sender, "/" + label + " remove ", true); - return true; - } - - CachedPlayer target = plugin.getPlayerUUIDCache().getPlayerFromNameOrUUID(args[1], true); - - if (target == null) { - plugin.sendMessage(sender, "Unknown player!", true); - return true; - } - int nr = getIntArgument(args[2], -1); - - ListedItemsData lid; - if (sender instanceof Player) { - Player player = ((Player) sender); - lid = plugin.getData().getListedItems(player.getUniqueId()); - } else { - lid = plugin.getData().getListedItems(null); - } - if (lid == null || !lid.getOwner().equals(target.getUniqueId())) { - plugin.sendMessage(sender, "Nicht der gelistete Spieler", true); - return true; - } - Integer key = lid.getItemDatabaseKey(nr); - if (key == null) { - plugin.sendMessage(sender, "Ungültige ID", true); - return true; - } - try { - if (plugin.getDatabase().deleteItem(target.getUniqueId(), key)) { - PlayerTreasureChestContent content = plugin.getData().getChestContent(target.getUniqueId()); - if (content != null && content.getLoadState() == LoadState.LOADED) { - content.removeItem(key); - } - } else { - plugin.sendMessage(sender, "Ungültige ID", true); - return true; - } - } catch (SQLException e) { - plugin.sendMessage(sender, ChatColor.DARK_RED + "Datenbankfehler"); - plugin.getLogger().log(Level.SEVERE, "Could not delete item " + key + " for " + target.getName() + ": " + e.getMessage(), e); - return true; - } - plugin.sendMessage(sender, "Der Preis wurde entfernt!"); - } else { - plugin.sendMessage(sender, "Unknown subcommand!", true); - return true; - } - } - return true; - } - - private void displayHelp(CommandSender sender, String label) { - plugin.sendMessage(sender, ChatColor.GREEN + "Commands"); - if (checkPlayer(sender, true) && checkPermission(sender, "treasurechest.setchest", true)) { - plugin.sendMessage(sender, "/" + label + " setchest"); - plugin.sendMessage(sender, ChatColor.GREEN + " Set the treasure chest location to the location you are looking at."); - } - if (checkPlayer(sender, true) && checkPermission(sender, "treasurechest.create", true)) { - plugin.sendMessage(sender, "/" + label + " create"); - plugin.sendMessage(sender, ChatColor.GREEN + " Creates a price with the item in hand as display item."); - plugin.sendMessage(sender, "/" + label + " additem"); - plugin.sendMessage(sender, ChatColor.GREEN + " Adds the item in hand to the price."); - plugin.sendMessage(sender, "/" + label + " addmoney "); - plugin.sendMessage(sender, ChatColor.GREEN + " Adds money to a price."); - } - if (checkPlayer(sender, true) && checkPermission(sender, "treasurechest.give", true)) { - plugin.sendMessage(sender, "/" + label + " give "); - plugin.sendMessage(sender, ChatColor.GREEN + " Gives a price to a player."); - } - if (checkPermission(sender, "treasurechest.list")) { - plugin.sendMessage(sender, "/" + label + " list "); - plugin.sendMessage(sender, ChatColor.GREEN + " Gives price for a player."); - } - if (checkPermission(sender, "treasurechest.remove")) { - plugin.sendMessage(sender, "/" + label + " remove "); - plugin.sendMessage(sender, ChatColor.GREEN + " Removes a price from a players chest."); - } - } - - private int getIntArgument(String value, int defaultValue) { - try { - return Integer.parseInt(value); - } catch (Exception e) { - // ignore - return default - } - return defaultValue; - } - - private boolean checkPermission(CommandSender sender, String perm) { - return checkPermission(sender, perm, false); - } - - private boolean checkPermission(CommandSender sender, String perm, boolean silent) { - boolean hasPermission = sender.hasPermission(perm); - if (!silent && !hasPermission) { - plugin.sendMessage(sender, "No permission!", true); - } - return hasPermission; - } - - private boolean checkPlayer(CommandSender sender) { - return checkPlayer(sender, false); - } - - private boolean checkPlayer(CommandSender sender, boolean silent) { - boolean isPlayer = sender instanceof Player; - if (!isPlayer && !silent) { - plugin.sendMessage(sender, "You must be a player!", true); - } - return isPlayer; - } -} diff --git a/src/main/java/de/iani/treasurechest/commands/AddItemCommand.java b/src/main/java/de/iani/treasurechest/commands/AddItemCommand.java new file mode 100644 index 0000000..72e585a --- /dev/null +++ b/src/main/java/de/iani/treasurechest/commands/AddItemCommand.java @@ -0,0 +1,65 @@ +package de.iani.treasurechest.commands; + +import de.iani.cubesideutils.StringUtil; +import de.iani.cubesideutils.bukkit.commands.SubCommand; +import de.iani.cubesideutils.bukkit.commands.exceptions.DisallowsCommandBlockException; +import de.iani.cubesideutils.bukkit.commands.exceptions.IllegalSyntaxException; +import de.iani.cubesideutils.bukkit.commands.exceptions.InternalCommandException; +import de.iani.cubesideutils.bukkit.commands.exceptions.NoPermissionException; +import de.iani.cubesideutils.bukkit.commands.exceptions.RequiresPlayerException; +import de.iani.cubesideutils.commands.ArgsParser; +import de.iani.treasurechest.Permissions; +import de.iani.treasurechest.TreasureChest; +import de.iani.treasurechest.TreasureChestItem; +import java.util.Collection; +import java.util.List; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class AddItemCommand extends SubCommand { + private TreasureChest plugin; + + public AddItemCommand(TreasureChest plugin) { + this.plugin = plugin; + } + + @Override + public String getRequiredPermission() { + return Permissions.CREATE; + } + + @Override + public boolean requiresPlayer() { + return true; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String alias, String commandString, ArgsParser args) throws DisallowsCommandBlockException, RequiresPlayerException, NoPermissionException, IllegalSyntaxException, InternalCommandException { + if (args.remaining() != 0) { + plugin.sendMessage(sender, commandString + getUsage(), true); + return true; + } + Player player = ((Player) sender); + ItemStack inHand = player.getInventory().getItemInMainHand(); + if (inHand == null || inHand.getType() == Material.AIR || inHand.getAmount() == 0) { + plugin.sendMessage(sender, "You have to hold the item in hand!", true); + return true; + } + TreasureChestItem activeItem = plugin.getData().getActiveItem(player.getUniqueId()); + if (activeItem == null) { + plugin.sendMessage(sender, "You have no active item!", true); + return true; + } + activeItem.addPriceItem(inHand.clone()); + plugin.sendMessage(sender, "Item added: " + inHand.getAmount() + " " + StringUtil.capitalizeFirstLetter(inHand.getType().name(), true)); + return true; + } + + @Override + public Collection onTabComplete(CommandSender sender, Command command, String alias, ArgsParser args) { + return List.of(); + } +} diff --git a/src/main/java/de/iani/treasurechest/commands/AddMoneyCommand.java b/src/main/java/de/iani/treasurechest/commands/AddMoneyCommand.java new file mode 100644 index 0000000..080dd00 --- /dev/null +++ b/src/main/java/de/iani/treasurechest/commands/AddMoneyCommand.java @@ -0,0 +1,63 @@ +package de.iani.treasurechest.commands; + +import de.iani.cubesideutils.bukkit.commands.SubCommand; +import de.iani.cubesideutils.bukkit.commands.exceptions.DisallowsCommandBlockException; +import de.iani.cubesideutils.bukkit.commands.exceptions.IllegalSyntaxException; +import de.iani.cubesideutils.bukkit.commands.exceptions.InternalCommandException; +import de.iani.cubesideutils.bukkit.commands.exceptions.NoPermissionException; +import de.iani.cubesideutils.bukkit.commands.exceptions.RequiresPlayerException; +import de.iani.cubesideutils.commands.ArgsParser; +import de.iani.treasurechest.Permissions; +import de.iani.treasurechest.TreasureChest; +import de.iani.treasurechest.TreasureChestItem; +import java.util.Collection; +import java.util.List; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class AddMoneyCommand extends SubCommand { + private TreasureChest plugin; + + public AddMoneyCommand(TreasureChest plugin) { + this.plugin = plugin; + } + + @Override + public String getRequiredPermission() { + return Permissions.CREATE; + } + + @Override + public boolean requiresPlayer() { + return true; + } + + @Override + public String getUsage() { + return ""; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String alias, String commandString, ArgsParser args) throws DisallowsCommandBlockException, RequiresPlayerException, NoPermissionException, IllegalSyntaxException, InternalCommandException { + if (args.remaining() != 1) { + plugin.sendMessage(sender, commandString + getUsage(), true); + return true; + } + int amount = args.getNext(0); + Player player = ((Player) sender); + TreasureChestItem activeItem = plugin.getData().getActiveItem(player.getUniqueId()); + if (activeItem == null) { + plugin.sendMessage(sender, "You have no active item!", true); + return true; + } + activeItem.setPriceMoney(activeItem.getPriceMoney() + amount); + plugin.sendMessage(sender, "Set the money to " + activeItem.getPriceMoney()); + return true; + } + + @Override + public Collection onTabComplete(CommandSender sender, Command command, String alias, ArgsParser args) { + return List.of(); + } +} diff --git a/src/main/java/de/iani/treasurechest/commands/CreateCommand.java b/src/main/java/de/iani/treasurechest/commands/CreateCommand.java new file mode 100644 index 0000000..1a2f36a --- /dev/null +++ b/src/main/java/de/iani/treasurechest/commands/CreateCommand.java @@ -0,0 +1,55 @@ +package de.iani.treasurechest.commands; + +import de.iani.cubesideutils.bukkit.commands.SubCommand; +import de.iani.cubesideutils.commands.ArgsParser; +import de.iani.treasurechest.Permissions; +import de.iani.treasurechest.TreasureChest; +import de.iani.treasurechest.TreasureChestItem; +import java.util.Collection; +import java.util.List; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class CreateCommand extends SubCommand { + private TreasureChest plugin; + + public CreateCommand(TreasureChest plugin) { + this.plugin = plugin; + } + + @Override + public String getRequiredPermission() { + return Permissions.CREATE; + } + + @Override + public boolean requiresPlayer() { + return true; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String alias, String commandString, ArgsParser args) { + if (args.remaining() != 0) { + plugin.sendMessage(sender, commandString + getUsage(), true); + return true; + } + Player player = ((Player) sender); + ItemStack inHand = player.getInventory().getItemInMainHand(); + if (inHand == null || inHand.getType() == Material.AIR || inHand.getAmount() == 0) { + plugin.sendMessage(sender, "You have to hold the display item in hand!", true); + return true; + } + TreasureChestItem newItem = new TreasureChestItem(inHand.clone(), null, 0); + plugin.getData().setActiveItem(player.getUniqueId(), newItem); + plugin.sendMessage(sender, "Created a new Treasurechest item!"); + return true; + } + + @Override + public Collection onTabComplete(CommandSender sender, Command command, String alias, ArgsParser args) { + return List.of(); + } +} diff --git a/src/main/java/de/iani/treasurechest/commands/GiveCommand.java b/src/main/java/de/iani/treasurechest/commands/GiveCommand.java new file mode 100644 index 0000000..5f19c64 --- /dev/null +++ b/src/main/java/de/iani/treasurechest/commands/GiveCommand.java @@ -0,0 +1,73 @@ +package de.iani.treasurechest.commands; + +import de.iani.cubesideutils.bukkit.commands.SubCommand; +import de.iani.cubesideutils.bukkit.commands.exceptions.DisallowsCommandBlockException; +import de.iani.cubesideutils.bukkit.commands.exceptions.IllegalSyntaxException; +import de.iani.cubesideutils.bukkit.commands.exceptions.InternalCommandException; +import de.iani.cubesideutils.bukkit.commands.exceptions.NoPermissionException; +import de.iani.cubesideutils.bukkit.commands.exceptions.RequiresPlayerException; +import de.iani.cubesideutils.commands.ArgsParser; +import de.iani.playerUUIDCache.CachedPlayer; +import de.iani.treasurechest.Permissions; +import de.iani.treasurechest.TreasureChest; +import de.iani.treasurechest.TreasureChestItem; +import java.util.Collection; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class GiveCommand extends SubCommand { + private TreasureChest plugin; + + public GiveCommand(TreasureChest plugin) { + this.plugin = plugin; + } + + @Override + public String getRequiredPermission() { + return Permissions.GIVE; + } + + @Override + public boolean requiresPlayer() { + return true; + } + + @Override + public String getUsage() { + return " [...]"; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String alias, String commandString, ArgsParser args) throws DisallowsCommandBlockException, RequiresPlayerException, NoPermissionException, IllegalSyntaxException, InternalCommandException { + if (args.remaining() < 1) { + plugin.sendMessage(sender, commandString + getUsage(), true); + return true; + } + Player player = ((Player) sender); + TreasureChestItem activeItem = plugin.getData().getActiveItem(player.getUniqueId()); + if (activeItem == null) { + plugin.sendMessage(sender, "You have no active item!", true); + return true; + } + + while (args.hasNext()) { + String nameOrId = args.getNext().replace(",", "").trim(); + if (nameOrId.length() > 0) { + CachedPlayer target = plugin.getPlayerUUIDCache().getPlayerFromNameOrUUID(nameOrId); + if (target == null) { + plugin.sendMessage(sender, "Unknown player: " + nameOrId, true); + } else { + plugin.addItem(target, activeItem.getDisplayItem(), activeItem.getPriceItems(), activeItem.getPriceMoney()); + plugin.sendMessage(sender, "Item given to: " + target.getName()); + } + } + } + return true; + } + + @Override + public Collection onTabComplete(CommandSender sender, Command command, String alias, ArgsParser args) { + return null; + } +} diff --git a/src/main/java/de/iani/treasurechest/commands/HelpCommand.java b/src/main/java/de/iani/treasurechest/commands/HelpCommand.java new file mode 100644 index 0000000..c137cbc --- /dev/null +++ b/src/main/java/de/iani/treasurechest/commands/HelpCommand.java @@ -0,0 +1,70 @@ +package de.iani.treasurechest.commands; + +import de.iani.cubesideutils.bukkit.commands.SubCommand; +import de.iani.cubesideutils.bukkit.commands.exceptions.DisallowsCommandBlockException; +import de.iani.cubesideutils.bukkit.commands.exceptions.IllegalSyntaxException; +import de.iani.cubesideutils.bukkit.commands.exceptions.InternalCommandException; +import de.iani.cubesideutils.bukkit.commands.exceptions.NoPermissionException; +import de.iani.cubesideutils.bukkit.commands.exceptions.RequiresPlayerException; +import de.iani.cubesideutils.commands.ArgsParser; +import de.iani.treasurechest.Permissions; +import de.iani.treasurechest.TreasureChest; +import java.util.Collection; +import java.util.List; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class HelpCommand extends SubCommand { + private TreasureChest plugin; + + public HelpCommand(TreasureChest plugin) { + this.plugin = plugin; + } + + @Override + public String getRequiredPermission() { + return null; + } + + @Override + public boolean requiresPlayer() { + return false; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String alias, String commandString, ArgsParser args) throws DisallowsCommandBlockException, RequiresPlayerException, NoPermissionException, IllegalSyntaxException, InternalCommandException { + plugin.sendMessage(sender, ChatColor.GREEN + "Commands"); + if (sender instanceof Player && sender.hasPermission(Permissions.SET_CHEST)) { + plugin.sendMessage(sender, "/" + alias + " setchest"); + plugin.sendMessage(sender, ChatColor.GREEN + " Set the treasure chest location to the location you are looking at."); + } + if (sender instanceof Player && sender.hasPermission(Permissions.CREATE)) { + plugin.sendMessage(sender, "/" + alias + " create"); + plugin.sendMessage(sender, ChatColor.GREEN + " Creates a price with the item in hand as display item."); + plugin.sendMessage(sender, "/" + alias + " additem"); + plugin.sendMessage(sender, ChatColor.GREEN + " Adds the item in hand to the price."); + plugin.sendMessage(sender, "/" + alias + " addmoney "); + plugin.sendMessage(sender, ChatColor.GREEN + " Adds money to a price."); + } + if (sender instanceof Player && sender.hasPermission(Permissions.GIVE)) { + plugin.sendMessage(sender, "/" + alias + " give "); + plugin.sendMessage(sender, ChatColor.GREEN + " Gives a price to a player."); + } + if (sender.hasPermission(Permissions.LIST)) { + plugin.sendMessage(sender, "/" + alias + " list "); + plugin.sendMessage(sender, ChatColor.GREEN + " Gives price for a player."); + } + if (sender.hasPermission(Permissions.REMOVE)) { + plugin.sendMessage(sender, "/" + alias + " remove "); + plugin.sendMessage(sender, ChatColor.GREEN + " Removes a price from a players chest."); + } + return true; + } + + @Override + public Collection onTabComplete(CommandSender sender, Command command, String alias, ArgsParser args) { + return List.of(); + } +} diff --git a/src/main/java/de/iani/treasurechest/commands/ListCommand.java b/src/main/java/de/iani/treasurechest/commands/ListCommand.java new file mode 100644 index 0000000..bd5c80d --- /dev/null +++ b/src/main/java/de/iani/treasurechest/commands/ListCommand.java @@ -0,0 +1,88 @@ +package de.iani.treasurechest.commands; + +import de.iani.cubesideutils.bukkit.commands.SubCommand; +import de.iani.cubesideutils.bukkit.commands.exceptions.DisallowsCommandBlockException; +import de.iani.cubesideutils.bukkit.commands.exceptions.IllegalSyntaxException; +import de.iani.cubesideutils.bukkit.commands.exceptions.InternalCommandException; +import de.iani.cubesideutils.bukkit.commands.exceptions.NoPermissionException; +import de.iani.cubesideutils.bukkit.commands.exceptions.RequiresPlayerException; +import de.iani.cubesideutils.commands.ArgsParser; +import de.iani.playerUUIDCache.CachedPlayer; +import de.iani.treasurechest.ListedItemsData; +import de.iani.treasurechest.Permissions; +import de.iani.treasurechest.PlayerTreasureChestContent; +import de.iani.treasurechest.TreasureChest; +import de.iani.treasurechest.database.DatabaseTreasureChestItem; +import java.util.Collection; +import java.util.List; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class ListCommand extends SubCommand { + private TreasureChest plugin; + + public ListCommand(TreasureChest plugin) { + this.plugin = plugin; + } + + @Override + public String getRequiredPermission() { + return Permissions.LIST; + } + + @Override + public boolean requiresPlayer() { + return false; + } + + @Override + public String getUsage() { + return ""; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String alias, String commandString, ArgsParser args) throws DisallowsCommandBlockException, RequiresPlayerException, NoPermissionException, IllegalSyntaxException, InternalCommandException { + if (args.remaining() != 1) { + plugin.sendMessage(sender, commandString + getUsage(), true); + return true; + } + CachedPlayer target = plugin.getPlayerUUIDCache().getPlayerFromNameOrUUID(args.getNext(), true); + if (target == null) { + plugin.sendMessage(sender, "Unknown player!", true); + return true; + } + + PlayerTreasureChestContent content = plugin.getData().getOrCreateChestContent(target.getUniqueId()); + content.loadAsync(() -> { + plugin.sendMessage(sender, ChatColor.GRAY + "Preise von " + target.getName() + " (" + target.getUniqueId().toString() + "):"); + List items = content.getItems(); + if (items.isEmpty()) { + plugin.sendMessage(sender, "keine Preise vorhanden"); + } else { + ListedItemsData lid = new ListedItemsData(target.getUniqueId()); + int nr = 1; + for (DatabaseTreasureChestItem i : items) { + plugin.sendMessage(sender, nr + ": " + i.getDisplayItem().getItemMeta().getDisplayName()); + lid.addItem(nr, i.getId()); + nr++; + } + if (sender instanceof Player player) { + plugin.getData().setListedItems(player.getUniqueId(), lid); + } else { + plugin.getData().setListedItems(null, lid); + } + } + }); + return true; + } + + @Override + public Collection onTabComplete(CommandSender sender, Command command, String alias, ArgsParser args) { + if (args.remaining() == 1) { + return null; + } + return List.of(); + } +} diff --git a/src/main/java/de/iani/treasurechest/commands/RemoveCommand.java b/src/main/java/de/iani/treasurechest/commands/RemoveCommand.java new file mode 100644 index 0000000..7192a12 --- /dev/null +++ b/src/main/java/de/iani/treasurechest/commands/RemoveCommand.java @@ -0,0 +1,102 @@ +package de.iani.treasurechest.commands; + +import de.iani.cubesideutils.bukkit.commands.SubCommand; +import de.iani.cubesideutils.bukkit.commands.exceptions.DisallowsCommandBlockException; +import de.iani.cubesideutils.bukkit.commands.exceptions.IllegalSyntaxException; +import de.iani.cubesideutils.bukkit.commands.exceptions.InternalCommandException; +import de.iani.cubesideutils.bukkit.commands.exceptions.NoPermissionException; +import de.iani.cubesideutils.bukkit.commands.exceptions.RequiresPlayerException; +import de.iani.cubesideutils.commands.ArgsParser; +import de.iani.playerUUIDCache.CachedPlayer; +import de.iani.treasurechest.ListedItemsData; +import de.iani.treasurechest.Permissions; +import de.iani.treasurechest.PlayerTreasureChestContent; +import de.iani.treasurechest.PlayerTreasureChestContent.LoadState; +import de.iani.treasurechest.TreasureChest; +import java.sql.SQLException; +import java.util.Collection; +import java.util.List; +import java.util.logging.Level; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class RemoveCommand extends SubCommand { + private TreasureChest plugin; + + public RemoveCommand(TreasureChest plugin) { + this.plugin = plugin; + } + + @Override + public String getRequiredPermission() { + return Permissions.REMOVE; + } + + @Override + public boolean requiresPlayer() { + return false; + } + + @Override + public String getUsage() { + return " "; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String alias, String commandString, ArgsParser args) throws DisallowsCommandBlockException, RequiresPlayerException, NoPermissionException, IllegalSyntaxException, InternalCommandException { + if (args.remaining() != 2) { + plugin.sendMessage(sender, commandString + getUsage(), true); + return true; + } + CachedPlayer target = plugin.getPlayerUUIDCache().getPlayerFromNameOrUUID(args.getNext(), true); + + if (target == null) { + plugin.sendMessage(sender, "Unknown player!", true); + return true; + } + int nr = args.getNext(-1); + + ListedItemsData lid; + if (sender instanceof Player player) { + lid = plugin.getData().getListedItems(player.getUniqueId()); + } else { + lid = plugin.getData().getListedItems(null); + } + if (lid == null || !lid.getOwner().equals(target.getUniqueId())) { + plugin.sendMessage(sender, "Nicht der gelistete Spieler", true); + return true; + } + Integer key = lid.getItemDatabaseKey(nr); + if (key == null) { + plugin.sendMessage(sender, "Ungültige ID", true); + return true; + } + try { + if (plugin.getDatabase().deleteItem(target.getUniqueId(), key)) { + PlayerTreasureChestContent content = plugin.getData().getChestContent(target.getUniqueId()); + if (content != null && content.getLoadState() == LoadState.LOADED) { + content.removeItem(key); + } + } else { + plugin.sendMessage(sender, "Ungültige ID", true); + return true; + } + } catch (SQLException e) { + plugin.sendMessage(sender, ChatColor.DARK_RED + "Datenbankfehler"); + plugin.getLogger().log(Level.SEVERE, "Could not delete item " + key + " for " + target.getName() + ": " + e.getMessage(), e); + return true; + } + plugin.sendMessage(sender, "Der Preis wurde entfernt!"); + return true; + } + + @Override + public Collection onTabComplete(CommandSender sender, Command command, String alias, ArgsParser args) { + if (args.remaining() == 1) { + return null; + } + return List.of(); + } +} diff --git a/src/main/java/de/iani/treasurechest/commands/SetChestCommand.java b/src/main/java/de/iani/treasurechest/commands/SetChestCommand.java new file mode 100644 index 0000000..0c9637b --- /dev/null +++ b/src/main/java/de/iani/treasurechest/commands/SetChestCommand.java @@ -0,0 +1,62 @@ +package de.iani.treasurechest.commands; + +import de.iani.cubesideutils.bukkit.commands.SubCommand; +import de.iani.cubesideutils.bukkit.commands.exceptions.DisallowsCommandBlockException; +import de.iani.cubesideutils.bukkit.commands.exceptions.IllegalSyntaxException; +import de.iani.cubesideutils.bukkit.commands.exceptions.InternalCommandException; +import de.iani.cubesideutils.bukkit.commands.exceptions.NoPermissionException; +import de.iani.cubesideutils.bukkit.commands.exceptions.RequiresPlayerException; +import de.iani.cubesideutils.commands.ArgsParser; +import de.iani.treasurechest.Permissions; +import de.iani.treasurechest.TreasureChest; +import java.util.Collection; +import java.util.List; +import org.bukkit.Effect; +import org.bukkit.FluidCollisionMode; +import org.bukkit.block.Block; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class SetChestCommand extends SubCommand { + private TreasureChest plugin; + + public SetChestCommand(TreasureChest plugin) { + this.plugin = plugin; + } + + @Override + public String getRequiredPermission() { + return Permissions.SET_CHEST; + } + + @Override + public boolean requiresPlayer() { + return true; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String alias, String commandString, ArgsParser args) throws DisallowsCommandBlockException, RequiresPlayerException, NoPermissionException, IllegalSyntaxException, InternalCommandException { + if (args.remaining() != 0) { + plugin.sendMessage(sender, commandString + getUsage(), true); + return true; + } + Player player = ((Player) sender); + Block target = player.getTargetBlockExact(5, FluidCollisionMode.NEVER); + plugin.setChestLocation(target == null ? null : target.getLocation()); + if (target != null) { + player.playEffect(target.getLocation(), Effect.MOBSPAWNER_FLAMES, null); + player.playEffect(target.getLocation(), Effect.MOBSPAWNER_FLAMES, null); + player.playEffect(target.getLocation(), Effect.MOBSPAWNER_FLAMES, null); + plugin.sendMessage(sender, "Treasurechest location set!"); + } else { + plugin.sendMessage(sender, "Treasurechest location removed!"); + } + return true; + } + + @Override + public Collection onTabComplete(CommandSender sender, Command command, String alias, ArgsParser args) { + return List.of(); + } +} diff --git a/src/main/java/de/iani/treasurechest/database/DatabaseTreasureChestItem.java b/src/main/java/de/iani/treasurechest/database/DatabaseTreasureChestItem.java index b36ebfd..bf8085d 100644 --- a/src/main/java/de/iani/treasurechest/database/DatabaseTreasureChestItem.java +++ b/src/main/java/de/iani/treasurechest/database/DatabaseTreasureChestItem.java @@ -1,8 +1,7 @@ package de.iani.treasurechest.database; -import org.bukkit.inventory.ItemStack; - import de.iani.treasurechest.TreasureChestItem; +import org.bukkit.inventory.ItemStack; public class DatabaseTreasureChestItem extends TreasureChestItem { diff --git a/src/main/java/de/iani/treasurechest/database/TreasureChestDatabase.java b/src/main/java/de/iani/treasurechest/database/TreasureChestDatabase.java index 09f9bce..95e7625 100644 --- a/src/main/java/de/iani/treasurechest/database/TreasureChestDatabase.java +++ b/src/main/java/de/iani/treasurechest/database/TreasureChestDatabase.java @@ -1,11 +1,9 @@ package de.iani.treasurechest.database; +import de.iani.cubesideutils.sql.MySQLConnection; +import de.iani.cubesideutils.sql.SQLConnection; import de.iani.treasurechest.TreasureChest; import de.iani.treasurechest.TreasureChestItem; -import de.iani.treasurechest.util.sql.MySQLConnection; -import de.iani.treasurechest.util.sql.SQLConnection; -import de.iani.treasurechest.util.sql.SQLRunnable; -import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @@ -43,21 +41,18 @@ removeOldContent = "DELETE FROM " + tableName + " WHERE time < ?"; - this.connection.runCommands(new SQLRunnable() { - @Override - public Void execute(Connection connection, SQLConnection sqlConnection) throws SQLException { - if (!sqlConnection.hasTable(tableName)) { - Statement smt = connection.createStatement(); - smt.executeUpdate("CREATE TABLE `" + tableName + "` ("// - + "`id` INT NOT NULL AUTO_INCREMENT,"// - + "`uuid` CHAR( 36 ) NOT NULL,"// - + "`time` BIGINT NOT NULL,"// - + "`content` LONGTEXT,"// - + "PRIMARY KEY ( `id` ), INDEX ( `uuid`, `time` ) ) ENGINE = innodb"); - smt.close(); - } - return null; + this.connection.runCommands((connection, sqlConnection) -> { + if (!sqlConnection.hasTable(tableName)) { + Statement smt = connection.createStatement(); + smt.executeUpdate("CREATE TABLE `" + tableName + "` ("// + + "`id` INT NOT NULL AUTO_INCREMENT,"// + + "`uuid` CHAR( 36 ) NOT NULL,"// + + "`time` BIGINT NOT NULL,"// + + "`content` LONGTEXT,"// + + "PRIMARY KEY ( `id` ), INDEX ( `uuid`, `time` ) ) ENGINE = innodb"); + smt.close(); } + return null; }); } @@ -66,106 +61,94 @@ } public DatabaseTreasureChestItem addItem(UUID owner, TreasureChestItem item) throws SQLException { - return this.connection.runCommands(new SQLRunnable() { - @Override - public DatabaseTreasureChestItem execute(Connection connection, SQLConnection sqlConnection) throws SQLException { - PreparedStatement smt = sqlConnection.getOrCreateStatement(insertContent, Statement.RETURN_GENERATED_KEYS); + return this.connection.runCommands((connection, sqlConnection) -> { + PreparedStatement smt = sqlConnection.getOrCreateStatement(insertContent, Statement.RETURN_GENERATED_KEYS); - smt.setString(1, owner.toString()); - long time = System.currentTimeMillis(); - smt.setLong(2, time); - YamlConfiguration conf = new YamlConfiguration(); - conf.set("display", item.getDisplayItem()); - ConfigurationSection itemsSection = conf.createSection("items"); - ItemStack[] items = item.getPriceItems(); - if (items != null) { - for (int i = 0; i < items.length; i++) { - ItemStack stack = items[i]; - itemsSection.set(Integer.toString(i), stack); - } + smt.setString(1, owner.toString()); + long time = System.currentTimeMillis(); + smt.setLong(2, time); + YamlConfiguration conf = new YamlConfiguration(); + conf.set("display", item.getDisplayItem()); + ConfigurationSection itemsSection = conf.createSection("items"); + ItemStack[] items = item.getPriceItems(); + if (items != null) { + for (int i = 0; i < items.length; i++) { + ItemStack stack = items[i]; + itemsSection.set(Integer.toString(i), stack); } - conf.set("money", item.getPriceMoney()); - smt.setString(3, conf.saveToString()); - smt.executeUpdate(); - ResultSet genKeys = smt.getGeneratedKeys(); - Integer id = null; - if (genKeys.next()) { - id = genKeys.getInt(1); - } - genKeys.close(); - if (id == null) { - throw new SQLException("No id was generated!"); - } - return new DatabaseTreasureChestItem(item.getDisplayItem(), item.getPriceItems(), item.getPriceMoney(), time, id); } + conf.set("money", item.getPriceMoney()); + smt.setString(3, conf.saveToString()); + smt.executeUpdate(); + ResultSet genKeys = smt.getGeneratedKeys(); + Integer id = null; + if (genKeys.next()) { + id = genKeys.getInt(1); + } + genKeys.close(); + if (id == null) { + throw new SQLException("No id was generated!"); + } + return new DatabaseTreasureChestItem(item.getDisplayItem(), item.getPriceItems(), item.getPriceMoney(), time, id); }); } public ArrayList getPlayerItems(UUID owner) throws SQLException { - return this.connection.runCommands(new SQLRunnable>() { - @Override - public ArrayList execute(Connection connection, SQLConnection sqlConnection) throws SQLException { - ArrayList result = new ArrayList<>(); - PreparedStatement smt = sqlConnection.getOrCreateStatement(selectContent); - smt.setString(1, owner.toString()); - ResultSet rs = smt.executeQuery(); - while (rs.next()) { - int id = rs.getInt("id"); - long time = rs.getLong("time"); - String content = rs.getString("content"); - YamlConfiguration conf = new YamlConfiguration(); - try { - conf.loadFromString(content); - } catch (InvalidConfigurationException e) { - plugin.getLogger().log(Level.WARNING, "Could not load treasure chest item " + id + " for player " + owner, e); - continue; - } - ItemStack displayItem = conf.getItemStack("display"); - if (displayItem == null || displayItem.getAmount() == 0 || displayItem.getType() == Material.AIR) { - plugin.getLogger().log(Level.WARNING, "No display item for item " + id + " for player " + owner); - continue; - } - ArrayList stacks = new ArrayList<>(); - ConfigurationSection itemsSection = conf.getConfigurationSection("items"); - for (String key : itemsSection.getKeys(false)) { - ItemStack stack = itemsSection.getItemStack(key); - if (stack != null && stack.getAmount() > 0 && stack.getType() != Material.AIR) { - stacks.add(stack); - } - } - ItemStack[] priceItems = stacks.toArray(new ItemStack[stacks.size()]); - int priceMoney = conf.getInt("money"); - result.add(new DatabaseTreasureChestItem(displayItem, priceItems, priceMoney, time, id)); + return this.connection.runCommands((connection, sqlConnection) -> { + ArrayList result = new ArrayList<>(); + PreparedStatement smt = sqlConnection.getOrCreateStatement(selectContent); + smt.setString(1, owner.toString()); + ResultSet rs = smt.executeQuery(); + while (rs.next()) { + int id = rs.getInt("id"); + long time = rs.getLong("time"); + String content = rs.getString("content"); + YamlConfiguration conf = new YamlConfiguration(); + try { + conf.loadFromString(content); + } catch (InvalidConfigurationException e) { + plugin.getLogger().log(Level.WARNING, "Could not load treasure chest item " + id + " for player " + owner, e); + continue; } - rs.close(); - return result; + ItemStack displayItem = conf.getItemStack("display"); + if (displayItem == null || displayItem.getAmount() == 0 || displayItem.getType() == Material.AIR) { + plugin.getLogger().log(Level.WARNING, "No display item for item " + id + " for player " + owner); + continue; + } + ArrayList stacks = new ArrayList<>(); + ConfigurationSection itemsSection = conf.getConfigurationSection("items"); + for (String key : itemsSection.getKeys(false)) { + ItemStack stack = itemsSection.getItemStack(key); + if (stack != null && stack.getAmount() > 0 && stack.getType() != Material.AIR) { + stacks.add(stack); + } + } + ItemStack[] priceItems = stacks.toArray(new ItemStack[stacks.size()]); + int priceMoney = conf.getInt("money"); + result.add(new DatabaseTreasureChestItem(displayItem, priceItems, priceMoney, time, id)); } + rs.close(); + return result; }); } public boolean deleteItem(UUID owner, int id) throws SQLException { - return this.connection.runCommands(new SQLRunnable() { - @Override - public Boolean execute(Connection connection, SQLConnection sqlConnection) throws SQLException { - PreparedStatement smt = sqlConnection.getOrCreateStatement(removeContent); - smt.setInt(1, id); - smt.setString(2, owner.toString()); - boolean updated = smt.executeUpdate() > 0; - return updated; - } + return this.connection.runCommands((connection, sqlConnection) -> { + PreparedStatement smt = sqlConnection.getOrCreateStatement(removeContent); + smt.setInt(1, id); + smt.setString(2, owner.toString()); + boolean updated = smt.executeUpdate() > 0; + return updated; }); } public int deleteOldItems(long days) throws SQLException { - return this.connection.runCommands(new SQLRunnable() { - @Override - public Integer execute(Connection connection, SQLConnection sqlConnection) throws SQLException { - PreparedStatement smt = sqlConnection.getOrCreateStatement(removeOldContent); - long minTime = System.currentTimeMillis() - days * 24 * 60 * 60 * 1000; - smt.setLong(1, minTime); - int updated = smt.executeUpdate(); - return updated; - } + return this.connection.runCommands((connection, sqlConnection) -> { + PreparedStatement smt = sqlConnection.getOrCreateStatement(removeOldContent); + long minTime = System.currentTimeMillis() - days * 24 * 60 * 60 * 1000; + smt.setLong(1, minTime); + int updated = smt.executeUpdate(); + return updated; }); } } diff --git a/src/main/java/de/iani/treasurechest/listener/ChestInventoryListener.java b/src/main/java/de/iani/treasurechest/listener/ChestInventoryListener.java new file mode 100644 index 0000000..eaf6856 --- /dev/null +++ b/src/main/java/de/iani/treasurechest/listener/ChestInventoryListener.java @@ -0,0 +1,305 @@ +package de.iani.treasurechest.listener; + +import de.iani.cubesideutils.StringUtil; +import de.iani.treasurechest.OpenInventoryData; +import de.iani.treasurechest.PlayerTreasureChestContent; +import de.iani.treasurechest.PlayerTreasureChestContent.LoadState; +import de.iani.treasurechest.TreasureChest; +import de.iani.treasurechest.TreasureChestItem; +import de.iani.treasurechest.TreasurePayoutEvent; +import de.iani.treasurechest.database.DatabaseTreasureChestItem; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.logging.Level; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.block.ShulkerBox; +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.inventory.InventoryAction; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.inventory.InventoryDragEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BlockStateMeta; +import org.bukkit.inventory.meta.Damageable; +import org.bukkit.inventory.meta.ItemMeta; + +public class ChestInventoryListener implements Listener { + private TreasureChest plugin; + + HashMap openInventories = new HashMap<>(); + + public ChestInventoryListener(TreasureChest plugin) { + this.plugin = plugin; + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onChestOpen(PlayerInteractEvent e) { + if (plugin.getChestLocation() == null) { + return; + } + Block b = e.getClickedBlock(); + if (e.getAction() == Action.RIGHT_CLICK_BLOCK && b != null && b.getLocation().equals(plugin.getChestLocation())) { + e.setCancelled(true); + if (!e.getPlayer().hasPermission("treasurechest.access")) { + plugin.sendMessage(e.getPlayer(), "Du hast keinen Zugriff auf die Schatztruhe!"); + return; + } + if (openInventories.containsKey(e.getPlayer())) { + return;// ist schon offen? + } + + PlayerTreasureChestContent content = plugin.getData().getChestContent(e.getPlayer().getUniqueId()); + if (content != null && content.getLoadState() != LoadState.LOADED) { + content.loadAsync(); + return; + } + if (content == null || content.isEmpty()) { + plugin.sendMessage(e.getPlayer(), "Deine Schatztruhe ist leer!"); + return; + } + Inventory inventory = plugin.getServer().createInventory(null, 9 * 6, "Schatztruhe"); + OpenInventoryData openInventory = new OpenInventoryData(b.getLocation(), inventory); + + int pos = 0; + for (DatabaseTreasureChestItem item : content.getItems()) { + if (pos < 9 * 6) { + ItemStack di = item.getDisplayItem().clone(); + ItemMeta meta = di.getItemMeta(); + ItemStack[] priceList = item.getPriceItems(); + ArrayList lore = new ArrayList<>(); + if (priceList != null) { + for (ItemStack stack : priceList) { + StringBuilder t = new StringBuilder(); + if (stack.getAmount() > 1) { + t.append(stack.getAmount()).append(" "); + } + t.append(StringUtil.capitalizeFirstLetter(stack.getType().name(), true)); + ItemMeta stackMeta = stack.getItemMeta(); + if (stackMeta instanceof Damageable damageable) { + if (damageable.hasDamage()) { + t.append(':').append(damageable.getDamage()); + } + } + if (stackMeta.hasDisplayName()) { + t.append(" (benanntes Item)"); + } + lore.add(t.toString()); + } + } + if (item.getPriceMoney() > 0) { + lore.add(plugin.formatMoney(item.getPriceMoney())); + } + meta.setLore(lore); + di.setItemMeta(meta); + inventory.setItem(pos, di); + openInventory.setItemAtPosition(pos, item.getId()); + } + pos += 1; + } + + e.getPlayer().openInventory(inventory); + openInventories.put(e.getPlayer(), openInventory); + e.getPlayer().playSound(b.getLocation(), Sound.BLOCK_CHEST_OPEN, 0.5f, 0.9f); + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void onInventoryClick(InventoryClickEvent event) { + OpenInventoryData openInventory = openInventories.get(event.getWhoClicked()); + if (openInventory == null) { + return; + } + + InventoryAction action = event.getAction(); + switch (action) { + case PICKUP_ALL: + case PICKUP_HALF: + case PICKUP_SOME: + case PICKUP_ONE: { + event.setCancelled(true); + if (event.getRawSlot() < event.getView().getTopInventory().getSize() && event.getWhoClicked() instanceof Player) { + Player player = (Player) event.getWhoClicked(); + + ItemStack[] playerInv = player.getInventory().getContents(); + playerInv = Arrays.copyOf(playerInv, 36); + Inventory clonedPlayerInventory = Bukkit.createInventory(null, 36); + clonedPlayerInventory.setContents(playerInv); + + PlayerTreasureChestContent content = plugin.getData().getChestContent(player.getUniqueId()); + Integer entryId = openInventory.getEntryAtPosition(event.getRawSlot()); + if (entryId == null) { + return; + } + TreasureChestItem selectedItem = content.getItem(entryId); + if (selectedItem != null) { + ItemStack[] priceList = selectedItem.getPriceItems(); + int priceMoney = Math.max(selectedItem.getPriceMoney(), 0); + TreasurePayoutEvent payoutEvent = new TreasurePayoutEvent(player, priceList == null || priceList.length == 0 ? Collections.emptyList() : Arrays.asList(priceList), priceMoney); + + int priceCount = payoutEvent.getItems().size(); + if (priceCount > 0) { + ItemStack[] temp = new ItemStack[priceCount]; + for (int i = 0; i < priceCount; i++) { + temp[i] = payoutEvent.getItems().get(i).clone(); + } + if (addItemsToInventory(clonedPlayerInventory, temp) == null) { + plugin.sendMessage(player, "Du hast nicht genügend Platz in deinem Inventar!", true); + return; + } + } + plugin.getServer().getPluginManager().callEvent(payoutEvent); + if (payoutEvent.isCancelled()) { + return; + } + try { + if (!plugin.getDatabase().deleteItem(player.getUniqueId(), entryId)) { + return; + } + } catch (SQLException e) { + plugin.sendMessage(player, ChatColor.DARK_RED + "Datenbankfehler"); + plugin.getLogger().log(Level.SEVERE, "Could not delete item " + entryId + " for " + player.getUniqueId() + ": " + e.getMessage(), e); + return; + } + plugin.sendMessage(player, ChatColor.GRAY + "Du hast folgende Items erhalten:"); + if (priceCount > 0) { + ItemStack[] temp = new ItemStack[priceCount]; + for (int i = 0; i < priceCount; i++) { + temp[i] = payoutEvent.getItems().get(i).clone(); + } + FilledInventory filledInventory = addItemsToInventory(player.getInventory(), temp); + for (ItemStack stack : payoutEvent.getItems()) { + StringBuilder t = new StringBuilder(" "); + if (stack.getAmount() > 1) { + t.append(stack.getAmount()).append(" "); + } + t.append(StringUtil.capitalizeFirstLetter(stack.getType().name(), true)); + ItemMeta stackMeta = stack.getItemMeta(); + if (stackMeta instanceof Damageable damageable) { + if (damageable.hasDamage()) { + t.append(':').append(damageable.getDamage()); + } + } + if (stackMeta.hasDisplayName()) { + t.append(" (").append(stackMeta.getDisplayName()).append(ChatColor.YELLOW).append(")"); + } + plugin.sendMessage(player, t.toString()); + } + if (filledInventory == FilledInventory.ShulkerBox) { + plugin.sendMessage(player, "Die Items wurden in eine leere Shulker-Kiste in deinem Inventar gelegt."); + } + } + int money = payoutEvent.getMoney(); + if (money > 0) { + plugin.giveMoney(player, money); + plugin.sendMessage(player, " " + plugin.formatMoney(money)); + } + + player.playSound(event.getWhoClicked().getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1f, 1f); + content.removeItem(entryId); + openInventory.getInventory().setItem(event.getRawSlot(), null); + openInventory.removeEntryAtPosition(event.getRawSlot()); + player.updateInventory(); + } + } + } + case CLONE_STACK: + case COLLECT_TO_CURSOR: + case DROP_ALL_CURSOR: + case DROP_ALL_SLOT: + case DROP_ONE_CURSOR: + case DROP_ONE_SLOT: + case HOTBAR_MOVE_AND_READD: + case HOTBAR_SWAP: + case UNKNOWN: + default: { + Player player = (Player) event.getWhoClicked(); + player.updateInventory(); + event.setCancelled(true); + return; + } + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void onInventoryDrag(InventoryDragEvent event) { + if (openInventories.containsKey(event.getWhoClicked())) { + event.setCancelled(true); + } + } + + @EventHandler + public void onInventoryClose(InventoryCloseEvent e) { + OpenInventoryData data = openInventories.remove(e.getPlayer()); + if (data != null) { + ((Player) e.getPlayer()).playSound(data.getLocation(), Sound.BLOCK_CHEST_CLOSE, 0.5f, 0.9f); + } + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + openInventories.remove(event.getPlayer()); + } + + private FilledInventory addItemsToInventory(Inventory inventory, ItemStack[] items) { + int itemCount = 0; + for (ItemStack itemStack : items) { + if (itemStack != null && itemStack.getType() != Material.AIR) { + itemCount++; + } + } + + int inventorySpace = 0; + for (ItemStack shulkerItem : inventory.getContents()) { + if (shulkerItem == null || shulkerItem.getType() == Material.AIR) { + inventorySpace++; + } + } + if (inventorySpace >= itemCount) { + inventory.addItem(items); + return FilledInventory.PlayerInventory; + } + + for (ItemStack inventoryItemStack : inventory.getContents()) { + if (inventoryItemStack != null) { + if (inventoryItemStack.getItemMeta() instanceof BlockStateMeta blockStateMeta) { + BlockState blockState = blockStateMeta.getBlockState(); + if (blockState instanceof ShulkerBox shulkerBox) { + ItemStack[] shulkerContents = shulkerBox.getSnapshotInventory().getStorageContents(); + boolean shulkerEmpty = true; + for (ItemStack shulkerItem : shulkerContents) { + if (shulkerItem != null && shulkerItem.getType() != Material.AIR) { + shulkerEmpty = false; + } + } + if (shulkerEmpty) { + shulkerBox.getSnapshotInventory().setStorageContents(items); + blockStateMeta.setBlockState(blockState); + inventoryItemStack.setItemMeta(blockStateMeta); + return FilledInventory.ShulkerBox; + } + } + } + } + } + return null; + } + + private enum FilledInventory { + PlayerInventory, ShulkerBox + } +} diff --git a/src/main/java/de/iani/treasurechest/listener/PlayerEventListener.java b/src/main/java/de/iani/treasurechest/listener/PlayerEventListener.java new file mode 100644 index 0000000..645be61 --- /dev/null +++ b/src/main/java/de/iani/treasurechest/listener/PlayerEventListener.java @@ -0,0 +1,28 @@ +package de.iani.treasurechest.listener; + +import de.iani.treasurechest.TreasureChest; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +public class PlayerEventListener implements Listener { + private TreasureChest plugin; + + public PlayerEventListener(TreasureChest plugin) { + this.plugin = plugin; + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + plugin.getData().reloadTreasureChest(event.getPlayer().getUniqueId()); + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + plugin.getData().removeActiveItem(event.getPlayer().getUniqueId()); + plugin.getData().unloadTreasureChest(event.getPlayer().getUniqueId()); + plugin.getData().removeListedItems(event.getPlayer().getUniqueId()); + } + +} diff --git a/src/main/java/de/iani/treasurechest/util/sql/MySQLConnection.java b/src/main/java/de/iani/treasurechest/util/sql/MySQLConnection.java deleted file mode 100644 index bb2d00b..0000000 --- a/src/main/java/de/iani/treasurechest/util/sql/MySQLConnection.java +++ /dev/null @@ -1,9 +0,0 @@ -package de.iani.treasurechest.util.sql; - -import java.sql.SQLException; - -public class MySQLConnection extends SQLConnection { - public MySQLConnection(String host, String database, String user, String password) throws SQLException { - super("jdbc:mysql://" + host + "/" + database, database, user, password, "com.mysql.jdbc.Driver"); - } -} diff --git a/src/main/java/de/iani/treasurechest/util/sql/SQLConnection.java b/src/main/java/de/iani/treasurechest/util/sql/SQLConnection.java deleted file mode 100644 index 02a8011..0000000 --- a/src/main/java/de/iani/treasurechest/util/sql/SQLConnection.java +++ /dev/null @@ -1,160 +0,0 @@ -package de.iani.treasurechest.util.sql; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.HashMap; - -public class SQLConnection { - private String connectURL; - - private Connection connection; - - private String user; - - private String password; - - private String database; - - private int maxTries; - - private HashMap cachedStatements; - - public SQLConnection(String connectURL, String database, String user, String password) throws SQLException { - this(connectURL, database, user, password, null); - } - - public SQLConnection(String connectURL, String database, String user, String password, String driverClass) throws SQLException { - if (driverClass != null) { - try { - Class.forName(driverClass); - } catch (Exception e) { - throw new SQLException(e); - } - } - this.connectURL = connectURL; - this.user = user; - this.password = password; - this.database = database; - this.cachedStatements = new HashMap(); - this.maxTries = 3; - connect(); - } - - public synchronized void disconnect() { - if (this.connection != null) { - try { - this.connection.close(); - } catch (SQLException e) { - // ignore - } - this.connection = null; - } - this.cachedStatements.clear(); - } - - private synchronized void connect() throws SQLException { - disconnect(); - this.connection = user != null ? DriverManager.getConnection(connectURL, user, password) : DriverManager.getConnection(connectURL); - this.connection.setAutoCommit(false); - } - - public synchronized T runCommands(SQLRunnable runnable) throws SQLException { - int fails = 0; - while (true) { - try { - if (connection == null) { - connect(); - } - T rv = runnable.execute(connection, this); - connection.commit(); - return rv; - } catch (SQLException e) { - fails += 1; - if (connection != null) { - try { - if (!connection.isClosed()) { - connection.rollback(); - } - } catch (SQLException ex) { - // ignore - } - try { - connection.close(); - } catch (SQLException ex) { - // ignore - } - connection = null; - } - if (fails >= maxTries) { - throw e; - } - } - } - } - - public PreparedStatement getOrCreateStatement(String statement) throws SQLException { - PreparedStatement smt = cachedStatements.get(statement); - if (smt == null || smt.isClosed()) { - smt = connection.prepareStatement(statement); - cachedStatements.put(statement, smt); - } - return smt; - } - - public PreparedStatement getOrCreateStatement(String statement, int autoGeneratedKeys) throws SQLException { - PreparedStatement smt = cachedStatements.get(statement); - if (smt == null || smt.isClosed()) { - smt = connection.prepareStatement(statement, autoGeneratedKeys); - cachedStatements.put(statement, smt); - } - return smt; - } - - public boolean hasTable(final String table) throws SQLException { - return hasTable(this.database, table); - } - - public boolean hasTable(final String database, final String table) throws SQLException { - return runCommands(new SQLRunnable() { - @Override - public Boolean execute(Connection connection, SQLConnection sqlConnection) throws SQLException { - PreparedStatement smt = sqlConnection.getOrCreateStatement("SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = ? AND table_name = ?"); - smt.setString(1, database); - smt.setString(2, table); - ResultSet rs = smt.executeQuery(); - boolean rv = false; - if (rs.next()) { - rv = rs.getInt(1) > 0; - } - rs.close(); - return rv; - } - }); - } - - public boolean hasColumn(final String table, final String column) throws SQLException { - return hasColumn(this.database, table, column); - } - - public boolean hasColumn(final String database, final String table, final String column) throws SQLException { - return runCommands(new SQLRunnable() { - @Override - public Boolean execute(Connection connection, SQLConnection sqlConnection) throws SQLException { - PreparedStatement smt = sqlConnection.getOrCreateStatement("SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = ? AND table_name = ? AND column_name = ?"); - smt.setString(1, database); - smt.setString(2, table); - smt.setString(3, column); - ResultSet rs = smt.executeQuery(); - boolean rv = false; - if (rs.next()) { - rv = rs.getInt(1) > 0; - } - rs.close(); - return rv; - } - }); - } -} diff --git a/src/main/java/de/iani/treasurechest/util/sql/SQLRunnable.java b/src/main/java/de/iani/treasurechest/util/sql/SQLRunnable.java deleted file mode 100644 index 2d225cb..0000000 --- a/src/main/java/de/iani/treasurechest/util/sql/SQLRunnable.java +++ /dev/null @@ -1,8 +0,0 @@ -package de.iani.treasurechest.util.sql; - -import java.sql.Connection; -import java.sql.SQLException; - -public interface SQLRunnable { - public T execute(Connection connection, SQLConnection sqlConnection) throws SQLException; -} diff --git a/src/main/java/de/iani/treasurechest/worker/WorkerThread.java b/src/main/java/de/iani/treasurechest/worker/WorkerThread.java index fa8fa41..4f9ae1f 100644 --- a/src/main/java/de/iani/treasurechest/worker/WorkerThread.java +++ b/src/main/java/de/iani/treasurechest/worker/WorkerThread.java @@ -1,10 +1,9 @@ package de.iani.treasurechest.worker; -import java.util.ArrayDeque; -import java.util.logging.Level; - import de.iani.treasurechest.TreasureChest; import de.iani.treasurechest.database.TreasureChestDatabase; +import java.util.ArrayDeque; +import java.util.logging.Level; public class WorkerThread extends Thread { @@ -15,7 +14,7 @@ public WorkerThread(TreasureChest plugin) { this.plugin = plugin; - this.work = new ArrayDeque(); + this.work = new ArrayDeque<>(); this.database = plugin.getDatabase(); setName("TreasureChest worker"); start(); diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 847e597..3de8ac5 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -4,7 +4,7 @@ author: Brokkonaut description: Treasure Chests for Events softdepend: [Vault] -depend: [PlayerUUIDCache] +depend: [CubesideUtils, PlayerUUIDCache] api-version: 1.13 commands: