From eb78b390ca603bfa0917017a8b7f83295be537e1 Mon Sep 17 00:00:00 2001 From: sk89q Date: Sun, 21 Nov 2010 00:45:16 -0800 Subject: [PATCH] Added item-durability and blacklist on-acquire event. Thanks to Dinnerbone for heading my requests :) --- README.txt | 3 + src/Blacklist.java | 44 ++++++++++++ src/BlacklistEntry.java | 118 ++++++++++++++++++++++++++------ src/BlacklistLogger.java | 14 +++- src/BlacklistLoggerHandler.java | 7 ++ src/ConsoleLoggerHandler.java | 12 ++++ src/DatabaseLoggerHandler.java | 12 ++++ src/FileLoggerHandler.java | 10 +++ src/WorldGuard.java | 6 +- src/WorldGuardListener.java | 56 +++++++++++++-- worldguard-blacklist.txt | 8 +++ 11 files changed, 262 insertions(+), 28 deletions(-) diff --git a/README.txt b/README.txt index 28dd71a7..9e3a032c 100644 --- a/README.txt +++ b/README.txt @@ -34,6 +34,9 @@ A "worldguard.properties" will be created the first the time that you load WorldGuard on your server. You can either restart your server or use /reloadplugin WorldGuard to reload the configuraton file after editing it. +- item-durability (def. true) + Enables item durability. + - classic-water (def. false) Toggle use of classic water. Be foreward that your world may be flooded if you are not careful. If you have WorldEdit, you can use diff --git a/src/Blacklist.java b/src/Blacklist.java index ee44c001..eadb28e4 100644 --- a/src/Blacklist.java +++ b/src/Blacklist.java @@ -219,6 +219,48 @@ public boolean onDrop(int item, Player player) { return ret; } + /** + * Called on acquire. Returns true to let the action pass through. + * + * @param item + * @param player + * @return + */ + public boolean onAcquire(int item, Player player) { + List entries = getEntries(item); + if (entries == null) { + return true; + } + boolean ret = true; + for (BlacklistEntry entry : entries) { + if (!entry.onAcquire(item, player)) { + ret = false; + } + } + return ret; + } + + /** + * Called on acquire. Returns true to let the action pass through. + * + * @param item + * @param player + * @return + */ + public boolean onSilentAcquire(int item, Player player) { + List entries = getEntries(item); + if (entries == null) { + return true; + } + boolean ret = true; + for (BlacklistEntry entry : entries) { + if (!entry.onSilentAcquire(item, player)) { + ret = false; + } + } + return ret; + } + /** * Load the blacklist. * @@ -304,6 +346,8 @@ public void load(File file) throws IOException { entry.setUseActions(parts[1].split(",")); } else if (parts[0].equalsIgnoreCase("on-drop")) { entry.setDropActions(parts[1].split(",")); + } else if (parts[0].equalsIgnoreCase("on-acquire")) { + entry.setAcquireActions(parts[1].split(",")); } else if (parts[0].equalsIgnoreCase("message")) { entry.setMessage(parts[1].trim()); } else if (parts[0].equalsIgnoreCase("comment")) { diff --git a/src/BlacklistEntry.java b/src/BlacklistEntry.java index 3dea1bcb..5ddae0a0 100644 --- a/src/BlacklistEntry.java +++ b/src/BlacklistEntry.java @@ -67,11 +67,29 @@ public class BlacklistEntry { */ private String[] dropActions; /** - * Comment for the log. + * List of actions to perform on drop. + */ + private String[] acquireActions; + /** + * Message for users. */ private String message; + /** + * Comment for administrators. + */ private String comment; + /** + * Used to ignore messages. + */ + private static ActionHandler silentHandler = new ActionHandler() { + public void log(String itemName) {} + public void kick(String itemName) {} + public void ban(String itemName) {} + public void notifyAdmins(String itemName) {} + public void tell(String itemName) {} + }; + /** * Construct the object. * @@ -183,6 +201,20 @@ public void setDropActions(String[] actions) { this.dropActions = actions; } + /** + * @return + */ + public String[] getAcquireActions() { + return acquireActions; + } + + /** + * @param actions + */ + public void setAcquireActions(String[] actions) { + this.acquireActions = actions; + } + /** * @return the message */ @@ -292,7 +324,7 @@ public void tell(String itemName) { } }; - return process(block.getType(), player, destroyActions, handler, false); + return process(block.getType(), player, destroyActions, handler, false, false); } /** @@ -329,7 +361,7 @@ public void tell(String itemName) { } }; - return process(block.getType(), player, breakActions, handler, true); + return process(block.getType(), player, breakActions, handler, true, false); } /** @@ -365,7 +397,7 @@ public void tell(String itemName) { } }; - return process(item, player, destroyWithActions, handler, false); + return process(item, player, destroyWithActions, handler, false, false); } /** @@ -401,7 +433,7 @@ public void tell(String itemName) { } }; - return process(item, player, createActions, handler, true); + return process(item, player, createActions, handler, true, false); } /** @@ -437,7 +469,7 @@ public void tell(String itemName) { } }; - return process(block.getType(), player, useActions, handler, false); + return process(block.getType(), player, useActions, handler, false, false); } /** @@ -452,20 +484,7 @@ public boolean onSilentUse(final Block block, final Player player) { return true; } - ActionHandler handler = new ActionHandler() { - public void log(String itemName) { - } - public void kick(String itemName) { - } - public void ban(String itemName) { - } - public void notifyAdmins(String itemName) { - } - public void tell(String itemName) { - } - }; - - return process(block.getType(), player, useActions, handler, false); + return process(block.getType(), player, useActions, silentHandler, false, true); } /** @@ -501,7 +520,58 @@ public void tell(String itemName) { } }; - return process(item, player, dropActions, handler, true); + return process(item, player, dropActions, handler, true, false); + } + + /** + * Called on item acquire. Returns true to let the action pass through. + * + * @param item + * @param player + * @return + */ + public boolean onAcquire(final int item, final Player player) { + if (acquireActions == null) { + return true; + } + + final BlacklistEntry entry = this; + + ActionHandler handler = new ActionHandler() { + public void log(String itemName) { + blacklist.getLogger().logAcquireAttempt(player, item, comment); + } + public void kick(String itemName) { + player.kick("You can't acquire " + itemName); + } + public void ban(String itemName) { + entry.banPlayer(player, "Banned: You can't acquire " + itemName); + } + public void notifyAdmins(String itemName) { + entry.notifyAdmins(player.getName() + " (acquire) " + itemName + + (comment != null ? " (" + comment + ")" : "") + "."); + } + public void tell(String itemName) { + player.sendMessage(Colors.Yellow + "You're not allowed to acquire " + itemName + "."); + } + }; + + return process(item, player, acquireActions, handler, true, false); + } + + /** + * Called on item acquire. Returns true to let the action pass through. + * + * @param item + * @param player + * @return + */ + public boolean onSilentAcquire(final int item, final Player player) { + if (acquireActions == null) { + return true; + } + + return process(item, player, acquireActions, silentHandler, false, true); } /** @@ -512,10 +582,11 @@ public void tell(String itemName) { * @param actions * @param handler * @param allowRepeat + * @param silent * @return */ private boolean process(int id, Player player, String[] actions, - ActionHandler handler, boolean allowRepeat) { + ActionHandler handler, boolean allowRepeat, boolean silent) { if (shouldIgnore(player)) { return true; @@ -543,6 +614,9 @@ private boolean process(int id, Player player, String[] actions, for (String action : actions) { // Deny if (action.equalsIgnoreCase("deny")) { + if (silent) { + return false; + } ret = false; // Kick diff --git a/src/BlacklistLogger.java b/src/BlacklistLogger.java index 029e31a5..35b25573 100644 --- a/src/BlacklistLogger.java +++ b/src/BlacklistLogger.java @@ -119,7 +119,7 @@ public void logCreateAttempt(Player player, int item, String comment) { } /** - * Log a right click attempt. + * Log a drop attempt. * * @param player * @param item @@ -130,6 +130,18 @@ public void logDropAttempt(Player player, int item, String comment) { } } + /** + * Log an acquire attempt. + * + * @param player + * @param item + */ + public void logAcquireAttempt(Player player, int item, String comment) { + for (BlacklistLoggerHandler handler : handlers) { + handler.logAcquireAttempt(player, item, comment); + } + } + /** * Close the connection. */ diff --git a/src/BlacklistLoggerHandler.java b/src/BlacklistLoggerHandler.java index d4161e9d..b782fb55 100644 --- a/src/BlacklistLoggerHandler.java +++ b/src/BlacklistLoggerHandler.java @@ -65,6 +65,13 @@ public interface BlacklistLoggerHandler { * @param item */ public void logDropAttempt(Player player, int item, String comment); + /** + * Log an acquire attempt. + * + * @param player + * @param item + */ + public void logAcquireAttempt(Player player, int item, String comment); /** * Close the logger. */ diff --git a/src/ConsoleLoggerHandler.java b/src/ConsoleLoggerHandler.java index fa096fcb..09cccb08 100644 --- a/src/ConsoleLoggerHandler.java +++ b/src/ConsoleLoggerHandler.java @@ -102,6 +102,18 @@ public void logDropAttempt(Player player, int item, String comment) { + (comment != null ? " (" + comment + ")" : "")); } + /** + * Log an acquire attempt. + * + * @param player + * @param item + */ + public void logAcquireAttempt(Player player, int item, String comment) { + logger.log(Level.INFO, "WorldGuard: " + player.getName() + + " tried to acquire " + getFriendlyItemName(item) + + (comment != null ? " (" + comment + ")" : "")); + } + /** * Get an item's friendly name with its ID. * diff --git a/src/DatabaseLoggerHandler.java b/src/DatabaseLoggerHandler.java index ff5d02c3..75cd4d46 100644 --- a/src/DatabaseLoggerHandler.java +++ b/src/DatabaseLoggerHandler.java @@ -188,6 +188,18 @@ public void logDropAttempt(Player player, int item, String comment) { (int)Math.floor(player.getZ()), item, comment); } + /** + * Log an aquire attempt. + * + * @param player + * @param item + */ + public void logAcquireAttempt(Player player, int item, String comment) { + logEvent("AQUIRE", player.getName(), + (int)Math.floor(player.getX()), (int)Math.floor(player.getY()), + (int)Math.floor(player.getZ()), item, comment); + } + /** * Close the connection. */ diff --git a/src/FileLoggerHandler.java b/src/FileLoggerHandler.java index dc07a248..ce3bc73c 100644 --- a/src/FileLoggerHandler.java +++ b/src/FileLoggerHandler.java @@ -269,6 +269,16 @@ public void logDropAttempt(Player player, int item, String comment) { log(player, "Tried to drop " + getFriendlyItemName(item), comment); } + /** + * Log an acquire attempt. + * + * @param player + * @param item + */ + public void logAcquireAttempt(Player player, int item, String comment) { + log(player, "Tried to acquire " + getFriendlyItemName(item), comment); + } + /** * Get an item's friendly name with its ID. * diff --git a/src/WorldGuard.java b/src/WorldGuard.java index 757d59bd..e1e69e75 100644 --- a/src/WorldGuard.java +++ b/src/WorldGuard.java @@ -75,12 +75,16 @@ public void initialize() { PluginListener.Priority.HIGH); loader.addListener(PluginLoader.Hook.DISCONNECT, listener, this, PluginListener.Priority.HIGH); - loader.addListener(PluginLoader.Hook.ITEM_DROP , listener, this, + loader.addListener(PluginLoader.Hook.ITEM_DROP, listener, this, + PluginListener.Priority.HIGH); + loader.addListener(PluginLoader.Hook.ITEM_PICK_UP, listener, this, PluginListener.Priority.HIGH); loader.addListener(PluginLoader.Hook.COMPLEX_BLOCK_CHANGE, listener, this, PluginListener.Priority.HIGH); loader.addListener(PluginLoader.Hook.COMPLEX_BLOCK_SEND, listener, this, PluginListener.Priority.HIGH); + loader.addListener(PluginLoader.Hook.INVENTORY_CHANGE, listener, this, + PluginListener.Priority.HIGH); } /** diff --git a/src/WorldGuardListener.java b/src/WorldGuardListener.java index a18a0785..f0252996 100644 --- a/src/WorldGuardListener.java +++ b/src/WorldGuardListener.java @@ -58,10 +58,6 @@ public class WorldGuardListener extends PluginListener { * Properties file for WorldGuard. */ private PropertiesFile properties = new PropertiesFile("worldguard.properties"); - /** - * List of blocks to remove when possible. - */ - private LinkedList blockRemoveQueue = new LinkedList(); /** * Stop fire spread mode. @@ -77,6 +73,7 @@ public class WorldGuardListener extends PluginListener { private boolean simulateSponge; private int spongeRadius; private boolean blockLagFix; + private boolean itemDurability; private Set fireNoSpreadBlocks; private Set allowedLavaSpreadOver; private Set itemDropBlacklist; @@ -143,6 +140,7 @@ public void loadConfiguration() { simulateSponge = properties.getBoolean("simulate-sponge", false); spongeRadius = Math.max(1, properties.getInt("sponge-radius", 3)) - 1; blockLagFix = properties.getBoolean("block-lag-fix", false); + itemDurability = properties.getBoolean("item-durability", true); // Console log configuration boolean logConsole = properties.getBoolean("log-console", true); @@ -346,6 +344,56 @@ public boolean onItemDrop(Player player, Item item) { } } + if (!itemDurability) { + item.setHealth(0); + } + + return false; + } + + /** + * Called when a player picks up an item. + * + * @param player + * player who picked up the item + * @param item + * item that was picked up + * @return true if you want to leave the item where it was + */ + public boolean onItemPickUp(Player player, Item item) { + if (!blacklist.onSilentAcquire(item.getItemId(), player)) { + return true; + } + + return false; + } + + /** + * Called when a player's inventory is modified. + * + * @param player + * player who's inventory was modified + * @return true if you want any changes to be reverted + */ + public boolean onInventoryChange(Player player) { + if (blacklist != null) { + hj[] items = player.getInventory().getArray(); + boolean needUpdate = false; + + for (int i = 0; i < items.length; i++) { + if (items[i] != null) { + if (!blacklist.onAcquire(items[i].c, player)) { + items[i] = null; + needUpdate = true; + } + } + } + + if (needUpdate) { + player.getInventory().updateInventory(); + } + } + return false; } diff --git a/worldguard-blacklist.txt b/worldguard-blacklist.txt index 90c9e9dd..2a257482 100644 --- a/worldguard-blacklist.txt +++ b/worldguard-blacklist.txt @@ -25,6 +25,7 @@ # - on-create (the item/block in the user's inventory is being created) # - on-use (the block is right clicked) # - on-drop (the item is being dropped from the player's inventory) +# - on-acquire (the item enters a player's inventory via some method) # # Actions (for events): # - deny (deny completely) @@ -34,6 +35,13 @@ # - kick (kick player) # - ban (ban player) # +# With the on-acquire event, it will completely block item pick ups +# (the item will still be on the ground) if you use 'deny' but the other +# actions (notify, log, etc.) won't do anything. However, if the player +# receives the item via a different method (i.e. from a chest), all actions +# will work although the item is removed after a short delay rather than +# blocked from the beginning (as it is part client-side). +# # Users with the /worldguardnotify permission will be receive notifications. # # -------------