diff --git a/config.yml b/config.yml index bcd95b4..1a7aa37 100644 --- a/config.yml +++ b/config.yml @@ -43,4 +43,6 @@ lockables: - DARK_OAK_DOOR - IRON_DOOR_BLOCK protection-exempt: -- nothing \ No newline at end of file +- nothing +disable-worlds: +- world_without_lockettepro \ No newline at end of file diff --git a/lang_zh-tw.yml b/lang_zh-tw.yml new file mode 100644 index 0000000..d82fa4a --- /dev/null +++ b/lang_zh-tw.yml @@ -0,0 +1,32 @@ +# Traditional Chinese translation by MapleHuang(stan60250@gmail.com) +command-usage: "&6[LockettePro]&bLockettePro 插件說明\n&c1. 為箱子新增或刪除使用者,首先右鍵選取一個告示牌, 然後輸入/lock 行號 玩家名稱 即可\n&c2. 管理員重新載入插件設定,使用 /lock reload\nLockettePro by connection_lost" +you-can-quick-lock-it: '&6[LockettePro]&6手持告示牌對目標方塊點右鍵即可上鎖' +you-can-manual-lock-it: '&6[LockettePro]&6貼上一個告示牌並寫上[Private]即可上鎖' +config-reloaded: '&6[LockettePro]&a設定已重新載入' +no-permission: '&6[LockettePro]&c權限不足! 無法使用該指令' +no-sign-selected: '&6[LockettePro]&c請先右鍵選擇一個告示牌' +sign-need-reselect: '&6[LockettePro]&c請重新選擇一個告示牌' +line-is-too-long: '&6[LockettePro]&c設定輸入告示牌的文字過長!' +cannot-change-this-line: '&6[LockettePro]&c無法修改這一行' +sign-changed: '&6[LockettePro]&a告示牌已修改' +locked-quick: '&6[LockettePro]&a已成功上鎖' +additional-sign-added-quick: '&6[LockettePro]&a更多的使用者告示牌已新增' +cannot-lock-quick: '&6[LockettePro]&c這個方塊無法上鎖' +cannot-add-additional-sign-quick: '&6[LockettePro]&c無法在這裡新增告示牌' +locked-manual: '&6[LockettePro]&a已成功上鎖' +additional-sign-added-manual: '&6[LockettePro]&a更多的使用者告示牌已新增' +cannot-lock-manual: '&6[LockettePro]&c這個方塊無法上鎖' +cannot-add-additional-sign-manual: '&6[LockettePro]&c無法在這裡新增告示牌' +not-locked-yet-manual: '&6[LockettePro]&c這個方塊還沒有上鎖' +cannot-lock-door-nearby-manual: '&6[LockettePro]&c這附近已經有其他人上鎖的門' +block-already-locked-manual: '&6[LockettePro]&c這個方塊已經被上鎖了' +block-is-not-lockable: '&6[LockettePro]&c這個方塊無法上鎖' +sign-selected: '&6[LockettePro]&a您選擇了一個告示牌,輸入/lock 行號 玩家名稱 來修改它' +break-own-lock-sign: '&6[LockettePro]&a上鎖的告示牌已拆除' +cannot-break-this-lock-sign: '&6[LockettePro]&c無法拆除其他玩家上鎖的告示牌' +break-own-additional-sign: '&6[LockettePro]&a更多使用者的告示牌已拆除' +break-redundant-additional-sign: '&6[LockettePro]&a更多使用者的告示牌已拆除' +cannot-break-this-additional-sign: '&6[LockettePro]&c無法拆除其他玩家上鎖的告示牌' +block-is-locked: '&6[LockettePro]&c這個方塊已被上鎖' +cannot-interfere-with-others: '&6[LockettePro]&c無法在已上鎖的方塊附近放置其他物件' +sign-error: '&4[ERROR]' \ No newline at end of file diff --git a/plugin.yml b/plugin.yml index c49b56a..9dd08fe 100644 --- a/plugin.yml +++ b/plugin.yml @@ -1,7 +1,7 @@ name: LockettePro main: me.crafter.mc.lockettepro.LockettePro author: connection_lost -softdepend: [Vault, WorldGuard, Residence, Towny, ProtocolLib, Factions, ASkyBlock, PlotSquared, SimpleClans] +softdepend: [Vault, WorldGuard, Residence, Towny, ProtocolLib, Factions, ASkyBlock, PlotSquared, SimpleClans, GriefPrevention] loadbefore: [SignShop] version: 2.8.1 description: > diff --git a/src/me/crafter/mc/lockettepro/BlockEnvironmentListener.java b/src/me/crafter/mc/lockettepro/BlockEnvironmentListener.java index e75d20c..62bb4f3 100644 --- a/src/me/crafter/mc/lockettepro/BlockEnvironmentListener.java +++ b/src/me/crafter/mc/lockettepro/BlockEnvironmentListener.java @@ -5,7 +5,10 @@ import org.bukkit.block.Block; import org.bukkit.block.BlockState; import org.bukkit.entity.Enderman; +import org.bukkit.entity.Silverfish; import org.bukkit.entity.Villager; +import org.bukkit.entity.Wither; +import org.bukkit.entity.Zombie; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -13,6 +16,7 @@ import org.bukkit.event.block.BlockPistonExtendEvent; import org.bukkit.event.block.BlockPistonRetractEvent; import org.bukkit.event.block.BlockRedstoneEvent; +import org.bukkit.event.entity.EntityChangeBlockEvent; import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.event.entity.EntityInteractEvent; import org.bukkit.event.world.StructureGrowEvent; @@ -22,7 +26,7 @@ public class BlockEnvironmentListener implements Listener{ // Prevent explosion break block @EventHandler(priority = EventPriority.HIGH) public void onEntityExplode(EntityExplodeEvent event){ - if (Config.isProtectionExempted("explosion")) return; + if (Config.isProtectionExempted("explosion")) return; Iterator it = event.blockList().iterator(); while (it.hasNext()) { Block block = it.next(); @@ -56,7 +60,7 @@ public void onStructureGrow(StructureGrowEvent event){ // Prevent piston extend break lock @EventHandler(priority = EventPriority.HIGH) public void onPistonExtend(BlockPistonExtendEvent event){ - if (Config.isProtectionExempted("piston")) return; + if (Config.isProtectionExempted("piston")) return; for (Block block : event.getBlocks()){ if (LocketteProAPI.isProtected(block)){ event.setCancelled(true); @@ -89,7 +93,7 @@ public void onBlockRedstoneChange(BlockRedstoneEvent event){ // Prevent villager open door @EventHandler(priority = EventPriority.HIGH) public void onVillagerOpenDoor(EntityInteractEvent event){ - if (Config.isProtectionExempted("villager")) return; + if (Config.isProtectionExempted("villager")) return; // Explicitly to villager vs all doors if (event.getEntity() instanceof Villager && (LocketteProAPI.isSingleDoorBlock(event.getBlock()) || LocketteProAPI.isDoubleDoorBlock(event.getBlock())) && @@ -98,13 +102,17 @@ public void onVillagerOpenDoor(EntityInteractEvent event){ } } - // Prevent Enderman take block + // Prevent mob change block @EventHandler(priority = EventPriority.HIGH) - public void onEndermanGreif(EntityInteractEvent event){ - if (Config.isProtectionExempted("enderman")) return; - if (event.getEntity() instanceof Enderman && LocketteProAPI.isProtected(event.getBlock())){ - event.setCancelled(true); - } + public void onMobChangeBlock(EntityChangeBlockEvent event) { + if ((event.getEntity() instanceof Enderman && !Config.isProtectionExempted("enderman")) ||// enderman pick up/place block + (event.getEntity() instanceof Wither && !Config.isProtectionExempted("wither")) ||// wither break block + (event.getEntity() instanceof Zombie && !Config.isProtectionExempted("zombie")) ||// zombie break door + (event.getEntity() instanceof Silverfish && !Config.isProtectionExempted("silverfish"))){ + if (LocketteProAPI.isProtected(event.getBlock())){ + event.setCancelled(true); + } + }// ignore other reason (boat break lily pad, arrow ignite tnt, etc) } } diff --git a/src/me/crafter/mc/lockettepro/BlockPlayerListener.java b/src/me/crafter/mc/lockettepro/BlockPlayerListener.java index fa04ded..bd849fc 100644 --- a/src/me/crafter/mc/lockettepro/BlockPlayerListener.java +++ b/src/me/crafter/mc/lockettepro/BlockPlayerListener.java @@ -8,6 +8,7 @@ import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.BlockState; +import org.bukkit.block.Chest; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -16,18 +17,23 @@ import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.block.SignChangeEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.DoubleChestInventory; import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.InventoryHolder; import org.bukkit.material.Openable; public class BlockPlayerListener implements Listener { // Quick protect for chests - @EventHandler(priority = EventPriority.NORMAL) + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPlayerQuickLockChest(PlayerInteractEvent event){ - if (event.isCancelled()) return; // Check quick lock enabled if (Config.getQuickProtectAction() == (byte)0) return; + // Check world enabled + if (Config.isDisabledWorld(event.getPlayer().getWorld().getName())) return; // Get player and action info Action action = event.getAction(); Player player = event.getPlayer(); @@ -165,7 +171,7 @@ public void onManualLock(SignChangeEvent event){ } // Player select sign - @EventHandler(priority = EventPriority.LOW) + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) public void playerSelectSign(PlayerInteractEvent event){ if (event.getAction() == Action.RIGHT_CLICK_BLOCK && event.getClickedBlock().getType() == Material.WALL_SIGN){ Block block = event.getClickedBlock(); @@ -180,9 +186,8 @@ public void playerSelectSign(PlayerInteractEvent event){ } // Player break sign - @EventHandler(priority = EventPriority.HIGH) + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void onAttemptBreakSign(BlockBreakEvent event){ - if (event.isCancelled()) return; Block block = event.getBlock(); Player player = event.getPlayer(); if (player.hasPermission("lockettepro.admin.break")) return; @@ -214,9 +219,8 @@ public void onAttemptBreakSign(BlockBreakEvent event){ } // Protect block from being destroyed - @EventHandler(priority = EventPriority.HIGH) + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void onAttemptBreakLockedBlocks(BlockBreakEvent event){ - if (event.isCancelled()) return; Block block = event.getBlock(); Player player = event.getPlayer(); if (LocketteProAPI.isLocked(block) || LocketteProAPI.isUpDownLockedDoor(block)){ @@ -246,7 +250,7 @@ public void onAttemptInteractLockedBlocks(PlayerInteractEvent event){ case LEFT_CLICK_BLOCK: case RIGHT_CLICK_BLOCK: Player player = event.getPlayer(); - if (((LocketteProAPI.isLocked(block) && !LocketteProAPI.isUser(block, player)) || + if (((LocketteProAPI.isLocked(block) && !LocketteProAPI.isUser(block, player) && !LocketteProAPI.isExhibit(block) ) || (LocketteProAPI.isUpDownLockedDoor(block) && !LocketteProAPI.isUserUpDownLockedDoor(block, player))) && !player.hasPermission("lockettepro.admin.use")){ Utils.sendMessages(player, Config.getLang("block-is-locked")); @@ -254,7 +258,8 @@ public void onAttemptInteractLockedBlocks(PlayerInteractEvent event){ Utils.playAccessDenyEffect(player, block); } else { // Handle double doors if (action == Action.RIGHT_CLICK_BLOCK){ - if ((LocketteProAPI.isDoubleDoorBlock(block) || LocketteProAPI.isSingleDoorBlock(block)) && LocketteProAPI.isLocked(block)){ + if(LocketteProAPI.isLocked(block)) { + if (LocketteProAPI.isDoubleDoorBlock(block) || LocketteProAPI.isSingleDoorBlock(block)){ Block doorblock = LocketteProAPI.getBottomDoorBlock(block); BlockState doorstate = doorblock.getState(); Openable openablestate = (Openable)doorstate.getData(); @@ -275,6 +280,19 @@ public void onAttemptInteractLockedBlocks(PlayerInteractEvent event){ if (closetime > 0){ Bukkit.getScheduler().runTaskLater(LockettePro.getPlugin(), new DoorToggleTask(doors), closetime*20); } + } else if ( + LocketteProAPI.isExhibit(block) && + !LocketteProAPI.isUser(block, player) && + !player.hasPermission("lockettepro.admin.use") + ) { + if (block.getState() instanceof Chest && ((Chest)block.getState()).getInventory() instanceof DoubleChestInventory) { + Utils.getProtectedInventoryHolder().put(player, ((DoubleChestInventory)((Chest)block.getState()).getInventory()).getLeftSide().getHolder()); + //player.sendMessage(("§bProtect DInventoryHolder: " + getCode(((DoubleChestInventory)((Chest)block.getState()).getInventory()).getLeftSide().getHolder().toString()))); + } else if (block.getState() instanceof InventoryHolder) { + Utils.getProtectedInventoryHolder().put(player, ((InventoryHolder)block.getState())); + //player.sendMessage("§bProtect InventoryHolder: " + getCode(((InventoryHolder)block.getState()).toString())); + } + } } } } @@ -284,10 +302,80 @@ public void onAttemptInteractLockedBlocks(PlayerInteractEvent event){ } } + /* + @EventHandler(ignoreCancelled = true) + public void onInventoryOpen(InventoryOpenEvent event) { + if( + event.getPlayer() != null && event.getPlayer() instanceof Player && + Utils.getProtectedInventoryHolder().containsKey((Player)event.getPlayer()) && + event.getInventory() != null) { + Player player = (Player)event.getPlayer(); + if(event.getInventory() instanceof DoubleChestInventory && Utils.getProtectedInventoryHolder().get((Player)event.getPlayer()).equals(((DoubleChestInventory)event.getInventory()).getLeftSide().getHolder())) { + player.sendMessage("§aProtected DoubleChestInventory Open: " + getCode(((DoubleChestInventory)event.getInventory()).getLeftSide().getHolder().toString())); + } else if (Utils.getProtectedInventoryHolder().get((Player)event.getPlayer()).equals(event.getInventory().getHolder())) { + player.sendMessage("§aProtected Inventory Open: " + getCode(event.getInventory().getHolder().toString())); + } + } + } + */ + + @EventHandler(ignoreCancelled = true) + public void onInventoryClick(InventoryClickEvent event) { + if( + event.getWhoClicked() != null && event.getWhoClicked() instanceof Player && + Utils.getProtectedInventoryHolder().containsKey((Player)event.getWhoClicked()) && + event.getInventory() != null) { + event.setCancelled(true); + /* + Player player = (Player)event.getWhoClicked(); + if(event.getInventory() instanceof DoubleChestInventory && Utils.getProtectedInventoryHolder().get((Player)event.getWhoClicked()).equals(((DoubleChestInventory)event.getInventory()).getLeftSide().getHolder())) { + player.sendMessage("§dProtected DoubleChestInventory Click: " + getCode(((DoubleChestInventory)event.getInventory()).getLeftSide().getHolder().toString())); + } else if (Utils.getProtectedInventoryHolder().get((Player)event.getWhoClicked()).equals(event.getInventory().getHolder())) { + player.sendMessage("§dProtected Inventory Click: " + getCode(event.getInventory().getHolder().toString())); + } + */ + } + } + + @EventHandler(ignoreCancelled = true) + public void onInventoryClose(InventoryCloseEvent event) { + if( + event.getPlayer() != null && event.getPlayer() instanceof Player && + Utils.getProtectedInventoryHolder().containsKey((Player)event.getPlayer()) && + event.getInventory() != null) { + /* + Player player = (Player)event.getPlayer(); + if(event.getInventory() instanceof DoubleChestInventory && Utils.getProtectedInventoryHolder().get((Player)event.getPlayer()).equals(((DoubleChestInventory)event.getInventory()).getLeftSide().getHolder())) { + player.sendMessage("§cProtected DInventory Close: " + getCode(((DoubleChestInventory)event.getInventory()).getLeftSide().getHolder().toString())); + } else if (Utils.getProtectedInventoryHolder().get((Player)event.getPlayer()).equals(event.getInventory().getHolder())) { + player.sendMessage("§cProtected Inventory Close: " + getCode(event.getInventory().getHolder().toString())); + } + */ + Utils.getProtectedInventoryHolder().remove((Player)event.getPlayer()); + } + } + + /* + private boolean isProtectedInventoryHolder(HumanEntity humanEntity, Inventory inventory) { + return + humanEntity != null && + humanEntity instanceof Player && + Utils.getProtectedInventoryHolder().containsKey((Player)humanEntity) && + inventory != null && + ( + (inventory instanceof DoubleChestInventory && Utils.getProtectedInventoryHolder().get((Player)humanEntity).equals(((DoubleChestInventory)inventory).getLeftSide().getHolder())) || + (Utils.getProtectedInventoryHolder().get((Player)humanEntity).equals(inventory.getHolder())) + ); + } + + private String getCode(String text) { + return text.substring(text.lastIndexOf("@") + 1); + } + */ + // Protect block from interfere block - @EventHandler(priority = EventPriority.HIGH) + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void onAttemptPlaceInterfereBlocks(BlockPlaceEvent event){ - if (event.isCancelled()) return; Block block = event.getBlock(); Player player = event.getPlayer(); if (player.hasPermission("lockettepro.admin.interfere")) return; @@ -299,9 +387,8 @@ public void onAttemptPlaceInterfereBlocks(BlockPlaceEvent event){ } // Tell player about lockettepro - @EventHandler(priority = EventPriority.MONITOR) + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onPlaceFirstBlockNotify(BlockPlaceEvent event){ - if (event.isCancelled()) return; Block block = event.getBlock(); Player player = event.getPlayer(); if (!player.hasPermission("lockettepro.lock")) return; diff --git a/src/me/crafter/mc/lockettepro/Config.java b/src/me/crafter/mc/lockettepro/Config.java index f1d657e..7615620 100644 --- a/src/me/crafter/mc/lockettepro/Config.java +++ b/src/me/crafter/mc/lockettepro/Config.java @@ -24,6 +24,7 @@ public class Config { private static Set privatestrings = new HashSet(); private static Set additionalstrings = new HashSet(); private static Set everyonestrings = new HashSet(); + private static Set exhibitstrings = new HashSet(); private static Set timerstrings = new HashSet(); private static String defaultprivatestring = "[Private]"; private static String defaultadditionalstring = "[More Users]"; @@ -39,6 +40,7 @@ public class Config { private static long lockdefaultcreatetime = -1L; private static String lockexpirestring = ""; private static Set protectionexempt = new HashSet(); + private static Set disableWorlds = new HashSet(); public Config(Plugin _plugin){ plugin = _plugin; @@ -75,11 +77,15 @@ public static void reload(){ List privatestringlist = config.getStringList("private-signs"); List additionalstringlist = config.getStringList("additional-signs"); List everyonestringlist = config.getStringList("everyone-signs"); + List exhibitstringlist = config.getStringList("exhibit-signs"); List protectionexemptstringlist = config.getStringList("protection-exempt"); + List disableworldsstringlist = config.getStringList("disable-worlds"); privatestrings = new HashSet(privatestringlist); additionalstrings = new HashSet(additionalstringlist); everyonestrings = new HashSet(everyonestringlist); + exhibitstrings = new HashSet(exhibitstringlist); protectionexempt = new HashSet(protectionexemptstringlist); + disableWorlds = new HashSet(disableworldsstringlist); defaultprivatestring = privatestringlist.get(0); defaultadditionalstring = additionalstringlist.get(0); @@ -177,6 +183,8 @@ public static void initDefaultConfig(){ config.addDefault("additional-signs", additional_signs); String[] everyone_signs = {"[Everyone]", "[everyone]"}; config.addDefault("everyone-signs", everyone_signs); + String[] exhibit_signs = {"[Exhibit]", "[exhibit]"}; + config.addDefault("exhibit-signs", exhibit_signs); String[] timer_signs = {"[Timer:@]", "[timer:@]"}; config.addDefault("timer-signs", timer_signs); String[] lockables = {"CHEST","TRAPPED_CHEST","FURNACE","BURNING_FURNACE","HOPPER","BREWING_STAND","DIAMOND_BLOCK", @@ -199,7 +207,7 @@ public static void initDefaultConfig(){ } public static void initAdditionalFiles(){ - String[] availablefiles = {"lang.yml", "lang_zh-cn.yml", "lang_es.yml", "lang_it.yml"}; + String[] availablefiles = {"lang.yml", "lang_zh-cn.yml", "lang_zh-tw.yml", "lang_es.yml", "lang_it.yml"}; for (String filename : availablefiles){ File langfile = new File(plugin.getDataFolder(), filename); if (!langfile.exists()){ @@ -243,6 +251,10 @@ public static boolean isEveryoneSignString(String message){ return everyonestrings.contains(message); } + public static boolean isExhibitSignString(String message){ + return exhibitstrings.contains(message); + } + public static boolean isTimerSignString(String message){ for (String timerstring : timerstrings){ String[] splitted = timerstring.split("@", 2); @@ -279,6 +291,10 @@ public static int getCacheTimeMillis(){ return cachetime; } + public static Set getExhibitTags(){ + return exhibitstrings; + } + public static boolean isCacheEnabled(){ return cacheenabled; } @@ -287,4 +303,8 @@ public static boolean isProtectionExempted(String against){ return protectionexempt.contains(against); } + public static boolean isDisabledWorld(String worldName){ + return disableWorlds.contains(worldName); + } + } diff --git a/src/me/crafter/mc/lockettepro/Dependency.java b/src/me/crafter/mc/lockettepro/Dependency.java index 5e89cc1..f7d6ca0 100644 --- a/src/me/crafter/mc/lockettepro/Dependency.java +++ b/src/me/crafter/mc/lockettepro/Dependency.java @@ -227,7 +227,7 @@ public static boolean isSimpleClanOf(String line, Player player){ if (clanplayer != null){ Clan clan = clanplayer.getClan(); if (clan != null){ - if (line.equals("[" + clan.getTag() + "]")) return true; + if (line.equalsIgnoreCase("[" + clan.getTag() + "]")) return true; } } } catch (Exception e){} diff --git a/src/me/crafter/mc/lockettepro/LocketteProAPI.java b/src/me/crafter/mc/lockettepro/LocketteProAPI.java index a6e92a6..1ef64de 100644 --- a/src/me/crafter/mc/lockettepro/LocketteProAPI.java +++ b/src/me/crafter/mc/lockettepro/LocketteProAPI.java @@ -1,5 +1,7 @@ package me.crafter.mc.lockettepro; +import java.util.Set; + import org.bukkit.Effect; import org.bukkit.Material; import org.bukkit.block.Block; @@ -17,6 +19,8 @@ public class LocketteProAPI { public static boolean isLocked(Block block){ if (block == null) return false; + // World check + if (Config.isDisabledWorld(block.getWorld().getName())) return false; switch (block.getType()){ // Double Doors case WOODEN_DOOR: @@ -151,6 +155,27 @@ public static boolean isUser(Block block, Player player){ return false; } + public static boolean isExhibit(Block block){ + switch (block.getType()){ + // Chests (Second block only) + case CHEST: + case TRAPPED_CHEST: + // Check second chest sign + for (BlockFace chestface : newsfaces){ + Block relativechest = block.getRelative(chestface); + if (relativechest.getType() == block.getType()){ + if (isTagSingleBlock(relativechest, chestface.getOppositeFace(), Config.getExhibitTags())) return true; + } + } + // Don't break here + // Everything else (First block of container check goes here) + default: + if (isTagSingleBlock(block, null, Config.getExhibitTags())) return true; + break; + } + return false; + } + public static boolean isProtected(Block block){ return (isLockSign(block) || isLocked(block) || isUpDownLockedDoor(block)); } @@ -197,6 +222,19 @@ public static boolean isUserSingleBlock(Block block, BlockFace exempt, Player pl return false; } + public static boolean isTagSingleBlock(Block block, BlockFace exempt, Set tags){ // Requires isLocked + for (BlockFace blockface : newsfaces){ + if (blockface == exempt) continue; + Block relativeblock = block.getRelative(blockface); + if (isLockSignOrAdditionalSign(relativeblock) && (((org.bukkit.material.Sign)relativeblock.getState().getData()).getFacing() == blockface)){ + if (isTagOnSign(relativeblock, tags)){ + return true; + } + } + } + return false; + } + public static boolean isOwnerOfSign(Block block, Player player){ // Requires isSign Block protectedblock = getAttachedBlock(block); // Normal situation, that block is just locked by an adjacent sign @@ -208,6 +246,8 @@ public static boolean isOwnerOfSign(Block block, Player player){ // Requires isS } public static boolean isLockable(Block block){ + // World check + if (block != null && Config.isDisabledWorld(block.getWorld().getName())) return false; Material material = block.getType(); //Bad blocks switch (material){ @@ -404,6 +444,16 @@ public static boolean isUserOnSign(Block block, Player player){ // Requires (isL return false; } + public static boolean isTagOnSign(Block block, Set tags){ + String[] lines = ((Sign)block.getState()).getLines(); + for (int i = 1; i < 4; i ++){ + if (tags.contains(lines[i])) { + return true; + } + } + return false; + } + public static boolean isSignExpired(Block block){ if (!isSign(block) || !isLockSign(block)) return false; return isLineExpired(((Sign)block.getState()).getLine(0)); diff --git a/src/me/crafter/mc/lockettepro/Utils.java b/src/me/crafter/mc/lockettepro/Utils.java index 672c505..c68d12a 100644 --- a/src/me/crafter/mc/lockettepro/Utils.java +++ b/src/me/crafter/mc/lockettepro/Utils.java @@ -19,6 +19,7 @@ import org.bukkit.block.Sign; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.metadata.MetadataValue; @@ -32,6 +33,7 @@ public class Utils { private static Map selectedsign = new HashMap(); private static Set notified = new HashSet(); + private static Map protectedinventoryholder = new HashMap(); // Helper functions @SuppressWarnings("deprecation") @@ -325,4 +327,8 @@ public static String getSignLineFromUnknown(String json){ return json; } + public static Map getProtectedInventoryHolder(){ + return protectedinventoryholder; + } + }