From 7aebce806a4f91688a41547ef863ebccdb80fdae Mon Sep 17 00:00:00 2001 From: DaTTV Date: Thu, 20 Feb 2025 13:47:43 +0100 Subject: [PATCH] Added (untested) ProtectedBlocks --- .../plugins/papermc/blazesmp/BlazeSMP.java | 4 +- .../blazesmp/command/ClaimCommand.java | 4 +- ...nager.java => ChunkInventoryListener.java} | 4 +- .../listener/ProtectedBlockListener.java | 213 ++++++++++++++++++ .../module/manager/ProtectedBlocks.java | 18 +- .../papermc/blazesmp/tasks/TabListTimer.java | 4 +- src/main/resources/storage/messages.json | 24 +- 7 files changed, 257 insertions(+), 14 deletions(-) rename src/main/java/me/freezy/plugins/papermc/blazesmp/listener/{ChunkInventoryManager.java => ChunkInventoryListener.java} (98%) create mode 100644 src/main/java/me/freezy/plugins/papermc/blazesmp/listener/ProtectedBlockListener.java diff --git a/src/main/java/me/freezy/plugins/papermc/blazesmp/BlazeSMP.java b/src/main/java/me/freezy/plugins/papermc/blazesmp/BlazeSMP.java index 3d29a3d..010d7af 100644 --- a/src/main/java/me/freezy/plugins/papermc/blazesmp/BlazeSMP.java +++ b/src/main/java/me/freezy/plugins/papermc/blazesmp/BlazeSMP.java @@ -6,7 +6,6 @@ import me.freezy.plugins.papermc.blazesmp.command.ClanCommand; import me.freezy.plugins.papermc.blazesmp.command.HomeCommand; import me.freezy.plugins.papermc.blazesmp.command.ReportCommand; import me.freezy.plugins.papermc.blazesmp.listener.*; -import me.freezy.plugins.papermc.blazesmp.module.Clan; import me.freezy.plugins.papermc.blazesmp.module.manager.Clans; import me.freezy.plugins.papermc.blazesmp.module.manager.Homes; import me.freezy.plugins.papermc.blazesmp.module.manager.L4M4; @@ -82,9 +81,10 @@ public final class BlazeSMP extends JavaPlugin { pm.registerEvents(new PlayerChatListener(), this); pm.registerEvents(new PlayerCommandBlockerListener(), this); pm.registerEvents(new PlayerClaimListener(), this); - pm.registerEvents(new ChunkInventoryManager(), this); + pm.registerEvents(new ChunkInventoryListener(), this); pm.registerEvents(new PressurePlateListener(), this); pm.registerEvents(new PlayerVsPlayerListener(clans), this); + pm.registerEvents(new ProtectedBlockListener(), this); this.log.info("Registered EventListeners!"); this.log.info("Starting Timer tasks..."); diff --git a/src/main/java/me/freezy/plugins/papermc/blazesmp/command/ClaimCommand.java b/src/main/java/me/freezy/plugins/papermc/blazesmp/command/ClaimCommand.java index 2a138b8..c3b4eab 100644 --- a/src/main/java/me/freezy/plugins/papermc/blazesmp/command/ClaimCommand.java +++ b/src/main/java/me/freezy/plugins/papermc/blazesmp/command/ClaimCommand.java @@ -2,7 +2,7 @@ package me.freezy.plugins.papermc.blazesmp.command; import me.freezy.plugins.papermc.blazesmp.BlazeSMP; import me.freezy.plugins.papermc.blazesmp.command.util.SimpleCommand; -import me.freezy.plugins.papermc.blazesmp.listener.ChunkInventoryManager; +import me.freezy.plugins.papermc.blazesmp.listener.ChunkInventoryListener; import me.freezy.plugins.papermc.blazesmp.module.Clan; import me.freezy.plugins.papermc.blazesmp.module.manager.Clans; import me.freezy.plugins.papermc.blazesmp.module.manager.L4M4; @@ -38,7 +38,7 @@ public class ClaimCommand extends SimpleCommand { } else { if (label.equalsIgnoreCase("claim")) { if (args.length != 0 && args[0].equalsIgnoreCase("see")) { - ChunkInventoryManager.openInv(player); + ChunkInventoryListener.openInv(player); return true; } Clan playerClan = clans.getClanByMember(playerUUID); diff --git a/src/main/java/me/freezy/plugins/papermc/blazesmp/listener/ChunkInventoryManager.java b/src/main/java/me/freezy/plugins/papermc/blazesmp/listener/ChunkInventoryListener.java similarity index 98% rename from src/main/java/me/freezy/plugins/papermc/blazesmp/listener/ChunkInventoryManager.java rename to src/main/java/me/freezy/plugins/papermc/blazesmp/listener/ChunkInventoryListener.java index f3437a2..673cdda 100644 --- a/src/main/java/me/freezy/plugins/papermc/blazesmp/listener/ChunkInventoryManager.java +++ b/src/main/java/me/freezy/plugins/papermc/blazesmp/listener/ChunkInventoryListener.java @@ -19,7 +19,7 @@ import org.bukkit.inventory.meta.SkullMeta; import java.util.*; -public class ChunkInventoryManager implements Listener { +public class ChunkInventoryListener implements Listener { // Speichert pro Spieler den aktuellen Seitenindex private final PaginatedData paginatedData = new PaginatedData(); @@ -32,7 +32,7 @@ public class ChunkInventoryManager implements Listener { )); return; } - new ChunkInventoryManager().chunksInv(player, clan); + new ChunkInventoryListener().chunksInv(player, clan); } /** diff --git a/src/main/java/me/freezy/plugins/papermc/blazesmp/listener/ProtectedBlockListener.java b/src/main/java/me/freezy/plugins/papermc/blazesmp/listener/ProtectedBlockListener.java new file mode 100644 index 0000000..a400da4 --- /dev/null +++ b/src/main/java/me/freezy/plugins/papermc/blazesmp/listener/ProtectedBlockListener.java @@ -0,0 +1,213 @@ +package me.freezy.plugins.papermc.blazesmp.listener; + +import me.freezy.plugins.papermc.blazesmp.BlazeSMP; +import me.freezy.plugins.papermc.blazesmp.module.ProtectedBlock; +import me.freezy.plugins.papermc.blazesmp.module.manager.L4M4; +import me.freezy.plugins.papermc.blazesmp.module.manager.ProtectedBlocks; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import org.bukkit.*; +import org.bukkit.block.*; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryMoveItemEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.*; + +public class ProtectedBlockListener implements Listener { + + private final MiniMessage miniMessage = MiniMessage.miniMessage(); + private final ProtectedBlocks protectedBlocks = BlazeSMP.getInstance().getProtectedBlocks(); + + // Supported storage block types + private final Set STORAGE_BLOCKS = Set.of( + Material.CHEST, Material.TRAPPED_CHEST, Material.BARREL, + Material.HOPPER, Material.DROPPER, Material.DISPENSER, + Material.FURNACE, Material.BLAST_FURNACE, Material.SMOKER + ); + + @EventHandler + public void onItemTransferHopperEvent(InventoryMoveItemEvent event) { + Block destinationBlock = Objects.requireNonNull(event.getDestination().getLocation()).getBlock(); + if (isProtected(destinationBlock)) { + event.setCancelled(true); + } + } + + @EventHandler + public void onBlockInteractEvent(PlayerInteractEvent event) { + Player player = event.getPlayer(); + Block block = event.getClickedBlock(); + if (block == null || !STORAGE_BLOCKS.contains(block.getType())) return; + + ItemStack mainHandItem = player.getInventory().getItemInMainHand(); + ProtectedBlock protectedBlock = getProtectedBlock(block); + + // Owner (if the block is locked) can always access the management GUI. + if (player.isSneaking() && protectedBlock != null && + protectedBlock.owner().equals(player.getUniqueId())) { + openManageKeysGUI(player, block); + return; + } + + // Shift + Right-click with a trial key: Relink the key to the new container. + if (player.isSneaking() && isValidKey(mainHandItem)) { + relinkKey(player, mainHandItem, block); + return; + } + + // Shift + Right-click without a key (and if the container is not locked) → open lock GUI. + if (player.isSneaking() && protectedBlock == null) { + openLockGUI(player, block); + return; + } + + // Normal right-click with a valid key: open the container inventory. + if (protectedBlock != null && isValidKey(mainHandItem, protectedBlock.key())) { + if (block.getState() instanceof Container container) { + player.openInventory(container.getInventory()); + } + return; + } + + // Normal right-click without a key on a locked container: show locked message. + if (protectedBlock != null) { + String lockedMsg = String.format(L4M4.get("storage.locked"), "minecraft:trial_key"); + player.sendMessage(miniMessage.deserialize(lockedMsg)); + } + } + + private void openLockGUI(Player player, Block block) { + String titleRaw = String.format(L4M4.get("storage.lock_gui_title"), block.getType().toString()); + Inventory lockInventory = Bukkit.createInventory(player, InventoryType.HOPPER, + miniMessage.deserialize(titleRaw)); + + UUID lockUUID = UUID.randomUUID(); + ItemStack trialKey1 = createTrialKey(lockUUID); + ItemStack trialKey2 = createTrialKey(lockUUID); + + lockInventory.setItem(0, trialKey1); + lockInventory.setItem(4, trialKey2); + + player.openInventory(lockInventory); + // Save the protected block. + protectedBlocks.addBlock(new ProtectedBlock(player.getUniqueId(), lockUUID, block.getLocation())); + } + + private void openManageKeysGUI(Player player, Block block) { + String titleRaw = String.format(L4M4.get("storage.manage_gui_title"), block.getType().toString()); + Inventory manageKeysInventory = Bukkit.createInventory(player, InventoryType.HOPPER, + miniMessage.deserialize(titleRaw)); + + ItemStack addKey = new ItemStack(Material.PAPER); + ItemMeta addKeyMeta = addKey.getItemMeta(); + addKeyMeta.displayName(miniMessage.deserialize(L4M4.get("storage.add_key"))); + addKey.setItemMeta(addKeyMeta); + + ItemStack removeKey = new ItemStack(Material.BARRIER); + ItemMeta removeKeyMeta = removeKey.getItemMeta(); + removeKeyMeta.displayName(miniMessage.deserialize(L4M4.get("storage.remove_key"))); + removeKey.setItemMeta(removeKeyMeta); + + manageKeysInventory.setItem(1, addKey); + manageKeysInventory.setItem(3, removeKey); + + player.openInventory(manageKeysInventory); + } + + private void relinkKey(Player player, ItemStack key, Block newBlock) { + UUID newLockUUID = UUID.randomUUID(); + ItemMeta meta = key.getItemMeta(); + if (meta != null) { + meta.lore(List.of( + miniMessage.deserialize(String.format(L4M4.get("storage.linked_to"), newLockUUID.toString())), + miniMessage.deserialize(L4M4.get("storage.not_usable_on_vaults")) + )); + key.setItemMeta(meta); + } + protectedBlocks.addBlock(new ProtectedBlock(player.getUniqueId(), newLockUUID, newBlock.getLocation())); + player.sendMessage(miniMessage.deserialize(L4M4.get("storage.link_success"))); + } + + @EventHandler + public void onInventoryClick(InventoryClickEvent event) { + String title = event.getView().title().toString(); + if (title.contains(L4M4.get("storage.lock_gui_title_prefix")) || + title.contains(L4M4.get("storage.manage_gui_title_prefix"))) { + event.setCancelled(true); + HumanEntity entity = event.getWhoClicked(); + if (entity instanceof Player player) { + player.sendMessage(miniMessage.deserialize(L4M4.get("storage.action_completed"))); + player.closeInventory(); + } + } + } + + @EventHandler + public void onBlockBreak(BlockBreakEvent event) { + Player player = event.getPlayer(); + Block block = event.getBlock(); + ProtectedBlock protectedBlock = getProtectedBlock(block); + + if (protectedBlock != null) { + if (protectedBlock.owner().equals(player.getUniqueId())) { + protectedBlocks.removeBlock(protectedBlock); + player.sendMessage(miniMessage.deserialize(L4M4.get("storage.removed_lock"))); + } else { + event.setCancelled(true); + player.sendMessage(miniMessage.deserialize(L4M4.get("storage.break_denied"))); + } + } + } + + @EventHandler + public void onExplosion(EntityExplodeEvent event) { + event.blockList().removeIf(this::isProtected); + } + + private ItemStack createTrialKey(UUID lockUUID) { + ItemStack trialKey = new ItemStack(Material.TRIPWIRE_HOOK); + ItemMeta meta = trialKey.getItemMeta(); + if (meta != null) { + meta.displayName(miniMessage.deserialize(L4M4.get("storage.trial_key"))); + meta.lore(List.of( + miniMessage.deserialize(String.format(L4M4.get("storage.linked_to"), lockUUID.toString())), + miniMessage.deserialize(L4M4.get("storage.not_usable_on_vaults")) + )); + trialKey.setItemMeta(meta); + } + return trialKey; + } + + private boolean isValidKey(ItemStack item) { + return item != null && item.getType() == Material.TRIPWIRE_HOOK && item.hasItemMeta(); + } + + private boolean isValidKey(ItemStack item, UUID lockUUID) { + if (!isValidKey(item)) return false; + ItemMeta meta = item.getItemMeta(); + if (meta == null || meta.lore() == null) return false; + return Objects.requireNonNull(meta.lore()).stream().anyMatch(line -> line.contains(Component.text(lockUUID.toString()))); + } + + private ProtectedBlock getProtectedBlock(Block block) { + return protectedBlocks.getBlocks().stream() + .filter(pb -> pb.location().equals(block.getLocation())) + .findFirst() + .orElse(null); + } + + private boolean isProtected(Block block) { + return getProtectedBlock(block) != null; + } +} diff --git a/src/main/java/me/freezy/plugins/papermc/blazesmp/module/manager/ProtectedBlocks.java b/src/main/java/me/freezy/plugins/papermc/blazesmp/module/manager/ProtectedBlocks.java index e0d1675..6c831ae 100644 --- a/src/main/java/me/freezy/plugins/papermc/blazesmp/module/manager/ProtectedBlocks.java +++ b/src/main/java/me/freezy/plugins/papermc/blazesmp/module/manager/ProtectedBlocks.java @@ -7,12 +7,15 @@ import me.freezy.plugins.papermc.blazesmp.module.ProtectedBlock; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; import java.util.UUID; import java.util.logging.Logger; @@ -27,10 +30,10 @@ public class ProtectedBlocks { private static final Logger LOGGER = Logger.getLogger("ProtectedBlocks"); // List of protected blocks - private final List blocks; + private final LinkedList blocks; public ProtectedBlocks() { - this.blocks = new ArrayList<>(); + this.blocks = new LinkedList<>(); } /** @@ -124,4 +127,15 @@ public class ProtectedBlocks { String y; String z; } + + public void addBlock(ProtectedBlock block) { + blocks.add(block); + this.save(); + } + + public boolean removeBlock(ProtectedBlock block) { + boolean bool = blocks.remove(block); + this.save(); + return bool; + } } diff --git a/src/main/java/me/freezy/plugins/papermc/blazesmp/tasks/TabListTimer.java b/src/main/java/me/freezy/plugins/papermc/blazesmp/tasks/TabListTimer.java index a6a0a17..73bce71 100644 --- a/src/main/java/me/freezy/plugins/papermc/blazesmp/tasks/TabListTimer.java +++ b/src/main/java/me/freezy/plugins/papermc/blazesmp/tasks/TabListTimer.java @@ -26,10 +26,10 @@ public class TabListTimer extends BukkitRunnable { // Falls eine Liste leer ist, setzen wir eine Fallback-Nachricht if (header.isEmpty()) { - header.add("Error"); + header.add(L4M4.get("error.not_found")); } if (footer.isEmpty()) { - footer.add("Error"); + footer.add(L4M4.get("error.not_found")); } } diff --git a/src/main/resources/storage/messages.json b/src/main/resources/storage/messages.json index dda198b..aface9e 100644 --- a/src/main/resources/storage/messages.json +++ b/src/main/resources/storage/messages.json @@ -29,6 +29,7 @@ "error.chunk_already_claimed": "Chunk is already claimed!", "error.max_claims_reached": "You cannot claim more than 50 chunks!", "error.chunk_too_close_to_spawn": "Chunk is too close to spawn!", + "error.not_found": "Not Found", "usage.clan_create": "Usage: /clan create ", "usage.clan_chat": "Usage: /clan chat ", @@ -121,8 +122,23 @@ "tablist.header": [ "BlazeSMP" ], - "tablist.footer": [ - "hosted by merged.games", - "made by BlazeHC Team & Freezy/DaTTV" - ] + "tablist.footer": [ + "hosted by merged.games", + "made by BlazeHC Team & Freezy/DaTTV" + ], + + "storage.locked": "This storage is locked! You need a %s to open it.", + "storage.lock_gui_title": "Lock & Link Storage - %s", + "storage.lock_gui_title_prefix": "Lock & Link Storage", + "storage.manage_gui_title": "Manage Keys - %s", + "storage.manage_gui_title_prefix": "Manage Keys", + "storage.add_key": "Add Key", + "storage.remove_key": "Remove Key", + "storage.linked_to": "Linked to: %s", + "storage.not_usable_on_vaults": "Not usable on vaults", + "storage.link_success": "Your key has been successfully linked to the new storage!", + "storage.action_completed": "Action completed successfully!", + "storage.removed_lock": "You removed the lock from this storage.", + "storage.break_denied": "You cannot break this locked storage!", + "storage.trial_key": "Linked Trial Key" }