From f8b459db427aac9077e48fa762f6b176ad41128c Mon Sep 17 00:00:00 2001 From: Swanty Date: Sun, 21 Jul 2024 11:47:34 +0300 Subject: [PATCH 1/8] Update anvilGuiVersion to not throw error on server start --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 73323d83..a3eb4564 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ blockProtVersion=1.2.1 nbtApiVersion=2.13.1-SNAPSHOT -anvilGuiVersion=1.9.5-SNAPSHOT +anvilGuiVersion=1.9.6-SNAPSHOT townyVersion=0.98.1.6 papiVersion=2.11.0 worldGuardVersion=7.0.7 From 570d9d0275f9f1f1ee2529deaf7719916eed558a Mon Sep 17 00:00:00 2001 From: Swanty Date: Sun, 21 Jul 2024 11:47:40 +0300 Subject: [PATCH 2/8] Fix block friend access flags not applied to other container --- .../bukkit/inventories/FriendDetailInventory.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendDetailInventory.java b/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendDetailInventory.java index 87d2eca6..fbc33afd 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendDetailInventory.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendDetailInventory.java @@ -22,12 +22,14 @@ import de.sean.blockprot.bukkit.TranslationKey; import de.sean.blockprot.bukkit.Translator; import de.sean.blockprot.bukkit.nbt.BlockAccessFlag; +import de.sean.blockprot.bukkit.nbt.BlockNBTHandler; import de.sean.blockprot.bukkit.nbt.FriendHandler; import de.sean.blockprot.bukkit.nbt.FriendSupportingHandler; import de.sean.blockprot.nbt.FriendModifyAction; import de.tr7zw.changeme.nbtapi.NBTCompound; import org.bukkit.Bukkit; import org.bukkit.Material; +import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryCloseEvent; @@ -115,8 +117,17 @@ public void onClick(@NotNull InventoryClickEvent event, @NotNull InventoryState @Override public void onClose(@NotNull InventoryCloseEvent event, @NotNull InventoryState state) { - if (this.playerHandler != null && curFlags != null) + if (this.playerHandler != null && curFlags != null) { this.playerHandler.setAccessFlags(curFlags); + + final Block block = state.getBlock(); + if (block == null) return; + + final BlockNBTHandler nbtHandler = getNbtHandlerOrNull(block); + if (nbtHandler == null) return; + + nbtHandler.applyToOtherContainer(); + } } @Nullable From eb71ea618f9ea63e678c19949ee6892090dee1ae Mon Sep 17 00:00:00 2001 From: Swanty Date: Sun, 21 Jul 2024 11:47:43 +0300 Subject: [PATCH 3/8] Fix block permission bypass bug if player has existing state --- .../listeners/InventoryEventListener.java | 62 ++++++++++--------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/InventoryEventListener.java b/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/InventoryEventListener.java index a7c6e207..cb4fd9f8 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/InventoryEventListener.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/InventoryEventListener.java @@ -68,43 +68,45 @@ public void onInventoryClick(@NotNull InventoryClickEvent event) { } else { event.setCancelled(true); // Don't allow interaction in a menu. } + + return; } - } else { - // No state, let's check if they're in some block inventory. - try { - // Casting null does not trigger a ClassCastException. - if (event.getInventory().getHolder() == null) return; - BlockInventoryHolder blockHolder = (BlockInventoryHolder) event.getInventory().getHolder(); - if (BlockProt.getDefaultConfig().isLockable(blockHolder.getBlock().getType())) { - // Ok, we have a lockable block, check if they can write anything to this. - // TODO: Implement a Cache for this lookup, it seems to be quite expensive. - // We should probably use a MultiMap, or implement our own Key that - // can use multiple key objects, a Block and Player in this case. - BlockNBTHandler handler = new BlockNBTHandler(blockHolder.getBlock()); - String playerUuid = player.getUniqueId().toString(); + } - if (handler.isProtected() && !handler.isOwner(playerUuid)) { - final var friend = handler.getFriend(playerUuid); - if (friend.isPresent()) { - if (!friend.get().canWrite()) { - event.setCancelled(true); - } else if (!friend.get().canRead()) { - event.setCancelled(true); - player.closeInventory(); - } - } else { - // The player is not a friend and not the owner; they shouldn't have - // access anyway. - player.closeInventory(); + // No state, let's check if they're in some block inventory. + try { + // Casting null does not trigger a ClassCastException. + if (event.getInventory().getHolder() == null) return; + BlockInventoryHolder blockHolder = (BlockInventoryHolder) event.getInventory().getHolder(); + if (BlockProt.getDefaultConfig().isLockable(blockHolder.getBlock().getType())) { + // Ok, we have a lockable block, check if they can write anything to this. + // TODO: Implement a Cache for this lookup, it seems to be quite expensive. + // We should probably use a MultiMap, or implement our own Key that + // can use multiple key objects, a Block and Player in this case. + BlockNBTHandler handler = new BlockNBTHandler(blockHolder.getBlock()); + String playerUuid = player.getUniqueId().toString(); + + if (handler.isProtected() && !handler.isOwner(playerUuid)) { + final var friend = handler.getFriend(playerUuid); + if (friend.isPresent()) { + if (!friend.get().canWrite()) { + event.setCancelled(true); + } else if (!friend.get().canRead()) { event.setCancelled(true); + player.closeInventory(); } + } else { + // The player is not a friend and not the owner; they shouldn't have + // access anyway. + player.closeInventory(); + event.setCancelled(true); } } - } catch (ClassCastException e) { - // It's not a block, and it's therefore also not lockable. - // This is probably some other custom inventory from another - // plugin, or possibly some entity inventory, e.g. villagers. } + } catch (ClassCastException e) { + // It's not a block, and it's therefore also not lockable. + // This is probably some other custom inventory from another + // plugin, or possibly some entity inventory, e.g. villagers. } } From 436a2858b5b2ae51b17cbe3f5495ba22598800f4 Mon Sep 17 00:00:00 2001 From: Swanty Date: Sun, 21 Jul 2024 11:47:49 +0300 Subject: [PATCH 4/8] Fix InventoryClickEvent docs says that we can't call closeInventory directly --- .../blockprot/bukkit/listeners/InventoryEventListener.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/InventoryEventListener.java b/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/InventoryEventListener.java index cb4fd9f8..5408f100 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/InventoryEventListener.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/InventoryEventListener.java @@ -93,13 +93,13 @@ public void onInventoryClick(@NotNull InventoryClickEvent event) { event.setCancelled(true); } else if (!friend.get().canRead()) { event.setCancelled(true); - player.closeInventory(); + Bukkit.getScheduler().runTask(BlockProt.getInstance(), player::closeInventory); } } else { // The player is not a friend and not the owner; they shouldn't have // access anyway. - player.closeInventory(); event.setCancelled(true); + Bukkit.getScheduler().runTask(BlockProt.getInstance(), player::closeInventory); } } } From 78723c203c1fc9e5501539cf4d5513ef8c1aaa24 Mon Sep 17 00:00:00 2001 From: Swanty Date: Sun, 21 Jul 2024 11:49:33 +0300 Subject: [PATCH 5/8] Fix friend permissions for a sign block not checked --- .../bukkit/listeners/BlockEventListener.java | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/BlockEventListener.java b/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/BlockEventListener.java index d1fa74d4..7ff7ef42 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/BlockEventListener.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/BlockEventListener.java @@ -39,6 +39,7 @@ import org.bukkit.NamespacedKey; import org.bukkit.block.Block; import org.bukkit.block.BlockState; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -227,10 +228,19 @@ public void onBlockPhysics(@NotNull final BlockPhysicsEvent event) { @EventHandler public void onSignChanged(@NotNull final SignChangeEvent event) { - if (BlockProt.getDefaultConfig().isLockableBlock(event.getBlock().getType())) { - final var handler = new BlockNBTHandler(event.getBlock()); - if (handler.isProtected() && !handler.isOwner(event.getPlayer().getUniqueId())) - event.setCancelled(true); - } + final Block block = event.getBlock(); + if (!BlockProt.getDefaultConfig().isLockableBlock(block.getType())) return; + + final BlockNBTHandler handler = new BlockNBTHandler(block); + if (!handler.isProtected()) return; + + final Player player = event.getPlayer(); + final String playerUuid = player.getUniqueId().toString(); + if (handler.isOwner(playerUuid)) return; + + final var friend = handler.getFriend(playerUuid); + if (friend.isPresent() && friend.get().canWrite()) return; + + event.setCancelled(true); } } From 4c52f2b338f86587d4f0fb21832385a92eaccde3 Mon Sep 17 00:00:00 2001 From: Swanty Date: Sun, 21 Jul 2024 11:56:54 +0300 Subject: [PATCH 6/8] Fix double chest not handled in onInventoryClick --- .../bukkit/listeners/InventoryEventListener.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/InventoryEventListener.java b/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/InventoryEventListener.java index 5408f100..3e5a3e64 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/InventoryEventListener.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/InventoryEventListener.java @@ -77,13 +77,23 @@ public void onInventoryClick(@NotNull InventoryClickEvent event) { try { // Casting null does not trigger a ClassCastException. if (event.getInventory().getHolder() == null) return; - BlockInventoryHolder blockHolder = (BlockInventoryHolder) event.getInventory().getHolder(); - if (BlockProt.getDefaultConfig().isLockable(blockHolder.getBlock().getType())) { + final InventoryHolder holder = event.getInventory().getHolder(); + + Block block; + if (holder instanceof BlockInventoryHolder blockHolder) { + block = blockHolder.getBlock(); + } else if (holder instanceof DoubleChest doubleChestHolder) { + block = doubleChestHolder.getLocation().getBlock(); + } else { + return; + } + + if (BlockProt.getDefaultConfig().isLockable(block.getType())) { // Ok, we have a lockable block, check if they can write anything to this. // TODO: Implement a Cache for this lookup, it seems to be quite expensive. // We should probably use a MultiMap, or implement our own Key that // can use multiple key objects, a Block and Player in this case. - BlockNBTHandler handler = new BlockNBTHandler(blockHolder.getBlock()); + BlockNBTHandler handler = new BlockNBTHandler(block); String playerUuid = player.getUniqueId().toString(); if (handler.isProtected() && !handler.isOwner(playerUuid)) { From 507ed6c9f0ea040e9e22b6dfa92afaed6fbcc9f6 Mon Sep 17 00:00:00 2001 From: Swanty Date: Sun, 21 Jul 2024 13:53:56 +0300 Subject: [PATCH 7/8] Update spigot-api to 1.21 --- spigot/build.gradle.kts | 2 +- .../blockprot/bukkit/inventories/BlockProtInventory.java | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/spigot/build.gradle.kts b/spigot/build.gradle.kts index 9f79de71..028fb823 100644 --- a/spigot/build.gradle.kts +++ b/spigot/build.gradle.kts @@ -39,7 +39,7 @@ dependencies { implementation(project(":common")) // Spigot - compileOnly("org.spigotmc:spigot-api:1.20.2-R0.1-SNAPSHOT") + compileOnly("org.spigotmc:spigot-api:1.21-R0.1-SNAPSHOT") compileOnly("org.apache.commons:commons-lang3:3.13.0") // bStats diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/BlockProtInventory.java b/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/BlockProtInventory.java index dfd40dff..18ef2ac3 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/BlockProtInventory.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/BlockProtInventory.java @@ -573,9 +573,9 @@ protected ItemStack toggleEnchants(@NotNull ItemStack stack, final @Nullable Boo } if (meta != null) { if (meta.hasEnchants() && (toggle == null || !toggle)) { - meta.removeEnchant(Enchantment.ARROW_INFINITE); + meta.removeEnchant(Enchantment.INFINITY); } else if (!meta.hasEnchants() && (toggle == null || toggle)) { - meta.addEnchant(Enchantment.ARROW_INFINITE, 1, true); + meta.addEnchant(Enchantment.INFINITY, 1, true); } meta.addItemFlags(ItemFlag.HIDE_ENCHANTS); stack.setItemMeta(meta); @@ -644,10 +644,10 @@ protected ItemStack toggleOption(@NotNull ItemStack stack, final @Nullable Boole } if (meta.hasEnchants() && (toggle == null || !toggle)) { - meta.removeEnchant(Enchantment.ARROW_INFINITE); + meta.removeEnchant(Enchantment.INFINITY); meta.setDisplayName(name + ": " + Translator.get(TranslationKey.DISABLED)); } else if (!meta.hasEnchants() && (toggle == null || toggle)) { - meta.addEnchant(Enchantment.ARROW_INFINITE, 1, true); + meta.addEnchant(Enchantment.INFINITY, 1, true); meta.setDisplayName(name + ": " + Translator.get(TranslationKey.ENABLED)); } meta.addItemFlags(ItemFlag.HIDE_ENCHANTS); From 295ab9374b20d3a930582fb6c436504a9d2e66da Mon Sep 17 00:00:00 2001 From: Swanty Date: Sun, 21 Jul 2024 13:55:24 +0300 Subject: [PATCH 8/8] Fix door, trapdoor and gate permissions not checked --- .../bukkit/listeners/InteractEventListener.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/InteractEventListener.java b/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/InteractEventListener.java index 127675ce..d7e38ff5 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/InteractEventListener.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/InteractEventListener.java @@ -29,7 +29,10 @@ import net.md_5.bungee.api.chat.hover.content.Text; import org.bukkit.Bukkit; import org.bukkit.Material; +import org.bukkit.block.data.type.Door; +import org.bukkit.block.data.type.Gate; import org.bukkit.block.data.type.Lectern; +import org.bukkit.block.data.type.TrapDoor; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -64,14 +67,15 @@ public void playerInteract(PlayerInteractEvent event) { sendMessage(player, Translator.get(TranslationKey.MESSAGES__NO_PERMISSION)); } else { BlockNBTHandler handler = new BlockNBTHandler(event.getClickedBlock()); + final var blockData = event.getClickedBlock().getBlockData(); if (!(handler.canAccess(player.getUniqueId().toString()) || player.hasPermission(Permissions.BYPASS.key()))) { event.setCancelled(true); sendMessage(player, Translator.get(TranslationKey.MESSAGES__NO_PERMISSION)); - } else if (event.getClickedBlock().getType() == Material.LECTERN && !handler.isOwner(player.getUniqueId())) { + } else if (event.getClickedBlock().getType() == Material.LECTERN && handler.isProtected() && !handler.isOwner(player.getUniqueId())) { // With Lecterns you place the books by interacting with the block. canAccess will return true because the // player has the READ permission, but this should not be allowed in this case. In the case that the player // wants to take the book from the lectern (hasBook returns true) we already listen for PlayerTakeLecternBookEvent. - final var lectern = (Lectern)event.getClickedBlock().getBlockData(); + final var lectern = (Lectern)blockData; if (!lectern.hasBook()) { final var friend = handler.getFriend(player.getUniqueId().toString()); if (friend.isEmpty() || !friend.get().canWrite()) { @@ -80,6 +84,13 @@ public void playerInteract(PlayerInteractEvent event) { sendMessage(player, Translator.get(TranslationKey.MESSAGES__NO_PERMISSION)); } } + } else if ((blockData instanceof Door || blockData instanceof TrapDoor || blockData instanceof Gate) && handler.isProtected() && !handler.isOwner(player.getUniqueId())) { + final var friend = handler.getFriend(player.getUniqueId().toString()); + if (friend.isEmpty() || !friend.get().canWrite()) { + // The player cannot write and therefore is not allowed to change the door open state. + event.setCancelled(true); + sendMessage(player, Translator.get(TranslationKey.MESSAGES__NO_PERMISSION)); + } } else if (!(new PlayerSettingsHandler(player).hasPlayerInteractedWithMenu())) { Long timestamp = LockHintMessageCooldown.getTimestamp(player); if (timestamp == null || timestamp < System.currentTimeMillis() - (BlockProt.getDefaultConfig().getLockHintCooldown() * 1000)) { // 10 seconds in milliseconds