Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add testBuild API to ARS and clean up flag querying #1996

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,6 @@

package com.sk89q.worldguard.protection;

import static com.sk89q.worldguard.protection.flags.StateFlag.test;

import com.sk89q.worldguard.protection.association.RegionAssociable;
import com.sk89q.worldguard.protection.flags.StateFlag;
import com.sk89q.worldguard.protection.flags.StateFlag.State;

import javax.annotation.Nullable;

public abstract class AbstractRegionSet implements ApplicableRegionSet {

@Override
public boolean testState(@Nullable RegionAssociable subject, StateFlag... flags) {
return test(queryState(subject, flags));
}

@Nullable
@Override
public State queryState(@Nullable RegionAssociable subject, StateFlag... flags) {
State value = null;

for (StateFlag flag : flags) {
value = StateFlag.combine(value, queryValue(subject, flag));
if (value == State.DENY) {
break;
}
}

return value;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,9 @@
package com.sk89q.worldguard.protection;

import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.protection.association.RegionAssociable;
import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.MapFlag;
import com.sk89q.worldguard.protection.flags.RegionGroup;
import com.sk89q.worldguard.protection.flags.StateFlag;
import com.sk89q.worldguard.protection.flags.StateFlag.State;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;

import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Set;

/**
Expand All @@ -41,7 +32,7 @@
* <p>An instance of this can be created using the spatial query methods
* available on {@link RegionManager}.</p>
*/
public interface ApplicableRegionSet extends Iterable<ProtectedRegion> {
public interface ApplicableRegionSet extends FlagQuery, Iterable<ProtectedRegion> {

/**
* Return whether this region set is a virtual set. A virtual set
Expand All @@ -61,127 +52,6 @@ public interface ApplicableRegionSet extends Iterable<ProtectedRegion> {
*/
boolean isVirtual();

/**
* Test whether the (effective) value for a list of state flags equals
* {@code ALLOW}.
*
* <p>{@code subject} can be non-null to satisfy region group requirements,
* otherwise it will be assumed that the caller that is not a member of any
* regions. (Flags on a region can be changed so that they only apply
* to certain users.) The subject argument is required if the
* {@link Flags#BUILD} flag is in the list of flags.</p>
*
* @param subject an optional subject, which would be used to determine the region groups that apply
* @param flags a list of flags to check
* @return true if the result was {@code ALLOW}
* @see #queryState(RegionAssociable, StateFlag...)
*/
boolean testState(@Nullable RegionAssociable subject, StateFlag... flags);

/**
* Get the (effective) value for a list of state flags. The rules of
* states is observed here; that is, {@code DENY} overrides {@code ALLOW},
* and {@code ALLOW} overrides {@code NONE}. One flag may override another.
*
* <p>{@code subject} can be non-null to satisfy region group requirements,
* otherwise it will be assumed that the caller that is not a member of any
* regions. (Flags on a region can be changed so that they only apply
* to certain users.) The subject argument is required if the
* {@link Flags#BUILD} flag is in the list of flags.</p>
*
* @param subject an optional subject, which would be used to determine the region groups that apply
* @param flags a list of flags to check
* @return a state
*/
@Nullable
State queryState(@Nullable RegionAssociable subject, StateFlag... flags);

/**
* Get the effective value for a flag. If there are multiple values
* (for example, multiple overlapping regions with
* the same priority may have the same flag set), then the selected
* (or "winning") value will depend on the flag type.
*
* <p>Only some flag types actually have a strategy for picking the
* "best value." For most types, the actual value that is chosen to be
* returned is undefined (it could be any value). As of writing, the only
* type of flag that actually has a strategy for picking a value is the
* {@link StateFlag}.</p>
*
* <p>{@code subject} can be non-null to satisfy region group requirements,
* otherwise it will be assumed that the caller that is not a member of any
* regions. (Flags on a region can be changed so that they only apply
* to certain users.) The subject argument is required if the
* {@link Flags#BUILD} flag is the flag being queried.</p>
*
* @param subject an optional subject, which would be used to determine the region group to apply
* @param flag the flag
* @return a value, which could be {@code null}
*/
@Nullable
<V> V queryValue(@Nullable RegionAssociable subject, Flag<V> flag);

/**
* Get the effective value for a key in a {@link MapFlag}. If there are multiple values
* (for example, if there are multiple regions with the same priority
* but with different farewell messages set, there would be multiple
* completing values), then the selected (or "winning") value will be undefined.
*
* <p>A subject can be provided that is used to determine whether the value
* of a flag on a particular region should be used. For example, if a
* flag's region group is set to {@link RegionGroup#MEMBERS} and the given
* subject is not a member, then the region would be skipped when
* querying that flag. If {@code null} is provided for the subject, then
* only flags that use {@link RegionGroup#ALL},
* {@link RegionGroup#NON_MEMBERS}, etc. will apply.</p>
*
* @param subject an optional subject, which would be used to determine the region group to apply
* @param flag the flag of type {@link MapFlag}
* @param key the key for the map flag
* @return a value, which could be {@code null}
*/
@Nullable
<V, K> V queryMapValue(@Nullable RegionAssociable subject, MapFlag<K, V> flag, K key);

/**
* Get the effective value for a key in a {@link MapFlag}. If there are multiple values
* (for example, if there are multiple regions with the same priority
* but with different farewell messages set, there would be multiple
* completing values), then the selected (or "winning") value will be undefined.
*
* <p>A subject can be provided that is used to determine whether the value
* of a flag on a particular region should be used. For example, if a
* flag's region group is set to {@link RegionGroup#MEMBERS} and the given
* subject is not a member, then the region would be skipped when
* querying that flag. If {@code null} is provided for the subject, then
* only flags that use {@link RegionGroup#ALL},
* {@link RegionGroup#NON_MEMBERS}, etc. will apply.</p>
*
* @param subject an optional subject, which would be used to determine the region group to apply
* @param flag the flag of type {@link MapFlag}
* @param key the key for the map flag
* @return a value, which could be {@code null}
*/
@Nullable
<V, K> V queryMapValue(@Nullable RegionAssociable subject, MapFlag<K, V> flag, K key, @Nullable Flag<V> fallback);

/**
* Get the effective values for a flag, returning a collection of all
* values. It is up to the caller to determine which value, if any,
* from the collection will be used.
*
* <p>{@code subject} can be non-null to satisfy region group requirements,
* otherwise it will be assumed that the caller that is not a member of any
* regions. (Flags on a region can be changed so that they only apply
* to certain users.) The subject argument is required if the
* {@link Flags#BUILD} flag is the flag being queried.</p>
*
* @param subject an optional subject, which would be used to determine the region group to apply
* @param flag the flag
* @return a collection of values
*/
<V> Collection<V> queryAllValues(@Nullable RegionAssociable subject, Flag<V> flag);

/**
* Test whether a player is an owner of all regions in this set.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.sk89q.worldguard.protection;

import com.google.common.collect.ImmutableList;
import com.sk89q.worldguard.protection.association.RegionAssociable;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.MapFlag;

import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Map;

/**
* Default implementation of {@link FlagQuery}, returning flag default values.
*/
public interface DefaultFlagQuery extends FlagQuery {

@Override
@Nullable
default <V, K> V queryMapValue(@Nullable RegionAssociable subject, MapFlag<K, V> flag, K key, @Nullable Flag<V> fallback) {
Map<K, V> defaultVal = flag.getDefault();
return defaultVal != null ? defaultVal.get(key) : fallback != null ? fallback.getDefault() : null;
}

@SuppressWarnings("unchecked")
@Override
default <V> Collection<V> queryAllValues(@Nullable RegionAssociable subject, Flag<V> flag, boolean acceptOne) {
V fallback = flag.getDefault();
return fallback != null ? ImmutableList.of(fallback) : (Collection<V>) ImmutableList.of();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,20 @@
import com.sk89q.worldguard.protection.association.RegionAssociable;
import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.MapFlag;
import com.sk89q.worldguard.protection.flags.StateFlag.State;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;

import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
* A region set that is to be used when region data has failed. Operations
* are blocked.
*/
public class FailedLoadRegionSet extends AbstractRegionSet {
public class FailedLoadRegionSet extends AbstractRegionSet implements DefaultFlagQuery {

private static final FailedLoadRegionSet INSTANCE = new FailedLoadRegionSet();

Expand All @@ -56,40 +54,14 @@ public boolean isVirtual() {
}

@SuppressWarnings("unchecked")
@Nullable
@Override
public <V> V queryValue(@Nullable RegionAssociable subject, Flag<V> flag) {
if (flag == Flags.BUILD) {
return (V) State.DENY;
} else if (flag == Flags.DENY_MESSAGE) {
return (V) denyMessage;
}
return flag.getDefault();
}

@Nullable
@Override
public <V, K> V queryMapValue(@Nullable RegionAssociable subject, MapFlag<K, V> flag, K key) {
return queryMapValue(subject, flag, key, null);
}

@Nullable
@Override
public <V, K> V queryMapValue(@Nullable RegionAssociable subject, MapFlag<K, V> flag, K key, @Nullable Flag<V> fallback) {
Map<K, V> defaultVal = flag.getDefault();
return defaultVal != null ? defaultVal.get(key) : fallback != null ? fallback.getDefault() : null;
}

@SuppressWarnings("unchecked")
@Override
public <V> Collection<V> queryAllValues(@Nullable RegionAssociable subject, Flag<V> flag) {
public <V> Collection<V> queryAllValues(@Nullable RegionAssociable subject, Flag<V> flag, boolean acceptOne) {
if (flag == Flags.BUILD) {
return (Collection<V>) ImmutableList.of(State.DENY);
} else if (flag == Flags.DENY_MESSAGE) {
return (Collection<V>) denyMessageCollection;
}
V fallback = flag.getDefault();
return fallback != null ? ImmutableList.of(fallback) : (Collection<V>) ImmutableList.of();
return DefaultFlagQuery.super.queryAllValues(subject, flag, acceptOne);
}

@Override
Expand Down
Loading