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; } }