mirror of
https://github.com/LuckPerms/LuckPerms.git
synced 2024-10-03 07:47:32 +02:00
Provide API access to cached data result info (#3243)
This commit is contained in:
parent
acdc259771
commit
6781c1fb51
@ -31,6 +31,10 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
/**
|
||||
* Holds cached lookup data for a given set of query options.
|
||||
*
|
||||
* <p>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.</p>
|
||||
*/
|
||||
public interface CachedData {
|
||||
|
||||
|
@ -39,7 +39,7 @@ import java.util.concurrent.CompletableFuture;
|
||||
* Holds cached permission and meta lookup data for a {@link PermissionHolder}.
|
||||
*
|
||||
* <p>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.</p>
|
||||
*/
|
||||
public interface CachedDataManager {
|
||||
@ -81,11 +81,10 @@ public interface CachedDataManager {
|
||||
* <p>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.</p>
|
||||
* {@link ContextManager#getStaticQueryOptions() the current static query options}.</p>
|
||||
*
|
||||
* <p>For {@link Group}s, the most appropriate query options will always be
|
||||
* {@link ContextManager#getStaticQueryOptions()} the current static query options.</p>
|
||||
* {@link ContextManager#getStaticQueryOptions() the current static query options}.</p>
|
||||
*
|
||||
* @return a permission data instance
|
||||
* @since 5.1
|
||||
@ -99,11 +98,10 @@ public interface CachedDataManager {
|
||||
* <p>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.</p>
|
||||
* {@link ContextManager#getStaticQueryOptions() the current static query options}.</p>
|
||||
*
|
||||
* <p>For {@link Group}s, the most appropriate query options will always be
|
||||
* {@link ContextManager#getStaticQueryOptions()} the current static query options.</p>
|
||||
* {@link ContextManager#getStaticQueryOptions() the current static query options}.</p>
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* <p>Can be called to allow for an update in defaults.</p>
|
||||
*/
|
||||
|
@ -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.
|
||||
*
|
||||
* <p>Meta data refers to {@link PrefixNode prefixes}, {@link SuffixNode suffixes} and
|
||||
* {@link MetaNode meta (options)} held by a permission holder.</p>
|
||||
*
|
||||
* <p>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.</p>
|
||||
*/
|
||||
public interface CachedMetaData extends CachedData {
|
||||
|
||||
/**
|
||||
* Query a meta value for the given {@code key}.
|
||||
*
|
||||
* <p>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.</p>
|
||||
*
|
||||
* @param key the key
|
||||
* @return a result containing the value
|
||||
* @since 5.4
|
||||
*/
|
||||
@NonNull Result<String, MetaNode> queryMetaValue(@NonNull String key);
|
||||
|
||||
/**
|
||||
* Gets a value for the given meta key.
|
||||
*
|
||||
* <p>If no such meta value exists for the given key, {@code null} is returned.</p>
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* <p>This method uses the rules defined by the {@link #getPrefixStackDefinition() prefix stack}
|
||||
* to produce a {@link String} output.</p>
|
||||
*
|
||||
* <p>Assuming the default configuration is used, this will usually be the value of the
|
||||
* holder's highest priority prefix node.</p>
|
||||
*
|
||||
* <p>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.</p>
|
||||
*
|
||||
* @return a result containing the prefix
|
||||
* @since 5.4
|
||||
*/
|
||||
@NonNull Result<String, PrefixNode> queryPrefix();
|
||||
|
||||
/**
|
||||
* Gets the prefix.
|
||||
*
|
||||
* <p>This method uses the rules defined by the {@link #getPrefixStackDefinition() prefix stack}
|
||||
* to produce a {@link String} output.</p>
|
||||
*
|
||||
* <p>Assuming the default configuration is used, this will usually be the value of the
|
||||
* holder's highest priority prefix node.</p>
|
||||
*
|
||||
* <p>If the resultant prefix stack contained no elements, {@code null} is returned.</p>
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* <p>This method uses the rules defined by the {@link #getSuffixStackDefinition() suffix stack}
|
||||
* to produce a {@link String} output.</p>
|
||||
*
|
||||
* <p>Assuming the default configuration is used, this will usually be the value of the
|
||||
* holder's highest priority suffix node.</p>
|
||||
*
|
||||
* <p>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.</p>
|
||||
*
|
||||
* @return a result containing the suffix
|
||||
* @since 5.4
|
||||
*/
|
||||
@NonNull Result<String, SuffixNode> querySuffix();
|
||||
|
||||
/**
|
||||
* Gets the suffix.
|
||||
*
|
||||
* <p>This method uses the rules defined by the {@link #getSuffixStackDefinition() suffix stack}
|
||||
* to produce a {@link String} output.</p>
|
||||
*
|
||||
* <p>Assuming the default configuration is used, this will usually be the value of the
|
||||
* holder's highest priority suffix node.</p>
|
||||
*
|
||||
* <p>If the resultant suffix stack contained no elements, {@code null} is returned.</p>
|
||||
*
|
||||
* @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
|
||||
* <p>Prefer using the {@link #getMetaValue(String)} method for querying values.</p>
|
||||
*
|
||||
* @return a map of meta
|
||||
*/
|
||||
@NonNull @Unmodifiable Map<String, List<String>> 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}.
|
||||
*
|
||||
* <p>Prefer using the {@link #getPrefix()} method for querying.</p>
|
||||
*
|
||||
* @return a sorted map of prefixes
|
||||
*/
|
||||
@NonNull @Unmodifiable SortedMap<Integer, String> 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}.
|
||||
*
|
||||
* <p>Prefer using the {@link #getSuffix()} method for querying.</p>
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
|
@ -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.
|
||||
*
|
||||
* <p>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.</p>
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* <p>This check is equivalent to the "hasPermission" method call on most platforms.
|
||||
* You can use {@link Tristate#asBoolean()} if you need a truthy result.</p>
|
||||
*
|
||||
* @param permission the permission node
|
||||
* @return a result containing the tristate
|
||||
* @throws NullPointerException if permission is null
|
||||
* @since 5.4
|
||||
*/
|
||||
@NonNull Result<Tristate, Node> queryPermission(@NonNull String permission);
|
||||
|
||||
/**
|
||||
* Performs a permission check for the given {@code permission} node.
|
||||
*
|
||||
* <p>This check is equivalent to the "hasPermission" method call on most platforms.
|
||||
* You can use {@link Tristate#asBoolean()} if you need a truthy result.</p>
|
||||
*
|
||||
* @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.
|
||||
|
@ -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.
|
||||
*
|
||||
* <p>You can find "the holder that has the node that caused this result"
|
||||
* using the following code:</p>
|
||||
* <p></p>
|
||||
* <blockquote>
|
||||
* <pre>
|
||||
* 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();
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p>Combined with the node itself, this is all the information needed to determine
|
||||
* the root cause of the result.</p>
|
||||
* </blockquote>
|
||||
*
|
||||
* <p>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.</p>
|
||||
*
|
||||
* @param <T> the result type
|
||||
* @param <N> the node type
|
||||
* @since 5.4
|
||||
*/
|
||||
public interface Result<T, N extends Node> {
|
||||
@ -51,11 +79,4 @@ public interface Result<T, N extends Node> {
|
||||
*/
|
||||
@Nullable N node();
|
||||
|
||||
/**
|
||||
* Gets the result that this result overrides, if applicable.
|
||||
*
|
||||
* @return the overridden result
|
||||
*/
|
||||
@Nullable Result<T, N> overriddenResult();
|
||||
|
||||
}
|
||||
|
@ -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;
|
@ -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))
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,6 @@ public final class StringResult<N extends Node> implements Result<String, N> {
|
||||
return this.node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable StringResult<N> overriddenResult() {
|
||||
return this.overriddenResult;
|
||||
}
|
||||
@ -86,23 +85,24 @@ public final class StringResult<N extends Node> implements Result<String, N> {
|
||||
private static final StringResult<?> NULL_RESULT = new StringResult<>(null, null, null);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends Node> StringResult<T> nullResult() {
|
||||
return (StringResult<T>) NULL_RESULT;
|
||||
public static <N extends Node> StringResult<N> nullResult() {
|
||||
return (StringResult<N>) NULL_RESULT;
|
||||
}
|
||||
|
||||
public static <T extends Node> StringResult<T> of(String result) {
|
||||
public static <N extends Node> StringResult<N> of(String result) {
|
||||
return new StringResult<>(result, null, null);
|
||||
}
|
||||
|
||||
public static <N extends Node> StringResult<N> of(String result, N node) {
|
||||
return new StringResult<>(result, node, null);
|
||||
}
|
||||
|
||||
public static StringResult<MetaNode> of(MetaNode node) {
|
||||
return new StringResult<>(node.getMetaValue(), node, null);
|
||||
}
|
||||
|
||||
public static StringResult<ChatMetaNode<?, ?>> of(ChatMetaNode<?, ?> node) {
|
||||
public static <N extends ChatMetaNode<?, ?>> StringResult<N> of(N node) {
|
||||
return new StringResult<>(node.getMetaValue(), node, null);
|
||||
}
|
||||
|
||||
public static StringResult<ChatMetaNode<?, ?>> of(String result, ChatMetaNode<?, ?> node) {
|
||||
return new StringResult<>(result, node, null);
|
||||
}
|
||||
}
|
||||
|
@ -81,7 +81,6 @@ public final class TristateResult implements Result<Tristate, Node> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable TristateResult overriddenResult() {
|
||||
return this.overriddenResult;
|
||||
}
|
||||
|
@ -78,8 +78,8 @@ public class MetaAccumulator {
|
||||
private final AtomicReference<State> state = new AtomicReference<>(State.ACCUMULATING);
|
||||
|
||||
private final ListMultimap<String, StringResult<MetaNode>> meta;
|
||||
private final SortedMap<Integer, StringResult<ChatMetaNode<?, ?>>> prefixes;
|
||||
private final SortedMap<Integer, StringResult<ChatMetaNode<?, ?>>> suffixes;
|
||||
private final SortedMap<Integer, StringResult<PrefixNode>> prefixes;
|
||||
private final SortedMap<Integer, StringResult<SuffixNode>> 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<PrefixNode> prefixAccumulator;
|
||||
private final MetaStackAccumulator<SuffixNode> 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<Integer, StringResult<ChatMetaNode<?, ?>>> getChatMeta(ChatMetaType type) {
|
||||
public Map<Integer, ? extends StringResult<? extends ChatMetaNode<?, ?>>> getChatMeta(ChatMetaType type) {
|
||||
ensureState(State.COMPLETE);
|
||||
return type == ChatMetaType.PREFIX ? this.prefixes : this.suffixes;
|
||||
}
|
||||
|
||||
public SortedMap<Integer, StringResult<ChatMetaNode<?, ?>>> getPrefixes() {
|
||||
public SortedMap<Integer, StringResult<PrefixNode>> getPrefixes() {
|
||||
ensureState(State.COMPLETE);
|
||||
return this.prefixes;
|
||||
}
|
||||
|
||||
public SortedMap<Integer, StringResult<ChatMetaNode<?, ?>>> getSuffixes() {
|
||||
public SortedMap<Integer, StringResult<SuffixNode>> getSuffixes() {
|
||||
ensureState(State.COMPLETE);
|
||||
return this.suffixes;
|
||||
}
|
||||
@ -216,12 +216,12 @@ public class MetaAccumulator {
|
||||
return this.suffixDefinition;
|
||||
}
|
||||
|
||||
public StringResult<ChatMetaNode<?, ?>> getPrefix() {
|
||||
public StringResult<PrefixNode> getPrefix() {
|
||||
ensureState(State.COMPLETE);
|
||||
return this.prefixAccumulator.toResult();
|
||||
}
|
||||
|
||||
public StringResult<ChatMetaNode<?, ?>> getSuffix() {
|
||||
public StringResult<SuffixNode> getSuffix() {
|
||||
ensureState(State.COMPLETE);
|
||||
return this.suffixAccumulator.toResult();
|
||||
}
|
||||
|
@ -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<String, List<StringResult<MetaNode>>> meta;
|
||||
private final Map<String, StringResult<MetaNode>> flattenedMeta;
|
||||
private final SortedMap<Integer, StringResult<ChatMetaNode<?, ?>>> prefixes;
|
||||
private final SortedMap<Integer, StringResult<ChatMetaNode<?, ?>>> suffixes;
|
||||
private final SortedMap<Integer, StringResult<PrefixNode>> prefixes;
|
||||
private final SortedMap<Integer, StringResult<SuffixNode>> suffixes;
|
||||
private final int weight;
|
||||
private final String primaryGroup;
|
||||
private final MetaStackDefinition prefixDefinition;
|
||||
private final MetaStackDefinition suffixDefinition;
|
||||
private final StringResult<ChatMetaNode<?, ?>> prefix;
|
||||
private final StringResult<ChatMetaNode<?, ?>> suffix;
|
||||
private final StringResult<PrefixNode> prefix;
|
||||
private final StringResult<SuffixNode> 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<String, MetaNode> 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<ChatMetaNode<?,?>> getPrefix(CheckOrigin origin) {
|
||||
public @NonNull StringResult<PrefixNode> getPrefix(CheckOrigin origin) {
|
||||
return this.prefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final @NonNull Result<String, PrefixNode> queryPrefix() {
|
||||
return getPrefix(CheckOrigin.LUCKPERMS_API);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final @Nullable String getPrefix() {
|
||||
return getPrefix(CheckOrigin.LUCKPERMS_API).result();
|
||||
}
|
||||
|
||||
public @NonNull StringResult<ChatMetaNode<?,?>> getSuffix(CheckOrigin origin) {
|
||||
public @NonNull StringResult<SuffixNode> getSuffix(CheckOrigin origin) {
|
||||
return this.suffix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final @NonNull Result<String, SuffixNode> querySuffix() {
|
||||
return getSuffix(CheckOrigin.LUCKPERMS_API);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final @Nullable String getSuffix() {
|
||||
return getSuffix(CheckOrigin.LUCKPERMS_API).result();
|
||||
|
@ -41,9 +41,9 @@ import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MetaStackAccumulator {
|
||||
public class MetaStackAccumulator<N extends ChatMetaNode<N, ?>> {
|
||||
private final MetaStackDefinition definition;
|
||||
private final List<Entry> entries;
|
||||
private final List<Entry<N>> entries;
|
||||
|
||||
public MetaStackAccumulator(MetaStackDefinition definition, ChatMetaType targetType) {
|
||||
this.definition = definition;
|
||||
@ -51,17 +51,17 @@ public class MetaStackAccumulator {
|
||||
List<MetaStackElement> 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<N> entry : this.entries) {
|
||||
entry.offer(node);
|
||||
}
|
||||
}
|
||||
|
||||
public List<ChatMetaNode<?, ?>> getElements() {
|
||||
public List<N> getElements() {
|
||||
return this.entries.stream()
|
||||
.map(Entry::getNode)
|
||||
.filter(Objects::nonNull)
|
||||
@ -70,8 +70,8 @@ public class MetaStackAccumulator {
|
||||
|
||||
public String toFormattedString() {
|
||||
List<String> elements = new LinkedList<>();
|
||||
for (Entry entry : this.entries) {
|
||||
ChatMetaNode<?, ?> node = entry.getNode();
|
||||
for (Entry<N> 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<ChatMetaNode<?, ?>> toResult() {
|
||||
public StringResult<N> toResult() {
|
||||
String formatted = toFormattedString();
|
||||
if (formatted == null) {
|
||||
return StringResult.nullResult();
|
||||
}
|
||||
|
||||
List<ChatMetaNode<?, ?>> elements = getElements();
|
||||
List<N> 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<ChatMetaNode<?, ?>> it = elements.iterator();
|
||||
StringResult<ChatMetaNode<?, ?>> result = StringResult.of(formatted, it.next());
|
||||
Iterator<N> it = elements.iterator();
|
||||
StringResult<N> result = StringResult.of(formatted, it.next());
|
||||
|
||||
StringResult<ChatMetaNode<?, ?>> root = result;
|
||||
StringResult<N> root = result;
|
||||
while (it.hasNext()) {
|
||||
StringResult<ChatMetaNode<?, ?>> nested = StringResult.of(it.next());
|
||||
StringResult<N> 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<N extends ChatMetaNode<?, ?>> {
|
||||
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;
|
||||
|
@ -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<ChatMetaNode<?, ?>> getPrefix(CheckOrigin origin) {
|
||||
StringResult<ChatMetaNode<?, ?>> value = super.getPrefix(origin);
|
||||
public StringResult<PrefixNode> getPrefix(CheckOrigin origin) {
|
||||
StringResult<PrefixNode> 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<ChatMetaNode<?, ?>> getSuffix(CheckOrigin origin) {
|
||||
StringResult<ChatMetaNode<?, ?>> value = super.getSuffix(origin);
|
||||
public StringResult<SuffixNode> getSuffix(CheckOrigin origin) {
|
||||
StringResult<SuffixNode> value = super.getSuffix(origin);
|
||||
this.plugin.getVerboseHandler().offerMetaCheckEvent(origin, this.metadata.getVerboseCheckInfo(), this.metadata.getQueryOptions(), Suffix.NODE_KEY, value);
|
||||
return value;
|
||||
}
|
||||
|
@ -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<Tristate, Node> 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();
|
||||
|
Loading…
Reference in New Issue
Block a user