Compare commits

...
11 Commits
7 changed files with 1068 additions and 725 deletions

No files matched your search

+13
View File
@@ -1,3 +1,16 @@
2.3:
- /god now works very well.
- Item (TNT, flint and steel, etc.) blocking should now work.
- The TNT blocking configuration variable should now work.
- Re-added /heal (not sure where that went), added /slay.
- Implemented contact damage disable toggle.
- Made all player damage disabling configuration parameters work.
- Fixed teleport-on-suffocation setting.
- Added /locate <name>, /locate <x> <y> <z>, and /locate that lets you
program/change your compass bearing to point to a player's position
(not yet live), a position, or back to spawn.
- Fixed CSVDatabase spitting an error if the owners list was empty.
2.2:
- Now supports GroupUsers.
- Added support for blocking creeper explosions.
+8 -11
View File
@@ -59,12 +59,13 @@ spawn:
teleport-to-home-on-death: off
player-damage:
disable-fall-damage: on
disable-lava-damage: on
disable-fire-damage: on
disable-drowning-damage: on
disable-suffocation-damage: on
teleport-on-suffocation: on
disable-fall-damage: off
disable-lava-damage: off
disable-fire-damage: off
disable-drowning-damage: off
disable-suffocation-damage: off
disable-contact-damage: off
teleport-on-suffocation: off
regions:
enable: on
@@ -87,12 +88,8 @@ blacklist:
# See http://wiki.sk89q.com/wiki/WorldGuard/Permissions/Bukkit
permissions:
groups:
default:
permissions:
- /reload
users:
sk89q:
permissions:
- /region
- /reload
- /reloadwg
+31 -1
View File
@@ -1,3 +1,33 @@
name: WorldGuard
main: com.sk89q.worldguard.bukkit.WorldGuardPlugin
version: WGVERSIONMACRO
version: WGVERSIONMACRO
commands:
stopfire:
description: Halts all fire spread until it is disabled or the server is restarted
usage: /<command>
allowfire:
description: Re-enables fire spread if he has been disabled with /stopfire
usage: /<command>
god:
description: Toggles god mode
usage: /<command> [other player]
heal:
description: Heal yourself or another
usage: /<command> [other player]
slay:
description: Slay yourself or another
usage: /<command> [other player]
stack:
description: Stacks items in the player's inventory
usage: /<command>
aliases: ;
region:
description: Adjust protected regions
usage: /<command> <define|claim|flag|delete|info|addowner|removeowner|list|save|load> ...
aliases: rg, regions
locate:
description: Set your compass towards a person
usage: /<command> <target>
reloadwg:
description: Reload WorldGuard's configuration
usage: /<command>
@@ -20,12 +20,15 @@
package com.sk89q.worldguard.bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.*;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BlockType;
import static com.sk89q.worldguard.bukkit.BukkitUtil.*;
public class WorldGuardEntityListener extends EntityListener {
@@ -48,40 +51,18 @@ public class WorldGuardEntityListener extends EntityListener {
Entity defender = event.getEntity();
DamageCause type = event.getCause();
if (defender instanceof Player) {
if (defender instanceof Player) {
Player player = (Player)defender;
if (plugin.invinciblePlayers.contains(player.getName())) {
event.setCancelled(true);
return;
}
if (plugin.disableFallDamage && type == DamageCause.FALL) {
event.setCancelled(true);
return;
}
if (plugin.disableLavaDamage && type == DamageCause.LAVA) {
event.setCancelled(true);
return;
}
if (plugin.disableFireDamage && (type == DamageCause.FIRE
|| type == DamageCause.FIRE_TICK)) {
event.setCancelled(true);
return;
}
if (plugin.disableDrowningDamage && type == DamageCause.DROWNING) {
event.setCancelled(true);
return;
}
if (type == DamageCause.DROWNING
&& plugin.amphibiousPlayers.contains(player.getName())) {
event.setCancelled(true);
return;
}
}
}
@@ -111,6 +92,72 @@ public class WorldGuardEntityListener extends EntityListener {
}
}
}
public void onEntityDamageByProjectile(EntityDamageByProjectileEvent event) {
Entity defender = event.getEntity();
if (defender instanceof Player) {
Player player = (Player)defender;
if (plugin.invinciblePlayers.contains(player.getName())) {
event.setCancelled(true);
return;
}
}
}
public void onEntityDamage(EntityDamageEvent event) {
Entity defender = event.getEntity();
DamageCause type = event.getCause();
if (defender instanceof Player) {
Player player = (Player)defender;
if (plugin.invinciblePlayers.contains(player.getName())) {
event.setCancelled(true);
return;
}
if (plugin.disableFallDamage && type == DamageCause.FALL) {
event.setCancelled(true);
return;
}
if (plugin.disableFireDamage && (type == DamageCause.FIRE
|| type == DamageCause.FIRE_TICK)) {
event.setCancelled(true);
return;
}
if (plugin.disableDrowningDamage && type == DamageCause.DROWNING) {
event.setCancelled(true);
return;
}
if (plugin.teleportOnSuffocation && type == DamageCause.SUFFOCATION) {
findFreePosition(player);
event.setCancelled(true);
return;
}
if (plugin.disableSuffocationDamage && type == DamageCause.SUFFOCATION) {
event.setCancelled(true);
return;
}
if (plugin.disableContactDamage && type == DamageCause.CONTACT) {
event.setCancelled(true);
return;
}
if (type == DamageCause.DROWNING
&& plugin.amphibiousPlayers.contains(player.getName())) {
event.setCancelled(true);
return;
}
}
}
@Override
public void onEntityExplode(EntityExplodeEvent event) {
@@ -133,6 +180,60 @@ public class WorldGuardEntityListener extends EntityListener {
return;
}
}
} else { // Shall assume that this is TNT
if (plugin.blockTNT) {
event.setCancelled(true);
return;
}
if (plugin.useRegions) {
Vector pt = toVector(event.getEntity().getLocation());
if (!plugin.regionManager.getApplicableRegions(pt).allowsTNT()) {
event.setCancelled(true);
return;
}
}
}
}
/**
* Find a position for the player to stand that is not inside a block.
* Blocks above the player will be iteratively tested until there is
* a series of two free blocks. The player will be teleported to
* that free position.
*
* @param player
*/
public void findFreePosition(Player player) {
Location loc = player.getLocation();
int x = loc.getBlockX();
int y = Math.max(0, loc.getBlockY());
int origY = y;
int z = loc.getBlockZ();
World world = player.getWorld();
byte free = 0;
while (y <= 129) {
if (BlockType.canPassThrough(world.getBlockTypeIdAt(x, y, z))) {
free++;
} else {
free = 0;
}
if (free == 2) {
if (y - 1 != origY) {
loc.setX(x + 0.5);
loc.setY(y);
loc.setZ(z + 0.5);
player.teleportTo(loc);
}
return;
}
y++;
}
}
}
@@ -19,31 +19,16 @@
package com.sk89q.worldguard.bukkit;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.player.*;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.blocks.ItemType;
import com.sk89q.worldedit.bukkit.WorldEditAPI;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.*;
import com.sk89q.worldguard.blacklist.events.ItemUseBlacklistEvent;
import com.sk89q.worldguard.domains.*;
import com.sk89q.worldguard.protection.*;
import static com.sk89q.worldguard.bukkit.BukkitUtil.*;
/**
@@ -54,12 +39,6 @@ public class WorldGuardPlayerListener extends PlayerListener {
* Plugin.
*/
private WorldGuardPlugin plugin;
/**
* Group pattern used to specify groups for the region command.
*/
private static Pattern groupPattern = Pattern.compile("^[gG]:(.+)$");
private static int CMD_LIST_SIZE = 9;
/**
* Construct the object;
@@ -117,8 +96,9 @@ public class WorldGuardPlayerListener extends PlayerListener {
public void onPlayerItem(PlayerItemEvent event) {
Player player = event.getPlayer();
Block block = event.getBlockClicked();
ItemStack item = event.getItem();
if (plugin.useRegions && !event.isBlock() && event.getBlockClicked() != null) {
if (plugin.useRegions && !event.isBlock() && block != null) {
Vector pt = toVector(block.getRelative(event.getBlockFace()));
LocalPlayer localPlayer = plugin.wrapPlayer(player);
@@ -131,10 +111,11 @@ public class WorldGuardPlayerListener extends PlayerListener {
}
}
if (block != null && plugin.blacklist != null) {
if (item != null && plugin.blacklist != null && block != null) {
if (!plugin.blacklist.check(
new ItemUseBlacklistEvent(plugin.wrapPlayer(player), toVector(block),
block.getTypeId()), false, false)) {
new ItemUseBlacklistEvent(plugin.wrapPlayer(player),
toVector(block.getRelative(event.getBlockFace())),
item.getTypeId()), false, false)) {
event.setCancelled(true);
return;
}
@@ -160,665 +141,4 @@ public class WorldGuardPlayerListener extends PlayerListener {
}
}
}
/**
* Called when a player attempts to use a command
*
* @param event Relevant event details
*/
@Override
public void onPlayerCommand(PlayerChatEvent event) {
if (handleCommand(event)) {
event.setCancelled(true);
}
}
/**
* Called when a player attempts to use a command
*
* @param event Relevant event details
*/
public boolean handleCommand(PlayerChatEvent event) {
Player player = event.getPlayer();
String[] split = event.getMessage().split(" ");
if (split[0].equalsIgnoreCase("/stopfire") &&
plugin.hasPermission(player, "/stopfire")) {
if (!plugin.fireSpreadDisableToggle) {
plugin.getServer().broadcastMessage(ChatColor.YELLOW
+ "Fire spread has been globally disabled by " + player.getName() + ".");
} else {
player.sendMessage(ChatColor.YELLOW + "Fire spread was already globally disabled.");
}
plugin.fireSpreadDisableToggle = true;
} else if (split[0].equalsIgnoreCase("/allowfire")
&& plugin.hasPermission(player, "/stopfire")) {
if (plugin.fireSpreadDisableToggle) {
plugin.getServer().broadcastMessage(ChatColor.YELLOW
+ "Fire spread has been globally re-enabled by " + player.getName() + ".");
} else {
player.sendMessage(ChatColor.YELLOW + "Fire spread was already globally enabled.");
}
plugin.fireSpreadDisableToggle = false;
} else if (split[0].equalsIgnoreCase("/god")
&& plugin.hasPermission(player, "/god")) {
// Allow setting other people invincible
if (split.length > 1) {
if (!plugin.hasPermission(player, "/godother")) {
player.sendMessage(ChatColor.RED + "You don't have permission to make others invincible.");
return true;
}
Player other = matchSinglePlayer(plugin.getServer(), split[1]);
if (other == null) {
player.sendMessage(ChatColor.RED + "Player not found.");
} else {
if (!plugin.invinciblePlayers.contains(other.getName())) {
plugin.invinciblePlayers.add(other.getName());
player.sendMessage(ChatColor.YELLOW + other.getName() + " is now invincible!");
other.sendMessage(ChatColor.YELLOW + player.getName() + " has made you invincible!");
} else {
plugin.invinciblePlayers.remove(other.getName());
player.sendMessage(ChatColor.YELLOW + other.getName() + " is no longer invincible.");
other.sendMessage(ChatColor.YELLOW + player.getName() + " has taken away your invincibility.");
}
}
// Invincibility for one's self
} else {
if (!plugin.invinciblePlayers.contains(player.getName())) {
plugin.invinciblePlayers.add(player.getName());
player.sendMessage(ChatColor.YELLOW + "You are now invincible!");
} else {
plugin.invinciblePlayers.remove(player.getName());
player.sendMessage(ChatColor.YELLOW + "You are no longer invincible.");
}
}
} else if ((split[0].equalsIgnoreCase("/stack")
|| split[0].equalsIgnoreCase("/;"))
&& plugin.hasPermission(player, "/stack")) {
ItemStack[] items = player.getInventory().getContents();
int len = items.length;
int affected = 0;
for (int i = 0; i < len; i++) {
ItemStack item = items[i];
// Avoid infinite stacks and stacks with durability
if (item == null || item.getAmount() <= 0
|| ItemType.shouldNotStack(item.getTypeId())) {
continue;
}
// Ignore buckets
if (item.getTypeId() >= 325 && item.getTypeId() <= 327) {
continue;
}
if (item.getAmount() < 64) {
int needed = 64 - item.getAmount(); // Number of needed items until 64
// Find another stack of the same type
for (int j = i + 1; j < len; j++) {
ItemStack item2 = items[j];
// Avoid infinite stacks and stacks with durability
if (item2 == null || item2.getAmount() <= 0
|| ItemType.shouldNotStack(item.getTypeId())) {
continue;
}
// Same type?
// Blocks store their color in the damage value
if (item2.getTypeId() == item.getTypeId() &&
(!ItemType.usesDamageValue(item.getTypeId())
|| item.getDamage() == item2.getDamage())) {
// This stack won't fit in the parent stack
if (item2.getAmount() > needed) {
item.setAmount(64);
item2.setAmount(item2.getAmount() - needed);
break;
// This stack will
} else {
items[j] = null;
item.setAmount(item.getAmount() + item2.getAmount());
needed = 64 - item.getAmount();
}
affected++;
}
}
}
}
if (affected > 0) {
player.getInventory().setContents(items);
}
player.sendMessage(ChatColor.YELLOW + "Items compacted into stacks!");
} else if (split[0].equalsIgnoreCase("/rg")
|| split[0].equalsIgnoreCase("/region")) {
if (split.length < 2) {
player.sendMessage(ChatColor.RED + "/region <define|claim|flag|delete|info|add|remove|list|save|load> ...");
return true;
}
String action = split[1];
String[] args = new String[split.length - 1];
System.arraycopy(split, 1, args, 0, split.length - 1);
handleRegionCommand(player, action, args);
} else if (split[0].equalsIgnoreCase("/reload")
&& plugin.hasPermission(player, "/reload")
&& split.length > 1) {
if (split[1].equalsIgnoreCase("WorldGuard")) {
LoggerToChatHandler handler = new LoggerToChatHandler(player);
handler.setLevel(Level.ALL);
Logger minecraftLogger = Logger.getLogger("Minecraft");
minecraftLogger.addHandler(handler);
try {
plugin.loadConfiguration();
plugin.postReload();
player.sendMessage("WorldGuard configuration reloaded.");
} catch (Throwable t) {
player.sendMessage("Error while reloading: "
+ t.getMessage());
} finally {
minecraftLogger.removeHandler(handler);
}
return true;
}
} else {
return false;
}
return true;
}
/**
* Handles a region command.
*
* @param player
* @param action
* @param args
*/
private void handleRegionCommand(Player player, String action, String[] args) {
if (!plugin.useRegions) {
player.sendMessage(ChatColor.RED + "Regions are disabled.");
return;
}
if (action.equalsIgnoreCase("define")) {
if (!canUseRegionCommand(player, "/regiondefine")) {
player.sendMessage(ChatColor.RED + "You don't have the /regiondefine permission.");
return;
}
if (args.length < 2) {
player.sendMessage(ChatColor.RED + "/region define <id> [owner1 [owner2 [owners...]]]");
return;
}
try {
String id = args[1].toLowerCase();
Plugin wePlugin = plugin.getServer().getPluginManager().getPlugin("WorldEdit");
if (plugin == null) {
player.sendMessage(ChatColor.RED + "WorldEdit must be installed and enabled as a plugin.");
return;
}
WorldEditPlugin worldEdit = (WorldEditPlugin)wePlugin;
WorldEditAPI api = worldEdit.getAPI();
LocalSession session = api.getSession(player);
Region weRegion = session.getRegion();
BlockVector min = weRegion.getMinimumPoint().toBlockVector();
BlockVector max = weRegion.getMaximumPoint().toBlockVector();
ProtectedRegion region = new ProtectedCuboidRegion(min, max);
if (args.length >= 3) {
region.setOwners(parseDomainString(args, 2));
}
plugin.regionManager.addRegion(id, region);
plugin.regionLoader.save(plugin.regionManager);
player.sendMessage(ChatColor.YELLOW + "Region saved as " + id + ".");
} catch (IncompleteRegionException e) {
player.sendMessage(ChatColor.RED + "You must first define an area in WorldEdit.");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
}
} else if (action.equalsIgnoreCase("claim")) {
if (!canUseRegionCommand(player, "/regionclaim")) {
player.sendMessage(ChatColor.RED + "You don't have the /regionclaim permission.");
return;
}
if (args.length < 1) {
player.sendMessage(ChatColor.RED + "/region claim <id>");
return;
}
try {
String id = args[1].toLowerCase();
Plugin wePlugin = plugin.getServer().getPluginManager().getPlugin("WorldEdit");
if (plugin == null) {
player.sendMessage(ChatColor.RED + "WorldEdit must be installed and enabled as a plugin.");
return;
}
ProtectedRegion existing = plugin.regionManager.getRegion(id);
if (existing != null) {
if (!existing.getOwners().contains(plugin.wrapPlayer(player))) {
player.sendMessage(ChatColor.RED + "You don't own this region.");
return;
}
}
WorldEditPlugin worldEdit = (WorldEditPlugin)wePlugin;
WorldEditAPI api = worldEdit.getAPI();
LocalSession session = api.getSession(player);
Region weRegion = session.getRegion();
BlockVector min = weRegion.getMinimumPoint().toBlockVector();
BlockVector max = weRegion.getMaximumPoint().toBlockVector();
ProtectedRegion region = new ProtectedCuboidRegion(min, max);
if (plugin.regionManager.overlapsUnownedRegion(region, plugin.wrapPlayer(player))) {
player.sendMessage(ChatColor.RED + "This region overlaps with someone else's region.");
return;
}
region.getOwners().addPlayer(player.getName());
plugin.regionManager.addRegion(id, region);
plugin.regionLoader.save(plugin.regionManager);
player.sendMessage(ChatColor.YELLOW + "Region saved as " + id + ".");
} catch (IncompleteRegionException e) {
player.sendMessage(ChatColor.RED + "You must first define an area in WorldEdit.");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
}
} else if (action.equalsIgnoreCase("flag")) {
if (!canUseRegionCommand(player, "/regiondefine")) {
player.sendMessage(ChatColor.RED + "You don't have the /regiondefine permission.");
return;
}
if (args.length < 4) {
player.sendMessage(ChatColor.RED + "/region flag <id> <flag> <none|allow|deny>");
return;
}
try {
String id = args[1].toLowerCase();
String flagStr = args[2];
String stateStr = args[3];
ProtectedRegion region = plugin.regionManager.getRegion(id);
if (region == null) {
player.sendMessage(ChatColor.RED + "Could not find a region by that ID.");
return;
}
AreaFlags.State state = null;
if (stateStr.equalsIgnoreCase("allow")) {
state = AreaFlags.State.ALLOW;
} else if (stateStr.equalsIgnoreCase("deny")) {
state = AreaFlags.State.DENY;
} else if (stateStr.equalsIgnoreCase("none")) {
state = AreaFlags.State.NONE;
} else {
player.sendMessage(ChatColor.RED + "Acceptable states: allow, deny, none");
return;
}
AreaFlags flags = region.getFlags();
if (flagStr.equalsIgnoreCase("build")) {
flags.allowBuild = state;
} else if (flagStr.equalsIgnoreCase("pvp")) {
flags.allowPvP = state;
} else if (flagStr.equalsIgnoreCase("tnt")) {
flags.allowTNT = state;
} else if (flagStr.equalsIgnoreCase("lighter")) {
flags.allowLighter = state;
} else {
player.sendMessage(ChatColor.RED + "Acceptable flags: build, pvp, tnt, lighter");
return;
}
plugin.regionLoader.save(plugin.regionManager);
player.sendMessage(ChatColor.YELLOW + "Region '" + id + "' updated.");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
}
/*} else if (action.equalsIgnoreCase("priority")) {
if (!canUseRegionCommand(player, "/regiondefine")) {
player.sendMessage(ChatColor.RED + "You don't have the /regiondefine permission.");
return;
}
if (args.length < 3) {
player.sendMessage(ChatColor.RED + "/region priority <id> <priority>");
return;
}
try {
String id = args[1].toLowerCase();
int priority = 0;
try {
priority = Integer.parseInt(args[2]);
} catch (NumberFormatException e) {
player.sendMessage(ChatColor.RED + "The priority must be a number.");
return;
}
ProtectedRegion region = plugin.regionManager.getRegion(id);
if (region == null) {
player.sendMessage(ChatColor.RED + "Could not find a region by that ID.");
return;
}
region.setPriority(priority);
plugin.regionLoader.save(plugin.regionManager);
player.sendMessage(ChatColor.YELLOW + "Region '" + id + "' updated.");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
}*/
} else if (action.equalsIgnoreCase("info")) {
if (!canUseRegionCommand(player, "/regioninfo")) {
player.sendMessage(ChatColor.RED + "You don't have the /regioninfo permission.");
return;
}
if (args.length < 2) {
player.sendMessage(ChatColor.RED + "/region info <id>");
return;
}
String id = args[1].toLowerCase();
if (!plugin.regionManager.hasRegion(id)) {
player.sendMessage(ChatColor.RED + "A region with ID '"
+ id + "' doesn't exist.");
return;
}
ProtectedRegion region = plugin.regionManager.getRegion(id);
AreaFlags flags = region.getFlags();
DefaultDomain domain = region.getOwners();
player.sendMessage(ChatColor.YELLOW + "Region ID: " + id);
player.sendMessage(ChatColor.GRAY + "Type: " + region.getClass().getCanonicalName());
player.sendMessage(ChatColor.GRAY + "Priority: " + region.getPriority());
player.sendMessage(ChatColor.BLUE + "Build: " + flags.allowBuild.name());
player.sendMessage(ChatColor.BLUE + "PvP: " + flags.allowPvP.name());
player.sendMessage(ChatColor.BLUE + "TNT: " + flags.allowTNT.name());
player.sendMessage(ChatColor.BLUE + "Lighter: " + flags.allowLighter.name());
player.sendMessage(ChatColor.LIGHT_PURPLE + "Players: " + domain.toPlayersString());
player.sendMessage(ChatColor.LIGHT_PURPLE + "Groups: " + domain.toGroupsString());
} else if (action.equalsIgnoreCase("addowner")) {
if (!canUseRegionCommand(player, "/regiondefine")
&& !canUseRegionCommand(player, "/regionclaim")) {
player.sendMessage(ChatColor.RED + "You don't have the /regiondefine permission.");
return;
}
if (args.length < 2) {
player.sendMessage(ChatColor.RED + "/region addowner <id>");
return;
}
try {
String id = args[1].toLowerCase();
if (!plugin.regionManager.hasRegion(id)) {
player.sendMessage(ChatColor.RED + "A region with ID '"
+ id + "' doesn't exist.");
return;
}
ProtectedRegion existing = plugin.regionManager.getRegion(id);
if (!canUseRegionCommand(player, "/regiondefine")
&& !existing.getOwners().contains(plugin.wrapPlayer(player))) {
player.sendMessage(ChatColor.RED + "You don't own this region.");
return;
}
addToDomain(existing.getOwners(), args, 2);
plugin.regionLoader.save(plugin.regionManager);
player.sendMessage(ChatColor.YELLOW + "Region updated!");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
}
} else if (action.equalsIgnoreCase("removeowner")) {
if (!canUseRegionCommand(player, "/regiondefine")
&& !canUseRegionCommand(player, "/regionclaim")) {
player.sendMessage(ChatColor.RED + "You don't have the /regiondefine permission.");
return;
}
if (args.length < 2) {
player.sendMessage(ChatColor.RED + "/region removeowner <id>");
return;
}
try {
String id = args[1].toLowerCase();
if (!plugin.regionManager.hasRegion(id)) {
player.sendMessage(ChatColor.RED + "A region with ID '"
+ id + "' doesn't exist.");
return;
}
ProtectedRegion existing = plugin.regionManager.getRegion(id);
if (!canUseRegionCommand(player, "/regiondefine")
&& !existing.getOwners().contains(plugin.wrapPlayer(player))) {
player.sendMessage(ChatColor.RED + "You don't own this region.");
return;
}
removeFromDomain(existing.getOwners(), args, 2);
plugin.regionLoader.save(plugin.regionManager);
player.sendMessage(ChatColor.YELLOW + "Region updated!");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
}
} else if (action.equalsIgnoreCase("list")) {
if (!canUseRegionCommand(player, "/regiondefine")) {
player.sendMessage(ChatColor.RED + "You don't have the /regiondefine permission.");
return;
}
int page = 0;
if (args.length >= 2) {
try {
page = Math.max(0, Integer.parseInt(args[1]) - 1);
} catch (NumberFormatException e) {
page = 0;
}
}
Map<String,ProtectedRegion> regions = plugin.regionManager.getRegions();
int size = regions.size();
int pages = (int)Math.ceil(size / (float)CMD_LIST_SIZE);
String[] regionIDList = new String[size];
int index = 0;
for (String id : regions.keySet()) {
regionIDList[index] = id;
index++;
}
Arrays.sort(regionIDList);
player.sendMessage(ChatColor.RED + "Regions (page "
+ (page + 1) + " of " + pages + "):");
if (page < pages) {
for (int i = page * CMD_LIST_SIZE; i < page * CMD_LIST_SIZE + CMD_LIST_SIZE; i++) {
if (i >= size) break;
player.sendMessage(ChatColor.YELLOW.toString() + (i + 1) + ". " + regionIDList[i]);
}
}
} else if (action.equalsIgnoreCase("delete")) {
if (!canUseRegionCommand(player, "/regiondelete")
&& !canUseRegionCommand(player, "/regionclaim")) {
player.sendMessage(ChatColor.RED + "You don't have the /regiondelete permission.");
return;
}
if (args.length < 2) {
player.sendMessage(ChatColor.RED + "/region delete <id>");
return;
}
try {
String id = args[1].toLowerCase();
if (!plugin.regionManager.hasRegion(id)) {
player.sendMessage(ChatColor.RED + "A region with ID '"
+ id + "' doesn't exist.");
return;
}
ProtectedRegion existing = plugin.regionManager.getRegion(id);
if (!canUseRegionCommand(player, "/regiondelete")
&& !existing.getOwners().contains(plugin.wrapPlayer(player))) {
player.sendMessage(ChatColor.RED + "You don't own this region.");
return;
}
plugin.regionManager.removeRegion(id);
plugin.regionLoader.save(plugin.regionManager);
player.sendMessage(ChatColor.YELLOW + "Region removed!");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
}
} else if (action.equalsIgnoreCase("save")) {
if (!canUseRegionCommand(player, "/regionsave")) {
player.sendMessage(ChatColor.RED + "You don't have the /regionsave permission.");
return;
}
try {
plugin.regionLoader.save(plugin.regionManager);
player.sendMessage(ChatColor.YELLOW + "Region database saved to file!");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
}
} else if (action.equalsIgnoreCase("load")) {
if (!canUseRegionCommand(player, "/regionload")) {
player.sendMessage(ChatColor.RED + "You don't have the /regionload permission.");
return;
}
try {
plugin.regionLoader.load(plugin.regionManager);
player.sendMessage(ChatColor.YELLOW + "Region database loaded from file!");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to load: "
+ e.getMessage());
}
} else {
player.sendMessage(ChatColor.RED + "/region <define|claim|flag|delete|info|addowner|removeowner|list|save|load> ...");
}
}
/**
* Checks for the command or /region.
*
* @param player
* @param cmd
* @return
*/
private boolean canUseRegionCommand(Player player, String cmd) {
return plugin.hasPermission(player, "/region")
|| plugin.hasPermission(player, cmd);
}
/**
* Parse a group/player DefaultDomain specification for areas.
*
* @param domain
* @param split
* @param startIndex
*/
private static void addToDomain(DefaultDomain domain,
String[] split, int startIndex) {
for (int i = startIndex; i < split.length; i++) {
String s = split[i];
Matcher m = groupPattern.matcher(s);
if (m.matches()) {
domain.addGroup(m.group(1));
} else {
domain.addPlayer(s);
}
}
}
/**
* Parse a group/player DefaultDomain specification for areas.
*
* @param domain
* @param split
* @param startIndex
*/
private static void removeFromDomain(DefaultDomain domain,
String[] split, int startIndex) {
for (int i = startIndex; i < split.length; i++) {
String s = split[i];
Matcher m = groupPattern.matcher(s);
if (m.matches()) {
domain.removeGroup(m.group(1));
} else {
domain.removePlayer(s);
}
}
}
/**
* Parse a group/player DefaultDomain specification for areas.
*
* @param split
* @param startIndex
* @return
*/
private static DefaultDomain parseDomainString(String[] split, int startIndex) {
DefaultDomain domain = new DefaultDomain();
for (int i = startIndex; i < split.length; i++) {
String s = split[i];
Matcher m = groupPattern.matcher(s);
if (m.matches()) {
domain.addGroup(m.group(1));
} else {
domain.addPlayer(s);
}
}
return domain;
}
}
@@ -19,29 +19,47 @@
package com.sk89q.worldguard.bukkit;
import static com.sk89q.worldguard.bukkit.BukkitUtil.matchSinglePlayer;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bukkit.command.Command;
import org.bukkit.entity.Player;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.event.Event.Priority;
import org.bukkit.event.Event;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.PluginLoader;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.config.Configuration;
import com.sk89q.bukkit.migration.PermissionsResolverManager;
import com.sk89q.bukkit.migration.PermissionsResolverServerListener;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.blocks.ItemType;
import com.sk89q.worldedit.bukkit.WorldEditAPI;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldguard.blacklist.Blacklist;
import com.sk89q.worldguard.blacklist.BlacklistLogger;
import com.sk89q.worldguard.blacklist.loggers.*;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.protection.*;
/**
@@ -52,6 +70,9 @@ import com.sk89q.worldguard.protection.*;
public class WorldGuardPlugin extends JavaPlugin {
private static final Logger logger = Logger.getLogger("Minecraft.WorldGuard");
private static Pattern groupPattern = Pattern.compile("^[gG]:(.+)$");
private static int CMD_LIST_SIZE = 9;
private final WorldGuardPlayerListener playerListener =
new WorldGuardPlayerListener(this);
private final WorldGuardBlockListener blockListener =
@@ -101,7 +122,8 @@ public class WorldGuardPlugin extends JavaPlugin {
boolean kickOnDeath;
boolean exactRespawn;
boolean teleportToHome;
boolean disableContactDamage;
boolean disableFallDamage;
boolean disableLavaDamage;
boolean disableFireDamage;
@@ -112,6 +134,16 @@ public class WorldGuardPlugin extends JavaPlugin {
boolean useRegions;
int regionWand = 287;
/**
* Construct the plugin.
*
* @param pluginLoader
* @param instance
* @param desc
* @param folder
* @param plugin
* @param cLoader
*/
public WorldGuardPlugin(PluginLoader pluginLoader, Server instance,
PluginDescriptionFile desc, File folder, File plugin, ClassLoader cLoader) {
super(pluginLoader, instance, desc, folder, plugin, cLoader);
@@ -132,12 +164,21 @@ public class WorldGuardPlugin extends JavaPlugin {
registerEvents();
}
/**
* Called on plugin enable.
*/
public void onEnable() {
}
/**
* Called on plugin disable.
*/
public void onDisable() {
}
/**
* Register used events.
*/
private void registerEvents() {
registerEvent(Event.Type.BLOCK_DAMAGED, blockListener, Priority.Normal);
registerEvent(Event.Type.BLOCK_FLOW, blockListener, Priority.Normal);
@@ -147,11 +188,12 @@ public class WorldGuardPlugin extends JavaPlugin {
registerEvent(Event.Type.BLOCK_PLACED, blockListener, Priority.Normal);
registerEvent(Event.Type.BLOCK_RIGHTCLICKED, blockListener, Priority.Normal);
registerEvent(Event.Type.ENTITY_DAMAGED, entityListener, Priority.Normal);
registerEvent(Event.Type.ENTITY_DAMAGEDBY_PROJECTILE, entityListener, Priority.Normal);
registerEvent(Event.Type.ENTITY_DAMAGEDBY_BLOCK, entityListener, Priority.Normal);
registerEvent(Event.Type.ENTITY_DAMAGEDBY_ENTITY, entityListener, Priority.Normal);
registerEvent(Event.Type.ENTITY_EXPLODE, entityListener, Priority.Normal);
registerEvent(Event.Type.PLAYER_COMMAND, playerListener, Priority.Normal);
registerEvent(Event.Type.PLAYER_ITEM, playerListener, Priority.Normal);
registerEvent(Event.Type.PLAYER_JOIN, playerListener, Priority.Normal);
registerEvent(Event.Type.PLAYER_LOGIN, playerListener, Priority.Normal);
@@ -160,10 +202,22 @@ public class WorldGuardPlugin extends JavaPlugin {
permsListener.register(this);
}
/**
* Register an event.
*
* @param type
* @param listener
* @param priority
*/
private void registerEvent(Event.Type type, Listener listener, Priority priority) {
getServer().getPluginManager().registerEvent(type, listener, priority, this);
}
/**
* Create a default configuration file from the .jar.
*
* @param name
*/
private void createDefaultConfiguration(String name) {
File actual = new File(getDataFolder(), name);
if (!actual.exists()) {
@@ -201,7 +255,7 @@ public class WorldGuardPlugin extends JavaPlugin {
}
/**
* Load the configuration
* Load the configuration.
*/
public void loadConfiguration() {
Configuration config = getConfiguration();
@@ -241,6 +295,7 @@ public class WorldGuardPlugin extends JavaPlugin {
disableFireDamage = config.getBoolean("player-damage.disable-fire-damage", false);
disableDrowningDamage = config.getBoolean("player-damage.disable-water-damage", false);
disableSuffocationDamage = config.getBoolean("player-damage.disable-suffocation-damage", false);
disableContactDamage = config.getBoolean("player-damage.disable-contact-damage", false);
teleportOnSuffocation = config.getBoolean("player-damage.teleport-on-suffocation", false);
useRegions = config.getBoolean("regions.enable", true);
@@ -358,13 +413,805 @@ public class WorldGuardPlugin extends JavaPlugin {
} catch (NullPointerException e) { // Thrown if loaded too early
}
}
/**
* Handles a command.
*/
public boolean onCommand(Player player, Command cmd, String commandLabel, String[] args) {
try {
return handleCommand(player, cmd.getName(), args);
} catch (InsufficientArgumentsException e) {
if (e.getHelp() != null) {
player.sendMessage(ChatColor.RED + e.getHelp());
return true;
} else {
return false;
}
} catch (InsufficientPermissionsException e) {
player.sendMessage(ChatColor.RED + "You don't have sufficient permission.");
return true;
}
}
/**
* Internal method to handle a command.
*
* @param player
* @param cmd
* @param args
* @return
* @throws InsufficientArgumentsException
* @throws InsufficientPermissionsException
*/
private boolean handleCommand(Player player, String cmd, String[] args)
throws InsufficientArgumentsException, InsufficientPermissionsException {
if (cmd.equalsIgnoreCase("stopfire")) {
checkPermission(player, "/stopfire");
checkArgs(args, 0, 0);
if (!fireSpreadDisableToggle) {
getServer().broadcastMessage(ChatColor.YELLOW
+ "Fire spread has been globally disabled by " + player.getName() + ".");
} else {
player.sendMessage(ChatColor.YELLOW + "Fire spread was already globally disabled.");
}
fireSpreadDisableToggle = true;
return true;
}
if (cmd.equalsIgnoreCase("allowfire")) {
checkPermission(player, "/stopfire");
checkArgs(args, 0, 0);
if (fireSpreadDisableToggle) {
getServer().broadcastMessage(ChatColor.YELLOW
+ "Fire spread has been globally re-enabled by " + player.getName() + ".");
} else {
player.sendMessage(ChatColor.YELLOW + "Fire spread was already globally enabled.");
}
fireSpreadDisableToggle = false;
return true;
}
if (cmd.equalsIgnoreCase("god")) {
checkPermission(player, "/god");
checkArgs(args, 0, 1);
// Allow setting other people invincible
if (args.length > 1) {
if (!hasPermission(player, "/godother")) {
player.sendMessage(ChatColor.RED + "You don't have permission to make others invincible.");
return true;
}
Player other = matchSinglePlayer(getServer(), args[1]);
if (other == null) {
player.sendMessage(ChatColor.RED + "Player not found.");
} else {
if (!invinciblePlayers.contains(other.getName())) {
invinciblePlayers.add(other.getName());
player.sendMessage(ChatColor.YELLOW + other.getName() + " is now invincible!");
other.sendMessage(ChatColor.YELLOW + player.getName() + " has made you invincible!");
} else {
invinciblePlayers.remove(other.getName());
player.sendMessage(ChatColor.YELLOW + other.getName() + " is no longer invincible.");
other.sendMessage(ChatColor.YELLOW + player.getName() + " has taken away your invincibility.");
}
}
// Invincibility for one's self
} else {
if (!invinciblePlayers.contains(player.getName())) {
invinciblePlayers.add(player.getName());
player.sendMessage(ChatColor.YELLOW + "You are now invincible!");
} else {
invinciblePlayers.remove(player.getName());
player.sendMessage(ChatColor.YELLOW + "You are no longer invincible.");
}
}
return true;
}
if (cmd.equalsIgnoreCase("heal")) {
checkPermission(player, "/heal");
checkArgs(args, 0, 1);
// Allow healing other people
if (args.length > 1) {
if (!hasPermission(player, "/healother")) {
player.sendMessage(ChatColor.RED + "You don't have permission to heal others.");
return true;
}
Player other = matchSinglePlayer(getServer(), args[1]);
if (other == null) {
player.sendMessage(ChatColor.RED + "Player not found.");
} else {
other.setHealth(20);
player.sendMessage(ChatColor.YELLOW + other.getName() + " has been healed!");
other.sendMessage(ChatColor.YELLOW + player.getName() + " has healed you!");
}
} else {
player.setHealth(20);
player.sendMessage(ChatColor.YELLOW + "You have been healed!");
}
return true;
}
if (cmd.equalsIgnoreCase("slay")) {
checkPermission(player, "/slay");
checkArgs(args, 0, 1);
// Allow killing other people
if (args.length > 1) {
if (!hasPermission(player, "/slayother")) {
player.sendMessage(ChatColor.RED + "You don't have permission to kill others.");
return true;
}
Player other = matchSinglePlayer(getServer(), args[1]);
if (other == null) {
player.sendMessage(ChatColor.RED + "Player not found.");
} else {
other.setHealth(0);
player.sendMessage(ChatColor.YELLOW + other.getName() + " has been killed!");
other.sendMessage(ChatColor.YELLOW + player.getName() + " has killed you!");
}
} else {
player.setHealth(0);
player.sendMessage(ChatColor.YELLOW + "You have committed suicide!");
}
return true;
}
if (cmd.equalsIgnoreCase("stack")) {
checkPermission(player, "stack");
checkArgs(args, 0, 0);
ItemStack[] items = player.getInventory().getContents();
int len = items.length;
int affected = 0;
for (int i = 0; i < len; i++) {
ItemStack item = items[i];
// Avoid infinite stacks and stacks with durability
if (item == null || item.getAmount() <= 0
|| ItemType.shouldNotStack(item.getTypeId())) {
continue;
}
// Ignore buckets
if (item.getTypeId() >= 325 && item.getTypeId() <= 327) {
continue;
}
if (item.getAmount() < 64) {
int needed = 64 - item.getAmount(); // Number of needed items until 64
// Find another stack of the same type
for (int j = i + 1; j < len; j++) {
ItemStack item2 = items[j];
// Avoid infinite stacks and stacks with durability
if (item2 == null || item2.getAmount() <= 0
|| ItemType.shouldNotStack(item.getTypeId())) {
continue;
}
// Same type?
// Blocks store their color in the damage value
if (item2.getTypeId() == item.getTypeId() &&
(!ItemType.usesDamageValue(item.getTypeId())
|| item.getDamage() == item2.getDamage())) {
// This stack won't fit in the parent stack
if (item2.getAmount() > needed) {
item.setAmount(64);
item2.setAmount(item2.getAmount() - needed);
break;
// This stack will
} else {
items[j] = null;
item.setAmount(item.getAmount() + item2.getAmount());
needed = 64 - item.getAmount();
}
affected++;
}
}
}
}
if (affected > 0) {
player.getInventory().setContents(items);
}
player.sendMessage(ChatColor.YELLOW + "Items compacted into stacks!");
return true;
}
if (cmd.equalsIgnoreCase("locate")) {
checkPermission(player, "locate");
checkArgs(args, 0, 3);
if (args.length == 2) {
String name = args[1];
Player target = BukkitUtil.matchSinglePlayer(getServer(), name);
if (target != null) {
player.setCompassTarget(target.getLocation());
player.sendMessage(ChatColor.YELLOW + "Compass target set to " + target.getName() + ".");
} else {
player.sendMessage(ChatColor.RED + "Could not find player.");
}
} else if (args.length == 4) {
try {
Location loc = new Location(
player.getWorld(),
Integer.parseInt(args[1]),
Integer.parseInt(args[2]),
Integer.parseInt(args[3])
);
player.setCompassTarget(loc);
player.sendMessage(ChatColor.YELLOW + "Compass target set to "
+ loc.getBlockX() + ","
+ loc.getBlockY() + ","
+ loc.getBlockZ() + ".");
} catch (NumberFormatException e) {
player.sendMessage(ChatColor.RED + "Invalid number specified");
}
} else if (args.length == 1) {
player.setCompassTarget(player.getWorld().getSpawnLocation());
player.sendMessage(ChatColor.YELLOW + "Compass reset to the spawn location.");
} else {
return false;
}
return true;
}
if (cmd.equalsIgnoreCase("region")) {
checkArgs(args, 1, -1);
String action = args[1];
String[] subArgs = new String[args.length - 1];
System.arraycopy(args, 1, subArgs, 0, args.length - 1);
return handleRegionCommand(player, action, subArgs);
}
if (cmd.equalsIgnoreCase("reloadwg")) {
checkPermission(player, "reloadwg");
checkArgs(args, 0, 0);
LoggerToChatHandler handler = new LoggerToChatHandler(player);
handler.setLevel(Level.ALL);
Logger minecraftLogger = Logger.getLogger("Minecraft");
minecraftLogger.addHandler(handler);
try {
loadConfiguration();
postReload();
player.sendMessage("WorldGuard configuration reloaded.");
} catch (Throwable t) {
player.sendMessage("Error while reloading: "
+ t.getMessage());
} finally {
minecraftLogger.removeHandler(handler);
}
return true;
}
return false;
}
/**
* Handles a region command.
*
* @param player
* @param action
* @param args
* @throws InsufficientPermissionsException
* @throws InsufficientArgumentsException
*/
private boolean handleRegionCommand(Player player, String action, String[] args)
throws InsufficientPermissionsException, InsufficientArgumentsException {
if (!useRegions) {
player.sendMessage(ChatColor.RED + "Regions are disabled.");
return true;
}
Plugin wePlugin = getServer().getPluginManager().getPlugin("WorldEdit");
if (wePlugin == null) {
player.sendMessage(ChatColor.RED + "WorldEdit must be installed and enabled!");
return true;
}
if (action.equalsIgnoreCase("define")) {
checkRegionPermission(player, "/regiondefine");
checkArgs(args, 1, -1, "/region define <id> [owner1 [owner2 [owners...]]]");
try {
String id = args[1].toLowerCase();
WorldEditPlugin worldEdit = (WorldEditPlugin)wePlugin;
WorldEditAPI api = worldEdit.getAPI();
LocalSession session = api.getSession(player);
Region weRegion = session.getRegion();
BlockVector min = weRegion.getMinimumPoint().toBlockVector();
BlockVector max = weRegion.getMaximumPoint().toBlockVector();
ProtectedRegion region = new ProtectedCuboidRegion(min, max);
if (args.length >= 2) {
region.setOwners(parseDomainString(args, 2));
}
regionManager.addRegion(id, region);
regionLoader.save(regionManager);
player.sendMessage(ChatColor.YELLOW + "Region saved as " + id + ".");
} catch (IncompleteRegionException e) {
player.sendMessage(ChatColor.RED + "You must first define an area in WorldEdit.");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
}
return true;
}
if (action.equalsIgnoreCase("claim")) {
checkRegionPermission(player, "/regionclaim");
checkArgs(args, 1, 1, "/region claim <id>");
try {
String id = args[1].toLowerCase();
ProtectedRegion existing = regionManager.getRegion(id);
if (existing != null) {
if (!existing.getOwners().contains(wrapPlayer(player))) {
player.sendMessage(ChatColor.RED + "You don't own this region.");
return true;
}
}
WorldEditPlugin worldEdit = (WorldEditPlugin)wePlugin;
WorldEditAPI api = worldEdit.getAPI();
LocalSession session = api.getSession(player);
Region weRegion = session.getRegion();
BlockVector min = weRegion.getMinimumPoint().toBlockVector();
BlockVector max = weRegion.getMaximumPoint().toBlockVector();
ProtectedRegion region = new ProtectedCuboidRegion(min, max);
if (regionManager.overlapsUnownedRegion(region, wrapPlayer(player))) {
player.sendMessage(ChatColor.RED + "This region overlaps with someone else's region.");
return true;
}
region.getOwners().addPlayer(player.getName());
regionManager.addRegion(id, region);
regionLoader.save(regionManager);
player.sendMessage(ChatColor.YELLOW + "Region saved as " + id + ".");
} catch (IncompleteRegionException e) {
player.sendMessage(ChatColor.RED + "You must first define an area in WorldEdit.");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
}
return true;
}
if (action.equalsIgnoreCase("flag")) {
checkRegionPermission(player, "/regiondefine");
checkArgs(args, 3, 3, "/region flag <id> <flag> <none|allow|deny>");
try {
String id = args[1].toLowerCase();
String flagStr = args[2];
String stateStr = args[3];
ProtectedRegion region = regionManager.getRegion(id);
if (region == null) {
player.sendMessage(ChatColor.RED + "Could not find a region by that ID.");
return true;
}
AreaFlags.State state = null;
if (stateStr.equalsIgnoreCase("allow")) {
state = AreaFlags.State.ALLOW;
} else if (stateStr.equalsIgnoreCase("deny")) {
state = AreaFlags.State.DENY;
} else if (stateStr.equalsIgnoreCase("none")) {
state = AreaFlags.State.NONE;
} else {
player.sendMessage(ChatColor.RED + "Acceptable states: allow, deny, none");
return true;
}
AreaFlags flags = region.getFlags();
if (flagStr.equalsIgnoreCase("build")) {
flags.allowBuild = state;
} else if (flagStr.equalsIgnoreCase("pvp")) {
flags.allowPvP = state;
} else if (flagStr.equalsIgnoreCase("tnt")) {
flags.allowTNT = state;
} else if (flagStr.equalsIgnoreCase("lighter")) {
flags.allowLighter = state;
} else {
player.sendMessage(ChatColor.RED + "Acceptable flags: build, pvp, tnt, lighter");
return true;
}
regionLoader.save(regionManager);
player.sendMessage(ChatColor.YELLOW + "Region '" + id + "' updated.");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
}
return true;
}
if (action.equalsIgnoreCase("info")) {
checkRegionPermission(player, "/regioninfo");
checkArgs(args, 1, 1, "/region info <id>");
String id = args[1].toLowerCase();
if (!regionManager.hasRegion(id)) {
player.sendMessage(ChatColor.RED + "A region with ID '"
+ id + "' doesn't exist.");
return true;
}
ProtectedRegion region = regionManager.getRegion(id);
AreaFlags flags = region.getFlags();
DefaultDomain domain = region.getOwners();
player.sendMessage(ChatColor.YELLOW + "Region ID: " + id);
player.sendMessage(ChatColor.GRAY + "Type: " + region.getClass().getCanonicalName());
player.sendMessage(ChatColor.GRAY + "Priority: " + region.getPriority());
player.sendMessage(ChatColor.BLUE + "Build: " + flags.allowBuild.name());
player.sendMessage(ChatColor.BLUE + "PvP: " + flags.allowPvP.name());
player.sendMessage(ChatColor.BLUE + "TNT: " + flags.allowTNT.name());
player.sendMessage(ChatColor.BLUE + "Lighter: " + flags.allowLighter.name());
player.sendMessage(ChatColor.LIGHT_PURPLE + "Players: " + domain.toPlayersString());
player.sendMessage(ChatColor.LIGHT_PURPLE + "Groups: " + domain.toGroupsString());
return true;
}
if (action.equalsIgnoreCase("addowner")) {
if (!hasPermission(player, "/regionclaim")) {
checkRegionPermission(player, "/regiondefine");
}
checkArgs(args, 2, -1, "/region addowner <id> [owner1 [owner2 [owners...]]]");
try {
String id = args[1].toLowerCase();
if (!regionManager.hasRegion(id)) {
player.sendMessage(ChatColor.RED + "A region with ID '"
+ id + "' doesn't exist.");
return true;
}
ProtectedRegion existing = regionManager.getRegion(id);
if (!canUseRegionCommand(player, "/regiondefine")
&& !existing.getOwners().contains(wrapPlayer(player))) {
player.sendMessage(ChatColor.RED + "You don't own this region.");
return true;
}
addToDomain(existing.getOwners(), args, 2);
regionLoader.save(regionManager);
player.sendMessage(ChatColor.YELLOW + "Region updated!");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
}
return true;
}
if (action.equalsIgnoreCase("removeowner")) {
if (!hasPermission(player, "/regionclaim")) {
checkRegionPermission(player, "/regiondefine");
}
checkArgs(args, 2, -1, "/region removeowner <id> [owner1 [owner2 [owners...]]]");
try {
String id = args[1].toLowerCase();
if (!regionManager.hasRegion(id)) {
player.sendMessage(ChatColor.RED + "A region with ID '"
+ id + "' doesn't exist.");
return true;
}
ProtectedRegion existing = regionManager.getRegion(id);
if (!canUseRegionCommand(player, "/regiondefine")
&& !existing.getOwners().contains(wrapPlayer(player))) {
player.sendMessage(ChatColor.RED + "You don't own this region.");
return true;
}
removeFromDomain(existing.getOwners(), args, 2);
regionLoader.save(regionManager);
player.sendMessage(ChatColor.YELLOW + "Region updated!");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
}
return true;
}
if (action.equalsIgnoreCase("list")) {
checkRegionPermission(player, "/regionlist");
checkArgs(args, 0, 1, "/region list [page]");
int page = 0;
if (args.length >= 2) {
try {
page = Math.max(0, Integer.parseInt(args[1]) - 1);
} catch (NumberFormatException e) {
page = 0;
}
}
Map<String,ProtectedRegion> regions = regionManager.getRegions();
int size = regions.size();
int pages = (int)Math.ceil(size / (float)CMD_LIST_SIZE);
String[] regionIDList = new String[size];
int index = 0;
for (String id : regions.keySet()) {
regionIDList[index] = id;
index++;
}
Arrays.sort(regionIDList);
player.sendMessage(ChatColor.RED + "Regions (page "
+ (page + 1) + " of " + pages + "):");
if (page < pages) {
for (int i = page * CMD_LIST_SIZE; i < page * CMD_LIST_SIZE + CMD_LIST_SIZE; i++) {
if (i >= size) break;
player.sendMessage(ChatColor.YELLOW.toString() + (i + 1) + ". " + regionIDList[i]);
}
}
return true;
}
if (action.equalsIgnoreCase("delete")) {
if (!hasPermission(player, "/regionclaim")) {
checkRegionPermission(player, "/regiondelete");
}
checkArgs(args, 0, 1, "/region delete <id>");
try {
String id = args[1].toLowerCase();
if (!regionManager.hasRegion(id)) {
player.sendMessage(ChatColor.RED + "A region with ID '"
+ id + "' doesn't exist.");
return true;
}
ProtectedRegion existing = regionManager.getRegion(id);
if (!canUseRegionCommand(player, "/regiondelete")
&& !existing.getOwners().contains(wrapPlayer(player))) {
player.sendMessage(ChatColor.RED + "You don't own this region.");
return true;
}
regionManager.removeRegion(id);
regionLoader.save(regionManager);
player.sendMessage(ChatColor.YELLOW + "Region removed!");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
}
return true;
}
if (action.equalsIgnoreCase("save")) {
checkRegionPermission(player, "/regionsave");
checkArgs(args, 0, 0, "/region save");
try {
regionLoader.save(regionManager);
player.sendMessage(ChatColor.YELLOW + "Region database saved to file!");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
}
return true;
}
if (action.equalsIgnoreCase("load")) {
checkRegionPermission(player, "/regionload");
checkArgs(args, 0, 0, "/region load");
try {
regionLoader.load(regionManager);
player.sendMessage(ChatColor.YELLOW + "Region database loaded from file!");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to load: "
+ e.getMessage());
}
return true;
}
return false;
}
/**
* Parse a group/player DefaultDomain specification for areas.
*
* @param domain
* @param split
* @param startIndex
*/
private static void addToDomain(DefaultDomain domain,
String[] split, int startIndex) {
for (int i = startIndex; i < split.length; i++) {
String s = split[i];
Matcher m = groupPattern.matcher(s);
if (m.matches()) {
domain.addGroup(m.group(1));
} else {
domain.addPlayer(s);
}
}
}
/**
* Parse a group/player DefaultDomain specification for areas.
*
* @param domain
* @param split
* @param startIndex
*/
private static void removeFromDomain(DefaultDomain domain,
String[] split, int startIndex) {
for (int i = startIndex; i < split.length; i++) {
String s = split[i];
Matcher m = groupPattern.matcher(s);
if (m.matches()) {
domain.removeGroup(m.group(1));
} else {
domain.removePlayer(s);
}
}
}
/**
* Parse a group/player DefaultDomain specification for areas.
*
* @param split
* @param startIndex
* @return
*/
private static DefaultDomain parseDomainString(String[] split, int startIndex) {
DefaultDomain domain = new DefaultDomain();
for (int i = startIndex; i < split.length; i++) {
String s = split[i];
Matcher m = groupPattern.matcher(s);
if (m.matches()) {
domain.addGroup(m.group(1));
} else {
domain.addPlayer(s);
}
}
return domain;
}
/**
* Checks for the command or /region.
*
* @param player
* @param cmd
* @return
*/
private boolean canUseRegionCommand(Player player, String cmd) {
return hasPermission(player, "/region")
|| hasPermission(player, cmd);
}
/**
* Checks to see if there are sufficient permissions, otherwise an exception
* is raised in that case.
*
* @param player
* @param permission
* @throws InsufficientPermissionsException
*/
private void checkRegionPermission(Player player, String permission)
throws InsufficientPermissionsException {
if (!hasPermission(player, "/region") && !hasPermission(player, permission)) {
throw new InsufficientPermissionsException();
}
}
/**
* Checks to see if there are sufficient permissions, otherwise an exception
* is raised in that case.
*
* @param player
* @param permission
* @throws InsufficientPermissionsException
*/
private void checkPermission(Player player, String permission)
throws InsufficientPermissionsException {
if (!hasPermission(player, permission)) {
throw new InsufficientPermissionsException();
}
}
/**
* Checks to make sure that there are enough but not too many arguments.
*
* @param args
* @param min
* @param max -1 for no maximum
* @throws InsufficientArgumentsException
*/
private void checkArgs(String[] args, int min, int max)
throws InsufficientArgumentsException {
if (args.length <= min || (max != -1 && args.length - 1 > max)) {
throw new InsufficientArgumentsException();
}
}
/**
* Checks to make sure that there are enough but not too many arguments.
*
* @param args
* @param min
* @param max -1 for no maximum
* @param help
* @throws InsufficientArgumentsException
*/
private void checkArgs(String[] args, int min, int max, String help)
throws InsufficientArgumentsException {
if (args.length <= min || (max != -1 && args.length - 1 > max)) {
throw new InsufficientArgumentsException(help);
}
}
boolean inGroup(Player player, String group) {
return perms.inGroup(player.getName(), group);
}
boolean hasPermission(Player player, String perm) {
return perms.hasPermission(player.getName(), perm);
return player.isOp() || perms.hasPermission(player.getName(), perm);
}
String[] getGroups(Player player) {
@@ -374,4 +1221,35 @@ public class WorldGuardPlugin extends JavaPlugin {
BukkitPlayer wrapPlayer(Player player) {
return new BukkitPlayer(this, player);
}
/**
* Thrown when a player has insufficient permissions.
*
* @author sk89q
*/
private static class InsufficientPermissionsException extends Exception {
private static final long serialVersionUID = 9087662707619954750L;
}
/**
* Thrown when a command wasn't given sufficient arguments.
*
* @author sk89q
*/
private static class InsufficientArgumentsException extends Exception {
private static final long serialVersionUID = 4153597953889773788L;
private final String help;
public InsufficientArgumentsException() {
help = null;
}
public InsufficientArgumentsException(String msg) {
this.help = msg;
}
public String getHelp() {
return help;
}
}
}
@@ -197,6 +197,10 @@ public class CSVDatabase implements ProtectionDatabase {
String[] parts = data.split(",");
for (String part : parts) {
if (part.trim().length() == 0) {
continue;
}
Matcher matcher = pattern.matcher(part);
if (!matcher.matches()) {