Compare commits

...
50 Commits
Author SHA1 Message Date
sk89q e09aa629c5 Updated CHANGELOG.txt. 2011-02-20 11:12:09 -08:00
sk89q 5c3fb9d2b7 Moved plugin initialization to onEnable. 2011-02-20 11:11:28 -08:00
Zenexer 1688276ff8 Updated for CraftBukkit 360 2011-02-20 12:35:18 -05:00
sk89q feb9ce6633 Re-added priority tree region manager implementation. Add and removal operations are not yet optimized. 2011-02-12 16:09:21 -08:00
sk89q 43489ca087 Changed how ApplicableRegionSet iterated over the region set, allowing it to be reused. 2011-02-12 15:49:55 -08:00
sk89q ce1a15e6ea Improved tick sync message suppression. 2011-02-05 14:00:06 -08:00
sk89q cc72d370ea Added suppress-tick-sync-warnings option. 2011-02-05 13:45:05 -08:00
sk89q d042185660 Added WorldGuardPlugin.canBuild(player, x, y, z) 2011-02-04 20:51:14 -08:00
sk89q e78b639018 Updated CHANGELOG.txt. 2011-02-02 23:37:40 -08:00
sk89q e8ea562b09 Changed 'release' target to also 'clean'. 2011-02-02 23:28:48 -08:00
sk89q 3b5a729ef3 Updated command handling for Bukkit. 2011-02-02 22:27:44 -08:00
sk89q ef7d487ec5 Updated burn event handling. 2011-02-02 22:21:44 -08:00
sk89q b379b8f022 Fixed suffocation disable option. 2011-02-02 21:03:33 -08:00
sk89q a31378c2c8 Changed disable-water-damage to disable-drowning-damage. 2011-02-02 20:51:52 -08:00
sk89q 0d2c2121bb 3.2.1 CHANGELOG.txt. 2011-01-31 14:36:33 -08:00
sk89q 21040b306a Updated for ItemStack change in Bukkit. 2011-01-31 14:35:46 -08:00
sk89q 541b1dbc44 Updated for 3.2. 2011-01-30 01:38:39 -08:00
sk89q 005ac41820 Added PvP default flag. 2011-01-30 01:36:59 -08:00
sk89q dd93772233 Fixed creeper explosion block with WorldGuard. 2011-01-30 01:16:16 -08:00
sk89q 428fc7e5f6 Fixed commands for the Bukkit commands change. 2011-01-30 01:03:57 -08:00
sk89q 5cf38cc885 Added redstone support to sponges, removed classic water. 2011-01-28 10:23:43 -08:00
sk89q 2f6b51e811 Fixed item durability disable for hoes. 2011-01-28 00:59:19 -08:00
sk89q 2f12da6bc6 Fixed error in a test. 2011-01-28 00:06:58 -08:00
sk89q 3985e157d9 Increased the priority of WorldGuard's event handling. 2011-01-24 09:17:20 -08:00
sk89q 3034eb5c12 Updated CHANGELOG.txt. 2011-01-24 09:12:56 -08:00
sk89q f666f1baa9 Fixed creeper and chest flag conflicting. 2011-01-24 09:12:32 -08:00
sk89q 3bbffa7b55 Updated for 3.1. 2011-01-24 02:40:17 -08:00
sk89q bc774e2596 Added /regionmembership permission. 2011-01-24 02:38:18 -08:00
sk89q 65a0e5c188 Possibly fixed projectile blocking in no-PvP zones. 2011-01-24 02:37:11 -08:00
sk89q 772d2cb580 Added ability to disable chest protection. 2011-01-24 02:35:33 -08:00
sk89q edc6825f83 Added WorldGuardPlugin.getRegionLoader(). 2011-01-22 01:41:18 -08:00
sk89q 7b2f9e0c86 Added Javadoc compilation. 2011-01-22 01:31:57 -08:00
sk89q 0fa4fa1862 Added getRegionManager() to WorldGuardPlugin. 2011-01-22 01:31:48 -08:00
sk89q 5be31ebb5c Fixed /god not working for others. 2011-01-21 19:49:22 -08:00
sk89q 962394b2ba Updated for 3.0b2. 2011-01-21 19:45:41 -08:00
sk89q 7cf7c5f44c Fixed issue where permissions were not loaded. 2011-01-21 19:45:06 -08:00
sk89q 5b494a09ec Fixed permissions for /stack, /locate, and /reloadwg. 2011-01-21 17:53:06 -08:00
sk89q 5cfac5da4a Marked version as beta1. 2011-01-21 15:41:25 -08:00
sk89q 203004951b Updated CHANGELOG.txt. 2011-01-21 15:26:43 -08:00
sk89q 765d7402fa Added parent-child relationships to regions, overhauled region code, added global build flag, improved flag support. 2011-01-21 15:23:11 -08:00
sk89q 151b5fc561 Fixed no-PvP zone messages being sent to the wrong person. 2011-01-21 01:37:40 -08:00
sk89q b489da7fe4 Fixed commands so that they work in a recent version of Bukkit. 2011-01-21 01:32:23 -08:00
sk89q 786a0f6f2b Reduced the number of imports in WorldGuardPlugin. 2011-01-21 01:27:18 -08:00
sk89q e2a940e01b Cleaned up code. 2011-01-21 01:21:36 -08:00
sk89q 518c3be478 Fixed errors in TestPlayer.java. 2011-01-21 01:13:20 -08:00
sk89q 6f3eaac008 Fixed NullPointerException in explode hook. 2011-01-21 00:51:50 -08:00
sk89q 31633e9466 Updated for 2.3.1. 2011-01-20 11:23:56 -08:00
sk89q 02913780ec Fixed the item durability disable setting changing the damage value on an empty hand. 2011-01-20 11:23:13 -08:00
sk89q f03a2263d8 Added checks for unchecked exceptions when resolving permissions. 2011-01-20 11:19:59 -08:00
sk89q a8cd832c28 Fixed various cast exceptions with the blacklist loggers. 2011-01-20 11:16:59 -08:00
31 changed files with 1831 additions and 665 deletions

No files matched your search

+52
View File
@@ -1,3 +1,55 @@
3.2.3:
- Updated for recent Bukkit builds. Thank Zenexer for changes.
- Added suppress-tick-sync-warnings.
3.2.2:
- Changed disable-water-damage to disable-drowning-damage.
- Fixed suffocation disable option.
- Fixed fire spread blocking.
- stopfire and allowfire now work in server console, just like in hMod.
3.2.1:
- Updated for recent Bukkit ItemStack change.
3.2:
- Added regions.default.pvp to control default PvP setting.
- Updated WorldGuard for the newer builds of Bukkit.
- Fixed creeper explosion blocking.
- Added redstone support to sponges, removed classic water.
- Fixed item durability disable for hoes.
3.1.2:
- Increased the priority of WorldGuard's event handling.
3.1.1:
- Fixed creeper and chest flag conflicting.
3.1:
- Added ability to disable chest protection. New configuration setting
(regions.build.chest-access) and new chest flag.
- Possibly fixed projectile blocking in no-PvP zones.
- Added /regionmembership permission that lets people only change
the owners and members of regions they own.
3.0b2:
- Fixed issue where built-in permissions were not (re)loaded.
- Fixed /god not working for others.
3.0b1:
- Added parent-child relationships to regions.
- Added global build flag.
- Improved flag support.
- Fixed no-PvP zone messages being sent to the wrong person.
- Fixed commands so that they work in a recent version of Bukkit.
- Fixed NullPointerException in explode hook.
2.3.1:
- Fixed various cast exceptions with the blacklist loggers.
- Added checks for unchecked exceptions when resolving permissions.
- Fixed the item durability disable setting changing the damage value on
an empty hand.
2.3:
- /god now works very well.
- Item (TNT, flint and steel, etc.) blocking should now work.
+39 -1
View File
@@ -1,3 +1,7 @@
----------------------------------------------------------------------------
WorldGuard License
----------------------------------------------------------------------------
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
@@ -162,4 +166,38 @@ General Public License ever published by the Free Software Foundation.
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.
Library.
----------------------------------------------------------------------------
PRTree License
----------------------------------------------------------------------------
Copyright (c) 2008-2010 Robert Olofsson.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the authors nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
+24 -5
View File
@@ -7,6 +7,15 @@
<property name="dist.dir" location="dist"/>
<property name="release.dir" location="release"/>
<property name="lib.dir" location="lib"/>
<property name="docs.dir" location="docs"/>
<fileset id="libs" dir="${lib.dir}">
<include name="truezip.jar" />
<include name="Bukkit.jar" />
<include name="Craftbukkit.jar" />
<include name="WorldEdit.jar" />
<include name="prtree.jar" />
</fileset>
<target name="init">
<mkdir dir="${build.dir}"/>
@@ -16,9 +25,7 @@
<target name="compile" depends="init">
<javac srcdir="${src.dir}" deprecation="true" includeantruntime="true" destdir="${build.dir}" debug="true">
<classpath>
<fileset dir="${lib.dir}">
<include name="*.jar"/>
</fileset>
<fileset refid="libs"/>
</classpath>
</javac>
</target>
@@ -38,7 +45,9 @@
<mkdir dir="${build.dir}/defaults"/>
<copy tofile="${build.dir}/defaults/config.yml" file="config.yml"/>
<copy tofile="${build.dir}/defaults/blacklist.txt" file="blacklist.txt"/>
<jar jarfile="${dist.dir}/WorldGuard.jar" basedir="${build.dir}" manifest="manifest.mf"/>
<jar jarfile="${dist.dir}/WorldGuard.jar" basedir="${build.dir}" manifest="manifest.mf">
<zipgroupfileset dir="lib" includes="prtree.jar" />
</jar>
</target>
<!-- Create the .jar -->
@@ -48,7 +57,7 @@
</target>
<!-- Build a release -->
<target name="release">
<target name="release" depends="clean">
<input message="Enter version:" addproperty="version"/>
<antcall target="jar"/>
<delete dir="${release.dir}"/>
@@ -66,11 +75,21 @@
<zip destfile="${release.dir}/worldguard-${version}-src.zip" basedir="${release.dir}" excludes="*.zip plugin.yml"/>
</target>
<!-- Javadoc -->
<target name="javadoc">
<javadoc access="public" author="true" destdir="${docs.dir}" doctitle="WorldGuard API" nodeprecated="false" nodeprecatedlist="false" noindex="false" nonavbar="false" notree="false" source="1.6" sourcepath="src" splitindex="true" use="true" version="true">
<classpath>
<fileset refid="libs"/>
</classpath>
</javadoc>
</target>
<!-- Clean the output -->
<target name="clean">
<delete dir="${build.dir}"/>
<delete dir="${dist.dir}"/>
<delete dir="${release.dir}"/>
<delete dir="${docs.dir}"/>
</target>
<!--<target name="-get-version-git" if="git-revision">
+7 -1
View File
@@ -21,14 +21,16 @@
summary-on-start: on
suppress-tick-sync-warnings: false
protection:
enforce-single-session: on
item-durability: on
simulation:
classic-water: off
sponge:
enable: on
redstone: off
radius: 3
physics:
@@ -70,6 +72,10 @@ player-damage:
regions:
enable: on
wand: 287
default:
build: true
chest-access: false
pvp: true
blacklist:
logging:
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project default="javadoc">
<target name="javadoc">
<javadoc access="public" author="true" classpath="P:\Projects\Minecraft\Libraries\GroupUsers.jar;P:\Projects\Minecraft\Libraries\jnbt.jar;P:\Projects\Minecraft\hMod\build\classes;P:\Projects\Minecraft\WorldEdit\build\classes;P:\Projects\Minecraft\Libraries\snakeyaml.jar;P:\Projects\Minecraft\Libraries\jopt-simple-3.2.jar;P:\Projects\Minecraft\Libraries\Permissions.jar;C:\Program Files\eclipse\plugins\org.hamcrest.core_1.1.0.v20090501071000.jar;P:\Projects\Minecraft\Libraries\json_simple-1.1.jar;P:\Projects\Minecraft\CraftBukkit\bin;P:\Projects\Minecraft\Libraries\truezip.jar;C:\Program Files\eclipse\plugins\org.junit_4.8.1.v4_8_1_v20100427-1100\junit.jar;P:\Projects\Minecraft\Bukkit\bin;P:\Projects\Minecraft\mc-dev" destdir="doc" doctitle="Worldguard API" nodeprecated="false" nodeprecatedlist="false" noindex="false" nonavbar="false" notree="false" packagenames="com.sk89q.worldguard.blacklist,com.sk89q.worldguard.domains,com.sk89q.worldguard.bukkit,com.sk89q.worldguard.protection,com.sk89q.worldguard.util,au.com.bytecode.opencsv,com.sk89q.worldguard,com.sk89q.worldguard.blacklist.loggers,com.sk89q.worldguard.blacklist.events" source="1.6" sourcepath="tests;src" splitindex="true" use="true" version="true"/>
</target>
</project>
BIN
View File
Binary file not shown.
+1 -1
View File
@@ -23,7 +23,7 @@ commands:
aliases: ;
region:
description: Adjust protected regions
usage: /<command> <define|claim|flag|delete|info|addowner|removeowner|list|save|load> ...
usage: /<command> <define|claim|setparent|flag|delete|info|addowner|removeowner|addmember|removemember|list|save|load> ...
aliases: rg, regions
locate:
description: Set your compass towards a person
@@ -19,7 +19,6 @@
package com.sk89q.worldguard;
import java.util.List;
import com.sk89q.worldedit.Vector;
public abstract class LocalPlayer {
@@ -0,0 +1,35 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard;
import java.util.logging.Filter;
import java.util.logging.Level;
import java.util.logging.LogRecord;
public class TickSyncDelayLoggerFilter implements Filter {
public boolean isLoggable(LogRecord record) {
if (record.getLevel() == Level.WARNING
&& record.getMessage().equals("Can't keep up! Did the system time change, or is the server overloaded?")) {
return false;
}
return true;
}
}
@@ -56,8 +56,8 @@ public class ConsoleLoggerHandler implements BlacklistLoggerHandler {
+ (comment != null ? " (" + comment + ")" : ""));
// Block interact
} else if (event instanceof BlockPlaceBlacklistEvent) {
BlockPlaceBlacklistEvent evt = (BlockPlaceBlacklistEvent)event;
} else if (event instanceof BlockInteractBlacklistEvent) {
BlockInteractBlacklistEvent evt = (BlockInteractBlacklistEvent)event;
logger.log(Level.INFO, "WorldGuard: " + event.getPlayer().getName()
+ " tried to interact with " + getFriendlyItemName(evt.getType())
+ (comment != null ? " (" + comment + ")" : ""));
@@ -172,7 +172,7 @@ public class DatabaseLoggerHandler implements BlacklistLoggerHandler {
// Use
} else if (event instanceof ItemUseBlacklistEvent) {
ItemDropBlacklistEvent evt = (ItemDropBlacklistEvent)event;
ItemUseBlacklistEvent evt = (ItemUseBlacklistEvent)event;
logEvent("USE", evt.getPlayer(), evt.getPlayer().getPosition(),
evt.getType(), comment);
@@ -255,12 +255,12 @@ public class FileLoggerHandler implements BlacklistLoggerHandler {
// Drop
} else if (event instanceof ItemDropBlacklistEvent) {
ItemAcquireBlacklistEvent evt = (ItemAcquireBlacklistEvent)event;
ItemDropBlacklistEvent evt = (ItemDropBlacklistEvent)event;
logEvent(event, "drop", evt.getType(), evt.getPosition(), comment);
// Use
} else if (event instanceof ItemUseBlacklistEvent) {
ItemDropBlacklistEvent evt = (ItemDropBlacklistEvent)event;
ItemUseBlacklistEvent evt = (ItemUseBlacklistEvent)event;
logEvent(event, "use", evt.getType(), evt.getPosition(), comment);
// Unknown
@@ -35,6 +35,7 @@ import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.blacklist.events.*;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.AreaFlags;
import static com.sk89q.worldguard.bukkit.BukkitUtil.*;
public class WorldGuardBlockListener extends BlockListener {
@@ -63,8 +64,10 @@ public class WorldGuardBlockListener extends BlockListener {
if (!plugin.itemDurability && event.getDamageLevel() == BlockDamageLevel.BROKEN) {
ItemStack held = player.getItemInHand();
held.setDamage((byte)-1);
player.setItemInHand(held);
if (held.getTypeId() > 0) {
held.setDurability((short) -1);
player.setItemInHand(held);
}
}
if (plugin.useRegions && event.getDamageLevel() == BlockDamageLevel.BROKEN) {
@@ -120,7 +123,9 @@ public class WorldGuardBlockListener extends BlockListener {
for (int cx = -plugin.spongeRadius; cx <= plugin.spongeRadius; cx++) {
for (int cy = -plugin.spongeRadius; cy <= plugin.spongeRadius; cy++) {
for (int cz = -plugin.spongeRadius; cz <= plugin.spongeRadius; cz++) {
if (world.getBlockTypeIdAt(ox + cx, oy + cy, oz + cz) == 19) {
Block sponge = world.getBlockAt(ox + cx, oy + cy, oz + cz);
if (sponge.getTypeId() == 19
&& (!plugin.redstoneSponges || !sponge.isBlockIndirectlyPowered())) {
event.setCancelled(true);
return;
}
@@ -129,14 +134,16 @@ public class WorldGuardBlockListener extends BlockListener {
}
}
if (plugin.classicWater && isWater) {
int blockBelow = world.getBlockTypeIdAt(blockFrom.getX(), blockFrom.getY() - 1, blockFrom.getZ());
/*if (plugin.classicWater && isWater) {
int blockBelow = blockFrom.getRelative(0, -1, 0).getTypeId();
if (blockBelow != 0 && blockBelow != 8 && blockBelow != 9) {
world.getBlockAt(blockFrom.getX(), blockFrom.getY(), blockFrom.getZ()).setTypeId(9);
event.setCancelled(true);
blockFrom.setTypeId(9);
if (blockTo.getTypeId() == 0) {
blockTo.setTypeId(9);
}
return;
}
}
}*/
if (plugin.preventWaterDamage.size() > 0 && isWater) {
int targetId = world.getBlockTypeIdAt(
@@ -166,10 +173,9 @@ public class WorldGuardBlockListener extends BlockListener {
public void onBlockIgnite(BlockIgniteEvent event) {
IgniteCause cause = event.getCause();
Block block = event.getBlock();
Player player = event.getPlayer();
//Player player = event.getPlayer();
World world = block.getWorld();
boolean isFireSpread = cause == IgniteCause.SLOW_SPREAD
|| cause == IgniteCause.SPREAD;
boolean isFireSpread = cause == IgniteCause.SPREAD;
if (plugin.preventLavaFire && cause == IgniteCause.LAVA) {
event.setCancelled(true);
@@ -206,18 +212,60 @@ public class WorldGuardBlockListener extends BlockListener {
}
}
if (plugin.useRegions && player != null && !plugin.hasPermission(player, "/regionbypass")) {
/*if (plugin.useRegions) {
Vector pt = toVector(block);
LocalPlayer localPlayer = plugin.wrapPlayer(player);
if (cause == IgniteCause.FLINT_AND_STEEL
&& !plugin.regionManager.getApplicableRegions(pt).canBuild(localPlayer)) {
if (player != null && !plugin.hasPermission(player, "/regionbypass")) {
LocalPlayer localPlayer = plugin.wrapPlayer(player);
if (cause == IgniteCause.FLINT_AND_STEEL
&& !plugin.regionManager.getApplicableRegions(pt).canBuild(localPlayer)) {
event.setCancelled(true);
return;
}
if (cause == IgniteCause.FLINT_AND_STEEL
&& !plugin.regionManager.getApplicableRegions(pt)
.allowsFlag(AreaFlags.FLAG_LIGHTER)) {
event.setCancelled(true);
return;
}
}
f (isFireSpread && !plugin.regionManager.getApplicableRegions(pt)
.allowsFlag(AreaFlags.FLAG_FIRE_SPREAD)) {
event.setCancelled(true);
return;
}
if (cause == IgniteCause.FLINT_AND_STEEL
&& !plugin.regionManager.getApplicableRegions(pt).allowsLighter()) {
if (cause == IgniteCause.LAVA && !plugin.regionManager.getApplicableRegions(pt)
.allowsFlag(AreaFlags.FLAG_LAVA_FIRE)) {
event.setCancelled(true);
return;
}
}*/
}
/**
* Called when a block is destroyed from burning
*
* @param event Relevant event details
*/
public void onBlockBurn(BlockBurnEvent event) {
if (plugin.disableFireSpread) {
event.setCancelled(true);
return;
}
if (plugin.fireSpreadDisableToggle) {
event.setCancelled(true);
return;
}
if (plugin.disableFireSpreadBlocks.size() > 0) {
Block block = event.getBlock();
if (plugin.disableFireSpreadBlocks.contains(block.getTypeId())) {
event.setCancelled(true);
return;
}
@@ -258,13 +306,19 @@ public class WorldGuardBlockListener extends BlockListener {
Block block = event.getBlock();
LivingEntity entity = event.getEntity();
if (entity instanceof Player && block.getType() == Material.CHEST) {
if (entity instanceof Player
&& (block.getType() == Material.CHEST
|| block.getType() == Material.DISPENSER
|| block.getType() == Material.FURNACE
|| block.getType() == Material.BURNING_FURNACE
|| block.getType() == Material.NOTE_BLOCK)) {
Player player = (Player)entity;
if (plugin.useRegions) {
Vector pt = toVector(block);
LocalPlayer localPlayer = plugin.wrapPlayer(player);
if (!plugin.hasPermission(player, "/regionbypass")
&& !plugin.regionManager.getApplicableRegions(pt).allowsFlag(AreaFlags.FLAG_CHEST_ACCESS)
&& !plugin.regionManager.getApplicableRegions(pt).canBuild(localPlayer)) {
player.sendMessage(ChatColor.DARK_RED + "You don't have permission for this area.");
event.setCancelled(true);
@@ -318,21 +372,15 @@ public class WorldGuardBlockListener extends BlockListener {
}
if (plugin.simulateSponge && blockPlaced.getTypeId() == 19) {
if (plugin.redstoneSponges && blockPlaced.isBlockIndirectlyPowered()) {
return;
}
int ox = blockPlaced.getX();
int oy = blockPlaced.getY();
int oz = blockPlaced.getZ();
for (int cx = -plugin.spongeRadius; cx <= plugin.spongeRadius; cx++) {
for (int cy = -plugin.spongeRadius; cy <= plugin.spongeRadius; cy++) {
for (int cz = -plugin.spongeRadius; cz <= plugin.spongeRadius; cz++) {
int id = world.getBlockTypeIdAt(ox + cx, oy + cy, oz + cz);
if (id == 8 || id == 9) {
world.getBlockAt(ox + cx, oy + cy, oz + cz)
.setTypeId(0);
}
}
}
}
clearSpongeWater(world, ox, oy, oz);
}
}
@@ -368,4 +416,61 @@ public class WorldGuardBlockListener extends BlockListener {
}
}
}
/**
* Called when redstone changes
* From: the source of the redstone change
* To: The redstone dust that changed
*
* @param event Relevant event details
*/
@Override
public void onBlockRedstoneChange(BlockRedstoneEvent event) {
World world = event.getBlock().getWorld();
Block blockTo = event.getBlock();
if (plugin.simulateSponge && plugin.redstoneSponges) {
int ox = blockTo.getX();
int oy = blockTo.getY();
int oz = blockTo.getZ();
for (int cx = -1; cx <= 1; cx++) {
for (int cy = -1; cy <= 1; cy++) {
for (int cz = -1; cz <= 1; cz++) {
Block sponge = world.getBlockAt(ox + cx, oy + cy, oz + cz);
if (sponge.getTypeId() == 19
&& sponge.isBlockIndirectlyPowered()) {
clearSpongeWater(world, ox + cx, oy + cy, oz + cz);
}
}
}
}
return;
}
}
/**
* Remove water around a sponge.
*
* @param world
* @param ox
* @param oy
* @param oz
*/
private void clearSpongeWater(World world, int ox, int oy, int oz) {
for (int cx = -plugin.spongeRadius; cx <= plugin.spongeRadius; cx++) {
for (int cy = -plugin.spongeRadius; cy <= plugin.spongeRadius; cy++) {
for (int cz = -plugin.spongeRadius; cz <= plugin.spongeRadius; cz++) {
Block block = world.getBlockAt(ox + cx, oy + cy, oz + cz);
int id = block.getTypeId();
if (id == 8 || id == 9) {
world.getBlockAt(ox + cx, oy + cy, oz + cz)
.setTypeId(0);
}
}
}
}
}
}
@@ -15,225 +15,259 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
*/
package com.sk89q.worldguard.bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Monster;
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 com.sk89q.worldguard.protection.AreaFlags;
import static com.sk89q.worldguard.bukkit.BukkitUtil.*;
public class WorldGuardEntityListener extends EntityListener {
/**
* Plugin.
*/
private WorldGuardPlugin plugin;
/**
* Construct the object;
*
* @param plugin
*/
public WorldGuardEntityListener(WorldGuardPlugin plugin) {
this.plugin = plugin;
}
@Override
public void onEntityDamageByBlock(EntityDamageByBlockEvent event) {
Entity defender = event.getEntity();
DamageCause type = event.getCause();
if (defender instanceof Player) {
Player player = (Player)defender;
public class WorldGuardEntityListener extends EntityListener
{
/**
* Plugin.
*/
private WorldGuardPlugin plugin;
if (plugin.invinciblePlayers.contains(player.getName())) {
event.setCancelled(true);
return;
}
/**
* Construct the object;
*
* @param plugin
*/
public WorldGuardEntityListener(WorldGuardPlugin plugin)
{
this.plugin = plugin;
}
if (plugin.disableLavaDamage && type == DamageCause.LAVA) {
event.setCancelled(true);
return;
}
}
}
@Override
public void onEntityDamage(EntityDamageEvent event)
{
Entity defender = event.getEntity();
DamageCause type = event.getCause();
@Override
public void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
Entity attacker = event.getDamager();
Entity defender = event.getEntity();
if (defender instanceof Player) {
Player player = (Player)defender;
if (defender instanceof Player)
{
Player player = (Player)defender;
if (plugin.invinciblePlayers.contains(player.getName())) {
event.setCancelled(true);
return;
}
if (attacker != null && attacker instanceof Player) {
if (plugin.useRegions) {
Vector pt = toVector(defender.getLocation());
if (!plugin.regionManager.getApplicableRegions(pt).allowsPvP()) {
player.sendMessage(ChatColor.DARK_RED + "You are in a no-PvP area.");
event.setCancelled(true);
return;
}
}
}
}
}
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;
}
if (plugin.invinciblePlayers.contains(player.getName())) {
event.setCancelled(true);
return;
}
}
if (plugin.disableLavaDamage && type == DamageCause.LAVA)
{
event.setCancelled(true);
return;
}
}
if (plugin.disableContactDamage && type == DamageCause.CONTACT)
{
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 (type == DamageCause.ENTITY_ATTACK)
{
Entity attacker = ((EntityDamageByEntityEvent)event).getDamager();
if (plugin.invinciblePlayers.contains(player.getName())) {
event.setCancelled(true);
return;
}
if (plugin.disableFallDamage && type == DamageCause.FALL) {
event.setCancelled(true);
return;
}
if (plugin.invinciblePlayers.contains(player.getName()))
{
event.setCancelled(true);
return;
}
if (plugin.disableFireDamage && (type == DamageCause.FIRE
|| type == DamageCause.FIRE_TICK)) {
event.setCancelled(true);
return;
}
if (attacker != null && attacker instanceof Player)
{
if (plugin.useRegions)
{
Vector pt = toVector(defender.getLocation());
if (plugin.disableDrowningDamage && type == DamageCause.DROWNING) {
event.setCancelled(true);
return;
}
if (plugin.teleportOnSuffocation && type == DamageCause.SUFFOCATION) {
findFreePosition(player);
event.setCancelled(true);
return;
}
if (!plugin.regionManager.getApplicableRegions(pt).allowsFlag(AreaFlags.FLAG_PVP))
{
((Player)attacker).sendMessage(ChatColor.DARK_RED + "You are in a no-PvP area.");
event.setCancelled(true);
return;
}
}
}
if (plugin.disableSuffocationDamage && type == DamageCause.SUFFOCATION) {
event.setCancelled(true);
return;
}
if (attacker != null && attacker instanceof Monster)
{
if (attacker instanceof Creeper && plugin.blockCreeperExplosions)
{
event.setCancelled(true);
return;
}
if (plugin.disableContactDamage && type == DamageCause.CONTACT) {
event.setCancelled(true);
return;
}
if (plugin.useRegions)
{
Vector pt = toVector(defender.getLocation());
if (type == DamageCause.DROWNING
&& plugin.amphibiousPlayers.contains(player.getName())) {
event.setCancelled(true);
return;
}
}
}
if (!plugin.regionManager.getApplicableRegions(pt).allowsFlag(AreaFlags.FLAG_MOB_DAMAGE))
{
event.setCancelled(true);
return;
}
@Override
public void onEntityExplode(EntityExplodeEvent event) {
if (event.getEntity() instanceof LivingEntity) {
if (plugin.blockCreeperBlockDamage) {
event.setCancelled(true);
return;
}
if (plugin.blockCreeperExplosions) {
event.setCancelled(true);
return;
}
if (plugin.useRegions) {
Vector pt = toVector(event.getEntity().getLocation());
if (!plugin.regionManager.getApplicableRegions(pt).allowsCreeperExplosions()) {
event.setCancelled(true);
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();
if (attacker instanceof Creeper)
{
if (!plugin.regionManager.getApplicableRegions(pt).allowsFlag(AreaFlags.FLAG_CREEPER_EXPLOSION))
{
event.setCancelled(true);
return;
}
}
}
}
}
byte free = 0;
if (plugin.disableFallDamage && type == DamageCause.FALL)
{
event.setCancelled(true);
return;
}
while (y <= 129) {
if (BlockType.canPassThrough(world.getBlockTypeIdAt(x, y, z))) {
free++;
} else {
free = 0;
}
if (plugin.disableFireDamage && (type == DamageCause.FIRE
|| type == DamageCause.FIRE_TICK))
{
event.setCancelled(true);
return;
}
if (free == 2) {
if (y - 1 != origY) {
loc.setX(x + 0.5);
loc.setY(y);
loc.setZ(z + 0.5);
player.teleportTo(loc);
}
if (plugin.disableDrowningDamage && type == DamageCause.DROWNING)
{
event.setCancelled(true);
return;
}
return;
}
if (plugin.teleportOnSuffocation && type == DamageCause.SUFFOCATION)
{
findFreePosition(player);
event.setCancelled(true);
return;
}
y++;
}
}
if (plugin.disableSuffocationDamage && type == DamageCause.SUFFOCATION)
{
event.setCancelled(true);
return;
}
if (type == DamageCause.DROWNING
&& plugin.amphibiousPlayers.contains(player.getName()))
{
event.setCancelled(true);
return;
}
}
}
@Override
public void onEntityExplode(EntityExplodeEvent event)
{
if (event.getEntity() instanceof LivingEntity)
{
if (plugin.blockCreeperBlockDamage)
{
event.setCancelled(true);
return;
}
if (plugin.blockCreeperExplosions)
{
event.setCancelled(true);
return;
}
if (plugin.useRegions)
{
Vector pt = toVector(event.getEntity().getLocation());
if (!plugin.regionManager.getApplicableRegions(pt).allowsFlag(AreaFlags.FLAG_CREEPER_EXPLOSION))
{
event.setCancelled(true);
return;
}
}
}
else
{ // Shall assume that this is TNT
if (plugin.blockTNT)
{
event.setCancelled(true);
return;
}
if (plugin.useRegions && event.getEntity() != null)
{
Vector pt = toVector(event.getEntity().getLocation());
if (!plugin.regionManager.getApplicableRegions(pt).allowsFlag(AreaFlags.FLAG_TNT))
{
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,8 +19,6 @@
package com.sk89q.worldguard.bukkit;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
@@ -29,6 +27,7 @@ import org.bukkit.inventory.ItemStack;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.*;
import com.sk89q.worldguard.blacklist.events.ItemUseBlacklistEvent;
import com.sk89q.worldguard.protection.AreaFlags;
import static com.sk89q.worldguard.bukkit.BukkitUtil.*;
/**
@@ -97,6 +96,14 @@ public class WorldGuardPlayerListener extends PlayerListener {
Player player = event.getPlayer();
Block block = event.getBlockClicked();
ItemStack item = event.getItem();
if (!plugin.itemDurability) {
// Hoes
if (item.getTypeId() >= 290 && item.getTypeId() <= 294) {
item.setDurability((byte)-1);
player.setItemInHand(item);
}
}
if (plugin.useRegions && !event.isBlock() && block != null) {
Vector pt = toVector(block.getRelative(event.getBlockFace()));
@@ -111,7 +118,7 @@ public class WorldGuardPlayerListener extends PlayerListener {
}
}
if (item != null && plugin.blacklist != null && block != null) {
if (plugin.blacklist != null && item != null && block != null) {
if (!plugin.blacklist.check(
new ItemUseBlacklistEvent(plugin.wrapPlayer(player),
toVector(block.getRelative(event.getBlockFace())),
@@ -120,6 +127,16 @@ public class WorldGuardPlayerListener extends PlayerListener {
return;
}
}
if (plugin.useRegions && item != null && block != null && item.getTypeId() == 259) {
Vector pt = toVector(block.getRelative(event.getBlockFace()));
if (!plugin.regionManager.getApplicableRegions(pt)
.allowsFlag(AreaFlags.FLAG_LIGHTER)) {
event.setCancelled(true);
return;
}
}
}
/**
@@ -20,31 +20,21 @@
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.io.*;
import java.util.*;
import java.util.logging.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
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;
@@ -52,40 +42,45 @@ 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.Vector;
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.LocalPlayer;
import com.sk89q.worldguard.TickSyncDelayLoggerFilter;
import com.sk89q.worldguard.blacklist.*;
import com.sk89q.worldguard.blacklist.loggers.*;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.protection.*;
import com.sk89q.worldguard.protection.AreaFlags.State;
import com.sk89q.worldguard.protection.ProtectedRegion.CircularInheritanceException;
/**
* Plugin for Bukkit.
*
* @author sk89qs
*/
public class WorldGuardPlugin extends JavaPlugin {
public final 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 =
private WorldGuardPlayerListener playerListener =
new WorldGuardPlayerListener(this);
private final WorldGuardBlockListener blockListener =
private WorldGuardBlockListener blockListener =
new WorldGuardBlockListener(this);
private final WorldGuardEntityListener entityListener =
private WorldGuardEntityListener entityListener =
new WorldGuardEntityListener(this);
private final PermissionsResolverServerListener permsListener;
private PermissionsResolverServerListener permsListener;
private final PermissionsResolverManager perms;
private PermissionsResolverManager perms;
Blacklist blacklist;
RegionManager regionManager = new FlatRegionManager();
GlobalFlags globalFlags = new GlobalFlags();
RegionManager regionManager = new FlatRegionManager(globalFlags);
ProtectionDatabase regionLoader;
Set<String> invinciblePlayers = new HashSet<String>();
@@ -94,12 +89,15 @@ public class WorldGuardPlugin extends JavaPlugin {
// Configuration follows
boolean suppressTickSyncWarnings;
boolean enforceOneSession;
boolean itemDurability;
boolean classicWater;
boolean simulateSponge;
int spongeRadius;
boolean redstoneSponges;
boolean noPhysicsGravel;
boolean noPhysicsSand;
@@ -133,41 +131,34 @@ 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);
logger.info("WorldGuard " + desc.getVersion() + " loaded.");
/**
* Called on plugin enable.
*/
public void onEnable() {
logger.info("WorldGuard " + getDescription().getVersion() + " loaded.");
folder.mkdirs();
getDataFolder().mkdirs();
createDefaultConfiguration("config.yml");
createDefaultConfiguration("blacklist.txt");
regionLoader = new CSVDatabase(new File(folder, "regions.txt"));
regionLoader = new CSVDatabase(new File(getDataFolder(), "regions.txt"));
perms = new PermissionsResolverManager(getConfiguration(), getServer(),
"WorldGuard", logger);
permsListener = new PermissionsResolverServerListener(perms);
loadConfiguration();
postReload();
registerEvents();
}
/**
* Called on plugin enable.
*/
public void onEnable() {
if (suppressTickSyncWarnings) {
Logger.getLogger("Minecraft").setFilter(new TickSyncDelayLoggerFilter());
} else {
Filter filter = Logger.getLogger("Minecraft").getFilter();
if (filter != null && filter instanceof TickSyncDelayLoggerFilter) {
Logger.getLogger("Minecraft").setFilter(null);
}
}
}
/**
@@ -180,21 +171,20 @@ public class WorldGuardPlugin extends JavaPlugin {
* Register used events.
*/
private void registerEvents() {
registerEvent(Event.Type.BLOCK_DAMAGED, blockListener, Priority.Normal);
registerEvent(Event.Type.BLOCK_DAMAGED, blockListener, Priority.High);
registerEvent(Event.Type.BLOCK_FLOW, blockListener, Priority.Normal);
registerEvent(Event.Type.BLOCK_IGNITE, blockListener, Priority.Normal);
registerEvent(Event.Type.BLOCK_IGNITE, blockListener, Priority.High);
registerEvent(Event.Type.BLOCK_PHYSICS, blockListener, Priority.Normal);
registerEvent(Event.Type.BLOCK_INTERACT, blockListener, Priority.Normal);
registerEvent(Event.Type.BLOCK_PLACED, blockListener, Priority.Normal);
registerEvent(Event.Type.BLOCK_RIGHTCLICKED, blockListener, Priority.Normal);
registerEvent(Event.Type.BLOCK_INTERACT, blockListener, Priority.High);
registerEvent(Event.Type.BLOCK_PLACED, blockListener, Priority.High);
registerEvent(Event.Type.BLOCK_RIGHTCLICKED, blockListener, Priority.High);
registerEvent(Event.Type.BLOCK_BURN, blockListener, Priority.High);
registerEvent(Event.Type.REDSTONE_CHANGE, blockListener, Priority.High);
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.ENTITY_DAMAGED, entityListener, Priority.High);
registerEvent(Event.Type.ENTITY_EXPLODE, entityListener, Priority.High);
registerEvent(Event.Type.PLAYER_ITEM, playerListener, Priority.Normal);
registerEvent(Event.Type.PLAYER_ITEM, playerListener, Priority.High);
registerEvent(Event.Type.PLAYER_JOIN, playerListener, Priority.Normal);
registerEvent(Event.Type.PLAYER_LOGIN, playerListener, Priority.Normal);
registerEvent(Event.Type.PLAYER_QUIT, playerListener, Priority.Normal);
@@ -260,6 +250,9 @@ public class WorldGuardPlugin extends JavaPlugin {
public void loadConfiguration() {
Configuration config = getConfiguration();
config.load();
perms.load();
suppressTickSyncWarnings = config.getBoolean("suppress-tick-sync-warnings", false);
enforceOneSession = config.getBoolean("protection.enforce-single-session", true);
itemDurability = config.getBoolean("protection.item-durability", true);
@@ -267,6 +260,7 @@ public class WorldGuardPlugin extends JavaPlugin {
classicWater = config.getBoolean("simulation.classic-water", false);
simulateSponge = config.getBoolean("simulation.sponge.enable", true);
spongeRadius = Math.max(1, config.getInt("simulation.sponge.radius", 3)) - 1;
redstoneSponges = config.getBoolean("simulation.sponge.redstone", false);
noPhysicsGravel = config.getBoolean("physics.no-physics-gravel", false);
noPhysicsSand = config.getBoolean("physics.no-physics-sand", false);
@@ -293,13 +287,16 @@ public class WorldGuardPlugin extends JavaPlugin {
disableFallDamage = config.getBoolean("player-damage.disable-fall-damage", false);
disableLavaDamage = config.getBoolean("player-damage.disable-lava-damage", false);
disableFireDamage = config.getBoolean("player-damage.disable-fire-damage", false);
disableDrowningDamage = config.getBoolean("player-damage.disable-water-damage", false);
disableDrowningDamage = config.getBoolean("player-damage.disable-drowning-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);
regionWand = config.getInt("regions.wand", 287);
globalFlags.canBuild = config.getBoolean("regions.default.build", true);
globalFlags.canAccessChests = config.getBoolean("regions.default.chest-access", false);
globalFlags.canPvP = config.getBoolean("regions.default.pvp", true);
try {
regionLoader.load();
@@ -417,18 +414,25 @@ public class WorldGuardPlugin extends JavaPlugin {
/**
* Handles a command.
*/
public boolean onCommand(Player player, Command cmd, String commandLabel, String[] args) {
public boolean onCommand(CommandSender sender, Command cmd,
String commandLabel, String[] args) {
try {
return handleCommand(player, cmd.getName(), args);
return handleCommand(sender, cmd.getName(), args);
} catch (InsufficientArgumentsException e) {
if (e.getHelp() != null) {
player.sendMessage(ChatColor.RED + e.getHelp());
sender.sendMessage(ChatColor.RED + e.getHelp());
return true;
} else {
return false;
}
} catch (InsufficientPermissionsException e) {
player.sendMessage(ChatColor.RED + "You don't have sufficient permission.");
sender.sendMessage(ChatColor.RED + "You don't have sufficient permission.");
return true;
} catch (CommandHandlingException e) {
return true;
} catch (Throwable t) {
sender.sendMessage(ChatColor.RED + "ERROR: " + t.getMessage());
t.printStackTrace();
return true;
}
}
@@ -440,21 +444,22 @@ public class WorldGuardPlugin extends JavaPlugin {
* @param cmd
* @param args
* @return
* @throws InsufficientArgumentsException
* @throws InsufficientPermissionsException
* @throws CommandHandlingException
*/
private boolean handleCommand(Player player, String cmd, String[] args)
throws InsufficientArgumentsException, InsufficientPermissionsException {
private boolean handleCommand(CommandSender sender, String cmd, String[] args)
throws CommandHandlingException {
String senderName = sender instanceof Player ? ((Player)sender).getName() : "Console";
if (cmd.equalsIgnoreCase("stopfire")) {
checkPermission(player, "/stopfire");
checkPermission(sender, "/stopfire");
checkArgs(args, 0, 0);
if (!fireSpreadDisableToggle) {
getServer().broadcastMessage(ChatColor.YELLOW
+ "Fire spread has been globally disabled by " + player.getName() + ".");
+ "Fire spread has been globally disabled by " + senderName + ".");
} else {
player.sendMessage(ChatColor.YELLOW + "Fire spread was already globally disabled.");
sender.sendMessage(ChatColor.YELLOW + "Fire spread was already globally disabled.");
}
fireSpreadDisableToggle = true;
@@ -463,14 +468,14 @@ public class WorldGuardPlugin extends JavaPlugin {
}
if (cmd.equalsIgnoreCase("allowfire")) {
checkPermission(player, "/stopfire");
checkPermission(sender, "/stopfire");
checkArgs(args, 0, 0);
if (fireSpreadDisableToggle) {
getServer().broadcastMessage(ChatColor.YELLOW
+ "Fire spread has been globally re-enabled by " + player.getName() + ".");
+ "Fire spread has been globally re-enabled by " + senderName + ".");
} else {
player.sendMessage(ChatColor.YELLOW + "Fire spread was already globally enabled.");
sender.sendMessage(ChatColor.YELLOW + "Fire spread was already globally enabled.");
}
fireSpreadDisableToggle = false;
@@ -478,18 +483,24 @@ public class WorldGuardPlugin extends JavaPlugin {
return true;
}
if (!(sender instanceof Player)) {
return false;
}
Player player = (Player)sender;
if (cmd.equalsIgnoreCase("god")) {
checkPermission(player, "/god");
checkArgs(args, 0, 1);
// Allow setting other people invincible
if (args.length > 1) {
if (args.length > 0) {
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]);
Player other = matchSinglePlayer(getServer(), args[0]);
if (other == null) {
player.sendMessage(ChatColor.RED + "Player not found.");
} else {
@@ -522,13 +533,13 @@ public class WorldGuardPlugin extends JavaPlugin {
checkArgs(args, 0, 1);
// Allow healing other people
if (args.length > 1) {
if (args.length > 0) {
if (!hasPermission(player, "/healother")) {
player.sendMessage(ChatColor.RED + "You don't have permission to heal others.");
return true;
}
Player other = matchSinglePlayer(getServer(), args[1]);
Player other = matchSinglePlayer(getServer(), args[0]);
if (other == null) {
player.sendMessage(ChatColor.RED + "Player not found.");
} else {
@@ -549,13 +560,13 @@ public class WorldGuardPlugin extends JavaPlugin {
checkArgs(args, 0, 1);
// Allow killing other people
if (args.length > 1) {
if (args.length > 0) {
if (!hasPermission(player, "/slayother")) {
player.sendMessage(ChatColor.RED + "You don't have permission to kill others.");
return true;
}
Player other = matchSinglePlayer(getServer(), args[1]);
Player other = matchSinglePlayer(getServer(), args[0]);
if (other == null) {
player.sendMessage(ChatColor.RED + "Player not found.");
} else {
@@ -572,7 +583,7 @@ public class WorldGuardPlugin extends JavaPlugin {
}
if (cmd.equalsIgnoreCase("stack")) {
checkPermission(player, "stack");
checkPermission(player, "/stack");
checkArgs(args, 0, 0);
ItemStack[] items = player.getInventory().getContents();
@@ -611,7 +622,7 @@ public class WorldGuardPlugin extends JavaPlugin {
// Blocks store their color in the damage value
if (item2.getTypeId() == item.getTypeId() &&
(!ItemType.usesDamageValue(item.getTypeId())
|| item.getDamage() == item2.getDamage())) {
|| item.getDurability() == item2.getDurability())) {
// This stack won't fit in the parent stack
if (item2.getAmount() > needed) {
item.setAmount(64);
@@ -640,11 +651,11 @@ public class WorldGuardPlugin extends JavaPlugin {
}
if (cmd.equalsIgnoreCase("locate")) {
checkPermission(player, "locate");
checkPermission(player, "/locate");
checkArgs(args, 0, 3);
if (args.length == 2) {
String name = args[1];
if (args.length == 1) {
String name = args[0];
Player target = BukkitUtil.matchSinglePlayer(getServer(), name);
if (target != null) {
player.setCompassTarget(target.getLocation());
@@ -652,13 +663,13 @@ public class WorldGuardPlugin extends JavaPlugin {
} else {
player.sendMessage(ChatColor.RED + "Could not find player.");
}
} else if (args.length == 4) {
} else if (args.length == 3) {
try {
Location loc = new Location(
player.getWorld(),
Integer.parseInt(args[0]),
Integer.parseInt(args[1]),
Integer.parseInt(args[2]),
Integer.parseInt(args[3])
Integer.parseInt(args[2])
);
player.setCompassTarget(loc);
player.sendMessage(ChatColor.YELLOW + "Compass target set to "
@@ -668,7 +679,7 @@ public class WorldGuardPlugin extends JavaPlugin {
} catch (NumberFormatException e) {
player.sendMessage(ChatColor.RED + "Invalid number specified");
}
} else if (args.length == 1) {
} else if (args.length == 0) {
player.setCompassTarget(player.getWorld().getSpawnLocation());
player.sendMessage(ChatColor.YELLOW + "Compass reset to the spawn location.");
} else {
@@ -681,14 +692,14 @@ public class WorldGuardPlugin extends JavaPlugin {
if (cmd.equalsIgnoreCase("region")) {
checkArgs(args, 1, -1);
String action = args[1];
String action = args[0];
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");
checkPermission(player, "/reloadwg");
checkArgs(args, 0, 0);
LoggerToChatHandler handler = new LoggerToChatHandler(player);
@@ -719,11 +730,10 @@ public class WorldGuardPlugin extends JavaPlugin {
* @param player
* @param action
* @param args
* @throws InsufficientPermissionsException
* @throws InsufficientArgumentsException
* @throws CommandHandlingException
*/
private boolean handleRegionCommand(Player player, String action, String[] args)
throws InsufficientPermissionsException, InsufficientArgumentsException {
throws CommandHandlingException {
if (!useRegions) {
player.sendMessage(ChatColor.RED + "Regions are disabled.");
return true;
@@ -740,7 +750,7 @@ public class WorldGuardPlugin extends JavaPlugin {
checkArgs(args, 1, -1, "/region define <id> [owner1 [owner2 [owners...]]]");
try {
String id = args[1].toLowerCase();
String id = args[0].toLowerCase();
WorldEditPlugin worldEdit = (WorldEditPlugin)wePlugin;
WorldEditAPI api = worldEdit.getAPI();
@@ -751,11 +761,11 @@ public class WorldGuardPlugin extends JavaPlugin {
BlockVector min = weRegion.getMinimumPoint().toBlockVector();
BlockVector max = weRegion.getMaximumPoint().toBlockVector();
ProtectedRegion region = new ProtectedCuboidRegion(min, max);
ProtectedRegion region = new ProtectedCuboidRegion(id, min, max);
if (args.length >= 2) {
region.setOwners(parseDomainString(args, 2));
region.setOwners(parseDomainString(args, 1));
}
regionManager.addRegion(id, region);
regionManager.addRegion(region);
regionLoader.save(regionManager);
player.sendMessage(ChatColor.YELLOW + "Region saved as " + id + ".");
} catch (IncompleteRegionException e) {
@@ -773,7 +783,7 @@ public class WorldGuardPlugin extends JavaPlugin {
checkArgs(args, 1, 1, "/region claim <id>");
try {
String id = args[1].toLowerCase();
String id = args[0].toLowerCase();
ProtectedRegion existing = regionManager.getRegion(id);
@@ -793,7 +803,7 @@ public class WorldGuardPlugin extends JavaPlugin {
BlockVector min = weRegion.getMinimumPoint().toBlockVector();
BlockVector max = weRegion.getMaximumPoint().toBlockVector();
ProtectedRegion region = new ProtectedCuboidRegion(min, max);
ProtectedRegion region = new ProtectedCuboidRegion(id, min, max);
if (regionManager.overlapsUnownedRegion(region, wrapPlayer(player))) {
player.sendMessage(ChatColor.RED + "This region overlaps with someone else's region.");
@@ -802,7 +812,7 @@ public class WorldGuardPlugin extends JavaPlugin {
region.getOwners().addPlayer(player.getName());
regionManager.addRegion(id, region);
regionManager.addRegion(region);
regionLoader.save(regionManager);
player.sendMessage(ChatColor.YELLOW + "Region saved as " + id + ".");
} catch (IncompleteRegionException e) {
@@ -820,9 +830,9 @@ public class WorldGuardPlugin extends JavaPlugin {
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];
String id = args[0].toLowerCase();
String flagStr = args[1];
String stateStr = args[2];
ProtectedRegion region = regionManager.getRegion(id);
if (region == null) {
@@ -843,23 +853,78 @@ public class WorldGuardPlugin extends JavaPlugin {
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;
if (flagStr.length() == 0) {
player.sendMessage(ChatColor.RED + "A flag must be specified.");
return true;
// Custom flag
} else if (flagStr.length() == 2 && flagStr.matches("^_[A-Za-z0-0]$")) {
} else {
player.sendMessage(ChatColor.RED + "Acceptable flags: build, pvp, tnt, lighter");
flagStr = AreaFlags.fromAlias(flagStr);
if (flagStr == null) {
player.sendMessage(ChatColor.RED + "Unknown flag specified.");
return true;
}
}
AreaFlags flags = region.getFlags();
flags.set(flagStr, state);
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("setparent")) {
if (!hasPermission(player, "/regionclaim")) {
checkRegionPermission(player, "/regiondefine");
}
checkArgs(args, 1, 2, "/region setparent <id> <parent-id>");
String id = args[0].toLowerCase();
String parentId = args.length > 1 ? args[1].toLowerCase() : null;
ProtectedRegion region = regionManager.getRegion(id);
if (region == null) {
player.sendMessage(ChatColor.RED + "Could not find a region with ID: " + id);
return true;
}
if (!canUseRegionCommand(player, "/regiondefine")
&& !region.isOwner(wrapPlayer(player))) {
player.sendMessage(ChatColor.RED + "You need to own the target regions");
return true;
}
ProtectedRegion parent = null;
// Set a parent
if (parentId != null) {
parent = regionManager.getRegion(parentId);
if (parent == null) {
player.sendMessage(ChatColor.RED + "Could not find a region with ID: " + parentId);
return true;
}
if (!canUseRegionCommand(player, "/regiondefine")
&& !parent.isOwner(wrapPlayer(player))) {
player.sendMessage(ChatColor.RED + "You need to own the parent region.");
return true;
}
}
try {
region.setParent(parent);
regionLoader.save(regionManager);
player.sendMessage(ChatColor.YELLOW + "Region '" + id + "' updated.");
} catch (CircularInheritanceException e) {
player.sendMessage(ChatColor.RED + "Circular inheritance detected. The operation failed.");
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
@@ -872,7 +937,7 @@ public class WorldGuardPlugin extends JavaPlugin {
checkRegionPermission(player, "/regioninfo");
checkArgs(args, 1, 1, "/region info <id>");
String id = args[1].toLowerCase();
String id = args[0].toLowerCase();
if (!regionManager.hasRegion(id)) {
player.sendMessage(ChatColor.RED + "A region with ID '"
+ id + "' doesn't exist.");
@@ -881,47 +946,74 @@ public class WorldGuardPlugin extends JavaPlugin {
ProtectedRegion region = regionManager.getRegion(id);
AreaFlags flags = region.getFlags();
DefaultDomain domain = region.getOwners();
DefaultDomain owners = region.getOwners();
DefaultDomain members = region.getMembers();
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());
player.sendMessage(ChatColor.YELLOW + "Region: " + id
+ ChatColor.GRAY + " (type: " + region.getTypeName() + ")");
player.sendMessage(ChatColor.BLUE + "Priority: " + region.getPriority());
StringBuilder s = new StringBuilder();
for (Map.Entry<String, State> entry : flags.entrySet()) {
if (s.length() > 0) {
s.append(", ");
}
if (entry.getValue() == State.ALLOW) {
s.append("+");
s.append(AreaFlags.getFlagName(entry.getKey()));
} else if (entry.getValue() == State.DENY) {
s.append("-");
s.append(AreaFlags.getFlagName(entry.getKey()));
}
}
player.sendMessage(ChatColor.BLUE + "Flags: " + s.toString());
player.sendMessage(ChatColor.BLUE + "Parent: "
+ (region.getParent() == null ? "(none)" : region.getParent().getId()));
player.sendMessage(ChatColor.LIGHT_PURPLE + "Owners: "
+ owners.toUserFriendlyString());
player.sendMessage(ChatColor.LIGHT_PURPLE + "Members: "
+ members.toUserFriendlyString());
return true;
}
if (action.equalsIgnoreCase("addowner")) {
if (!hasPermission(player, "/regionclaim")) {
if (action.equalsIgnoreCase("addowner") || action.equalsIgnoreCase("addmember")) {
if (!hasPermission(player, "/regionclaim") && !hasPermission(player, "/regionmembership")) {
checkRegionPermission(player, "/regiondefine");
}
checkArgs(args, 2, -1, "/region addowner <id> [owner1 [owner2 [owners...]]]");
checkArgs(args, 2, -1, "/region add[member|owner] <id> [player1 [group1 [players/groups...]]]");
boolean isOwner = action.equalsIgnoreCase("addowner");
String id = args[0].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.isOwner(wrapPlayer(player))) {
player.sendMessage(ChatColor.RED + "You don't own this region.");
return true;
}
if (isOwner) {
addToDomain(existing.getOwners(), args, 1);
} else {
addToDomain(existing.getMembers(), args, 1);
}
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!");
player.sendMessage(ChatColor.GRAY + "Current owners: "
+ existing.getOwners().toUserFriendlyString());
player.sendMessage(ChatColor.GRAY + "Current members: "
+ existing.getMembers().toUserFriendlyString());
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
@@ -930,32 +1022,42 @@ public class WorldGuardPlugin extends JavaPlugin {
return true;
}
if (action.equalsIgnoreCase("removeowner")) {
if (!hasPermission(player, "/regionclaim")) {
if (action.equalsIgnoreCase("removeowner") || action.equalsIgnoreCase("removemember")) {
if (!hasPermission(player, "/regionclaim") && !hasPermission(player, "/regionmembership")) {
checkRegionPermission(player, "/regiondefine");
}
checkArgs(args, 2, -1, "/region removeowner <id> [owner1 [owner2 [owners...]]]");
boolean isOwner = action.equalsIgnoreCase("removeowner");
String id = args[0].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.isOwner(wrapPlayer(player))) {
player.sendMessage(ChatColor.RED + "You don't own this region.");
return true;
}
if (isOwner) {
removeFromDomain(existing.getOwners(), args, 1);
} else {
removeFromDomain(existing.getMembers(), args, 1);
}
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!");
player.sendMessage(ChatColor.GRAY + "Current owners: "
+ existing.getOwners().toUserFriendlyString());
player.sendMessage(ChatColor.GRAY + "Current members: "
+ existing.getMembers().toUserFriendlyString());
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "Region database failed to save: "
+ e.getMessage());
@@ -970,9 +1072,9 @@ public class WorldGuardPlugin extends JavaPlugin {
int page = 0;
if (args.length >= 2) {
if (args.length >= 1) {
try {
page = Math.max(0, Integer.parseInt(args[1]) - 1);
page = Math.max(0, Integer.parseInt(args[0]) - 1);
} catch (NumberFormatException e) {
page = 0;
}
@@ -1011,7 +1113,7 @@ public class WorldGuardPlugin extends JavaPlugin {
checkArgs(args, 0, 1, "/region delete <id>");
try {
String id = args[1].toLowerCase();
String id = args[0].toLowerCase();
if (!regionManager.hasRegion(id)) {
player.sendMessage(ChatColor.RED + "A region with ID '"
+ id + "' doesn't exist.");
@@ -1021,7 +1123,7 @@ public class WorldGuardPlugin extends JavaPlugin {
ProtectedRegion existing = regionManager.getRegion(id);
if (!canUseRegionCommand(player, "/regiondelete")
&& !existing.getOwners().contains(wrapPlayer(player))) {
&& !existing.isOwner(wrapPlayer(player))) {
player.sendMessage(ChatColor.RED + "You don't own this region.");
return true;
}
@@ -1164,13 +1266,16 @@ public class WorldGuardPlugin extends JavaPlugin {
* Checks to see if there are sufficient permissions, otherwise an exception
* is raised in that case.
*
* @param player
* @param sender
* @param permission
* @throws InsufficientPermissionsException
*/
private void checkPermission(Player player, String permission)
private void checkPermission(CommandSender sender, String permission)
throws InsufficientPermissionsException {
if (!hasPermission(player, permission)) {
if (!(sender instanceof Player)) {
return;
}
if (!hasPermission((Player)sender, permission)) {
throw new InsufficientPermissionsException();
}
}
@@ -1185,7 +1290,7 @@ public class WorldGuardPlugin extends JavaPlugin {
*/
private void checkArgs(String[] args, int min, int max)
throws InsufficientArgumentsException {
if (args.length <= min || (max != -1 && args.length - 1 > max)) {
if (args.length < min || (max != -1 && args.length > max)) {
throw new InsufficientArgumentsException();
}
}
@@ -1201,33 +1306,91 @@ public class WorldGuardPlugin extends JavaPlugin {
*/
private void checkArgs(String[] args, int min, int max, String help)
throws InsufficientArgumentsException {
if (args.length <= min || (max != -1 && args.length - 1 > max)) {
if (args.length < min || (max != -1 && args.length > max)) {
throw new InsufficientArgumentsException(help);
}
}
/**
* Get the region manager.
*
* @return
*/
public RegionManager getRegionManager() {
return regionManager;
}
/**
* Get the region loader.
*
* @return
*/
public ProtectionDatabase getRegionLoader() {
return regionLoader;
}
public boolean canBuild(Player player, int x, int y, int z) {
if (useRegions) {
Vector pt = new Vector(x, y, z);
LocalPlayer localPlayer = wrapPlayer(player);
if (!hasPermission(player, "/regionbypass")
&& !regionManager.getApplicableRegions(pt).canBuild(localPlayer)) {
return false;
}
return true;
} else {
return true;
}
}
boolean inGroup(Player player, String group) {
return perms.inGroup(player.getName(), group);
try {
return perms.inGroup(player.getName(), group);
} catch (Throwable t) {
t.printStackTrace();
return false;
}
}
boolean hasPermission(Player player, String perm) {
return player.isOp() || perms.hasPermission(player.getName(), perm);
try {
return player.isOp() || perms.hasPermission(player.getName(), perm);
} catch (Throwable t) {
t.printStackTrace();
return false;
}
}
String[] getGroups(Player player) {
return perms.getGroups(player.getName());
try {
return perms.getGroups(player.getName());
} catch (Throwable t) {
t.printStackTrace();
return new String[0];
}
}
BukkitPlayer wrapPlayer(Player player) {
return new BukkitPlayer(this, player);
}
/**
* Thrown when command handling has raised an exception.
*
* @author sk89q
*/
private static class CommandHandlingException extends Exception {
private static final long serialVersionUID = 7912130636812036780L;
}
/**
* Thrown when a player has insufficient permissions.
*
* @author sk89q
*/
private static class InsufficientPermissionsException extends Exception {
private static class InsufficientPermissionsException extends CommandHandlingException {
private static final long serialVersionUID = 9087662707619954750L;
}
@@ -1236,7 +1399,7 @@ public class WorldGuardPlugin extends JavaPlugin {
*
* @author sk89q
*/
private static class InsufficientArgumentsException extends Exception {
private static class InsufficientArgumentsException extends CommandHandlingException {
private static final long serialVersionUID = 4153597953889773788L;
private final String help;
@@ -98,6 +98,7 @@ public class DefaultDomain implements Domain {
public String toGroupsString() {
StringBuilder str = new StringBuilder();
for (Iterator<String> it = groups.iterator(); it.hasNext(); ) {
str.append("*");
str.append(it.next());
if (it.hasNext()) {
str.append(", ");
@@ -105,4 +106,21 @@ public class DefaultDomain implements Domain {
}
return str.toString();
}
public String toUserFriendlyString() {
StringBuilder str = new StringBuilder();
if (players.size() > 0) {
str.append(toPlayersString());
}
if (groups.size() > 0) {
if (str.length() > 0) {
str.append("; ");
}
str.append(toGroupsString());
}
return str.toString();
}
}
@@ -19,7 +19,10 @@
package com.sk89q.worldguard.protection;
import java.util.SortedMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.protection.AreaFlags.State;
@@ -30,175 +33,154 @@ import com.sk89q.worldguard.protection.AreaFlags.State;
* @author sk89q
*/
public class ApplicableRegionSet {
private GlobalFlags global;
private Vector pt;
private SortedMap<String,ProtectedRegion> regions;
private Iterator<ProtectedRegion> applicable;
public ApplicableRegionSet(Vector pt, SortedMap<String,ProtectedRegion> regions) {
/**
* Construct the object.
*
* @param pt
* @param regions
* @param global
*/
public ApplicableRegionSet(Vector pt, Iterator<ProtectedRegion> applicable,
GlobalFlags global) {
this.pt = pt;
this.regions = regions;
this.applicable = applicable;
this.global = global;
}
/**
* Checks if a player can build in an area.
*
* @param player
* @return
*/
public boolean canBuild(LocalPlayer player) {
boolean found = false;
int lastPriority = 0;
return isFlagAllowed(AreaFlags.FLAG_BUILD, global.canBuild, player);
}
/**
* Checks a flag.
*
* @param player
* @return
*/
public boolean allowsFlag(String flag) {
boolean def = true;
if (flag.equals(AreaFlags.FLAG_CHEST_ACCESS)) {
def = global.canAccessChests;
} else if (flag.equals(AreaFlags.FLAG_PVP)) {
def = global.canPvP;
}
for (ProtectedRegion region : regions.values()) {
if (region.getFlags().allowBuild == State.ALLOW) continue;
if (!region.contains(pt)) continue;
return isFlagAllowed(flag, def, null);
}
/**
* Checks to see if a flag is permitted.
*
* @param def default state if there are no regions defined
* @param player null to not check owners and members
* @return
*/
private boolean isFlagAllowed(String flag, boolean def, LocalPlayer player) {
boolean found = false;
boolean allowed = false; // Used for ALLOW override
if (player == null) {
allowed = def;
}
int lastPriority = 0;
// The algorithm is as follows:
// While iterating through the list of regions, if an entry disallows
// the flag, then put it into the needsClear set. If an entry allows
// the flag and it has a parent, then its parent is put into hasCleared.
// In the situation that the child is reached before the parent, upon
// the parent being reached, even if the parent disallows, because the
// parent will be in hasCleared, permission will be allowed. In the
// other case, where the parent is reached first, if it does not allow
// permissions, it will be placed into needsClear. If a child of
// the parent is reached later, the parent will be removed from
// needsClear. At the end, if needsClear is not empty, that means that
// permission should not be given. If a parent has multiple children
// and one child does not allow permissions, then it will be placed into
// needsClear just like as if was a parent.
Set<ProtectedRegion> needsClear = new HashSet<ProtectedRegion>();
Set<ProtectedRegion> hasCleared = new HashSet<ProtectedRegion>();
while (applicable.hasNext()) {
ProtectedRegion region = applicable.next();
// Ignore lower priority regions
if (found && region.getPriority() < lastPriority) {
break;
// Ignore non-build regions
if (player != null && region.getFlags().get(AreaFlags.FLAG_PASSTHROUGH) == State.ALLOW) {
continue;
}
if (!region.getOwners().contains(player)) {
// Forget about regions that are not covered
if (!region.contains(pt)) {
continue;
}
// Allow DENY to override everything
if (region.getFlags().get(flag) == State.DENY) {
return false;
}
found = true;
lastPriority = region.getPriority();
}
return true;
}
public boolean allowsPvP() {
boolean found = false;
int lastPriority = 0;
for (ProtectedRegion region : regions.values()) {
if (!region.contains(pt)) continue;
if (region.getFlags().allowPvP == State.DENY) return false;
// Forget about regions that allow it, although make sure the
// default state is now to allow
if (region.getFlags().get(flag) == State.ALLOW) {
allowed = true;
found = true;
continue;
}
// Ignore lower priority regions
if (found && region.getPriority() < lastPriority) {
break;
}
found = true;
lastPriority = region.getPriority();
}
return true;
}
public boolean allowsMobDamage() {
boolean found = false;
int lastPriority = 0;
for (ProtectedRegion region : regions.values()) {
if (!region.contains(pt)) continue;
if (region.getFlags().allowMobDamage == State.DENY) return false;
// Ignore lower priority regions
if (found && region.getPriority() < lastPriority) {
break;
if (player != null) {
if (hasCleared.contains(region)) {
// Already cleared, so do nothing
} else {
if (!region.isMember(player)) {
needsClear.add(region);
} else {
// Need to clear all parents
clearParents(needsClear, hasCleared, region);
}
}
}
found = true;
lastPriority = region.getPriority();
}
return true;
return (found == false ? def : allowed)
|| (player != null && needsClear.size() == 0);
}
public boolean allowsCreeperExplosions() {
boolean found = false;
int lastPriority = 0;
/**
* Clear a region's parents for isFlagAllowed().
*
* @param needsClear
* @param hasCleared
* @param region
*/
private void clearParents(Set<ProtectedRegion> needsClear,
Set<ProtectedRegion> hasCleared, ProtectedRegion region) {
ProtectedRegion parent = region.getParent();
for (ProtectedRegion region : regions.values()) {
if (!region.contains(pt)) continue;
if (region.getFlags().allowCreeperExplosions == State.DENY) return false;
// Ignore lower priority regions
if (found && region.getPriority() < lastPriority) {
break;
while (parent != null) {
if (!needsClear.remove(parent)) {
hasCleared.add(parent);
}
found = true;
lastPriority = region.getPriority();
parent = parent.getParent();
}
return true;
}
public boolean allowsTNT() {
boolean found = false;
int lastPriority = 0;
for (ProtectedRegion region : regions.values()) {
if (!region.contains(pt)) continue;
if (region.getFlags().allowTNT == State.DENY) return false;
// Ignore lower priority regions
if (found && region.getPriority() < lastPriority) {
break;
}
found = true;
lastPriority = region.getPriority();
}
return true;
}
public boolean allowsLighter() {
boolean found = false;
int lastPriority = 0;
for (ProtectedRegion region : regions.values()) {
if (!region.contains(pt)) continue;
if (region.getFlags().allowLighter == State.DENY) return false;
// Ignore lower priority regions
if (found && region.getPriority() < lastPriority) {
break;
}
found = true;
lastPriority = region.getPriority();
}
return true;
}
public boolean allowsFireSpread() {
boolean found = false;
int lastPriority = 0;
for (ProtectedRegion region : regions.values()) {
if (!region.contains(pt)) continue;
if (region.getFlags().allowFireSpread == State.DENY) return false;
// Ignore lower priority regions
if (found && region.getPriority() < lastPriority) {
break;
}
found = true;
lastPriority = region.getPriority();
}
return true;
}
public boolean allowsLavaFire() {
boolean found = false;
int lastPriority = 0;
for (ProtectedRegion region : regions.values()) {
if (!region.contains(pt)) continue;
if (region.getFlags().allowLavaFire == State.DENY) return false;
// Ignore lower priority regions
if (found && region.getPriority() < lastPriority) {
break;
}
found = true;
lastPriority = region.getPriority();
}
return true;
}
}
@@ -19,7 +19,12 @@
package com.sk89q.worldguard.protection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* Holds the flags for a region.
*
* @author sk89q
*/
@@ -30,14 +35,103 @@ public class AreaFlags {
DENY,
};
public State allowBuild = State.NONE;
public State allowPvP = State.NONE;
public State allowMobDamage = State.NONE;
public State allowCreeperExplosions = State.NONE;
public State allowTNT = State.NONE;
public State allowLighter = State.NONE;
public State allowFireSpread = State.NONE;
public State allowLavaFire = State.NONE;
public static final String FLAG_PASSTHROUGH = "z";
public static final String FLAG_BUILD = "b";
public static final String FLAG_PVP = "p";
public static final String FLAG_MOB_DAMAGE = "m";
public static final String FLAG_CREEPER_EXPLOSION = "c";
public static final String FLAG_TNT = "t";
public static final String FLAG_LIGHTER = "l";
public static final String FLAG_FIRE_SPREAD = "f";
public static final String FLAG_LAVA_FIRE = "F";
public static final String FLAG_CHEST_ACCESS = "C";
/**
* Get the user-friendly name of a flag. If a name isn't known, then
* the flag is returned unchanged.
*
* @param flag
* @return
*/
public static String getFlagName(String flag) {
if (flag.equals(FLAG_PASSTHROUGH)) {
return "passthrough";
} else if (flag.equals(FLAG_BUILD)) {
return "build";
} else if (flag.equals(FLAG_PVP)) {
return "PvP";
} else if (flag.equals(FLAG_MOB_DAMAGE)) {
return "mob damage";
} else if (flag.equals(FLAG_CREEPER_EXPLOSION)) {
return "creeper explosion";
} else if (flag.equals(FLAG_TNT)) {
return "TNT";
} else if (flag.equals(FLAG_LIGHTER)) {
return "lighter";
} else if (flag.equals(FLAG_FIRE_SPREAD)) {
return "fire spread";
} else if (flag.equals(FLAG_LAVA_FIRE)) {
return "lava fire spread";
} else if (flag.equals(FLAG_CHEST_ACCESS)) {
return "chest access";
} else {
return flag;
}
}
/**
* Gets a flag from an alias. May return null.
*
* @param name
* @return
*/
public static String fromAlias(String name) {
if (name.equalsIgnoreCase("passthrough")) {
return FLAG_PASSTHROUGH;
} else if (name.equalsIgnoreCase("build")) {
return FLAG_BUILD;
} else if (name.equalsIgnoreCase("pvp")) {
return FLAG_PVP;
} else if (name.equalsIgnoreCase("mobdamage")) {
return FLAG_MOB_DAMAGE;
} else if (name.equalsIgnoreCase("creeper")) {
return FLAG_CREEPER_EXPLOSION;
} else if (name.equalsIgnoreCase("tnt")) {
return FLAG_TNT;
} else if (name.equalsIgnoreCase("lighter")) {
return FLAG_LIGHTER;
} else if (name.equalsIgnoreCase("firespread")) {
return FLAG_FIRE_SPREAD;
} else if (name.equalsIgnoreCase("lavafirespread")) {
return FLAG_LAVA_FIRE;
} else if (name.equalsIgnoreCase("chest")) {
return FLAG_CHEST_ACCESS;
} else {
return null;
}
}
private Map<String, State> states = new HashMap<String, State>();
public State get(String flag) {
State state = states.get(flag);
if (state == null) {
return State.NONE;
}
return state;
}
public void set(String flag, State state) {
if (state == State.NONE) {
states.remove(flag);
} else {
states.put(flag, state);
}
}
public Set<Map.Entry<String, State>> entrySet() {
return states.entrySet();
}
@Override
public boolean equals(Object obj) {
@@ -46,14 +140,6 @@ public class AreaFlags {
}
AreaFlags other = (AreaFlags)obj;
return other.allowBuild == allowBuild
&& other.allowPvP == allowPvP
&& other.allowMobDamage == allowMobDamage
&& other.allowCreeperExplosions == allowCreeperExplosions
&& other.allowTNT == allowTNT
&& other.allowLighter == allowLighter
&& other.allowFireSpread == allowFireSpread
&& other.allowLavaFire == allowLavaFire;
return other.states.equals(this);
}
}
@@ -20,6 +20,7 @@
package com.sk89q.worldguard.protection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.logging.Logger;
import java.util.regex.Matcher;
@@ -31,6 +32,8 @@ import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.protection.AreaFlags.State;
import com.sk89q.worldguard.protection.ProtectedRegion.CircularInheritanceException;
import com.sk89q.worldguard.util.ArrayReader;
/**
* Represents a protected area database that uses CSV files.
@@ -82,7 +85,7 @@ public class CSVDatabase implements ProtectionDatabase {
writer.writeNext(new String[] {
id,
"cuboid",
"cuboid.2",
String.valueOf(min.getBlockX()),
String.valueOf(min.getBlockY()),
String.valueOf(min.getBlockZ()),
@@ -90,9 +93,12 @@ public class CSVDatabase implements ProtectionDatabase {
String.valueOf(max.getBlockY()),
String.valueOf(max.getBlockZ()),
String.valueOf(cuboid.getPriority()),
cuboid.getParent() != null ? cuboid.getParent().getId() : "",
writeDomains(cuboid.getOwners()),
writeDomains(cuboid.getMembers()),
writeFlags(cuboid.getFlags()),
cuboid.getEnterMessage(),
cuboid.getEnterMessage() != null ? cuboid.getEnterMessage() : "",
cuboid.getLeaveMessage() != null ? cuboid.getLeaveMessage() : "",
});
}
} finally {
@@ -110,6 +116,8 @@ public class CSVDatabase implements ProtectionDatabase {
public void load() throws IOException {
Map<String,ProtectedRegion> regions =
new HashMap<String,ProtectedRegion>();
Map<ProtectedRegion,String> parentSets =
new LinkedHashMap<ProtectedRegion, String>();
CSVReader reader = new CSVReader(new FileReader(file));
@@ -117,16 +125,21 @@ public class CSVDatabase implements ProtectionDatabase {
String[] line;
while ((line = reader.readNext()) != null) {
if (line.length >= 12) {
String type = line[1];
if (!type.equalsIgnoreCase("cuboid")) {
logger.warning("Only cuboid region types are supported: "
+ line);
break;
if (line.length < 2) {
logger.warning("Invalid region definition: " + line);
continue;
}
String id = line[0].toLowerCase();
String type = line[1];
ArrayReader<String> entries = new ArrayReader<String>(line);
if (type.equalsIgnoreCase("cuboid")) {
if (line.length < 8) {
logger.warning("Invalid region definition: " + line);
continue;
}
String id = line[0];
Vector pt1 = new Vector(
Integer.parseInt(line[2]),
Integer.parseInt(line[3]),
@@ -139,19 +152,51 @@ public class CSVDatabase implements ProtectionDatabase {
BlockVector min = Vector.getMinimum(pt1, pt2).toBlockVector();
BlockVector max = Vector.getMaximum(pt1, pt2).toBlockVector();
int priority = Integer.parseInt(line[8]);
String ownersData = line[9];
String flagsData = line[10];
String enterMessage = line[11];
int priority = entries.get(8) == null ? 0 : Integer.parseInt(entries.get(8));
String ownersData = entries.get(9);
String flagsData = entries.get(10);
String enterMessage = nullEmptyString(entries.get(11));
ProtectedRegion region = new ProtectedCuboidRegion(min, max);
ProtectedRegion region = new ProtectedCuboidRegion(id, min, max);
region.setPriority(priority);
region.setFlags(parseFlags(flagsData));
region.setOwners(this.parseDomains(ownersData));
region.setEnterMessage(enterMessage);
region.setFlags(parseFlags(flagsData));
regions.put(id, region);
} else {
logger.warning("Line is invalid: " + line);
} else if (type.equalsIgnoreCase("cuboid.2")) {
Vector pt1 = new Vector(
Integer.parseInt(line[2]),
Integer.parseInt(line[3]),
Integer.parseInt(line[4]));
Vector pt2 = new Vector(
Integer.parseInt(line[5]),
Integer.parseInt(line[6]),
Integer.parseInt(line[7]));
BlockVector min = Vector.getMinimum(pt1, pt2).toBlockVector();
BlockVector max = Vector.getMaximum(pt1, pt2).toBlockVector();
int priority = entries.get(8) == null ? 0 : Integer.parseInt(entries.get(8));
String parentId = entries.get(9);
String ownersData = entries.get(10);
String membersData = entries.get(11);
String flagsData = entries.get(12);
String enterMessage = nullEmptyString(entries.get(13));
String leaveMessage = nullEmptyString(entries.get(14));
ProtectedRegion region = new ProtectedCuboidRegion(id, min, max);
region.setPriority(priority);
region.setFlags(parseFlags(flagsData));
region.setOwners(this.parseDomains(ownersData));
region.setMembers(this.parseDomains(membersData));
region.setEnterMessage(enterMessage);
region.setLeaveMessage(leaveMessage);
regions.put(id, region);
// Link children to parents later
if (parentId.length() > 0) {
parentSets.put(region, parentId);
}
}
}
} finally {
@@ -161,6 +206,20 @@ public class CSVDatabase implements ProtectionDatabase {
}
}
for (Map.Entry<ProtectedRegion, String> entry : parentSets.entrySet()) {
ProtectedRegion parent = regions.get(entry.getValue());
if (parent != null) {
try {
entry.getKey().setParent(parent);
} catch (CircularInheritanceException e) {
logger.warning("Circular inheritance detect with '"
+ entry.getValue() + "' detected as a parent");
}
} else {
logger.warning("Unknown region parent: " + entry.getValue());
}
}
this.regions = regions;
}
@@ -191,6 +250,10 @@ public class CSVDatabase implements ProtectionDatabase {
* @return
*/
private DefaultDomain parseDomains(String data) {
if (data == null) {
return new DefaultDomain();
}
DefaultDomain domain = new DefaultDomain();
Pattern pattern = Pattern.compile("^([A-Za-z]):(.*)$");
@@ -230,33 +293,32 @@ public class CSVDatabase implements ProtectionDatabase {
* @return
*/
private AreaFlags parseFlags(String data) {
if (data == null) {
return new AreaFlags();
}
AreaFlags flags = new AreaFlags();
State curState = State.ALLOW;
for (int i = 0; i < data.length(); i++) {
char flag = data.charAt(i);
if (flag == '+') {
char k = data.charAt(i);
if (k == '+') {
curState = State.ALLOW;
} else if (flag == '-') {
} else if (k == '-') {
curState = State.DENY;
} else if (flag == 'b') {
flags.allowBuild = curState;
} else if (flag == 'p') {
flags.allowPvP = curState;
} else if (flag == 'm') {
flags.allowMobDamage = curState;
} else if (flag == 'c') {
flags.allowCreeperExplosions = curState;
} else if (flag == 't') {
flags.allowTNT = curState;
} else if (flag == 'l') {
flags.allowLighter = curState;
} else if (flag == 'f') {
flags.allowFireSpread = curState;
} else if (flag == 'F') {
flags.allowLavaFire = curState;
} else {
logger.warning("Unknown area flag/flag modifier: " + flag);
String flag;
if (k == '_') {
if (i == data.length() - 1) {
logger.warning("_ read ahead fail");
break;
}
flag = "_" + data.charAt(i + 1);
i++;
} else {
flag = String.valueOf(k);
}
flags.set(flag, curState);
}
}
@@ -302,6 +364,22 @@ public class CSVDatabase implements ProtectionDatabase {
return "";
}
/**
* Returns a null if a string is null or empty.
*
* @param str
* @return
*/
private String nullEmptyString(String str) {
if (str == null) {
return null;
} else if (str.length() == 0) {
return null;
} else {
return str;
}
}
/**
* Used to write the list of flags.
*
@@ -310,14 +388,9 @@ public class CSVDatabase implements ProtectionDatabase {
*/
private String writeFlags(AreaFlags flags) {
StringBuilder str = new StringBuilder();
str.append(writeFlag(flags.allowBuild, "b"));
str.append(writeFlag(flags.allowPvP, "p"));
str.append(writeFlag(flags.allowMobDamage, "m"));
str.append(writeFlag(flags.allowCreeperExplosions, "c"));
str.append(writeFlag(flags.allowTNT, "t"));
str.append(writeFlag(flags.allowLighter, "l"));
str.append(writeFlag(flags.allowFireSpread, "f"));
str.append(writeFlag(flags.allowLavaFire, "F"));
for (Map.Entry<String, State> entry : flags.entrySet()) {
str.append(writeFlag(entry.getValue(), entry.getKey()));
}
return str.toString();
}
@@ -38,13 +38,18 @@ public class FlatRegionManager implements RegionManager {
/**
* List of protected regions.
*/
private SortedMap<String,ProtectedRegion> regions;
private Map<String,ProtectedRegion> regions;
/**
* Global flags.
*/
private GlobalFlags global;
/**
* Construct the manager.
*/
public FlatRegionManager() {
public FlatRegionManager(GlobalFlags global) {
regions = new TreeMap<String,ProtectedRegion>();
this.global = global;
}
/**
@@ -55,7 +60,6 @@ public class FlatRegionManager implements RegionManager {
public Map<String,ProtectedRegion> getRegions() {
return regions;
}
/**
* Set a list of protected regions.
@@ -65,23 +69,34 @@ public class FlatRegionManager implements RegionManager {
public void setRegions(Map<String,ProtectedRegion> regions) {
this.regions = new TreeMap<String,ProtectedRegion>(regions);
}
/**
* Adds a region.
*
* @param id
* @param region
*/
public void addRegion(String id, ProtectedRegion region) {
regions.put(id, region);
public void addRegion(ProtectedRegion region) {
regions.put(region.getId(), region);
}
/**
* Removes a region.
* Removes a region and its children.
*
* @param id
*/
public void removeRegion(String id) {
ProtectedRegion region = regions.get(id);
regions.remove(id);
if (region != null) {
for (Map.Entry<String, ProtectedRegion> entry : regions.entrySet()) {
if (entry.getValue().getParent() == region) {
removeRegion(entry.getKey());
}
}
}
}
/**
@@ -110,7 +125,7 @@ public class FlatRegionManager implements RegionManager {
* @return
*/
public ApplicableRegionSet getApplicableRegions(Vector pt) {
return new ApplicableRegionSet(pt, regions);
return new ApplicableRegionSet(pt, regions.values().iterator(), global);
}
/**
@@ -0,0 +1,31 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection;
/**
* Used for default flags.
*
* @author sk89q
*/
public class GlobalFlags {
public boolean canBuild = true;
public boolean canAccessChests = false;
public boolean canPvP = true;
}
@@ -0,0 +1,203 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.khelekore.prtree.MBRConverter;
import org.khelekore.prtree.PRTree;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.LocalPlayer;
public class PRTreeRegionManager implements RegionManager {
private static final int BRANCH_FACTOR = 30;
/**
* List of protected regions.
*/
private Map<String,ProtectedRegion> regions;
/**
* Global flags.
*/
private GlobalFlags global;
/**
* Converter to get coordinates of the tree.
*/
private MBRConverter<ProtectedRegion> converter
= new ProtectedRegionMBRConverter();
/**
* Priority R-tree.
*/
private PRTree<ProtectedRegion> tree;
/**
* Construct the manager.
*/
public PRTreeRegionManager(GlobalFlags global) {
regions = new TreeMap<String,ProtectedRegion>();
tree = new PRTree<ProtectedRegion>(converter, BRANCH_FACTOR);
this.global = global;
}
/**
* Get a list of protected regions.
*
* @return
*/
public Map<String,ProtectedRegion> getRegions() {
return regions;
}
/**
* Set a list of protected regions.
*
* @return
*/
public void setRegions(Map<String,ProtectedRegion> regions) {
this.regions = new TreeMap<String,ProtectedRegion>(regions);
tree = new PRTree<ProtectedRegion>(converter, BRANCH_FACTOR);
tree.load(regions.values());
}
/**
* Adds a region.
*
* @param id
* @param region
*/
public void addRegion(ProtectedRegion region) {
regions.put(region.getId(), region);
tree = new PRTree<ProtectedRegion>(converter, BRANCH_FACTOR);
tree.load(regions.values());
}
/**
* Return whether a region exists by an ID.
*
* @param id
* @return
*/
public boolean hasRegion(String id) {
return regions.containsKey(id);
}
/**
* Get a region by its ID.
*
* @param id
*/
public ProtectedRegion getRegion(String id) {
return regions.get(id);
}
/**
* Removes a region and its children.
*
* @param id
*/
public void removeRegion(String id) {
ProtectedRegion region = regions.get(id);
regions.remove(id);
if (region != null) {
for (Map.Entry<String, ProtectedRegion> entry : regions.entrySet()) {
if (entry.getValue().getParent() == region) {
removeRegion(entry.getKey());
}
}
}
tree = new PRTree<ProtectedRegion>(converter, BRANCH_FACTOR);
tree.load(regions.values());
}
/**
* Get an object for a point for rules to be applied with.
*
* @param pt
* @return
*/
public ApplicableRegionSet getApplicableRegions(Vector pt) {
return new ApplicableRegionSet(pt, regions.values().iterator(), global);
}
/**
* Get a list of region IDs that contain a point.
*
* @param pt
* @return
*/
public List<String> getApplicableRegionsIDs(Vector pt) {
List<String> applicable = new ArrayList<String>();
int x = pt.getBlockX();
int z = pt.getBlockZ();
for (ProtectedRegion region : tree.find(x, z, x, z)) {
if (region.contains(pt)) {
applicable.add(region.getId());
}
}
return applicable;
}
/**
* Returns true if the provided region overlaps with any other region that
* is not owned by the player.
*
* @param region
* @param player
* @return
*/
public boolean overlapsUnownedRegion(ProtectedRegion region, LocalPlayer player) {
for (ProtectedRegion other : regions.values()) {
if (other.getOwners().contains(player)) {
continue;
}
try {
if (ProtectedRegion.intersects(region, other)) {
return true;
}
} catch (UnsupportedIntersectionException e) {
// TODO: Maybe do something here
}
}
return false;
}
/**
* Get the number of regions.
*
* @return
*/
public int size() {
return regions.size();
}
}
@@ -39,12 +39,13 @@ public class ProtectedCuboidRegion extends ProtectedRegion {
/**
* Construct a new instance of this cuboid region.
*
* @param id
* @param pos1
* @param pos2
* @param priority
*/
public ProtectedCuboidRegion(BlockVector min, BlockVector max) {
super();
public ProtectedCuboidRegion(String id, BlockVector min, BlockVector max) {
super(id);
this.min = min;
this.max = max;
}
@@ -85,6 +86,9 @@ public class ProtectedCuboidRegion extends ProtectedRegion {
max = pt;
}
/**
* Checks to see if a point is inside this region.
*/
@Override
public boolean contains(Vector pt) {
int x = pt.getBlockX();
@@ -94,4 +98,13 @@ public class ProtectedCuboidRegion extends ProtectedRegion {
&& y >= min.getBlockY() && y <= max.getBlockY()
&& z >= min.getBlockZ() && z <= max.getBlockZ();
}
/**
* Return the type of region as a user-friendly name.
*
* @return type of region
*/
public String getTypeName() {
return "cuboid";
}
}
@@ -21,6 +21,7 @@ package com.sk89q.worldguard.protection;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.domains.DefaultDomain;
/**
@@ -30,36 +31,68 @@ import com.sk89q.worldguard.domains.DefaultDomain;
*/
public abstract class ProtectedRegion implements Comparable<ProtectedRegion> {
/**
* Area message.
* Holds the region's ID.
*/
private String enterMessage;
/**
* List of owners.
*/
private DefaultDomain owners = new DefaultDomain();
private String id;
/**
* Priority.
*/
private int priority = 0;
/**
* Parent region.
*/
private ProtectedRegion parent;
/**
* List of owners.
*/
private DefaultDomain owners = new DefaultDomain();
/**
* List of members.
*/
private DefaultDomain members = new DefaultDomain();
/**
* Area flags.
*/
private AreaFlags flags = new AreaFlags();
/**
* Area message.
*/
private String enterMessage;
/**
* Area message.
*/
private String leaveMessage;
/**
* Construct a new instance of this region.
*
* @param id
* @param priority
* @param owners
* @param enterMessage
*/
public ProtectedRegion() {
this.priority = 0;
this.owners = new DefaultDomain();
this.enterMessage = null;
public ProtectedRegion(String id) {
this.id = id;
}
/**
* @return the id
*/
public String getId() {
return id;
}
/**
* Get the lower point of the cuboid.
*
* @return min point
*/
public abstract BlockVector getMinimumPoint();
/**
* Get the upper point of the cuboid.
*
* @return max point
*/
public abstract BlockVector getMaximumPoint();
/**
* @return the priority
*/
@@ -74,6 +107,41 @@ public abstract class ProtectedRegion implements Comparable<ProtectedRegion> {
this.priority = priority;
}
/**
* @return the parent
*/
public ProtectedRegion getParent() {
return parent;
}
/**
* Set the parent. This checks to make sure that it will not result
* in circular inheritance.
*
* @param parent the parent to set
* @throws CircularInheritanceException
*/
public void setParent(ProtectedRegion parent) throws CircularInheritanceException {
if (parent == null) {
this.parent = null;
return;
}
if (parent == this) {
throw new CircularInheritanceException();
}
ProtectedRegion p = parent.getParent();
while (p != null) {
if (p == this) {
throw new CircularInheritanceException();
}
p = p.getParent();
}
this.parent = parent;
}
/**
* Se flags.
* @param flags
@@ -95,6 +163,20 @@ public abstract class ProtectedRegion implements Comparable<ProtectedRegion> {
public void setEnterMessage(String enterMessage) {
this.enterMessage = enterMessage;
}
/**
* @return the leaveMessage
*/
public String getLeaveMessage() {
return leaveMessage;
}
/**
* @param leaveMessage the leaveMessage to set
*/
public void setLeaveMessage(String leaveMessage) {
this.leaveMessage = leaveMessage;
}
/**
* @return the owners
@@ -110,6 +192,67 @@ public abstract class ProtectedRegion implements Comparable<ProtectedRegion> {
this.owners = owners;
}
/**
* @return the members
*/
public DefaultDomain getMembers() {
return members;
}
/**
* @param owners the owners to set
*/
public void setMembers(DefaultDomain members) {
this.members = members;
}
/**
* Checks whether a player is an owner of region or any of its parents.
*
* @param player
* @return
*/
public boolean isOwner(LocalPlayer player) {
if (owners.contains(player)) {
return true;
}
ProtectedRegion parent = getParent();
while (parent != null) {
if (parent.getOwners().contains(player)) {
return true;
}
parent = parent.getParent();
}
return false;
}
/**
* Checks whether a player is a member of the region or any of its parents.
*
* @param player
* @return
*/
public boolean isMember(LocalPlayer player) {
if (owners.contains(player) || members.contains(player)) {
return true;
}
ProtectedRegion parent = getParent();
while (parent != null) {
if (parent.getOwners().contains(player)
|| parent.getMembers().contains(player)) {
return true;
}
parent = parent.getParent();
}
return false;
}
/**
* Get flags.
*
@@ -143,6 +286,13 @@ public abstract class ProtectedRegion implements Comparable<ProtectedRegion> {
}
}
/**
* Return the type of region as a user-friendly, lowercase name.
*
* @return type of region
*/
public abstract String getTypeName();
/**
* Checks if two region intersects.
*
@@ -172,4 +322,13 @@ public abstract class ProtectedRegion implements Comparable<ProtectedRegion> {
throw new UnsupportedIntersectionException();
}
}
/**
* Thrown when setting a parent would create a circular inheritance
* situation.
*
*/
public static class CircularInheritanceException extends Exception {
private static final long serialVersionUID = 7479613488496776022L;
}
}
@@ -0,0 +1,41 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection;
import org.khelekore.prtree.MBRConverter;
public class ProtectedRegionMBRConverter implements MBRConverter<ProtectedRegion> {
public double getMinX(ProtectedRegion t) {
return t.getMinimumPoint().getBlockX();
}
public double getMinY(ProtectedRegion t) {
return t.getMinimumPoint().getBlockZ();
}
public double getMaxX(ProtectedRegion t) {
return t.getMaximumPoint().getBlockX();
}
public double getMaxY(ProtectedRegion t) {
return t.getMaximumPoint().getBlockZ();
}
}
@@ -53,7 +53,7 @@ public interface RegionManager {
* @param id
* @param region
*/
public void addRegion(String id, ProtectedRegion region);
public void addRegion(ProtectedRegion region);
/**
* Return whether a region exists by an ID.
@@ -71,7 +71,7 @@ public interface RegionManager {
public ProtectedRegion getRegion(String id);
/**
* Removes a region.
* Removes a region, including inheriting children.
*
* @param id
*/
@@ -0,0 +1,44 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.util;
public class ArrayReader<T> {
private T[] arr;
public ArrayReader(T[] arr) {
this.arr = arr;
}
public T get(int index) {
if (arr.length > index) {
return arr[index];
} else {
return null;
}
}
public T get(int index, T def) {
if (arr.length > index) {
return arr[index];
} else {
return def;
}
}
}
+1 -2
View File
@@ -19,7 +19,6 @@
package com.sk89q.worldguard;
import java.util.List;
import java.util.Set;
import java.util.HashSet;
import com.sk89q.worldedit.Vector;
@@ -72,7 +71,7 @@ public class TestPlayer extends LocalPlayer {
}
@Override
public List<String> getGroups() {
public String[] getGroups() {
// TODO Auto-generated method stub
return null;
}
@@ -26,27 +26,33 @@ import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.TestPlayer;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.protection.AreaFlags.State;
public class ApplicableRegionSetTest {
static String COURTYARD_ID = "courtyard";
static String FOUNTAIN_ID = "fountain";
static String NO_FIRE_ID = "nofire";
static String MEMBER_GROUP = "member";
static String COURTYARD_GROUP = "courtyard";
Vector inFountain = new Vector(2, 2, 2);
Vector inCourtyard = new Vector(7, 7, 7);
Vector outside = new Vector(15, 15, 15);
Vector inNoFire = new Vector(150, 150, 150);
RegionManager manager;
ProtectedRegion courtyard;
ProtectedRegion fountain;
TestPlayer player1;
TestPlayer player2;
@Before
public void setUp() throws Exception {
manager = new FlatRegionManager();
manager = new FlatRegionManager(new GlobalFlags());
setUpPlayers();
setUpCourtyardRegion();
setUpFountainRegion();
setUpNoFireRegion();
}
void setUpPlayers() {
@@ -62,24 +68,41 @@ public class ApplicableRegionSetTest {
DefaultDomain domain = new DefaultDomain();
domain.addGroup(COURTYARD_GROUP);
ProtectedRegion region = new ProtectedCuboidRegion(
ProtectedRegion region = new ProtectedCuboidRegion(COURTYARD_ID,
new BlockVector(0, 0, 0), new BlockVector(10, 10, 10));
AreaFlags flags = new AreaFlags();
flags.allowBuild = AreaFlags.State.NONE;
flags.allowFireSpread = AreaFlags.State.ALLOW;
flags.set(AreaFlags.FLAG_BUILD, State.NONE);
flags.set(AreaFlags.FLAG_FIRE_SPREAD, State.ALLOW);
region.setFlags(flags);
region.setOwners(domain);
manager.addRegion(COURTYARD_ID, region);
manager.addRegion(region);
courtyard = region;
}
void setUpFountainRegion() {
ProtectedRegion region = new ProtectedCuboidRegion(
void setUpFountainRegion() throws Exception {
DefaultDomain domain = new DefaultDomain();
domain.addGroup(MEMBER_GROUP);
ProtectedRegion region = new ProtectedCuboidRegion(FOUNTAIN_ID,
new BlockVector(0, 0, 0), new BlockVector(5, 5, 5));
AreaFlags flags = new AreaFlags();
flags.allowBuild = AreaFlags.State.ALLOW;
flags.allowFireSpread = AreaFlags.State.DENY;
flags.set(AreaFlags.FLAG_FIRE_SPREAD, State.DENY);
region.setFlags(flags);
manager.addRegion(FOUNTAIN_ID, region);
region.setMembers(domain);
manager.addRegion(region);
fountain = region;
fountain.setParent(courtyard);
}
void setUpNoFireRegion() throws Exception {
ProtectedRegion region = new ProtectedCuboidRegion(NO_FIRE_ID,
new BlockVector(100, 100, 100), new BlockVector(200, 200, 200));
AreaFlags flags = new AreaFlags();
flags.set(AreaFlags.FLAG_FIRE_SPREAD, State.DENY);
region.setFlags(flags);
manager.addRegion(region);
}
@Test
@@ -88,13 +111,17 @@ public class ApplicableRegionSetTest {
// Outside
appl = manager.getApplicableRegions(outside);
assertTrue(appl.allowsFireSpread());
assertTrue(appl.allowsFlag(AreaFlags.FLAG_FIRE_SPREAD));
// Inside courtyard
appl = manager.getApplicableRegions(inCourtyard);
assertTrue(appl.allowsFireSpread());
assertTrue(appl.allowsFlag(AreaFlags.FLAG_FIRE_SPREAD));
// Inside fountain
appl = manager.getApplicableRegions(inFountain);
assertFalse(appl.allowsFireSpread());
assertFalse(appl.allowsFlag(AreaFlags.FLAG_FIRE_SPREAD));
// Inside no fire zone
appl = manager.getApplicableRegions(inNoFire);
assertFalse(appl.allowsFlag(AreaFlags.FLAG_FIRE_SPREAD));
}
@Test
@@ -28,6 +28,7 @@ import org.junit.Test;
import static org.junit.Assert.*;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.protection.AreaFlags.State;
public class CSVDatabaseTest {
@Before
@@ -63,9 +64,9 @@ public class CSVDatabaseTest {
private void checkTestRegion1(ProtectedRegion region) {
AreaFlags flags = new AreaFlags();
flags.allowFireSpread = AreaFlags.State.ALLOW;
flags.allowPvP = AreaFlags.State.DENY;
flags.allowLighter = AreaFlags.State.DENY;
flags.set(AreaFlags.FLAG_FIRE_SPREAD, State.ALLOW);
flags.set(AreaFlags.FLAG_PVP, State.DENY);
flags.set(AreaFlags.FLAG_LIGHTER, State.DENY);
region.setFlags(flags);
assertEquals(region.getFlags(), flags);
@@ -75,12 +76,12 @@ public class CSVDatabaseTest {
BlockVector min = new BlockVector(1, 2, 3);
BlockVector max = new BlockVector(4, 5, 6);
ProtectedRegion region = new ProtectedCuboidRegion(min, max);
ProtectedRegion region = new ProtectedCuboidRegion("test2", min, max);
AreaFlags flags = new AreaFlags();
flags.allowFireSpread = AreaFlags.State.ALLOW;
flags.allowPvP = AreaFlags.State.DENY;
flags.allowLighter = AreaFlags.State.DENY;
flags.set(AreaFlags.FLAG_FIRE_SPREAD, State.ALLOW);
flags.set(AreaFlags.FLAG_PVP, State.DENY);
flags.set(AreaFlags.FLAG_LIGHTER, State.DENY);
region.setFlags(flags);
DefaultDomain domain = new DefaultDomain();
@@ -101,12 +102,12 @@ public class CSVDatabaseTest {
BlockVector min = new BlockVector(7, 8, 9);
BlockVector max = new BlockVector(10, 11, 12);
ProtectedRegion region = new ProtectedCuboidRegion(min, max);
ProtectedRegion region = new ProtectedCuboidRegion("test2", min, max);
AreaFlags flags = new AreaFlags();
flags.allowFireSpread = AreaFlags.State.DENY;
flags.allowPvP = AreaFlags.State.ALLOW;
flags.allowMobDamage = AreaFlags.State.DENY;
flags.set(AreaFlags.FLAG_FIRE_SPREAD, State.ALLOW);
flags.set(AreaFlags.FLAG_PVP, State.ALLOW);
flags.set(AreaFlags.FLAG_LIGHTER, State.DENY);
region.setFlags(flags);
DefaultDomain domain = new DefaultDomain();