Make the state flag test use a Predicate for membership testing.

This commit is contained in:
sk89q 2014-08-15 14:16:05 -07:00
parent c0d4ba5c6c
commit d07e81288a

View File

@ -19,13 +19,14 @@
package com.sk89q.worldguard.protection; package com.sk89q.worldguard.protection;
import com.google.common.base.Predicate;
import com.sk89q.worldguard.LocalPlayer; import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.protection.flags.DefaultFlag; import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.flags.Flag; import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.RegionGroup; import com.sk89q.worldguard.protection.flags.RegionGroup;
import com.sk89q.worldguard.protection.flags.RegionGroupFlag; import com.sk89q.worldguard.protection.flags.RegionGroupFlag;
import com.sk89q.worldguard.protection.flags.StateFlag; import com.sk89q.worldguard.protection.flags.StateFlag;
import com.sk89q.worldguard.protection.flags.StateFlag.State; import com.sk89q.worldguard.protection.flags.StateFlag.*;
import com.sk89q.worldguard.protection.managers.RegionManager; import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedRegion; import com.sk89q.worldguard.protection.regions.ProtectedRegion;
@ -93,7 +94,7 @@ public ApplicableRegionSet(SortedSet<ProtectedRegion> applicable, @Nullable Prot
*/ */
public boolean canBuild(LocalPlayer player) { public boolean canBuild(LocalPlayer player) {
checkNotNull(player); checkNotNull(player);
return test(calculateState(DefaultFlag.BUILD, player, null)); return test(calculateState(DefaultFlag.BUILD, new RegionMemberTest(player), null));
} }
/** /**
@ -184,13 +185,24 @@ public boolean isMemberOfAll(LocalPlayer player) {
* value of a flag {@link StateFlag#getDefault()}. * value of a flag {@link StateFlag#getDefault()}.
* *
* @param flag the flag to check * @param flag the flag to check
* @param player the player, or null to not check owners and members * @param membershipTest null to perform a "wilderness check" or a predicate
* returns true if a the subject is a member of the
* region passed
* @param groupPlayer a player to use for the group flag check * @param groupPlayer a player to use for the group flag check
* @return the allow/deny state for the flag * @return the allow/deny state for the flag
*/ */
private State calculateState(StateFlag flag, @Nullable LocalPlayer player, @Nullable LocalPlayer groupPlayer) { private State calculateState(StateFlag flag, @Nullable Predicate<ProtectedRegion> membershipTest, @Nullable LocalPlayer groupPlayer) {
checkNotNull(flag); checkNotNull(flag);
// This method works in two modes:
//
// 1) Membership mode (if membershipTest != null):
// a) Regions in this set -> Check membership + Check region flags
// a) No regions -> Use global region + default value
// 1) Flag mode:
// a) Regions in this set -> Use global region + default value
// a) No regions -> Use global region + default value
int minimumPriority = Integer.MIN_VALUE; int minimumPriority = Integer.MIN_VALUE;
boolean regionsThatCountExistHere = false; // We can't do a application.isEmpty() because boolean regionsThatCountExistHere = false; // We can't do a application.isEmpty() because
// PASSTHROUGH regions have to be skipped // PASSTHROUGH regions have to be skipped
@ -237,7 +249,7 @@ private State calculateState(StateFlag flag, @Nullable LocalPlayer player, @Null
// If PASSTHROUGH is set and we are checking to see if a player // If PASSTHROUGH is set and we are checking to see if a player
// is a member, then skip this region // is a member, then skip this region
if (player != null && getStateFlagIncludingParents(region, DefaultFlag.PASSTHROUGH) == State.ALLOW) { if (membershipTest != null && getStateFlagIncludingParents(region, DefaultFlag.PASSTHROUGH) == State.ALLOW) {
continue; continue;
} }
@ -269,11 +281,11 @@ private State calculateState(StateFlag flag, @Nullable LocalPlayer player, @Null
minimumPriority = region.getPriority(); minimumPriority = region.getPriority();
} else { } else {
if (player != null) { if (membershipTest != null) {
minimumPriority = region.getPriority(); minimumPriority = region.getPriority();
if (!hasCleared.contains(region)) { if (!hasCleared.contains(region)) {
if (!region.isMember(player)) { if (!membershipTest.apply(region)) {
needsClear.add(region); needsClear.add(region);
} else { } else {
// Need to clear all parents // Need to clear all parents
@ -284,13 +296,13 @@ private State calculateState(StateFlag flag, @Nullable LocalPlayer player, @Null
} }
} }
if (player != null) { if (membershipTest != null) {
State fallback; State fallback;
if (regionsThatCountExistHere) { if (regionsThatCountExistHere) {
fallback = allowOrNone(needsClear.isEmpty()); fallback = allowOrNone(needsClear.isEmpty());
} else { } else {
fallback = getDefault(flag, player); fallback = getDefault(flag, membershipTest);
} }
return combine(state, fallback); return combine(state, fallback);
@ -300,7 +312,7 @@ private State calculateState(StateFlag flag, @Nullable LocalPlayer player, @Null
} }
@Nullable @Nullable
private State getDefault(StateFlag flag, @Nullable LocalPlayer player) { private State getDefault(StateFlag flag, @Nullable Predicate<ProtectedRegion> membershipTest) {
boolean allowed = flag.getDefault(); boolean allowed = flag.getDefault();
// Handle defaults // Handle defaults
@ -310,15 +322,15 @@ private State getDefault(StateFlag flag, @Nullable LocalPlayer player) {
// The global region has this flag set // The global region has this flag set
if (globalState != null) { if (globalState != null) {
// Build flag is very special // Build flag is very special
if (player != null && globalRegion.hasMembersOrOwners()) { if (membershipTest != null && globalRegion.hasMembersOrOwners()) {
allowed = globalRegion.isMember(player) && (globalState == State.ALLOW); allowed = membershipTest.apply(globalRegion) && (globalState == State.ALLOW);
} else { } else {
allowed = (globalState == State.ALLOW); allowed = (globalState == State.ALLOW);
} }
} else { } else {
// Build flag is very special // Build flag is very special
if (player != null && globalRegion.hasMembersOrOwners()) { if (membershipTest != null && globalRegion.hasMembersOrOwners()) {
allowed = globalRegion.isMember(player); allowed = membershipTest.apply(globalRegion);
} }
} }
} }
@ -487,4 +499,20 @@ public static ApplicableRegionSet getEmpty() {
return EMPTY; return EMPTY;
} }
/**
* Returns true if a player is a member (or owner) of a region.
*/
private static class RegionMemberTest implements Predicate<ProtectedRegion> {
private final LocalPlayer player;
private RegionMemberTest(LocalPlayer player) {
this.player = checkNotNull(player);
}
@Override
public boolean apply(ProtectedRegion region) {
return region.isMember(player);
}
}
} }