diff --git a/src/main/java/pro/cloudnode/smp/bankaccounts/BankAccounts.java b/src/main/java/pro/cloudnode/smp/bankaccounts/BankAccounts.java index bf83a4a..d0d0bb9 100644 --- a/src/main/java/pro/cloudnode/smp/bankaccounts/BankAccounts.java +++ b/src/main/java/pro/cloudnode/smp/bankaccounts/BankAccounts.java @@ -23,7 +23,7 @@ import pro.cloudnode.smp.bankaccounts.events.BlockBreak; import pro.cloudnode.smp.bankaccounts.events.GUI; import pro.cloudnode.smp.bankaccounts.events.Join; -import pro.cloudnode.smp.bankaccounts.events.PlayerInteract; +import pro.cloudnode.smp.bankaccounts.events.POSOpen; import pro.cloudnode.smp.bankaccounts.integrations.PAPIIntegration; import pro.cloudnode.smp.bankaccounts.integrations.VaultIntegration; @@ -89,7 +89,7 @@ public void onEnable() { final @NotNull Listener[] events = new Listener[]{ new Join(), new BlockBreak(), - new PlayerInteract(), + new POSOpen(), new GUI() }; for (final @NotNull Listener event : events) getServer().getPluginManager().registerEvents(event, this); diff --git a/src/main/java/pro/cloudnode/smp/bankaccounts/commands/POSCommand.java b/src/main/java/pro/cloudnode/smp/bankaccounts/commands/POSCommand.java index b91aca7..056e8a9 100644 --- a/src/main/java/pro/cloudnode/smp/bankaccounts/commands/POSCommand.java +++ b/src/main/java/pro/cloudnode/smp/bankaccounts/commands/POSCommand.java @@ -1,10 +1,14 @@ package pro.cloudnode.smp.bankaccounts.commands; import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; import org.bukkit.block.BlockState; import org.bukkit.block.Chest; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.DoubleChestInventory; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -19,6 +23,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Date; +import java.util.List; import java.util.Optional; import java.util.Set; @@ -71,6 +76,8 @@ public boolean execute(final @NotNull CommandSender sender, final @NotNull Strin if (block.isEmpty()) return sendMessage(sender, BankAccounts.getInstance().config().messagesErrorsAsyncFailed()); if (!(block.get() instanceof final @NotNull Chest chest)) return sendMessage(sender, BankAccounts.getInstance().config().messagesErrorsPosNotChest()); + if (!canOpenChest(player, chest)) + return true; if (chest.getInventory() instanceof DoubleChestInventory) return sendMessage(sender, BankAccounts.getInstance().config().messagesErrorsPosDoubleChest()); if (chest.getInventory().isEmpty()) return sendMessage(sender, BankAccounts.getInstance().config().messagesErrorsPosEmpty()); @@ -88,6 +95,31 @@ public boolean execute(final @NotNull CommandSender sender, final @NotNull Strin return sendMessage(sender, BankAccounts.getInstance().config().messagesPosCreated(pos)); } + private static boolean canOpenChest(final @NotNull Player player, final @NotNull Chest chest) { + return BankAccounts.runOnMain(() -> { + final @NotNull Block block = chest.getBlock(); + + final @NotNull PlayerInteractEvent event = new PlayerInteractEvent( + player, + Action.RIGHT_CLICK_BLOCK, + player.getInventory().getItemInMainHand(), + block, + getTargetedFace(player).orElse(BlockFace.NORTH) + ); + + BankAccounts.getInstance().getServer().getPluginManager().callEvent(event); + return event.useInteractedBlock() != Event.Result.DENY; + }).orElse(false); + } + + private static @NotNull Optional<@NotNull BlockFace> getTargetedFace(final @NotNull Player player) { + final @NotNull List<@NotNull Block> lastTwoTargetBlocks = player.getLastTwoTargetBlocks(null, 5); + if (lastTwoTargetBlocks.size() != 2 || !lastTwoTargetBlocks.get(1).getType().isOccluding()) return Optional.empty(); + final @NotNull Block targetBlock = lastTwoTargetBlocks.get(1); + final @NotNull Block adjacentBlock = lastTwoTargetBlocks.get(0); + return Optional.ofNullable(targetBlock.getFace(adjacentBlock)); + } + @Override public @NotNull ArrayList<@NotNull String> tab(final @NotNull CommandSender sender, final @NotNull String @NotNull [] args) { final @NotNull ArrayList<@NotNull String> suggestions = new ArrayList<>(); diff --git a/src/main/java/pro/cloudnode/smp/bankaccounts/events/POSOpen.java b/src/main/java/pro/cloudnode/smp/bankaccounts/events/POSOpen.java new file mode 100644 index 0000000..5fc51a4 --- /dev/null +++ b/src/main/java/pro/cloudnode/smp/bankaccounts/events/POSOpen.java @@ -0,0 +1,62 @@ +package pro.cloudnode.smp.bankaccounts.events; + +import org.bukkit.block.Block; +import org.bukkit.block.Chest; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.DoubleChestInventory; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import pro.cloudnode.smp.bankaccounts.Account; +import pro.cloudnode.smp.bankaccounts.BankAccounts; +import pro.cloudnode.smp.bankaccounts.POS; +import pro.cloudnode.smp.bankaccounts.Permissions; + +import java.util.Optional; + +public final class POSOpen implements Listener { + @EventHandler + public void openPOS(final @NotNull PlayerInteractEvent event) { + if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return; + final @Nullable Block block = event.getClickedBlock(); + if (block == null) return; + if (!(block.getState() instanceof final @NotNull Chest chest)) return; + if (chest.getInventory().isEmpty()) return; + if (chest.getInventory() instanceof DoubleChestInventory) return; + + final @NotNull Optional pos = POS.get(block); + if (pos.isEmpty()) return; + + event.setUseInteractedBlock(Event.Result.DENY); + + final @NotNull Player player = event.getPlayer(); + if (player.getUniqueId().equals(pos.get().seller.owner.getUniqueId())) { + POS.openOwnerGui(player, chest, pos.get()); + return; + } + if (!player.hasPermission(Permissions.POS_USE)) { + player.sendMessage(BankAccounts.getInstance().config().messagesErrorsPosNoPermission()); + return; + } + final @NotNull ItemStack heldItem = player.getInventory().getItemInMainHand(); + if (heldItem.getType() != BankAccounts.getInstance().config().instrumentsMaterial()) { + player.sendMessage(BankAccounts.getInstance().config().messagesErrorsNoCard()); + return; + } + final @NotNull Optional<@NotNull Account> account = Account.get(heldItem); + if (account.isEmpty()) player.sendMessage(BankAccounts.getInstance().config().messagesErrorsPosInvalidCard()); + else { + if (!player.hasPermission(Permissions.POS_USE_OTHER) && !account.get().owner.getUniqueId() + .equals(player.getUniqueId())) { + player.sendMessage(BankAccounts.getInstance().config().messagesErrorsNotAccountOwner()); + return; + } + POS.openBuyGui(player, chest, pos.get(), account.get()); + } + } +} diff --git a/src/main/java/pro/cloudnode/smp/bankaccounts/events/PlayerInteract.java b/src/main/java/pro/cloudnode/smp/bankaccounts/events/PlayerInteract.java deleted file mode 100644 index 3f6144f..0000000 --- a/src/main/java/pro/cloudnode/smp/bankaccounts/events/PlayerInteract.java +++ /dev/null @@ -1,56 +0,0 @@ -package pro.cloudnode.smp.bankaccounts.events; - -import org.bukkit.block.Block; -import org.bukkit.block.Chest; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.block.Action; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.inventory.DoubleChestInventory; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; -import pro.cloudnode.smp.bankaccounts.Account; -import pro.cloudnode.smp.bankaccounts.BankAccounts; -import pro.cloudnode.smp.bankaccounts.POS; -import pro.cloudnode.smp.bankaccounts.Permissions; - -import java.util.Optional; - -public final class PlayerInteract implements Listener { - @EventHandler - public void onPlayerInteractEvent(final @NotNull PlayerInteractEvent event) { - final @NotNull Player player = event.getPlayer(); - if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { - final @NotNull Optional block = Optional.ofNullable(event.getClickedBlock()); - if (block.isPresent() && block.get().getState() instanceof final @NotNull Chest chest && !chest.getInventory().isEmpty() && !(chest.getInventory() instanceof DoubleChestInventory)) { - final @NotNull Optional pos = POS.get(block.get()); - if (pos.isEmpty()) return; - event.setCancelled(true); - if (player.getUniqueId().equals(pos.get().seller.owner.getUniqueId())) { - POS.openOwnerGui(player, chest, pos.get()); - return; - } - if (!player.hasPermission(Permissions.POS_USE)) { - player.sendMessage(BankAccounts.getInstance().config().messagesErrorsPosNoPermission()); - return; - } - final @NotNull ItemStack heldItem = player.getInventory().getItemInMainHand(); - if (heldItem.getType() != BankAccounts.getInstance().config().instrumentsMaterial()) { - player.sendMessage(BankAccounts.getInstance().config().messagesErrorsNoCard()); - return; - } - final @NotNull Optional<@NotNull Account> account = Account.get(heldItem); - if (account.isEmpty()) - player.sendMessage(BankAccounts.getInstance().config().messagesErrorsPosInvalidCard()); - else { - if (!player.hasPermission(Permissions.POS_USE_OTHER) && !account.get().owner.getUniqueId().equals(player.getUniqueId())) { - player.sendMessage(BankAccounts.getInstance().config().messagesErrorsNotAccountOwner()); - return; - } - POS.openBuyGui(player, chest, pos.get(), account.get()); - } - } - } - } -}