From 6781c1fb519d34da55279eae35a9d00b94d6ce50 Mon Sep 17 00:00:00 2001 From: Luck Date: Sat, 1 Jan 2022 14:38:46 +0000 Subject: [PATCH] Provide API access to cached data result info (#3243) --- .../luckperms/api/cacheddata/CachedData.java | 4 + .../api/cacheddata/CachedDataManager.java | 14 +-- .../api/cacheddata/CachedMetaData.java | 113 ++++++++++++++++-- .../api/cacheddata/CachedPermissionData.java | 27 ++++- .../net/luckperms/api/cacheddata/Result.java | 37 ++++-- .../api/cacheddata/package-info.java | 2 +- .../cacheddata/AbstractCachedDataManager.java | 17 +-- .../cacheddata/result/StringResult.java | 16 +-- .../cacheddata/result/TristateResult.java | 1 - .../cacheddata/type/MetaAccumulator.java | 22 ++-- .../common/cacheddata/type/MetaCache.java | 30 +++-- .../cacheddata/type/MetaStackAccumulator.java | 36 +++--- .../cacheddata/type/MonitoredMetaCache.java | 11 +- .../cacheddata/type/PermissionCache.java | 6 + 14 files changed, 239 insertions(+), 97 deletions(-) diff --git a/api/src/main/java/net/luckperms/api/cacheddata/CachedData.java b/api/src/main/java/net/luckperms/api/cacheddata/CachedData.java index 709ebff30..ce030d14c 100644 --- a/api/src/main/java/net/luckperms/api/cacheddata/CachedData.java +++ b/api/src/main/java/net/luckperms/api/cacheddata/CachedData.java @@ -31,6 +31,10 @@ import org.checkerframework.checker.nullness.qual.NonNull; /** * Holds cached lookup data for a given set of query options. + * + *

All calls will account for inheritance, as well as any default data + * provided by the platform. These calls are heavily cached and are therefore + * fast.

*/ public interface CachedData { diff --git a/api/src/main/java/net/luckperms/api/cacheddata/CachedDataManager.java b/api/src/main/java/net/luckperms/api/cacheddata/CachedDataManager.java index fe52d97a2..e1388b358 100644 --- a/api/src/main/java/net/luckperms/api/cacheddata/CachedDataManager.java +++ b/api/src/main/java/net/luckperms/api/cacheddata/CachedDataManager.java @@ -39,7 +39,7 @@ import java.util.concurrent.CompletableFuture; * Holds cached permission and meta lookup data for a {@link PermissionHolder}. * *

All calls will account for inheritance, as well as any default data - * provided by the platform. This calls are heavily cached and are therefore + * provided by the platform. These calls are heavily cached and are therefore * fast.

*/ public interface CachedDataManager { @@ -81,11 +81,10 @@ public interface CachedDataManager { *

For {@link User}s, the most appropriate query options will be their * {@link ContextManager#getQueryOptions(User) current active query options} if the * corresponding player is online, and otherwise, will fallback to - * {@link ContextManager#getStaticQueryOptions() the current static query options} - * if they are offline.

+ * {@link ContextManager#getStaticQueryOptions() the current static query options}.

* *

For {@link Group}s, the most appropriate query options will always be - * {@link ContextManager#getStaticQueryOptions()} the current static query options.

+ * {@link ContextManager#getStaticQueryOptions() the current static query options}.

* * @return a permission data instance * @since 5.1 @@ -99,11 +98,10 @@ public interface CachedDataManager { *

For {@link User}s, the most appropriate query options will be their * {@link ContextManager#getQueryOptions(User) current active query options} if the * corresponding player is online, and otherwise, will fallback to - * {@link ContextManager#getStaticQueryOptions() the current static query options} - * if they are offline.

+ * {@link ContextManager#getStaticQueryOptions() the current static query options}.

* *

For {@link Group}s, the most appropriate query options will always be - * {@link ContextManager#getStaticQueryOptions()} the current static query options.

+ * {@link ContextManager#getStaticQueryOptions() the current static query options}.

* * @return a meta data instance * @since 5.1 @@ -118,7 +116,7 @@ public interface CachedDataManager { void invalidate(); /** - * Invalidates all of the underlying Permission calculators. + * Invalidates all underlying permission calculators. * *

Can be called to allow for an update in defaults.

*/ diff --git a/api/src/main/java/net/luckperms/api/cacheddata/CachedMetaData.java b/api/src/main/java/net/luckperms/api/cacheddata/CachedMetaData.java index 646fb6f34..467d3c48c 100644 --- a/api/src/main/java/net/luckperms/api/cacheddata/CachedMetaData.java +++ b/api/src/main/java/net/luckperms/api/cacheddata/CachedMetaData.java @@ -26,6 +26,9 @@ package net.luckperms.api.cacheddata; import net.luckperms.api.metastacking.MetaStackDefinition; +import net.luckperms.api.node.types.MetaNode; +import net.luckperms.api.node.types.PrefixNode; +import net.luckperms.api.node.types.SuffixNode; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; @@ -39,16 +42,40 @@ import java.util.function.Function; /** * Holds cached meta lookup data for a specific set of contexts. + * + *

Meta data refers to {@link PrefixNode prefixes}, {@link SuffixNode suffixes} and + * {@link MetaNode meta (options)} held by a permission holder.

+ * + *

All calls will account for inheritance, as well as any default data + * provided by the platform. These calls are heavily cached and are therefore + * fast.

*/ public interface CachedMetaData extends CachedData { + /** + * Query a meta value for the given {@code key}. + * + *

This method will always return a {@link Result}, but the + * {@link Result#result() inner result} {@link String} will be null if a value + * for the given key was not found.

+ * + * @param key the key + * @return a result containing the value + * @since 5.4 + */ + @NonNull Result queryMetaValue(@NonNull String key); + /** * Gets a value for the given meta key. + * + *

If no such meta value exists for the given key, {@code null} is returned.

* * @param key the key * @return the value */ - @Nullable String getMetaValue(@NonNull String key); + default @Nullable String getMetaValue(@NonNull String key) { + return queryMetaValue(key).result(); + } /** * Gets a value for the given meta key, and runs it through the given {@code transformer}. @@ -81,37 +108,97 @@ public interface CachedMetaData extends CachedData { } /** - * Gets the holder's highest priority prefix, or null if the holder has no prefixes + * Query for a prefix. + * + *

This method uses the rules defined by the {@link #getPrefixStackDefinition() prefix stack} + * to produce a {@link String} output.

+ * + *

Assuming the default configuration is used, this will usually be the value of the + * holder's highest priority prefix node.

+ * + *

This method will always return a {@link Result}, but the + * {@link Result#result() inner result} {@link String} will be null if + * a the resultant prefix stack contained no elements.

+ * + * @return a result containing the prefix + * @since 5.4 + */ + @NonNull Result queryPrefix(); + + /** + * Gets the prefix. + * + *

This method uses the rules defined by the {@link #getPrefixStackDefinition() prefix stack} + * to produce a {@link String} output.

+ * + *

Assuming the default configuration is used, this will usually be the value of the + * holder's highest priority prefix node.

+ * + *

If the resultant prefix stack contained no elements, {@code null} is returned.

* * @return a prefix string, or null */ - @Nullable String getPrefix(); + default @Nullable String getPrefix() { + return queryPrefix().result(); + } /** - * Gets the holder's highest priority suffix, or null if the holder has no suffixes + * Query for a suffix. + * + *

This method uses the rules defined by the {@link #getSuffixStackDefinition() suffix stack} + * to produce a {@link String} output.

+ * + *

Assuming the default configuration is used, this will usually be the value of the + * holder's highest priority suffix node.

+ * + *

This method will always return a {@link Result}, but the + * {@link Result#result() inner result} {@link String} will be null if + * a the resultant suffix stack contained no elements.

+ * + * @return a result containing the suffix + * @since 5.4 + */ + @NonNull Result querySuffix(); + + /** + * Gets the suffix. + * + *

This method uses the rules defined by the {@link #getSuffixStackDefinition() suffix stack} + * to produce a {@link String} output.

+ * + *

Assuming the default configuration is used, this will usually be the value of the + * holder's highest priority suffix node.

+ * + *

If the resultant suffix stack contained no elements, {@code null} is returned.

* * @return a suffix string, or null */ - @Nullable String getSuffix(); + default @Nullable String getSuffix() { + return querySuffix().result(); + } /** - * Gets an immutable copy of the meta this holder has. + * Gets a map of all accumulated {@link MetaNode meta}. * - * @return an immutable map of meta + *

Prefer using the {@link #getMetaValue(String)} method for querying values.

+ * + * @return a map of meta */ @NonNull @Unmodifiable Map> getMeta(); /** - * Gets an immutable sorted map of all of the prefixes the holder has, whereby the first - * value is the highest priority prefix. + * Gets a sorted map of all accumulated {@link PrefixNode prefixes}. + * + *

Prefer using the {@link #getPrefix()} method for querying.

* * @return a sorted map of prefixes */ @NonNull @Unmodifiable SortedMap getPrefixes(); /** - * Gets an immutable sorted map of all of the suffixes the holder has, whereby the first - * value is the highest priority suffix. + * Gets a sorted map of all accumulated {@link SuffixNode suffixes}. + * + *

Prefer using the {@link #getSuffix()} method for querying.

* * @return a sorted map of suffixes */ @@ -128,14 +215,14 @@ public interface CachedMetaData extends CachedData { @Nullable String getPrimaryGroup(); /** - * Gets the definition used for the prefix stack + * Gets the definition used for the prefix stack. * * @return the definition used for the prefix stack */ @NonNull MetaStackDefinition getPrefixStackDefinition(); /** - * Gets the definition used for the suffix stack + * Gets the definition used for the suffix stack. * * @return the definition used for the suffix stack */ diff --git a/api/src/main/java/net/luckperms/api/cacheddata/CachedPermissionData.java b/api/src/main/java/net/luckperms/api/cacheddata/CachedPermissionData.java index 2b8e65aa8..c97c7ce94 100644 --- a/api/src/main/java/net/luckperms/api/cacheddata/CachedPermissionData.java +++ b/api/src/main/java/net/luckperms/api/cacheddata/CachedPermissionData.java @@ -25,6 +25,7 @@ package net.luckperms.api.cacheddata; +import net.luckperms.api.node.Node; import net.luckperms.api.util.Tristate; import org.checkerframework.checker.nullness.qual.NonNull; @@ -34,17 +35,39 @@ import java.util.Map; /** * Holds cached permission lookup data for a specific set of contexts. + * + *

All calls will account for inheritance, as well as any default data + * provided by the platform. These calls are heavily cached and are therefore + * fast.

*/ public interface CachedPermissionData extends CachedData { /** - * Gets a permission check result for the given permission node. + * Performs a permission check for the given {@code permission} node. + * + *

This check is equivalent to the "hasPermission" method call on most platforms. + * You can use {@link Tristate#asBoolean()} if you need a truthy result.

+ * + * @param permission the permission node + * @return a result containing the tristate + * @throws NullPointerException if permission is null + * @since 5.4 + */ + @NonNull Result queryPermission(@NonNull String permission); + + /** + * Performs a permission check for the given {@code permission} node. + * + *

This check is equivalent to the "hasPermission" method call on most platforms. + * You can use {@link Tristate#asBoolean()} if you need a truthy result.

* * @param permission the permission node * @return a tristate result * @throws NullPointerException if permission is null */ - @NonNull Tristate checkPermission(@NonNull String permission); + default @NonNull Tristate checkPermission(@NonNull String permission) { + return queryPermission(permission).result(); + } /** * Invalidates the underlying permission calculator cache. diff --git a/api/src/main/java/net/luckperms/api/cacheddata/Result.java b/api/src/main/java/net/luckperms/api/cacheddata/Result.java index 0f61190f6..9f7398f3d 100644 --- a/api/src/main/java/net/luckperms/api/cacheddata/Result.java +++ b/api/src/main/java/net/luckperms/api/cacheddata/Result.java @@ -30,9 +30,37 @@ import net.luckperms.api.node.Node; import org.checkerframework.checker.nullness.qual.Nullable; /** - * Represents the result of a cached data lookup + * Represents the result of a cached data lookup. + * + *

You can find "the holder that has the node that caused this result" + * using the following code:

+ *

+ *
+ *
+ * public static {@link net.luckperms.api.model.PermissionHolder.Identifier} holderThatHasTheNodeThatCausedTheResult(Result<?, ?> result) {
+ *     {@link Node} node = result.node();
+ *     if (node == null) {
+ *         return null;
+ *     }
+ *     {@link net.luckperms.api.node.metadata.types.InheritanceOriginMetadata} origin = node.getMetadata(InheritanceOriginMetadata.KEY).orElse(null);
+ *     if (origin == null) {
+ *         return null;
+ *     }
+ *     return origin.getOrigin();
+ * }
+ * 
+ * + *

Combined with the node itself, this is all the information needed to determine + * the root cause of the result.

+ *
+ * + *

The nullability of {@link #result()} is purposely undefined to allow the + * flexibility for methods using {@link Result} to declare it. In general, if the {@code T} type + * has a nullable/undefined value, then the return of {@link #result()} will be non-null, + * and if not, it will be nullable.

* * @param the result type + * @param the node type * @since 5.4 */ public interface Result { @@ -51,11 +79,4 @@ public interface Result { */ @Nullable N node(); - /** - * Gets the result that this result overrides, if applicable. - * - * @return the overridden result - */ - @Nullable Result overriddenResult(); - } diff --git a/api/src/main/java/net/luckperms/api/cacheddata/package-info.java b/api/src/main/java/net/luckperms/api/cacheddata/package-info.java index 0358e6716..ec5b4bb8c 100644 --- a/api/src/main/java/net/luckperms/api/cacheddata/package-info.java +++ b/api/src/main/java/net/luckperms/api/cacheddata/package-info.java @@ -24,7 +24,7 @@ */ /** - * CachedData lookup API for {@link net.luckperms.api.model.user.User}s and + * Caches permission checks and meta lookups for {@link net.luckperms.api.model.user.User}s and * {@link net.luckperms.api.model.group.Group}s. */ package net.luckperms.api.cacheddata; \ No newline at end of file diff --git a/common/src/main/java/me/lucko/luckperms/common/cacheddata/AbstractCachedDataManager.java b/common/src/main/java/me/lucko/luckperms/common/cacheddata/AbstractCachedDataManager.java index 581c11663..930db77fe 100644 --- a/common/src/main/java/me/lucko/luckperms/common/cacheddata/AbstractCachedDataManager.java +++ b/common/src/main/java/me/lucko/luckperms/common/cacheddata/AbstractCachedDataManager.java @@ -255,24 +255,11 @@ public abstract class AbstractCachedDataManager implements CachedDataManager { this.cache.clear(); } } - - private MetaStackDefinition getMetaStackDefinition(QueryOptions queryOptions, ChatMetaType type) { - MetaStackDefinition stack = queryOptions.option(type == ChatMetaType.PREFIX ? - MetaStackDefinition.PREFIX_STACK_KEY : - MetaStackDefinition.SUFFIX_STACK_KEY - ).orElse(null); - - if (stack == null) { - stack = getDefaultMetaStackDefinition(type); - } - - return stack; - } private MetaAccumulator newAccumulator(QueryOptions queryOptions) { return new MetaAccumulator( - getMetaStackDefinition(queryOptions, ChatMetaType.PREFIX), - getMetaStackDefinition(queryOptions, ChatMetaType.SUFFIX) + queryOptions.option(MetaStackDefinition.PREFIX_STACK_KEY).orElseGet(() -> getDefaultMetaStackDefinition(ChatMetaType.PREFIX)), + queryOptions.option(MetaStackDefinition.SUFFIX_STACK_KEY).orElseGet(() -> getDefaultMetaStackDefinition(ChatMetaType.SUFFIX)) ); } diff --git a/common/src/main/java/me/lucko/luckperms/common/cacheddata/result/StringResult.java b/common/src/main/java/me/lucko/luckperms/common/cacheddata/result/StringResult.java index b8567a3b0..a88a9148c 100644 --- a/common/src/main/java/me/lucko/luckperms/common/cacheddata/result/StringResult.java +++ b/common/src/main/java/me/lucko/luckperms/common/cacheddata/result/StringResult.java @@ -62,7 +62,6 @@ public final class StringResult implements Result { return this.node; } - @Override public @Nullable StringResult overriddenResult() { return this.overriddenResult; } @@ -86,23 +85,24 @@ public final class StringResult implements Result { private static final StringResult NULL_RESULT = new StringResult<>(null, null, null); @SuppressWarnings("unchecked") - public static StringResult nullResult() { - return (StringResult) NULL_RESULT; + public static StringResult nullResult() { + return (StringResult) NULL_RESULT; } - public static StringResult of(String result) { + public static StringResult of(String result) { return new StringResult<>(result, null, null); } + public static StringResult of(String result, N node) { + return new StringResult<>(result, node, null); + } + public static StringResult of(MetaNode node) { return new StringResult<>(node.getMetaValue(), node, null); } - public static StringResult> of(ChatMetaNode node) { + public static > StringResult of(N node) { return new StringResult<>(node.getMetaValue(), node, null); } - public static StringResult> of(String result, ChatMetaNode node) { - return new StringResult<>(result, node, null); - } } diff --git a/common/src/main/java/me/lucko/luckperms/common/cacheddata/result/TristateResult.java b/common/src/main/java/me/lucko/luckperms/common/cacheddata/result/TristateResult.java index 46886566e..f8a8a49f6 100644 --- a/common/src/main/java/me/lucko/luckperms/common/cacheddata/result/TristateResult.java +++ b/common/src/main/java/me/lucko/luckperms/common/cacheddata/result/TristateResult.java @@ -81,7 +81,6 @@ public final class TristateResult implements Result { } } - @Override public @Nullable TristateResult overriddenResult() { return this.overriddenResult; } diff --git a/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MetaAccumulator.java b/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MetaAccumulator.java index 2252387c8..ce2255a61 100644 --- a/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MetaAccumulator.java +++ b/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MetaAccumulator.java @@ -78,8 +78,8 @@ public class MetaAccumulator { private final AtomicReference state = new AtomicReference<>(State.ACCUMULATING); private final ListMultimap> meta; - private final SortedMap>> prefixes; - private final SortedMap>> suffixes; + private final SortedMap> prefixes; + private final SortedMap> suffixes; private int weight = 0; private String primaryGroup; @@ -87,8 +87,8 @@ public class MetaAccumulator { private final MetaStackDefinition prefixDefinition; private final MetaStackDefinition suffixDefinition; - private final MetaStackAccumulator prefixAccumulator; - private final MetaStackAccumulator suffixAccumulator; + private final MetaStackAccumulator prefixAccumulator; + private final MetaStackAccumulator suffixAccumulator; public MetaAccumulator(MetaStackDefinition prefixDefinition, MetaStackDefinition suffixDefinition) { Objects.requireNonNull(prefixDefinition, "prefixDefinition"); @@ -98,8 +98,8 @@ public class MetaAccumulator { this.suffixes = new TreeMap<>(Comparator.reverseOrder()); this.prefixDefinition = prefixDefinition; this.suffixDefinition = suffixDefinition; - this.prefixAccumulator = new MetaStackAccumulator(this.prefixDefinition, ChatMetaType.PREFIX); - this.suffixAccumulator = new MetaStackAccumulator(this.suffixDefinition, ChatMetaType.SUFFIX); + this.prefixAccumulator = new MetaStackAccumulator<>(this.prefixDefinition, ChatMetaType.PREFIX); + this.suffixAccumulator = new MetaStackAccumulator<>(this.suffixDefinition, ChatMetaType.SUFFIX); } private void ensureState(State state) { @@ -181,17 +181,17 @@ public class MetaAccumulator { return this.meta; } - public Map>> getChatMeta(ChatMetaType type) { + public Map>> getChatMeta(ChatMetaType type) { ensureState(State.COMPLETE); return type == ChatMetaType.PREFIX ? this.prefixes : this.suffixes; } - public SortedMap>> getPrefixes() { + public SortedMap> getPrefixes() { ensureState(State.COMPLETE); return this.prefixes; } - public SortedMap>> getSuffixes() { + public SortedMap> getSuffixes() { ensureState(State.COMPLETE); return this.suffixes; } @@ -216,12 +216,12 @@ public class MetaAccumulator { return this.suffixDefinition; } - public StringResult> getPrefix() { + public StringResult getPrefix() { ensureState(State.COMPLETE); return this.prefixAccumulator.toResult(); } - public StringResult> getSuffix() { + public StringResult getSuffix() { ensureState(State.COMPLETE); return this.suffixAccumulator.toResult(); } diff --git a/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MetaCache.java b/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MetaCache.java index 066d1f03c..da8f7ce23 100644 --- a/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MetaCache.java +++ b/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MetaCache.java @@ -42,8 +42,9 @@ import me.lucko.luckperms.common.verbose.event.CheckOrigin; import net.luckperms.api.cacheddata.CachedMetaData; import net.luckperms.api.cacheddata.Result; import net.luckperms.api.metastacking.MetaStackDefinition; -import net.luckperms.api.node.types.ChatMetaNode; import net.luckperms.api.node.types.MetaNode; +import net.luckperms.api.node.types.PrefixNode; +import net.luckperms.api.node.types.SuffixNode; import net.luckperms.api.query.QueryOptions; import net.luckperms.api.query.meta.MetaValueSelector; @@ -69,14 +70,14 @@ public class MetaCache extends UsageTracked implements CachedMetaData { /* The data */ private final Map>> meta; private final Map> flattenedMeta; - private final SortedMap>> prefixes; - private final SortedMap>> suffixes; + private final SortedMap> prefixes; + private final SortedMap> suffixes; private final int weight; private final String primaryGroup; private final MetaStackDefinition prefixDefinition; private final MetaStackDefinition suffixDefinition; - private final StringResult> prefix; - private final StringResult> suffix; + private final StringResult prefix; + private final StringResult suffix; public MetaCache(LuckPermsPlugin plugin, QueryOptions queryOptions, MetaAccumulator sourceMeta) { this.plugin = plugin; @@ -118,24 +119,39 @@ public class MetaCache extends UsageTracked implements CachedMetaData { return this.flattenedMeta.getOrDefault(key.toLowerCase(Locale.ROOT), StringResult.nullResult()); } + @Override + public final @NonNull Result queryMetaValue(@NonNull String key) { + 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> getPrefix(CheckOrigin origin) { + public @NonNull StringResult getPrefix(CheckOrigin origin) { return this.prefix; } + @Override + public final @NonNull Result queryPrefix() { + return getPrefix(CheckOrigin.LUCKPERMS_API); + } + @Override public final @Nullable String getPrefix() { return getPrefix(CheckOrigin.LUCKPERMS_API).result(); } - public @NonNull StringResult> getSuffix(CheckOrigin origin) { + public @NonNull StringResult getSuffix(CheckOrigin origin) { return this.suffix; } + @Override + public final @NonNull Result querySuffix() { + return getSuffix(CheckOrigin.LUCKPERMS_API); + } + @Override public final @Nullable String getSuffix() { return getSuffix(CheckOrigin.LUCKPERMS_API).result(); diff --git a/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MetaStackAccumulator.java b/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MetaStackAccumulator.java index 124dd7ca1..ad7eb88a6 100644 --- a/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MetaStackAccumulator.java +++ b/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MetaStackAccumulator.java @@ -41,9 +41,9 @@ import java.util.List; import java.util.Objects; import java.util.stream.Collectors; -public class MetaStackAccumulator { +public class MetaStackAccumulator> { private final MetaStackDefinition definition; - private final List entries; + private final List> entries; public MetaStackAccumulator(MetaStackDefinition definition, ChatMetaType targetType) { this.definition = definition; @@ -51,17 +51,17 @@ public class MetaStackAccumulator { List elements = definition.getElements(); this.entries = new ArrayList<>(elements.size()); for (MetaStackElement element : elements) { - this.entries.add(new Entry(element, targetType)); + this.entries.add(new Entry<>(element, targetType)); } } - public void offer(ChatMetaNode node) { - for (Entry entry : this.entries) { + public void offer(N node) { + for (Entry entry : this.entries) { entry.offer(node); } } - public List> getElements() { + public List getElements() { return this.entries.stream() .map(Entry::getNode) .filter(Objects::nonNull) @@ -70,8 +70,8 @@ public class MetaStackAccumulator { public String toFormattedString() { List elements = new LinkedList<>(); - for (Entry entry : this.entries) { - ChatMetaNode node = entry.getNode(); + for (Entry entry : this.entries) { + N node = entry.getNode(); if (node != null) { elements.add(node.getMetaValue()); } @@ -105,13 +105,13 @@ public class MetaStackAccumulator { return sb.toString(); } - public StringResult> toResult() { + public StringResult toResult() { String formatted = toFormattedString(); if (formatted == null) { return StringResult.nullResult(); } - List> elements = getElements(); + List elements = getElements(); switch (elements.size()) { case 0: @@ -119,12 +119,12 @@ public class MetaStackAccumulator { case 1: return StringResult.of(formatted, elements.get(0)); default: { - Iterator> it = elements.iterator(); - StringResult> result = StringResult.of(formatted, it.next()); + Iterator it = elements.iterator(); + StringResult result = StringResult.of(formatted, it.next()); - StringResult> root = result; + StringResult root = result; while (it.hasNext()) { - StringResult> nested = StringResult.of(it.next()); + StringResult nested = StringResult.of(it.next()); root.setOverriddenResult(nested); root = nested; } @@ -134,22 +134,22 @@ public class MetaStackAccumulator { } } - private static final class Entry { + private static final class Entry> { private final MetaStackElement element; private final ChatMetaType type; - private @Nullable ChatMetaNode current = null; + private @Nullable N current = null; Entry(MetaStackElement element, ChatMetaType type) { this.element = element; this.type = type; } - public ChatMetaNode getNode() { + public N getNode() { return this.current; } - public boolean offer(ChatMetaNode node) { + public boolean offer(N node) { if (this.element.shouldAccumulate(this.type, node, this.current)) { this.current = node; return true; diff --git a/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MonitoredMetaCache.java b/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MonitoredMetaCache.java index fd014eecd..ecd2116c6 100644 --- a/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MonitoredMetaCache.java +++ b/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/MonitoredMetaCache.java @@ -35,8 +35,9 @@ import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.verbose.event.CheckOrigin; import net.luckperms.api.cacheddata.CachedMetaData; -import net.luckperms.api.node.types.ChatMetaNode; import net.luckperms.api.node.types.MetaNode; +import net.luckperms.api.node.types.PrefixNode; +import net.luckperms.api.node.types.SuffixNode; import net.luckperms.api.query.QueryOptions; import org.checkerframework.checker.nullness.qual.NonNull; @@ -73,16 +74,16 @@ public class MonitoredMetaCache extends MetaCache implements CachedMetaData { @Override @NonNull - public StringResult> getPrefix(CheckOrigin origin) { - StringResult> value = super.getPrefix(origin); + public StringResult getPrefix(CheckOrigin origin) { + StringResult value = super.getPrefix(origin); this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), Prefix.NODE_KEY, value); return value; } @Override @NonNull - public StringResult> getSuffix(CheckOrigin origin) { - StringResult> value = super.getSuffix(origin); + public StringResult getSuffix(CheckOrigin origin) { + StringResult value = super.getSuffix(origin); this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), Suffix.NODE_KEY, value); return value; } diff --git a/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/PermissionCache.java b/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/PermissionCache.java index c26d5a4c4..6b754579e 100644 --- a/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/PermissionCache.java +++ b/common/src/main/java/me/lucko/luckperms/common/cacheddata/type/PermissionCache.java @@ -35,6 +35,7 @@ import me.lucko.luckperms.common.calculator.PermissionCalculator; import me.lucko.luckperms.common.verbose.event.CheckOrigin; import net.luckperms.api.cacheddata.CachedPermissionData; +import net.luckperms.api.cacheddata.Result; import net.luckperms.api.node.Node; import net.luckperms.api.query.QueryOptions; import net.luckperms.api.util.Tristate; @@ -102,6 +103,11 @@ public class PermissionCache extends UsageTracked implements CachedPermissionDat return this.calculator.checkPermission(permission, origin); } + @Override + public @NonNull Result queryPermission(@NonNull String permission) { + return checkPermission(permission, CheckOrigin.LUCKPERMS_API); + } + @Override public @NonNull Tristate checkPermission(@NonNull String permission) { return checkPermission(permission, CheckOrigin.LUCKPERMS_API).result();