diff --git a/com/Acrobot/ChestShop/Config/Language.java b/com/Acrobot/ChestShop/Config/Language.java index 12d06a9..f7f2239 100644 --- a/com/Acrobot/ChestShop/Config/Language.java +++ b/com/Acrobot/ChestShop/Config/Language.java @@ -38,6 +38,7 @@ public enum Language { NO_PERMISSION("You don't have permissions to do that!"), INCORRECT_ITEM_ID("You have specified invalid item id!"), + NOT_ENOUGH_LWC_PROTECTIONS("You have reached the LWC protections limit!"), TOWNY_CANNOT_CREATE_SHOP_HERE("You can't create shop here!"); diff --git a/com/Acrobot/ChestShop/Config/Property.java b/com/Acrobot/ChestShop/Config/Property.java index 83cbc93..edaf267 100644 --- a/com/Acrobot/ChestShop/Config/Property.java +++ b/com/Acrobot/ChestShop/Config/Property.java @@ -28,7 +28,8 @@ public enum Property { TOWNY_INTEGRATION(false, "Do you want to only let people build inside shop plots?"), WORLDGUARD_INTEGRATION(false, "Do you want to only let people build inside plots?"), TAX_AMOUNT(0, "Percent of the price that should go to the server's account. (100 = 100 percent)"), - SHOP_REFUND_PRICE(0, "How much money do you get back when destroying a sign?"); + SHOP_REFUND_PRICE(0, "How much money do you get back when destroying a sign?"), + ALLOW_MULTIPLE_SHOPS_AT_ONE_BLOCK(false, "Do you want to allow other players to build a shop on a block where there's one already?"); private final Object value; diff --git a/com/Acrobot/ChestShop/Listeners/blockBreak.java b/com/Acrobot/ChestShop/Listeners/blockBreak.java index b8065f5..a6f3372 100644 --- a/com/Acrobot/ChestShop/Listeners/blockBreak.java +++ b/com/Acrobot/ChestShop/Listeners/blockBreak.java @@ -26,15 +26,27 @@ import java.util.List; */ public class blockBreak extends BlockListener { public static boolean cancellingBlockBreak(Block block, Player player) { - if (block == null || (player != null && (Permission.has(player, Permission.ADMIN) || Permission.has(player, Permission.MOD)))) return false; - if (uSign.isSign(block)) block.getState().update(); + if (block == null) return false; + if (player != null && (Permission.has(player, Permission.ADMIN) || Permission.has(player, Permission.MOD))) return false; + if (uSign.isSign(block)) block.getState().update(); //Show the text immediately - Sign sign = uBlock.findRestrictedSign(block); - if (isCorrectSign(sign, block)) return true; + if (restrictedSign(block)) return true; //If the block is a restricted sign (and the player is not an admin/mod) - sign = uBlock.findSign(block); - if (Config.getFloat(Property.SHOP_REFUND_PRICE) != 0F && isCorrectSign(sign, block) && !playerIsNotOwner(player, sign)) Economy.add(uLongName.getName(sign.getLine(0)), Config.getFloat(Property.SHOP_REFUND_PRICE)); - return isCorrectSign(sign, block) && playerIsNotOwner(player, sign); + Sign sign = uBlock.findSign(block, uLongName.stripName(player.getName())); + if (!isCorrectSign(sign, block)) return false; //It's not a correct shop sign, so don't cancel it + if (playerIsNotOwner(player, sign)) return true; //Player is not the owner of the shop - cancel! + if (weShouldReturnMoney()) Economy.add(uLongName.getName(sign.getLine(0)), Config.getFloat(Property.SHOP_REFUND_PRICE)); //Add some money + return false; //Player is the owner, so we don't want to cancel this :) + } + + private static boolean weShouldReturnMoney() { + //We should return money when it's turned on in config, obviously + return Config.getFloat(Property.SHOP_REFUND_PRICE) != 0; + } + + private static boolean restrictedSign(Block block) { + Sign s = uBlock.findRestrictedSign(block); + return isCorrectSign(s, block); } public void onBlockBreak(BlockBreakEvent event) { @@ -50,7 +62,7 @@ public class blockBreak extends BlockListener { } private static boolean playerIsNotOwner(Player player, Sign sign) { - return player == null || !uLongName.stripName(player.getName()).equals(sign.getLine(0)); + return player == null || (!uLongName.stripName(player.getName()).equals(sign.getLine(0)) && !Permission.has(player, Permission.OTHER_NAME + sign.getLine(0))); } public void onBlockPistonExtend(BlockPistonExtendEvent event) { diff --git a/com/Acrobot/ChestShop/Listeners/playerInteract.java b/com/Acrobot/ChestShop/Listeners/playerInteract.java index ae9b87b..c439251 100644 --- a/com/Acrobot/ChestShop/Listeners/playerInteract.java +++ b/com/Acrobot/ChestShop/Listeners/playerInteract.java @@ -33,7 +33,6 @@ public class playerInteract extends PlayerListener { private static final HashMap lastTransactionTime = new HashMap(); //Last player's transaction private static final int interval = 100;//Minimal interval between transactions - public void onPlayerInteract(PlayerInteractEvent event) { Action action = event.getAction(); if (action != Action.LEFT_CLICK_BLOCK && action != Action.RIGHT_CLICK_BLOCK) return; diff --git a/com/Acrobot/ChestShop/Listeners/pluginEnable.java b/com/Acrobot/ChestShop/Listeners/pluginEnable.java index a5fc1ca..a3a51c3 100644 --- a/com/Acrobot/ChestShop/Listeners/pluginEnable.java +++ b/com/Acrobot/ChestShop/Listeners/pluginEnable.java @@ -5,6 +5,7 @@ import com.Acrobot.ChestShop.Economy; import com.Acrobot.ChestShop.Items.Odd; import com.Acrobot.ChestShop.Permission; import com.Acrobot.ChestShop.Protection.Plugins.DeadboltPlugin; +import com.Acrobot.ChestShop.Protection.Plugins.Default; import com.Acrobot.ChestShop.Protection.Plugins.LWCplugin; import com.Acrobot.ChestShop.Protection.Plugins.LockettePlugin; import com.Acrobot.ChestShop.Protection.Security; @@ -43,21 +44,22 @@ public class pluginEnable extends ServerListener { } private static void initializePlugin(String name, Plugin plugin) { //Really messy, right? But it's short and fast :) + Security.protections.add(new Default()); //Initialize basic protection if (name.equals("Permissions")) { if (Permission.permissions != null) return; Permission.permissions = ((Permissions) plugin).getHandler(); } else if (name.equals("LWC")) { if (LWCplugin.lwc != null) return; LWCplugin.setLWC(((LWCPlugin) plugin).getLWC()); - Security.protection = new LWCplugin(); + Security.protections.add(new LWCplugin()); } else if (name.equals("Lockette")) { if (LockettePlugin.lockette != null) return; LockettePlugin.lockette = (Lockette) plugin; - Security.protection = new LockettePlugin(); + Security.protections.add(new LockettePlugin()); } else if (name.equals("Deadbolt")) { if (DeadboltPlugin.deadbolt != null) return; DeadboltPlugin.deadbolt = (Deadbolt) plugin; - Security.protection = new DeadboltPlugin(); + Security.protections.add(new DeadboltPlugin()); } else if (name.equals("OddItem")) { if (Odd.isInitialized()) return; if (plugin.getDescription().getVersion().startsWith("0.7")) { System.out.println(generateOutdatedVersion(name, plugin.getDescription().getVersion(), "0.8")); return; } diff --git a/com/Acrobot/ChestShop/Listeners/signChange.java b/com/Acrobot/ChestShop/Listeners/signChange.java index c444f16..b64b808 100644 --- a/com/Acrobot/ChestShop/Listeners/signChange.java +++ b/com/Acrobot/ChestShop/Listeners/signChange.java @@ -6,7 +6,6 @@ import com.Acrobot.ChestShop.Config.Property; import com.Acrobot.ChestShop.Economy; import com.Acrobot.ChestShop.Items.Items; import com.Acrobot.ChestShop.Permission; -import com.Acrobot.ChestShop.Protection.Plugins.Default; import com.Acrobot.ChestShop.Protection.Security; import com.Acrobot.ChestShop.Signs.restrictedSign; import com.Acrobot.ChestShop.Utils.*; @@ -82,7 +81,7 @@ public class signChange extends BlockListener { dropSign(event); return; } else if (!playerIsAdmin) { - if (!Security.canPlaceSign(player, (Sign) signBlock.getState())) { + if (!Config.getBoolean(Property.ALLOW_MULTIPLE_SHOPS_AT_ONE_BLOCK) && !Security.canPlaceSign(player, (Sign) signBlock.getState())) { player.sendMessage(Config.getLocal(Language.ANOTHER_SHOP_DETECTED)); dropSign(event); return; @@ -98,12 +97,6 @@ public class signChange extends BlockListener { boolean canAccess = !Security.isProtected(chestBlock) || Security.canAccess(player, chestBlock); - if (!(Security.protection instanceof Default) && canAccess) { - Default protection = new Default(); - if (protection.isProtected(chestBlock) && !protection.canAccess(player, chestBlock)) - canAccess = false; - } - if (!canAccess) { player.sendMessage(Config.getLocal(Language.CANNOT_ACCESS_THE_CHEST)); dropSign(event); @@ -125,7 +118,7 @@ public class signChange extends BlockListener { } if (Config.getBoolean(Property.PROTECT_SIGN_WITH_LWC)) { - Security.protect(player.getName(), signBlock); + if (!Security.protect(player.getName(), signBlock)) player.sendMessage(Config.getLocal(Language.NOT_ENOUGH_LWC_PROTECTIONS)); } if (Config.getBoolean(Property.PROTECT_CHEST_WITH_LWC) && chest != null && Security.protect(player.getName(), chest.getBlock())) { player.sendMessage(Config.getLocal(Language.PROTECTED_SHOP)); @@ -146,11 +139,12 @@ public class signChange extends BlockListener { } private static String formatThirdLine(String thirdLine) { + thirdLine = thirdLine.toUpperCase(); String[] split = thirdLine.split(":"); if (uNumber.isFloat(split[0])) thirdLine = "B " + thirdLine; if (split.length == 2 && uNumber.isFloat(split[1])) thirdLine = thirdLine + " S"; if (thirdLine.length() > 15) thirdLine = thirdLine.replace(" ", ""); - thirdLine = thirdLine.toUpperCase(); + return (thirdLine.length() > 15 ? null : thirdLine); } @@ -171,7 +165,10 @@ public class signChange extends BlockListener { } private static boolean formatFirstLine(String line1, Player player) { - return line1.isEmpty() || (!line1.equals(uLongName.stripName(player.getName())) && !Permission.has(player, Permission.ADMIN)); + return line1.isEmpty() || + (!line1.equals(uLongName.stripName(player.getName())) + && !Permission.has(player, Permission.ADMIN) + && !Permission.has(player, Permission.OTHER_NAME + line1)); } private static void dropSign(SignChangeEvent event) { diff --git a/com/Acrobot/ChestShop/Permission.java b/com/Acrobot/ChestShop/Permission.java index 1b61348..0d10176 100644 --- a/com/Acrobot/ChestShop/Permission.java +++ b/com/Acrobot/ChestShop/Permission.java @@ -13,7 +13,8 @@ public enum Permission { SELL_ID("ChestShop.shop.sell."), SELL("ChestShop.shop.sell"), ADMIN("ChestShop.admin"), - MOD("ChestShop.mod"); + MOD("ChestShop.mod"), + OTHER_NAME("ChestShop.name."); private final String permission; @@ -28,8 +29,8 @@ public enum Permission { } public static boolean has(Player player, String node) { - if (permissions != null) return permissions.has(player, node); - return player.hasPermission(node); + if (permissions != null) return permissions.has(player, node) || permissions.has(player, node.toLowerCase()); + return player.hasPermission(node) || player.hasPermission(node.toLowerCase()); } public String toString() { diff --git a/com/Acrobot/ChestShop/Protection/Security.java b/com/Acrobot/ChestShop/Protection/Security.java index 1bae7fa..3c87d8e 100644 --- a/com/Acrobot/ChestShop/Protection/Security.java +++ b/com/Acrobot/ChestShop/Protection/Security.java @@ -1,7 +1,6 @@ package com.Acrobot.ChestShop.Protection; import com.Acrobot.ChestShop.Listeners.blockBreak; -import com.Acrobot.ChestShop.Protection.Plugins.Default; import com.Acrobot.ChestShop.Utils.uLongName; import com.Acrobot.ChestShop.Utils.uSign; import org.bukkit.block.Block; @@ -9,28 +8,35 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.Sign; import org.bukkit.entity.Player; +import java.util.ArrayList; + /** * @author Acrobot */ public class Security { private static BlockFace[] faces = {BlockFace.UP, BlockFace.EAST, BlockFace.WEST, BlockFace.NORTH, BlockFace.SOUTH}; - public static Protection protection = new Default(); + public static ArrayList protections = new ArrayList(); public static boolean protect(String name, Block block) { - return protection.protect(name, block); + boolean works = false; + for (int i = 0; i < protections.size() && !works; i++) works = protections.get(i).protect(name, block); + return works; } public static boolean canAccess(Player player, Block block) { - return protection.canAccess(player, block); + boolean works = true; + for (int i = 0; i < protections.size() && works; i++) works = protections.get(i).canAccess(player, block); + return works; } public static boolean isProtected(Block block) { - return protection.isProtected(block); + boolean isProtected = false; + for (int i = 0; i < protections.size() && !isProtected; i++) isProtected = protections.get(i).isProtected(block); + return isProtected; } public static boolean canPlaceSign(Player p, Sign sign) { - Block block = blockBreak.getAttachedFace(sign); - return !thereIsAnotherSignByPlayer(block, sign.getBlock(), uLongName.stripName(p.getName())); + return !thereIsAnotherSignByPlayer(blockBreak.getAttachedFace(sign), sign.getBlock(), uLongName.stripName(p.getName())); } private static boolean thereIsAnotherSignByPlayer(Block baseBlock, Block signBlock, String shortName){ diff --git a/com/Acrobot/ChestShop/Utils/uBlock.java b/com/Acrobot/ChestShop/Utils/uBlock.java index 1c823ae..0335572 100644 --- a/com/Acrobot/ChestShop/Utils/uBlock.java +++ b/com/Acrobot/ChestShop/Utils/uBlock.java @@ -29,7 +29,14 @@ public class uBlock { return null; } - public static Sign findSign(Block block) { + public static Sign findSign(Block block, String originalName) { + for (BlockFace bf : shopFaces) { + Block faceBlock = block.getRelative(bf); + if (uSign.isSign(faceBlock)) { + Sign sign = (Sign) faceBlock.getState(); + if (uSign.isValid(sign) && !sign.getLine(0).equals(originalName) && (faceBlock.equals(block) || blockBreak.getAttachedFace(sign).equals(block))) return sign; + } + } for (BlockFace bf : shopFaces) { Block faceBlock = block.getRelative(bf); if (uSign.isSign(faceBlock)) { diff --git a/plugin.yml b/plugin.yml index 915139f..c68fb12 100644 --- a/plugin.yml +++ b/plugin.yml @@ -2,7 +2,7 @@ name: ChestShop main: com.Acrobot.ChestShop.ChestShop -version: 3.23 +version: 3.28 author: Acrobot @@ -54,4 +54,6 @@ permissions: description: Allows user to modify/destroy other stores and create an Admin Shops default: op ChestShop.mod: - description: Allows user only to view other store chests, he can't destroy them or create an Admin Shop \ No newline at end of file + description: Allows user only to view other store chests, he can't destroy them or create an Admin Shop + ChestShop.name.(some name): + description: Gives you the power to do create shops for (some name), for example your town. \ No newline at end of file