diff --git a/src/main/java/com/sk89q/worldguard/LocalPlayer.java b/src/main/java/com/sk89q/worldguard/LocalPlayer.java
index 585acd2f..46689110 100644
--- a/src/main/java/com/sk89q/worldguard/LocalPlayer.java
+++ b/src/main/java/com/sk89q/worldguard/LocalPlayer.java
@@ -24,6 +24,7 @@
import com.sk89q.worldguard.protection.association.RegionAssociable;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
+import java.util.List;
import java.util.UUID;
public abstract class LocalPlayer implements RegionAssociable {
@@ -94,14 +95,18 @@ public abstract class LocalPlayer implements RegionAssociable {
public abstract boolean hasPermission(String perm);
@Override
- public Association getAssociation(ProtectedRegion region) {
- if (region.isOwner(this)) {
- return Association.OWNER;
- } else if (region.isMember(this)) {
- return Association.MEMBER;
- } else {
- return Association.NON_MEMBER;
+ public Association getAssociation(List regions) {
+ boolean member = false;
+
+ for (ProtectedRegion region : regions) {
+ if (region.isOwner(this)) {
+ return Association.OWNER;
+ } else if (!member && region.isMember(this)) {
+ member = true;
+ }
}
+
+ return member ? Association.MEMBER : Association.NON_MEMBER;
}
@Override
diff --git a/src/main/java/com/sk89q/worldguard/bukkit/protection/DelayedRegionOverlapAssociation.java b/src/main/java/com/sk89q/worldguard/bukkit/protection/DelayedRegionOverlapAssociation.java
index 953b5e69..8577639b 100644
--- a/src/main/java/com/sk89q/worldguard/bukkit/protection/DelayedRegionOverlapAssociation.java
+++ b/src/main/java/com/sk89q/worldguard/bukkit/protection/DelayedRegionOverlapAssociation.java
@@ -27,6 +27,7 @@
import org.bukkit.Location;
import javax.annotation.Nullable;
+import java.util.List;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -36,7 +37,7 @@
* region is in a set of source regions.
*
* This class only performs a spatial query if its
- * {@link #getAssociation(ProtectedRegion)} method is called.
+ * {@link #getAssociation(List)} method is called.
*/
public class DelayedRegionOverlapAssociation implements RegionAssociable {
@@ -59,17 +60,19 @@ public DelayedRegionOverlapAssociation(RegionQuery query, Location location) {
}
@Override
- public Association getAssociation(ProtectedRegion region) {
+ public Association getAssociation(List regions) {
if (source == null) {
ApplicableRegionSet result = query.getApplicableRegions(location);
source = result.getRegions();
}
- if ((region.getId().equals(ProtectedRegion.GLOBAL_REGION) && source.isEmpty()) || source.contains(region)) {
- return Association.OWNER;
- } else {
- return Association.NON_MEMBER;
+ for (ProtectedRegion region : regions) {
+ if ((region.getId().equals(ProtectedRegion.GLOBAL_REGION) && source.isEmpty()) || source.contains(region)) {
+ return Association.OWNER;
+ }
}
+
+ return Association.NON_MEMBER;
}
}
diff --git a/src/main/java/com/sk89q/worldguard/protection/FlagValueCalculator.java b/src/main/java/com/sk89q/worldguard/protection/FlagValueCalculator.java
index 858b7e2e..b337c094 100644
--- a/src/main/java/com/sk89q/worldguard/protection/FlagValueCalculator.java
+++ b/src/main/java/com/sk89q/worldguard/protection/FlagValueCalculator.java
@@ -31,13 +31,7 @@
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import javax.annotation.Nullable;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -157,7 +151,7 @@ public Result getMembership(RegionAssociable subject) {
foundApplicableRegion = true;
if (!hasCleared.contains(region)) {
- if (!RegionGroup.MEMBERS.contains(subject.getAssociation(region))) {
+ if (!RegionGroup.MEMBERS.contains(subject.getAssociation(Arrays.asList(region)))) {
needsClear.add(region);
} else {
// Need to clear all parents
@@ -330,12 +324,6 @@ public Collection queryAllValues(@Nullable RegionAssociable subject, Flag
ignoreValuesOfParents(consideredValues, ignoredRegions, region);
consideredValues.put(region, value);
-
- if (value == State.DENY) {
- // Since DENY overrides all other values, there
- // is no need to consider any further regions
- break;
- }
}
}
@@ -411,7 +399,11 @@ public V getEffectiveFlag(final ProtectedRegion region, Flag flag, @Nulla
ProtectedRegion current = region;
+ List seen = new ArrayList();
+
while (current != null) {
+ seen.add(current);
+
V value = current.getFlag(flag);
if (value != null) {
@@ -427,7 +419,7 @@ public V getEffectiveFlag(final ProtectedRegion region, Flag flag, @Nulla
use = false;
} else if (subject == null) {
use = group.contains(Association.NON_MEMBER);
- } else if (!group.contains(subject.getAssociation(region))) {
+ } else if (!group.contains(subject.getAssociation(seen))) {
use = false;
}
}
diff --git a/src/main/java/com/sk89q/worldguard/protection/association/ConstantAssociation.java b/src/main/java/com/sk89q/worldguard/protection/association/ConstantAssociation.java
index 95e8d5e9..0f5f3a10 100644
--- a/src/main/java/com/sk89q/worldguard/protection/association/ConstantAssociation.java
+++ b/src/main/java/com/sk89q/worldguard/protection/association/ConstantAssociation.java
@@ -22,6 +22,8 @@
import com.sk89q.worldguard.domains.Association;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
+import java.util.List;
+
class ConstantAssociation implements RegionAssociable {
private final Association association;
@@ -31,7 +33,7 @@ class ConstantAssociation implements RegionAssociable {
}
@Override
- public Association getAssociation(ProtectedRegion region) {
+ public Association getAssociation(List regions) {
return association;
}
diff --git a/src/main/java/com/sk89q/worldguard/protection/association/RegionAssociable.java b/src/main/java/com/sk89q/worldguard/protection/association/RegionAssociable.java
index 07e8c3f4..95b9c9f3 100644
--- a/src/main/java/com/sk89q/worldguard/protection/association/RegionAssociable.java
+++ b/src/main/java/com/sk89q/worldguard/protection/association/RegionAssociable.java
@@ -22,17 +22,19 @@
import com.sk89q.worldguard.domains.Association;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
+import java.util.List;
+
/**
* An object that can have membership in a region.
*/
public interface RegionAssociable {
/**
- * Get the most specific association level for the input region.
+ * Get the highest association level for the input regions.
*
- * @param region the input region
- * @return the most specific membership level
+ * @param regions a list of regions
+ * @return the highest membership level
*/
- Association getAssociation(ProtectedRegion region);
+ Association getAssociation(List regions);
}
diff --git a/src/main/java/com/sk89q/worldguard/protection/association/RegionOverlapAssociation.java b/src/main/java/com/sk89q/worldguard/protection/association/RegionOverlapAssociation.java
index 7165c9c2..0c7cdef2 100644
--- a/src/main/java/com/sk89q/worldguard/protection/association/RegionOverlapAssociation.java
+++ b/src/main/java/com/sk89q/worldguard/protection/association/RegionOverlapAssociation.java
@@ -22,6 +22,7 @@
import com.sk89q.worldguard.domains.Association;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
+import java.util.List;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -45,12 +46,14 @@ public RegionOverlapAssociation(Set source) {
}
@Override
- public Association getAssociation(ProtectedRegion region) {
- if (source.contains(region)) {
- return Association.OWNER;
- } else {
- return Association.NON_MEMBER;
+ public Association getAssociation(List regions) {
+ for (ProtectedRegion region : regions) {
+ if (source.contains(region)) {
+ return Association.OWNER;
+ }
}
+
+ return Association.NON_MEMBER;
}
}