package com.Acrobot.ChestShop.Signs; import com.Acrobot.Breeze.Utils.BlockUtil; import com.Acrobot.ChestShop.Config.Config; import com.Acrobot.ChestShop.Config.Language; import com.Acrobot.ChestShop.Events.PreTransactionEvent; import com.Acrobot.ChestShop.Permission; import org.bukkit.Location; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.Sign; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.SignChangeEvent; import static com.Acrobot.ChestShop.Events.PreTransactionEvent.TransactionOutcome.SHOP_IS_RESTRICTED; /** * @author Acrobot */ public class RestrictedSign implements Listener { private static final BlockFace[] SIGN_CONNECTION_FACES = {BlockFace.SELF, BlockFace.UP, BlockFace.EAST, BlockFace.WEST, BlockFace.NORTH, BlockFace.SOUTH}; @EventHandler(ignoreCancelled = true) public static void onBlockDestroy(BlockBreakEvent event) { Block destroyed = event.getBlock(); Sign attachedRestrictedSign = getRestrictedSign(destroyed.getLocation()); if (attachedRestrictedSign == null) { return; } if (!canDestroy(event.getPlayer(), attachedRestrictedSign)) { event.setCancelled(true); } } @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) public static void onSignChange(SignChangeEvent event) { String[] lines = event.getLines(); Player player = event.getPlayer(); if (isRestricted(lines)) { if (!hasPermission(player, lines)) { player.sendMessage(Config.getLocal(Language.ACCESS_DENIED)); dropSignAndCancelEvent(event); return; } Block connectedSign = event.getBlock().getRelative(BlockFace.DOWN); if (!Permission.has(player, Permission.ADMIN) || !BlockUtil.isSign(connectedSign) || !ChestShopSign.isValid(connectedSign)) { dropSignAndCancelEvent(event); return; } Sign sign = (Sign) connectedSign.getState(); if (!ChestShopSign.isValid(sign) || !ChestShopSign.canAccess(player, sign)) { dropSignAndCancelEvent(event); } } } @EventHandler(priority = EventPriority.LOW) public static void onPreTransaction(PreTransactionEvent event) { if (event.isCancelled()) { return; } Sign sign = event.getSign(); if (isRestricted(sign) && !canAccess(sign, event.getClient())) { event.setCancelled(SHOP_IS_RESTRICTED); } } public static Sign getRestrictedSign(Location location) { Block currentBlock = location.getBlock(); if (BlockUtil.isSign(currentBlock)) { return (Sign) currentBlock.getState(); } for (BlockFace face : SIGN_CONNECTION_FACES) { Block relative = currentBlock.getRelative(face); if (!BlockUtil.isSign(relative)) { continue; } Sign sign = (Sign) relative.getState(); if (!BlockUtil.getAttachedFace(sign).equals(currentBlock)) { continue; } if (isRestricted(sign)) { return sign; } } return null; //No sign found } public static boolean isRestrictedShop(Sign sign) { Block blockUp = sign.getBlock().getRelative(BlockFace.UP); return BlockUtil.isSign(blockUp) && isRestricted(((Sign) blockUp.getState()).getLines()); } public static boolean isRestricted(String[] lines) { return lines[0].equalsIgnoreCase("[restricted]"); } public static boolean isRestricted(Sign sign) { return isRestricted(sign.getLines()); } public static boolean canAccess(Sign sign, Player player) { Block blockUp = sign.getBlock().getRelative(BlockFace.UP); return !BlockUtil.isSign(blockUp) || hasPermission(player, ((Sign) blockUp.getState()).getLines()); } public static boolean canDestroy(Player p, Sign sign) { Sign shopSign = getAssociatedSign(sign); return ChestShopSign.canAccess(p, shopSign); } public static Sign getAssociatedSign(Sign restricted) { Block down = restricted.getBlock().getRelative(BlockFace.DOWN); return BlockUtil.isSign(down) ? (Sign) down.getState() : null; } public static boolean hasPermission(Player p, String[] lines) { if (Permission.has(p, Permission.ADMIN)) { return true; } for (String line : lines) { if (p.hasPermission(Permission.GROUP.toString() + line)) { return true; } } return false; } private static void dropSignAndCancelEvent(SignChangeEvent event) { event.getBlock().breakNaturally(); event.setCancelled(true); } }