diff --git a/src/main/java/pro/cloudnode/smp/bankaccounts/POS.java b/src/main/java/pro/cloudnode/smp/bankaccounts/POS.java index b7f6c6f..ac68717 100644 --- a/src/main/java/pro/cloudnode/smp/bankaccounts/POS.java +++ b/src/main/java/pro/cloudnode/smp/bankaccounts/POS.java @@ -26,6 +26,7 @@ import java.util.Arrays; import java.util.Comparator; import java.util.Date; +import java.util.HashMap; import java.util.Objects; import java.util.Optional; import java.util.UUID; @@ -66,6 +67,8 @@ public final class POS { */ public final @NotNull Date created; + public final static @NotNull HashMap<@NotNull Inventory, @NotNull POS> activePosChestGuis = new HashMap<>(); + /** * Create new POS instance * @@ -118,6 +121,15 @@ public POS(final @NotNull ResultSet rs) throws @NotNull SQLException, @NotNull I return getLocation().getBlock(); } + /** + * Get POS chest + */ + public @Nullable Chest getChest() { + if (getBlock().getState() instanceof final @NotNull Chest chest) return chest; + delete(); + return null; + } + /** * Create POS id */ @@ -259,10 +271,11 @@ public void delete() { * @param pos The POS */ public static void openOwnerGui(final @NotNull Player player, final @NotNull Chest chest, final @NotNull POS pos) { - final @NotNull ItemStack @NotNull [] items = Arrays.stream(chest.getInventory().getStorageContents()).filter(Objects::nonNull).toArray(ItemStack[]::new); + final @NotNull ItemStack @NotNull [] items = Arrays.stream(chest.getInventory().getStorageContents()).filter(Objects::nonNull).map(ItemStack::clone).toArray(ItemStack[]::new); final int extraRows = 1; final int size = extraRows * 9 + items.length + 9 - items.length % 9; final @NotNull Inventory gui = BankAccounts.getInstance().getServer().createInventory(null, size, BankAccounts.getInstance().config().posTitle(pos)); + POS.activePosChestGuis.put(gui, pos); gui.addItem(items); final @NotNull ItemStack overview = new ItemStack(BankAccounts.getInstance().config().posInfoMaterial(), 1); @@ -304,10 +317,11 @@ public static void openOwnerGui(final @NotNull Player player, final @NotNull Che * @param pos The POS */ public static void openBuyGui(final @NotNull Player player, final @NotNull Chest chest, final @NotNull POS pos, final @NotNull Account account) { - final @NotNull ItemStack @NotNull [] items = Arrays.stream(chest.getInventory().getStorageContents()).filter(Objects::nonNull).toArray(ItemStack[]::new); + final @NotNull ItemStack @NotNull [] items = Arrays.stream(chest.getInventory().getStorageContents()).filter(Objects::nonNull).map(ItemStack::clone).toArray(ItemStack[]::new); final int extraRows = 1; final int size = extraRows * 9 + items.length + 9 - items.length % 9; final @NotNull Inventory gui = BankAccounts.getInstance().getServer().createInventory(null, size, BankAccounts.getInstance().config().posTitle(pos)); + POS.activePosChestGuis.put(gui, pos); gui.addItem(items); final @NotNull ItemStack overview = new ItemStack(BankAccounts.getInstance().config().posInfoMaterial(), 1); diff --git a/src/main/java/pro/cloudnode/smp/bankaccounts/events/GUI.java b/src/main/java/pro/cloudnode/smp/bankaccounts/events/GUI.java index de2636a..87753f8 100644 --- a/src/main/java/pro/cloudnode/smp/bankaccounts/events/GUI.java +++ b/src/main/java/pro/cloudnode/smp/bankaccounts/events/GUI.java @@ -5,10 +5,13 @@ import org.bukkit.block.Chest; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; import org.bukkit.event.inventory.InventoryDragEvent; +import org.bukkit.event.inventory.InventoryMoveItemEvent; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.persistence.PersistentDataContainer; @@ -152,6 +155,34 @@ public void onInventoryClick(final @NotNull InventoryDragEvent event) { event.setCancelled(true); } + /** + * Detect changes in items of POS chest while a POS GUI is opened and prevent the item change. + * POS items can still be modified if no POS GUI is opened for that POS. + */ + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void posItemsChangeWhileOpened(final @NotNull InventoryMoveItemEvent event) { + final @NotNull Inventory source = event.getSource(); + final @NotNull Inventory destination = event.getDestination(); + for (final @NotNull POS pos : POS.activePosChestGuis.values()) { + final @Nullable Chest chest = pos.getChest(); + if (chest == null) continue; + final @NotNull Inventory chestInventory = chest.getInventory(); + if (source.equals(chestInventory) || destination.equals(chestInventory)) { + event.setCancelled(true); + return; + } + } + } + + /** + * POS GUI closed + */ + @EventHandler + public void posGuiClosed(final @NotNull InventoryCloseEvent event) { + if (!POS.activePosChestGuis.containsKey(event.getInventory())) return; + POS.activePosChestGuis.remove(event.getInventory()); + } + public final static @NotNull HashMap<@NotNull String, @NotNull NamespacedKey[]> keys = new HashMap<>() {{ put("pos-owner", new NamespacedKey[]{BankAccounts.Key.POS_OWNER_GUI}); put("pos-buyer", new NamespacedKey[]{BankAccounts.Key.POS_BUYER_GUI_CONFIRM, BankAccounts.Key.POS_BUYER_GUI, BankAccounts.Key.POS_BUYER_GUI_CANCEL});