From f61a9ab5cc998cbe864e3f8f5b43e99a8b921eaf Mon Sep 17 00:00:00 2001 From: Redecouverte Date: Thu, 24 Feb 2011 11:19:35 +0100 Subject: [PATCH] added multiworld support for regions and json region database --- build.xml | 4 +- lib/gson-1.7-SNAPSHOT.jar | Bin 0 -> 171075 bytes lib/json-simple-1.1.jar | Bin 16046 -> 0 bytes nbproject/project.properties | 4 +- .../bukkit/WorldGuardBlockListener.java | 42 +- .../bukkit/WorldGuardEntityListener.java | 33 +- .../bukkit/WorldGuardPlayerListener.java | 14 +- .../worldguard/bukkit/WorldGuardPlugin.java | 171 +++-- .../protection/ApplicableRegionSet.java | 4 +- .../DescendingPriorityComparator.java | 1 + .../worldguard/protection/RegionManager.java | 112 --- .../protection/{ => dbs}/CSVDatabase.java | 10 +- .../protection/dbs/JSONContainer.java | 109 +++ .../protection/dbs/JSONDatabase.java | 168 +++++ .../{ => dbs}/ProtectionDatabase.java | 138 ++-- .../FlatRegionManager.java | 391 +++++----- .../regionmanager/GlobalRegionManager.java | 89 +++ .../PRTreeRegionManager.java | 421 ++++++----- .../regionmanager/RegionManager.java | 181 +++++ .../protection/{ => regions}/AreaFlags.java | 290 ++++---- .../{ => regions}/ProtectedCuboidRegion.java | 2 +- .../ProtectedPolygonalRegion.java | 264 +++---- .../{ => regions}/ProtectedRegion.java | 695 +++++++++--------- .../ProtectedRegionMBRConverter.java | 83 +-- .../protection/ApplicableRegionSetTest.java | 10 +- .../protection/CSVDatabaseTest.java | 6 +- 26 files changed, 1909 insertions(+), 1333 deletions(-) create mode 100644 lib/gson-1.7-SNAPSHOT.jar delete mode 100644 lib/json-simple-1.1.jar delete mode 100644 src/com/sk89q/worldguard/protection/RegionManager.java rename src/com/sk89q/worldguard/protection/{ => dbs}/CSVDatabase.java (96%) create mode 100644 src/com/sk89q/worldguard/protection/dbs/JSONContainer.java create mode 100644 src/com/sk89q/worldguard/protection/dbs/JSONDatabase.java rename src/com/sk89q/worldguard/protection/{ => dbs}/ProtectionDatabase.java (91%) rename src/com/sk89q/worldguard/protection/{ => regionmanager}/FlatRegionManager.java (81%) create mode 100644 src/com/sk89q/worldguard/protection/regionmanager/GlobalRegionManager.java rename src/com/sk89q/worldguard/protection/{ => regionmanager}/PRTreeRegionManager.java (85%) create mode 100644 src/com/sk89q/worldguard/protection/regionmanager/RegionManager.java rename src/com/sk89q/worldguard/protection/{ => regions}/AreaFlags.java (96%) rename src/com/sk89q/worldguard/protection/{ => regions}/ProtectedCuboidRegion.java (98%) rename src/com/sk89q/worldguard/protection/{ => regions}/ProtectedPolygonalRegion.java (95%) rename src/com/sk89q/worldguard/protection/{ => regions}/ProtectedRegion.java (91%) rename src/com/sk89q/worldguard/protection/{ => regions}/ProtectedRegionMBRConverter.java (91%) diff --git a/build.xml b/build.xml index eebaa28c..bb4ec824 100644 --- a/build.xml +++ b/build.xml @@ -14,7 +14,7 @@ - + @@ -47,7 +47,7 @@ - + diff --git a/lib/gson-1.7-SNAPSHOT.jar b/lib/gson-1.7-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..1ae527790e4007e6d14e2eb31c45d7e50111d530 GIT binary patch literal 171075 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 literal 0 HcmV?d00001 diff --git a/lib/json-simple-1.1.jar b/lib/json-simple-1.1.jar deleted file mode 100644 index f395f41471a796876278a6c5667ded4632546893..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16046 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 regions = plugin.regionManager.getApplicableRegionsIDs(pt); + + RegionManager mgr = plugin.getGlobalRegionManager().getRegionmanager(player.getWorld().getName()); + ApplicableRegionSet app = mgr.getApplicableRegions(pt); + List regions = mgr.getApplicableRegionsIDs(pt); if (regions.size() > 0) { player.sendMessage(ChatColor.YELLOW + "Can you build? " @@ -504,10 +502,8 @@ public void onBlockRightClick(BlockRightClickEvent event) { if (plugin.useRegions && type == Material.CAKE_BLOCK) { Vector pt = toVector(blockClicked); - LocalPlayer localPlayer = plugin.wrapPlayer(player); - if (!plugin.hasPermission(player, "/regionbypass") - && !plugin.regionManager.getApplicableRegions(pt).canBuild(localPlayer)) { + if (!plugin.canBuild(player, pt)) { player.sendMessage(ChatColor.DARK_RED + "You don't have permission for this area."); byte newData = (byte) (blockClicked.getData() - 1); diff --git a/src/com/sk89q/worldguard/bukkit/WorldGuardEntityListener.java b/src/com/sk89q/worldguard/bukkit/WorldGuardEntityListener.java index 14405cf8..6ad769a6 100644 --- a/src/com/sk89q/worldguard/bukkit/WorldGuardEntityListener.java +++ b/src/com/sk89q/worldguard/bukkit/WorldGuardEntityListener.java @@ -19,6 +19,7 @@ package com.sk89q.worldguard.bukkit; +import com.sk89q.worldguard.protection.regionmanager.RegionManager; import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.World; @@ -32,7 +33,7 @@ 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 com.sk89q.worldguard.protection.regions.AreaFlags; import static com.sk89q.worldguard.bukkit.BukkitUtil.*; public class WorldGuardEntityListener extends EntityListener { @@ -91,8 +92,9 @@ public void onEntityDamageByEntity(EntityDamageByEntityEvent event) { if (attacker != null && attacker instanceof Player) { if (plugin.useRegions) { Vector pt = toVector(defender.getLocation()); - - if (!plugin.regionManager.getApplicableRegions(pt) + RegionManager mgr = plugin.getGlobalRegionManager().getRegionmanager(player.getWorld().getName()); + + if (!mgr.getApplicableRegions(pt) .allowsFlag(AreaFlags.FLAG_PVP)) { ((Player)attacker).sendMessage(ChatColor.DARK_RED + "You are in a no-PvP area."); event.setCancelled(true); @@ -109,15 +111,16 @@ public void onEntityDamageByEntity(EntityDamageByEntityEvent event) { if (plugin.useRegions) { Vector pt = toVector(defender.getLocation()); - - if (!plugin.regionManager.getApplicableRegions(pt) + RegionManager mgr = plugin.getGlobalRegionManager().getRegionmanager(player.getWorld().getName()); + + if (!mgr.getApplicableRegions(pt) .allowsFlag(AreaFlags.FLAG_MOB_DAMAGE)) { event.setCancelled(true); return; } if (attacker instanceof Creeper) { - if (!plugin.regionManager.getApplicableRegions(pt) + if (!mgr.getApplicableRegions(pt) .allowsFlag(AreaFlags.FLAG_CREEPER_EXPLOSION)) { event.setCancelled(true); return; @@ -144,8 +147,9 @@ public void onEntityDamageByProjectile(EntityDamageByProjectileEvent event) { if (attacker != null && attacker instanceof Player) { if (plugin.useRegions) { Vector pt = toVector(defender.getLocation()); - - if (!plugin.regionManager.getApplicableRegions(pt) + RegionManager mgr = plugin.getGlobalRegionManager().getRegionmanager(player.getWorld().getName()); + + if (!mgr.getApplicableRegions(pt) .allowsFlag(AreaFlags.FLAG_PVP)) { ((Player)attacker).sendMessage(ChatColor.DARK_RED + "You are in a no-PvP area."); event.setCancelled(true); @@ -156,8 +160,9 @@ public void onEntityDamageByProjectile(EntityDamageByProjectileEvent event) { if (attacker != null && attacker instanceof Skeleton) { if (plugin.useRegions) { Vector pt = toVector(defender.getLocation()); - - if (!plugin.regionManager.getApplicableRegions(pt) + RegionManager mgr = plugin.getGlobalRegionManager().getRegionmanager(player.getWorld().getName()); + + if (!mgr.getApplicableRegions(pt) .allowsFlag(AreaFlags.FLAG_MOB_DAMAGE)) { event.setCancelled(true); return; @@ -254,8 +259,9 @@ public void onEntityExplode(EntityExplodeEvent event) { if (plugin.useRegions) { Vector pt = toVector(event.getEntity().getLocation()); + RegionManager mgr = plugin.getGlobalRegionManager().getRegionmanager(event.getEntity().getWorld().getName()); - if (!plugin.regionManager.getApplicableRegions(pt) + if (!mgr.getApplicableRegions(pt) .allowsFlag(AreaFlags.FLAG_CREEPER_EXPLOSION)) { event.setCancelled(true); return; @@ -269,8 +275,9 @@ public void onEntityExplode(EntityExplodeEvent event) { if (plugin.useRegions && event.getEntity() != null) { Vector pt = toVector(event.getEntity().getLocation()); - - if (!plugin.regionManager.getApplicableRegions(pt) + RegionManager mgr = plugin.getGlobalRegionManager().getRegionmanager(event.getEntity().getWorld().getName()); + + if (!mgr.getApplicableRegions(pt) .allowsFlag(AreaFlags.FLAG_TNT)) { event.setCancelled(true); return; diff --git a/src/com/sk89q/worldguard/bukkit/WorldGuardPlayerListener.java b/src/com/sk89q/worldguard/bukkit/WorldGuardPlayerListener.java index c8fcf1af..39e693ad 100644 --- a/src/com/sk89q/worldguard/bukkit/WorldGuardPlayerListener.java +++ b/src/com/sk89q/worldguard/bukkit/WorldGuardPlayerListener.java @@ -19,6 +19,7 @@ package com.sk89q.worldguard.bukkit; +import com.sk89q.worldguard.protection.regionmanager.RegionManager; import com.sk89q.worldguard.blacklist.events.ItemAcquireBlacklistEvent; import org.bukkit.entity.Item; import com.sk89q.worldguard.blacklist.events.ItemDropBlacklistEvent; @@ -30,7 +31,7 @@ import com.sk89q.worldedit.Vector; import com.sk89q.worldguard.*; import com.sk89q.worldguard.blacklist.events.ItemUseBlacklistEvent; -import com.sk89q.worldguard.protection.AreaFlags; +import com.sk89q.worldguard.protection.regions.AreaFlags; import static com.sk89q.worldguard.bukkit.BukkitUtil.*; /** @@ -116,10 +117,8 @@ public void onPlayerItem(PlayerItemEvent event) { if (plugin.useRegions && !event.isBlock() && block != null) { Vector pt = toVector(block.getRelative(event.getBlockFace())); - LocalPlayer localPlayer = plugin.wrapPlayer(player); - - if (!plugin.hasPermission(player, "/regionbypass") - && !plugin.regionManager.getApplicableRegions(pt).canBuild(localPlayer)) { + + if (!plugin.canBuild(player, pt)) { player.sendMessage(ChatColor.DARK_RED + "You don't have permission for this area."); event.setCancelled(true); @@ -139,8 +138,9 @@ public void onPlayerItem(PlayerItemEvent event) { if (plugin.useRegions && item != null && block != null && item.getTypeId() == 259) { Vector pt = toVector(block.getRelative(event.getBlockFace())); - - if (!plugin.regionManager.getApplicableRegions(pt) + RegionManager mgr = plugin.getGlobalRegionManager().getRegionmanager(player.getWorld().getName()); + + if (!mgr.getApplicableRegions(pt) .allowsFlag(AreaFlags.FLAG_LIGHTER)) { event.setCancelled(true); return; diff --git a/src/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java b/src/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java index dfe70150..f3fd2432 100644 --- a/src/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java +++ b/src/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java @@ -19,8 +19,11 @@ package com.sk89q.worldguard.bukkit; + +import com.sk89q.worldguard.protection.dbs.CSVDatabase; +import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion; +import com.sk89q.worldguard.protection.regionmanager.RegionManager; import static com.sk89q.worldguard.bukkit.BukkitUtil.matchSinglePlayer; -import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector; import java.io.*; import java.util.*; import java.util.logging.*; @@ -31,14 +34,12 @@ 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; @@ -49,7 +50,6 @@ import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.blocks.ItemType; import com.sk89q.worldedit.bukkit.BukkitWorld; -import com.sk89q.worldedit.bukkit.WorldEditAPI; import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldguard.LocalPlayer; @@ -58,8 +58,12 @@ 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; +import com.sk89q.worldguard.protection.regionmanager.GlobalRegionManager; +import com.sk89q.worldguard.protection.regions.AreaFlags; +import com.sk89q.worldguard.protection.regions.AreaFlags.State; +import com.sk89q.worldguard.protection.regions.ProtectedRegion; +import com.sk89q.worldguard.protection.regions.ProtectedRegion.CircularInheritanceException; +import org.bukkit.World; /** * Plugin for Bukkit. @@ -81,12 +85,10 @@ public class WorldGuardPlugin extends JavaPlugin { private PermissionsResolverServerListener permsListener; private PermissionsResolverManager perms; - + Blacklist blacklist; - GlobalFlags globalFlags = new GlobalFlags(); - RegionManager regionManager = new FlatRegionManager(globalFlags); - ProtectionDatabase regionLoader; + GlobalRegionManager globalRegionManager; Set invinciblePlayers = new HashSet(); Set amphibiousPlayers = new HashSet(); @@ -158,7 +160,8 @@ public void onEnable() { createDefaultConfiguration("config.yml"); createDefaultConfiguration("blacklist.txt"); - regionLoader = new CSVDatabase(new File(folder, "regions.txt")); + globalRegionManager = new GlobalRegionManager(this); + perms = new PermissionsResolverManager(getConfiguration(), getServer(), "WorldGuard", logger); permsListener = new PermissionsResolverServerListener(perms); @@ -316,6 +319,8 @@ public void loadConfiguration() { useRegions = config.getBoolean("regions.enable", true); regionWand = config.getInt("regions.wand", 287); + + GlobalFlags globalFlags = new GlobalFlags(); 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); @@ -323,16 +328,35 @@ public void loadConfiguration() { globalFlags.canTnt = config.getBoolean("regions.default.tnt", true); globalFlags.allowCreeper = config.getBoolean("regions.default.creeper", true); globalFlags.allowMobDamage = config.getBoolean("regions.default.mobdamage", true); + globalRegionManager.setGlobalFlags(globalFlags); try { - regionLoader.load(); - regionManager.setRegions(regionLoader.getRegions()); + File CSVfile = new File(this.getDataFolder(), "regions.txt"); + if (CSVfile.exists()) { + + logger.info("WorldGuard: Converting old regions.txt to new format...."); + + World w = this.getServer().getWorlds().get(0); + RegionManager mgr = globalRegionManager.getRegionmanager(w.getName()); + + CSVDatabase db = new CSVDatabase(CSVfile); + db.load(); + + for (Map.Entry entry : db.getRegions().entrySet()) { + mgr.addRegion(entry.getValue()); + } + + mgr.save(); + CSVfile.renameTo(new File(this.getDataFolder(), "region.txt.old")); + + logger.info("WorldGuard: Done."); + } } catch (FileNotFoundException e) { } catch (IOException e) { logger.warning("WorldGuard: Failed to load regions: " + e.getMessage()); } - + // Console log configuration boolean logConsole = config.getBoolean("blacklist.logging.console.enable", true); @@ -780,9 +804,10 @@ private boolean handleRegionCommand(Player player, String action, String[] args) String id = args[0].toLowerCase(); WorldEditPlugin worldEdit = (WorldEditPlugin)wePlugin; + World w = player.getWorld(); LocalSession session = worldEdit.getSession(player); - Region weRegion = session.getSelection(new BukkitWorld(player.getWorld())); + Region weRegion = session.getSelection(new BukkitWorld(w)); BlockVector min = weRegion.getMinimumPoint().toBlockVector(); BlockVector max = weRegion.getMaximumPoint().toBlockVector(); @@ -791,8 +816,9 @@ private boolean handleRegionCommand(Player player, String action, String[] args) if (args.length >= 2) { region.setOwners(parseDomainString(args, 1)); } - regionManager.addRegion(region); - regionLoader.save(regionManager); + RegionManager mgr = globalRegionManager.getRegionmanager(w.getName()); + mgr.addRegion(region); + mgr.save(); player.sendMessage(ChatColor.YELLOW + "Region saved as " + id + "."); } catch (IncompleteRegionException e) { player.sendMessage(ChatColor.RED + "You must first define an area in WorldEdit."); @@ -810,8 +836,9 @@ private boolean handleRegionCommand(Player player, String action, String[] args) try { String id = args[0].toLowerCase(); + RegionManager mgr = globalRegionManager.getRegionmanager(player.getWorld().getName()); - ProtectedRegion existing = regionManager.getRegion(id); + ProtectedRegion existing = mgr.getRegion(id); if (existing != null) { if (!existing.getOwners().contains(wrapPlayer(player))) { @@ -830,15 +857,15 @@ private boolean handleRegionCommand(Player player, String action, String[] args) ProtectedRegion region = new ProtectedCuboidRegion(id, min, max); - if (regionManager.overlapsUnownedRegion(region, wrapPlayer(player))) { + if (mgr.overlapsUnownedRegion(region, wrapPlayer(player))) { player.sendMessage(ChatColor.RED + "This region overlaps with someone else's region."); return true; } region.getOwners().addPlayer(player.getName()); - regionManager.addRegion(region); - regionLoader.save(regionManager); + mgr.addRegion(region); + mgr.save(); player.sendMessage(ChatColor.YELLOW + "Region saved as " + id + "."); } catch (IncompleteRegionException e) { player.sendMessage(ChatColor.RED + "You must first define an area in WorldEdit."); @@ -858,7 +885,8 @@ private boolean handleRegionCommand(Player player, String action, String[] args) String id = args[0].toLowerCase(); String flagStr = args[1]; String stateStr = args[2]; - ProtectedRegion region = regionManager.getRegion(id); + RegionManager mgr = globalRegionManager.getRegionmanager(player.getWorld().getName()); + ProtectedRegion region = mgr.getRegion(id); if (region == null) { player.sendMessage(ChatColor.RED + "Could not find a region by that ID."); @@ -893,7 +921,7 @@ private boolean handleRegionCommand(Player player, String action, String[] args) AreaFlags flags = region.getFlags(); flags.set(flagStr, state); - regionLoader.save(regionManager); + mgr.save(); player.sendMessage(ChatColor.YELLOW + "Region '" + id + "' updated."); } catch (IOException e) { player.sendMessage(ChatColor.RED + "Region database failed to save: " @@ -911,8 +939,9 @@ private boolean handleRegionCommand(Player player, String action, String[] args) String id = args[0].toLowerCase(); String parentId = args.length > 1 ? args[1].toLowerCase() : null; - - ProtectedRegion region = regionManager.getRegion(id); + RegionManager mgr = globalRegionManager.getRegionmanager(player.getWorld().getName()); + + ProtectedRegion region = mgr.getRegion(id); if (region == null) { player.sendMessage(ChatColor.RED + "Could not find a region with ID: " + id); @@ -929,7 +958,7 @@ private boolean handleRegionCommand(Player player, String action, String[] args) // Set a parent if (parentId != null) { - parent = regionManager.getRegion(parentId); + parent = mgr.getRegion(parentId); if (parent == null) { player.sendMessage(ChatColor.RED + "Could not find a region with ID: " + parentId); @@ -946,7 +975,7 @@ private boolean handleRegionCommand(Player player, String action, String[] args) try { region.setParent(parent); - regionLoader.save(regionManager); + mgr.save(); player.sendMessage(ChatColor.YELLOW + "Region '" + id + "' updated."); } catch (CircularInheritanceException e) { player.sendMessage(ChatColor.RED + "Circular inheritance detected. The operation failed."); @@ -961,15 +990,16 @@ private boolean handleRegionCommand(Player player, String action, String[] args) if (action.equalsIgnoreCase("info")) { checkRegionPermission(player, "/regioninfo"); checkArgs(args, 1, 1, "/region info "); - + + RegionManager mgr = globalRegionManager.getRegionmanager(player.getWorld().getName()); String id = args[0].toLowerCase(); - if (!regionManager.hasRegion(id)) { + if (!mgr.hasRegion(id)) { player.sendMessage(ChatColor.RED + "A region with ID '" + id + "' doesn't exist."); return true; } - ProtectedRegion region = regionManager.getRegion(id); + ProtectedRegion region = mgr.getRegion(id); AreaFlags flags = region.getFlags(); DefaultDomain owners = region.getOwners(); DefaultDomain members = region.getMembers(); @@ -1010,15 +1040,16 @@ private boolean handleRegionCommand(Player player, String action, String[] args) checkArgs(args, 2, -1, "/region add[member|owner] [player1 [group1 [players/groups...]]]"); boolean isOwner = action.equalsIgnoreCase("addowner"); + RegionManager mgr = globalRegionManager.getRegionmanager(player.getWorld().getName()); String id = args[0].toLowerCase(); - if (!regionManager.hasRegion(id)) { + if (!mgr.hasRegion(id)) { player.sendMessage(ChatColor.RED + "A region with ID '" + id + "' doesn't exist."); return true; } - ProtectedRegion existing = regionManager.getRegion(id); + ProtectedRegion existing = mgr.getRegion(id); if (!canUseRegionCommand(player, "/regiondefine") && !existing.isOwner(wrapPlayer(player))) { @@ -1033,7 +1064,7 @@ private boolean handleRegionCommand(Player player, String action, String[] args) } try { - regionLoader.save(regionManager); + mgr.save(); player.sendMessage(ChatColor.YELLOW + "Region updated!"); player.sendMessage(ChatColor.GRAY + "Current owners: " + existing.getOwners().toUserFriendlyString()); @@ -1054,15 +1085,16 @@ private boolean handleRegionCommand(Player player, String action, String[] args) checkArgs(args, 2, -1, "/region removeowner [owner1 [owner2 [owners...]]]"); boolean isOwner = action.equalsIgnoreCase("removeowner"); - + RegionManager mgr = globalRegionManager.getRegionmanager(player.getWorld().getName()); + String id = args[0].toLowerCase(); - if (!regionManager.hasRegion(id)) { + if (!mgr.hasRegion(id)) { player.sendMessage(ChatColor.RED + "A region with ID '" + id + "' doesn't exist."); return true; } - ProtectedRegion existing = regionManager.getRegion(id); + ProtectedRegion existing = mgr.getRegion(id); if (!canUseRegionCommand(player, "/regiondefine") && !existing.isOwner(wrapPlayer(player))) { @@ -1077,7 +1109,7 @@ private boolean handleRegionCommand(Player player, String action, String[] args) } try { - regionLoader.save(regionManager); + mgr.save(); player.sendMessage(ChatColor.YELLOW + "Region updated!"); player.sendMessage(ChatColor.GRAY + "Current owners: " + existing.getOwners().toUserFriendlyString()); @@ -1104,8 +1136,9 @@ private boolean handleRegionCommand(Player player, String action, String[] args) page = 0; } } - - Map regions = regionManager.getRegions(); + + RegionManager mgr = globalRegionManager.getRegionmanager(player.getWorld().getName()); + Map regions = mgr.getRegions(); int size = regions.size(); int pages = (int)Math.ceil(size / (float)CMD_LIST_SIZE); @@ -1139,13 +1172,15 @@ private boolean handleRegionCommand(Player player, String action, String[] args) try { String id = args[0].toLowerCase(); - if (!regionManager.hasRegion(id)) { + RegionManager mgr = globalRegionManager.getRegionmanager(player.getWorld().getName()); + + if (!mgr.hasRegion(id)) { player.sendMessage(ChatColor.RED + "A region with ID '" + id + "' doesn't exist."); return true; } - ProtectedRegion existing = regionManager.getRegion(id); + ProtectedRegion existing = mgr.getRegion(id); if (!canUseRegionCommand(player, "/regiondelete") && !existing.isOwner(wrapPlayer(player))) { @@ -1153,8 +1188,8 @@ private boolean handleRegionCommand(Player player, String action, String[] args) return true; } - regionManager.removeRegion(id); - regionLoader.save(regionManager); + mgr.removeRegion(id); + mgr.save(); player.sendMessage(ChatColor.YELLOW + "Region removed!"); } catch (IOException e) { player.sendMessage(ChatColor.RED + "Region database failed to save: " @@ -1169,7 +1204,8 @@ private boolean handleRegionCommand(Player player, String action, String[] args) checkArgs(args, 0, 0, "/region save"); try { - regionLoader.save(regionManager); + RegionManager mgr = globalRegionManager.getRegionmanager(player.getWorld().getName()); + mgr.save(); player.sendMessage(ChatColor.YELLOW + "Region database saved to file!"); } catch (IOException e) { player.sendMessage(ChatColor.RED + "Region database failed to save: " @@ -1184,7 +1220,8 @@ private boolean handleRegionCommand(Player player, String action, String[] args) checkArgs(args, 0, 0, "/region load"); try { - regionLoader.load(regionManager); + RegionManager mgr = globalRegionManager.getRegionmanager(player.getWorld().getName()); + mgr.load(); player.sendMessage(ChatColor.YELLOW + "Region database loaded from file!"); } catch (IOException e) { player.sendMessage(ChatColor.RED + "Region database failed to load: " @@ -1341,35 +1378,49 @@ private void checkArgs(String[] args, int min, int max, String help) * * @return */ - public RegionManager getRegionManager() { - return regionManager; - } - - /** - * Get the region loader. - * - * @return - */ - public ProtectionDatabase getRegionLoader() { - return regionLoader; + public GlobalRegionManager getGlobalRegionManager() { + return globalRegionManager; } 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; + if (!hasPermission(player, "/regionbypass")) { + RegionManager mgr = globalRegionManager.getRegionmanager(player.getWorld().getName()); + + if (!mgr.getApplicableRegions(pt).canBuild(localPlayer)) { + return false; + } } - + return true; } else { return true; } } + public boolean canBuild(Player player, Vector pt) { + + if (useRegions) { + LocalPlayer localPlayer = wrapPlayer(player); + + if (!hasPermission(player, "/regionbypass")) { + RegionManager mgr = globalRegionManager.getRegionmanager(player.getWorld().getName()); + + if (!mgr.getApplicableRegions(pt).canBuild(localPlayer)) { + return false; + } + } + + return true; + } else { + return true; + } + } + boolean inGroup(Player player, String group) { try { return perms.inGroup(player.getName(), group); diff --git a/src/com/sk89q/worldguard/protection/ApplicableRegionSet.java b/src/com/sk89q/worldguard/protection/ApplicableRegionSet.java index d0594bf0..047aa448 100644 --- a/src/com/sk89q/worldguard/protection/ApplicableRegionSet.java +++ b/src/com/sk89q/worldguard/protection/ApplicableRegionSet.java @@ -19,13 +19,15 @@ package com.sk89q.worldguard.protection; +import com.sk89q.worldguard.protection.regions.ProtectedRegion; 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; +import com.sk89q.worldguard.protection.regions.AreaFlags; +import com.sk89q.worldguard.protection.regions.AreaFlags.State; /** * Represents a set of regions and their rules as applied to one point. diff --git a/src/com/sk89q/worldguard/protection/DescendingPriorityComparator.java b/src/com/sk89q/worldguard/protection/DescendingPriorityComparator.java index 6b198a9a..402093d5 100644 --- a/src/com/sk89q/worldguard/protection/DescendingPriorityComparator.java +++ b/src/com/sk89q/worldguard/protection/DescendingPriorityComparator.java @@ -19,6 +19,7 @@ package com.sk89q.worldguard.protection; +import com.sk89q.worldguard.protection.regions.ProtectedRegion; import java.util.Comparator; class DescendingPriorityComparator implements Comparator { diff --git a/src/com/sk89q/worldguard/protection/RegionManager.java b/src/com/sk89q/worldguard/protection/RegionManager.java deleted file mode 100644 index 0f7be557..00000000 --- a/src/com/sk89q/worldguard/protection/RegionManager.java +++ /dev/null @@ -1,112 +0,0 @@ -// $Id$ -/* - * WorldGuard - * Copyright (C) 2010 sk89q - * - * 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 . -*/ - -package com.sk89q.worldguard.protection; - -import java.util.List; -import java.util.Map; -import com.sk89q.worldedit.Vector; -import com.sk89q.worldguard.LocalPlayer; - -/** - * An interface for getting, setting, and looking up regions. The most - * simple implementation uses a flat list and iterates through the entire - * list to look for applicable regions, but a more complicated (and more - * efficient) implementation may use space partitioning techniques. - * - * @author sk89q - */ -public interface RegionManager { - /** - * Get a list of protected regions. - * - * @return - */ - public Map getRegions(); - - /** - * Set a list of protected regions. - * - * @return - */ - public void setRegions(Map regions); - - /** - * Adds a region. - * - * @param id - * @param region - */ - public void addRegion(ProtectedRegion region); - - /** - * Return whether a region exists by an ID. - * - * @param id - * @return - */ - public boolean hasRegion(String id); - - /** - * Get a region by its ID. - * - * @param id - */ - public ProtectedRegion getRegion(String id); - - /** - * Removes a region, including inheriting children. - * - * @param id - */ - public void removeRegion(String id); - - /** - * Get an object for a point for rules to be applied with. - * - * @param pt - * @return - */ - public ApplicableRegionSet getApplicableRegions(Vector pt); - - /** - * Get a list of region IDs that contain a point. - * - * @param pt - * @return - */ - public List getApplicableRegionsIDs(Vector pt); - - /** - * 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); - - /** - * Get the number of regions. - * - * @return - */ - public int size(); -} diff --git a/src/com/sk89q/worldguard/protection/CSVDatabase.java b/src/com/sk89q/worldguard/protection/dbs/CSVDatabase.java similarity index 96% rename from src/com/sk89q/worldguard/protection/CSVDatabase.java rename to src/com/sk89q/worldguard/protection/dbs/CSVDatabase.java index 8859527a..eec7ecf3 100644 --- a/src/com/sk89q/worldguard/protection/CSVDatabase.java +++ b/src/com/sk89q/worldguard/protection/dbs/CSVDatabase.java @@ -17,8 +17,10 @@ * along with this program. If not, see . */ -package com.sk89q.worldguard.protection; +package com.sk89q.worldguard.protection.dbs; +import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion; +import com.sk89q.worldguard.protection.regionmanager.RegionManager; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; @@ -31,8 +33,10 @@ 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.protection.regions.AreaFlags; +import com.sk89q.worldguard.protection.regions.AreaFlags.State; +import com.sk89q.worldguard.protection.regions.ProtectedRegion; +import com.sk89q.worldguard.protection.regions.ProtectedRegion.CircularInheritanceException; import com.sk89q.worldguard.util.ArrayReader; /** diff --git a/src/com/sk89q/worldguard/protection/dbs/JSONContainer.java b/src/com/sk89q/worldguard/protection/dbs/JSONContainer.java new file mode 100644 index 00000000..302516a0 --- /dev/null +++ b/src/com/sk89q/worldguard/protection/dbs/JSONContainer.java @@ -0,0 +1,109 @@ +// $Id$ +/* + * WorldGuard + * Copyright (C) 2010 sk89q + * + * 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 . +*/ + +package com.sk89q.worldguard.protection.dbs; + +import com.sk89q.worldguard.domains.DefaultDomain; +import com.sk89q.worldguard.protection.regions.AreaFlags; +import com.sk89q.worldguard.protection.regions.ProtectedRegion; +import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion; +import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion; +import com.sk89q.worldguard.protection.regions.ProtectedRegion.CircularInheritanceException; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Logger; + +/** + * + * @author Redecouverte + */ +public class JSONContainer { + + private static Logger logger = Logger.getLogger("Minecraft.WorldGuard"); + + private HashMap cRegions; + private HashMap pRegions; + + public JSONContainer(Map regions) + { + + this.cRegions = new HashMap(); + this.pRegions = new HashMap(); + + for (Map.Entry entry : regions.entrySet()) { + String id = entry.getKey(); + ProtectedRegion region = entry.getValue(); + region.setParentId(); + + if(region instanceof ProtectedCuboidRegion) + { + cRegions.put(id, (ProtectedCuboidRegion)region); + } + else if(region instanceof ProtectedPolygonalRegion) + { + pRegions.put(id, (ProtectedPolygonalRegion)region); + } + else + { + logger.info("regions of type '" + region.getClass().toString() + "' are not supported for saving, yet."); + } + } + + } + + public Map getRegions() { + HashMap ret = new HashMap(); + ret.putAll(this.cRegions); + ret.putAll(this.pRegions); + + for (Map.Entry entry : ret.entrySet()) { + String id = entry.getKey(); + ProtectedRegion region = entry.getValue(); + + String parentId = region.getParentId(); + if (parentId != null) { + try { + region.setParent(ret.get(parentId)); + } catch (CircularInheritanceException ex) { + } + } else { + try { + region.setParent(null); + } catch (CircularInheritanceException ex) { + } + } + + if(region.getOwners() == null) + { + region.setOwners(new DefaultDomain()); + } + else if(region.getMembers() == null) + { + region.setMembers(new DefaultDomain()); + } + else if(region.getFlags() == null) + { + region.setFlags(new AreaFlags()); + } + + } + + return ret; + } +} diff --git a/src/com/sk89q/worldguard/protection/dbs/JSONDatabase.java b/src/com/sk89q/worldguard/protection/dbs/JSONDatabase.java new file mode 100644 index 00000000..8f4c2912 --- /dev/null +++ b/src/com/sk89q/worldguard/protection/dbs/JSONDatabase.java @@ -0,0 +1,168 @@ +// $Id$ +/* + * WorldGuard + * Copyright (C) 2010 sk89q + * + * 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 . +*/ + +package com.sk89q.worldguard.protection.dbs; + +import com.sk89q.worldguard.protection.dbs.ProtectionDatabase; +import com.sk89q.worldguard.protection.dbs.JSONContainer; +import com.sk89q.worldguard.protection.regionmanager.RegionManager; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.sk89q.worldedit.BlockVector; +import com.sk89q.worldguard.protection.regions.ProtectedRegion; +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.lang.String; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Logger; + +/** + * Represents a protected area database that uses JSON files. + * + * @author Redecouverte + */ +public class JSONDatabase implements ProtectionDatabase { + private static Logger logger = Logger.getLogger("Minecraft.WorldGuard"); + + /** + * References the json db folder. + */ + private File file; + + /** + * Holds the list of regions. + */ + private Map regions; + + /** + * Construct the database with a path to a file. No file is read or + * written at this time. + * + * @param file + */ + public JSONDatabase(File file) { + this.file = file; + } + + /** + * Helper function to read a file into a String + */ + private static String readFileAsString(File file) throws java.io.IOException { + byte[] buffer = new byte[(int) file.length()]; + BufferedInputStream f = null; + try { + f = new BufferedInputStream(new FileInputStream(file.getAbsolutePath())); + f.read(buffer); + } finally { + if (f != null) { + try { + f.close(); + } catch (IOException ignored) { + } + } + } + return new String(buffer); + } + + /** + * Load the database from file. + */ + public void load() throws IOException { + + Gson gson = new Gson(); + JSONContainer jContainer = gson.fromJson(readFileAsString(file), JSONContainer.class); + this.regions = jContainer.getRegions(); + } + + /** + * Saves the database. + */ + public void save() throws IOException { + + Gson gson = new Gson(); + String jsonData = gson.toJson(new JSONContainer(this.regions), JSONContainer.class); + writeStringToFile(jsonData, this.file); + } + + + /** + * Writes a String to a file. + * + * @throws IOException + */ + public static void writeStringToFile(String string, File file) throws IOException { + FileWriter writer = null; + + try { + writer = new FileWriter(file); + writer.write(string); + } finally { + try { + if (writer != null) { + writer.close(); + } + } catch (IOException e) { + } + } + } + + /** + * Load the list of regions into a region manager. + * + * @throws IOException + */ + public void load(RegionManager manager) throws IOException { + load(); + manager.setRegions(regions); + } + + /** + * Save the list of regions from a region manager. + * + * @throws IOException + */ + public void save(RegionManager manager) throws IOException { + regions = manager.getRegions(); + save(); + } + + /** + * Get a list of protected regions. + * + * @return + */ + public Map getRegions() { + return regions; + } + + /** + * Get a list of protected regions. + * + * @return + */ + public void setRegions(Map regions) { + this.regions = regions; + } +} diff --git a/src/com/sk89q/worldguard/protection/ProtectionDatabase.java b/src/com/sk89q/worldguard/protection/dbs/ProtectionDatabase.java similarity index 91% rename from src/com/sk89q/worldguard/protection/ProtectionDatabase.java rename to src/com/sk89q/worldguard/protection/dbs/ProtectionDatabase.java index 03aaa848..5181742c 100644 --- a/src/com/sk89q/worldguard/protection/ProtectionDatabase.java +++ b/src/com/sk89q/worldguard/protection/dbs/ProtectionDatabase.java @@ -1,68 +1,70 @@ -// $Id$ -/* - * WorldGuard - * Copyright (C) 2010 sk89q - * - * 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 . -*/ - -package com.sk89q.worldguard.protection; - -import java.io.IOException; -import java.util.Map; - -/** - * Represents a database to read and write lists of regions from and to. - * - * @author sk89q - */ -public interface ProtectionDatabase { - /** - * Load the list of regions. The method should not modify the list returned - * by getRegions() unless the load finishes successfully. - * - * @throws IOException - */ - public void load() throws IOException; - /** - * Save the list of regions. - * - * @throws IOException - */ - public void save() throws IOException; - /** - * Load the list of regions into a region manager. - * - * @throws IOException - */ - public void load(RegionManager manager) throws IOException; - /** - * Save the list of regions from a region manager. - * - * @throws IOException - */ - public void save(RegionManager manager) throws IOException; - /** - * Get a list of regions. - * - * @return - */ - public Map getRegions(); - /** - * Set the list of regions. - * - * @param regions - */ - public void setRegions(Map regions); -} +// $Id$ +/* + * WorldGuard + * Copyright (C) 2010 sk89q + * + * 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 . +*/ + +package com.sk89q.worldguard.protection.dbs; + +import com.sk89q.worldguard.protection.regions.ProtectedRegion; +import com.sk89q.worldguard.protection.regionmanager.RegionManager; +import java.io.IOException; +import java.util.Map; + +/** + * Represents a database to read and write lists of regions from and to. + * + * @author sk89q + */ +public interface ProtectionDatabase { + /** + * Load the list of regions. The method should not modify the list returned + * by getRegions() unless the load finishes successfully. + * + * @throws IOException + */ + public void load() throws IOException; + /** + * Save the list of regions. + * + * @throws IOException + */ + public void save() throws IOException; + /** + * Load the list of regions into a region manager. + * + * @throws IOException + */ + public void load(RegionManager manager) throws IOException; + /** + * Save the list of regions from a region manager. + * + * @throws IOException + */ + public void save(RegionManager manager) throws IOException; + /** + * Get a list of regions. + * + * @return + */ + public Map getRegions(); + /** + * Set the list of regions. + * + * @param regions + */ + public void setRegions(Map regions); +} diff --git a/src/com/sk89q/worldguard/protection/FlatRegionManager.java b/src/com/sk89q/worldguard/protection/regionmanager/FlatRegionManager.java similarity index 81% rename from src/com/sk89q/worldguard/protection/FlatRegionManager.java rename to src/com/sk89q/worldguard/protection/regionmanager/FlatRegionManager.java index 812e0a20..e6ac5f07 100644 --- a/src/com/sk89q/worldguard/protection/FlatRegionManager.java +++ b/src/com/sk89q/worldguard/protection/regionmanager/FlatRegionManager.java @@ -1,183 +1,208 @@ -// $Id$ -/* - * WorldGuard - * Copyright (C) 2010 sk89q - * - * 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 . -*/ - -package com.sk89q.worldguard.protection; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.SortedMap; -import java.util.TreeMap; -import com.sk89q.worldedit.Vector; -import com.sk89q.worldguard.LocalPlayer; - -/** - * A very simple implementation of the region manager that uses a flat list - * and iterates through the list to identify applicable regions. This method - * is not very efficient. - * - * @author sk89q - */ -public class FlatRegionManager implements RegionManager { - /** - * List of protected regions. - */ - private Map regions; - /** - * Global flags. - */ - private GlobalFlags global; - - /** - * Construct the manager. - */ - public FlatRegionManager(GlobalFlags global) { - regions = new TreeMap(); - this.global = global; - } - - /** - * Get a list of protected regions. - * - * @return - */ - public Map getRegions() { - return regions; - } - - /** - * Set a list of protected regions. - * - * @return - */ - public void setRegions(Map regions) { - this.regions = new TreeMap(regions); - } - - /** - * Adds a region. - * - * @param id - * @param region - */ - public void addRegion(ProtectedRegion region) { - regions.put(region.getId(), 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 entry : regions.entrySet()) { - if (entry.getValue().getParent() == region) { - removeRegion(entry.getKey()); - } - } - } - } - - /** - * 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); - } - - /** - * 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 getApplicableRegionsIDs(Vector pt) { - List applicable = new ArrayList(); - - for (Map.Entry entry : regions.entrySet()) { - if (entry.getValue().contains(pt)) { - applicable.add(entry.getKey()); - } - } - - 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(); - } -} +// $Id$ +/* + * WorldGuard + * Copyright (C) 2010 sk89q + * + * 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 . +*/ + +package com.sk89q.worldguard.protection.regionmanager; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.SortedMap; +import java.util.TreeMap; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldguard.LocalPlayer; +import com.sk89q.worldguard.protection.ApplicableRegionSet; +import com.sk89q.worldguard.protection.GlobalFlags; +import com.sk89q.worldguard.protection.regions.ProtectedRegion; +import com.sk89q.worldguard.protection.UnsupportedIntersectionException; +import com.sk89q.worldguard.protection.dbs.ProtectionDatabase; +import java.io.FileNotFoundException; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * A very simple implementation of the region manager that uses a flat list + * and iterates through the list to identify applicable regions. This method + * is not very efficient. + * + * @author sk89q + */ +public class FlatRegionManager extends RegionManager { + /** + * List of protected regions. + */ + private Map regions; + + + /** + * Construct the manager. + */ + public FlatRegionManager(GlobalFlags global, ProtectionDatabase regionloader) throws IOException { + + super(global, regionloader); + regions = new TreeMap(); + this.load(); + } + + /** + * Get a list of protected regions. + * + * @return + */ + public Map getRegions() { + return regions; + } + + /** + * Set a list of protected regions. + * + * @return + */ + public void setRegions(Map regions) { + this.regions = new TreeMap(regions); + } + + /** + * Adds a region. + * + * @param id + * @param region + */ + public void addRegion(ProtectedRegion region) { + regions.put(region.getId(), 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 entry : regions.entrySet()) { + if (entry.getValue().getParent() == region) { + removeRegion(entry.getKey()); + } + } + } + } + + /** + * 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); + } + + /** + * 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 getApplicableRegionsIDs(Vector pt) { + List applicable = new ArrayList(); + + for (Map.Entry entry : regions.entrySet()) { + if (entry.getValue().contains(pt)) { + applicable.add(entry.getKey()); + } + } + + 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(); + } + + + /** + * Save the list of regions. + * + * @throws IOException + */ + public void save() throws IOException + { + if(this.regionloader == null) + { + return; + } + + regionloader.save(this); + } + +} diff --git a/src/com/sk89q/worldguard/protection/regionmanager/GlobalRegionManager.java b/src/com/sk89q/worldguard/protection/regionmanager/GlobalRegionManager.java new file mode 100644 index 00000000..630d1f56 --- /dev/null +++ b/src/com/sk89q/worldguard/protection/regionmanager/GlobalRegionManager.java @@ -0,0 +1,89 @@ +// $Id$ +/* + * WorldGuard + * Copyright (C) 2010 sk89q + * + * 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 . + */ +package com.sk89q.worldguard.protection.regionmanager; + +import com.sk89q.worldguard.bukkit.WorldGuardPlugin; +import com.sk89q.worldguard.protection.GlobalFlags; +import com.sk89q.worldguard.protection.dbs.JSONDatabase; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Logger; +import org.bukkit.World; + +/** + * + * @author Redecouverte + */ +public class GlobalRegionManager { + + private WorldGuardPlugin wg; + private HashMap managers; + private GlobalFlags globalFlags; + private static final Logger logger = Logger.getLogger("Minecraft.WorldGuard"); + + public GlobalRegionManager(WorldGuardPlugin wg) { + + this.wg = wg; + this.managers = new HashMap(); + this.globalFlags = new GlobalFlags(); + + for (World w : wg.getServer().getWorlds()) { + loadWorld(w.getName()); + } + } + + private void loadWorld(String name) { + + String filename = name + ".regions.json"; + try { + managers.put(name, new FlatRegionManager(globalFlags, new JSONDatabase(new File(wg.getDataFolder(), filename)))); + } catch (FileNotFoundException e) { + } catch (IOException e) { + logger.warning("WorldGuard: Failed to load regions from file " + filename + " : " + + e.getMessage()); + } + } + + public RegionManager getRegionmanager(String worldName) { + + RegionManager ret = this.managers.get(worldName); + + if (ret == null) { + if (wg.getServer().getWorld(worldName) != null) { + loadWorld(worldName); + } + } + + return ret; + } + + public void setGlobalFlags(GlobalFlags globalflags) { + + if (globalflags != null) { + this.globalFlags = globalflags; + for (Map.Entry entry : managers.entrySet()) { + entry.getValue().setGlobalFlags(globalflags); + } + } + + } +} diff --git a/src/com/sk89q/worldguard/protection/PRTreeRegionManager.java b/src/com/sk89q/worldguard/protection/regionmanager/PRTreeRegionManager.java similarity index 85% rename from src/com/sk89q/worldguard/protection/PRTreeRegionManager.java rename to src/com/sk89q/worldguard/protection/regionmanager/PRTreeRegionManager.java index 7236fa66..908fac39 100644 --- a/src/com/sk89q/worldguard/protection/PRTreeRegionManager.java +++ b/src/com/sk89q/worldguard/protection/regionmanager/PRTreeRegionManager.java @@ -1,203 +1,218 @@ -// $Id$ -/* - * WorldGuard - * Copyright (C) 2010 sk89q - * - * 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 . -*/ - -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 regions; - /** - * Global flags. - */ - private GlobalFlags global; - - /** - * Converter to get coordinates of the tree. - */ - private MBRConverter converter - = new ProtectedRegionMBRConverter(); - - /** - * Priority R-tree. - */ - private PRTree tree; - - /** - * Construct the manager. - */ - public PRTreeRegionManager(GlobalFlags global) { - regions = new TreeMap(); - tree = new PRTree(converter, BRANCH_FACTOR); - this.global = global; - } - - /** - * Get a list of protected regions. - * - * @return - */ - public Map getRegions() { - return regions; - } - - /** - * Set a list of protected regions. - * - * @return - */ - public void setRegions(Map regions) { - this.regions = new TreeMap(regions); - tree = new PRTree(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(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 entry : regions.entrySet()) { - if (entry.getValue().getParent() == region) { - removeRegion(entry.getKey()); - } - } - } - - tree = new PRTree(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 getApplicableRegionsIDs(Vector pt) { - List applicable = new ArrayList(); - - 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(); - } - -} +// $Id$ +/* + * WorldGuard + * Copyright (C) 2010 sk89q + * + * 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 . +*/ + +package com.sk89q.worldguard.protection.regionmanager; + +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; +import com.sk89q.worldguard.protection.ApplicableRegionSet; +import com.sk89q.worldguard.protection.GlobalFlags; +import com.sk89q.worldguard.protection.regions.ProtectedRegion; +import com.sk89q.worldguard.protection.regions.ProtectedRegionMBRConverter; +import com.sk89q.worldguard.protection.UnsupportedIntersectionException; +import com.sk89q.worldguard.protection.dbs.ProtectionDatabase; +import java.io.IOException; +import java.util.HashMap; + +public class PRTreeRegionManager extends RegionManager { + private static final int BRANCH_FACTOR = 30; + + /** + * List of protected regions. + */ + private Map regions; + + /** + * Converter to get coordinates of the tree. + */ + private MBRConverter converter + = new ProtectedRegionMBRConverter(); + + /** + * Priority R-tree. + */ + private PRTree tree; + + /** + * Construct the manager. + */ + public PRTreeRegionManager(GlobalFlags global, ProtectionDatabase regionloader) throws IOException { + super(global, regionloader); + regions = new TreeMap(); + tree = new PRTree(converter, BRANCH_FACTOR); + this.load(); + } + + /** + * Get a list of protected regions. + * + * @return + */ + public Map getRegions() { + return regions; + } + + /** + * Set a list of protected regions. + * + * @return + */ + public void setRegions(Map regions) { + this.regions = new TreeMap(regions); + tree = new PRTree(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(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 entry : regions.entrySet()) { + if (entry.getValue().getParent() == region) { + removeRegion(entry.getKey()); + } + } + } + + tree = new PRTree(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 getApplicableRegionsIDs(Vector pt) { + List applicable = new ArrayList(); + + 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(); + } + + /** + * Save the list of regions. + * + * @throws IOException + */ + public void save() throws IOException + { + regionloader.save(this); + } + +} diff --git a/src/com/sk89q/worldguard/protection/regionmanager/RegionManager.java b/src/com/sk89q/worldguard/protection/regionmanager/RegionManager.java new file mode 100644 index 00000000..c7b1c572 --- /dev/null +++ b/src/com/sk89q/worldguard/protection/regionmanager/RegionManager.java @@ -0,0 +1,181 @@ +// $Id$ +/* + * WorldGuard + * Copyright (C) 2010 sk89q + * + * 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 . +*/ + +package com.sk89q.worldguard.protection.regionmanager; + +import java.util.List; +import java.util.Map; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldguard.LocalPlayer; +import com.sk89q.worldguard.protection.ApplicableRegionSet; +import com.sk89q.worldguard.protection.GlobalFlags; +import com.sk89q.worldguard.protection.dbs.ProtectionDatabase; +import com.sk89q.worldguard.protection.regions.ProtectedRegion; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.HashMap; +import java.util.logging.Logger; + +/** + * An abstract class for getting, setting, and looking up regions. The most + * simple implementation uses a flat list and iterates through the entire + * list to look for applicable regions, but a more complicated (and more + * efficient) implementation may use space partitioning techniques. + * + * @author sk89q + */ +public abstract class RegionManager { + + private static final Logger logger = Logger.getLogger("Minecraft.WorldGuard"); + + /** + * Global flags. + */ + protected GlobalFlags global; + + + protected ProtectionDatabase regionloader; + + + public RegionManager(GlobalFlags global, ProtectionDatabase regionloader) + { + this.global = global; + this.regionloader = regionloader; + } + + + /** + * Load the list of regions. + * + * @throws IOException + */ + public void load() throws IOException + { + if(this.regionloader == null) + { + return; + } + + try { + this.regionloader.load(); + this.setRegions(this.regionloader.getRegions()); + + } catch (FileNotFoundException e) { + } catch (IOException e) { + logger.warning("WorldGuard: Failed to load regions: " + + e.getMessage()); + } + } + + + /** + * Save the list of regions. + * + * @throws IOException + */ + public abstract void save() throws IOException; + + + /** + * Get a list of protected regions. + * + * @return + */ + public abstract Map getRegions(); + + /** + * Set a list of protected regions. + * + * @return + */ + public abstract void setRegions(Map regions); + + /** + * Adds a region. + * + * @param id + * @param region + */ + public abstract void addRegion(ProtectedRegion region); + + /** + * Return whether a region exists by an ID. + * + * @param id + * @return + */ + public abstract boolean hasRegion(String id); + + /** + * Get a region by its ID. + * + * @param id + */ + public abstract ProtectedRegion getRegion(String id); + + /** + * Removes a region, including inheriting children. + * + * @param id + */ + public abstract void removeRegion(String id); + + /** + * Get an object for a point for rules to be applied with. + * + * @param pt + * @return + */ + public abstract ApplicableRegionSet getApplicableRegions(Vector pt); + + /** + * Get a list of region IDs that contain a point. + * + * @param pt + * @return + */ + public abstract List getApplicableRegionsIDs(Vector pt); + + /** + * Returns true if the provided region overlaps with any other region that + * is not owned by the player. + * + * @param region + * @param player + * @return + */ + public abstract boolean overlapsUnownedRegion(ProtectedRegion region, LocalPlayer player); + + /** + * Get the number of regions. + * + * @return + */ + public abstract int size(); + + /** + * Sets the global flags. + * + * @return + */ + public void setGlobalFlags(GlobalFlags globalflags) + { + global = globalflags; + } +} diff --git a/src/com/sk89q/worldguard/protection/AreaFlags.java b/src/com/sk89q/worldguard/protection/regions/AreaFlags.java similarity index 96% rename from src/com/sk89q/worldguard/protection/AreaFlags.java rename to src/com/sk89q/worldguard/protection/regions/AreaFlags.java index 4b31fb27..81a12d96 100644 --- a/src/com/sk89q/worldguard/protection/AreaFlags.java +++ b/src/com/sk89q/worldguard/protection/regions/AreaFlags.java @@ -1,145 +1,145 @@ -// $Id$ -/* - * WorldGuard - * Copyright (C) 2010 sk89q - * - * 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 . -*/ - -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 - */ -public class AreaFlags { - public enum State { - NONE, - ALLOW, - DENY, - }; - - 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 states = new HashMap(); - - 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> entrySet() { - return states.entrySet(); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof AreaFlags)) { - return false; - } - - AreaFlags other = (AreaFlags)obj; - return other.states.equals(this); - } -} +// $Id$ +/* + * WorldGuard + * Copyright (C) 2010 sk89q + * + * 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 . +*/ + +package com.sk89q.worldguard.protection.regions; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * Holds the flags for a region. + * + * @author sk89q + */ +public class AreaFlags { + public enum State { + NONE, + ALLOW, + DENY, + }; + + 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 states = new HashMap(); + + 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> entrySet() { + return states.entrySet(); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof AreaFlags)) { + return false; + } + + AreaFlags other = (AreaFlags)obj; + return other.states.equals(this); + } +} diff --git a/src/com/sk89q/worldguard/protection/ProtectedCuboidRegion.java b/src/com/sk89q/worldguard/protection/regions/ProtectedCuboidRegion.java similarity index 98% rename from src/com/sk89q/worldguard/protection/ProtectedCuboidRegion.java rename to src/com/sk89q/worldguard/protection/regions/ProtectedCuboidRegion.java index 4d7f0fa6..7638f06a 100644 --- a/src/com/sk89q/worldguard/protection/ProtectedCuboidRegion.java +++ b/src/com/sk89q/worldguard/protection/regions/ProtectedCuboidRegion.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldguard.protection; +package com.sk89q.worldguard.protection.regions; import com.sk89q.worldedit.*; diff --git a/src/com/sk89q/worldguard/protection/ProtectedPolygonalRegion.java b/src/com/sk89q/worldguard/protection/regions/ProtectedPolygonalRegion.java similarity index 95% rename from src/com/sk89q/worldguard/protection/ProtectedPolygonalRegion.java rename to src/com/sk89q/worldguard/protection/regions/ProtectedPolygonalRegion.java index 6337ac44..d21ef495 100644 --- a/src/com/sk89q/worldguard/protection/ProtectedPolygonalRegion.java +++ b/src/com/sk89q/worldguard/protection/regions/ProtectedPolygonalRegion.java @@ -1,132 +1,132 @@ -// $Id$ -/* - * WorldGuard - * Copyright (C) 2010 sk89q - * - * 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 . -*/ - -package com.sk89q.worldguard.protection; - -import java.util.List; -import com.sk89q.worldedit.BlockVector; -import com.sk89q.worldedit.BlockVector2D; -import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.Vector2D; - -public class ProtectedPolygonalRegion extends ProtectedRegion { - protected List points; - protected int minY; - protected int maxY; - private BlockVector min; - private BlockVector max; - - public ProtectedPolygonalRegion(String id, List points, int minY, int maxY) { - super(id); - this.points = points; - this.minY = minY; - this.maxY = maxY; - - int minX = points.get(0).getBlockX(); - int minZ = points.get(0).getBlockZ(); - int maxX = points.get(0).getBlockX(); - int maxZ = points.get(0).getBlockZ(); - - for (BlockVector2D v : points) { - int x = v.getBlockX(); - int z = v.getBlockZ(); - if (x < minX) minX = x; - if (z < minZ) minZ = z; - if (x > maxX) maxX = x; - if (z > maxZ) maxZ = z; - } - - min = new BlockVector(minX, minY, minZ); - max = new BlockVector(maxX, maxY, maxZ); - } - - @Override - public BlockVector getMinimumPoint() { - return min; - } - - @Override - public BlockVector getMaximumPoint() { - return max; - } - - /** - * Checks to see if a point is inside this region. - */ - @Override - public boolean contains(Vector pt) { - int targetX = pt.getBlockX(); //wide - int targetY = pt.getBlockY(); //height - int targetZ = pt.getBlockZ(); //depth - - if (targetY < minY || targetY > maxY) { - return false; - } - //Quick and dirty check. - if(targetX < min.getBlockX() || targetX > max.getBlockX() || targetZ < min.getBlockZ() || targetZ > max.getBlockZ()){ - return false; - } - boolean inside = false; - int npoints = points.size(); - int xNew, zNew; - int xOld, zOld; - int x1, z1; - int x2, z2; - int i; - - xOld = points.get(npoints - 1).getBlockX(); - zOld = points.get(npoints - 1).getBlockZ(); - - for (i = 0; i < npoints; i++) { - xNew = points.get(i).getBlockX(); - zNew = points.get(i).getBlockZ(); - if (xNew > xOld) { - x1 = xOld; - x2 = xNew; - z1 = zOld; - z2 = zNew; - } else { - x1 = xNew; - x2 = xOld; - z1 = zNew; - z2 = zOld; - } - if ((xNew < targetX) == (targetX <= xOld) - && ((long) targetZ - (long) z1) * (long) (x2 - x1) <= ((long) z2 - (long) z1) - * (long) (targetX - x1)) { - inside = !inside; - } - xOld = xNew; - zOld = zNew; - } - - return inside; - } - - /** - * Return the type of region as a user-friendly name. - * - * @return type of region - */ - @Override - public String getTypeName() { - return "polygon"; - } - -} +// $Id$ +/* + * WorldGuard + * Copyright (C) 2010 sk89q + * + * 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 . +*/ + +package com.sk89q.worldguard.protection.regions; + +import java.util.List; +import com.sk89q.worldedit.BlockVector; +import com.sk89q.worldedit.BlockVector2D; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.Vector2D; + +public class ProtectedPolygonalRegion extends ProtectedRegion { + protected List points; + protected int minY; + protected int maxY; + private BlockVector min; + private BlockVector max; + + public ProtectedPolygonalRegion(String id, List points, int minY, int maxY) { + super(id); + this.points = points; + this.minY = minY; + this.maxY = maxY; + + int minX = points.get(0).getBlockX(); + int minZ = points.get(0).getBlockZ(); + int maxX = points.get(0).getBlockX(); + int maxZ = points.get(0).getBlockZ(); + + for (BlockVector2D v : points) { + int x = v.getBlockX(); + int z = v.getBlockZ(); + if (x < minX) minX = x; + if (z < minZ) minZ = z; + if (x > maxX) maxX = x; + if (z > maxZ) maxZ = z; + } + + min = new BlockVector(minX, minY, minZ); + max = new BlockVector(maxX, maxY, maxZ); + } + + @Override + public BlockVector getMinimumPoint() { + return min; + } + + @Override + public BlockVector getMaximumPoint() { + return max; + } + + /** + * Checks to see if a point is inside this region. + */ + @Override + public boolean contains(Vector pt) { + int targetX = pt.getBlockX(); //wide + int targetY = pt.getBlockY(); //height + int targetZ = pt.getBlockZ(); //depth + + if (targetY < minY || targetY > maxY) { + return false; + } + //Quick and dirty check. + if(targetX < min.getBlockX() || targetX > max.getBlockX() || targetZ < min.getBlockZ() || targetZ > max.getBlockZ()){ + return false; + } + boolean inside = false; + int npoints = points.size(); + int xNew, zNew; + int xOld, zOld; + int x1, z1; + int x2, z2; + int i; + + xOld = points.get(npoints - 1).getBlockX(); + zOld = points.get(npoints - 1).getBlockZ(); + + for (i = 0; i < npoints; i++) { + xNew = points.get(i).getBlockX(); + zNew = points.get(i).getBlockZ(); + if (xNew > xOld) { + x1 = xOld; + x2 = xNew; + z1 = zOld; + z2 = zNew; + } else { + x1 = xNew; + x2 = xOld; + z1 = zNew; + z2 = zOld; + } + if ((xNew < targetX) == (targetX <= xOld) + && ((long) targetZ - (long) z1) * (long) (x2 - x1) <= ((long) z2 - (long) z1) + * (long) (targetX - x1)) { + inside = !inside; + } + xOld = xNew; + zOld = zNew; + } + + return inside; + } + + /** + * Return the type of region as a user-friendly name. + * + * @return type of region + */ + @Override + public String getTypeName() { + return "polygon"; + } + +} diff --git a/src/com/sk89q/worldguard/protection/ProtectedRegion.java b/src/com/sk89q/worldguard/protection/regions/ProtectedRegion.java similarity index 91% rename from src/com/sk89q/worldguard/protection/ProtectedRegion.java rename to src/com/sk89q/worldguard/protection/regions/ProtectedRegion.java index e3351a40..ef3b6a92 100644 --- a/src/com/sk89q/worldguard/protection/ProtectedRegion.java +++ b/src/com/sk89q/worldguard/protection/regions/ProtectedRegion.java @@ -1,334 +1,361 @@ -// $Id$ -/* - * WorldGuard - * Copyright (C) 2010 sk89q - * - * 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 . -*/ - -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; - -/** - * Represents a region of any shape and size that can be protected. - * - * @author sk89q - */ -public abstract class ProtectedRegion implements Comparable { - /** - * Holds the region's ID. - */ - 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 - */ - 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 - */ - public int getPriority() { - return priority; - } - - /** - * @param priority the priority to set - */ - public void setPriority(int priority) { - 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 - */ - public void setFlags(AreaFlags flags) { - this.flags = flags; - } - - /** - * @return the enterMessage - */ - public String getEnterMessage() { - return enterMessage; - } - - /** - * @param enterMessage the enterMessage to set - */ - 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 - */ - public DefaultDomain getOwners() { - return owners; - } - - /** - * @param owners the owners to set - */ - public void setOwners(DefaultDomain owners) { - 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. - * - * @return - */ - public AreaFlags getFlags() { - return flags; - } - - /** - * Check to see if a point is inside this region. - * - * @param pt - * @return - */ - public abstract boolean contains(Vector pt); - - /** - * Compares to another region. - * - * @param other - * @return - */ - public int compareTo(ProtectedRegion other) { - if (priority == other.priority) { - return 0; - } else if (priority > other.priority) { - return -1; - } else { - return 1; - } - } - - /** - * Return the type of region as a user-friendly, lowercase name. - * - * @return type of region - */ - public abstract String getTypeName(); - - /** - * Checks if two region intersects. - * - * @param region1 - * @param region2 - * @throws UnsupportedIntersectionException - * @return - */ - public static boolean intersects(ProtectedRegion region1, ProtectedRegion region2) - throws UnsupportedIntersectionException { - if (region1 instanceof ProtectedCuboidRegion - && region2 instanceof ProtectedCuboidRegion) { - ProtectedCuboidRegion r1 = (ProtectedCuboidRegion)region1; - ProtectedCuboidRegion r2 = (ProtectedCuboidRegion)region2; - BlockVector min1 = r1.getMinimumPoint(); - BlockVector max1 = r1.getMaximumPoint(); - BlockVector min2 = r2.getMinimumPoint(); - BlockVector max2 = r2.getMaximumPoint(); - - return !(min1.getBlockX() > max2.getBlockX() - || min1.getBlockY() > max2.getBlockY() - || min1.getBlockZ() > max2.getBlockZ() - || max1.getBlockX() < min2.getBlockX() - || max1.getBlockY() < min2.getBlockY() - || max1.getBlockZ() < min2.getBlockZ()); - } else { - 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; - } -} +// $Id$ +/* + * WorldGuard + * Copyright (C) 2010 sk89q + * + * 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 . +*/ + +package com.sk89q.worldguard.protection.regions; + +import com.sk89q.worldedit.BlockVector; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldguard.LocalPlayer; +import com.sk89q.worldguard.domains.DefaultDomain; +import com.sk89q.worldguard.protection.UnsupportedIntersectionException; + +/** + * Represents a region of any shape and size that can be protected. + * + * @author sk89q + */ +public abstract class ProtectedRegion implements Comparable { + /** + * Holds the region's ID. + */ + private String id; + /** + * Priority. + */ + private int priority = 0; + /** + * Holds the parent. + */ + private transient ProtectedRegion parent; + /** + * Holds the parent's Id. Used for serialization, don't touch it. + */ + private String parentId; + /** + * 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 + */ + public ProtectedRegion(String id) { + this.id = id; + } + + /** + * @return the id + */ + public String getId() { + return id; + } + + /** + * @return the parentId. + */ + public String getParentId() { + this.setParentId(); + return parentId; + } + + /** + * @set the parentId. Used for serialization, don't touch it. + */ + public void setParentId() { + + if (this.parent != null) { + this.parentId = parent.getId(); + } else { + this.parentId = null; + } + } + + /** + * 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 + */ + public int getPriority() { + return priority; + } + + /** + * @param priority the priority to set + */ + public void setPriority(int priority) { + 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 + */ + public void setFlags(AreaFlags flags) { + this.flags = flags; + } + + /** + * @return the enterMessage + */ + public String getEnterMessage() { + return enterMessage; + } + + /** + * @param enterMessage the enterMessage to set + */ + 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 + */ + public DefaultDomain getOwners() { + + return owners; + } + + /** + * @param owners the owners to set + */ + public void setOwners(DefaultDomain owners) { + 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. + * + * @return + */ + public AreaFlags getFlags() { + return flags; + } + + /** + * Check to see if a point is inside this region. + * + * @param pt + * @return + */ + public abstract boolean contains(Vector pt); + + /** + * Compares to another region. + * + * @param other + * @return + */ + public int compareTo(ProtectedRegion other) { + if (priority == other.priority) { + return 0; + } else if (priority > other.priority) { + return -1; + } else { + return 1; + } + } + + /** + * Return the type of region as a user-friendly, lowercase name. + * + * @return type of region + */ + public abstract String getTypeName(); + + /** + * Checks if two region intersects. + * + * @param region1 + * @param region2 + * @throws UnsupportedIntersectionException + * @return + */ + public static boolean intersects(ProtectedRegion region1, ProtectedRegion region2) + throws UnsupportedIntersectionException { + if (region1 instanceof ProtectedCuboidRegion + && region2 instanceof ProtectedCuboidRegion) { + ProtectedCuboidRegion r1 = (ProtectedCuboidRegion)region1; + ProtectedCuboidRegion r2 = (ProtectedCuboidRegion)region2; + BlockVector min1 = r1.getMinimumPoint(); + BlockVector max1 = r1.getMaximumPoint(); + BlockVector min2 = r2.getMinimumPoint(); + BlockVector max2 = r2.getMaximumPoint(); + + return !(min1.getBlockX() > max2.getBlockX() + || min1.getBlockY() > max2.getBlockY() + || min1.getBlockZ() > max2.getBlockZ() + || max1.getBlockX() < min2.getBlockX() + || max1.getBlockY() < min2.getBlockY() + || max1.getBlockZ() < min2.getBlockZ()); + } else { + 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; + } +} diff --git a/src/com/sk89q/worldguard/protection/ProtectedRegionMBRConverter.java b/src/com/sk89q/worldguard/protection/regions/ProtectedRegionMBRConverter.java similarity index 91% rename from src/com/sk89q/worldguard/protection/ProtectedRegionMBRConverter.java rename to src/com/sk89q/worldguard/protection/regions/ProtectedRegionMBRConverter.java index 268a4904..a59df7e1 100644 --- a/src/com/sk89q/worldguard/protection/ProtectedRegionMBRConverter.java +++ b/src/com/sk89q/worldguard/protection/regions/ProtectedRegionMBRConverter.java @@ -1,41 +1,42 @@ -// $Id$ -/* - * WorldGuard - * Copyright (C) 2010 sk89q - * - * 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 . -*/ - -package com.sk89q.worldguard.protection; - -import org.khelekore.prtree.MBRConverter; - -public class ProtectedRegionMBRConverter implements MBRConverter { - 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(); - } - -} +// $Id$ +/* + * WorldGuard + * Copyright (C) 2010 sk89q + * + * 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 . +*/ + +package com.sk89q.worldguard.protection.regions; + +import com.sk89q.worldguard.protection.regions.ProtectedRegion; +import org.khelekore.prtree.MBRConverter; + +public class ProtectedRegionMBRConverter implements MBRConverter { + 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(); + } + +} diff --git a/tests/com/sk89q/worldguard/protection/ApplicableRegionSetTest.java b/tests/com/sk89q/worldguard/protection/ApplicableRegionSetTest.java index 0fb4c91a..e4413434 100644 --- a/tests/com/sk89q/worldguard/protection/ApplicableRegionSetTest.java +++ b/tests/com/sk89q/worldguard/protection/ApplicableRegionSetTest.java @@ -19,6 +19,11 @@ package com.sk89q.worldguard.protection; +import com.sk89q.worldguard.protection.regions.ProtectedRegion; +import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion; +import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion; +import com.sk89q.worldguard.protection.regionmanager.RegionManager; +import com.sk89q.worldguard.protection.regionmanager.FlatRegionManager; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.*; @@ -27,7 +32,8 @@ import com.sk89q.worldedit.Vector; import com.sk89q.worldguard.TestPlayer; import com.sk89q.worldguard.domains.DefaultDomain; -import com.sk89q.worldguard.protection.AreaFlags.State; +import com.sk89q.worldguard.protection.regions.AreaFlags; +import com.sk89q.worldguard.protection.regions.AreaFlags.State; import java.util.ArrayList; import java.util.List; @@ -50,7 +56,7 @@ public class ApplicableRegionSetTest { @Before public void setUp() throws Exception { - manager = new FlatRegionManager(new GlobalFlags()); + manager = new FlatRegionManager(new GlobalFlags(), null); setUpPlayers(); setUpCourtyardRegion(); diff --git a/tests/com/sk89q/worldguard/protection/CSVDatabaseTest.java b/tests/com/sk89q/worldguard/protection/CSVDatabaseTest.java index 9fe0a6d4..c6a1bbf0 100644 --- a/tests/com/sk89q/worldguard/protection/CSVDatabaseTest.java +++ b/tests/com/sk89q/worldguard/protection/CSVDatabaseTest.java @@ -19,6 +19,9 @@ package com.sk89q.worldguard.protection; +import com.sk89q.worldguard.protection.dbs.CSVDatabase; +import com.sk89q.worldguard.protection.regions.ProtectedRegion; +import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion; import java.io.*; import java.util.Map; import java.util.HashMap; @@ -28,7 +31,8 @@ import static org.junit.Assert.*; import com.sk89q.worldedit.BlockVector; import com.sk89q.worldguard.domains.DefaultDomain; -import com.sk89q.worldguard.protection.AreaFlags.State; +import com.sk89q.worldguard.protection.regions.AreaFlags; +import com.sk89q.worldguard.protection.regions.AreaFlags.State; public class CSVDatabaseTest { @Before