commit ae17ca81ee96a1b6e34955d8a4b9500ceca6f205 Author: BuildTools Date: Sat Oct 31 11:53:16 2015 +0800 first commit diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..91bd1db --- /dev/null +++ b/README.txt @@ -0,0 +1,17 @@ + +Lockette for Bukkit, written by Acru Jovian, updated by ElgarL and +now mainteined by vk2gpz. +Distributed under the The Non-Profit Open Software License version 3.0 (NPOSL-3.0) +http://www.opensource.org/licenses/NOSL3.0 + +This project needs the following Libraries: (Version used in brackets) + +* Bukkit/Spigot (1.8.x) +* PluginCore (1.4.0) + +To compile against spigot1.8, you need to obtain your own copy of +spigot.jar since it's no longer distributed in the form of .jar. + +This version now use Maven as the project management system. + + diff --git a/changelog.txt b/changelog.txt new file mode 100644 index 0000000..2a0fed4 --- /dev/null +++ b/changelog.txt @@ -0,0 +1,294 @@ +* Unreleased changes: + +? + + +* Active release build change log is here: + +http://dev.bukkit.org/server-mods/lockette/pages/lockette-change-log/ + + +* But here is a copy/paste: + +Version 1.8.0 + + Add support for doors and IRON_TRAPDOOR introduced in 1.8. + +Version 1.7.12 + + Add support for droppers and trapped chests (new permission node 'lockette.user.create.dropper' and 'lockette.admin.create.dropper'). + Fixed Auto chest rotation. + Lockette will not ONLY protect items from explosions IF 'explosion-protection-all' is true. Be sure to check your config. Default used to be false. + Changed all event priorities which were HIGHEST to LOW. Other plugins (Shopkeepers) can now see if Lockette has cancelled an event. + Updated recomended and minimum Craftbukkit versions. + - rec: 2771 + - min: 2735 + +Version 1.7.11 + + Prevent the placement of hoppers on protected blocks other than by the blocks owner. + +Version 1.7.10 + + Updated PluginCore to 1.3.7 to handle the new mcMMO (Beta) API hooks. + +Version 1.7.9 + + Added Anvils to the default custom block protection list. + +Version 1.7.8 + + Fix protection of trap doors + Update PluginCore to 1.3.6 + +Version 1.7.7 + + Fix Expanding chests. + +Version 1.7.6: + + Bugfix for sign detection with blockFacing changes. + Update pluginCore for blockFace changes. + +Version 1.7.5: + + Update blockFacing code for bukkit change (metalhedd). + Added Simplified chinese language file (supplied by ngbeslhang). + +Version 1.7.4: + + Improved the error handling and reporting when loading string files. + Corrected a number of issues with existing language translations. + Added Swedish language translation. + Added Italian language translation. + +Version 1.7.3: + + Corrected an undefined method error. + Added Norwegian language translation. + +Version 1.7.2: + + Added a configuration option to disable specific linked plugins, in case the api changes. + Added a check for hoeing grass with attached trap doors. + Re-implemented debug code as a configuration option, for test servers. + +Version 1.7.1: [ElgarL] + + Removed debug code which could be exploited on off-line servers. + +Version 1.7: [ElgarL] + + Allowed pluginCore to recognize/handle non Towny worlds. + Update plugin dependencies to latest versions. + +Version 1.6: + + Lowered earliest supported build version to 1846 and made manditory. + Fixed trees breaking signs off chests, this time for sure. + Fixed sticky pistons pulling protected pullable blocks. + Added Spanish language translation. + Added protection of brewing stands. (Finally...) + Added a custom list of protected blocks, set by config. + Defaults to the three blocks made with diamonds. + There may be some glitches, so be sure to test. + Core: Fixed native groups support for bPermissions. + Core: Added LWC support for zones. + +Version 1.5 + + Explosions are no longer canceled, but the list of blocks destroyed is pruned. + Added check to prevent trees from growing into protected blocks. + Fixed for the fence gate exploit. + Added some additional translations. + Added a command alias '/lock'. + Built in support for color tags, when creating protection signs. + Color tags are also allowed in the strings file. + Bug fix for piston extension event. + Added a configuration option for operator breaking. + Changed the format of the log messages, for a cleaner look. + Core: Factions support for groups. (And fixed it again.) + Core: SimpleClans support for groups. + Core: MCMmo support for groups. + Core: Superperms, along with bPermissions support. + Core: Redesigned how other plugins are linked. + Core: iConomy support. (Unused in Lockette 1.5 so far...) + And more that I have probably forgotten... + +Version 1.4.4 + + Added a feature to fix badly rotated chests when upgrading from pre-1.8 to 1.8+ + Right-clicking the side of an older chest will cause the chest to face that side, works once only. + Added a configuration option 'enable-chest-rotation' to have this always work, defaults to false. + Core: Towny: Fixed never being allowed to protect chests in a town. + +Version 1.4.3 + + Fixed an exception in the previous version, thrown when PermissionsBukkit/Towny is not available. + +Version 1.4.2 + + Core: No longer attempts to force-enable PermissionsBukkit/PermissionsEx/Towny, due to a bug in Bukkit. + Core: Improved Towny Town/Nation check for when a Resident/Town is not registered. + +Version 1.4.1 + + Experimental Towny support, though not tested. I need someone to help with testing! + Core: Towny group support for towns/nations. + New permission lockette.towny.wilds for protecting in the wilds. + Fixed quick-protect throwing an exception when another plugin removed the placed sign. + Core: New support of build zones. + Core: Improved handling when using multiple permission/group plugins. + Core: Added PermissionsBukkit group support. + +Version 1.4 + + You can now protect a chest/furnace/dispenser instantly by right clicking it while holding a sign! + A second sign will be a [More Users] sign with [Everyone] as a user. + This new method can be toggled with the enable-quick-protect configuration option. + New command: /lockette fix, to toggle an automatic door that has gotten out of sync. Look at it when typing the command. + Full trap door support. + Full piston protection for doors and trap doors. + Language file configuration option. + Preliminary support for MC 1.8 fence gates, may or may not work as expected. + Core: Worked around a change in GroupManager API, in the Essentials Phoenix build. + Added missing sound effects for doors, supported in builds 851+. + Fixed redstone still being disabled if the owner line is [Everyone]. + Applied a fix for when another plugin was triggering the conflicting door message, when there was no conflict. + Improved security in a number of obscure cases. + More public functions for plugin interoperability. + +Version 1.3.8 + + Reversed the change related to MinecartManiaAdminControls, but said plugin is updated too now. + This fixes a security issue. + +Version 1.3.7 + + Worked around a change in MinecartManiaAdminControls 1.1.0 breaking door signs. + Changed the default value for enable-permissions to false. + Too many people had Permissions/GroupManager installed but didn't know how to use. + This will not effect existing configuration files. + +Version 1.3.6 + + Fixed a config file option forcing permissions on if there are no permission plugins. + Added an internal warning about builds 685-703. + +Version 1.3.5 + + Automatically closing doors! (Eg.: Use [Timer: 5] on the private sign.) + The global configuration setting can be overridden using an option on the sign. + Added a check to see if a user is online, when creating a container for another user. + Allowed a group to be set as an owner, but with no permission to modify. + Support for using GroupManager and Permissions simultaneously. + Fix for some dated or fake versions of permissions plugins. + Separate permissions for creating protection on different types of blocks. + Also for the admin version. + Changed lockette.create.* to lockette.user.create.*, but left in support for the old node. + Added a number of new configuration options. + Several options to specify who to send the broadcast messages to. + Support for either a group or a specific player. + Options for disabling permissions and door bypassing. + Fixed a case where the bypass message reported the wrong user. + Added a workaround for an mcMMO bug. + New undocumented command '/lockette version'. + +Version 1.3.4 + + Native support for GroupManager, up to date Permissions handling, and three new permissions nodes! + Changed snoop behavior for doors, with a new permission, no longer broadcasts. + Added a permission for creating locked containers at all. + Added an admin permission for creating locked containers for anyone. + Improved player listener effeciency in builds 588+. + Fixed an exception that was throwing for builds 561-587. + Wooden door breakage security fix for change in builds 561+. + Blocked tilling dirt under a door in builds 561+. + Blocked placing of doors by owned doors in builds 561+. + Updated internal minimum recommended build to 561... :3 + Added an internal warning about builds 605-612. + +Version 1.3.3 + + Fixed plugin for a breaking change in CB build 600, though backwards compatible. + Added a second undocumented public function, for connectivity. + +Version 1.3.2 + + Enabled redstone for protected doors with [Everyone] as a user. + Improved detection of conflicting private doors, when creating new ones. + Relaxed restrictions on the placement of [More Users] signs on doors. (See doors section.) + Blocked a possible security issue with double doors. + Added support for CraftBukkit build 561 and up. + +Version 1.3.1 + + Increased the internal recommended build version from 522 to 552. (Oops.) + Added a config file option to globally enable/disable door support. + Slightly changed container search to use the NESW rule, disregarding block types. + +Version 1.3 + + Full support for protected doors, including double doors. + Added [Operators] keyword as a built in user group. + Color codes are stripped from signs before processing, for color compatibility. + Prevents an issue where one could replace sign text, in CB builds prior to 522. + Catches issues with out of date Permissions plugin. + Exposes an interface for other plugins to access, to check Lockette protected blocks. + Some general speed improvements. + +Version 1.2.2 + + Workaround for Craftbukkit 454+, though this may break again in the future. + Fixed a bug I noticed in sign editing. + +Version 1.2.1 + + Built against a newer version of Bukkit. + +Version 1.2 + + Added configurations file for settings, and a strings file for additional language support. + Full Nijikokun's Permissions support, both versions 2.0 and 2.1, for groups and admin powers. + Defaults to using the ops file, if the plugin isn't available. + Allowed the editing of previously placed signs. + More helpful messages, and options to disable them if you don't like messages. + Many other small details. + +Version 1.1.4 + + Added a check for the server's CraftBukkit build version on enable. Enable will be aborted if it detects an unsupported version, and says so clearly in the log. (Auto-detects builds 231-326 only.) + Strengthened the owner's username check to be case sensitive. (Entered automatically, so no need to be insensitive here.) + Removed one unnecessary server log message. + +Version 1.1.3 + + Added informational server log messages. + Added preliminary support for Nijikokun's Permissions plugin. (Not functional yet.) + Thought up a better namespace, so changed it again. + +Version 1.1.2 + + Relaxed all user name checks to be case insensitive. + Updated plugin to use a more personal namespace. (Required by craftbukkit soon.) + +Version 1.1.1 + + Made the check for [Everyone] case insensitive. + +Version 1.1 + + Protection extended to Dispensers and Furnaces. + Explicitly blocked the creation of illegal sized chests. (Chests are 1 or 2 blocks in size only.) + Allowed [Everyone] as a user that lets anyone into the container. + Allowed more users via additional signs, headed [More Users]. + +Version 1.0.1 + + Improved handling of long user names. (Name matches to 15 characters.) + Improved status messages from the plugin. + +Version 1.0 + + First public release. + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..5144dbe --- /dev/null +++ b/pom.xml @@ -0,0 +1,113 @@ + + + 4.0.0 + cn.mcraft + Lockette + 1.0 + jar + + ${project.name} + + + src/main/resources + true + + + + + maven-compiler-plugin + 3.1 + + 1.7 + 1.7 + + + + org.apache.maven.plugins + maven-shade-plugin + 2.3 + + + package + + shade + + + false + + + cn.citycraft:PluginHelper + + + + + + + + maven-clean-plugin + 2.6 + + + Deleting all unnecessary files before lint analysis + verify + + clean + + + + + true + + + target + false + + ${project.name}.jar + + + + true + + + + + + + spigot-repo + https://hub.spigotmc.org/nexus/content/groups/public/ + + + dmulloy2-repo + http://repo.dmulloy2.net/content/groups/public/ + + + sumcraft-repo + ${jenkins.url}/plugin/repository/everything/ + + + + + org.spigotmc + spigot-api + jar + 1.8.3-R0.1-SNAPSHOT + + + com.comphenix.protocol + ProtocolLib + 3.6.4 + + + cn.citycraft + PlugnHelper + jar + 1.0 + + + + UTF-8 + 1.7 + 1.7 + http://ci.sumcraft.net:8080 + + \ No newline at end of file diff --git a/src/main/java/org/yi/acru/bukkit/Lockette/BlockUtil.java b/src/main/java/org/yi/acru/bukkit/Lockette/BlockUtil.java new file mode 100644 index 0000000..2b684b2 --- /dev/null +++ b/src/main/java/org/yi/acru/bukkit/Lockette/BlockUtil.java @@ -0,0 +1,217 @@ +package org.yi.acru.bukkit.Lockette; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; + +public class BlockUtil { + + public static byte[] faceList = {5, 3, 4, 2}; + public static byte[] attachList = {1, 2, 0, 3}; + public static final int[] materialList; + public static final int[] materialListTrapDoors; + public static final int[] materialListNonDoors; + public static final int[] materialListTools; + public static final int[] materialListChests; + public static final int[] materialListFurnaces; + public static final int[] materialListDoors; + public static final int[] materialListJustDoors; + public static final int[] materialListWoodenDoors; + public static final int[] materialListGates; + public static final int[] materialListBad; + + public static boolean isInList(int target, int[] list) { + if (list == null) { + return false; + } + for (int x = 0; x < list.length; x++) { + if (target == list[x]) { + return true; + } + } + return false; + } + + static { + if (BlockFace.NORTH.getModX() != -1) { + faceList[0] = 3; + faceList[1] = 4; + faceList[2] = 2; + faceList[3] = 5; + + attachList[0] = 1; + attachList[0] = 2; + attachList[0] = 0; + attachList[0] = 3; + } + + materialList = new int[]{Material.CHEST + .getId(), Material.TRAPPED_CHEST + .getId(), Material.DISPENSER + .getId(), Material.DROPPER + .getId(), Material.FURNACE + .getId(), Material.BURNING_FURNACE + .getId(), Material.BREWING_STAND + .getId(), Material.TRAP_DOOR + .getId(), Material.WOODEN_DOOR + .getId(), Material.IRON_DOOR_BLOCK + .getId(), Material.FENCE_GATE + .getId(), Material.ACACIA_DOOR + .getId(), Material.ACACIA_FENCE_GATE + .getId(), Material.BIRCH_DOOR + .getId(), Material.BIRCH_FENCE_GATE + .getId(), Material.DARK_OAK_DOOR + .getId(), Material.DARK_OAK_FENCE_GATE + .getId(), Material.JUNGLE_DOOR + .getId(), Material.JUNGLE_FENCE_GATE + .getId(), Material.SPRUCE_DOOR + .getId(), Material.SPRUCE_FENCE_GATE + .getId(), Material.WOOD_DOOR + .getId(), Material.IRON_TRAPDOOR + .getId()}; + + materialListTrapDoors = new int[]{Material.TRAP_DOOR + .getId(), Material.IRON_TRAPDOOR + .getId()}; + + materialListNonDoors = new int[]{Material.CHEST + .getId(), Material.TRAPPED_CHEST + .getId(), Material.DISPENSER + .getId(), Material.DROPPER + .getId(), Material.FURNACE + .getId(), Material.BURNING_FURNACE + .getId(), Material.BREWING_STAND + .getId()}; + + materialListTools = new int[]{Material.DISPENSER + .getId(), Material.DROPPER + .getId(), Material.FURNACE + .getId(), Material.BURNING_FURNACE + .getId(), Material.BREWING_STAND + .getId()}; + + materialListChests = new int[]{Material.CHEST + .getId(), Material.TRAPPED_CHEST + .getId()}; + + materialListFurnaces = new int[]{Material.FURNACE + .getId(), Material.BURNING_FURNACE + .getId()}; + + materialListDoors = new int[]{Material.WOODEN_DOOR + .getId(), Material.IRON_DOOR_BLOCK + .getId(), Material.FENCE_GATE + .getId(), Material.ACACIA_DOOR + .getId(), Material.ACACIA_FENCE_GATE + .getId(), Material.BIRCH_DOOR + .getId(), Material.BIRCH_FENCE_GATE + .getId(), Material.DARK_OAK_DOOR + .getId(), Material.DARK_OAK_FENCE_GATE + .getId(), Material.JUNGLE_DOOR + .getId(), Material.JUNGLE_FENCE_GATE + .getId(), Material.SPRUCE_DOOR + .getId(), Material.SPRUCE_FENCE_GATE + .getId(), Material.WOOD_DOOR + .getId()}; + + materialListJustDoors = new int[]{Material.WOODEN_DOOR + .getId(), Material.IRON_DOOR_BLOCK + .getId(), Material.ACACIA_DOOR + .getId(), Material.BIRCH_DOOR + .getId(), Material.DARK_OAK_DOOR + .getId(), Material.JUNGLE_DOOR + .getId(), Material.SPRUCE_DOOR + .getId(), Material.WOOD_DOOR + .getId()}; + + materialListWoodenDoors = new int[]{Material.TRAP_DOOR + .getId(), Material.WOODEN_DOOR + .getId(), Material.FENCE_GATE + .getId(), Material.ACACIA_DOOR + .getId(), Material.ACACIA_FENCE_GATE + .getId(), Material.BIRCH_DOOR + .getId(), Material.BIRCH_FENCE_GATE + .getId(), Material.DARK_OAK_DOOR + .getId(), Material.DARK_OAK_FENCE_GATE + .getId(), Material.JUNGLE_DOOR + .getId(), Material.JUNGLE_FENCE_GATE + .getId(), Material.SPRUCE_DOOR + .getId(), Material.SPRUCE_FENCE_GATE + .getId(), Material.WOOD_DOOR + .getId()}; + + materialListGates = new int[]{Material.FENCE_GATE + .getId(), Material.ACACIA_FENCE_GATE + .getId(), Material.BIRCH_FENCE_GATE + .getId(), Material.DARK_OAK_FENCE_GATE + .getId(), Material.JUNGLE_FENCE_GATE + .getId(), Material.SPRUCE_FENCE_GATE + .getId()}; + + materialListBad = new int[]{50, 63, 64, 65, 68, 71, 75, 76, 96}; + } + + public static Block getSignAttachedBlock(Block block) { + if (block.getTypeId() != Material.WALL_SIGN.getId()) { + return null; + } + int face = block.getData() & 7; + if (face == BlockUtil.faceList[0]) { + return block.getRelative(BlockFace.NORTH); + } + if (face == BlockUtil.faceList[1]) { + return block.getRelative(BlockFace.EAST); + } + if (face == BlockUtil.faceList[2]) { + return block.getRelative(BlockFace.SOUTH); + } + if (face == BlockUtil.faceList[3]) { + return block.getRelative(BlockFace.WEST); + } + return null; + } + + public static Block getTrapDoorAttachedBlock(Block block) { + int type = block.getTypeId(); + if ((type != Material.TRAP_DOOR.getId()) && (type != Material.IRON_TRAPDOOR.getId())) { + return null; + } + int face = block.getData() & 3; + if (face == BlockUtil.attachList[0]) { + return block.getRelative(BlockFace.NORTH); + } + if (face == BlockUtil.attachList[1]) { + return block.getRelative(BlockFace.EAST); + } + if (face == BlockUtil.attachList[2]) { + return block.getRelative(BlockFace.SOUTH); + } + if (face == BlockUtil.attachList[3]) { + return block.getRelative(BlockFace.WEST); + } + return null; + } + + public static BlockFace getPistonFacing(Block block) { + int type = block.getTypeId(); + if ((type != Material.PISTON_BASE.getId()) && (type != Material.PISTON_STICKY_BASE.getId()) && (type != Material.PISTON_EXTENSION.getId())) { + return BlockFace.SELF; + } + int face = block.getData() & 7; + switch (face) { + case 0: + return BlockFace.DOWN; + case 1: + return BlockFace.UP; + case 2: + return BlockFace.NORTH; + case 3: + return BlockFace.SOUTH; + case 4: + return BlockFace.WEST; + case 5: + return BlockFace.EAST; + } + return BlockFace.SELF; + } +} diff --git a/src/main/java/org/yi/acru/bukkit/Lockette/Lockette.java b/src/main/java/org/yi/acru/bukkit/Lockette/Lockette.java new file mode 100644 index 0000000..0295be4 --- /dev/null +++ b/src/main/java/org/yi/acru/bukkit/Lockette/Lockette.java @@ -0,0 +1,1879 @@ +package org.yi.acru.bukkit.Lockette; + +import java.io.File; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.SocketTimeoutException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.UUID; +import java.util.logging.Logger; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.OfflinePlayer; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.Sign; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.metadata.MetadataValue; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.java.JavaPlugin; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; + +public class Lockette extends JavaPlugin { + + static boolean DEBUG = false; + private static Lockette plugin; + private static boolean enabled = false; + + private static boolean uuidSupport = false; + private static boolean registered = false; + private final LocketteBlockListener blockListener = new LocketteBlockListener(this); + private final LocketteEntityListener entityListener = new LocketteEntityListener(this); + private final LockettePlayerListener playerListener = new LockettePlayerListener(this); + private final LockettePrefixListener prefixListener = new LockettePrefixListener(this); + private final LocketteWorldListener worldListener = new LocketteWorldListener(this); + private final LocketteInventoryListener inventoryListener = new LocketteInventoryListener(this); + protected final LocketteDoorCloser doorCloser = new LocketteDoorCloser(this); + protected static boolean explosionProtectionAll; + protected static boolean rotateChests; + protected static boolean adminSnoop; + protected static boolean adminBypass; + protected static boolean adminBreak; + protected static boolean protectDoors; + protected static boolean protectTrapDoors; + protected static boolean usePermissions; + protected static boolean usingExternalZones = false; + protected static boolean directPlacement; + protected static boolean colorTags; + protected static boolean debugMode; + protected static boolean blockHopper = false; + protected static int defaultDoorTimer; + protected static String broadcastSnoopTarget; + protected static String broadcastBreakTarget; + protected static String broadcastReloadTarget; + protected static boolean msgUser; + protected static boolean msgOwner; + protected static boolean msgAdmin; + protected static boolean msgError; + protected static boolean msgHelp; + protected static String altPrivate; + protected static String altMoreUsers; + protected static String altEveryone; + protected static String altOperators; + protected static String altTimer; + protected static String altFee; + protected static List customBlockList = null; + protected static List disabledPluginList = null; + + protected static FileConfiguration strings = null; + protected final HashMap playerList = new HashMap(); + private static final String META_KEY = "LocketteUUIDs"; + private static String NAME_HISTORY_URL = "https://api.mojang.com/user/profiles/"; + private static final JSONParser jsonParser = new JSONParser(); + + public static final Logger log = Logger.getLogger("Minecraft"); + + private static String lastZoneDeny = "lockette.unknown"; + + public Lockette() { + plugin = this; + } + + @Override + public void onLoad() { + } + + @Override + public void onEnable() { + if (enabled) { + return; + } + + log.info("[" + getDescription().getName() + "] Version " + getDescription().getVersion() + " is being enabled! Yay!"); + + loadProperties(false); + + super.onEnable(); + + if (!registered) { + this.blockListener.registerEvents(); + this.entityListener.registerEvents(); + this.playerListener.registerEvents(); + this.prefixListener.registerEvents(); + this.worldListener.registerEvents(); + this.inventoryListener.registerEvents(); + registered = true; + } + + log.info("[" + getDescription().getName() + "] Ready to protect your containers."); + enabled = true; + } + + @Override + public void onDisable() { + if (!enabled) { + return; + } + log.info(getDescription().getName() + " is being disabled... ;.;"); + + if ((protectDoors) || (protectTrapDoors)) { + log.info("[" + getDescription().getName() + "] Closing all automatic doors."); + this.doorCloser.cleanup(); + } + + super.onDisable(); + + enabled = false; + } + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) { + if (!cmd.getName().equalsIgnoreCase("lockette")) { + return false; + } + if ((sender instanceof Player)) { + return true; + } + + if (args.length == 1) { + if (args[0].equalsIgnoreCase("reload")) { + loadProperties(true); + + localizedMessage(null, broadcastReloadTarget, "msg-admin-reload"); + } + + } + + return true; + } + + protected void loadProperties(boolean reload) { + if (reload) { + log.info("[" + getDescription().getName() + "] Reloading plugin configuration files."); + reloadConfig(); + } + + FileConfiguration properties = getConfig(); + boolean propChanged = true; + + uuidSupport = properties.getBoolean("enable-uuid-support", false); + properties.set("enable-uuid-support", Boolean.valueOf(uuidSupport)); + msgUser = properties.getBoolean("enable-messages-user", true); + properties.set("enable-messages-user", Boolean.valueOf(msgUser)); + msgOwner = properties.getBoolean("enable-messages-owner", false); + properties.set("enable-messages-owner", Boolean.valueOf(msgOwner)); + + msgAdmin = properties.getBoolean("enable-messages-admin", true); + properties.set("enable-messages-admin", Boolean.valueOf(msgAdmin)); + msgError = properties.getBoolean("enable-messages-error", true); + properties.set("enable-messages-error", Boolean.valueOf(msgError)); + msgHelp = properties.getBoolean("enable-messages-help", true); + properties.set("enable-messages-help", Boolean.valueOf(msgHelp)); + + explosionProtectionAll = properties.getBoolean("explosion-protection-all", true); + properties.set("explosion-protection-all", Boolean.valueOf(explosionProtectionAll)); + rotateChests = properties.getBoolean("enable-chest-rotation", false); + properties.set("enable-chest-rotation", Boolean.valueOf(rotateChests)); + + usePermissions = properties.getBoolean("enable-permissions", false); + properties.set("enable-permissions", Boolean.valueOf(usePermissions)); + protectDoors = properties.getBoolean("enable-protection-doors", true); + properties.set("enable-protection-doors", Boolean.valueOf(protectDoors)); + protectTrapDoors = properties.getBoolean("enable-protection-trapdoors", true); + properties.set("enable-protection-trapdoors", Boolean.valueOf(protectTrapDoors)); + + adminSnoop = properties.getBoolean("allow-admin-snoop", false); + properties.set("allow-admin-snoop", Boolean.valueOf(adminSnoop)); + adminBypass = properties.getBoolean("allow-admin-bypass", true); + properties.set("allow-admin-bypass", Boolean.valueOf(adminBypass)); + adminBreak = properties.getBoolean("allow-admin-break", true); + properties.set("allow-admin-break", Boolean.valueOf(adminBreak)); + + blockHopper = properties.getBoolean("enable-hopper-blocking", true); + properties.set("enable-hopper-blocking", Boolean.valueOf(blockHopper)); + + if ((protectDoors) || (protectTrapDoors)) { + if (this.doorCloser.start()) { + log.severe("[" + getDescription().getName() + "] Failed to register door closing task!"); + } + } else { + this.doorCloser.stop(); + } + + directPlacement = properties.getBoolean("enable-quick-protect", true); + properties.set("enable-quick-protect", Boolean.valueOf(directPlacement)); + colorTags = properties.getBoolean("enable-color-tags", true); + properties.set("enable-color-tags", Boolean.valueOf(colorTags)); + + debugMode = properties.getBoolean("enable-debug", false); + if (debugMode) { + log.warning("[" + getDescription().getName() + "] Debug mode is enabled, so Lockette chests are NOT secure."); + } + + defaultDoorTimer = properties.getInt("default-door-timer", -1); + if (defaultDoorTimer == -1) { + defaultDoorTimer = 0; + properties.set("default-door-timer", Integer.valueOf(defaultDoorTimer)); + propChanged = true; + } + + customBlockList = (List) properties.getList("custom-lockable-block-list"); + if (customBlockList == null) { + customBlockList = new ArrayList(3); + customBlockList.add(Integer.valueOf(Material.ENCHANTMENT_TABLE.getId())); + customBlockList.add(Integer.valueOf(Material.JUKEBOX.getId())); + customBlockList.add(Integer.valueOf(Material.DIAMOND_BLOCK.getId())); + customBlockList.add(Integer.valueOf(Material.ANVIL.getId())); + customBlockList.add(Integer.valueOf(Material.HOPPER.getId())); + properties.set("custom-lockable-block-list", customBlockList); + propChanged = true; + } + if (!customBlockList.isEmpty()) { + log.info("[" + getDescription().getName() + "] Custom lockable block list: " + customBlockList.toString()); + } + + disabledPluginList = (List) properties.getList("linked-plugin-ignore-list"); + if (disabledPluginList == null) { + disabledPluginList = new ArrayList(1); + disabledPluginList.add("mcMMO"); + properties.set("linked-plugin-ignore-list", disabledPluginList); + propChanged = true; + } + if (!disabledPluginList.isEmpty()) { + log.info("[" + getDescription().getName() + "] Ignoring linked plugins: " + disabledPluginList.toString()); + } + + broadcastSnoopTarget = properties.getString("broadcast-snoop-target"); + if (broadcastSnoopTarget == null) { + broadcastSnoopTarget = "[Everyone]"; + properties.set("broadcast-snoop-target", broadcastSnoopTarget); + propChanged = true; + } + broadcastBreakTarget = properties.getString("broadcast-break-target"); + if (broadcastBreakTarget == null) { + broadcastBreakTarget = "[Everyone]"; + properties.set("broadcast-break-target", broadcastBreakTarget); + propChanged = true; + } + broadcastReloadTarget = properties.getString("broadcast-reload-target"); + if (broadcastReloadTarget == null) { + broadcastReloadTarget = "[Operators]"; + properties.set("broadcast-reload-target", broadcastReloadTarget); + propChanged = true; + } + + String stringsFileName = properties.getString("strings-file-name"); + if ((stringsFileName == null) || (stringsFileName.isEmpty())) { + stringsFileName = "strings-en.yml"; + properties.set("strings-file-name", stringsFileName); + propChanged = true; + } + + if (propChanged) { + saveConfig(); + } + loadStrings(reload, stringsFileName); + } + + protected void loadStrings(boolean reload, String fileName) { + boolean stringChanged = false; + + File stringsFile = new File(getDataFolder(), fileName); + + if (strings != null) { + strings = null; + } + + strings = new YamlConfiguration(); + try { + strings.load(stringsFile); + } catch (InvalidConfigurationException ex) { + log.warning("[" + getDescription().getName() + "] Error loading " + fileName + ": " + ex.getMessage()); + + if (!fileName.equals("strings-en.yml")) { + loadStrings(reload, "strings-en.yml"); + return; + } + log.warning("[" + getDescription().getName() + "] Returning to default strings."); + } catch (Exception ex) { + } + + boolean original = false; + if (fileName.equals("strings-en.yml")) { + original = true; + + strings.set("language", "English"); + + if (original) { + try { + strings.save(stringsFile); + strings.load(stringsFile); + } catch (Exception ex) { + } + } + strings.set("author", "Acru"); + strings.set("editors", ""); + strings.set("version", Integer.valueOf(0)); + } + + String tempString = strings.getString("language"); + if ((tempString == null) || (tempString.isEmpty())) { + log.info("[" + getDescription().getName() + "] Loading strings file " + fileName); + } else { + log.info("[" + getDescription().getName() + "] Loading strings file for " + tempString + " by " + strings.getString("author")); + } + + altPrivate = strings.getString("alternate-private-tag"); + if ((altPrivate == null) || (altPrivate.isEmpty()) || ((original) && (altPrivate.equals("Privé")))) { + altPrivate = "Private"; + strings.set("alternate-private-tag", altPrivate); + } + altPrivate = "[" + altPrivate + "]"; + + altMoreUsers = strings.getString("alternate-moreusers-tag"); + if ((altMoreUsers == null) || (altMoreUsers.isEmpty()) || ((original) && (altMoreUsers.equals("Autre Noms")))) { + altMoreUsers = "More Users"; + strings.set("alternate-moreusers-tag", altMoreUsers); + stringChanged = true; + } + altMoreUsers = "[" + altMoreUsers + "]"; + + altEveryone = strings.getString("alternate-everyone-tag"); + if ((altEveryone == null) || (altEveryone.isEmpty()) || ((original) && (altEveryone.equals("Tout le Monde")))) { + altEveryone = "Everyone"; + strings.set("alternate-everyone-tag", altEveryone); + stringChanged = true; + } + altEveryone = "[" + altEveryone + "]"; + + altOperators = strings.getString("alternate-operators-tag"); + if ((altOperators == null) || (altOperators.isEmpty()) || ((original) && (altOperators.equals("Opérateurs")))) { + altOperators = "Operators"; + strings.set("alternate-operators-tag", altOperators); + stringChanged = true; + } + altOperators = "[" + altOperators + "]"; + + altTimer = strings.getString("alternate-timer-tag"); + if ((altTimer == null) || (altTimer.isEmpty()) || ((original) && (altTimer.equals("Minuterie")))) { + altTimer = "Timer"; + strings.set("alternate-timer-tag", altTimer); + stringChanged = true; + } + + altFee = strings.getString("alternate-fee-tag"); + if ((altFee == null) || (altFee.isEmpty())) { + altFee = "Fee"; + strings.set("alternate-fee-tag", altFee); + stringChanged = true; + } + + tempString = strings.getString("msg-user-conflict-door"); + if (tempString == null) { + strings.set("msg-user-conflict-door", "Conflicting door removed!"); + stringChanged = true; + } + tempString = strings.getString("msg-user-illegal"); + if (tempString == null) { + strings.set("msg-user-illegal", "Illegal chest removed!"); + stringChanged = true; + } + tempString = strings.getString("msg-user-resize-owned"); + if (tempString == null) { + strings.set("msg-user-resize-owned", "You cannot resize a chest claimed by ***."); + stringChanged = true; + } + tempString = strings.getString("msg-help-chest"); + if (tempString == null) { + strings.set("msg-help-chest", "Place a sign headed [Private] next to a chest to lock it."); + stringChanged = true; + } + + tempString = strings.getString("msg-owner-release"); + if (tempString == null) { + strings.set("msg-owner-release", "You have released a container!"); + stringChanged = true; + } + tempString = strings.getString("msg-admin-release"); + if (tempString == null) { + strings.set("msg-admin-release", "(Admin) @@@ has broken open a container owned by ***!"); + stringChanged = true; + } + tempString = strings.getString("msg-user-release-owned"); + if (tempString == null) { + strings.set("msg-user-release-owned", "You cannot release a container claimed by ***."); + stringChanged = true; + } + tempString = strings.getString("msg-owner-remove"); + if (tempString == null) { + strings.set("msg-owner-remove", "You have removed users from a container!"); + stringChanged = true; + } + tempString = strings.getString("msg-user-remove-owned"); + if (tempString == null) { + strings.set("msg-user-remove-owned", "You cannot remove users from a container claimed by ***."); + stringChanged = true; + } + tempString = strings.getString("msg-user-break-owned"); + if (tempString == null) { + strings.set("msg-user-break-owned", "You cannot break a container claimed by ***."); + stringChanged = true; + } + + tempString = strings.getString("msg-user-denied-door"); + if (tempString == null) { + strings.set("msg-user-denied-door", "You don't have permission to use this door."); + stringChanged = true; + } + + tempString = strings.getString("msg-user-touch-fee"); + if (tempString == null) { + strings.set("msg-user-touch-fee", "A fee of ### will be paid to ***, to open."); + stringChanged = true; + } + tempString = strings.getString("msg-user-touch-owned"); + if (tempString == null) { + strings.set("msg-user-touch-owned", "This container has been claimed by ***."); + stringChanged = true; + } + tempString = strings.getString("msg-help-select"); + if (tempString == null) { + strings.set("msg-help-select", "Sign selected, use /lockette to edit."); + stringChanged = true; + } + + tempString = strings.getString("msg-admin-bypass"); + if (tempString == null) { + strings.set("msg-admin-bypass", "Bypassed a door owned by ***, be sure to close it behind you."); + stringChanged = true; + } + tempString = strings.getString("msg-admin-snoop"); + if (tempString == null) { + strings.set("msg-admin-snoop", "(Admin) @@@ has snooped around in a container owned by ***!"); + stringChanged = true; + } + tempString = strings.getString("msg-user-denied"); + if (tempString == null) { + strings.set("msg-user-denied", "You don't have permission to open this container."); + stringChanged = true; + } + + tempString = strings.getString("msg-error-zone"); + if (tempString == null) { + strings.set("msg-error-zone", "This zone is protected by ***."); + stringChanged = true; + } + tempString = strings.getString("msg-error-permission"); + if (tempString == null) { + strings.set("msg-error-permission", "Permission to lock container denied."); + stringChanged = true; + } else if (tempString.equals("Permission to lock containers denied.")) { + strings.set("msg-error-permission", "Permission to lock container denied."); + stringChanged = true; + } + tempString = strings.getString("msg-error-claim"); + if (tempString == null) { + strings.set("msg-error-claim", "No unclaimed container nearby to make Private!"); + stringChanged = true; + } + tempString = strings.getString("msg-error-claim-conflict"); + if (tempString == null) { + strings.set("msg-error-claim-conflict", "Conflict with an existing protected door."); + stringChanged = true; + } + tempString = strings.getString("msg-admin-claim-error"); + if (tempString == null) { + strings.set("msg-admin-claim-error", "Player *** is not online, be sure you have the correct name."); + stringChanged = true; + } + tempString = strings.getString("msg-admin-claim"); + if (tempString == null) { + strings.set("msg-admin-claim", "You have claimed a container for ***."); + stringChanged = true; + } + tempString = strings.getString("msg-owner-claim"); + if (tempString == null) { + strings.set("msg-owner-claim", "You have claimed a container!"); + stringChanged = true; + } + tempString = strings.getString("msg-error-adduser-owned"); + if (tempString == null) { + strings.set("msg-error-adduser-owned", "You cannot add users to a container claimed by ***."); + stringChanged = true; + } + tempString = strings.getString("msg-error-adduser"); + if (tempString == null) { + strings.set("msg-error-adduser", "No claimed container nearby to add users to!"); + stringChanged = true; + } + tempString = strings.getString("msg-owner-adduser"); + if (tempString == null) { + strings.set("msg-owner-adduser", "You have added users to a container!"); + stringChanged = true; + } + + if (original) { + strings.set("msg-help-command1", "&C/lockette - Edits signs on locked containers. Right click on the sign to edit."); + strings.set("msg-help-command2", "&C/lockette fix - Fixes an automatic door that is in the wrong position. Look at the door to edit."); + strings.set("msg-help-command3", "&C/lockette reload - Reloads the configuration files. Operators only."); + strings.set("msg-help-command4", "&C/lockette version - Reports Lockette version."); + stringChanged = true; + } + + tempString = strings.getString("msg-admin-reload"); + if (tempString == null) { + strings.set("msg-admin-reload", "Reloading plugin configuration files."); + stringChanged = true; + } + tempString = strings.getString("msg-error-fix"); + if (tempString == null) { + strings.set("msg-error-fix", "No owned door found."); + stringChanged = true; + } + tempString = strings.getString("msg-error-edit"); + if (tempString == null) { + strings.set("msg-error-edit", "First select a sign by right clicking it."); + stringChanged = true; + } + tempString = strings.getString("msg-owner-edit"); + if (tempString == null) { + strings.set("msg-owner-edit", "Sign edited successfully."); + stringChanged = true; + } + + if ((original) && (stringChanged)) { + try { + strings.save(stringsFile); + } catch (Exception ex) { + } + } + } + + public static boolean isProtected(Block block) { + if (!enabled) { + return false; + } + + int type = block.getTypeId(); + + if (type == Material.WALL_SIGN.getId()) { + Sign sign = (Sign) block.getState(); + String text = sign.getLine(0).replaceAll("(?i)§[0-F]", "").toLowerCase(); + + if ((text.equals("[private]")) || (text.equalsIgnoreCase(altPrivate))) { + return true; + } + if ((text.equals("[more users]")) || (text.equalsIgnoreCase(altMoreUsers))) { + Block checkBlock = BlockUtil.getSignAttachedBlock(block); + + if ((checkBlock != null) && (findBlockOwner(checkBlock) != null)) { + return true; + } + } + } else if (findBlockOwner(block) != null) { + return true; + } + return false; + } + + public static String getProtectedOwner(Block block) { + return Bukkit.getOfflinePlayer(getProtectedOwnerUUID(block)).getName(); + } + + public static UUID getProtectedOwnerUUID(Block block) { + if (!enabled) { + return null; + } + + int type = block.getTypeId(); + + if (type == Material.WALL_SIGN.getId()) { + Sign sign = (Sign) block.getState(); + String text = ChatColor.stripColor(sign.getLine(0)).toLowerCase(); + + if ((text.equals("[private]")) || (text.equalsIgnoreCase(altPrivate))) { + return getUUIDFromMeta(sign, 1); + } + if ((text.equals("[more users]")) || (text.equalsIgnoreCase(altMoreUsers))) { + Block checkBlock = BlockUtil.getSignAttachedBlock(block); + + if (checkBlock != null) { + Block signBlock = findBlockOwner(checkBlock); + + if (signBlock != null) { + sign = (Sign) signBlock.getState(); + return getUUIDFromMeta(sign, 1); + } + } + } + } else { + Block signBlock = findBlockOwner(block); + if (signBlock != null) { + Sign sign = (Sign) signBlock.getState(); + return getUUIDFromMeta(sign, 1); + } + } + + return null; + } + + public static boolean isEveryone(Block block) { + if (!enabled) { + return true; + } + + Block signBlock = findBlockOwner(block); + + if (signBlock == null) { + return true; + } + + Sign sign = (Sign) signBlock.getState(); + + for (int y = 1; y <= 3; y++) { + if (!sign.getLine(y).isEmpty()) { + String line = sign.getLine(y).replaceAll("(?i)§[0-F]", ""); + + if ((line.equalsIgnoreCase("[Everyone]")) || (line.equalsIgnoreCase(altEveryone))) { + return true; + } + + } + } + + List list = findBlockUsers(block, signBlock); + int count = list.size(); + + for (int x = 0; x < count; x++) { + sign = (Sign) ((Block) list.get(x)).getState(); + + for (int y = 1; y <= 3; y++) { + if (!sign.getLine(y).isEmpty()) { + String line = sign.getLine(y).replaceAll("(?i)§[0-F]", ""); + + if ((line.equalsIgnoreCase("[Everyone]")) || (line.equalsIgnoreCase(altEveryone))) { + return true; + } + } + } + + } + + return false; + } + + protected boolean pluginEnableOverride(String pluginName) { + return isInList(pluginName, disabledPluginList); + } + + protected boolean usingExternalPermissions() { + return usePermissions; + } + + protected boolean usingExternalZones() { + return usingExternalZones; + } + + protected String getLocalizedEveryone() { + return altEveryone; + } + + protected String getLocalizedOperators() { + return altOperators; + } + + protected void localizedMessage(Player player, String broadcast, String key) { + localizedMessage(player, broadcast, key, null, null); + } + + protected void localizedMessage(Player player, String broadcast, String key, String sub) { + localizedMessage(player, broadcast, key, sub, null); + } + + protected void localizedMessage(Player player, String broadcast, String key, String sub, String num) { + String color = ""; + + if (key.startsWith("msg-user-")) { + if ((broadcast == null) && (!msgUser)) { + return; + } + color = ChatColor.YELLOW.toString(); + } else if (key.startsWith("msg-owner-")) { + if ((broadcast == null) && (!msgOwner)) { + return; + } + color = ChatColor.GOLD.toString(); + } else if (key.startsWith("msg-admin-")) { + if ((broadcast == null) && (!msgAdmin)) { + return; + } + color = ChatColor.RED.toString(); + } else if (key.startsWith("msg-error-")) { + if ((broadcast == null) && (!msgError)) { + return; + } + color = ChatColor.RED.toString(); + } else if (key.startsWith("msg-help-")) { + if ((broadcast == null) && (!msgHelp)) { + return; + } + color = ChatColor.GOLD.toString(); + } + + String message = strings.getString(key); + if ((message == null) || (message.isEmpty())) { + return; + } + + message = message.replaceAll("&([0-9A-Fa-f])", "§$1"); + if (sub != null) { + message = message.replaceAll("\\*\\*\\*", sub + color); + } + if (num != null) { + message = message.replaceAll("###", num); + } + if (player != null) { + message = message.replaceAll("@@@", player.getName()); + } + + if (broadcast != null) { + selectiveBroadcast(broadcast, color + "[Lockette] " + message); + } else if (player != null) { + player.sendMessage(color + "[Lockette] " + message); + } + } + + protected void selectiveBroadcast(String target, String message) { + if (target == null) { + return; + } + if (target.isEmpty()) { + return; + } + if (message == null) { + return; + } + if (message.isEmpty()) { + return; + } + + Collection players = Utils.getOnlinePlayers(); + + if (target.charAt(0) == '[') { + for (Player p : players) { + if (inGroup(p.getWorld(), p, target)) { + p.sendMessage(message); + } + } + } else { + for (Player p : players) { + if (target.equalsIgnoreCase(p.getName())) { + p.sendMessage(message); + } + } + } + } + + protected static Block findBlockOwner(Block block) { + return findBlockOwner(block, null, false); + } + + protected static Block findBlockOwnerBreak(Block block) { + int type = block.getTypeId(); + + if (BlockUtil.isInList(type, BlockUtil.materialListChests)) { + return findBlockOwnerBase(block, null, false, false, false, false, false); + } + if ((BlockUtil.isInList(type, BlockUtil.materialListTools)) || (isInList(Integer.valueOf(type), customBlockList))) { + return findBlockOwnerBase(block, null, false, false, false, false, false); + } + if ((protectTrapDoors) && (BlockUtil.isInList(type, BlockUtil.materialListTrapDoors))) { + return findBlockOwnerBase(block, null, false, false, false, false, false); + } + if ((protectDoors) && (BlockUtil.isInList(type, BlockUtil.materialListDoors))) { + return findBlockOwnerBase(block, null, false, true, true, false, false); + } + + Block checkBlock = findBlockOwnerBase(block, null, false, false, false, false, false); + if (checkBlock != null) { + return checkBlock; + } + + if (protectTrapDoors) { + checkBlock = block.getRelative(BlockFace.NORTH); + if ((BlockUtil.isInList(checkBlock.getTypeId(), BlockUtil.materialListTrapDoors)) + && ((checkBlock.getData() & 0x3) == 2)) { + checkBlock = findBlockOwnerBase(checkBlock, null, false, false, false, false, false); + if (checkBlock != null) { + return checkBlock; + } + + } + + checkBlock = block.getRelative(BlockFace.EAST); + if ((BlockUtil.isInList(checkBlock.getTypeId(), BlockUtil.materialListTrapDoors)) + && ((checkBlock.getData() & 0x3) == 0)) { + checkBlock = findBlockOwnerBase(checkBlock, null, false, false, false, false, false); + if (checkBlock != null) { + return checkBlock; + } + + } + + checkBlock = block.getRelative(BlockFace.SOUTH); + if ((BlockUtil.isInList(checkBlock.getTypeId(), BlockUtil.materialListTrapDoors)) + && ((checkBlock.getData() & 0x3) == 3)) { + checkBlock = findBlockOwnerBase(checkBlock, null, false, false, false, false, false); + if (checkBlock != null) { + return checkBlock; + } + + } + + checkBlock = block.getRelative(BlockFace.WEST); + if ((BlockUtil.isInList(checkBlock.getTypeId(), BlockUtil.materialListTrapDoors)) + && ((checkBlock.getData() & 0x3) == 1)) { + checkBlock = findBlockOwnerBase(checkBlock, null, false, false, false, false, false); + if (checkBlock != null) { + return checkBlock; + } + } + + } + + if (protectDoors) { + checkBlock = block.getRelative(BlockFace.UP); + type = checkBlock.getTypeId(); + + if (!BlockUtil.isInList(type, BlockUtil.materialListDoors)) { + return findBlockOwnerBase(checkBlock, null, false, true, true, false, false); + } + } + + return null; + } + + protected static Block findBlockOwner(Block block, Block ignoreBlock, boolean iterateFurther) { + if (block == null) { + return null; + } + int type = block.getTypeId(); + Location ignore; + if (ignoreBlock != null) { + ignore = ignoreBlock.getLocation(); + } else { + ignore = null; + } + + if (BlockUtil.isInList(type, BlockUtil.materialListChests)) { + return findBlockOwnerBase(block, ignore, true, false, false, false, false); + } + if ((BlockUtil.isInList(type, BlockUtil.materialListTools)) || (isInList(Integer.valueOf(type), customBlockList))) { + return findBlockOwnerBase(block, ignore, false, false, false, false, false); + } + if ((protectTrapDoors) && (BlockUtil.isInList(type, BlockUtil.materialListTrapDoors))) { + return findBlockOwner(BlockUtil.getTrapDoorAttachedBlock(block), ignoreBlock, false); + } + if ((protectDoors) && (BlockUtil.isInList(type, BlockUtil.materialListDoors))) { + return findBlockOwnerBase(block, ignore, true, true, true, true, iterateFurther); + } + + if (protectTrapDoors) { + Block checkBlock = findBlockOwnerBase(block, ignore, false, false, false, false, false); + if (checkBlock != null) { + return checkBlock; + } + + checkBlock = block.getRelative(BlockFace.NORTH); + if ((BlockUtil.isInList(checkBlock.getTypeId(), BlockUtil.materialListTrapDoors)) + && ((checkBlock.getData() & 0x3) == 2)) { + checkBlock = findBlockOwnerBase(checkBlock, ignore, false, false, false, false, false); + if (checkBlock != null) { + return checkBlock; + } + + } + + checkBlock = block.getRelative(BlockFace.EAST); + if ((BlockUtil.isInList(checkBlock.getTypeId(), BlockUtil.materialListTrapDoors)) + && ((checkBlock.getData() & 0x3) == 0)) { + checkBlock = findBlockOwnerBase(checkBlock, ignore, false, false, false, false, false); + if (checkBlock != null) { + return checkBlock; + } + + } + + checkBlock = block.getRelative(BlockFace.SOUTH); + if ((BlockUtil.isInList(checkBlock.getTypeId(), BlockUtil.materialListTrapDoors)) + && ((checkBlock.getData() & 0x3) == 3)) { + checkBlock = findBlockOwnerBase(checkBlock, ignore, false, false, false, false, false); + if (checkBlock != null) { + return checkBlock; + } + + } + + checkBlock = block.getRelative(BlockFace.WEST); + if ((BlockUtil.isInList(checkBlock.getTypeId(), BlockUtil.materialListTrapDoors)) + && ((checkBlock.getData() & 0x3) == 1)) { + checkBlock = findBlockOwnerBase(checkBlock, ignore, false, false, false, false, false); + if (checkBlock != null) { + return checkBlock; + } + } + + } + + if (protectDoors) { + Block checkBlock = block.getRelative(BlockFace.UP); + type = checkBlock.getTypeId(); + if (BlockUtil.isInList(type, BlockUtil.materialListDoors)) { + Block result = findBlockOwnerBase(checkBlock, ignore, true, true, true, true, iterateFurther); + if (result != null) { + return result; + } + + } + + checkBlock = block.getRelative(BlockFace.DOWN); + type = checkBlock.getTypeId(); + if (BlockUtil.isInList(type, BlockUtil.materialListDoors)) { + Block checkBlock2 = checkBlock.getRelative(BlockFace.DOWN); + type = checkBlock2.getTypeId(); + if (BlockUtil.isInList(type, BlockUtil.materialListDoors)) { + return findBlockOwnerBase(checkBlock2, ignore, true, true, false, true, iterateFurther); + } + + return findBlockOwnerBase(checkBlock, ignore, true, true, false, true, iterateFurther); + } + + } + + return null; + } + + private static Block findBlockOwnerBase(Block block, Location ignore, boolean iterate, boolean iterateUp, boolean iterateDown, boolean includeEnds, boolean iterateFurther) { + if (iterateUp) { + Block checkBlock = block.getRelative(BlockFace.UP); + int type = checkBlock.getTypeId(); + + if (BlockUtil.isInList(type, BlockUtil.materialListDoors)) { + checkBlock = findBlockOwnerBase(checkBlock, ignore, false, iterateUp, false, includeEnds, false); + } else if (includeEnds) { + checkBlock = findBlockOwnerBase(checkBlock, ignore, false, false, false, includeEnds, false); + } else { + checkBlock = null; + } + if (checkBlock != null) { + return checkBlock; + } + } + + if (iterateDown) { + Block checkBlock = block.getRelative(BlockFace.DOWN); + int type = checkBlock.getTypeId(); + + if (BlockUtil.isInList(type, BlockUtil.materialListDoors)) { + checkBlock = findBlockOwnerBase(checkBlock, ignore, false, false, iterateDown, includeEnds, false); + } else if (includeEnds) { + checkBlock = findBlockOwnerBase(checkBlock, ignore, false, false, false, includeEnds, false); + } else { + checkBlock = null; + } + if (checkBlock != null) { + return checkBlock; + } + + } + + Block checkBlock = block.getRelative(BlockFace.NORTH); + if (checkBlock.getTypeId() == Material.WALL_SIGN.getId()) { + byte face = checkBlock.getData(); + if (face == BlockUtil.faceList[2]) { + boolean doCheck; + if (ignore == null) { + doCheck = true; + } else { + if (checkBlock.getLocation().equals(ignore)) { + doCheck = false; + } else { + doCheck = true; + } + } + if (doCheck) { + Sign sign = (Sign) checkBlock.getState(); + String text = sign.getLine(0).replaceAll("(?i)§[0-F]", "").toLowerCase(); + + if ((text.equals("[private]")) || (text.equalsIgnoreCase(altPrivate))) { + return checkBlock; + } + } + } + } else if ((iterate) && (checkBlock.getTypeId() == block.getTypeId())) { + checkBlock = findBlockOwnerBase(checkBlock, ignore, iterateFurther, iterateUp, iterateDown, includeEnds, false); + if (checkBlock != null) { + return checkBlock; + } + } + + checkBlock = block.getRelative(BlockFace.EAST); + if (checkBlock.getTypeId() == Material.WALL_SIGN.getId()) { + byte face = checkBlock.getData(); + if (face == BlockUtil.faceList[3]) { + boolean doCheck; + if (ignore == null) { + doCheck = true; + } else { + if (checkBlock.getLocation().equals(ignore)) { + doCheck = false; + } else { + doCheck = true; + } + } + if (doCheck) { + Sign sign = (Sign) checkBlock.getState(); + String text = sign.getLine(0).replaceAll("(?i)§[0-F]", "").toLowerCase(); + + if ((text.equals("[private]")) || (text.equalsIgnoreCase(altPrivate))) { + return checkBlock; + } + } + } + } else if ((iterate) && (checkBlock.getTypeId() == block.getTypeId())) { + checkBlock = findBlockOwnerBase(checkBlock, ignore, iterateFurther, iterateUp, iterateDown, includeEnds, false); + if (checkBlock != null) { + return checkBlock; + } + } + + checkBlock = block.getRelative(BlockFace.SOUTH); + if (checkBlock.getTypeId() == Material.WALL_SIGN.getId()) { + byte face = checkBlock.getData(); + if (face == BlockUtil.faceList[0]) { + boolean doCheck; + if (ignore == null) { + doCheck = true; + } else { + doCheck = !checkBlock.getLocation().equals(ignore); + } + if (doCheck) { + Sign sign = (Sign) checkBlock.getState(); + String text = sign.getLine(0).replaceAll("(?i)§[0-F]", "").toLowerCase(); + + if ((text.equals("[private]")) || (text.equalsIgnoreCase(altPrivate))) { + return checkBlock; + } + } + } + } else if ((iterate) && (checkBlock.getTypeId() == block.getTypeId())) { + checkBlock = findBlockOwnerBase(checkBlock, ignore, iterateFurther, iterateUp, iterateDown, includeEnds, false); + if (checkBlock != null) { + return checkBlock; + } + } + + checkBlock = block.getRelative(BlockFace.WEST); + if (checkBlock.getTypeId() == Material.WALL_SIGN.getId()) { + byte face = checkBlock.getData(); + if (face == BlockUtil.faceList[1]) { + boolean doCheck; + if (ignore == null) { + doCheck = true; + } else { + doCheck = !checkBlock.getLocation().equals(ignore); + } + if (doCheck) { + Sign sign = (Sign) checkBlock.getState(); + String text = sign.getLine(0).replaceAll("(?i)§[0-F]", "").toLowerCase(); + + if ((text.equals("[private]")) || (text.equalsIgnoreCase(altPrivate))) { + return checkBlock; + } + } + } + } else if ((iterate) && (checkBlock.getTypeId() == block.getTypeId())) { + checkBlock = findBlockOwnerBase(checkBlock, ignore, iterateFurther, iterateUp, iterateDown, includeEnds, false); + if (checkBlock != null) { + return checkBlock; + } + } + + return null; + } + + protected static List findBlockUsers(Block block, Block signBlock) { + int type = block.getTypeId(); + + if (BlockUtil.isInList(type, BlockUtil.materialListChests)) { + return findBlockUsersBase(block, true, false, false, false, 0); + } + if ((protectTrapDoors) && (BlockUtil.isInList(type, BlockUtil.materialListTrapDoors))) { + return findBlockUsersBase(BlockUtil.getTrapDoorAttachedBlock(block), false, false, false, true, 0); + } + if ((protectDoors) && (BlockUtil.isInList(type, BlockUtil.materialListDoors))) { + return findBlockUsersBase(block, true, true, true, false, signBlock.getY()); + } + return findBlockUsersBase(block, false, false, false, false, 0); + } + + private static List findBlockUsersBase(Block block, boolean iterate, boolean iterateUp, boolean iterateDown, boolean traps, int includeYPos) { + List list = new ArrayList(); + + if (iterateUp) { + Block checkBlock = block.getRelative(BlockFace.UP); + int type = checkBlock.getTypeId(); + + if (BlockUtil.isInList(type, BlockUtil.materialListDoors)) { + list.addAll(findBlockUsersBase(checkBlock, false, iterateUp, false, false, includeYPos)); + } else if (checkBlock.getY() == includeYPos) { + list.addAll(findBlockUsersBase(checkBlock, false, false, false, false, includeYPos)); + } + } + + if (iterateDown) { + Block checkBlock = block.getRelative(BlockFace.DOWN); + int type = checkBlock.getTypeId(); + + if (BlockUtil.isInList(type, BlockUtil.materialListDoors)) { + list.addAll(findBlockUsersBase(checkBlock, false, false, iterateDown, false, includeYPos)); + } else { + list.addAll(findBlockUsersBase(checkBlock, false, false, false, false, includeYPos)); + } + + } + + Block checkBlock = block.getRelative(BlockFace.NORTH); + int type = checkBlock.getTypeId(); + if (type == Material.WALL_SIGN.getId()) { + byte face = checkBlock.getData(); + if (face == BlockUtil.faceList[2]) { + Sign sign = (Sign) checkBlock.getState(); + String text = sign.getLine(0).replaceAll("(?i)§[0-F]", "").toLowerCase(); + + if ((text.equals("[more users]")) || (text.equalsIgnoreCase(altMoreUsers))) { + list.add(checkBlock); + } + } + } else if (iterate) { + if (type == block.getTypeId()) { + list.addAll(findBlockUsersBase(checkBlock, false, iterateUp, iterateDown, false, includeYPos)); + } + } else if ((traps) && (BlockUtil.isInList(type, BlockUtil.materialListTrapDoors))) { + byte face = checkBlock.getData(); + if ((face & 0x3) == 2) { + list.addAll(findBlockUsersBase(checkBlock, false, false, false, false, includeYPos)); + } + } + + checkBlock = block.getRelative(BlockFace.EAST); + type = checkBlock.getTypeId(); + if (type == Material.WALL_SIGN.getId()) { + byte face = checkBlock.getData(); + if (face == BlockUtil.faceList[3]) { + Sign sign = (Sign) checkBlock.getState(); + String text = sign.getLine(0).replaceAll("(?i)§[0-F]", "").toLowerCase(); + + if ((text.equals("[more users]")) || (text.equalsIgnoreCase(altMoreUsers))) { + list.add(checkBlock); + } + } + } else if (iterate) { + if (type == block.getTypeId()) { + list.addAll(findBlockUsersBase(checkBlock, false, iterateUp, iterateDown, false, includeYPos)); + } + } else if ((traps) && (BlockUtil.isInList(type, BlockUtil.materialListTrapDoors))) { + byte face = checkBlock.getData(); + if ((face & 0x3) == 0) { + list.addAll(findBlockUsersBase(checkBlock, false, false, false, false, includeYPos)); + } + } + + checkBlock = block.getRelative(BlockFace.SOUTH); + type = checkBlock.getTypeId(); + if (type == Material.WALL_SIGN.getId()) { + byte face = checkBlock.getData(); + if (face == BlockUtil.faceList[0]) { + Sign sign = (Sign) checkBlock.getState(); + String text = sign.getLine(0).replaceAll("(?i)§[0-F]", "").toLowerCase(); + + if ((text.equals("[more users]")) || (text.equalsIgnoreCase(altMoreUsers))) { + list.add(checkBlock); + } + } + } else if (iterate) { + if (type == block.getTypeId()) { + list.addAll(findBlockUsersBase(checkBlock, false, iterateUp, iterateDown, false, includeYPos)); + } + } else if ((traps) && (BlockUtil.isInList(type, BlockUtil.materialListTrapDoors))) { + byte face = checkBlock.getData(); + if ((face & 0x3) == 3) { + list.addAll(findBlockUsersBase(checkBlock, false, false, false, false, includeYPos)); + } + } + + checkBlock = block.getRelative(BlockFace.WEST); + type = checkBlock.getTypeId(); + if (type == Material.WALL_SIGN.getId()) { + byte face = checkBlock.getData(); + if (face == BlockUtil.faceList[1]) { + Sign sign = (Sign) checkBlock.getState(); + String text = sign.getLine(0).replaceAll("(?i)§[0-F]", "").toLowerCase(); + + if ((text.equals("[more users]")) || (text.equalsIgnoreCase(altMoreUsers))) { + list.add(checkBlock); + } + } + } else if (iterate) { + if (type == block.getTypeId()) { + list.addAll(findBlockUsersBase(checkBlock, false, iterateUp, iterateDown, false, includeYPos)); + } + } else if ((traps) && (BlockUtil.isInList(type, BlockUtil.materialListTrapDoors))) { + byte face = checkBlock.getData(); + if ((face & 0x3) == 1) { + list.addAll(findBlockUsersBase(checkBlock, false, false, false, false, includeYPos)); + } + } + + return list; + } + + protected static int findChestCountNear(Block block) { + return findChestCountNearBase(block, (byte) 0); + } + + private static int findChestCountNearBase(Block block, byte face) { + int count = 0; + + if (face != 2) { + Block checkBlock = block.getRelative(BlockFace.NORTH); + if ((BlockUtil.isInList(checkBlock.getTypeId(), BlockUtil.materialListChests)) && (checkBlock.getTypeId() == block.getTypeId())) { + count++; + if (face == 0) { + count += findChestCountNearBase(checkBlock, (byte) 3); + } + } + } + + if (face != 5) { + Block checkBlock = block.getRelative(BlockFace.EAST); + if ((BlockUtil.isInList(checkBlock.getTypeId(), BlockUtil.materialListChests)) && (checkBlock.getTypeId() == block.getTypeId())) { + count++; + if (face == 0) { + count += findChestCountNearBase(checkBlock, (byte) 4); + } + } + } + + if (face != 3) { + Block checkBlock = block.getRelative(BlockFace.SOUTH); + if ((BlockUtil.isInList(checkBlock.getTypeId(), BlockUtil.materialListChests)) && (checkBlock.getTypeId() == block.getTypeId())) { + count++; + if (face == 0) { + count += findChestCountNearBase(checkBlock, (byte) 2); + } + } + } + + if (face != 4) { + Block checkBlock = block.getRelative(BlockFace.WEST); + if ((BlockUtil.isInList(checkBlock.getTypeId(), BlockUtil.materialListChests)) && (checkBlock.getTypeId() == block.getTypeId())) { + count++; + if (face == 0) { + count += findChestCountNearBase(checkBlock, (byte) 5); + } + } + } + + return count; + } + + protected static void rotateChestOrientation(Block block, BlockFace blockFace) { + if (!BlockUtil.isInList(block.getTypeId(), BlockUtil.materialListChests)) { + return; + } + if ((!rotateChests) && (block.getData() != 0)) { + return; + } + byte face; + if (blockFace == BlockFace.NORTH) { + face = BlockUtil.faceList[2]; + } else { + if (blockFace == BlockFace.EAST) { + face = BlockUtil.faceList[3]; + } else { + if (blockFace == BlockFace.SOUTH) { + face = BlockUtil.faceList[0]; + } else { + if (blockFace == BlockFace.WEST) { + face = BlockUtil.faceList[1]; + } else { + return; + } + } + } + } + Block checkBlock = block.getRelative(BlockFace.NORTH); + if ((BlockUtil.isInList(checkBlock.getTypeId(), BlockUtil.materialListChests)) && (checkBlock.getTypeId() == block.getTypeId())) { + if ((face == BlockUtil.faceList[1]) || (face == BlockUtil.faceList[3])) { + block.setData(face); + checkBlock.setData(face); + } + return; + } + + checkBlock = block.getRelative(BlockFace.EAST); + if ((BlockUtil.isInList(checkBlock.getTypeId(), BlockUtil.materialListChests)) && (checkBlock.getTypeId() == block.getTypeId())) { + if ((face == BlockUtil.faceList[2]) || (face == BlockUtil.faceList[0])) { + block.setData(face); + checkBlock.setData(face); + } + return; + } + + checkBlock = block.getRelative(BlockFace.SOUTH); + if ((BlockUtil.isInList(checkBlock.getTypeId(), BlockUtil.materialListChests)) && (checkBlock.getTypeId() == block.getTypeId())) { + if ((face == BlockUtil.faceList[1]) || (face == BlockUtil.faceList[3])) { + block.setData(face); + checkBlock.setData(face); + } + return; + } + + checkBlock = block.getRelative(BlockFace.WEST); + if ((BlockUtil.isInList(checkBlock.getTypeId(), BlockUtil.materialListChests)) && (checkBlock.getTypeId() == block.getTypeId())) { + if ((face == BlockUtil.faceList[2]) || (face == BlockUtil.faceList[0])) { + block.setData(face); + checkBlock.setData(face); + } + return; + } + + block.setData(face); + } + + protected static List toggleDoors(Block block, Block keyBlock, boolean wooden, boolean trap) { + List list = new ArrayList(); + + toggleDoorBase(block, keyBlock, !trap, wooden, list); + try { + if (!wooden) { + block.getWorld().playEffect(block.getLocation(), Effect.DOOR_TOGGLE, 0); + } + } catch (NoSuchFieldError ex) { + } catch (NoSuchMethodError ex) { + } catch (NoClassDefFoundError ex) { + } + return list; + } + + protected static void toggleSingleDoor(Block block) { + int type = block.getTypeId(); + + if (BlockUtil.isInList(type, BlockUtil.materialListJustDoors)) { + toggleDoorBase(block, null, true, false, null); + } else if ((BlockUtil.isInList(type, BlockUtil.materialListTrapDoors)) + || (BlockUtil.isInList(type, BlockUtil.materialListGates))) { + toggleDoorBase(block, null, false, false, null); + } + } + + protected static void toggleHalfDoor(Block block, boolean effect) { + int type = block.getTypeId(); + + if (BlockUtil.isInList(type, BlockUtil.materialListDoors)) { + block.setData((byte) (block.getData() ^ 0x4)); + try { + if (effect) { + block.getWorld().playEffect(block.getLocation(), Effect.DOOR_TOGGLE, 0); + } + } catch (NoSuchFieldError ex) { + } catch (NoSuchMethodError ex) { + } catch (NoClassDefFoundError ex) { + } + } + } + + private static void toggleDoorBase(Block block, Block keyBlock, boolean iterateUpDown, boolean skipDoor, List list) { + if (list != null) { + list.add(block); + } + if (!skipDoor) { + block.setData((byte) (block.getData() ^ 0x4)); + } + + if (iterateUpDown) { + Block checkBlock = block.getRelative(BlockFace.UP); + if (checkBlock.getTypeId() == block.getTypeId()) { + toggleDoorBase(checkBlock, null, false, skipDoor, list); + } + + checkBlock = block.getRelative(BlockFace.DOWN); + if (checkBlock.getTypeId() == block.getTypeId()) { + toggleDoorBase(checkBlock, null, false, skipDoor, list); + } + + } + + if (keyBlock != null) { + Block checkBlock = block.getRelative(BlockFace.NORTH); + if ((checkBlock.getTypeId() == block.getTypeId()) && (((checkBlock.getX() == keyBlock.getX()) && (checkBlock.getZ() == keyBlock.getZ())) || ((block + .getX() == keyBlock.getX()) && (block.getZ() == keyBlock.getZ())))) { + toggleDoorBase(checkBlock, null, true, false, list); + } + + checkBlock = block.getRelative(BlockFace.EAST); + if ((checkBlock.getTypeId() == block.getTypeId()) && (((checkBlock.getX() == keyBlock.getX()) && (checkBlock.getZ() == keyBlock.getZ())) || ((block + .getX() == keyBlock.getX()) && (block.getZ() == keyBlock.getZ())))) { + toggleDoorBase(checkBlock, null, true, false, list); + } + + checkBlock = block.getRelative(BlockFace.SOUTH); + if ((checkBlock.getTypeId() == block.getTypeId()) && (((checkBlock.getX() == keyBlock.getX()) && (checkBlock.getZ() == keyBlock.getZ())) || ((block + .getX() == keyBlock.getX()) && (block.getZ() == keyBlock.getZ())))) { + toggleDoorBase(checkBlock, null, true, false, list); + } + + checkBlock = block.getRelative(BlockFace.WEST); + if ((checkBlock.getTypeId() == block.getTypeId()) && (((checkBlock.getX() == keyBlock.getX()) && (checkBlock.getZ() == keyBlock.getZ())) || ((block + .getX() == keyBlock.getX()) && (block.getZ() == keyBlock.getZ())))) { + toggleDoorBase(checkBlock, null, true, false, list); + } + } + } + + protected static int getSignOption(Block signBlock, String tag, String altTag, int defaultValue) { + Sign sign = (Sign) signBlock.getState(); + + for (int y = 2; y <= 3; y++) { + if (!sign.getLine(y).isEmpty()) { + String line = sign.getLine(y).replaceAll("(?i)§[0-F]", ""); + + int end = line.length() - 1; + + if ((end >= 2) && (line.charAt(0) == '[') && (line.charAt(end) == ']')) { + int index = line.indexOf(":"); + + if (index == -1) { + if ((line.substring(1, end).equalsIgnoreCase(tag)) || (line.substring(1, end).equalsIgnoreCase(altTag))) { + return defaultValue; + } + } else { + if ((!line.substring(1, index).equalsIgnoreCase(tag)) && (!line.substring(1, index).equalsIgnoreCase(altTag))) { + continue; + } + for (int x = index; x < end; x++) { + if (Character.isDigit(line.charAt(x))) { + index = x; + break; + } + } + for (int x = index + 1; x < end; x++) { + if (!Character.isDigit(line.charAt(x))) { + end = x; + break; + } + + } + + try { + int value = Integer.parseInt(line.substring(index, end)); + return value; + } catch (NumberFormatException ex) { + return defaultValue; + } + } + } + } + } + + return defaultValue; + } + + protected static boolean isInList(Object target, List list) { + if (list == null) { + return false; + } + for (int x = 0; x < list.size(); x++) { + if (list.get(x).equals(target)) { + return true; + } + } + return false; + } + + private static boolean isHackFormat(String line) { + String[] strs = line.split(":"); + return (line.indexOf(":") > 1) && (strs[1].length() == 36); + } + + private static String trim(String str) { + return str == null ? null : str.trim(); + } + + private static String getPlayerName(String str) { + return trim(str.indexOf(":") > 0 ? str.split(":")[0] : str); + } + + private static String getPlayerUUIDString(String str) { + return trim(str.indexOf(":") > 0 ? str.split(":")[1] : str); + } + + private static UUID getPlayerUUID(String str) { + return UUID.fromString(getPlayerUUIDString(str)); + } + + static void setLine(Sign sign, int index, String typed) { + OfflinePlayer player = null; + if ((!typed.isEmpty()) && (typed.indexOf("[") != 0)) { + String id = ChatColor.stripColor(typed.replaceAll("&([0-9A-Fa-f])", "")); + player = Bukkit.getOfflinePlayer(id); + } + + setLine(sign, index, typed, player); + } + + static void setLine(Sign sign, int index, String typed, OfflinePlayer player) { + String cline = typed.replaceAll("&([0-9A-Fa-f])", "§$1"); + sign.setLine(index, cline); + sign.update(true); + + UUID[] uuids = null; + if (!sign.hasMetadata("LocketteUUIDs")) { + uuids = new UUID[3]; + sign.setMetadata("LocketteUUIDs", new FixedMetadataValue(plugin, uuids)); + } else { + List list = sign.getMetadata("LocketteUUIDs"); + + uuids = (UUID[]) (UUID[]) ((MetadataValue) list.get(0)).value(); + } + uuids[(index - 1)] = (player != null ? player.getUniqueId() : null); + if (DEBUG) { + log.info("[Lockette] setting the line " + index + " to " + cline); + log.info("[Lockette] corresponding player is " + player); + log.info("[Lockette] uuid has been attached: " + uuids[(index - 1)]); + } + } + + private static UUID getUUIDFromMeta(Sign sign, int index) { + if (sign.hasMetadata("LocketteUUIDs")) { + List list = sign.getMetadata("LocketteUUIDs"); + + return ((UUID[]) (UUID[]) ((MetadataValue) list.get(0)).value())[(index - 1)]; + } + return null; + } + + static void removeUUIDMetadata(Sign sign) { + if (sign.hasMetadata("LocketteUUIDs")) { + sign.removeMetadata("LocketteUUIDs", plugin); + } + } + + private static boolean oldFormatCheck(String signname, String pname) { + signname = ChatColor.stripColor(signname); + pname = ChatColor.stripColor(pname); + int length = pname.length(); + if (length > 15) { + length = 15; + } + return signname.equalsIgnoreCase(pname.substring(0, length)); + } + + private static boolean matchUserUUID(Sign sign, int index, OfflinePlayer player, boolean update) { + try { + String line = sign.getLine(index); + String checkline = ChatColor.stripColor(line); + + if (((checkline.indexOf("[") == 0) && (checkline.indexOf("]") > 1)) + || (line + .isEmpty())) { + return false; + } + + if (!uuidSupport) { + if (DEBUG) { + log.info("[Lockette] NO UUID support, doing old name checking."); + } + + String pname = player.getName(); + String against = checkline.split(":")[0].trim(); + return oldFormatCheck(against, pname); + } + + UUID uuid = null; + String name = getPlayerName(line); + if (DEBUG) { + log.info("[Lockette] Name on the sign is : " + name); + } + + if (isHackFormat(line)) { + try { + uuid = getPlayerUUID(line); + } catch (IllegalArgumentException e) { + log.info("[" + plugin.getDescription().getName() + "] Invalid Player UUID!"); + return false; + } + if ((uuid != null) && (update)) { + OfflinePlayer p = Bukkit.getOfflinePlayer(uuid); + if (DEBUG) { + log.info("[Lockette] updating the old hacked format for " + p); + } + setLine(sign, index, name, p); + } + + sign.update(); + } + + if ((!sign.hasMetadata("LocketteUUIDs")) || (getUUIDFromMeta(sign, index) == null)) { + if (DEBUG) { + log.info("[Lockette] Checking for original format for " + checkline); + } + OfflinePlayer oplayer = Bukkit.getOfflinePlayer(checkline); + if ((oplayer != null) && (oplayer.hasPlayedBefore())) { + if (DEBUG) { + log.info("[Lockette] converting original format for " + oplayer + " name = " + checkline); + } + setLine(sign, index, line, oplayer); + } else { + String pname = player.getName(); + String against = checkline.split(":")[0].trim(); + if (oldFormatCheck(against, pname)) { + if (DEBUG) { + log.info("[Lockette] Partial match! Converting original format for " + player.getName() + " name = " + checkline); + } + setLine(sign, index, player.getName(), player); + } + + } + + sign.update(); + } + + uuid = getUUIDFromMeta(sign, index); + + if (DEBUG) { + log.info("[Lockette] uuid on the sign = " + uuid); + log.info("[Lockette] player's uuid = " + player.getUniqueId()); + } + + if (uuid != null) { + if (uuid.equals(player.getUniqueId())) { + if (!ChatColor.stripColor(ChatColor.stripColor(name)).equals(player.getName())) { + sign.setLine(index, player.getName()); + sign.update(); + } + return true; + } + + OfflinePlayer oplayer = Bukkit.getOfflinePlayer(uuid); + if (!oplayer.hasPlayedBefore()) { + if (DEBUG) { + log.info("[Lockette] removing bad UUID"); + } + removeUUIDMetadata(sign); + } + } else { + List names = getPreviousNames(player.getUniqueId()); + for (String n : names) { + if (n.equalsIgnoreCase(name)) { + if (DEBUG) { + log.info("[Lockette] Found the match in the name history!"); + } + + setLine(sign, index, player.getName(), player); + return true; + } + } + } + } catch (Exception e) { + String name; + String pname; + log.info("[Lockette] Something bad happened returning match = false"); + e.printStackTrace(); + } + + return false; + } + + public static boolean isOwner(Block block, String name) { + return isOwner(block, Bukkit.getOfflinePlayer(name)); + } + + public static boolean isUser(Block block, String name, boolean withGroups) { + return isUser(block, Bukkit.getOfflinePlayer(name), withGroups); + } + + public static boolean isOwner(Block block, OfflinePlayer player) { + if (!enabled) { + return true; + } + Block checkBlock = findBlockOwner(block); + if (checkBlock == null) { + return true; + } + Sign sign = (Sign) checkBlock.getState(); + + return matchUserUUID(sign, 1, player, true); + } + + public static boolean isOwner(Sign sign, OfflinePlayer player) { + return matchUserUUID(sign, 1, player, true); + } + + public static boolean isUser(Block block, OfflinePlayer player, boolean withGroups) { + if (!enabled) { + return true; + } + Block signBlock = findBlockOwner(block); + + if (signBlock == null) { + return true; + } + + Sign sign = (Sign) signBlock.getState(); + String line; + for (int y = 1; y <= 3; y++) { + line = sign.getLine(y); + if (matchUserUUID(sign, y, player, true)) { + return true; + } + + if ((withGroups) && (plugin.inGroup(block.getWorld(), player.getName(), line))) { + return true; + } + + } + + List list = findBlockUsers(block, signBlock); + for (Block blk : list) { + sign = (Sign) blk.getState(); + + for (int y = 1; y <= 3; y++) { + line = sign.getLine(y); + if (matchUserUUID(sign, y, player, true)) { + return true; + } + + if ((withGroups) && (plugin.inGroup(block.getWorld(), player.getName(), line))) { + return true; + } + } + } + + return false; + } + + private static List getPreviousNames(UUID uuid) { + String name = null; + List list = new ArrayList(); + try { + if (name == null) { + HttpURLConnection connection = (HttpURLConnection) new URL(NAME_HISTORY_URL + uuid.toString().replace("-", "") + "/names").openConnection(); + connection.setConnectTimeout(5000); + connection.setReadTimeout(5000); + JSONArray array = (JSONArray) jsonParser.parse(new InputStreamReader(connection.getInputStream())); + + Iterator iterator = array.iterator(); + while (iterator.hasNext()) { + JSONObject obj = (JSONObject) iterator.next(); + list.add((String) obj.get("name")); + } + } + } catch (SocketTimeoutException ste) { + log.info("[Lockette] Connection timeout (to Mojang site)"); + } catch (Exception ioe) { + log.info("[Lockette] Failed to get Name history!"); + } + return list; + } + + public boolean hasPermission(World world, Player player, String permissionNode) { + return player.hasPermission(permissionNode); + } + + public boolean hasPermission(World world, String playerName, String permissionNode) { + return this.hasPermission(world, getServer().getPlayerExact(playerName), permissionNode); + } + + public boolean canBuild(String playerName, Block block) { + return canBuild(getServer().getPlayerExact(playerName), block); + } + + private static boolean useTowny = false; + private static boolean useLWC = false; + + public boolean canBuild(Player player, Block block) { + lastZoneDeny = "noone"; + if (!usingExternalZones()) { + return true; + } + + if (useTowny) { + try { + if ((TownyUniverse.getDataSource().getWorld(block.getWorld().getName()).isUsingTowny()) + && (TownyUniverse.isWilderness(block)) + && (usingExternalPermissions()) + && (!hasPermission(block.getWorld(), player, "lockette.towny.wilds"))) { + lastZoneDeny = "towny.wilds"; + return false; + } + + } catch (Exception e) { + } + + } + + if (useLWC) { + LWC lwc = linkLWC.getLWCPlugin().getLWC(); + Protection protection = lwc.findProtection(block); + + if ((protection != null) + && (!lwc.canAdminProtection(player, protection))) { + lastZoneDeny = "lwc.protection"; + return false; + } + + } + + return true; + } + + public boolean inGroup(org.bukkit.World world, Player player, String groupName) { + return inGroup(world, player, player.getName(), groupName); + } + + public boolean inGroup(org.bukkit.World world, String playerName, String groupName) { + return inGroup(world, getServer().getPlayer(playerName), playerName, groupName); + } + + private boolean inGroup(org.bukkit.World world, Player player, String playerName, String groupName) { + throw new UnsupportedOperationException("..."); + } + + public boolean playerOnline(String truncName) { + return Bukkit.getPlayerExact(truncName) != null; + } + + public static String lastZoneDeny() { + return lastZoneDeny; + } + +} diff --git a/src/main/java/org/yi/acru/bukkit/Lockette/LocketteBlockListener.java b/src/main/java/org/yi/acru/bukkit/Lockette/LocketteBlockListener.java new file mode 100644 index 0000000..71dc8e5 --- /dev/null +++ b/src/main/java/org/yi/acru/bukkit/Lockette/LocketteBlockListener.java @@ -0,0 +1,987 @@ +package org.yi.acru.bukkit.Lockette; + +import java.util.HashMap; +import java.util.List; +import java.util.logging.Logger; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.Server; +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.BlockPistonExtendEvent; +import org.bukkit.event.block.BlockPistonRetractEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.block.BlockRedstoneEvent; +import org.bukkit.event.block.SignChangeEvent; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.PluginManager; + +public class LocketteBlockListener implements Listener { + + private static Lockette plugin; + + public LocketteBlockListener(Lockette instance) { + plugin = instance; + } + + protected void registerEvents() { + PluginManager pm = plugin.getServer().getPluginManager(); + + pm.registerEvents(this, plugin); + } + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onBlockBreak(BlockBreakEvent event) { + Player player = event.getPlayer(); + Block block = event.getBlock(); + int type = block.getTypeId(); + + if ((event.isCancelled()) + && (!BlockUtil.isInList(type, BlockUtil.materialListJustDoors))) { + return; + } + + if (type == Material.WALL_SIGN.getId()) { + if (block.getData() == 0) { + block.setData((byte) 5); + } + + Sign sign = (Sign) block.getState(); + String text = ChatColor.stripColor(sign.getLine(0)); + + if ((text.equalsIgnoreCase("[Private]")) || (text.equalsIgnoreCase(Lockette.altPrivate))) { + int length = player.getName().length(); + + if (Lockette.isOwner(sign, player)) { + Lockette.log.info("[" + plugin.getDescription().getName() + "] " + player.getName() + " has released a container."); + + Lockette.removeUUIDMetadata(sign); + + plugin.localizedMessage(player, null, "msg-owner-release"); + return; + } + + if (Lockette.adminBreak) { + boolean snoop = false; + + if (plugin.hasPermission(block.getWorld(), player, "lockette.admin.break")) { + snoop = true; + } + if (snoop) { + Lockette.log.info("[" + plugin.getDescription().getName() + "] (Admin) " + player.getName() + " has broken open a container owned by " + sign.getLine(1) + "!"); + + Lockette.removeUUIDMetadata(sign); + plugin.localizedMessage(player, Lockette.broadcastBreakTarget, "msg-admin-release", sign.getLine(1)); + return; + } + } + + event.setCancelled(true); + sign.update(); + + plugin.localizedMessage(player, null, "msg-user-release-owned", sign.getLine(1)); + } else if ((text.equalsIgnoreCase("[More Users]")) || (text.equalsIgnoreCase(Lockette.altMoreUsers))) { + Block checkBlock = BlockUtil.getSignAttachedBlock(block); + if (checkBlock == null) { + return; + } + Block signBlock = Lockette.findBlockOwner(checkBlock); + if (signBlock == null) { + return; + } + Sign sign2 = (Sign) signBlock.getState(); + if (Lockette.isOwner(sign2, player)) { + Lockette.removeUUIDMetadata(sign); + plugin.localizedMessage(player, null, "msg-owner-remove"); + return; + } + + event.setCancelled(true); + sign.update(); + + plugin.localizedMessage(player, null, "msg-user-remove-owned", sign2.getLine(1)); + } + } else { + Block signBlock = Lockette.findBlockOwner(block); + + if (signBlock == null) { + return; + } + Sign sign = (Sign) signBlock.getState(); + + if (Lockette.isOwner(sign, player)) { + signBlock = Lockette.findBlockOwnerBreak(block); + if (signBlock != null) { + sign = (Sign) signBlock.getState(); + Lockette.removeUUIDMetadata(sign); + + Lockette.log.info("[" + plugin.getDescription().getName() + "] " + player.getName() + " has released a container."); + } else if (!BlockUtil.isInList(type, BlockUtil.materialListJustDoors)); + return; + } + + event.setCancelled(true); + + plugin.localizedMessage(player, null, "msg-user-break-owned", sign.getLine(1)); + } + } + + @EventHandler(priority = EventPriority.LOW) + public void onBlockPistonExtend(BlockPistonExtendEvent event) { + Block block = event.getBlock(); + + List blockList = event.getBlocks(); + int count = blockList.size(); + + for (int x = 0; x < count; x++) { + Block checkBlock = (Block) blockList.get(x); + + if (Lockette.isProtected(checkBlock)) { + event.setCancelled(true); + return; + } + + } + + Block checkBlock = block.getRelative(BlockUtil.getPistonFacing(block), event.getLength() + 1); + + if (Lockette.isProtected(checkBlock)) { + event.setCancelled(true); + return; + } + } + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onBlockPistonRetract(BlockPistonRetractEvent event) { + if (!event.isSticky()) { + return; + } + Block block = event.getBlock(); + Block checkBlock = block.getRelative(BlockUtil.getPistonFacing(block), 2); + + int type = checkBlock.getTypeId(); + + if (BlockUtil.isInList(type, BlockUtil.materialListNonDoors)) { + return; + } + if (BlockUtil.isInList(type, BlockUtil.materialListJustDoors)) { + return; + } + + if (Lockette.isProtected(checkBlock)) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onBlockPlace(BlockPlaceEvent event) { + if (event.isCancelled()) { + return; + } + Player player = event.getPlayer(); + Block block = event.getBlockPlaced(); + int type = block.getTypeId(); + Block against = event.getBlockAgainst(); + + if (against.getTypeId() == Material.WALL_SIGN.getId()) { + Sign sign = (Sign) against.getState(); + String text = ChatColor.stripColor(sign.getLine(0)); + + if ((text.equalsIgnoreCase("[Private]")) || (text.equalsIgnoreCase(Lockette.altPrivate)) || (text.equalsIgnoreCase("[More Psers]")) || (text.equalsIgnoreCase(Lockette.altMoreUsers))) { + event.setCancelled(true); + return; + } + + } + + if (BlockUtil.isInList(type, BlockUtil.materialListDoors)) { + if (canBuildDoor(block, against, player)) { + return; + } + event.setCancelled(true); + + plugin.localizedMessage(player, null, "msg-user-conflict-door"); + return; + } + + if ((Lockette.directPlacement) + && (type == Material.WALL_SIGN.getId())) { + Block checkBlock = BlockUtil.getSignAttachedBlock(block); + + if (checkBlock == null) { + return; + } + type = checkBlock.getTypeId(); + + if ((BlockUtil.isInList(type, BlockUtil.materialListNonDoors)) + || (Lockette.isInList(Integer.valueOf(type), + Lockette.customBlockList))) { + Sign sign = (Sign) block.getState(); + + if (Lockette.isProtected(checkBlock)) { + if (Lockette.isOwner(checkBlock, player)) { + sign.setLine(0, Lockette.altMoreUsers); + sign.setLine(1, Lockette.altEveryone); + sign.setLine(2, ""); + sign.setLine(3, ""); + sign.update(true); + + plugin.localizedMessage(player, null, "msg-owner-adduser"); + } else { + event.setCancelled(true); + } + return; + } + + if (!checkPermissions(player, block, checkBlock)) { + event.setCancelled(true); + plugin.localizedMessage(player, null, "msg-error-permission"); + return; + } + + sign.setLine(0, Lockette.altPrivate); + Lockette.setLine(sign, 1, player.getName()); + + sign.setLine(2, ""); + sign.setLine(3, ""); + sign.update(true); + + Lockette.log.info("[" + plugin.getDescription().getName() + "] " + player.getName() + " has protected a block or door."); + + plugin.localizedMessage(player, null, "msg-owner-claim"); + } + + return; + } + + if (BlockUtil.isInList(type, BlockUtil.materialListChests)) { + int chests = Lockette.findChestCountNear(block); + + if (chests > 1) { + event.setCancelled(true); + + plugin.localizedMessage(player, null, "msg-user-illegal"); + return; + } + + Block signBlock = Lockette.findBlockOwner(block); + + if (signBlock != null) { + Sign sign = (Sign) signBlock.getState(); + + if (Lockette.isOwner(sign, player)) { + return; + } + + event.setCancelled(true); + + plugin.localizedMessage(player, null, "msg-user-resize-owned", sign.getLine(1)); + } else if (plugin.playerList.get(player.getName()) == null) { + plugin.playerList.put(player.getName(), block); + plugin.localizedMessage(player, null, "msg-help-chest"); + } + + } + + if (type == Material.HOPPER.getId()) { + Block checkBlock = block.getRelative(BlockFace.UP); + type = checkBlock.getTypeId(); + + if ((BlockUtil.isInList(type, BlockUtil.materialListNonDoors)) + || (Lockette.isInList(Integer.valueOf(type), + Lockette.customBlockList))) { + if (!validateOwner(checkBlock, player)) { + event.setCancelled(true); + + plugin.localizedMessage(player, null, "msg-user-denied"); + return; + } + } + + checkBlock = block.getRelative(BlockFace.DOWN); + type = checkBlock.getTypeId(); + + if ((BlockUtil.isInList(type, BlockUtil.materialListNonDoors)) + || (Lockette.isInList(Integer.valueOf(type), + Lockette.customBlockList))) { + if (!validateOwner(checkBlock, player)) { + event.setCancelled(true); + + plugin.localizedMessage(player, null, "msg-user-denied"); + return; + } + } + } + } + + private boolean checkPermissions(Player player, Block block, Block checkBlock) { + int type = checkBlock.getTypeId(); + + if (plugin.usingExternalZones()) { + if (!plugin.canBuild(player, block)) { + plugin.localizedMessage(player, null, "msg-error-zone", PluginCore.lastZoneDeny()); + return false; + } + + if (!plugin.canBuild(player, checkBlock)) { + plugin.localizedMessage(player, null, "msg-error-zone", PluginCore.lastZoneDeny()); + return false; + } + } + + if (plugin.usingExternalPermissions()) { + boolean create = false; + + if (plugin.hasPermission(block.getWorld(), player, "lockette.create.all")) { + create = true; + } else if (BlockUtil.isInList(type, BlockUtil.materialListChests)) { + if (plugin.hasPermission(block.getWorld(), player, "lockette.user.create.chest")) { + create = true; + } + } else if ((type == Material.FURNACE.getId()) || (type == Material.BURNING_FURNACE.getId())) { + if (plugin.hasPermission(block.getWorld(), player, "lockette.user.create.furnace")) { + create = true; + } + } else if (type == Material.DISPENSER.getId()) { + if (plugin.hasPermission(block.getWorld(), player, "lockette.user.create.dispenser")) { + create = true; + } + } else if (type == Material.DROPPER.getId()) { + if (plugin.hasPermission(block.getWorld(), player, "lockette.user.create.dropper")) { + create = true; + } + } else if (type == Material.BREWING_STAND.getId()) { + if (plugin.hasPermission(block.getWorld(), player, "lockette.user.create.brewingstand")) { + create = true; + } + } else if ((Lockette.isInList(Integer.valueOf(type), Lockette.customBlockList)) + && (plugin.hasPermission(block.getWorld(), player, "lockette.user.create.custom"))) { + create = true; + } + + return create; + } + + return true; + } + + private boolean validateOwner(Block block, Player player) { + Block signBlock = Lockette.findBlockOwner(block); + + if (signBlock == null) { + return true; + } + Sign sign = (Sign) signBlock.getState(); + + return Lockette.isOwner(sign, player); + } + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onBlockRedstoneChange(BlockRedstoneEvent event) { + Block block = event.getBlock(); + int type = block.getTypeId(); + boolean doCheck = false; + + if ((Lockette.protectTrapDoors) + && (BlockUtil.isInList(type, BlockUtil.materialListTrapDoors))) { + doCheck = true; + } + + if ((Lockette.protectDoors) + && (BlockUtil.isInList(type, BlockUtil.materialListDoors))) { + doCheck = true; + } + + if (doCheck) { + Block signBlock = Lockette.findBlockOwner(block); + + if (signBlock == null) { + return; + } + + Sign sign = (Sign) signBlock.getState(); + + for (int y = 1; y <= 3; y++) { + if (!sign.getLine(y).isEmpty()) { + String line = ChatColor.stripColor(sign.getLine(y)); + + if ((line.equalsIgnoreCase("[Everyone]")) || (line.equalsIgnoreCase(Lockette.altEveryone))) { + return; + } + } + } + + List list = Lockette.findBlockUsers(block, signBlock); + for (Block blk : list) { + sign = (Sign) blk.getState(); + + for (int y = 1; y <= 3; y++) { + if (!sign.getLine(y).isEmpty()) { + String line = ChatColor.stripColor(sign.getLine(y)); + + if ((line.equalsIgnoreCase("[Everyone]")) || (line.equalsIgnoreCase(Lockette.altEveryone))) { + return; + } + } + } + } + + event.setNewCurrent(event.getOldCurrent()); + } + } + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = false) + public void onSignChange(SignChangeEvent event) { + Player player = event.getPlayer(); + Block block = event.getBlock(); + int blockType = block.getTypeId(); + boolean typeWallSign = blockType == Material.WALL_SIGN.getId(); + boolean typeSignPost = blockType == Material.SIGN_POST.getId(); + + if (typeWallSign) { + Sign sign = (Sign) block.getState(); + String text = ChatColor.stripColor(sign.getLine(0)); + + if (((text.equalsIgnoreCase("[Private]")) || (text.equalsIgnoreCase(Lockette.altPrivate))) && (isEmptyChange(event))) { + event.setCancelled(true); + return; + } + } else if (!typeSignPost) { + event.setCancelled(true); + return; + } + + String text = ChatColor.stripColor(event.getLine(0)); + + if ((text.equalsIgnoreCase("[Private]")) || (text.equalsIgnoreCase(Lockette.altPrivate))) { + boolean doChests = true; + boolean doFurnaces = true; + boolean doDispensers = true; + boolean doDroppers = true; + boolean doBrewingStands = true; + boolean doCustoms = true; + boolean doTrapDoors = true; + boolean doDoors = true; + + if ((plugin.usingExternalZones()) + && (!plugin.canBuild(player, block))) { + event.setLine(0, "[?]"); + + plugin.localizedMessage(player, null, "msg-error-zone", PluginCore.lastZoneDeny()); + return; + } + + if (plugin.usingExternalPermissions()) { + boolean create = false; + + doChests = false; + doFurnaces = false; + doDispensers = false; + doDroppers = false; + doBrewingStands = false; + doCustoms = false; + doTrapDoors = false; + doDoors = false; + + if (plugin.hasPermission(block.getWorld(), player, "lockette.create.all")) { + create = true; + doChests = true; + doFurnaces = true; + doDispensers = true; + doDroppers = true; + doBrewingStands = true; + doCustoms = true; + doTrapDoors = true; + doDoors = true; + } else { + if (plugin.hasPermission(block.getWorld(), player, "lockette.user.create.chest")) { + create = true; + doChests = true; + } + if (plugin.hasPermission(block.getWorld(), player, "lockette.user.create.furnace")) { + create = true; + doFurnaces = true; + } + if (plugin.hasPermission(block.getWorld(), player, "lockette.user.create.dispenser")) { + create = true; + doDispensers = true; + } + if (plugin.hasPermission(block.getWorld(), player, "lockette.user.create.dropper")) { + create = true; + doDroppers = true; + } + if (plugin.hasPermission(block.getWorld(), player, "lockette.user.create.brewingstand")) { + create = true; + doBrewingStands = true; + } + if (plugin.hasPermission(block.getWorld(), player, "lockette.user.create.custom")) { + create = true; + doCustoms = true; + } + if (plugin.hasPermission(block.getWorld(), player, "lockette.user.create.trapdoor")) { + create = true; + doTrapDoors = true; + } + if (plugin.hasPermission(block.getWorld(), player, "lockette.user.create.door")) { + create = true; + doDoors = true; + } + } + + if (!create) { + event.setLine(0, "[?]"); + + plugin.localizedMessage(player, null, "msg-error-permission"); + return; + } + + } + + Block[] checkBlock = new Block[4]; + byte face = 0; + int type = 0; + boolean conflict = false; + boolean deny = false; + boolean zonedeny = false; + + if ((Lockette.protectTrapDoors) + && (typeWallSign)) { + checkBlock[3] = BlockUtil.getSignAttachedBlock(block); + + if ((checkBlock[3] != null) + && (!BlockUtil.isInList(checkBlock[3].getTypeId(), BlockUtil.materialListBad))) { + checkBlock[0] = checkBlock[3].getRelative(BlockFace.NORTH); + checkBlock[1] = checkBlock[3].getRelative(BlockFace.EAST); + checkBlock[2] = checkBlock[3].getRelative(BlockFace.SOUTH); + checkBlock[3] = checkBlock[3].getRelative(BlockFace.WEST); + + for (int x = 0; x < 4; x++) { + if ((!BlockUtil.isInList(checkBlock[x].getTypeId(), BlockUtil.materialListTrapDoors)) + || (Lockette.findBlockOwner(checkBlock[x], block, true) != null)) { + continue; + } + if (!doTrapDoors) { + deny = true; + } else { + face = block.getData(); + type = 4; + break; + } + + } + + } + + } + + if ((Lockette.protectDoors) + && (typeWallSign)) { + checkBlock[0] = BlockUtil.getSignAttachedBlock(block); + + if ((checkBlock[0] != null) + && (!BlockUtil.isInList(checkBlock[0].getTypeId(), BlockUtil.materialListBad))) { + checkBlock[1] = checkBlock[0].getRelative(BlockFace.UP); + checkBlock[2] = checkBlock[0].getRelative(BlockFace.DOWN); + + if (BlockUtil.isInList(checkBlock[1].getTypeId(), BlockUtil.materialListDoors)) { + if (Lockette.findBlockOwner(checkBlock[1], block, true) == null) { + if (BlockUtil.isInList(checkBlock[2].getTypeId(), BlockUtil.materialListDoors)) { + if (Lockette.findBlockOwner(checkBlock[2], block, true) == null) { + if (!doDoors) { + deny = true; + } else { + face = block.getData(); + type = 5; + } + } else { + conflict = true; + } + } else if (!doDoors) { + deny = true; + } else { + face = block.getData(); + type = 5; + } + + } else { + conflict = true; + } + } else if (BlockUtil.isInList(checkBlock[2].getTypeId(), BlockUtil.materialListDoors)) { + if (Lockette.findBlockOwner(checkBlock[2], block, true) == null) { + if (!doDoors) { + deny = true; + } else { + face = block.getData(); + type = 5; + } + } else { + conflict = true; + } + } + } + + } + + if (conflict == true) { + face = 0; + type = 0; + } + + if (face == 0) { + checkBlock[0] = block.getRelative(BlockFace.NORTH); + checkBlock[1] = block.getRelative(BlockFace.EAST); + checkBlock[2] = block.getRelative(BlockFace.SOUTH); + checkBlock[3] = block.getRelative(BlockFace.WEST); + + for (int x = 0; x < 4; x++) { + if ((plugin.usingExternalZones()) + && (!plugin.canBuild(player, checkBlock[x]))) { + zonedeny = true; + } else { + int lastType; + if (BlockUtil.isInList(checkBlock[x].getTypeId(), BlockUtil.materialListChests)) { + if (!doChests) { + deny = true; + continue; + } + lastType = 1; + } else { + if (BlockUtil.isInList(checkBlock[x].getTypeId(), BlockUtil.materialListFurnaces)) { + if (!doFurnaces) { + deny = true; + continue; + } + lastType = 2; + } else { + if (checkBlock[x].getTypeId() == Material.DISPENSER.getId()) { + if (!doDispensers) { + deny = true; + continue; + } + lastType = 3; + } else { + if (checkBlock[x].getTypeId() == Material.DROPPER.getId()) { + if (!doDroppers) { + deny = true; + continue; + } + lastType = 8; + } else { + if (checkBlock[x].getTypeId() == Material.BREWING_STAND.getId()) { + if (!doBrewingStands) { + deny = true; + continue; + } + lastType = 6; + } else { + if (Lockette.isInList(Integer.valueOf(checkBlock[x].getTypeId()), Lockette.customBlockList)) { + if (!doCustoms) { + deny = true; + continue; + } + lastType = 7; + } else { + if (BlockUtil.isInList(checkBlock[x].getTypeId(), BlockUtil.materialListTrapDoors)) { + if (!Lockette.protectTrapDoors) { + continue; + } + if (!doTrapDoors) { + deny = true; + continue; + } + lastType = 4; + } else { + if ((!BlockUtil.isInList(checkBlock[x].getTypeId(), BlockUtil.materialListDoors)) + || (!Lockette.protectDoors)) { + continue; + } + if (!doDoors) { + deny = true; + continue; + } + lastType = 5; + } + } + } + } + } + } + } + if (Lockette.findBlockOwner(checkBlock[x], block, true) == null) { + face = BlockUtil.faceList[x]; + type = lastType; + break; + } + + if ((Lockette.protectTrapDoors) + && (doTrapDoors) + && (BlockUtil.isInList(checkBlock[x].getTypeId(), BlockUtil.materialListTrapDoors))) { + conflict = true; + } + + if ((!Lockette.protectDoors) + || (!doDoors) + || (!BlockUtil.isInList(checkBlock[x].getTypeId(), BlockUtil.materialListDoors))) { + continue; + } + conflict = true; + } + + } + + } + + if (face == 0) { + event.setLine(0, "[?]"); + + if (conflict) { + plugin.localizedMessage(player, null, "msg-error-claim-conflict"); + } else if (zonedeny) { + plugin.localizedMessage(player, null, "msg-error-zone", PluginCore.lastZoneDeny()); + } else if (deny) { + plugin.localizedMessage(player, null, "msg-error-permission"); + } else { + plugin.localizedMessage(player, null, "msg-error-claim"); + } + return; + } + + boolean anyone = true; + if (Lockette.DEBUG) { + Lockette.log.info("[Lockette] creating new Lockette sign"); + Lockette.log.info("[Lockette] 1st line = " + event.getLine(1)); + } + + if (event.getLine(1).isEmpty()) { + anyone = false; + } + + event.setCancelled(false); + + if (anyone) { + if (type == 1) { + if (!plugin.hasPermission(block.getWorld(), player, "lockette.admin.create.chest")) { + anyone = false; + } + } else if (type == 2) { + if (!plugin.hasPermission(block.getWorld(), player, "lockette.admin.create.furnace")) { + anyone = false; + } + } else if (type == 3) { + if (!plugin.hasPermission(block.getWorld(), player, "lockette.admin.create.dispenser")) { + anyone = false; + } + } else if (type == 8) { + if (!plugin.hasPermission(block.getWorld(), player, "lockette.admin.create.dropper")) { + anyone = false; + } + } else if (type == 6) { + if (!plugin.hasPermission(block.getWorld(), player, "lockette.admin.create.brewingstand")) { + anyone = false; + } + } else if (type == 7) { + if (!plugin.hasPermission(block.getWorld(), player, "lockette.admin.create.custom")) { + anyone = false; + } + } else if (type == 4) { + if (!plugin.hasPermission(block.getWorld(), player, "lockette.admin.create.trapdoor")) { + anyone = false; + } + } else if (type == 5) { + if (!plugin.hasPermission(block.getWorld(), player, "lockette.admin.create.door")) { + anyone = false; + } + } else { + anyone = false; + } + } + + if (!anyone) { + Sign sign = (Sign) block.getState(); + if (Lockette.DEBUG) { + Lockette.log.info("[Lockette] Setting palyer's name : " + player.getName()); + } + Lockette.setLine(sign, 1, player.getName()); + event.setLine(1, player.getName()); + sign.update(true); + } else { + Sign sign = (Sign) block.getState(); + if (Lockette.DEBUG) { + Lockette.log.info("[Lockette] Setting other's name : " + event.getLine(1)); + } + Lockette.setLine(sign, 1, event.getLine(1)); + event.setLine(1, event.getLine(1)); + } + + if (!typeWallSign) { + block.setType(Material.WALL_SIGN); + block.setData(face); + + Sign sign = (Sign) block.getState(); + + sign.setLine(0, event.getLine(0)); + Lockette.setLine(sign, 1, event.getLine(1)); + Lockette.setLine(sign, 2, event.getLine(2)); + Lockette.setLine(sign, 3, event.getLine(3)); + sign.update(true); + } else { + block.setData(face); + } + + if (anyone) { + Lockette.log.info("[" + plugin.getDescription().getName() + "] (Admin) " + player.getName() + " has claimed a container for " + event.getLine(1) + "."); + + if (!plugin.playerOnline(event.getLine(1))) { + plugin.localizedMessage(player, null, "msg-admin-claim-error", event.getLine(1)); + } else { + plugin.localizedMessage(player, null, "msg-admin-claim", event.getLine(1)); + } + } else { + Lockette.log.info("[" + plugin.getDescription().getName() + "] " + player.getName() + " has claimed a container."); + + plugin.localizedMessage(player, null, "msg-owner-claim"); + } + } else if ((text.equalsIgnoreCase("[More Users]")) || (text.equalsIgnoreCase(Lockette.altMoreUsers))) { + Block[] checkBlock = new Block[4]; + Block signBlock = null; + Sign sign = null; + byte face = 0; + + if (((Lockette.protectDoors) || (Lockette.protectTrapDoors)) + && (typeWallSign)) { + checkBlock[0] = BlockUtil.getSignAttachedBlock(block); + + if ((checkBlock[0] != null) + && (!BlockUtil.isInList(checkBlock[0].getTypeId(), BlockUtil.materialListBad))) { + signBlock = Lockette.findBlockOwner(checkBlock[0]); + + if (signBlock != null) { + sign = (Sign) signBlock.getState(); + + if (Lockette.isOwner(sign, player)) { + face = block.getData(); + } + } + + } + + } + + if (face == 0) { + checkBlock[0] = block.getRelative(BlockFace.NORTH); + checkBlock[1] = block.getRelative(BlockFace.EAST); + checkBlock[2] = block.getRelative(BlockFace.SOUTH); + checkBlock[3] = block.getRelative(BlockFace.WEST); + + for (int x = 0; x < 4; x++) { + if (!BlockUtil.isInList(checkBlock[x].getTypeId(), BlockUtil.materialList)) { + continue; + } + if ((!Lockette.protectTrapDoors) + && (BlockUtil.isInList(checkBlock[x].getTypeId(), BlockUtil.materialListTrapDoors))) { + continue; + } + if ((!Lockette.protectDoors) + && (BlockUtil.isInList(checkBlock[x].getTypeId(), BlockUtil.materialListDoors))) { + continue; + } + signBlock = Lockette.findBlockOwner(checkBlock[x]); + + if (signBlock != null) { + sign = (Sign) signBlock.getState(); + + if (Lockette.isOwner(sign, player)) { + face = BlockUtil.faceList[x]; + + break; + } + } + + } + + } + + if (face == 0) { + event.setLine(0, "[?]"); + if (sign != null) { + plugin.localizedMessage(player, null, "msg-error-adduser-owned", sign.getLine(1)); + } else { + plugin.localizedMessage(player, null, "msg-error-adduser"); + } + return; + } + + event.setCancelled(false); + if (!typeWallSign) { + block.setType(Material.WALL_SIGN); + block.setData(face); + + sign = (Sign) block.getState(); + + sign.setLine(0, event.getLine(0)); + Lockette.setLine(sign, 1, event.getLine(1)); + Lockette.setLine(sign, 2, event.getLine(2)); + Lockette.setLine(sign, 3, event.getLine(2)); + + sign.update(true); + } else { + block.setData(face); + } + + plugin.localizedMessage(player, null, "msg-owner-adduser"); + } + } + + private static boolean canBuildDoor(Block block, Block against, Player player) { + if (!Lockette.isOwner(against, player)) { + return false; + } + if ((Lockette.protectTrapDoors) + && (BlockUtil.isInList(block.getTypeId(), BlockUtil.materialListTrapDoors))) { + return true; + } + + if (!Lockette.isOwner(against.getRelative(BlockFace.UP, 3), player)) { + return false; + } + + Block checkBlock = block.getRelative(BlockFace.NORTH); + if ((checkBlock.getTypeId() == block.getTypeId()) + && (!Lockette.isOwner(checkBlock, player))) { + return false; + } + + checkBlock = block.getRelative(BlockFace.EAST); + if ((checkBlock.getTypeId() == block.getTypeId()) + && (!Lockette.isOwner(checkBlock, player))) { + return false; + } + + checkBlock = block.getRelative(BlockFace.SOUTH); + if ((checkBlock.getTypeId() == block.getTypeId()) + && (!Lockette.isOwner(checkBlock, player))) { + return false; + } + + checkBlock = block.getRelative(BlockFace.WEST); + + return (checkBlock.getTypeId() != block.getTypeId()) + || (Lockette.isOwner(checkBlock, player)); + } + + static boolean isEmptyChange(SignChangeEvent signe) { + for (int i = 0; i < 4; i++) { + String str = ChatColor.stripColor(signe.getLine(i)); + if (!str.isEmpty()) { + return false; + } + } + return true; + } +} diff --git a/src/main/java/org/yi/acru/bukkit/Lockette/LocketteDoorCloser.java b/src/main/java/org/yi/acru/bukkit/Lockette/LocketteDoorCloser.java new file mode 100644 index 0000000..740f81e --- /dev/null +++ b/src/main/java/org/yi/acru/bukkit/Lockette/LocketteDoorCloser.java @@ -0,0 +1,158 @@ +package org.yi.acru.bukkit.Lockette; + +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.PriorityQueue; +import org.bukkit.Server; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.scheduler.BukkitScheduler; + +public class LocketteDoorCloser implements Runnable { + + private static Lockette plugin; + private static int doorTask = -1; + private final PriorityQueue closeTaskList = new PriorityQueue(); + + public LocketteDoorCloser(Lockette instance) { + plugin = instance; + } + + protected boolean start() { + if (doorTask != -1) { + return false; + } + + doorTask = plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, this, 100L, 10L); + return doorTask == -1; + } + + protected boolean stop() { + if (doorTask == -1) { + return false; + } + + plugin.getServer().getScheduler().cancelTask(doorTask); + doorTask = -1; + cleanup(); + + return false; + } + + protected void cleanup() { + while (!this.closeTaskList.isEmpty()) { + closeTask door = (closeTask) this.closeTaskList.poll(); + if (door == null) { + break; + } + close(door); + } + } + + public void run() { + if (this.closeTaskList.isEmpty()) { + return; + } + + Date time = new Date(); + + while (time.after(((closeTask) this.closeTaskList.peek()).time)) { + closeTask door = (closeTask) this.closeTaskList.poll(); + if (door == null) { + break; + } + close(door); + if (!this.closeTaskList.isEmpty()) { + continue; + } + } + } + + private void close(closeTask door) { + Lockette.toggleHalfDoor(door.world.getBlockAt(door.x, door.y, door.z), door.effect); + } + + // Assumes all blocks in the list are for the same world. + public void add(final List list, final boolean auto, final int delta) { + if (list == null) { + return; + } + if (list.isEmpty()) { + return; + } + Iterator it; + Iterator itb; + closeTask task; + Block block; + final World world = list.get(0).getWorld(); + + // Check each item in the task list for duplicates. + it = closeTaskList.iterator(); + while (it.hasNext()) { + task = it.next(); + + // Ignore block lists for another world. + if (!task.world.equals(world)) { + continue; + } + + // Compare to each of the blocks in the new list. + itb = list.iterator(); + while (itb.hasNext()) { + block = itb.next(); + + // Ignore block lists for another world. + // if(!block.getWorld().equals(task.world)) break; + if ((block.getX() == task.x) && (block.getY() == task.y) && (block.getZ() == task.z)) { + // Duplicate found, remove it from both lists. A door to be closed was closed manually. + // Lockette.log.info("Duplicate"); + it.remove(); + itb.remove(); + break; + } + } + } + + // If the list is empty or the new door blocks aren't automatic, we are done. + if (!auto) { + return; + } + if (list.isEmpty()) { + return; + } + + // Add the new blocks to the task list. + // (((block.getX()&0x7)*4)+2) + // Lockette.log.info("Adding " + list.size()); + final Date time = new Date(); + time.setTime(time.getTime() + (delta * 1000L)); + + for (int x = 0; x < list.size(); ++x) { + closeTaskList.add(new closeTask(time, list.get(x), x == 0)); + } + } + + protected class closeTask implements Comparable { + + Date time; + World world; + int x; + int y; + int z; + boolean effect; + + public closeTask(Date taskTime, Block block, boolean taskEffect) { + this.time = taskTime; + this.world = block.getWorld(); + this.x = block.getX(); + this.y = block.getY(); + this.z = block.getZ(); + this.effect = taskEffect; + } + + public int compareTo(closeTask arg) { + return this.time.compareTo(arg.time); + } + } +} diff --git a/src/main/java/org/yi/acru/bukkit/Lockette/LocketteEntityListener.java b/src/main/java/org/yi/acru/bukkit/Lockette/LocketteEntityListener.java new file mode 100644 index 0000000..62f35cc --- /dev/null +++ b/src/main/java/org/yi/acru/bukkit/Lockette/LocketteEntityListener.java @@ -0,0 +1,51 @@ +package org.yi.acru.bukkit.Lockette; + +import java.util.Iterator; +import java.util.List; +import org.bukkit.Server; +import org.bukkit.block.Block; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.plugin.PluginManager; + +public class LocketteEntityListener + implements Listener +{ + private static Lockette plugin; + + public LocketteEntityListener(Lockette instance) + { + plugin = instance; + } + + protected void registerEvents() + { + PluginManager pm = plugin.getServer().getPluginManager(); + + pm.registerEvents(this, plugin); + } + + @EventHandler(priority=EventPriority.LOW, ignoreCancelled=true) + public void onEntityExplode(EntityExplodeEvent event) + { + if (event.isCancelled()) return; + + if (Lockette.explosionProtectionAll) { + Iterator it = event.blockList().iterator(); + while (it.hasNext()) { + Block block = (Block)it.next(); + if (Lockette.isProtected(block)) { + it.remove(); + continue; + } + + if (BlockUtil.isInList(block.getTypeId(), BlockUtil.materialListNonDoors)) { + it.remove(); + continue; + } + } + } + } +} \ No newline at end of file diff --git a/src/main/java/org/yi/acru/bukkit/Lockette/LocketteInventoryListener.java b/src/main/java/org/yi/acru/bukkit/Lockette/LocketteInventoryListener.java new file mode 100644 index 0000000..f6cd61e --- /dev/null +++ b/src/main/java/org/yi/acru/bukkit/Lockette/LocketteInventoryListener.java @@ -0,0 +1,124 @@ +package org.yi.acru.bukkit.Lockette; + +import java.util.UUID; +import org.bukkit.Server; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.block.DoubleChest; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryMoveItemEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.plugin.PluginManager; + +public class LocketteInventoryListener + implements Listener +{ + private static Lockette plugin; + + public LocketteInventoryListener(Lockette instance) + { + plugin = instance; + } + + protected void registerEvents() { + PluginManager pm = plugin.getServer().getPluginManager(); + + pm.registerEvents(this, plugin); + } + + private boolean isProtected(Inventory inv, boolean allowEveryone) + { + if (!Lockette.blockHopper) { + return false; + } + InventoryHolder holder = inv.getHolder(); + + if ((holder instanceof DoubleChest)) { + holder = ((DoubleChest)holder).getLeftSide(); + } + + if ((holder instanceof BlockState)) { + Block block = ((BlockState)holder).getBlock(); + int type = block.getTypeId(); + if ((BlockUtil.isInList(type, BlockUtil.materialListNonDoors)) || + (Lockette.isInList(Integer.valueOf(type), + Lockette.customBlockList))) { + return (allowEveryone) && (Lockette.isEveryone(block)) ? false : Lockette.isProtected(block); + } + } + + return false; + } + + private boolean passThrough(Inventory src, Inventory dest, Inventory me) { + if (!Lockette.blockHopper) + return true; + UUID srcOwner = null; + UUID destOwner = null; + UUID meOwner = null; + + if (src != null) { + InventoryHolder holder = src.getHolder(); + if ((holder instanceof DoubleChest)) { + holder = ((DoubleChest)holder).getLeftSide(); + } + + if ((holder instanceof BlockState)) { + Block block = ((BlockState)holder).getBlock(); + srcOwner = Lockette.getProtectedOwnerUUID(block); + if (Lockette.isEveryone(block)) + srcOwner = null; + } + } + if (dest != null) { + InventoryHolder holder = dest.getHolder(); + if ((holder instanceof DoubleChest)) { + holder = ((DoubleChest)holder).getLeftSide(); + } + + if ((holder instanceof BlockState)) { + Block block = ((BlockState)holder).getBlock(); + destOwner = Lockette.getProtectedOwnerUUID(block); + if (Lockette.isEveryone(block)) { + destOwner = null; + } + } + } + if (me != null) { + InventoryHolder holder = me.getHolder(); + if ((holder instanceof DoubleChest)) { + holder = ((DoubleChest)holder).getLeftSide(); + } + + if ((holder instanceof BlockState)) { + Block block = ((BlockState)holder).getBlock(); + meOwner = Lockette.getProtectedOwnerUUID(block); + if (Lockette.isEveryone(block)) { + meOwner = null; + } + + } + + } + + return ((srcOwner == meOwner) && (meOwner == destOwner)) || ((srcOwner == meOwner) && (destOwner == null)) || ((srcOwner == null) && (meOwner == destOwner)) || ((srcOwner == null) && (destOwner == null)); + } + + @EventHandler + public void onInventoryItemMove(InventoryMoveItemEvent event) + { + Inventory src = event.getSource(); + Inventory dest = event.getDestination(); + Inventory me = event.getInitiator(); + + if (passThrough(src, dest, me)) { + return; + } + if ((isProtected(event.getSource(), false)) || + (isProtected(event + .getDestination(), true))) + event.setCancelled(true); + } +} \ No newline at end of file diff --git a/src/main/java/org/yi/acru/bukkit/Lockette/LockettePlayerListener.java b/src/main/java/org/yi/acru/bukkit/Lockette/LockettePlayerListener.java new file mode 100644 index 0000000..471723d --- /dev/null +++ b/src/main/java/org/yi/acru/bukkit/Lockette/LockettePlayerListener.java @@ -0,0 +1,510 @@ +package org.yi.acru.bukkit.Lockette; + +import java.util.HashMap; +import java.util.List; +import java.util.Set; +import java.util.logging.Logger; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.Server; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.Event.Result; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.PluginManager; + +public class LockettePlayerListener + implements Listener { + + private static Lockette plugin; + + public LockettePlayerListener(Lockette instance) { + plugin = instance; + } + + protected void registerEvents() { + PluginManager pm = plugin.getServer().getPluginManager(); + + pm.registerEvents(this, plugin); + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) { + String[] command = event.getMessage().split(" ", 3); + + if (command.length < 1) { + return; + } + if ((!command[0].equalsIgnoreCase("/lockette")) && (!command[0].equalsIgnoreCase("/lock"))) { + return; + } + event.setCancelled(true); + + Player player = event.getPlayer(); + + if (command.length == 2) { + if (command[1].equalsIgnoreCase("reload")) { + if (!plugin.hasPermission(player.getWorld(), player, "lockette.admin.reload")) { + return; + } + + plugin.loadProperties(true); + + plugin.localizedMessage(player, Lockette.broadcastReloadTarget, "msg-admin-reload"); + return; + } + + if (command[1].equalsIgnoreCase("version")) { + player.sendMessage(ChatColor.RED + "Lockette version " + plugin.getDescription().getVersion() + " loaded."); + return; + } + + if (command[1].equalsIgnoreCase("fix")) { + if (fixDoor(player)) { + plugin.localizedMessage(player, null, "msg-error-fix"); + } + return; + } + } else if ((command.length == 3) + && (command[1].equalsIgnoreCase("debug"))) { + Lockette.DEBUG = Boolean.parseBoolean(command[2]); + player.sendMessage(ChatColor.RED + "[Lockette] DEBUG mode is set to " + Lockette.DEBUG); + return; + } + + if (((command.length == 2) || (command.length == 3)) && ((command[1].equals("1")) || (command[1].equals("2")) || (command[1].equals("3")) || (command[1].equals("4")))) { + Block block = (Block) plugin.playerList.get(player.getName()); + + if (block == null) { + plugin.localizedMessage(player, null, "msg-error-edit"); + return; + } + if (block.getTypeId() != Material.WALL_SIGN.getId()) { + plugin.localizedMessage(player, null, "msg-error-edit"); + return; + } + + Sign sign = (Sign) block.getState(); + Sign owner = sign; + String text = sign.getLine(0).replaceAll("(?i)§[0-F]", "").toLowerCase(); + boolean privateSign; + if ((text.equals("[private]")) || (text.equalsIgnoreCase(Lockette.altPrivate))) { + privateSign = true; + } else if ((text.equals("[more users]")) || (text.equalsIgnoreCase(Lockette.altMoreUsers))) { + privateSign = false; + + Block checkBlock = BlockUtil.getSignAttachedBlock(block); + if (checkBlock == null) { + plugin.localizedMessage(player, null, "msg-error-edit"); + return; + } + Block signBlock = Lockette.findBlockOwner(checkBlock); + if (signBlock == null) { + plugin.localizedMessage(player, null, "msg-error-edit"); + return; + } + owner = (Sign) signBlock.getState(); + } else { + plugin.localizedMessage(player, null, "msg-error-edit"); + return; + } + if ((Lockette.isOwner(owner, player)) || (Lockette.debugMode)) { + int line = Integer.parseInt(command[1]) - 1; + + if (!Lockette.debugMode) { + if (line <= 0) { + return; + } + if (line <= 1) { + if ((privateSign) && ((command.length < 3) + || (command[2].isEmpty()) || (!command[2].replaceAll("&([0-9A-Fa-f])", "").equalsIgnoreCase(player.getName())))) { + return; + } + + } + + } + + if (command.length == 3) { + String id = !Lockette.colorTags ? command[2].replaceAll("&([0-9A-Fa-f])", "") : command[2]; + + if (Lockette.DEBUG) { + Lockette.log.info("[Lockette] striped name = " + command[2].replaceAll("&([0-9A-Fa-f])", "")); + Lockette.log.info("[Lockette] player name = " + player.getName()); + } + + Lockette.setLine(sign, line, id); + } else { + Lockette.setLine(sign, line, ""); + } + sign.update(); + + plugin.localizedMessage(player, null, "msg-owner-edit"); + return; + } + plugin.localizedMessage(player, null, "msg-error-edit"); + return; + } + + plugin.localizedMessage(player, null, "msg-help-command1"); + plugin.localizedMessage(player, null, "msg-help-command2"); + plugin.localizedMessage(player, null, "msg-help-command3"); + plugin.localizedMessage(player, null, "msg-help-command4"); + plugin.localizedMessage(player, null, "msg-help-command5"); + plugin.localizedMessage(player, null, "msg-help-command6"); + plugin.localizedMessage(player, null, "msg-help-command7"); + plugin.localizedMessage(player, null, "msg-help-command8"); + plugin.localizedMessage(player, null, "msg-help-command9"); + } + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onPlayerInteract(PlayerInteractEvent event) { + if (!event.hasBlock()) { + return; + } + + Action action = event.getAction(); + Player player = event.getPlayer(); + Block block = event.getClickedBlock(); + int type = block.getTypeId(); + BlockFace face = event.getBlockFace(); + + if (action == Action.RIGHT_CLICK_BLOCK) { + if ((Lockette.protectTrapDoors) && (BlockUtil.isInList(type, BlockUtil.materialListTrapDoors))) { + if (interactDoor(block, player)) { + return; + } + + event.setUseInteractedBlock(Event.Result.DENY); + event.setUseItemInHand(Event.Result.DENY); + return; + } + + if ((Lockette.protectDoors) && (BlockUtil.isInList(type, BlockUtil.materialListDoors))) { + if (interactDoor(block, player)) { + return; + } + + event.setUseInteractedBlock(Event.Result.DENY); + event.setUseItemInHand(Event.Result.DENY); + return; + } + + if (type == Material.WALL_SIGN.getId()) { + interactSign(block, player); + return; + } + + if (BlockUtil.isInList(type, BlockUtil.materialListChests)) { + Lockette.rotateChestOrientation(block, face); + } + + if ((BlockUtil.isInList(type, BlockUtil.materialListNonDoors)) + || (Lockette.isInList(Integer.valueOf(type), + Lockette.customBlockList))) { + if ((Lockette.directPlacement) && (event.hasItem()) && (face != BlockFace.UP) && (face != BlockFace.DOWN)) { + ItemStack item = event.getItem(); + + if (item.getTypeId() == Material.SIGN.getId()) { + Block checkBlock = block.getRelative(face); + + type = checkBlock.getTypeId(); + + if (type == Material.AIR.getId()) { + boolean place = false; + + if (Lockette.isProtected(block)) { + if (Lockette.isOwner(block, player)) { + place = true; + } + } else { + place = true; + } + if (place) { + event.setUseItemInHand(Event.Result.ALLOW); + event.setUseInteractedBlock(Event.Result.DENY); + return; + } + } + } + + } + + if (interactContainer(block, player)) { + return; + } + + event.setUseInteractedBlock(Event.Result.DENY); + event.setUseItemInHand(Event.Result.DENY); + return; + } + + if ((type == Material.DIRT.getId()) && (event.hasItem())) { + ItemStack item = event.getItem(); + + type = item.getTypeId(); + + if ((type == Material.DIAMOND_HOE.getId()) || (type == Material.GOLD_HOE.getId()) || (type == Material.IRON_HOE.getId()) + || (type == Material.STONE_HOE + .getId()) || (type == Material.WOOD_HOE.getId())) { + Block checkBlock = block.getRelative(BlockFace.UP); + + type = checkBlock.getTypeId(); + + if (BlockUtil.isInList(type, BlockUtil.materialListDoors)) { + event.setUseInteractedBlock(Event.Result.DENY); + return; + } + + if (hasAttachedTrapDoor(block)) { + event.setUseInteractedBlock(Event.Result.DENY); + return; + } + } + } + + } else if (action == Action.LEFT_CLICK_BLOCK) { + if ((Lockette.protectTrapDoors) && (BlockUtil.isInList(type, BlockUtil.materialListTrapDoors))) { + if (interactDoor(block, player)) { + return; + } + + event.setUseInteractedBlock(Event.Result.DENY); + event.setUseItemInHand(Event.Result.DENY); + return; + } + + if ((Lockette.protectDoors) && (BlockUtil.isInList(type, BlockUtil.materialListDoors))) { + if (interactDoor(block, player)) { + return; + } + + event.setUseInteractedBlock(Event.Result.DENY); + event.setUseItemInHand(Event.Result.DENY); + return; + } + } + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onPlayerQuit(PlayerQuitEvent event) { + Player player = event.getPlayer(); + + plugin.playerList.remove(player.getName()); + } + + private static boolean interactDoor(Block block, Player player) { + Block signBlock = Lockette.findBlockOwner(block); + + if (signBlock == null) { + return true; + } + + boolean wooden = BlockUtil.isInList(block.getTypeId(), BlockUtil.materialListWoodenDoors); + boolean trap = false; + + if ((Lockette.protectTrapDoors) && (BlockUtil.isInList(block.getTypeId(), BlockUtil.materialListTrapDoors))) { + trap = true; + } + + boolean allow = false; + + if (canInteract(block, signBlock, player, true)) { + allow = true; + } + + if (allow) { + List list = Lockette.toggleDoors(block, BlockUtil.getSignAttachedBlock(signBlock), wooden, trap); + + int delta = Lockette.getSignOption(signBlock, "timer", Lockette.altTimer, Lockette.defaultDoorTimer); + + plugin.doorCloser.add(list, delta != 0, delta); + return true; + } + + if (block.equals(plugin.playerList.get(player.getName()))) { + return false; + } + plugin.playerList.put(player.getName(), block); + plugin.localizedMessage(player, null, "msg-user-denied-door"); + return false; + } + + private static void interactSign(Block block, Player player) { + Sign sign = (Sign) block.getState(); + String text = sign.getLine(0).replaceAll("(?i)§[0-F]", "").toLowerCase(); + + if ((!text.equals("[private]")) && (!text.equalsIgnoreCase(Lockette.altPrivate))) { + if ((text.equals("[more users]")) || (text.equalsIgnoreCase(Lockette.altMoreUsers))) { + Block checkBlock = BlockUtil.getSignAttachedBlock(block); + if (checkBlock == null) { + return; + } + + Block signBlock = Lockette.findBlockOwner(checkBlock); + if (signBlock == null) { + return; + } + + sign = (Sign) signBlock.getState(); + } else { + return; + } + } + + if ((Lockette.isOwner(sign, player)) || (Lockette.debugMode)) { + if (!block.equals(plugin.playerList.get(player.getName()))) { + plugin.playerList.put(player.getName(), block); + plugin.localizedMessage(player, null, "msg-help-select"); + } + + } else if (!block.equals(plugin.playerList.get(player.getName()))) { + plugin.playerList.put(player.getName(), block); + plugin.localizedMessage(player, null, "msg-user-touch-owned", sign.getLine(1)); + } + } + + private static boolean interactContainer(Block block, Player player) { + Block signBlock = Lockette.findBlockOwner(block); + + if (signBlock == null) { + return true; + } + + if (canInteract(block, signBlock, player, false)) { + return true; + } + + if (block.equals(plugin.playerList.get(player.getName()))) { + return false; + } + plugin.playerList.put(player.getName(), block); + plugin.localizedMessage(player, null, "msg-user-denied"); + return false; + } + + private static boolean canInteract(Block block, Block signBlock, Player player, boolean isDoor) { + Sign sign = (Sign) signBlock.getState(); + + if (Lockette.isUser(block, player, true)) { + return true; + } + + boolean snoop = false; + + if (isDoor) { + if (Lockette.adminBypass) { + if (plugin.hasPermission(block.getWorld(), player, "lockette.admin.bypass")) { + snoop = true; + } + + if (snoop) { + Lockette.log.info("[" + plugin.getDescription().getName() + "] (Admin) " + player.getName() + " has bypassed a door owned by " + sign.getLine(1)); + + plugin.localizedMessage(player, null, "msg-admin-bypass", sign.getLine(1)); + return true; + } + } + } else if (Lockette.adminSnoop) { + if (plugin.hasPermission(block.getWorld(), player, "lockette.admin.snoop")) { + snoop = true; + } + + if (snoop) { + Lockette.log.info("[" + plugin.getDescription().getName() + "] (Admin) " + player.getName() + " has snooped around in a container owned by " + sign.getLine(1) + "!"); + + plugin.localizedMessage(player, Lockette.broadcastSnoopTarget, "msg-admin-snoop", sign.getLine(1)); + return true; + } + + } + + return false; + } + + private static boolean fixDoor(Player player) { + Block block = player.getTargetBlock((Set) null, 10); + int type = block.getTypeId(); + boolean doCheck = false; + + if ((Lockette.protectTrapDoors) + && (BlockUtil.isInList(type, BlockUtil.materialListTrapDoors))) { + doCheck = true; + } + + if ((Lockette.protectDoors) + && (BlockUtil.isInList(type, BlockUtil.materialListDoors))) { + doCheck = true; + } + + if (!doCheck) { + return true; + } + + Block signBlock = Lockette.findBlockOwner(block); + + if (signBlock == null) { + return true; + } + + Sign sign = (Sign) signBlock.getState(); + + if (Lockette.isOwner(block, player)) { + Lockette.toggleSingleDoor(block); + return false; + } + + return true; + } + + public static boolean hasAttachedTrapDoor(Block block) { + Block checkBlock = block.getRelative(BlockFace.NORTH); + int type = checkBlock.getTypeId(); + if (BlockUtil.isInList(type, BlockUtil.materialListTrapDoors)) { + int face = checkBlock.getData() & 0x3; + if (face == 2) { + return true; + } + } + + checkBlock = block.getRelative(BlockFace.EAST); + type = checkBlock.getTypeId(); + if (BlockUtil.isInList(type, BlockUtil.materialListTrapDoors)) { + int face = checkBlock.getData() & 0x3; + if (face == 0) { + return true; + } + } + + checkBlock = block.getRelative(BlockFace.SOUTH); + type = checkBlock.getTypeId(); + if (BlockUtil.isInList(type, BlockUtil.materialListTrapDoors)) { + int face = checkBlock.getData() & 0x3; + if (face == 3) { + return true; + } + } + + checkBlock = block.getRelative(BlockFace.WEST); + type = checkBlock.getTypeId(); + if (BlockUtil.isInList(type, BlockUtil.materialListTrapDoors)) { + int face = checkBlock.getData() & 0x3; + if (face == 1) { + return true; + } + } + + return false; + } +} diff --git a/src/main/java/org/yi/acru/bukkit/Lockette/LockettePrefixListener.java b/src/main/java/org/yi/acru/bukkit/Lockette/LockettePrefixListener.java new file mode 100644 index 0000000..7b37a3e --- /dev/null +++ b/src/main/java/org/yi/acru/bukkit/Lockette/LockettePrefixListener.java @@ -0,0 +1,76 @@ +package org.yi.acru.bukkit.Lockette; + +import java.util.logging.Logger; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.Server; +import org.bukkit.block.Block; +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.SignChangeEvent; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.PluginManager; + +public class LockettePrefixListener + implements Listener +{ + private static Lockette plugin; + + public LockettePrefixListener(Lockette instance) + { + plugin = instance; + } + + protected void registerEvents() + { + PluginManager pm = plugin.getServer().getPluginManager(); + + pm.registerEvents(this, plugin); + } + + @EventHandler(priority=EventPriority.LOW, ignoreCancelled=true) + public void onSignChange(SignChangeEvent event) + { + Block block = event.getBlock(); + Player player = event.getPlayer(); + int blockType = block.getTypeId(); + boolean typeWallSign = blockType == Material.WALL_SIGN.getId(); + boolean typeSignPost = blockType == Material.SIGN_POST.getId(); + + if (typeWallSign) { + Sign sign = (Sign)block.getState(); + String text = ChatColor.stripColor(sign.getLine(0)); + + if (((text.equalsIgnoreCase("[Private]")) || (text.equalsIgnoreCase(Lockette.altPrivate)) || (text.equalsIgnoreCase("[More Users]")) || (text.equalsIgnoreCase(Lockette.altMoreUsers))) && (LocketteBlockListener.isEmptyChange(event))) + { + if (Lockette.DEBUG) { + Lockette.log.info("[Lockette] Sign already exists, resetting"); + } + + event.setCancelled(true); + event.setLine(0, sign.getLine(0)); + event.setLine(1, sign.getLine(1)); + event.setLine(2, sign.getLine(2)); + event.setLine(3, sign.getLine(3)); + Lockette.log.info("[" + plugin.getDescription().getName() + "] " + player.getName() + " just tried to change a non-editable sign. (Bukkit bug, or plugin conflict?)"); + return; + } + } + else if (!typeSignPost) + { + event.setCancelled(true); + Lockette.log.info("[" + plugin.getDescription().getName() + "] " + player.getName() + " just tried to set text for a non-sign. (Bukkit bug, or hacked client?)"); + return; + } + + if (Lockette.colorTags) { + event.setLine(0, event.getLine(0).replaceAll("&([0-9A-Fa-f])", "§$1")); + event.setLine(1, event.getLine(1).replaceAll("&([0-9A-Fa-f])", "§$1")); + event.setLine(2, event.getLine(2).replaceAll("&([0-9A-Fa-f])", "§$1")); + event.setLine(3, event.getLine(3).replaceAll("&([0-9A-Fa-f])", "§$1")); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/yi/acru/bukkit/Lockette/LocketteWorldListener.java b/src/main/java/org/yi/acru/bukkit/Lockette/LocketteWorldListener.java new file mode 100644 index 0000000..958173b --- /dev/null +++ b/src/main/java/org/yi/acru/bukkit/Lockette/LocketteWorldListener.java @@ -0,0 +1,52 @@ +package org.yi.acru.bukkit.Lockette; + +import java.util.List; +import org.bukkit.Server; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.world.StructureGrowEvent; +import org.bukkit.plugin.PluginManager; + +public class LocketteWorldListener + implements Listener +{ + private static Lockette plugin; + + public LocketteWorldListener(Lockette instance) + { + plugin = instance; + } + + protected void registerEvents() + { + PluginManager pm = plugin.getServer().getPluginManager(); + + pm.registerEvents(this, plugin); + } + + @EventHandler(priority=EventPriority.LOW, ignoreCancelled=true) + public void onStructureGrow(StructureGrowEvent event) + { + if (event.isCancelled()) return; + + List blockList = event.getBlocks(); + int count = blockList.size(); + + for (int x = 0; x < count; x++) { + Block block = ((BlockState)blockList.get(x)).getBlock(); + + if (Lockette.isProtected(block)) { + event.setCancelled(true); + return; + } + + if ((!Lockette.explosionProtectionAll) || + (!BlockUtil.isInList(block.getTypeId(), BlockUtil.materialListNonDoors))) continue; + event.setCancelled(true); + return; + } + } +} \ No newline at end of file diff --git a/src/main/java/org/yi/acru/bukkit/Lockette/Utils.java b/src/main/java/org/yi/acru/bukkit/Lockette/Utils.java new file mode 100644 index 0000000..78cb450 --- /dev/null +++ b/src/main/java/org/yi/acru/bukkit/Lockette/Utils.java @@ -0,0 +1,24 @@ +package org.yi.acru.bukkit.Lockette; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.Collection; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +public class Utils { + + public static Collection getOnlinePlayers() { + try (java.io.Closeable asdhqjefhusfer = null) { + } catch (Exception cvmoiej_djiqwg) { + } + try { + Method method = Bukkit.class.getDeclaredMethod("getOnlinePlayers"); + Player[] players = (Player[]) method.invoke(null); + return Arrays.asList(players); + } catch (Exception e) { + return Bukkit.getOnlinePlayers(); + } + } + +} \ No newline at end of file diff --git a/src/main/resources/LanguageInfo.txt b/src/main/resources/LanguageInfo.txt new file mode 100644 index 0000000..3cf172a --- /dev/null +++ b/src/main/resources/LanguageInfo.txt @@ -0,0 +1,16 @@ +String translations should be in ANSI format. (UTF-8 doesn't seem to work anymore.) +Care should be taken with the special characters in yml, such as quotes and colons. + + +Translation credit where credit is due! + +French by Misa +German by Efstajas +Polish by Kamild1996 +Dutch by Tofun +Danish by Dumle29 +Slovenian by LiqouRiiCe +Spanish by Agubelu +Norwegian by Tio1999 +Swedish by TheMineKraftor +Italian by Nikkolo_DTU \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..971caf9 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,102 @@ +name: Lockette +main: org.yi.acru.bukkit.Lockette.Lockette +version: 1.8.20 +authors: [Acru, ElgarL, vk2gpz] +description: A simple plugin for locking containers and doors without passwords or database files. Inspired by the old hmod plugins Lock by Roman "kingseta" Pramberger and ChestCapsule by Fernando "Fergo". +commands: + lockette: + aliases: [lock] + description: Access to the Lockette plugin via commands. + usage: | + / - Edits signs on locked containers. Right click on the sign to edit. + / fix - Fixes an automatic door that is in the wrong position. Look at the door to edit. + / reload - Reloads the configuration files. Operators only. + / version - Reports Lockette version string. +permissions: + lockette.*: + description: Permission for a super admin who can do anything. + children: + lockette.user.create.*: true + lockette.admin.create.*: true + lockette.admin.break: true + lockette.admin.bypass: true + lockette.admin.snoop: true + lockette.admin.reload: true + lockette.towny.wilds: true + lockette.user.*: + description: All the permissions a normal user normally needs. + children: + lockette.user.create.*: true + lockette.towny.wilds: true + lockette.user.create.*: + description: Allows the normal method of locking containers. + children: + lockette.user.create.chest: true + lockette.user.create.furnace: true + lockette.user.create.dispenser: true + lockette.user.create.dropper: true + lockette.user.create.brewingstand: true + lockette.user.create.custom: true + lockette.user.create.trapdoor: true + lockette.user.create.door: true + lockette.admin.*: + description: All the permissions a normal admin normally needs. + children: + lockette.user.create.*: true + lockette.admin.create.*: true + lockette.admin.break: true + lockette.admin.bypass: true + lockette.towny.wilds: true + lockette.admin.create.*: + description: Allows the admin method of locking containers. + children: + lockette.admin.create.chest: true + lockette.admin.create.furnace: true + lockette.admin.create.dispenser: true + lockette.admin.create.dropper: true + lockette.admin.create.brewingstand: true + lockette.admin.create.custom: true + lockette.admin.create.trapdoor: true + lockette.admin.create.door: true + lockette.user.create.chest: + default: op + lockette.user.create.furnace: + default: op + lockette.user.create.dispenser: + default: op + lockette.user.create.dropper: + default: op + lockette.user.create.brewingstand: + default: op + lockette.user.create.custom: + default: op + lockette.user.create.trapdoor: + default: op + lockette.user.create.door: + default: op + lockette.admin.create.chest: + default: op + lockette.admin.create.furnace: + default: op + lockette.admin.create.dispenser: + default: op + lockette.admin.create.dropper: + default: op + lockette.admin.create.brewingstand: + default: op + lockette.admin.create.custom: + default: op + lockette.admin.create.trapdoor: + default: op + lockette.admin.create.door: + default: op + lockette.admin.break: + default: op + lockette.admin.bypass: + default: op + lockette.admin.snoop: + default: false + lockette.admin.reload: + default: false + lockette.towny.wilds: + default: op diff --git a/src/main/resources/strings-da.yml b/src/main/resources/strings-da.yml new file mode 100644 index 0000000..ab30703 --- /dev/null +++ b/src/main/resources/strings-da.yml @@ -0,0 +1,45 @@ +language: Danish +author: Dumle29 +editors: '' +version: 2 +alternate-private-tag: Privat +alternate-moreusers-tag: Flere brugere +alternate-everyone-tag: Alle +alternate-operators-tag: Operatører +alternate-timer-tag: Timer +alternate-fee-tag: Gebyr +msg-user-conflict-door: En konfliktende dør fjernet! +msg-user-illegal: Ulovlig kiste fjernet! +msg-user-resize-owned: Du kan ikke ændre størrelsen af en kist, krævet af en anden ***. +msg-help-chest: Placer et skilt med overskriften [Private] for at låse den. +msg-owner-release: Du har frigivet en beholder! +msg-admin-release: (Admin) @@@ har tvangsåbnet en beholder ejet af ***! +msg-user-release-owned: Du kan ikke frigøre en kist krævet af ***. +msg-owner-remove: Du har fjernet brugere fra en beholder! +msg-user-remove-owned: Du kan ikke fjerne brugere fra en beholder krævet af ***. +msg-user-break-owned: Du kan ikke ødelægge en container krævet af ***. +msg-user-denied-door: Du har ikke ret til at bruge denne dør. +msg-user-touch-fee: 'Et gebyr ### vil blive opkrævet til ***, for at åbne.' +msg-user-touch-owned: Denne beholder er krævet af ***. +msg-help-select: Skilt valgt, brug /lockette for at redigere. +msg-admin-bypass: Omgik en dør ejet af ***, sørg for at lukke den efter dig. +msg-admin-snoop: (Admin) @@@ har snuset rundt i en beholder ejet af ***! +msg-user-denied: Du har ikke ret til at åbne denne kiste. +msg-error-zone: Denne zone er beskyttet af ***. +msg-error-permission: Retten til at låse beholderen er benægtet. +msg-error-claim: Ingen ukrævet beholder i nærheden til at kræve! +msg-error-claim-conflict: Konflikt med en eksisterende beskyttet dør. +msg-admin-claim-error: Spiller *** er ikke online, vær sikker på at du har det rigtige navn. +msg-admin-claim: Du har krævet en beholder for ***. +msg-owner-claim: Du har krævet en beholder! +msg-error-adduser-owned: Du kan ikke tilføje brugere til en beholder krævet af ***. +msg-error-adduser: Ingen krævet beholder i nærheden til at tilføje brugere til! +msg-owner-adduser: Du har tilføjet brugere til beholderen! +msg-help-command1: '&C/lockette - Redigere skilte på låste beholdere. Højreklik på skiltene for at redigere.' +msg-help-command2: '&C/lockette fix - Fikser en automatisk dør der sidder forkert. Kig på døren for at vælge den.' +msg-help-command3: '&C/lockette reload - Reloader konfigurationsfilerne. kun operatører.' +msg-help-command4: '&C/lockette version - Viser lockettes versions streng.' +msg-admin-reload: Genindlæs pluginets konfigurations-filer. +msg-error-fix: Ingen ejet dør fundet. +msg-error-edit: Vælg først et skilt ved at højreklikke på det. +msg-owner-edit: Skilt redigeret succefuldt. diff --git a/src/main/resources/strings-de.yml b/src/main/resources/strings-de.yml new file mode 100644 index 0000000..da2ce2e --- /dev/null +++ b/src/main/resources/strings-de.yml @@ -0,0 +1,42 @@ +language: German +author: Efstajas +editors: '' +version: 2 +alternate-private-tag: Privat +alternate-moreusers-tag: Mehr Leute +alternate-everyone-tag: Jeder +alternate-operators-tag: Operatoren +alternate-timer-tag: Minuten +msg-user-illegal: Illegale Kiste entfernt! +msg-user-resize-owned: Du kannst keine von *** geschützte Kiste vergrössern. +msg-help-chest: Platziere ein Schild mit [Private] an der Truhe, um sie zu schützen. +msg-user-touch-owned: Diese Kiste wurde geschützt von ***. +msg-help-select: Schild ausgewählt, benutze /lockette , um sie zu ändern. +msg-admin-snoop: (Admin) @@@ hat in eine Truhe, die *** geschützt hat, reingeguckt! +msg-user-denied: Du darfst das hier nicht öffnen! +msg-owner-release: Du hast diese Truhe wieder öffentlich gemacht! +msg-admin-release: (Admin) @@@ hat eine Truhe von *** öffentlich gemacht! +msg-user-release-owned: Du kannst diese Truhe von *** nicht öffentlich machen. +msg-owner-remove: Du hast Personen von der Inhaberliste dieser Truhe entfernt! +msg-user-remove-owned: Du kannst keine Personen von dieser Truhe entfernen. +msg-user-break-owned: Du kannst diese von *** geschützte Truhe nicht zerstören. +msg-error-claim: Hier gibt es keine Truhe in der Nähe! +msg-owner-claim: Du hast diese Truhe geschützt! +msg-error-adduser-owned: Du kannst keine Personen auf die Inhaberliste dieser Truhe setzen. +msg-error-adduser: Hier gibt es keine Truhe! +msg-owner-adduser: Du hast Personen zu dieser Truhe hinzugefügt! +msg-help-command1: '&C/lockette - Ändert Text auf Lockette- Schildern. Rechtsklick auf das Schild, um es auszuwählen.' +msg-help-command2: '&C/lockette fix - Fix eine automatische Tür. Schauen Sie sich die Tür zu bearbeiten.' +msg-help-command3: '&C/lockette reload - Lädt die Konfiguration neu.' +msg-help-command4: '&C/lockette version - Zeige version.' +msg-admin-reload: Lädt Lockette- Konfiguration neu. +msg-error-edit: Du musst erst ein Schild per Rechtsklick auswählen. +msg-owner-edit: Text geändert. +msg-user-denied-door: Du darfst diese Tür nicht benutzen. +msg-error-claim-conflict: Konflikt mit einer bereits vorhandenen geschützten Tür. +msg-user-conflict-door: Konflikt- Tür entfernt! +msg-admin-bypass: Du hast eine Tür von *** geöffnet, denke dran sie zu schliessen. +msg-error-permission: Permission to lock container denied. +msg-admin-claim-error: Spieler *** ist nicht online. Hast du den richtigen Namen eingegeben? +msg-admin-claim: Du hast eine Truhe für *** geschützt.. +msg-error-fix: Kein Besitz Tür gefunden. diff --git a/src/main/resources/strings-es.yml b/src/main/resources/strings-es.yml new file mode 100644 index 0000000..861341e --- /dev/null +++ b/src/main/resources/strings-es.yml @@ -0,0 +1,45 @@ +language: Spanish +author: Agubelu +editors: _Robert +version: 3 +alternate-private-tag: Privado +alternate-moreusers-tag: Mas Usuarios +alternate-everyone-tag: Todos +alternate-operators-tag: Moderadores +alternate-timer-tag: Tiempo +alternate-fee-tag: Impuesto +msg-user-conflict-door: ¡Puerta conflictiva eliminada! +msg-user-illegal: ¡Cofre ilegal eliminado! +msg-user-resize-owned: No puedes cambiar un cofre que pertenece a ***. +msg-help-chest: Coloca un cartel con [Private] en la primera linea al lado del cofre para protegerlo. +msg-owner-release: ¡Has desprotegido este objeto! +msg-admin-release: (Admin) @@@ ha roto un objeto perteneciente a *** +msg-user-release-owned: No puedes desproteger un objeto que pertenece a ***. +msg-owner-remove: Has eliminado usuarios de este objeto! +msg-user-remove-owned: No puedes modificar los usuarios en un objeto perteneciente a ***. +msg-user-break-owned: No puedes romper un objeto que pertenece a ***. +msg-user-denied-door: No tienes permiso para usar esta puerta. +msg-user-touch-fee: 'Pagaras un impuesto de ### a *** para usar este objeto.' +msg-user-touch-owned: Este objeto pertecene a ***. +msg-help-select: Cartel seleccionado, usa /lockette para cambiarlo. +msg-admin-bypass: Has usado una puerta que pertenece a ***, recuerda cerrarla. +msg-admin-snoop: (Admin) @@@ ha usado un objeto perteneciente a *** +msg-user-denied: No tienes permiso para usar este objeto. +msg-error-zone: Esta zona esta protegida por ***. +msg-error-permission: No tienes permiso para proteger este objeto. +msg-error-claim: ¡No se ha encontrado nada cercano para proteger! +msg-error-claim-conflict: Existe un conflicto con una puerta protegida cercana. +msg-admin-claim-error: El jugador *** no esta conectado, asegurate de escribir correctamente su nombre. +msg-admin-claim: Has protegido un objeto para ***. +msg-owner-claim: ¡Has protegido este objeto! +msg-error-adduser-owned: No puedes añadir usuarios en un objeto perteneciente a ***. +msg-error-adduser: ¡No se ha encontrado ningun objeto cercano para añadir usuarios! +msg-owner-adduser: Has añadido usuarios a este objeto. +msg-help-command1: '&C/lockette - Edita carteles en objetos protegidos. Clic derecho en el cartel a proteger.' +msg-help-command2: '&C/lockette fix - Arregla una puerta protegida que no funciona correctamente. Apunta la puerta a arreglar y usa este comando.' +msg-help-command3: '&C/lockette reload - Recarga los archivos de configuracion. ¡Solo administradores!' +msg-help-command4: '&C/lockette version - Muestra la version de Lockette.' +msg-admin-reload: Recargando archivos de la configuracion. +msg-error-fix: No se ha encontrado ninguna puerta para arreglar. +msg-error-edit: Primero has de seleccionar un cartel. Haz clic derecho a uno para editarlo. +msg-owner-edit: Cartel editado. \ No newline at end of file diff --git a/src/main/resources/strings-fr.yml b/src/main/resources/strings-fr.yml new file mode 100644 index 0000000..0ec9f6a --- /dev/null +++ b/src/main/resources/strings-fr.yml @@ -0,0 +1,42 @@ +language: French +author: Misa +editors: Acru +version: 3 +alternate-private-tag: Privé +alternate-moreusers-tag: Autre Noms +alternate-everyone-tag: Tout le Monde +alternate-operators-tag: Opérateurs +alternate-timer-tag: Minuterie +msg-user-conflict-door: Porte en conflit supprimée ! +msg-user-illegal: Coffre invalide supprimé ! +msg-user-resize-owned: Vous ne pouvez pas redimensionner un coffre protégé par ***. +msg-help-chest: Placez un panneau avec [Privé] sur la première ligne devant un coffre pour le protéger. +msg-owner-release: Vous avez libéré un conteneur ! +msg-admin-release: (Admin) @@@ a libéré un conteneur appartenant à ***! +msg-user-release-owned: Vous ne pouvez pas libérer un conteneur appartenant à ***. +msg-owner-remove: Vous avez supprimé des utilisateurs d'un conteneur ! +msg-user-remove-owned: Vous ne pouvez pas supprimer des joueurs d'un conteneur appartenant à ***. +msg-user-break-owned: Vous ne pouvez pas détruire un conteneur appartenant à ***. +msg-user-denied-door: Vous n'avez pas la permission d'ouvrir cette porte. +msg-user-touch-owned: Ce conteneur a été protégé par ***. +msg-help-select: Panneau selectionné, utilisez /lockette pour éditer. +msg-admin-bypass: Vous avez forcé une porte appartenant à ***, pensez à la fermer derrière vous. +msg-admin-snoop: (Admin) @@@ a jeté un oeil dans un conteneur appartenant à ***! +msg-user-denied: Vous n'avez pas la permission d'ouvrir ce conteneur. +msg-error-permission: Vous n'avez pas la permission de vérouiller ce conteneur. +msg-error-claim: Aucun conteneur non protégé dans le coin. +msg-error-claim-conflict: Conflit avec une porte existante +msg-admin-claim-error: Le joueur *** n'est pas en ligne, soyez sur de bien écrire son nom. +msg-admin-claim: Vous avez protégé un conteneur pour ***. +msg-owner-claim: Vous avez protégé un conteneur ! +msg-error-adduser-owned: Vous ne pouvez pas ajouter de joueurs pour le conteneur protégé par ***. +msg-error-adduser: Aucun conteneur protégé dans le coin pour y ajouter des utilisateurs ! +msg-owner-adduser: Vous avez ajouté des joueurs à ce conteneur ! +msg-help-command1: '&C/lockette - Edite le panneau sur un conteneur proétégé, clique droit pour éditer.' +msg-help-command2: '&C/lockette fix - Fixer une porte automatique. Regardez la porte à éditer.' +msg-help-command3: '&C/lockette reload - Recharger les fichiers de configuration.' +msg-help-command4: '&C/lockette version - Voir la version.' +msg-admin-reload: Rechargement des fichiers de configuration +msg-error-edit: D'abord, selectionnez un panneau en faisant un clique droit dessus ! +msg-owner-edit: Panneau édité avec succès. +msg-error-fix: Pas de porte propriété trouvé. diff --git a/src/main/resources/strings-it.yml b/src/main/resources/strings-it.yml new file mode 100644 index 0000000..7d1a3f9 --- /dev/null +++ b/src/main/resources/strings-it.yml @@ -0,0 +1,45 @@ +language: Italian +author: Nikkolo_DTU +editors: '' +version: 1 +alternate-private-tag: Privato +alternate-moreusers-tag: Altri player +alternate-everyone-tag: Tutti +alternate-operators-tag: Operatori +alternate-timer-tag: Timer +alternate-fee-tag: Tassa +msg-user-conflict-door: Conflitto della porta rimosso! +msg-user-illegal: Cassetta invalida rimossa! +msg-user-resize-owned: Non puoi modificare la cassetta claimata da ***. +msg-help-chest: Piazza un cartello con scritto [Private] vicino alla cassetta per bloccarla. +msg-owner-release: Hai rilasciato un container! +msg-admin-release: (Admin) @@@ ha aperto un container controllato da ***! +msg-user-release-owned: Non puoi rilasciare un container claimato da ***. +msg-owner-remove: Hai rimosso un player dal container! +msg-user-remove-owned: Non puoi rimuovere i player dal container claimato da ***. +msg-user-break-owned: Non puoi rompere il container claimato da ***. +msg-user-denied-door: Non hai il permesso di usare questa porta. +msg-user-touch-fee: Una tassa di ### verrà pagata a ***, per aprire. +msg-user-touch-owned: Questo container è stato claimato da ***. +msg-help-select: Cartello selezionato, usa /lockette per modificarlo. +msg-admin-bypass: Hai bypassato la porta di ***, ricordati di chiuderla. +msg-admin-snoop: (Admin) @@@ stà curiosando nel container claimato da ***! +msg-user-denied: Non hai il permesso per aprire questo container. +msg-error-zone: Questa zona è stata protetta da ***. +msg-error-permission: Non hai i permessi per bloccare questo container. +msg-error-claim: Nessun container da claimare qui vicino! +msg-error-claim-conflict: Conflitto con una porta gia protetta. +msg-admin-claim-error: Il player *** non è online, controlla di aver scritto correttamente il nome. +msg-admin-claim: Hai claimato un container per ***. +msg-owner-claim: Hai claimato un container! +msg-error-adduser-owned: Non puoi aggiungere altri player nel container claimato da ***. +msg-error-adduser: Nessun container a cui aggiungere altri player qui vicino! +msg-owner-adduser: Hai aggiunto un player nel container! +msg-help-command1: '&C/lockette - Modifica i cartelli dei container claimati. Click destro sul cartello per modificarlo.' +msg-help-command2: '&C/lockette fix - Risolvi una porta automatica che è nella posizione sbagliata. Guarda la porta per modificare.' +msg-help-command3: '&C/lockette reload - Ricarica la configurazione dei file. Solooperatori.' +msg-help-command4: '&C/lockette version - Riporta la versione corrente del plugin.' +msg-admin-reload: Ricaricando la configurazione dei file. +msg-error-fix: Nessun proprietario della porta trovato. +msg-error-edit: Prima seleziona un cartello cliccandoci con il tasto destro. +msg-owner-edit: Cartello modificato con successo. diff --git a/src/main/resources/strings-nl.yml b/src/main/resources/strings-nl.yml new file mode 100644 index 0000000..cc553a0 --- /dev/null +++ b/src/main/resources/strings-nl.yml @@ -0,0 +1,42 @@ +language: Dutch +author: Tofun +editors: '' +version: 2 +alternate-private-tag: Prive +alternate-moreusers-tag: Meer mensen +alternate-everyone-tag: Iedereen +alternate-operators-tag: Beheerders +alternate-timer-tag: Tijd +msg-user-conflict-door: Conflicterende deur verwijderd! +msg-user-illegal: Niet-toegestane kist verwijderd! +msg-user-resize-owned: Je kan een kist van *** niet veranderen. +msg-help-chest: Plaats een bordje met "[Prive]" naast de deur/kist om hem op slot te doen. +msg-owner-release: Je hebt een container vrijgegeven! +msg-admin-release: (Admin) @@@ heeft een container open gebroken van***! +msg-user-release-owned: Je kan niet een container vrijgeven van ***. +msg-owner-remove: Je hebt spelers verwijderd van een container! +msg-user-remove-owned: Je kan geen spelers weg halen van een container van ***. +msg-user-break-owned: Je kan geen container kapot maken van ***. +msg-user-denied-door: Je hebt geen toegang tot deze deur. +msg-user-touch-owned: Deze container is van ***. +msg-help-select: Bord geselecteerd, gebruik /lockette edit om te bewerken. +msg-admin-bypass: Je hebt een deur van *** open gebroken, doe de deur achter je dicht. +msg-admin-snoop: (Admin) @@@ heeft gespiekt in een container van ***! +msg-user-denied: Je hebt geen toegang tot deze container. +msg-error-permission: Toegang tot op slot zetten geweigerd. +msg-error-claim: Er is geen container in de buurt om op slot te zetten! +msg-error-claim-conflict: Er is een conflict met een bestaande deur. +msg-admin-claim-error: Speler *** is niet online, zorg dat je de goede naam hebt. +msg-admin-claim: Je hebt een container geclaimd voor ***. +msg-owner-claim: Je hebt een container geclaimd. +msg-error-adduser-owned: Je kan geen spelers toevoegen aan de container van ***. +msg-error-adduser: Geen container in de buurt om gebruikers aan toe te voegen! +msg-owner-adduser: Je hebt mensen toegevoegd aan een container! +msg-help-command1: '&C/lockette - Bewerkt signs op gesloten containers.' +msg-help-command2: '&C/lockette fix - Fix een automatische deur. Kijk naar de deur te bewerken.' +msg-help-command3: '&C/lockette reload - Herlaadt de config.' +msg-help-command4: '&C/lockette version - Tonen versie.' +msg-admin-reload: Plugin config bestanden herladen... +msg-error-edit: Selecteer eerst een sign door rechts te klikken. +msg-owner-edit: Sign bewerkt. +msg-error-fix: Geen eigendom van de deur gevonden. diff --git a/src/main/resources/strings-no.yml b/src/main/resources/strings-no.yml new file mode 100644 index 0000000..b2fa5e3 --- /dev/null +++ b/src/main/resources/strings-no.yml @@ -0,0 +1,45 @@ +language: Norwegian +author: Tio1999 +editors: Acru +version: 3 +alternate-private-tag: Privat +alternate-moreusers-tag: Fler Brukere +alternate-everyone-tag: Alle +alternate-operators-tag: Opertører +alternate-timer-tag: Timer +alternate-fee-tag: Takst +msg-user-conflict-door: Problemskapende dør fjernet! +msg-user-illegal: Fjernet skdet kiste. +msg-user-resize-owned: Du kan ikke gjøre om kister som er *** sin. +msg-help-chest: Plasser et skilt hvor det står [Privat] får å sikre kisten din. +msg-owner-release: Du har fjernet sikringen! +msg-admin-release: (Admin) @@@ Har brutt en sikring eiet av ***! +msg-user-release-owned: DU kan ikke fjerne *** sin sikring. +msg-owner-remove: DU har fjernet eiere av sikringen! +msg-user-remove-owned: Du kan ikke fjerne brukere fra *** sin sikring! +msg-user-break-owned: Du kan ikke ødlegge en gjenstand som er sikret av ***. +msg-user-denied-door: Du kan ikke åpne denne døren. +msg-user-touch-fee: 'En sum på ### har blitt betalt til *** for å åpne.' +msg-user-touch-owned: Denne gjenstanden har blitt sikret av ***. +msg-help-select: Skilt valgt. Bruk /lockette for å gjøre om. +msg-admin-bypass: Du har passert en dør som eies ***, husk å stenge etter deg. +msg-admin-snoop: (Admin) @@@ har snust i en kiste som er eid av ***! +msg-user-denied: Du kan ikke åpne denne. +msg-error-zone: Omerådet er sikret av ***. +msg-error-permission: Du kan ikke sikre gjensanden. +msg-error-claim: Ingen usikret gjendstand å sikre! +msg-error-claim-conflict: Denne vil lage en konflikt med en annen sikret dør. +msg-admin-claim-error: Bruker *** er ikke online! Har du skrevet brukernavnet riktig? +msg-admin-claim: Du har sikret en gjenstand for ***. +msg-owner-claim: Du har sikret denne gjenstanden! +msg-error-adduser-owned: Du kan ikke legge til brukere på *** sin sikring. +msg-error-adduser: Ingen gjendstand i nærheten å legge til brukere på! +msg-owner-adduser: Du har lagdt til fler brukere på gjenstanden! +msg-help-command1: '&C/lockette - Gjør om skiltet. Høyreklikk på skiltet for å redigere.' +msg-help-command2: '&C/lockette fix - Reparerer en automatisk dør posisjon. Se på døra for å gjøre om.' +msg-help-command3: '&C/lockette reload - Laster inn konfigurasjonsfilen på nytt. Operatører eneste kommandoen.' +msg-help-command4: '&C/lockette version - Rapporterer Lockette versjon.' +msg-admin-reload: laster inn konfigurasjonsfilen på nytt. +msg-error-fix: Ingen sikret dør funnet. +msg-error-edit: Først velg et skilt ved å høyrekilkke på det. +msg-owner-edit: Skiltet ble gjort om uten problemer. diff --git a/src/main/resources/strings-pl.yml b/src/main/resources/strings-pl.yml new file mode 100644 index 0000000..b9bcd69 --- /dev/null +++ b/src/main/resources/strings-pl.yml @@ -0,0 +1,42 @@ +language: Polish +author: Kamild1996 +editors: '' +version: 2 +alternate-private-tag: Prywatny +alternate-moreusers-tag: Uprawnieni +alternate-everyone-tag: Wszyscy +alternate-operators-tag: Operatorzy +alternate-timer-tag: Zegar +msg-user-conflict-door: Drzwi kolidujace usuniete! +msg-user-illegal: Nieprawidlowa skrzynia usunieta! +msg-user-resize-owned: Nie mozesz powiekszyc skrzyni posiadanej przez ***. +msg-help-chest: Poloz tabliczke z napisem [private] przed skrzynia by ja zabezpieczyc. +msg-owner-release: Odbezpieczyles skrzynie! +msg-admin-release: (Admin) @@@ has broken open a container owned by ***! +msg-user-release-owned: Nie mozesz odbezpieczyc skrzyni zabezpieczonej przez ***. +msg-owner-remove: Usunales uzytkownikow skrzyni! +msg-user-remove-owned: Nie mozesz usunac uzytkownikow skrzyni zabezpieczonej przez ***. +msg-user-break-owned: Nie mozesz rozwalic skrzyni zabezpieczonej przez ***. +msg-user-denied-door: Nie masz uprawnien, by uzywac tych drzwi. +msg-user-touch-owned: Ta skrzynia zostala zabezpieczona przez ***. +msg-help-select: Tabliczka wybrana, uzyj /lockette w celu edycji. +msg-admin-bypass: Ominales zabezpieczenia drzwi gracza ***, nie zapomnij zamknac drzwi za soba. +msg-admin-snoop: (Admin) @@@ przeglada skrzynie zabezpieczona przez ***! +msg-user-denied: Nie masz uprawnien, by uzywac tej skrzyni. +msg-error-permission: Nie posiadasz uprawnien do blokady skrzyni/drzwi. +msg-error-claim: Brak nieprzypisanej skrzyni w poblizu, by uczynic ja prywatna! +msg-error-claim-conflict: Konflikt z zabezpieczonymi juz drzwiami. +msg-admin-claim-error: Gracz *** nie jest online, upewnij sie, ze uzyles prawidlowego nicku. +msg-admin-claim: Zablokowales skrzynie/drzwi dla ***. +msg-owner-claim: Zablokowales skrzynie/drzwi! +msg-error-adduser-owned: Nie mozesz dodac uzytkownikow skrzyni zabezpieczonej przez ***. +msg-error-adduser: Brak zabezpieczonej skrzyni, do ktorej moznaby bylo przypisac uzytkownikow! +msg-owner-adduser: Dodales uzytkownikow skrzyni! +msg-help-command1: '&C/lockette - Edytuje tabliczki na zablokowanych skrzyniach/drzwiach. Prawym klikiem na tabliczke, by ja edytowac.' +msg-help-command2: '&C/lockette fix - Rozwiazuje automatyczne drzwi. Spojrz na drzwi do edycji.' +msg-help-command3: '&C/lockette reload - Przeladowuje konfiguracje Lockette.' +msg-help-command4: '&C/lockette version - Pokaz wersji.' +msg-admin-reload: Przeladowywanie plikow konfiguracyjnych Lockette. +msg-error-edit: Najpierw wybierz tabliczke klikajac prawym przyciskiem myszy. +msg-owner-edit: Pomyslnie zakonczono edycje tabliczki. +msg-error-fix: Brak wlasnoscia drzwi znaleziono. diff --git a/src/main/resources/strings-sl.yml b/src/main/resources/strings-sl.yml new file mode 100644 index 0000000..537e94c --- /dev/null +++ b/src/main/resources/strings-sl.yml @@ -0,0 +1,47 @@ +language: Slovenian +author: LiqouRiiCe +editors: '' +version: 1 +alternate-private-tag: Privat +alternate-moreusers-tag: Drugi +alternate-everyone-tag: Vsi +alternate-operators-tag: Admini +alternate-timer-tag: Timing +alternate-fee-tag: Davek +msg-user-conflict-door: Konfliktna vrata odstranjena! +msg-user-illegal: Nedovoljena skrinja odstranjena! +msg-user-resize-owned: Ne mores povecati predmeta od ***. +msg-help-chest: Postavi znak z napisom [Privat] ob skrinji za zaklep. +msg-owner-release: Odstranil si zascito! +msg-admin-release: (Admin) @@@ je odstranil zasctito igralca ***! +msg-user-release-owned: Ne mores odstraniti zascite od ***. +msg-owner-remove: Odstranil si uporabnike! +msg-user-remove-owned: Ne mores odstraniti uporabnikov predmeta od ***. +msg-user-break-owned: Ne mores odstraniti predmeta od ***. +msg-user-denied-door: Nimas dovoljenja za odpiranje teh vrat ! +msg-user-touch-fee: 'Davek ### bo placan igralcu ***, za odpiranje.' +msg-user-touch-owned: Ta predmet si lasti ***. +msg-help-select: Znak oznacen, uporabi /lockette za urejanje. +msg-admin-bypass: Odprl si vrata ki si jih lasti ***, ne pozabi jih zapreti ! +msg-admin-snoop: (Admin) @@@ si je ogledal skrinjo ki si jo lasti ***! +msg-user-denied: Nimas dovoljenja za odpiranje te skrinje. +msg-error-zone: To obmocje je zasciteno na ukaz ***. +msg-error-permission: Nimas dovoljenja za zaklep ! +msg-error-claim: V blizini ni predmeta ki bi ga lahko zaklenil ! +msg-error-claim-conflict: Napaka pri zaklepanju konfliktnih vrat. +msg-admin-claim-error: Igralec *** ni online, prepricaj se da je to pravo ime! +msg-admin-claim: Zaklenil si predmet za igralca ***. +msg-owner-claim: Zaklenil si predmet ! +msg-error-adduser-owned: Ne mores dodati uporabnikov k skirnji/vratom od ***. +msg-error-adduser: V blizini ni predmeta h kateremu bi lahko dodal uporabnike ! +msg-owner-adduser: Dodal si uporabnike h predmetu! +msg-help-command1: '&C/lockette - Uredi napis na znaku. + Desni klik na znak ki ga zelis urediti.' +msg-help-command2: '&C/lockette fix - Popravi vrata ki so obrnjena narobe. + Glej v vrata ki jih zelis popraviti.' +msg-help-command3: '&C/lockette reload - Znova nalozi konfiguracijsko datoteko.' +msg-help-command4: '&C/lockette version - Verzija plugina Lockette.' +msg-admin-reload: Nalagam konfiguracijsko datoteko. +msg-error-fix: Ne najdem vrat za popravilo. +msg-error-edit: Najprej izberi znak z desnim klikom. +msg-owner-edit: Znak urejen ! diff --git a/src/main/resources/strings-sv.yml b/src/main/resources/strings-sv.yml new file mode 100644 index 0000000..49eb60d --- /dev/null +++ b/src/main/resources/strings-sv.yml @@ -0,0 +1,46 @@ +language: Swedish +author: TheMineKraftor +editors: '' +version: 2 +alternate-private-tag: Privat +alternate-moreusers-tag: Fler användare +alternate-everyone-tag: Alla +alternate-operators-tag: Operatörer +alternate-timer-tag: Timer +alternate-fee-tag: Kostnad +msg-user-conflict-door: Problematisk dörr borttagen! +msg-user-illegal: Illegal kista har blivit borttagen! +msg-user-resize-owned: Du kan inte storleksförändra kistan som *** äger. +msg-help-chest: Placera en skylt med överskriften [Private] bredvid en kista för att låsa den. +msg-owner-release: Du har frigjort ett föremål! +msg-admin-release: (Admin) @@@ har brutit upp ett föremål som *** äger! +msg-user-release-owned: Du kan inte frigöra föremålet som *** äger. +msg-owner-remove: Du har tagit bort användare från föremålet! +msg-user-remove-owned: Du kan inte ta bort användare från föremålet som *** äger. +msg-user-break-owned: Du kan inte förstöra ett föremål som *** äger. +msg-user-denied-door: Du har inte tillstånd att öppna denna dörr. +msg-user-touch-fee: 'En kostnad av ### kommer betalas till ***, för att öppnas.' +msg-user-touch-owned: Detta föremål har redan lagts anspråk på utav ***. +msg-help-select: Skylt markerad, använd /lockette för att redigera. +msg-admin-bypass: Brutit upp en dörr som ägs av ***, se till att stänga den efter dig. +msg-admin-snoop: (Admin) @@@ har snokat runt i ett föremål som är ägd av ***! +msg-user-denied: Du har inte tillstånd att öppna detta föremål. +msg-error-zone: Denna zon är skyddad av ***. +msg-error-permission: Tillstånd att låsa föremålet nekas. +msg-error-claim: Inget oägt föremål i närheten för att göra det Privat! +msg-error-claim-conflict: Ett problem uppstod med en dörr som redan är skyddad +msg-admin-claim-error: '*** är inte online, se till att du har skrivit rätt namn.' +msg-admin-claim: Du har lagt anspråk på ett föremål för ***. +msg-owner-claim: Du har lagt anspråk på ett föremål! +msg-error-adduser-owned: Du kan inte lägga anspråk på föremålet som ägs av ***. +msg-error-adduser: Inget föremål i närheten tillgängligt för nya användare! +msg-owner-adduser: Du har lagt till användare till föremålet! +msg-help-command1: '&C/lockette - Redigera skyltar på låsta föremål. +Högerklicka på skylten för att redigera.' +msg-help-command2: '&C/lockette fix - Lagar en dörr i felaktig position. Titta på dörren för att redigera.' +msg-help-command3: '&C/lockette reload - Laddar om inställningsfilerna. Endas för OP.' +msg-help-command4: '&C/lockette version - Visar nuvarande Lockette version.' +msg-admin-reload: Laddar om inställningsfiler. +msg-error-fix: Ingen ägd dörr hittades. +msg-error-edit: Markera en skylt genom att högerklicka. +msg-owner-edit: Redigering av skylten lyckades. \ No newline at end of file diff --git a/src/main/resources/strings-zh_cn.yml b/src/main/resources/strings-zh_cn.yml new file mode 100644 index 0000000..5ad63a3 --- /dev/null +++ b/src/main/resources/strings-zh_cn.yml @@ -0,0 +1,45 @@ +language: Chinese +author: ngbeslhang +editors: '' +version: 1 +alternate-private-tag: ˽ÓÐ +alternate-moreusers-tag: ¸ü¶àÓû§ +alternate-everyone-tag: ´ó¼Ò +alternate-operators-tag: ¹ÜÀíÔ± +alternate-timer-tag: ¼ÆʱÆ÷ +alternate-fee-tag: ·ÑÓà +msg-user-conflict-door: ·¢Éú³åÍ»µÄÃÅÒѱ»ÒƳý£¡ +msg-user-illegal: ²»Õý³£µÄÏä×ÓÒѱ»ÒƳý£¡ +msg-user-resize-owned: Äã²»ÄÜÖØиıä***ÓµÓеÄÏä×ÓÐÎ×´¡£ +msg-help-chest: ÇëÔÚÏä×ÓÅÔ·ÅÖÃÒÔ[˽ÓÐ]Ϊ¿ªÍ·µÄÅÆ×ÓÒÔËøÉÏÏä×Ó¡£ +msg-owner-release: ÄãÒѽâËøÁËÒ»¸öÏä×Ó£¡ +msg-admin-release: (¹ÜÀíÔ±)@@@´ò¿ªÁËÓÉ***ÓµÓеÄÏä×Ó£¡ +msg-user-release-owned: Äã²»ÄܽâËø***ÓµÓеÄÏä×Ó¡£ +msg-owner-remove: ÄãÒÑ´ÓÏä×ÓÉÏÒƳýÍæ¼ÒÃû×Ö£¡ +msg-user-remove-owned: Äã²»ÄÜ´Ó***ÓµÓеÄÏä×ÓÉÏÒƳýÍæ¼ÒÃû×Ö¡£ +msg-user-break-owned: Äã²»ÄÜÆÆ»µ***ÓµÓеÄÏä×Ó¡£ +msg-user-denied-door: ÄãûÓÐȨÏÞʹÓôËÃÅ +msg-user-touch-fee: '###½«»á½»¸ø***ÒÔ´ò¿ª¡£' +msg-user-touch-owned: Õâ¸öÏä×ÓÒѾ­ÊôÓÚ***¡£ +msg-help-select: ÒÑÑ¡ÔñÅÆ×Ó£¬Ê¹ÓÃ/lockette <ÅÆ×ÓÐÐÊý> <Óû§Ãû>ÒÔÐ޸ġ£ +msg-admin-bypass: ÒÑ´ò¿ª***ÓµÓеÄÃÅ£¬Çë¼ÇµÃ¹ØÉÏ¡£ +msg-admin-snoop: (¹ÜÀíÔ±)@@@ÕýÔÚΧÈÆ***ÓµÓеÄÏä×Ó£¡ +msg-user-denied: ÄãûÓÐȨÏÞʹÓôËÏä×Ó¡£ +msg-error-zone: ´ËµØÒÑÓÉ***±£»¤¡£ +msg-error-permission: ¾Ü¾øʹÓÃËøÏä×ÓµÄȨÏÞ¡£ +msg-error-claim: ¸½½üûÓÐÈκÎû±»Õ¼ÓùýµÄÏä×ÓÀ´Ëøס£¡ +msg-error-claim-conflict: ºÍÒѱ»Õ¼ÓõÄÃÅÆð³åÍ»¡£ +msg-admin-claim-error: Íæ¼Ò***²»ÔÚÏߣ¬ÇëÈ·¶¨ÄãÊäÈëµÄÊÇÕýÈ·µÄÃû×Ö¡£ +msg-admin-claim: ÄãÒÑΪ***Õ¼ÓÃÏä×Ó£¡ +msg-owner-claim: ÄãÒÑÕ¼ÓÃÏä×Ó£¡ +msg-error-adduser-owned: Äã²»ÄÜΪ***ÓµÓеÄÏä×ÓÉÏÌí¼ÓÓû§¡£ +msg-error-adduser: ¸½½üûÓÐÈκα»Õ¼ÓõÄÏä×ÓÀ´Ìí¼ÓÓû§£¡ +msg-owner-adduser: ÄãÒѶÔÏä×ÓÌí¼ÓÓû§£¡ +msg-help-command1: '&C/lockette - ÐÞ¸ÄÓÃÀ´ËøסÏä×ÓµÄÅÆ×Ó¡£¶Ô×ÅÅÆ×ÓʹÓÃÓÒ¼üÀ´Ð޸ġ£' +msg-help-command2: '&C/lockette fix - ÐÞ¸´ÔÚ´íÎóλÖõÄ×Ô¶¯ÃÅ¡£¿´×ÅÃÅÒÔÐÞ¸´¡£' +msg-help-command3: '&C/lockette reload - ÖØмÓÔØÅäÖÃÎļþ¡£Ö»ÏÞ¹ÜÀíÔ±¡£' +msg-help-command4: '&C/lockette version - ÏÔʾLocketteµÄ°æ±¾¡£' +msg-admin-reload: ÕýÔÚÖØмÓÔزå¼þµÄÅäÖÃÎļþ¡£ +msg-error-fix: ûÓÐÕÒµ½ÈκÎÒ»¸ö±»Õ¼ÓõÄÃÅ¡£ +msg-error-edit: Ê×ÏÈʹÓÃÓÒ¼üÀ´Ñ¡ÔñÏä×Ó¡£ +msg-owner-edit: ÅÆ×ÓÒѳɹ¦Ð޸ġ£ diff --git a/src/test/java/cn/mcraft/AppTest.java b/src/test/java/cn/mcraft/AppTest.java new file mode 100644 index 0000000..03e086b --- /dev/null +++ b/src/test/java/cn/mcraft/AppTest.java @@ -0,0 +1,38 @@ +package cn.mcraft; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +}