Compare commits

..
8 Commits
14 changed files with 619 additions and 275 deletions

No files matched your search

+4
View File
@@ -1,3 +1,7 @@
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.
+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.
+8 -2
View File
@@ -10,7 +10,11 @@
<property name="docs.dir" location="docs"/>
<fileset id="libs" dir="${lib.dir}">
<include name="*.jar"/>
<include name="truezip.jar" />
<include name="Bukkit.jar" />
<include name="Craftbukkit.jar" />
<include name="WorldEdit.jar" />
<include name="prtree.jar" />
</fileset>
<target name="init">
@@ -41,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 -->
+2
View File
@@ -21,6 +21,8 @@
summary-on-start: on
suppress-tick-sync-warnings: false
protection:
enforce-single-session: on
item-durability: on
BIN
View File
Binary file not shown.
@@ -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;
}
}
@@ -426,9 +426,9 @@ public class WorldGuardBlockListener extends BlockListener {
* @param event Relevant event details
*/
@Override
public void onBlockRedstoneChange(BlockFromToEvent event) {
public void onBlockRedstoneChange(BlockRedstoneEvent event) {
World world = event.getBlock().getWorld();
Block blockTo = event.getToBlock();
Block blockTo = event.getBlock();
if (plugin.simulateSponge && plugin.redstoneSponges) {
int ox = blockTo.getX();
@@ -15,8 +15,7 @@
*
* 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;
@@ -34,252 +33,241 @@ 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();
if (plugin.disableContactDamage && type == DamageCause.CONTACT) {
event.setCancelled(true);
return;
}
}
}
if (defender instanceof Player)
{
Player player = (Player)defender;
@Override
public void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
Entity attacker = event.getDamager();
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 (attacker != null && attacker instanceof Player) {
if (plugin.useRegions) {
Vector pt = toVector(defender.getLocation());
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 (attacker != null && attacker instanceof Monster) {
if (attacker instanceof Creeper && plugin.blockCreeperExplosions) {
event.setCancelled(true);
return;
}
if (plugin.useRegions) {
Vector pt = toVector(defender.getLocation());
if (!plugin.regionManager.getApplicableRegions(pt)
.allowsFlag(AreaFlags.FLAG_MOB_DAMAGE)) {
event.setCancelled(true);
return;
}
if (attacker instanceof Creeper) {
if (!plugin.regionManager.getApplicableRegions(pt)
.allowsFlag(AreaFlags.FLAG_CREEPER_EXPLOSION)) {
event.setCancelled(true);
return;
}
}
}
}
}
}
public void onEntityDamageByProjectile(EntityDamageByProjectileEvent event) {
Entity defender = event.getEntity();
Entity attacker = event.getDamager();
if (defender instanceof Player) {
Player player = (Player)defender;
if (plugin.disableContactDamage && type == DamageCause.CONTACT)
{
event.setCancelled(true);
return;
}
if (plugin.invinciblePlayers.contains(player.getName())) {
event.setCancelled(true);
return;
}
if (type == DamageCause.ENTITY_ATTACK)
{
Entity attacker = ((EntityDamageByEntityEvent)event).getDamager();
if (attacker != null && attacker instanceof Player) {
if (plugin.useRegions) {
Vector pt = toVector(defender.getLocation());
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.invinciblePlayers.contains(player.getName()))
{
event.setCancelled(true);
return;
}
}
if (attacker != null && attacker instanceof Player)
{
if (plugin.useRegions)
{
Vector pt = toVector(defender.getLocation());
public void onEntityDamage(EntityDamageEvent event) {
Entity defender = event.getEntity();
DamageCause type = event.getCause();
if (defender instanceof Player) {
Player player = (Player)defender;
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.invinciblePlayers.contains(player.getName())) {
event.setCancelled(true);
return;
}
if (plugin.disableFallDamage && type == DamageCause.FALL) {
event.setCancelled(true);
return;
}
if (attacker != null && attacker instanceof Monster)
{
if (attacker instanceof Creeper && plugin.blockCreeperExplosions)
{
event.setCancelled(true);
return;
}
if (plugin.disableFireDamage && (type == DamageCause.FIRE
|| type == DamageCause.FIRE_TICK)) {
event.setCancelled(true);
return;
}
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_MOB_DAMAGE))
{
event.setCancelled(true);
return;
}
if (plugin.disableSuffocationDamage && type == DamageCause.SUFFOCATION) {
event.setCancelled(true);
return;
}
if (attacker instanceof Creeper)
{
if (!plugin.regionManager.getApplicableRegions(pt).allowsFlag(AreaFlags.FLAG_CREEPER_EXPLOSION))
{
event.setCancelled(true);
return;
}
}
}
}
}
if (type == DamageCause.DROWNING
&& plugin.amphibiousPlayers.contains(player.getName())) {
event.setCancelled(true);
return;
}
}
}
if (plugin.disableFallDamage && type == DamageCause.FALL)
{
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();
if (plugin.disableFireDamage && (type == DamageCause.FIRE
|| type == DamageCause.FIRE_TICK))
{
event.setCancelled(true);
return;
}
byte free = 0;
if (plugin.disableDrowningDamage && type == DamageCause.DROWNING)
{
event.setCancelled(true);
return;
}
while (y <= 129) {
if (BlockType.canPassThrough(world.getBlockTypeIdAt(x, y, z))) {
free++;
} else {
free = 0;
}
if (plugin.teleportOnSuffocation && type == DamageCause.SUFFOCATION)
{
findFreePosition(player);
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.disableSuffocationDamage && type == DamageCause.SUFFOCATION)
{
event.setCancelled(true);
return;
}
return;
}
if (type == DamageCause.DROWNING
&& plugin.amphibiousPlayers.contains(player.getName()))
{
event.setCancelled(true);
return;
}
}
}
y++;
}
}
@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++;
}
}
}
@@ -30,14 +30,11 @@ 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;
@@ -45,10 +42,13 @@ 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.LocalPlayer;
import com.sk89q.worldguard.TickSyncDelayLoggerFilter;
import com.sk89q.worldguard.blacklist.*;
import com.sk89q.worldguard.blacklist.loggers.*;
import com.sk89q.worldguard.domains.DefaultDomain;
@@ -61,21 +61,21 @@ import com.sk89q.worldguard.protection.ProtectedRegion.CircularInheritanceExcept
*
* @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;
@@ -89,6 +89,8 @@ public class WorldGuardPlugin extends JavaPlugin {
// Configuration follows
boolean suppressTickSyncWarnings;
boolean enforceOneSession;
boolean itemDurability;
@@ -129,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);
}
}
}
/**
@@ -187,9 +182,6 @@ public class WorldGuardPlugin extends JavaPlugin {
registerEvent(Event.Type.REDSTONE_CHANGE, blockListener, Priority.High);
registerEvent(Event.Type.ENTITY_DAMAGED, entityListener, Priority.High);
registerEvent(Event.Type.ENTITY_DAMAGEDBY_PROJECTILE, entityListener, Priority.High);
registerEvent(Event.Type.ENTITY_DAMAGEDBY_BLOCK, entityListener, Priority.High);
registerEvent(Event.Type.ENTITY_DAMAGEDBY_ENTITY, entityListener, Priority.High);
registerEvent(Event.Type.ENTITY_EXPLODE, entityListener, Priority.High);
registerEvent(Event.Type.PLAYER_ITEM, playerListener, Priority.High);
@@ -259,6 +251,8 @@ public class WorldGuardPlugin extends JavaPlugin {
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);
@@ -1335,6 +1329,22 @@ public class WorldGuardPlugin extends JavaPlugin {
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) {
try {
return perms.inGroup(player.getName(), group);
@@ -20,8 +20,9 @@
package com.sk89q.worldguard.protection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.protection.AreaFlags.State;
@@ -34,7 +35,7 @@ import com.sk89q.worldguard.protection.AreaFlags.State;
public class ApplicableRegionSet {
private GlobalFlags global;
private Vector pt;
private SortedMap<String,ProtectedRegion> regions;
private Iterator<ProtectedRegion> applicable;
/**
* Construct the object.
@@ -43,10 +44,10 @@ public class ApplicableRegionSet {
* @param regions
* @param global
*/
public ApplicableRegionSet(Vector pt, SortedMap<String,ProtectedRegion> regions,
public ApplicableRegionSet(Vector pt, Iterator<ProtectedRegion> applicable,
GlobalFlags global) {
this.pt = pt;
this.regions = regions;
this.applicable = applicable;
this.global = global;
}
@@ -111,7 +112,9 @@ public class ApplicableRegionSet {
Set<ProtectedRegion> needsClear = new HashSet<ProtectedRegion>();
Set<ProtectedRegion> hasCleared = new HashSet<ProtectedRegion>();
for (ProtectedRegion region : regions.values()) {
while (applicable.hasNext()) {
ProtectedRegion region = applicable.next();
// Ignore non-build regions
if (player != null && region.getFlags().get(AreaFlags.FLAG_PASSTHROUGH) == State.ALLOW) {
continue;
@@ -38,7 +38,7 @@ public class FlatRegionManager implements RegionManager {
/**
* List of protected regions.
*/
private SortedMap<String,ProtectedRegion> regions;
private Map<String,ProtectedRegion> regions;
/**
* Global flags.
*/
@@ -60,7 +60,6 @@ public class FlatRegionManager implements RegionManager {
public Map<String,ProtectedRegion> getRegions() {
return regions;
}
/**
* Set a list of protected regions.
@@ -70,6 +69,7 @@ public class FlatRegionManager implements RegionManager {
public void setRegions(Map<String,ProtectedRegion> regions) {
this.regions = new TreeMap<String,ProtectedRegion>(regions);
}
/**
* Adds a region.
*
@@ -125,7 +125,7 @@ public class FlatRegionManager implements RegionManager {
* @return
*/
public ApplicableRegionSet getApplicableRegions(Vector pt) {
return new ApplicableRegionSet(pt, regions, global);
return new ApplicableRegionSet(pt, regions.values().iterator(), global);
}
/**
@@ -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();
}
}
@@ -79,6 +79,20 @@ public abstract class ProtectedRegion implements Comparable<ProtectedRegion> {
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
*/
@@ -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();
}
}