mirror of
https://github.com/EngineHub/WorldGuard.git
synced 2024-12-25 18:47:44 +01:00
Added item-durability and blacklist on-acquire event. Thanks to Dinnerbone for heading my requests :)
This commit is contained in:
parent
a0fc3472e4
commit
eb78b390ca
@ -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
|
WorldGuard on your server. You can either restart your server or use
|
||||||
/reloadplugin WorldGuard to reload the configuraton file after editing it.
|
/reloadplugin WorldGuard to reload the configuraton file after editing it.
|
||||||
|
|
||||||
|
- item-durability (def. true)
|
||||||
|
Enables item durability.
|
||||||
|
|
||||||
- classic-water (def. false)
|
- classic-water (def. false)
|
||||||
Toggle use of classic water. Be foreward that your world may be
|
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
|
flooded if you are not careful. If you have WorldEdit, you can use
|
||||||
|
@ -219,6 +219,48 @@ public boolean onDrop(int item, Player player) {
|
|||||||
return ret;
|
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<BlacklistEntry> 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<BlacklistEntry> 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.
|
* Load the blacklist.
|
||||||
*
|
*
|
||||||
@ -304,6 +346,8 @@ public void load(File file) throws IOException {
|
|||||||
entry.setUseActions(parts[1].split(","));
|
entry.setUseActions(parts[1].split(","));
|
||||||
} else if (parts[0].equalsIgnoreCase("on-drop")) {
|
} else if (parts[0].equalsIgnoreCase("on-drop")) {
|
||||||
entry.setDropActions(parts[1].split(","));
|
entry.setDropActions(parts[1].split(","));
|
||||||
|
} else if (parts[0].equalsIgnoreCase("on-acquire")) {
|
||||||
|
entry.setAcquireActions(parts[1].split(","));
|
||||||
} else if (parts[0].equalsIgnoreCase("message")) {
|
} else if (parts[0].equalsIgnoreCase("message")) {
|
||||||
entry.setMessage(parts[1].trim());
|
entry.setMessage(parts[1].trim());
|
||||||
} else if (parts[0].equalsIgnoreCase("comment")) {
|
} else if (parts[0].equalsIgnoreCase("comment")) {
|
||||||
|
@ -67,11 +67,29 @@ public class BlacklistEntry {
|
|||||||
*/
|
*/
|
||||||
private String[] dropActions;
|
private String[] dropActions;
|
||||||
/**
|
/**
|
||||||
* Comment for the log.
|
* List of actions to perform on drop.
|
||||||
|
*/
|
||||||
|
private String[] acquireActions;
|
||||||
|
/**
|
||||||
|
* Message for users.
|
||||||
*/
|
*/
|
||||||
private String message;
|
private String message;
|
||||||
|
/**
|
||||||
|
* Comment for administrators.
|
||||||
|
*/
|
||||||
private String comment;
|
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.
|
* Construct the object.
|
||||||
*
|
*
|
||||||
@ -183,6 +201,20 @@ public void setDropActions(String[] actions) {
|
|||||||
this.dropActions = actions;
|
this.dropActions = actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String[] getAcquireActions() {
|
||||||
|
return acquireActions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param actions
|
||||||
|
*/
|
||||||
|
public void setAcquireActions(String[] actions) {
|
||||||
|
this.acquireActions = actions;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the message
|
* @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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ActionHandler handler = new ActionHandler() {
|
return process(block.getType(), player, useActions, silentHandler, false, true);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -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 actions
|
||||||
* @param handler
|
* @param handler
|
||||||
* @param allowRepeat
|
* @param allowRepeat
|
||||||
|
* @param silent
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private boolean process(int id, Player player, String[] actions,
|
private boolean process(int id, Player player, String[] actions,
|
||||||
ActionHandler handler, boolean allowRepeat) {
|
ActionHandler handler, boolean allowRepeat, boolean silent) {
|
||||||
|
|
||||||
if (shouldIgnore(player)) {
|
if (shouldIgnore(player)) {
|
||||||
return true;
|
return true;
|
||||||
@ -543,6 +614,9 @@ private boolean process(int id, Player player, String[] actions,
|
|||||||
for (String action : actions) {
|
for (String action : actions) {
|
||||||
// Deny
|
// Deny
|
||||||
if (action.equalsIgnoreCase("deny")) {
|
if (action.equalsIgnoreCase("deny")) {
|
||||||
|
if (silent) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
ret = false;
|
ret = false;
|
||||||
|
|
||||||
// Kick
|
// Kick
|
||||||
|
@ -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 player
|
||||||
* @param item
|
* @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.
|
* Close the connection.
|
||||||
*/
|
*/
|
||||||
|
@ -65,6 +65,13 @@ public interface BlacklistLoggerHandler {
|
|||||||
* @param item
|
* @param item
|
||||||
*/
|
*/
|
||||||
public void logDropAttempt(Player player, int item, String comment);
|
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.
|
* Close the logger.
|
||||||
*/
|
*/
|
||||||
|
@ -102,6 +102,18 @@ public void logDropAttempt(Player player, int item, String comment) {
|
|||||||
+ (comment != null ? " (" + 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.
|
* Get an item's friendly name with its ID.
|
||||||
*
|
*
|
||||||
|
@ -188,6 +188,18 @@ public void logDropAttempt(Player player, int item, String comment) {
|
|||||||
(int)Math.floor(player.getZ()), item, 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.
|
* Close the connection.
|
||||||
*/
|
*/
|
||||||
|
@ -269,6 +269,16 @@ public void logDropAttempt(Player player, int item, String comment) {
|
|||||||
log(player, "Tried to drop " + getFriendlyItemName(item), 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.
|
* Get an item's friendly name with its ID.
|
||||||
*
|
*
|
||||||
|
@ -77,10 +77,14 @@ public void initialize() {
|
|||||||
PluginListener.Priority.HIGH);
|
PluginListener.Priority.HIGH);
|
||||||
loader.addListener(PluginLoader.Hook.ITEM_DROP, listener, this,
|
loader.addListener(PluginLoader.Hook.ITEM_DROP, listener, this,
|
||||||
PluginListener.Priority.HIGH);
|
PluginListener.Priority.HIGH);
|
||||||
|
loader.addListener(PluginLoader.Hook.ITEM_PICK_UP, listener, this,
|
||||||
|
PluginListener.Priority.HIGH);
|
||||||
loader.addListener(PluginLoader.Hook.COMPLEX_BLOCK_CHANGE, listener, this,
|
loader.addListener(PluginLoader.Hook.COMPLEX_BLOCK_CHANGE, listener, this,
|
||||||
PluginListener.Priority.HIGH);
|
PluginListener.Priority.HIGH);
|
||||||
loader.addListener(PluginLoader.Hook.COMPLEX_BLOCK_SEND, listener, this,
|
loader.addListener(PluginLoader.Hook.COMPLEX_BLOCK_SEND, listener, this,
|
||||||
PluginListener.Priority.HIGH);
|
PluginListener.Priority.HIGH);
|
||||||
|
loader.addListener(PluginLoader.Hook.INVENTORY_CHANGE, listener, this,
|
||||||
|
PluginListener.Priority.HIGH);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -58,10 +58,6 @@ public class WorldGuardListener extends PluginListener {
|
|||||||
* Properties file for WorldGuard.
|
* Properties file for WorldGuard.
|
||||||
*/
|
*/
|
||||||
private PropertiesFile properties = new PropertiesFile("worldguard.properties");
|
private PropertiesFile properties = new PropertiesFile("worldguard.properties");
|
||||||
/**
|
|
||||||
* List of blocks to remove when possible.
|
|
||||||
*/
|
|
||||||
private LinkedList<int[]> blockRemoveQueue = new LinkedList<int[]>();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop fire spread mode.
|
* Stop fire spread mode.
|
||||||
@ -77,6 +73,7 @@ public class WorldGuardListener extends PluginListener {
|
|||||||
private boolean simulateSponge;
|
private boolean simulateSponge;
|
||||||
private int spongeRadius;
|
private int spongeRadius;
|
||||||
private boolean blockLagFix;
|
private boolean blockLagFix;
|
||||||
|
private boolean itemDurability;
|
||||||
private Set<Integer> fireNoSpreadBlocks;
|
private Set<Integer> fireNoSpreadBlocks;
|
||||||
private Set<Integer> allowedLavaSpreadOver;
|
private Set<Integer> allowedLavaSpreadOver;
|
||||||
private Set<Integer> itemDropBlacklist;
|
private Set<Integer> itemDropBlacklist;
|
||||||
@ -143,6 +140,7 @@ public void loadConfiguration() {
|
|||||||
simulateSponge = properties.getBoolean("simulate-sponge", false);
|
simulateSponge = properties.getBoolean("simulate-sponge", false);
|
||||||
spongeRadius = Math.max(1, properties.getInt("sponge-radius", 3)) - 1;
|
spongeRadius = Math.max(1, properties.getInt("sponge-radius", 3)) - 1;
|
||||||
blockLagFix = properties.getBoolean("block-lag-fix", false);
|
blockLagFix = properties.getBoolean("block-lag-fix", false);
|
||||||
|
itemDurability = properties.getBoolean("item-durability", true);
|
||||||
|
|
||||||
// Console log configuration
|
// Console log configuration
|
||||||
boolean logConsole = properties.getBoolean("log-console", true);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
# - on-create (the item/block in the user's inventory is being created)
|
# - on-create (the item/block in the user's inventory is being created)
|
||||||
# - on-use (the block is right clicked)
|
# - on-use (the block is right clicked)
|
||||||
# - on-drop (the item is being dropped from the player's inventory)
|
# - 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):
|
# Actions (for events):
|
||||||
# - deny (deny completely)
|
# - deny (deny completely)
|
||||||
@ -34,6 +35,13 @@
|
|||||||
# - kick (kick player)
|
# - kick (kick player)
|
||||||
# - ban (ban 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.
|
# Users with the /worldguardnotify permission will be receive notifications.
|
||||||
#
|
#
|
||||||
# -------------
|
# -------------
|
||||||
|
Loading…
Reference in New Issue
Block a user