diff --git a/src/com/sk89q/worldguard/bukkit/WorldGuardPlayerListener.java b/src/com/sk89q/worldguard/bukkit/WorldGuardPlayerListener.java index 379eec77..b38ad379 100644 --- a/src/com/sk89q/worldguard/bukkit/WorldGuardPlayerListener.java +++ b/src/com/sk89q/worldguard/bukkit/WorldGuardPlayerListener.java @@ -301,7 +301,7 @@ public boolean handleCommand(PlayerChatEvent event) { } else if (split[0].equalsIgnoreCase("/rg") || split[0].equalsIgnoreCase("/region")) { if (split.length < 2) { - player.sendMessage(ChatColor.RED + "/region ..."); + player.sendMessage(ChatColor.RED + "/region ..."); return true; } @@ -455,8 +455,7 @@ private void handleRegionCommand(Player player, String action, String[] args) { } if (args.length < 4) { - player.sendMessage(ChatColor.RED + "/region flag "); - player.sendMessage(ChatColor.RED + "Other flags not supported in Bukkit at the moment."); + player.sendMessage(ChatColor.RED + "/region flag "); return; } @@ -486,13 +485,13 @@ private void handleRegionCommand(Player player, String action, String[] args) { AreaFlags flags = region.getFlags(); - /*if (flagStr.equalsIgnoreCase("build")) { + if (flagStr.equalsIgnoreCase("build")) { flags.allowBuild = state; } else if (flagStr.equalsIgnoreCase("pvp")) { flags.allowPvP = state; } else if (flagStr.equalsIgnoreCase("tnt")) { flags.allowTNT = state; - } else*/ if (flagStr.equalsIgnoreCase("lighter")) { + } else if (flagStr.equalsIgnoreCase("lighter")) { flags.allowLighter = state; } else { player.sendMessage(ChatColor.RED + "Acceptable flags: build, pvp, tnt, lighter"); @@ -505,6 +504,42 @@ private void handleRegionCommand(Player player, String action, String[] args) { player.sendMessage(ChatColor.RED + "Region database failed to save: " + e.getMessage()); } + /*} else if (action.equalsIgnoreCase("priority")) { + if (!canUseRegionCommand(player, "/regiondefine")) { + player.sendMessage(ChatColor.RED + "You don't have the /regiondefine permission."); + return; + } + + if (args.length < 3) { + player.sendMessage(ChatColor.RED + "/region priority "); + return; + } + + try { + String id = args[1].toLowerCase(); + int priority = 0; + try { + priority = Integer.parseInt(args[2]); + } catch (NumberFormatException e) { + player.sendMessage(ChatColor.RED + "The priority must be a number."); + return; + } + + ProtectedRegion region = plugin.regionManager.getRegion(id); + + if (region == null) { + player.sendMessage(ChatColor.RED + "Could not find a region by that ID."); + return; + } + + region.setPriority(priority); + + plugin.regionLoader.save(plugin.regionManager); + player.sendMessage(ChatColor.YELLOW + "Region '" + id + "' updated."); + } catch (IOException e) { + player.sendMessage(ChatColor.RED + "Region database failed to save: " + + e.getMessage()); + }*/ } else if (action.equalsIgnoreCase("info")) { if (!canUseRegionCommand(player, "/regioninfo")) { player.sendMessage(ChatColor.RED + "You don't have the /regioninfo permission."); @@ -529,6 +564,7 @@ private void handleRegionCommand(Player player, String action, String[] args) { player.sendMessage(ChatColor.YELLOW + "Region ID: " + id); player.sendMessage(ChatColor.GRAY + "Type: " + region.getClass().getCanonicalName()); + player.sendMessage(ChatColor.GRAY + "Priority: " + region.getPriority()); player.sendMessage(ChatColor.BLUE + "Build: " + flags.allowBuild.name()); player.sendMessage(ChatColor.BLUE + "PvP: " + flags.allowPvP.name()); player.sendMessage(ChatColor.BLUE + "TNT: " + flags.allowTNT.name()); diff --git a/src/com/sk89q/worldguard/protection/ApplicableRegionSet.java b/src/com/sk89q/worldguard/protection/ApplicableRegionSet.java index 076ef872..d557a3be 100644 --- a/src/com/sk89q/worldguard/protection/ApplicableRegionSet.java +++ b/src/com/sk89q/worldguard/protection/ApplicableRegionSet.java @@ -19,7 +19,7 @@ package com.sk89q.worldguard.protection; -import java.util.Map; +import java.util.SortedMap; import com.sk89q.worldedit.Vector; import com.sk89q.worldguard.LocalPlayer; import com.sk89q.worldguard.protection.AreaFlags.State; @@ -31,93 +31,172 @@ */ public class ApplicableRegionSet { private Vector pt; - private Map regions; + private SortedMap regions; - public ApplicableRegionSet(Vector pt, Map regions) { + public ApplicableRegionSet(Vector pt, SortedMap regions) { this.pt = pt; this.regions = regions; } public boolean canBuild(LocalPlayer player) { - boolean allowed = false; boolean found = false; + int lastPriority = 0; for (ProtectedRegion region : regions.values()) { + if (region.getFlags().allowBuild == State.ALLOW) continue; if (!region.contains(pt)) continue; - if (region.getFlags().allowBuild == State.DENY) return false; + + // Ignore lower priority regions + if (found && region.getPriority() < lastPriority) { + break; + } + + if (!region.getOwners().contains(player)) { + return false; + } found = true; - - if (!allowed && region.getFlags().allowBuild == State.ALLOW) { - allowed = true; - } - - if (!allowed && region.getOwners().contains(player)) { - allowed = true; - } + lastPriority = region.getPriority(); } - return found ? allowed : true; + return true; } public boolean allowsPvP() { + boolean found = false; + int lastPriority = 0; + for (ProtectedRegion region : regions.values()) { if (!region.contains(pt)) continue; - if (region.getFlags().allowBuild == State.DENY) return false; + if (region.getFlags().allowPvP == State.DENY) return false; + + // Ignore lower priority regions + if (found && region.getPriority() < lastPriority) { + break; + } + + found = true; + lastPriority = region.getPriority(); } return true; } public boolean allowsMobDamage() { + boolean found = false; + int lastPriority = 0; + for (ProtectedRegion region : regions.values()) { if (!region.contains(pt)) continue; if (region.getFlags().allowMobDamage == State.DENY) return false; + + // Ignore lower priority regions + if (found && region.getPriority() < lastPriority) { + break; + } + + found = true; + lastPriority = region.getPriority(); } return true; } public boolean allowsCreeperExplosions() { + boolean found = false; + int lastPriority = 0; + for (ProtectedRegion region : regions.values()) { if (!region.contains(pt)) continue; if (region.getFlags().allowCreeperExplosions == State.DENY) return false; + + // Ignore lower priority regions + if (found && region.getPriority() < lastPriority) { + break; + } + + found = true; + lastPriority = region.getPriority(); } return true; } public boolean allowsTNT() { + boolean found = false; + int lastPriority = 0; + for (ProtectedRegion region : regions.values()) { if (!region.contains(pt)) continue; if (region.getFlags().allowTNT == State.DENY) return false; + + // Ignore lower priority regions + if (found && region.getPriority() < lastPriority) { + break; + } + + found = true; + lastPriority = region.getPriority(); } return true; } public boolean allowsLighter() { + boolean found = false; + int lastPriority = 0; + for (ProtectedRegion region : regions.values()) { if (!region.contains(pt)) continue; if (region.getFlags().allowLighter == State.DENY) return false; + + // Ignore lower priority regions + if (found && region.getPriority() < lastPriority) { + break; + } + + found = true; + lastPriority = region.getPriority(); } return true; } public boolean allowsFireSpread() { + boolean found = false; + int lastPriority = 0; + for (ProtectedRegion region : regions.values()) { if (!region.contains(pt)) continue; if (region.getFlags().allowFireSpread == State.DENY) return false; + + // Ignore lower priority regions + if (found && region.getPriority() < lastPriority) { + break; + } + + found = true; + lastPriority = region.getPriority(); } return true; } public boolean allowsLavaFire() { + boolean found = false; + int lastPriority = 0; + for (ProtectedRegion region : regions.values()) { if (!region.contains(pt)) continue; if (region.getFlags().allowLavaFire == State.DENY) return false; + + // Ignore lower priority regions + if (found && region.getPriority() < lastPriority) { + break; + } + + found = true; + lastPriority = region.getPriority(); } return true; diff --git a/src/com/sk89q/worldguard/protection/CSVDatabase.java b/src/com/sk89q/worldguard/protection/CSVDatabase.java index dd24983a..e4edc289 100644 --- a/src/com/sk89q/worldguard/protection/CSVDatabase.java +++ b/src/com/sk89q/worldguard/protection/CSVDatabase.java @@ -28,6 +28,7 @@ import au.com.bytecode.opencsv.CSVReader; import au.com.bytecode.opencsv.CSVWriter; import com.sk89q.worldedit.BlockVector; +import com.sk89q.worldedit.Vector; import com.sk89q.worldguard.domains.DefaultDomain; import com.sk89q.worldguard.protection.AreaFlags.State; @@ -126,14 +127,18 @@ public void load() throws IOException { } String id = line[0]; - BlockVector min = new BlockVector( + Vector pt1 = new Vector( Integer.parseInt(line[2]), Integer.parseInt(line[3]), Integer.parseInt(line[4])); - BlockVector max = new BlockVector( + Vector pt2 = new Vector( Integer.parseInt(line[5]), Integer.parseInt(line[6]), Integer.parseInt(line[7])); + + BlockVector min = Vector.getMinimum(pt1, pt2).toBlockVector(); + BlockVector max = Vector.getMaximum(pt1, pt2).toBlockVector(); + int priority = Integer.parseInt(line[8]); String ownersData = line[9]; String flagsData = line[10]; @@ -146,7 +151,7 @@ public void load() throws IOException { region.setFlags(parseFlags(flagsData)); regions.put(id, region); } else { - logger.warning("Line has invalid: " + line); + logger.warning("Line is invalid: " + line); } } } finally { diff --git a/src/com/sk89q/worldguard/protection/DescendingPriorityComparator.java b/src/com/sk89q/worldguard/protection/DescendingPriorityComparator.java new file mode 100644 index 00000000..6b198a9a --- /dev/null +++ b/src/com/sk89q/worldguard/protection/DescendingPriorityComparator.java @@ -0,0 +1,40 @@ +// $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.Comparator; + +class DescendingPriorityComparator implements Comparator { + /** + * Compares two regions. + * + * @param other + * @return + */ + public int compare(ProtectedRegion r1, ProtectedRegion r2) { + if (r1.getPriority() == r2.getPriority()) { + return 0; + } else if (r1.getPriority() > r2.getPriority()) { + return -1; + } else { + return 1; + } + } +} diff --git a/src/com/sk89q/worldguard/protection/FlatRegionManager.java b/src/com/sk89q/worldguard/protection/FlatRegionManager.java index 44bb050b..f0bab964 100644 --- a/src/com/sk89q/worldguard/protection/FlatRegionManager.java +++ b/src/com/sk89q/worldguard/protection/FlatRegionManager.java @@ -22,7 +22,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.LinkedHashMap; +import java.util.SortedMap; +import java.util.TreeMap; import com.sk89q.worldedit.Vector; import com.sk89q.worldguard.LocalPlayer; @@ -37,13 +38,13 @@ public class FlatRegionManager implements RegionManager { /** * List of protected regions. */ - private Map regions; + private SortedMap regions; /** * Construct the manager. */ public FlatRegionManager() { - regions = new LinkedHashMap(); + regions = new TreeMap(); } /** @@ -54,7 +55,16 @@ public FlatRegionManager() { 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. * @@ -93,15 +103,6 @@ public ProtectedRegion getRegion(String id) { return regions.get(id); } - /** - * Set a list of protected regions. - * - * @return - */ - public void setRegions(Map regions) { - this.regions = regions; - } - /** * Get an object for a point for rules to be applied with. * diff --git a/src/com/sk89q/worldguard/protection/ProtectedRegion.java b/src/com/sk89q/worldguard/protection/ProtectedRegion.java index 957f050d..36332c55 100644 --- a/src/com/sk89q/worldguard/protection/ProtectedRegion.java +++ b/src/com/sk89q/worldguard/protection/ProtectedRegion.java @@ -28,7 +28,7 @@ * * @author sk89q */ -public abstract class ProtectedRegion { +public abstract class ProtectedRegion implements Comparable { /** * Area message. */ @@ -47,7 +47,7 @@ public abstract class ProtectedRegion { private AreaFlags flags = new AreaFlags(); /** - * Construct a new instance of this cuboid region. + * Construct a new instance of this region. * * @param id * @param priority @@ -127,6 +127,22 @@ public AreaFlags getFlags() { */ 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; + } + } + /** * Checks if two region intersects. * diff --git a/src/com/sk89q/worldguard/protection/RegionManager.java b/src/com/sk89q/worldguard/protection/RegionManager.java index 95bd82c9..669a180e 100644 --- a/src/com/sk89q/worldguard/protection/RegionManager.java +++ b/src/com/sk89q/worldguard/protection/RegionManager.java @@ -38,7 +38,7 @@ public interface RegionManager { * * @return */ - public Map getRegions(); + public Map getRegions(); /** * Set a list of protected regions.