From 88c91ce3fc9e34a08f85d5250b00f321733c7824 Mon Sep 17 00:00:00 2001 From: JOO200 Date: Sun, 18 Oct 2020 14:07:00 +0200 Subject: [PATCH] Add fallback value to queryMapValue, use Flag$chooseValue --- .../protection/ApplicableRegionSet.java | 22 +++++++++++++++++++ .../protection/FailedLoadRegionSet.java | 8 ++++++- .../protection/FlagValueCalculator.java | 21 +++++++++++++----- .../protection/PermissiveRegionSet.java | 8 ++++++- .../protection/RegionResultSet.java | 8 ++++++- 5 files changed, 58 insertions(+), 9 deletions(-) diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/ApplicableRegionSet.java b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/ApplicableRegionSet.java index 67b10200..845931d0 100644 --- a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/ApplicableRegionSet.java +++ b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/ApplicableRegionSet.java @@ -143,6 +143,28 @@ public interface ApplicableRegionSet extends Iterable { @Nullable V queryMapValue(@Nullable RegionAssociable subject, MapFlag 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. + * + *

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.

+ * + * @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 queryMapValue(@Nullable RegionAssociable subject, MapFlag flag, K key, @Nullable Flag 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, diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/FailedLoadRegionSet.java b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/FailedLoadRegionSet.java index cef3f409..71b99e05 100644 --- a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/FailedLoadRegionSet.java +++ b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/FailedLoadRegionSet.java @@ -70,8 +70,14 @@ public V queryValue(@Nullable RegionAssociable subject, Flag flag) { @Nullable @Override public V queryMapValue(@Nullable RegionAssociable subject, MapFlag flag, K key) { + return queryMapValue(subject, flag, key, null); + } + + @Nullable + @Override + public V queryMapValue(@Nullable RegionAssociable subject, MapFlag flag, K key, @Nullable Flag fallback) { Map defaultVal = flag.getDefault(); - return defaultVal != null ? defaultVal.get(key) : null; + return defaultVal != null ? defaultVal.get(key) : fallback != null ? fallback.getDefault() : null; } @SuppressWarnings("unchecked") diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/FlagValueCalculator.java b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/FlagValueCalculator.java index caabb79e..4f58e9c5 100644 --- a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/FlagValueCalculator.java +++ b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/FlagValueCalculator.java @@ -245,11 +245,12 @@ public V queryValue(@Nullable RegionAssociable subject, Flag flag) { * @return a value, which could be {@code null} */ @Nullable - public V queryMapValue(@Nullable RegionAssociable subject, MapFlag flag, T key) { + public V queryMapValue(@Nullable RegionAssociable subject, MapFlag flag, K key, Flag fallback) { checkNotNull(flag); checkNotNull(key); - V value = null; + Map consideredValues = new HashMap<>(); + Map fallbackValues = new HashMap<>(); int minimumPriority = Integer.MIN_VALUE; Set ignoredParents = new HashSet<>(); @@ -266,23 +267,31 @@ public V queryMapValue(@Nullable RegionAssociable subject, MapFlag if (effectiveValue != null) { minimumPriority = getPriority(region); - value = effectiveValue; + consideredValues.put(region, effectiveValue); + } else { + effectiveValue = getEffectiveFlag(region, fallback, subject); + if (effectiveValue != null) { + minimumPriority = getPriority(region); + fallbackValues.put(region, effectiveValue); + } } addParents(ignoredParents, region); } - return value; + V finalValue = flag.getValueFlag().chooseValue(consideredValues.values()); + if (finalValue == null) return fallback.chooseValue(fallbackValues.values()); + return finalValue; } @Nullable - private V getEffectiveMapValue(ProtectedRegion region, MapFlag mapFlag, T key, RegionAssociable subject) { + private V getEffectiveMapValue(ProtectedRegion region, MapFlag mapFlag, K key, RegionAssociable subject) { List seen = new ArrayList<>(); ProtectedRegion current = region; while (current != null) { seen.add(current); - Map mapValue = current.getFlag(mapFlag); + Map mapValue = current.getFlag(mapFlag); if (mapValue != null && mapValue.containsKey(key)) { boolean use = true; diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/PermissiveRegionSet.java b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/PermissiveRegionSet.java index 0ce29571..bf800e5b 100644 --- a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/PermissiveRegionSet.java +++ b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/PermissiveRegionSet.java @@ -64,8 +64,14 @@ public V queryValue(@Nullable RegionAssociable subject, Flag flag) { @Nullable @Override public V queryMapValue(@Nullable RegionAssociable subject, MapFlag flag, K key) { + return queryMapValue(subject, flag, key, null); + } + + @Nullable + @Override + public V queryMapValue(@Nullable RegionAssociable subject, MapFlag flag, K key, @Nullable Flag fallback) { Map defaultVal = flag.getDefault(); - return defaultVal != null ? defaultVal.get(key) : null; + return defaultVal != null ? defaultVal.get(key) : fallback != null ? fallback.getDefault() : null; } @SuppressWarnings("unchecked") diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/RegionResultSet.java b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/RegionResultSet.java index 967d82cb..7afec721 100644 --- a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/RegionResultSet.java +++ b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/RegionResultSet.java @@ -112,7 +112,13 @@ public Collection queryAllValues(@Nullable RegionAssociable subject, Flag @Override @Nullable public V queryMapValue(@Nullable RegionAssociable subject, MapFlag flag, K key) { - return flagValueCalculator.queryMapValue(subject, flag, key); + return flagValueCalculator.queryMapValue(subject, flag, key, null); + } + + @Override + @Nullable + public V queryMapValue(@Nullable RegionAssociable subject, MapFlag flag, K key, Flag fallback) { + return flagValueCalculator.queryMapValue(subject, flag, key, fallback); } @Override