MetaCache refactoring

This commit is contained in:
Luck 2022-07-17 11:53:52 +01:00
parent 016f35a6f0
commit bf93077474
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
9 changed files with 257 additions and 89 deletions

View File

@ -29,6 +29,7 @@ import net.luckperms.api.metastacking.MetaStackDefinition;
import net.luckperms.api.node.types.MetaNode; import net.luckperms.api.node.types.MetaNode;
import net.luckperms.api.node.types.PrefixNode; import net.luckperms.api.node.types.PrefixNode;
import net.luckperms.api.node.types.SuffixNode; import net.luckperms.api.node.types.SuffixNode;
import net.luckperms.api.node.types.WeightNode;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
@ -177,6 +178,30 @@ public interface CachedMetaData extends CachedData {
return querySuffix().result(); return querySuffix().result();
} }
/**
* Query for a weight.
*
* <p>This method will always return a {@link Result}, and the
* {@link Result#result() inner result} {@link Integer} will never be null.
* A value of {@code 0} is equivalent to null.</p>
*
* @return a result containing the weight
* @since 5.5
*/
@NonNull Result<Integer, WeightNode> queryWeight();
/**
* Gets the weight.
*
* <p>If the there is no defined weight, {@code 0} is returned.</p>
*
* @return the weight
* @since 5.5
*/
default int getWeight() {
return queryWeight().result();
}
/** /**
* Gets a map of all accumulated {@link MetaNode meta}. * Gets a map of all accumulated {@link MetaNode meta}.
* *

View File

@ -0,0 +1,125 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.cacheddata.result;
import net.luckperms.api.cacheddata.Result;
import net.luckperms.api.node.Node;
import net.luckperms.api.node.types.WeightNode;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Represents the result of an integer meta lookup
*
* @param <N> the node type
*/
public final class IntegerResult<N extends Node> implements Result<Integer, N> {
/** The result */
private final int result;
/** The node that caused the result */
private final N node;
/** A reference to another result that this one overrides */
private IntegerResult<N> overriddenResult;
public IntegerResult(int result, N node, IntegerResult<N> overriddenResult) {
this.result = result;
this.node = node;
this.overriddenResult = overriddenResult;
}
@Override
@Deprecated // use intResult()
public @NonNull Integer result() {
return this.result;
}
public int intResult() {
return this.result;
}
public StringResult<N> asStringResult() {
if (isNull()) {
return StringResult.nullResult();
} else {
StringResult<N> result = StringResult.of(Integer.toString(this.result), this.node);
if (this.overriddenResult != null) {
result.setOverriddenResult(this.overriddenResult.asStringResult());
}
return result;
}
}
@Override
public @Nullable N node() {
return this.node;
}
public @Nullable IntegerResult<N> overriddenResult() {
return this.overriddenResult;
}
public void setOverriddenResult(IntegerResult<N> overriddenResult) {
this.overriddenResult = overriddenResult;
}
public boolean isNull() {
return this == NULL_RESULT;
}
public IntegerResult<N> copy() {
return new IntegerResult<>(this.result, this.node, this.overriddenResult);
}
@Override
public String toString() {
return "IntegerResult(" +
"result=" + this.result + ", " +
"node=" + this.node + ", " +
"overriddenResult=" + this.overriddenResult + ')';
}
private static final IntegerResult<?> NULL_RESULT = new IntegerResult<>(0, null, null);
@SuppressWarnings("unchecked")
public static <N extends Node> IntegerResult<N> nullResult() {
return (IntegerResult<N>) NULL_RESULT;
}
public static <N extends Node> IntegerResult<N> of(int result) {
return new IntegerResult<>(result, null, null);
}
public static <N extends Node> IntegerResult<N> of(int result, N node) {
return new IntegerResult<>(result, node, null);
}
public static IntegerResult<WeightNode> of(WeightNode node) {
return new IntegerResult<>(node.getWeight(), node, null);
}
}

View File

@ -28,6 +28,7 @@ package me.lucko.luckperms.common.cacheddata.type;
import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap; import com.google.common.collect.ListMultimap;
import me.lucko.luckperms.common.cacheddata.result.IntegerResult;
import me.lucko.luckperms.common.cacheddata.result.StringResult; import me.lucko.luckperms.common.cacheddata.result.StringResult;
import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.node.types.Weight; import me.lucko.luckperms.common.node.types.Weight;
@ -40,6 +41,7 @@ import net.luckperms.api.node.types.ChatMetaNode;
import net.luckperms.api.node.types.MetaNode; import net.luckperms.api.node.types.MetaNode;
import net.luckperms.api.node.types.PrefixNode; import net.luckperms.api.node.types.PrefixNode;
import net.luckperms.api.node.types.SuffixNode; import net.luckperms.api.node.types.SuffixNode;
import net.luckperms.api.node.types.WeightNode;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashSet; import java.util.HashSet;
@ -80,7 +82,7 @@ public class MetaAccumulator {
private final ListMultimap<String, StringResult<MetaNode>> meta; private final ListMultimap<String, StringResult<MetaNode>> meta;
private final SortedMap<Integer, StringResult<PrefixNode>> prefixes; private final SortedMap<Integer, StringResult<PrefixNode>> prefixes;
private final SortedMap<Integer, StringResult<SuffixNode>> suffixes; private final SortedMap<Integer, StringResult<SuffixNode>> suffixes;
private int weight = 0; private IntegerResult<WeightNode> weight;
private String primaryGroup; private String primaryGroup;
private Set<String> seenNodeKeys = new HashSet<>(); private Set<String> seenNodeKeys = new HashSet<>();
@ -96,6 +98,7 @@ public class MetaAccumulator {
this.meta = ArrayListMultimap.create(); this.meta = ArrayListMultimap.create();
this.prefixes = new TreeMap<>(Comparator.reverseOrder()); this.prefixes = new TreeMap<>(Comparator.reverseOrder());
this.suffixes = new TreeMap<>(Comparator.reverseOrder()); this.suffixes = new TreeMap<>(Comparator.reverseOrder());
this.weight = IntegerResult.nullResult();
this.prefixDefinition = prefixDefinition; this.prefixDefinition = prefixDefinition;
this.suffixDefinition = suffixDefinition; this.suffixDefinition = suffixDefinition;
this.prefixAccumulator = new MetaStackAccumulator<>(this.prefixDefinition, ChatMetaType.PREFIX); this.prefixAccumulator = new MetaStackAccumulator<>(this.prefixDefinition, ChatMetaType.PREFIX);
@ -120,8 +123,8 @@ public class MetaAccumulator {
} }
// perform final changes // perform final changes
if (!this.meta.containsKey(Weight.NODE_KEY) && this.weight != 0) { if (!this.meta.containsKey(Weight.NODE_KEY) && !this.weight.isNull()) {
this.meta.put(Weight.NODE_KEY, StringResult.of(String.valueOf(this.weight))); this.meta.put(Weight.NODE_KEY, StringResult.of(String.valueOf(this.weight.intResult())));
} }
if (this.primaryGroup != null && !this.meta.containsKey("primarygroup")) { if (this.primaryGroup != null && !this.meta.containsKey("primarygroup")) {
this.meta.put("primarygroup", StringResult.of(this.primaryGroup)); this.meta.put("primarygroup", StringResult.of(this.primaryGroup));
@ -164,9 +167,11 @@ public class MetaAccumulator {
} }
} }
public void accumulateWeight(int weight) { public void accumulateWeight(IntegerResult<WeightNode> weight) {
ensureState(State.ACCUMULATING); ensureState(State.ACCUMULATING);
this.weight = Math.max(this.weight, weight); if (this.weight.isNull() || weight.intResult() > this.weight.intResult()) {
this.weight = weight;
}
} }
public void setPrimaryGroup(String primaryGroup) { public void setPrimaryGroup(String primaryGroup) {
@ -196,7 +201,7 @@ public class MetaAccumulator {
return this.suffixes; return this.suffixes;
} }
public int getWeight() { public IntegerResult<WeightNode> getWeight() {
ensureState(State.COMPLETE); ensureState(State.COMPLETE);
return this.weight; return this.weight;
} }

View File

@ -34,8 +34,11 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Multimaps; import com.google.common.collect.Multimaps;
import me.lucko.luckperms.common.cacheddata.UsageTracked; import me.lucko.luckperms.common.cacheddata.UsageTracked;
import me.lucko.luckperms.common.cacheddata.result.IntegerResult;
import me.lucko.luckperms.common.cacheddata.result.StringResult; import me.lucko.luckperms.common.cacheddata.result.StringResult;
import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.node.types.Prefix;
import me.lucko.luckperms.common.node.types.Suffix;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.verbose.event.CheckOrigin; import me.lucko.luckperms.common.verbose.event.CheckOrigin;
@ -45,6 +48,7 @@ import net.luckperms.api.metastacking.MetaStackDefinition;
import net.luckperms.api.node.types.MetaNode; import net.luckperms.api.node.types.MetaNode;
import net.luckperms.api.node.types.PrefixNode; import net.luckperms.api.node.types.PrefixNode;
import net.luckperms.api.node.types.SuffixNode; import net.luckperms.api.node.types.SuffixNode;
import net.luckperms.api.node.types.WeightNode;
import net.luckperms.api.query.QueryOptions; import net.luckperms.api.query.QueryOptions;
import net.luckperms.api.query.meta.MetaValueSelector; import net.luckperms.api.query.meta.MetaValueSelector;
@ -72,7 +76,7 @@ public class MetaCache extends UsageTracked implements CachedMetaData {
private final Map<String, StringResult<MetaNode>> flattenedMeta; private final Map<String, StringResult<MetaNode>> flattenedMeta;
private final SortedMap<Integer, StringResult<PrefixNode>> prefixes; private final SortedMap<Integer, StringResult<PrefixNode>> prefixes;
private final SortedMap<Integer, StringResult<SuffixNode>> suffixes; private final SortedMap<Integer, StringResult<SuffixNode>> suffixes;
private final int weight; private final IntegerResult<WeightNode> weight;
private final String primaryGroup; private final String primaryGroup;
private final MetaStackDefinition prefixDefinition; private final MetaStackDefinition prefixDefinition;
private final MetaStackDefinition suffixDefinition; private final MetaStackDefinition suffixDefinition;
@ -119,50 +123,58 @@ public class MetaCache extends UsageTracked implements CachedMetaData {
return this.flattenedMeta.getOrDefault(key.toLowerCase(Locale.ROOT), StringResult.nullResult()); return this.flattenedMeta.getOrDefault(key.toLowerCase(Locale.ROOT), StringResult.nullResult());
} }
public @NonNull StringResult<PrefixNode> getPrefix(CheckOrigin origin) {
return this.prefix;
}
public @NonNull StringResult<SuffixNode> getSuffix(CheckOrigin origin) {
return this.suffix;
}
public @NonNull IntegerResult<WeightNode> getWeight(CheckOrigin origin) {
return this.weight;
}
public @NonNull Map<String, List<StringResult<MetaNode>>> getMetaResults(CheckOrigin origin) {
return this.meta;
}
public @Nullable String getPrimaryGroup(CheckOrigin origin) {
return this.primaryGroup;
}
public final Map<String, List<String>> getMeta(CheckOrigin origin) {
return Maps.transformValues(getMetaResults(origin), list -> Lists.transform(list, StringResult::result));
}
public @Nullable String getMetaOrChatMetaValue(String key, CheckOrigin origin) {
if (key.equals(Prefix.NODE_KEY)) {
return getPrefix(origin).result();
} else if (key.equals(Suffix.NODE_KEY)) {
return getSuffix(origin).result();
} else {
return getMetaValue(key, origin).result();
}
}
@Override @Override
public final @NonNull Result<String, MetaNode> queryMetaValue(@NonNull String key) { public final @NonNull Result<String, MetaNode> queryMetaValue(@NonNull String key) {
return getMetaValue(key, CheckOrigin.LUCKPERMS_API); return getMetaValue(key, CheckOrigin.LUCKPERMS_API);
} }
@Override
public final @Nullable String getMetaValue(@NonNull String key) {
return getMetaValue(key, CheckOrigin.LUCKPERMS_API).result();
}
public @NonNull StringResult<PrefixNode> getPrefix(CheckOrigin origin) {
return this.prefix;
}
@Override @Override
public final @NonNull Result<String, PrefixNode> queryPrefix() { public final @NonNull Result<String, PrefixNode> queryPrefix() {
return getPrefix(CheckOrigin.LUCKPERMS_API); return getPrefix(CheckOrigin.LUCKPERMS_API);
} }
@Override
public final @Nullable String getPrefix() {
return getPrefix(CheckOrigin.LUCKPERMS_API).result();
}
public @NonNull StringResult<SuffixNode> getSuffix(CheckOrigin origin) {
return this.suffix;
}
@Override @Override
public final @NonNull Result<String, SuffixNode> querySuffix() { public final @NonNull Result<String, SuffixNode> querySuffix() {
return getSuffix(CheckOrigin.LUCKPERMS_API); return getSuffix(CheckOrigin.LUCKPERMS_API);
} }
@Override @Override
public final @Nullable String getSuffix() { public @NonNull Result<Integer, WeightNode> queryWeight() {
return getSuffix(CheckOrigin.LUCKPERMS_API).result(); return getWeight(CheckOrigin.LUCKPERMS_API);
}
protected Map<String, List<StringResult<MetaNode>>> getMetaResults(CheckOrigin origin) {
return this.meta;
}
public final Map<String, List<String>> getMeta(CheckOrigin origin) {
return Maps.transformValues(getMetaResults(origin), list -> Lists.transform(list, StringResult::result));
} }
@Override @Override
@ -170,6 +182,11 @@ public class MetaCache extends UsageTracked implements CachedMetaData {
return getMeta(CheckOrigin.LUCKPERMS_API); return getMeta(CheckOrigin.LUCKPERMS_API);
} }
@Override
public final @Nullable String getPrimaryGroup() {
return getPrimaryGroup(CheckOrigin.LUCKPERMS_API);
}
@Override @Override
public @NonNull SortedMap<Integer, String> getPrefixes() { public @NonNull SortedMap<Integer, String> getPrefixes() {
return Maps.transformValues(this.prefixes, StringResult::result); return Maps.transformValues(this.prefixes, StringResult::result);
@ -180,24 +197,6 @@ public class MetaCache extends UsageTracked implements CachedMetaData {
return Maps.transformValues(this.suffixes, StringResult::result); return Maps.transformValues(this.suffixes, StringResult::result);
} }
public int getWeight(CheckOrigin origin) {
return this.weight;
}
//@Override - not actually exposed in the API atm
public final int getWeight() {
return getWeight(CheckOrigin.LUCKPERMS_API);
}
public @Nullable String getPrimaryGroup(CheckOrigin origin) {
return this.primaryGroup;
}
@Override
public final @Nullable String getPrimaryGroup() {
return getPrimaryGroup(CheckOrigin.LUCKPERMS_API);
}
@Override @Override
public @NonNull MetaStackDefinition getPrefixStackDefinition() { public @NonNull MetaStackDefinition getPrefixStackDefinition() {
return this.prefixDefinition; return this.prefixDefinition;

View File

@ -28,6 +28,7 @@ package me.lucko.luckperms.common.cacheddata.type;
import com.google.common.collect.ForwardingMap; import com.google.common.collect.ForwardingMap;
import me.lucko.luckperms.common.cacheddata.CacheMetadata; import me.lucko.luckperms.common.cacheddata.CacheMetadata;
import me.lucko.luckperms.common.cacheddata.result.IntegerResult;
import me.lucko.luckperms.common.cacheddata.result.StringResult; import me.lucko.luckperms.common.cacheddata.result.StringResult;
import me.lucko.luckperms.common.node.types.Prefix; import me.lucko.luckperms.common.node.types.Prefix;
import me.lucko.luckperms.common.node.types.Suffix; import me.lucko.luckperms.common.node.types.Suffix;
@ -38,6 +39,7 @@ import net.luckperms.api.cacheddata.CachedMetaData;
import net.luckperms.api.node.types.MetaNode; import net.luckperms.api.node.types.MetaNode;
import net.luckperms.api.node.types.PrefixNode; import net.luckperms.api.node.types.PrefixNode;
import net.luckperms.api.node.types.SuffixNode; import net.luckperms.api.node.types.SuffixNode;
import net.luckperms.api.node.types.WeightNode;
import net.luckperms.api.query.QueryOptions; import net.luckperms.api.query.QueryOptions;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
@ -65,38 +67,35 @@ public class MonitoredMetaCache extends MetaCache implements CachedMetaData {
} }
@Override @Override
@NonNull public @NonNull StringResult<MetaNode> getMetaValue(String key, CheckOrigin origin) {
public StringResult<MetaNode> getMetaValue(String key, CheckOrigin origin) {
StringResult<MetaNode> value = super.getMetaValue(key, origin); StringResult<MetaNode> value = super.getMetaValue(key, origin);
this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), key, value); this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), key, value);
return value; return value;
} }
@Override @Override
@NonNull public @NonNull StringResult<PrefixNode> getPrefix(CheckOrigin origin) {
public StringResult<PrefixNode> getPrefix(CheckOrigin origin) {
StringResult<PrefixNode> value = super.getPrefix(origin); StringResult<PrefixNode> value = super.getPrefix(origin);
this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), Prefix.NODE_KEY, value); this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), Prefix.NODE_KEY, value);
return value; return value;
} }
@Override @Override
@NonNull public @NonNull StringResult<SuffixNode> getSuffix(CheckOrigin origin) {
public StringResult<SuffixNode> getSuffix(CheckOrigin origin) {
StringResult<SuffixNode> value = super.getSuffix(origin); StringResult<SuffixNode> value = super.getSuffix(origin);
this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), Suffix.NODE_KEY, value); this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), Suffix.NODE_KEY, value);
return value; return value;
} }
@Override @Override
protected Map<String, List<StringResult<MetaNode>>> getMetaResults(CheckOrigin origin) { public @NonNull Map<String, List<StringResult<MetaNode>>> getMetaResults(CheckOrigin origin) {
return new MonitoredMetaMap(super.getMetaResults(origin), origin); return new MonitoredMetaMap(super.getMetaResults(origin), origin);
} }
@Override @Override
public int getWeight(CheckOrigin origin) { public @NonNull IntegerResult<WeightNode> getWeight(CheckOrigin origin) {
int value = super.getWeight(origin); IntegerResult<WeightNode> value = super.getWeight(origin);
this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), "weight", StringResult.of(String.valueOf(value))); this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), "weight", value.asStringResult());
return value; return value;
} }

View File

@ -28,6 +28,7 @@ package me.lucko.luckperms.common.model;
import me.lucko.luckperms.common.api.implementation.ApiGroup; import me.lucko.luckperms.common.api.implementation.ApiGroup;
import me.lucko.luckperms.common.cache.Cache; import me.lucko.luckperms.common.cache.Cache;
import me.lucko.luckperms.common.cacheddata.GroupCachedDataManager; import me.lucko.luckperms.common.cacheddata.GroupCachedDataManager;
import me.lucko.luckperms.common.cacheddata.result.IntegerResult;
import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.locale.Message; import me.lucko.luckperms.common.locale.Message;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
@ -36,13 +37,13 @@ import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import net.luckperms.api.node.NodeType; import net.luckperms.api.node.NodeType;
import net.luckperms.api.node.types.DisplayNameNode; import net.luckperms.api.node.types.DisplayNameNode;
import net.luckperms.api.node.types.WeightNode;
import net.luckperms.api.query.QueryOptions; import net.luckperms.api.query.QueryOptions;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.Locale; import java.util.Locale;
import java.util.Optional; import java.util.Optional;
import java.util.OptionalInt;
public class Group extends PermissionHolder { public class Group extends PermissionHolder {
private final ApiGroup apiProxy = new ApiGroup(this); private final ApiGroup apiProxy = new ApiGroup(this);
@ -55,7 +56,7 @@ public class Group extends PermissionHolder {
/** /**
* Caches the groups weight * Caches the groups weight
*/ */
private final Cache<OptionalInt> weightCache = new WeightCache(this); private final Cache<IntegerResult<WeightNode>> weightCache = new WeightCache(this);
/** /**
* Caches the groups display name * Caches the groups display name
@ -143,7 +144,7 @@ public class Group extends PermissionHolder {
} }
@Override @Override
public OptionalInt getWeight() { public IntegerResult<WeightNode> getWeightResult() {
return this.weightCache.get(); return this.weightCache.get();
} }

View File

@ -28,6 +28,7 @@ package me.lucko.luckperms.common.model;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import me.lucko.luckperms.common.cacheddata.HolderCachedDataManager; import me.lucko.luckperms.common.cacheddata.HolderCachedDataManager;
import me.lucko.luckperms.common.cacheddata.result.IntegerResult;
import me.lucko.luckperms.common.cacheddata.type.MetaAccumulator; import me.lucko.luckperms.common.cacheddata.type.MetaAccumulator;
import me.lucko.luckperms.common.inheritance.InheritanceComparator; import me.lucko.luckperms.common.inheritance.InheritanceComparator;
import me.lucko.luckperms.common.inheritance.InheritanceGraph; import me.lucko.luckperms.common.inheritance.InheritanceGraph;
@ -49,6 +50,7 @@ import net.luckperms.api.node.Node;
import net.luckperms.api.node.NodeEqualityPredicate; import net.luckperms.api.node.NodeEqualityPredicate;
import net.luckperms.api.node.NodeType; import net.luckperms.api.node.NodeType;
import net.luckperms.api.node.types.InheritanceNode; import net.luckperms.api.node.types.InheritanceNode;
import net.luckperms.api.node.types.WeightNode;
import net.luckperms.api.query.Flag; import net.luckperms.api.query.Flag;
import net.luckperms.api.query.QueryOptions; import net.luckperms.api.query.QueryOptions;
import net.luckperms.api.util.Tristate; import net.luckperms.api.util.Tristate;
@ -400,9 +402,9 @@ public abstract class PermissionHolder {
} }
// accumulate weight // accumulate weight
OptionalInt w = holder.getWeight(); IntegerResult<WeightNode> weight = holder.getWeightResult();
if (w.isPresent()) { if (!weight.isNull()) {
accumulator.accumulateWeight(w.getAsInt()); accumulator.accumulateWeight(weight);
} }
} }
@ -591,8 +593,13 @@ public abstract class PermissionHolder {
return true; return true;
} }
public IntegerResult<WeightNode> getWeightResult() {
return IntegerResult.nullResult();
}
public OptionalInt getWeight() { public OptionalInt getWeight() {
return OptionalInt.empty(); IntegerResult<WeightNode> result = getWeightResult();
return result.isNull() ? OptionalInt.empty() : OptionalInt.of(result.intResult());
} }
private static final class MergedNodeResult implements DataMutateResult.WithMergedNode { private static final class MergedNodeResult implements DataMutateResult.WithMergedNode {

View File

@ -26,6 +26,7 @@
package me.lucko.luckperms.common.model; package me.lucko.luckperms.common.model;
import me.lucko.luckperms.common.cache.Cache; import me.lucko.luckperms.common.cache.Cache;
import me.lucko.luckperms.common.cacheddata.result.IntegerResult;
import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.query.QueryOptionsImpl; import me.lucko.luckperms.common.query.QueryOptionsImpl;
@ -36,12 +37,11 @@ import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.OptionalInt;
/** /**
* Cache instance to supply the weight of a {@link Group}. * Cache instance to supply the weight of a {@link Group}.
*/ */
public class WeightCache extends Cache<OptionalInt> { public class WeightCache extends Cache<IntegerResult<WeightNode>> {
private final Group group; private final Group group;
public WeightCache(Group group) { public WeightCache(Group group) {
@ -49,27 +49,24 @@ public class WeightCache extends Cache<OptionalInt> {
} }
@Override @Override
protected @NonNull OptionalInt supply() { protected @NonNull IntegerResult<WeightNode> supply() {
boolean seen = false; IntegerResult<WeightNode> weight = null;
int weight = 0;
for (WeightNode n : this.group.getOwnNodes(NodeType.WEIGHT, QueryOptionsImpl.DEFAULT_NON_CONTEXTUAL)) { for (WeightNode n : this.group.getOwnNodes(NodeType.WEIGHT, QueryOptionsImpl.DEFAULT_NON_CONTEXTUAL)) {
int value = n.getWeight(); int value = n.getWeight();
if (!seen || value > weight) { if (weight == null || value > weight.intResult()) {
seen = true; weight = IntegerResult.of(n);
weight = value;
} }
} }
if (!seen) { if (weight == null) {
Map<String, Integer> configWeights = this.group.getPlugin().getConfiguration().get(ConfigKeys.GROUP_WEIGHTS); Map<String, Integer> configWeights = this.group.getPlugin().getConfiguration().get(ConfigKeys.GROUP_WEIGHTS);
Integer value = configWeights.get(this.group.getIdentifier().getName().toLowerCase(Locale.ROOT)); Integer value = configWeights.get(this.group.getIdentifier().getName().toLowerCase(Locale.ROOT));
if (value != null) { if (value != null) {
seen = true; weight = IntegerResult.of(value);
weight = value;
} }
} }
return seen ? OptionalInt.of(weight) : OptionalInt.empty(); return weight != null ? weight : IntegerResult.nullResult();
} }
} }

View File

@ -43,6 +43,7 @@ import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.server.permission.handler.IPermissionHandler; import net.minecraftforge.server.permission.handler.IPermissionHandler;
import net.minecraftforge.server.permission.nodes.PermissionDynamicContext; import net.minecraftforge.server.permission.nodes.PermissionDynamicContext;
import net.minecraftforge.server.permission.nodes.PermissionNode; import net.minecraftforge.server.permission.nodes.PermissionNode;
import net.minecraftforge.server.permission.nodes.PermissionType;
import net.minecraftforge.server.permission.nodes.PermissionTypes; import net.minecraftforge.server.permission.nodes.PermissionTypes;
import java.util.Collection; import java.util.Collection;
@ -111,28 +112,37 @@ public class ForgePermissionHandler implements IPermissionHandler {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private static <T> T getPermissionValue(User user, QueryOptions queryOptions, PermissionNode<T> node, PermissionDynamicContext<?>... context) { private static <T> T getPermissionValue(User user, QueryOptions queryOptions, PermissionNode<T> node, PermissionDynamicContext<?>... context) {
queryOptions = appendContextToQueryOptions(queryOptions, context); queryOptions = appendContextToQueryOptions(queryOptions, context);
String key = node.getNodeName();
PermissionType<T> type = node.getType();
if (node.getType() == PermissionTypes.BOOLEAN) { // permission check
if (type == PermissionTypes.BOOLEAN) {
PermissionCache cache = user.getCachedData().getPermissionData(queryOptions); PermissionCache cache = user.getCachedData().getPermissionData(queryOptions);
Tristate value = cache.checkPermission(node.getNodeName(), CheckOrigin.PLATFORM_API_HAS_PERMISSION).result(); Tristate value = cache.checkPermission(key, CheckOrigin.PLATFORM_API_HAS_PERMISSION).result();
if (value != Tristate.UNDEFINED) { if (value != Tristate.UNDEFINED) {
return (T) (Boolean) value.asBoolean(); return (T) (Boolean) value.asBoolean();
} }
} }
if (node.getType() == PermissionTypes.INTEGER) { // meta lookup
if (node.getType() == PermissionTypes.STRING) {
MetaCache cache = user.getCachedData().getMetaData(queryOptions); MetaCache cache = user.getCachedData().getMetaData(queryOptions);
Integer value = cache.getMetaValue(node.getNodeName(), Integer::parseInt).orElse(null); String value = cache.getMetaOrChatMetaValue(node.getNodeName(), CheckOrigin.PLATFORM_API);
if (value != null) { if (value != null) {
return (T) value; return (T) value;
} }
} }
if (node.getType() == PermissionTypes.STRING) { // meta lookup (integer)
if (node.getType() == PermissionTypes.INTEGER) {
MetaCache cache = user.getCachedData().getMetaData(queryOptions); MetaCache cache = user.getCachedData().getMetaData(queryOptions);
String value = cache.getMetaValue(node.getNodeName()); String value = cache.getMetaOrChatMetaValue(node.getNodeName(), CheckOrigin.PLATFORM_API);
if (value != null) { if (value != null) {
return (T) value; try {
return (T) Integer.valueOf(Integer.parseInt(value));
} catch (IllegalArgumentException e) {
// ignore
}
} }
} }