WorldGuard/worldguard-core/src/main/java/com/sk89q/worldguard/protection/RegionResultSet.java
stonar96 4644268214
Fix member inheritance for non-player associables (#1804)
* Add options to query region sets unsorted and without parents

* Fix member inheritance for non-player associables

* Add member inheritance for non-player associables

* Rename Option to QueryOption, remove functional definitions, bit of cleanup.

Co-authored-by: wizjany <wizjany@gmail.com>
2021-08-08 22:58:09 -04:00

187 lines
6.0 KiB
Java

/*
* 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.ImmutableSet;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.protection.association.RegionAssociable;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.MapFlag;
import com.sk89q.worldguard.protection.flags.StateFlag;
import com.sk89q.worldguard.protection.flags.StateFlag.State;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.protection.util.NormativeOrders;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* An implementation that calculates flags using a list of regions.
*/
public class RegionResultSet extends AbstractRegionSet {
private final List<ProtectedRegion> applicable;
private final FlagValueCalculator flagValueCalculator;
@Nullable
private Set<ProtectedRegion> regionSet;
/**
* Create a new region result set.
*
* <p>The given list must not contain duplicates or the behavior of
* this instance will be undefined.</p>
*
* @param applicable the regions contained in this set
* @param globalRegion the global region, set aside for special handling.
*/
public RegionResultSet(List<ProtectedRegion> applicable, @Nullable ProtectedRegion globalRegion) {
this(applicable, globalRegion, false);
}
/**
* Create a new region result set.
*
* @param applicable the regions contained in this set
* @param globalRegion the global region, set aside for special handling.
*/
public RegionResultSet(Set<ProtectedRegion> applicable, @Nullable ProtectedRegion globalRegion) {
this(NormativeOrders.fromSet(applicable), globalRegion, true);
this.regionSet = ImmutableSet.copyOf(applicable);
}
/**
* Create a new region result set.
*
* <p>The list of regions may be first sorted with
* {@link NormativeOrders}. If that is the case, {@code sorted} should be
* {@code true}. Otherwise, the list will be sorted in-place.</p>
*
* @param applicable the regions contained in this set
* @param globalRegion the global region, set aside for special handling.
* @param sorted true if the list is already sorted with {@link NormativeOrders}
*/
public RegionResultSet(List<ProtectedRegion> applicable, @Nullable ProtectedRegion globalRegion, boolean sorted) {
checkNotNull(applicable);
if (!sorted) {
NormativeOrders.sort(applicable);
}
this.applicable = Collections.unmodifiableList(applicable);
this.flagValueCalculator = new FlagValueCalculator(applicable, globalRegion);
}
@Override
public boolean isVirtual() {
return false;
}
@Override
@Nullable
public State queryState(@Nullable RegionAssociable subject, StateFlag... flags) {
return flagValueCalculator.queryState(subject, flags);
}
@Override
@Nullable
public <V> V queryValue(@Nullable RegionAssociable subject, Flag<V> flag) {
return flagValueCalculator.queryValue(subject, flag);
}
@Override
public <V> Collection<V> queryAllValues(@Nullable RegionAssociable subject, Flag<V> flag) {
return flagValueCalculator.queryAllValues(subject, flag);
}
@Override
@Nullable
public <V, K> V queryMapValue(@Nullable RegionAssociable subject, MapFlag<K, V> flag, K key) {
return flagValueCalculator.queryMapValue(subject, flag, key, null);
}
@Override
@Nullable
public <V, K> V queryMapValue(@Nullable RegionAssociable subject, MapFlag<K, V> flag, K key, Flag<V> fallback) {
return flagValueCalculator.queryMapValue(subject, flag, key, fallback);
}
@Override
public boolean isOwnerOfAll(LocalPlayer player) {
checkNotNull(player);
for (ProtectedRegion region : applicable) {
if (!region.isOwner(player)) {
return false;
}
}
return true;
}
@Override
public boolean isMemberOfAll(LocalPlayer player) {
checkNotNull(player);
for (ProtectedRegion region : applicable) {
if (!region.isMember(player)) {
return false;
}
}
return true;
}
@Override
public int size() {
return applicable.size();
}
@Override
public Set<ProtectedRegion> getRegions() {
if (regionSet != null) {
return regionSet;
}
regionSet = ImmutableSet.copyOf(applicable);
return regionSet;
}
@Override
public Iterator<ProtectedRegion> iterator() {
return applicable.iterator();
}
/**
* Create a new instance using a list of regions that is known to
* already be sorted by priority descending.
*
* @param regions a list of regions
* @param globalRegion a global region
* @return an instance
*/
public static RegionResultSet fromSortedList(List<ProtectedRegion> regions, @Nullable ProtectedRegion globalRegion) {
return new RegionResultSet(regions, globalRegion, true);
}
}