mirror of
https://github.com/LuckPerms/LuckPerms.git
synced 2025-01-16 21:31:35 +01:00
Allow data query order to be specified via the API
This commit is contained in:
parent
bafada4f17
commit
4667ffc681
@ -28,8 +28,10 @@ package me.lucko.luckperms.api.context;
|
||||
/**
|
||||
* Some default context keys used by the plugin.
|
||||
*/
|
||||
public enum DefaultContextKeys {
|
||||
;
|
||||
public final class DefaultContextKeys {
|
||||
private DefaultContextKeys() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
/**
|
||||
* The context key used to denote the subjects server.
|
||||
|
@ -57,34 +57,64 @@ import java.util.function.Predicate;
|
||||
public interface PermissionHolder {
|
||||
|
||||
/**
|
||||
* Gets the objects generic name.
|
||||
*
|
||||
* <p>The result of this method is guaranteed to be a unique identifier for distinct instances
|
||||
* of the same type of object.</p>
|
||||
*
|
||||
* <p>For {@link User}s, this method returns a {@link UUID#toString() string} representation of
|
||||
* the users {@link User#getUniqueId() unique id}.</p>
|
||||
*
|
||||
* <p>For {@link Group}s, this method returns the {@link Group#getName() group name}.</p>
|
||||
*
|
||||
* <p>The {@link User#getUniqueId()}, {@link User#getUsername()} and {@link Group#getName()} methods
|
||||
* define a "tighter" specification for obtaining object identifiers.</p>
|
||||
*
|
||||
* @return the identifier for this object. Either a uuid string or name.
|
||||
* Represents a way to identify distinct {@link PermissionHolder}s.
|
||||
*/
|
||||
@NonNull String getObjectName();
|
||||
interface Identifier {
|
||||
|
||||
/**
|
||||
* The {@link #getType() type} of {@link User} permission holders.
|
||||
*/
|
||||
String USER_TYPE = "user";
|
||||
|
||||
/**
|
||||
* The {@link #getType() type} of {@link Group} permission holders.
|
||||
*/
|
||||
String GROUP_TYPE = "group";
|
||||
|
||||
/**
|
||||
* Gets the {@link PermissionHolder}s generic name.
|
||||
*
|
||||
* <p>The result of this method is guaranteed to be a unique identifier for distinct instances
|
||||
* of the same type of object.</p>
|
||||
*
|
||||
* <p>For {@link User}s, this method returns a {@link UUID#toString() string} representation of
|
||||
* the users {@link User#getUniqueId() unique id}.</p>
|
||||
*
|
||||
* <p>For {@link Group}s, this method returns the {@link Group#getName() group name}.</p>
|
||||
*
|
||||
* <p>The {@link User#getUniqueId()}, {@link User#getUsername()} and {@link Group#getName()} methods
|
||||
* define a "tighter" specification for obtaining object identifiers.</p>
|
||||
*
|
||||
* @return the identifier for this object. Either a uuid string or name.
|
||||
*/
|
||||
@NonNull String getName();
|
||||
|
||||
/**
|
||||
* Gets the type of the {@link PermissionHolder}.
|
||||
*
|
||||
* @return the type
|
||||
*/
|
||||
@NonNull String getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the identifier of the holder.
|
||||
*
|
||||
* @return the identifier
|
||||
*/
|
||||
@NonNull Identifier getIdentifier();
|
||||
|
||||
/**
|
||||
* Gets a friendly name for this holder, to be displayed in command output, etc.
|
||||
*
|
||||
* <p>This will <strong>always</strong> return a value, eventually falling back to
|
||||
* {@link #getObjectName()} if no other "friendlier" identifiers are present.</p>
|
||||
* {@link Identifier#getName()} if no other "friendlier" identifiers are present.</p>
|
||||
*
|
||||
* <p>For {@link User}s, this method will attempt to return the {@link User#getUsername() username},
|
||||
* before falling back to {@link #getObjectName()}.</p>
|
||||
* before falling back to {@link Identifier#getName()}.</p>
|
||||
*
|
||||
* <p>For {@link Group}s, this method will attempt to return the groups display name, before
|
||||
* falling back to {@link #getObjectName()}.</p>
|
||||
* falling back to {@link Identifier#getName()}.</p>
|
||||
*
|
||||
* @return a friendly identifier for this holder
|
||||
*/
|
||||
|
@ -28,7 +28,6 @@ package me.lucko.luckperms.api.node;
|
||||
import me.lucko.luckperms.api.LuckPermsProvider;
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadata;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadataKey;
|
||||
import me.lucko.luckperms.api.node.types.DisplayNameNode;
|
||||
import me.lucko.luckperms.api.node.types.InheritanceNode;
|
||||
@ -188,21 +187,21 @@ public interface Node {
|
||||
* Gets the metadata corresponding to the given <code>key</code>, if present.
|
||||
*
|
||||
* @param key the key
|
||||
* @param <T> the {@link NodeMetadata} type
|
||||
* @param <T> the metadata type
|
||||
* @return the data, if present
|
||||
*/
|
||||
<T extends NodeMetadata> Optional<T> getMetadata(NodeMetadataKey<T> key);
|
||||
<T> Optional<T> getMetadata(NodeMetadataKey<T> key);
|
||||
|
||||
/**
|
||||
* Gets the metadata corresponding to the given <code>key</code>, throwing an exception
|
||||
* if no data is present.
|
||||
*
|
||||
* @param key the key
|
||||
* @param <T> the {@link NodeMetadata} type
|
||||
* @param <T> the metadata type
|
||||
* @return the data
|
||||
* @throws IllegalStateException if data isn't present
|
||||
*/
|
||||
default <T extends NodeMetadata> T metadata(NodeMetadataKey<T> key) throws IllegalStateException {
|
||||
default <T> T metadata(NodeMetadataKey<T> key) throws IllegalStateException {
|
||||
return getMetadata(key).orElseThrow(() -> new IllegalStateException("Node '" + getKey() + "' does not have '" + key.name() + "' attached."));
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,6 @@
|
||||
package me.lucko.luckperms.api.node;
|
||||
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadata;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadataKey;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
@ -138,7 +137,7 @@ public interface NodeBuilder<N extends ScopedNode<N, B>, B extends NodeBuilder<N
|
||||
* @param <T> the metadata type
|
||||
* @return the builder
|
||||
*/
|
||||
@NonNull <T extends NodeMetadata> B withMetadata(@NonNull NodeMetadataKey<T> key, @Nullable T metadata);
|
||||
@NonNull <T> B withMetadata(@NonNull NodeMetadataKey<T> key, @Nullable T metadata);
|
||||
|
||||
/**
|
||||
* Creates a {@link Node} instance from the builder.
|
||||
|
@ -30,7 +30,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Represents a key for a specific type of {@link NodeMetadata}.
|
||||
* Represents a key for a specific type of node metadata.
|
||||
*
|
||||
* <p>Metadata keys are compared using reference equality, the
|
||||
* {@link #equals(Object)} method should not be implemented.</p>
|
||||
@ -43,7 +43,7 @@ import java.util.Objects;
|
||||
*
|
||||
* @param <T> the metadata type
|
||||
*/
|
||||
public interface NodeMetadataKey<T extends NodeMetadata> {
|
||||
public interface NodeMetadataKey<T> {
|
||||
|
||||
/**
|
||||
* Creates a new {@link NodeMetadataKey} for the given name and type.
|
||||
@ -55,7 +55,7 @@ public interface NodeMetadataKey<T extends NodeMetadata> {
|
||||
* @param <T> the type parameter
|
||||
* @return the key
|
||||
*/
|
||||
static <T extends NodeMetadata> @NonNull NodeMetadataKey<T> of(@NonNull String name, @NonNull Class<T> type) {
|
||||
static <T> @NonNull NodeMetadataKey<T> of(@NonNull String name, @NonNull Class<T> type) {
|
||||
Objects.requireNonNull(name, "name");
|
||||
Objects.requireNonNull(type, "type");
|
||||
return new SimpleNodeMetadataKey<>(name, type);
|
||||
|
@ -27,7 +27,7 @@ package me.lucko.luckperms.api.node.metadata;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
final class SimpleNodeMetadataKey<T extends NodeMetadata> implements NodeMetadataKey<T> {
|
||||
final class SimpleNodeMetadataKey<T> implements NodeMetadataKey<T> {
|
||||
private final String name;
|
||||
private final Class<T> type;
|
||||
|
||||
|
@ -27,15 +27,14 @@ package me.lucko.luckperms.api.node.metadata.types;
|
||||
|
||||
import me.lucko.luckperms.api.model.PermissionHolder;
|
||||
import me.lucko.luckperms.api.node.Node;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadata;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadataKey;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
/**
|
||||
* {@link NodeMetadata} indicating where a node was inherited from.
|
||||
* Node metadata indicating where a node was inherited from.
|
||||
*/
|
||||
public interface InheritanceOriginMetadata extends NodeMetadata {
|
||||
public interface InheritanceOriginMetadata {
|
||||
|
||||
/**
|
||||
* The {@link NodeMetadataKey} for {@link InheritanceOriginMetadata}.
|
||||
@ -45,10 +44,10 @@ public interface InheritanceOriginMetadata extends NodeMetadata {
|
||||
/**
|
||||
* Gets the location where the {@link Node} is inherited from.
|
||||
*
|
||||
* <p>The resultant string is the {@link PermissionHolder#getObjectName() object name} of the
|
||||
* <p>The resultant string is the {@link PermissionHolder.Identifier#getName() object name} of the
|
||||
* permission holder the node was inherited from.</p>
|
||||
*
|
||||
* <p>If the node was not inherited, the {@link PermissionHolder#getObjectName() object name}
|
||||
* <p>If the node was not inherited, the {@link PermissionHolder.Identifier#getName() object name}
|
||||
* of the permission holder itself (the one that defined the node) will be returned.</p>
|
||||
*
|
||||
* @return where the node was inherited from.
|
||||
|
@ -32,8 +32,10 @@ import java.util.EnumSet;
|
||||
/**
|
||||
* Some default {@link QueryOptions} instances.
|
||||
*/
|
||||
enum DefaultQueryOptions {
|
||||
;
|
||||
final class DefaultQueryOptions {
|
||||
private DefaultQueryOptions() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
private static final EnumSet<Flag> DEFAULT_FLAGS = EnumSet.allOf(Flag.class);
|
||||
|
||||
|
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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.api.query.dataorder;
|
||||
|
||||
import me.lucko.luckperms.api.model.DataType;
|
||||
import me.lucko.luckperms.api.query.QueryOptions;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Represents the order in which to query different {@link DataType}s.
|
||||
*
|
||||
* <p>The {@link DataQueryOrder} enum simply represents some default
|
||||
* implementations of the {@link Comparator} required by {@link QueryOptions}
|
||||
* and the {@link #queryInOrder(Comparator, Consumer)} or
|
||||
* {@link #order(Comparator)} methods.</p>
|
||||
*
|
||||
* <p>Users are free to implement their own comparator. However, be aware that
|
||||
* it is possible that more {@link DataType}s may be added in the future.
|
||||
* Ideally the {@link Comparator} implementations should be able to handle these
|
||||
* smoothly.</p>
|
||||
*/
|
||||
public enum DataQueryOrder implements Comparator<DataType> {
|
||||
|
||||
/**
|
||||
* A data query order indicating that {@link DataType#TRANSIENT} should be queried first.
|
||||
*/
|
||||
TRANSIENT_FIRST {
|
||||
@Override
|
||||
public int compare(DataType o1, DataType o2) {
|
||||
if (o1 == o2) {
|
||||
return 0;
|
||||
}
|
||||
return Boolean.compare(
|
||||
o1 == DataType.TRANSIENT,
|
||||
o2 == DataType.TRANSIENT
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* A data query order indicating that {@link DataType#TRANSIENT} should be queried last.
|
||||
*/
|
||||
TRANSIENT_LAST {
|
||||
@Override
|
||||
public int compare(DataType o1, DataType o2) {
|
||||
if (o1 == o2) {
|
||||
return 0;
|
||||
}
|
||||
return -Boolean.compare(
|
||||
o1 == DataType.TRANSIENT,
|
||||
o2 == DataType.TRANSIENT
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
private static final List<DataType> TRANSIENT_FIRST_LIST = Collections.unmodifiableList(Arrays.asList(DataType.TRANSIENT, DataType.NORMAL));
|
||||
private static final List<DataType> TRANSIENT_LAST_LIST = Collections.unmodifiableList(Arrays.asList(DataType.NORMAL, DataType.TRANSIENT));
|
||||
|
||||
/**
|
||||
* Gets a {@link List} of all {@link DataType}s, in the order defined by
|
||||
* the {@code comparator}.
|
||||
*
|
||||
* @param comparator the comparator
|
||||
* @return the ordered data types
|
||||
*/
|
||||
public static List<DataType> order(@NonNull Comparator<? super DataType> comparator) {
|
||||
int compare = comparator.compare(DataType.TRANSIENT, DataType.NORMAL);
|
||||
if (compare > 0) {
|
||||
// transient first
|
||||
return TRANSIENT_FIRST_LIST;
|
||||
} else if (compare < 0) {
|
||||
// transient last
|
||||
return TRANSIENT_LAST_LIST;
|
||||
} else {
|
||||
// ??? - no defined order
|
||||
throw new IllegalStateException("Comparator " + comparator + " does not define an order between DataType.NORMAL and DataType.TRANSIENT!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the {@code action} {@link Consumer} for each {@link DataType}, in
|
||||
* the order defined by the {@code comparator}.
|
||||
*
|
||||
* @param comparator the comparator
|
||||
* @param action the action
|
||||
*/
|
||||
public static void queryInOrder(@NonNull Comparator<? super DataType> comparator, @NonNull Consumer<? super DataType> action) {
|
||||
order(comparator).forEach(action);
|
||||
}
|
||||
|
||||
}
|
@ -23,21 +23,34 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.sponge.service.model;
|
||||
package me.lucko.luckperms.api.query.dataorder;
|
||||
|
||||
import me.lucko.luckperms.api.model.DataType;
|
||||
import me.lucko.luckperms.api.model.PermissionHolder;
|
||||
import me.lucko.luckperms.api.query.OptionKey;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* Defines in what order data should be resolved.
|
||||
* A function that generates a {@link DataQueryOrder} comparator for
|
||||
* {@link PermissionHolder}s as required during inheritance.
|
||||
*/
|
||||
public enum ResolutionOrder {
|
||||
public interface DataQueryOrderFunction {
|
||||
|
||||
/**
|
||||
* Marks that transient data should be considered before enduring data
|
||||
* The {@link OptionKey} for {@link DataQueryOrderFunction}.
|
||||
*/
|
||||
TRANSIENT_FIRST,
|
||||
OptionKey<DataQueryOrderFunction> KEY = new OptionKey<DataQueryOrderFunction>(){};
|
||||
|
||||
/**
|
||||
* Marks that transient data should be considered after enduring data
|
||||
* Gets the {@link DataQueryOrder} comparator for the given
|
||||
* {@link PermissionHolder.Identifier holder identifier}.
|
||||
*
|
||||
* @param holderIdentifier the holder identifier
|
||||
* @return the comparator to use
|
||||
*/
|
||||
TRANSIENT_LAST
|
||||
@NonNull Comparator<DataType> getOrderComparator(PermissionHolder.@NonNull Identifier holderIdentifier);
|
||||
|
||||
}
|
@ -29,7 +29,6 @@ import com.google.common.base.Preconditions;
|
||||
|
||||
import me.lucko.luckperms.api.model.DataType;
|
||||
import me.lucko.luckperms.api.node.Node;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadata;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadataKey;
|
||||
import me.lucko.luckperms.bukkit.inject.dummy.DummyPlugin;
|
||||
import me.lucko.luckperms.common.config.ConfigKeys;
|
||||
@ -53,7 +52,7 @@ import java.util.Set;
|
||||
*
|
||||
* Applies all permissions directly to the backing user instance via transient nodes.
|
||||
*/
|
||||
public class LPPermissionAttachment extends PermissionAttachment implements NodeMetadata {
|
||||
public class LPPermissionAttachment extends PermissionAttachment {
|
||||
|
||||
public static final NodeMetadataKey<LPPermissionAttachment> TRANSIENT_SOURCE_KEY = NodeMetadataKey.of("TransientSource", LPPermissionAttachment.class);
|
||||
|
||||
|
@ -25,8 +25,8 @@
|
||||
|
||||
package me.lucko.luckperms.common.api;
|
||||
|
||||
import me.lucko.luckperms.api.LuckPermsProvider;
|
||||
import me.lucko.luckperms.api.LuckPerms;
|
||||
import me.lucko.luckperms.api.LuckPermsProvider;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
|
@ -76,9 +76,8 @@ public class ApiGroup extends ApiPermissionHolder implements me.lucko.luckperms.
|
||||
return this.handle.getWeight();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public GroupCachedDataManager getCachedData() {
|
||||
public @NonNull GroupCachedDataManager getCachedData() {
|
||||
return this.handle.getCachedData();
|
||||
}
|
||||
|
||||
|
@ -72,8 +72,8 @@ public class ApiPermissionHolder implements me.lucko.luckperms.api.model.Permiss
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull String getObjectName() {
|
||||
return this.handle.getObjectName();
|
||||
public @NonNull Identifier getIdentifier() {
|
||||
return this.handle.getIdentifier();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -87,9 +87,8 @@ public class ApiUser extends ApiPermissionHolder implements me.lucko.luckperms.a
|
||||
return DataMutateResult.SUCCESS;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public UserCachedDataManager getCachedData() {
|
||||
public @NonNull UserCachedDataManager getCachedData() {
|
||||
return this.handle.getCachedData();
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,6 @@
|
||||
package me.lucko.luckperms.common.model;
|
||||
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
import me.lucko.luckperms.api.model.DataType;
|
||||
import me.lucko.luckperms.api.node.Node;
|
||||
import me.lucko.luckperms.api.node.types.DisplayNameNode;
|
||||
import me.lucko.luckperms.common.api.implementation.ApiGroup;
|
||||
@ -116,7 +115,7 @@ public class Group extends PermissionHolder implements Identifiable<String> {
|
||||
* @return the display name
|
||||
*/
|
||||
public Optional<String> getDisplayName(ContextSet contextSet) {
|
||||
for (Node n : getData(DataType.NORMAL).immutable().get(contextSet.immutableCopy())) {
|
||||
for (Node n : normalData().immutable().get(contextSet.immutableCopy())) {
|
||||
if (n instanceof DisplayNameNode) {
|
||||
return Optional.of(((DisplayNameNode) n).getDisplayName());
|
||||
}
|
||||
|
@ -43,6 +43,8 @@ import me.lucko.luckperms.api.node.Tristate;
|
||||
import me.lucko.luckperms.api.node.types.InheritanceNode;
|
||||
import me.lucko.luckperms.api.query.Flag;
|
||||
import me.lucko.luckperms.api.query.QueryOptions;
|
||||
import me.lucko.luckperms.api.query.dataorder.DataQueryOrder;
|
||||
import me.lucko.luckperms.api.query.dataorder.DataQueryOrderFunction;
|
||||
import me.lucko.luckperms.common.cacheddata.HolderCachedDataManager;
|
||||
import me.lucko.luckperms.common.cacheddata.type.MetaAccumulator;
|
||||
import me.lucko.luckperms.common.inheritance.InheritanceComparator;
|
||||
@ -175,6 +177,10 @@ public abstract class PermissionHolder {
|
||||
return this.transientNodes;
|
||||
}
|
||||
|
||||
public PermissionHolderIdentifier getIdentifier() {
|
||||
return new PermissionHolderIdentifier(getType(), getObjectName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the unique name of this holder object.
|
||||
*
|
||||
@ -234,22 +240,43 @@ public abstract class PermissionHolder {
|
||||
|
||||
public List<Node> getOwnNodes(QueryOptions queryOptions) {
|
||||
List<Node> ret = new ArrayList<>();
|
||||
this.transientNodes.copyTo(ret, queryOptions);
|
||||
this.normalNodes.copyTo(ret, queryOptions);
|
||||
|
||||
Comparator<DataType> comparator = queryOptions.option(DataQueryOrderFunction.KEY)
|
||||
.map(func -> func.getOrderComparator(getIdentifier()))
|
||||
.orElse(DataQueryOrder.TRANSIENT_FIRST);
|
||||
|
||||
for (DataType dataType : DataQueryOrder.order(comparator)) {
|
||||
getData(dataType).copyTo(ret, queryOptions);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public SortedSet<Node> getOwnNodesSorted(QueryOptions queryOptions) {
|
||||
SortedSet<Node> ret = new TreeSet<>(NodeWithContextComparator.reverse());
|
||||
this.transientNodes.copyTo(ret, queryOptions);
|
||||
this.normalNodes.copyTo(ret, queryOptions);
|
||||
|
||||
Comparator<DataType> comparator = queryOptions.option(DataQueryOrderFunction.KEY)
|
||||
.map(func -> func.getOrderComparator(getIdentifier()))
|
||||
.orElse(DataQueryOrder.TRANSIENT_FIRST);
|
||||
|
||||
for (DataType dataType : DataQueryOrder.order(comparator)) {
|
||||
getData(dataType).copyTo(ret, queryOptions);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<InheritanceNode> getOwnGroupNodes(QueryOptions queryOptions) {
|
||||
List<InheritanceNode> ret = new ArrayList<>();
|
||||
this.transientNodes.copyInheritanceNodesTo(ret, queryOptions);
|
||||
this.normalNodes.copyInheritanceNodesTo(ret, queryOptions);
|
||||
|
||||
Comparator<DataType> comparator = queryOptions.option(DataQueryOrderFunction.KEY)
|
||||
.map(func -> func.getOrderComparator(getIdentifier()))
|
||||
.orElse(DataQueryOrder.TRANSIENT_FIRST);
|
||||
|
||||
for (DataType dataType : DataQueryOrder.order(comparator)) {
|
||||
getData(dataType).copyInheritanceNodesTo(ret, queryOptions);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -23,14 +23,49 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.api.node.metadata;
|
||||
package me.lucko.luckperms.common.model;
|
||||
|
||||
import me.lucko.luckperms.api.node.Node;
|
||||
import me.lucko.luckperms.api.model.PermissionHolder.Identifier;
|
||||
|
||||
/**
|
||||
* Generic interface for an {@link Object} which can be attached to a
|
||||
* {@link Node} as metadata.
|
||||
*/
|
||||
public interface NodeMetadata {
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public final class PermissionHolderIdentifier implements Identifier {
|
||||
private final String type;
|
||||
private final String name;
|
||||
|
||||
public PermissionHolderIdentifier(String type, String name) {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public PermissionHolderIdentifier(HolderType type, String name) {
|
||||
this.type = type == HolderType.USER ? Identifier.USER_TYPE : Identifier.GROUP_TYPE;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull String getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof Identifier)) return false;
|
||||
Identifier that = (Identifier) o;
|
||||
return getType().equals(that.getType()) &&
|
||||
getName().equals(that.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(getType(), getName());
|
||||
}
|
||||
}
|
@ -33,7 +33,6 @@ import me.lucko.luckperms.api.node.Node;
|
||||
import me.lucko.luckperms.api.node.NodeBuilder;
|
||||
import me.lucko.luckperms.api.node.NodeEqualityPredicate;
|
||||
import me.lucko.luckperms.api.node.ScopedNode;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadata;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadataKey;
|
||||
import me.lucko.luckperms.api.node.types.RegexPermissionNode;
|
||||
import me.lucko.luckperms.common.node.utils.ShorthandParser;
|
||||
@ -63,14 +62,14 @@ public abstract class AbstractNode<N extends ScopedNode<N, B>, B extends NodeBui
|
||||
protected final boolean value;
|
||||
protected final long expireAt; // 0L for no expiry
|
||||
protected final ImmutableContextSet contexts;
|
||||
protected final Map<NodeMetadataKey<?>, NodeMetadata> metadata;
|
||||
protected final Map<NodeMetadataKey<?>, Object> metadata;
|
||||
|
||||
private final List<String> resolvedShorthand;
|
||||
|
||||
// this class is immutable, so we can cache the hashcode calculation
|
||||
private final int hashCode;
|
||||
|
||||
protected AbstractNode(String key, boolean value, long expireAt, ImmutableContextSet contexts, Map<NodeMetadataKey<?>, NodeMetadata> metadata) {
|
||||
protected AbstractNode(String key, boolean value, long expireAt, ImmutableContextSet contexts, Map<NodeMetadataKey<?>, Object> metadata) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
this.expireAt = expireAt;
|
||||
@ -98,7 +97,7 @@ public abstract class AbstractNode<N extends ScopedNode<N, B>, B extends NodeBui
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends NodeMetadata> Optional<T> getMetadata(NodeMetadataKey<T> key) {
|
||||
public <T> Optional<T> getMetadata(NodeMetadataKey<T> key) {
|
||||
//noinspection unchecked
|
||||
T value = (T) this.metadata.get(key);
|
||||
return Optional.ofNullable(value);
|
||||
|
@ -30,7 +30,6 @@ import me.lucko.luckperms.api.context.DefaultContextKeys;
|
||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||
import me.lucko.luckperms.api.node.NodeBuilder;
|
||||
import me.lucko.luckperms.api.node.ScopedNode;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadata;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadataKey;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
@ -44,7 +43,7 @@ public abstract class AbstractNodeBuilder<N extends ScopedNode<N, B>, B extends
|
||||
protected boolean value;
|
||||
protected long expireAt;
|
||||
protected ImmutableContextSet.Builder context;
|
||||
protected Map<NodeMetadataKey<?>, NodeMetadata> metadata;
|
||||
protected Map<NodeMetadataKey<?>, Object> metadata;
|
||||
|
||||
protected AbstractNodeBuilder() {
|
||||
this.value = true;
|
||||
@ -53,7 +52,7 @@ public abstract class AbstractNodeBuilder<N extends ScopedNode<N, B>, B extends
|
||||
this.metadata = new IdentityHashMap<>();
|
||||
}
|
||||
|
||||
protected AbstractNodeBuilder(boolean value, long expireAt, ImmutableContextSet context, Map<NodeMetadataKey<?>, NodeMetadata> metadata) {
|
||||
protected AbstractNodeBuilder(boolean value, long expireAt, ImmutableContextSet context, Map<NodeMetadataKey<?>, Object> metadata) {
|
||||
this.value = value;
|
||||
this.expireAt = expireAt;
|
||||
this.context = ImmutableContextSet.builder().addAll(context);
|
||||
@ -108,7 +107,7 @@ public abstract class AbstractNodeBuilder<N extends ScopedNode<N, B>, B extends
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull <T extends NodeMetadata> B withMetadata(@NonNull NodeMetadataKey<T> key, @Nullable T metadata) {
|
||||
public @NonNull <T> B withMetadata(@NonNull NodeMetadataKey<T> key, @Nullable T metadata) {
|
||||
Objects.requireNonNull(key, "key");
|
||||
if (metadata == null) {
|
||||
this.metadata.remove(key);
|
||||
|
@ -26,7 +26,6 @@
|
||||
package me.lucko.luckperms.common.node.types;
|
||||
|
||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadata;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadataKey;
|
||||
import me.lucko.luckperms.api.node.types.DisplayNameNode;
|
||||
import me.lucko.luckperms.common.node.AbstractNode;
|
||||
@ -41,7 +40,7 @@ import java.util.Objects;
|
||||
public class DisplayName extends AbstractNode<DisplayNameNode, DisplayNameNode.Builder> implements DisplayNameNode {
|
||||
private final String displayName;
|
||||
|
||||
public DisplayName(String displayName, boolean value, long expireAt, ImmutableContextSet contexts, Map<NodeMetadataKey<?>, NodeMetadata> metadata) {
|
||||
public DisplayName(String displayName, boolean value, long expireAt, ImmutableContextSet contexts, Map<NodeMetadataKey<?>, Object> metadata) {
|
||||
super(NodeFactory.displayName(displayName), value, expireAt, contexts, metadata);
|
||||
this.displayName = displayName;
|
||||
}
|
||||
@ -63,7 +62,7 @@ public class DisplayName extends AbstractNode<DisplayNameNode, DisplayNameNode.B
|
||||
this.displayName = null;
|
||||
}
|
||||
|
||||
public Builder(String displayName, boolean value, long expireAt, ImmutableContextSet context, Map<NodeMetadataKey<?>, NodeMetadata> metadata) {
|
||||
public Builder(String displayName, boolean value, long expireAt, ImmutableContextSet context, Map<NodeMetadataKey<?>, Object> metadata) {
|
||||
super(value, expireAt, context, metadata);
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ package me.lucko.luckperms.common.node.types;
|
||||
|
||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||
import me.lucko.luckperms.api.model.group.Group;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadata;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadataKey;
|
||||
import me.lucko.luckperms.api.node.types.InheritanceNode;
|
||||
import me.lucko.luckperms.common.node.AbstractNode;
|
||||
@ -42,7 +41,7 @@ import java.util.Objects;
|
||||
public class Inheritance extends AbstractNode<InheritanceNode, InheritanceNode.Builder> implements InheritanceNode {
|
||||
private final String groupName;
|
||||
|
||||
public Inheritance(String groupName, boolean value, long expireAt, ImmutableContextSet contexts, Map<NodeMetadataKey<?>, NodeMetadata> metadata) {
|
||||
public Inheritance(String groupName, boolean value, long expireAt, ImmutableContextSet contexts, Map<NodeMetadataKey<?>, Object> metadata) {
|
||||
super(NodeFactory.groupNode(groupName), value, expireAt, contexts, metadata);
|
||||
this.groupName = groupName;
|
||||
}
|
||||
@ -64,7 +63,7 @@ public class Inheritance extends AbstractNode<InheritanceNode, InheritanceNode.B
|
||||
this.groupName = null;
|
||||
}
|
||||
|
||||
public Builder(String groupName, boolean value, long expireAt, ImmutableContextSet context, Map<NodeMetadataKey<?>, NodeMetadata> metadata) {
|
||||
public Builder(String groupName, boolean value, long expireAt, ImmutableContextSet context, Map<NodeMetadataKey<?>, Object> metadata) {
|
||||
super(value, expireAt, context, metadata);
|
||||
this.groupName = groupName;
|
||||
}
|
||||
|
@ -26,7 +26,6 @@
|
||||
package me.lucko.luckperms.common.node.types;
|
||||
|
||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadata;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadataKey;
|
||||
import me.lucko.luckperms.api.node.types.MetaNode;
|
||||
import me.lucko.luckperms.common.node.AbstractNode;
|
||||
@ -42,7 +41,7 @@ public class Meta extends AbstractNode<MetaNode, MetaNode.Builder> implements Me
|
||||
private final String metaKey;
|
||||
private final String metaValue;
|
||||
|
||||
public Meta(String metaKey, String metaValue, boolean value, long expireAt, ImmutableContextSet contexts, Map<NodeMetadataKey<?>, NodeMetadata> metadata) {
|
||||
public Meta(String metaKey, String metaValue, boolean value, long expireAt, ImmutableContextSet contexts, Map<NodeMetadataKey<?>, Object> metadata) {
|
||||
super(NodeFactory.metaNode(metaKey, metaValue), value, expireAt, contexts, metadata);
|
||||
this.metaKey = metaKey;
|
||||
this.metaValue = metaValue;
|
||||
@ -72,7 +71,7 @@ public class Meta extends AbstractNode<MetaNode, MetaNode.Builder> implements Me
|
||||
this.metaValue = null;
|
||||
}
|
||||
|
||||
public Builder(String metaKey, String metaValue, boolean value, long expireAt, ImmutableContextSet context, Map<NodeMetadataKey<?>, NodeMetadata> metadata) {
|
||||
public Builder(String metaKey, String metaValue, boolean value, long expireAt, ImmutableContextSet context, Map<NodeMetadataKey<?>, Object> metadata) {
|
||||
super(value, expireAt, context, metadata);
|
||||
this.metaKey = metaKey;
|
||||
this.metaValue = metaValue;
|
||||
|
@ -27,7 +27,6 @@ package me.lucko.luckperms.common.node.types;
|
||||
|
||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||
import me.lucko.luckperms.api.node.NodeBuilder;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadata;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadataKey;
|
||||
import me.lucko.luckperms.api.node.types.PermissionNode;
|
||||
import me.lucko.luckperms.common.calculator.processor.WildcardProcessor;
|
||||
@ -44,7 +43,7 @@ import java.util.OptionalInt;
|
||||
public class Permission extends AbstractNode<PermissionNode, PermissionNode.Builder> implements PermissionNode {
|
||||
private final int wildcardLevel;
|
||||
|
||||
public Permission(String permission, boolean value, long expireAt, ImmutableContextSet contexts, Map<NodeMetadataKey<?>, NodeMetadata> metadata) {
|
||||
public Permission(String permission, boolean value, long expireAt, ImmutableContextSet contexts, Map<NodeMetadataKey<?>, Object> metadata) {
|
||||
super(permission, value, expireAt, contexts, metadata);
|
||||
this.wildcardLevel = permission.endsWith(WildcardProcessor.WILDCARD_SUFFIX) ? permission.chars().filter(num -> num == NODE_SEPARATOR_CODE).sum() : -1;
|
||||
}
|
||||
@ -76,7 +75,7 @@ public class Permission extends AbstractNode<PermissionNode, PermissionNode.Buil
|
||||
this.permission = null;
|
||||
}
|
||||
|
||||
public Builder(String permission, boolean value, long expireAt, ImmutableContextSet context, Map<NodeMetadataKey<?>, NodeMetadata> metadata) {
|
||||
public Builder(String permission, boolean value, long expireAt, ImmutableContextSet context, Map<NodeMetadataKey<?>, Object> metadata) {
|
||||
super(value, expireAt, context, metadata);
|
||||
this.permission = permission;
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ package me.lucko.luckperms.common.node.types;
|
||||
|
||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||
import me.lucko.luckperms.api.node.ChatMetaType;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadata;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadataKey;
|
||||
import me.lucko.luckperms.api.node.types.PrefixNode;
|
||||
import me.lucko.luckperms.common.node.AbstractNode;
|
||||
@ -43,7 +42,7 @@ public class Prefix extends AbstractNode<PrefixNode, PrefixNode.Builder> impleme
|
||||
private final String prefix;
|
||||
private final int priority;
|
||||
|
||||
public Prefix(String prefix, int priority, boolean value, long expireAt, ImmutableContextSet contexts, Map<NodeMetadataKey<?>, NodeMetadata> metadata) {
|
||||
public Prefix(String prefix, int priority, boolean value, long expireAt, ImmutableContextSet contexts, Map<NodeMetadataKey<?>, Object> metadata) {
|
||||
super(NodeFactory.prefixNode(priority, prefix), value, expireAt, contexts, metadata);
|
||||
this.prefix = prefix;
|
||||
this.priority = priority;
|
||||
@ -78,7 +77,7 @@ public class Prefix extends AbstractNode<PrefixNode, PrefixNode.Builder> impleme
|
||||
this.priority = null;
|
||||
}
|
||||
|
||||
public Builder(String prefix, int priority, boolean value, long expireAt, ImmutableContextSet context, Map<NodeMetadataKey<?>, NodeMetadata> metadata) {
|
||||
public Builder(String prefix, int priority, boolean value, long expireAt, ImmutableContextSet context, Map<NodeMetadataKey<?>, Object> metadata) {
|
||||
super(value, expireAt, context, metadata);
|
||||
this.prefix = prefix;
|
||||
this.priority = priority;
|
||||
|
@ -26,7 +26,6 @@
|
||||
package me.lucko.luckperms.common.node.types;
|
||||
|
||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadata;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadataKey;
|
||||
import me.lucko.luckperms.api.node.types.RegexPermissionNode;
|
||||
import me.lucko.luckperms.common.cache.Cache;
|
||||
@ -52,7 +51,7 @@ public class RegexPermission extends AbstractNode<RegexPermissionNode, RegexPerm
|
||||
}
|
||||
};
|
||||
|
||||
public RegexPermission(String pattern, boolean value, long expireAt, ImmutableContextSet contexts, Map<NodeMetadataKey<?>, NodeMetadata> metadata) {
|
||||
public RegexPermission(String pattern, boolean value, long expireAt, ImmutableContextSet contexts, Map<NodeMetadataKey<?>, Object> metadata) {
|
||||
super(NodeFactory.regexNode(pattern), value, expireAt, contexts, metadata);
|
||||
this.pattern = pattern;
|
||||
}
|
||||
@ -79,7 +78,7 @@ public class RegexPermission extends AbstractNode<RegexPermissionNode, RegexPerm
|
||||
this.pattern = null;
|
||||
}
|
||||
|
||||
public Builder(String pattern, boolean value, long expireAt, ImmutableContextSet context, Map<NodeMetadataKey<?>, NodeMetadata> metadata) {
|
||||
public Builder(String pattern, boolean value, long expireAt, ImmutableContextSet context, Map<NodeMetadataKey<?>, Object> metadata) {
|
||||
super(value, expireAt, context, metadata);
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ package me.lucko.luckperms.common.node.types;
|
||||
|
||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||
import me.lucko.luckperms.api.node.ChatMetaType;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadata;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadataKey;
|
||||
import me.lucko.luckperms.api.node.types.SuffixNode;
|
||||
import me.lucko.luckperms.common.node.AbstractNode;
|
||||
@ -43,7 +42,7 @@ public class Suffix extends AbstractNode<SuffixNode, SuffixNode.Builder> impleme
|
||||
private final String suffix;
|
||||
private final int priority;
|
||||
|
||||
public Suffix(String suffix, int priority, boolean value, long expireAt, ImmutableContextSet contexts, Map<NodeMetadataKey<?>, NodeMetadata> metadata) {
|
||||
public Suffix(String suffix, int priority, boolean value, long expireAt, ImmutableContextSet contexts, Map<NodeMetadataKey<?>, Object> metadata) {
|
||||
super(NodeFactory.suffixNode(priority, suffix), value, expireAt, contexts, metadata);
|
||||
this.suffix = suffix;
|
||||
this.priority = priority;
|
||||
@ -78,7 +77,7 @@ public class Suffix extends AbstractNode<SuffixNode, SuffixNode.Builder> impleme
|
||||
this.priority = null;
|
||||
}
|
||||
|
||||
public Builder(String suffix, int priority, boolean value, long expireAt, ImmutableContextSet context, Map<NodeMetadataKey<?>, NodeMetadata> metadata) {
|
||||
public Builder(String suffix, int priority, boolean value, long expireAt, ImmutableContextSet context, Map<NodeMetadataKey<?>, Object> metadata) {
|
||||
super(value, expireAt, context, metadata);
|
||||
this.suffix = suffix;
|
||||
this.priority = priority;
|
||||
|
@ -26,7 +26,6 @@
|
||||
package me.lucko.luckperms.common.node.types;
|
||||
|
||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadata;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadataKey;
|
||||
import me.lucko.luckperms.api.node.types.WeightNode;
|
||||
import me.lucko.luckperms.common.node.AbstractNode;
|
||||
@ -41,7 +40,7 @@ import java.util.Objects;
|
||||
public class Weight extends AbstractNode<WeightNode, WeightNode.Builder> implements WeightNode {
|
||||
private final int weight;
|
||||
|
||||
public Weight(int weight, boolean value, long expireAt, ImmutableContextSet contexts, Map<NodeMetadataKey<?>, NodeMetadata> metadata) {
|
||||
public Weight(int weight, boolean value, long expireAt, ImmutableContextSet contexts, Map<NodeMetadataKey<?>, Object> metadata) {
|
||||
super(NodeFactory.weightNode(weight), value, expireAt, contexts, metadata);
|
||||
this.weight = weight;
|
||||
}
|
||||
@ -63,7 +62,7 @@ public class Weight extends AbstractNode<WeightNode, WeightNode.Builder> impleme
|
||||
this.weight = null;
|
||||
}
|
||||
|
||||
public Builder(int weight, boolean value, long expireAt, ImmutableContextSet context, Map<NodeMetadataKey<?>, NodeMetadata> metadata) {
|
||||
public Builder(int weight, boolean value, long expireAt, ImmutableContextSet context, Map<NodeMetadataKey<?>, Object> metadata) {
|
||||
super(value, expireAt, context, metadata);
|
||||
this.weight = weight;
|
||||
}
|
||||
|
@ -29,7 +29,6 @@ import com.google.common.base.Preconditions;
|
||||
|
||||
import me.lucko.luckperms.api.model.DataType;
|
||||
import me.lucko.luckperms.api.node.Node;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadata;
|
||||
import me.lucko.luckperms.api.node.metadata.NodeMetadataKey;
|
||||
import me.lucko.luckperms.api.util.Result;
|
||||
import me.lucko.luckperms.common.config.ConfigKeys;
|
||||
@ -56,7 +55,7 @@ import java.util.Set;
|
||||
*
|
||||
* Applies all permissions directly to the backing user instance via transient nodes.
|
||||
*/
|
||||
public class LPPermissionAttachment extends PermissionAttachment implements NodeMetadata {
|
||||
public class LPPermissionAttachment extends PermissionAttachment {
|
||||
|
||||
public static final NodeMetadataKey<LPPermissionAttachment> TRANSIENT_SOURCE_KEY = NodeMetadataKey.of("TransientSource", LPPermissionAttachment.class);
|
||||
|
||||
|
@ -30,6 +30,7 @@ import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||
import me.lucko.luckperms.api.query.dataorder.DataQueryOrder;
|
||||
|
||||
import org.spongepowered.api.service.permission.SubjectCollection;
|
||||
|
||||
@ -52,11 +53,11 @@ public interface LPSubjectCollection {
|
||||
Predicate<String> getIdentifierValidityPredicate();
|
||||
|
||||
// transient has priority for all collections except default
|
||||
default ResolutionOrder getResolutionOrder() {
|
||||
default DataQueryOrder getResolutionOrder() {
|
||||
if (isDefaultsCollection()) {
|
||||
return ResolutionOrder.TRANSIENT_LAST;
|
||||
return DataQueryOrder.TRANSIENT_LAST;
|
||||
} else {
|
||||
return ResolutionOrder.TRANSIENT_FIRST;
|
||||
return DataQueryOrder.TRANSIENT_FIRST;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,6 @@ import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||
import me.lucko.luckperms.api.model.DataMutateResult;
|
||||
import me.lucko.luckperms.api.model.DataType;
|
||||
import me.lucko.luckperms.api.node.ChatMetaType;
|
||||
import me.lucko.luckperms.api.node.Node;
|
||||
@ -58,11 +57,9 @@ import org.spongepowered.api.service.permission.SubjectData;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class PermissionHolderSubjectData implements LPSubjectData {
|
||||
@ -129,54 +126,20 @@ public class PermissionHolderSubjectData implements LPSubjectData {
|
||||
if (tristate == Tristate.UNDEFINED) {
|
||||
// Unset
|
||||
Node node = NodeFactory.builder(permission).withContext(contexts).build();
|
||||
switch (this.type) {
|
||||
case NORMAL:
|
||||
this.holder.unsetPermission(DataType.NORMAL, node);
|
||||
break;
|
||||
case TRANSIENT:
|
||||
this.holder.unsetPermission(DataType.TRANSIENT, node);
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
this.holder.unsetPermission(this.type, node);
|
||||
return save(this.holder).thenApply(v -> true);
|
||||
}
|
||||
|
||||
Node node = NodeFactory.builder(permission).value(tristate.asBoolean()).withContext(contexts).build();
|
||||
// unset the inverse, to allow false -> true, true -> false overrides.
|
||||
// unset the inverse, to allow false -> true, true -> false overrides.
|
||||
switch (this.type) {
|
||||
case NORMAL:
|
||||
// unset the inverse, to allow false -> true, true -> false overrides.
|
||||
this.holder.unsetPermission(DataType.NORMAL, node);
|
||||
this.holder.setPermission(DataType.NORMAL, node, true);
|
||||
break;
|
||||
case TRANSIENT:
|
||||
// unset the inverse, to allow false -> true, true -> false overrides.
|
||||
this.holder.unsetPermission(DataType.TRANSIENT, node);
|
||||
this.holder.setPermission(DataType.TRANSIENT, node, true);
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
this.holder.unsetPermission(this.type, node);
|
||||
this.holder.setPermission(this.type, node, true);
|
||||
return save(this.holder).thenApply(v -> true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> clearPermissions() {
|
||||
boolean ret;
|
||||
switch (this.type) {
|
||||
case NORMAL:
|
||||
ret = this.holder.clearNodes(DataType.NORMAL, null);
|
||||
break;
|
||||
case TRANSIENT:
|
||||
ret = this.holder.clearNodes(DataType.TRANSIENT, null);
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
if (!this.holder.clearNodes(this.type, null)) {
|
||||
return CompletableFuture.completedFuture(false);
|
||||
}
|
||||
|
||||
@ -190,24 +153,7 @@ public class PermissionHolderSubjectData implements LPSubjectData {
|
||||
@Override
|
||||
public CompletableFuture<Boolean> clearPermissions(ImmutableContextSet contexts) {
|
||||
Objects.requireNonNull(contexts, "contexts");
|
||||
boolean ret;
|
||||
switch (this.type) {
|
||||
case NORMAL:
|
||||
ret = this.holder.clearNodes(DataType.NORMAL, contexts);
|
||||
break;
|
||||
case TRANSIENT:
|
||||
List<Node> toRemove = streamNodes()
|
||||
.filter(n -> n.getContexts().equals(contexts))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
toRemove.forEach(node -> this.holder.unsetPermission(DataType.TRANSIENT, node));
|
||||
ret = !toRemove.isEmpty();
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
if (!this.holder.clearNodes(this.type, contexts)) {
|
||||
return CompletableFuture.completedFuture(false);
|
||||
}
|
||||
|
||||
@ -257,19 +203,7 @@ public class PermissionHolderSubjectData implements LPSubjectData {
|
||||
.withContext(contexts)
|
||||
.build();
|
||||
|
||||
DataMutateResult result;
|
||||
switch (this.type) {
|
||||
case NORMAL:
|
||||
result = this.holder.setPermission(DataType.NORMAL, node, true);
|
||||
break;
|
||||
case TRANSIENT:
|
||||
result = this.holder.setPermission(DataType.TRANSIENT, node, true);
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
if (!result.wasSuccessful()) {
|
||||
if (!this.holder.setPermission(this.type, node, true).wasSuccessful()) {
|
||||
return CompletableFuture.completedFuture(false);
|
||||
}
|
||||
|
||||
@ -289,19 +223,7 @@ public class PermissionHolderSubjectData implements LPSubjectData {
|
||||
.withContext(contexts)
|
||||
.build();
|
||||
|
||||
DataMutateResult result;
|
||||
switch (this.type) {
|
||||
case NORMAL:
|
||||
result = this.holder.unsetPermission(DataType.NORMAL, node);
|
||||
break;
|
||||
case TRANSIENT:
|
||||
result = this.holder.unsetPermission(DataType.TRANSIENT, node);
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
if (!result.wasSuccessful()) {
|
||||
if (!this.holder.unsetPermission(this.type, node).wasSuccessful()) {
|
||||
return CompletableFuture.completedFuture(false);
|
||||
}
|
||||
|
||||
@ -316,12 +238,10 @@ public class PermissionHolderSubjectData implements LPSubjectData {
|
||||
ret = this.holder.clearNormalParents(null, true);
|
||||
break;
|
||||
case TRANSIENT:
|
||||
List<Node> toRemove = streamNodes()
|
||||
ret = streamNodes()
|
||||
.filter(n -> n instanceof InheritanceNode)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
toRemove.forEach(node -> this.holder.unsetPermission(DataType.TRANSIENT, node));
|
||||
ret = !toRemove.isEmpty();
|
||||
.peek(n -> this.holder.unsetPermission(DataType.TRANSIENT, n))
|
||||
.findAny().isPresent();
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
@ -343,13 +263,11 @@ public class PermissionHolderSubjectData implements LPSubjectData {
|
||||
ret = this.holder.clearNormalParents(contexts, true);
|
||||
break;
|
||||
case TRANSIENT:
|
||||
List<Node> toRemove = streamNodes()
|
||||
ret = streamNodes()
|
||||
.filter(n -> n instanceof InheritanceNode)
|
||||
.filter(n -> n.getContexts().equals(contexts))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
toRemove.forEach(node -> this.holder.unsetPermission(DataType.TRANSIENT, node));
|
||||
ret = !toRemove.isEmpty();
|
||||
.peek(n -> this.holder.unsetPermission(DataType.TRANSIENT, n))
|
||||
.findAny().isPresent();
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
@ -425,20 +343,9 @@ public class PermissionHolderSubjectData implements LPSubjectData {
|
||||
|
||||
// remove all prefixes/suffixes from the user
|
||||
streamNodes()
|
||||
.filter(node1 -> type.nodeType().matches(node1))
|
||||
.filter(n -> type.nodeType().matches(n))
|
||||
.filter(n -> n.getContexts().equals(contexts))
|
||||
.forEach(n -> {
|
||||
switch (this.type) {
|
||||
case NORMAL:
|
||||
this.holder.unsetPermission(DataType.NORMAL, n);
|
||||
break;
|
||||
case TRANSIENT:
|
||||
this.holder.unsetPermission(DataType.TRANSIENT, n);
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
});
|
||||
.forEach(n -> this.holder.unsetPermission(this.type, n));
|
||||
|
||||
MetaAccumulator metaAccumulator = this.holder.accumulateMeta(null, QueryOptions.defaultContextualOptions().toBuilder().context(contexts).build());
|
||||
metaAccumulator.complete();
|
||||
@ -451,32 +358,12 @@ public class PermissionHolderSubjectData implements LPSubjectData {
|
||||
streamNodes()
|
||||
.filter(n -> n instanceof MetaNode && ((MetaNode) n).getMetaKey().equals(key))
|
||||
.filter(n -> n.getContexts().equals(contexts))
|
||||
.forEach(n -> {
|
||||
switch (this.type) {
|
||||
case NORMAL:
|
||||
this.holder.unsetPermission(DataType.NORMAL, n);
|
||||
break;
|
||||
case TRANSIENT:
|
||||
this.holder.unsetPermission(DataType.TRANSIENT, n);
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
});
|
||||
.forEach(n -> this.holder.unsetPermission(this.type, n));
|
||||
|
||||
node = NodeFactory.buildMetaNode(key, value).withContext(contexts).build();
|
||||
}
|
||||
|
||||
switch (this.type) {
|
||||
case NORMAL:
|
||||
this.holder.setPermission(DataType.NORMAL, node, true);
|
||||
break;
|
||||
case TRANSIENT:
|
||||
this.holder.setPermission(DataType.TRANSIENT, node, true);
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
this.holder.setPermission(this.type, node, true);
|
||||
return save(this.holder).thenApply(v -> true);
|
||||
}
|
||||
|
||||
@ -496,18 +383,7 @@ public class PermissionHolderSubjectData implements LPSubjectData {
|
||||
}
|
||||
})
|
||||
.filter(n -> n.getContexts().equals(contexts))
|
||||
.forEach(node -> {
|
||||
switch (this.type) {
|
||||
case NORMAL:
|
||||
this.holder.unsetPermission(DataType.NORMAL, node);
|
||||
break;
|
||||
case TRANSIENT:
|
||||
this.holder.unsetPermission(DataType.TRANSIENT, node);
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
});
|
||||
.forEach(n -> this.holder.unsetPermission(this.type, n));
|
||||
|
||||
return save(this.holder).thenApply(v -> true);
|
||||
}
|
||||
@ -516,25 +392,13 @@ public class PermissionHolderSubjectData implements LPSubjectData {
|
||||
public CompletableFuture<Boolean> clearOptions(ImmutableContextSet contexts) {
|
||||
Objects.requireNonNull(contexts, "contexts");
|
||||
|
||||
List<Node> toRemove = streamNodes()
|
||||
boolean success = streamNodes()
|
||||
.filter(NodeType.META_OR_CHAT_META::matches)
|
||||
.filter(n -> n.getContexts().equals(contexts))
|
||||
.collect(Collectors.toList());
|
||||
.peek(n -> this.holder.unsetPermission(this.type, n))
|
||||
.findAny().isPresent();
|
||||
|
||||
toRemove.forEach(node -> {
|
||||
switch (this.type) {
|
||||
case NORMAL:
|
||||
this.holder.unsetPermission(DataType.NORMAL, node);
|
||||
break;
|
||||
case TRANSIENT:
|
||||
this.holder.unsetPermission(DataType.TRANSIENT, node);
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
});
|
||||
|
||||
if (toRemove.isEmpty()) {
|
||||
if (!success) {
|
||||
return CompletableFuture.completedFuture(false);
|
||||
}
|
||||
|
||||
@ -543,24 +407,12 @@ public class PermissionHolderSubjectData implements LPSubjectData {
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> clearOptions() {
|
||||
List<Node> toRemove = streamNodes()
|
||||
boolean success = streamNodes()
|
||||
.filter(NodeType.META_OR_CHAT_META::matches)
|
||||
.collect(Collectors.toList());
|
||||
.peek(n -> this.holder.unsetPermission(this.type, n))
|
||||
.findAny().isPresent();
|
||||
|
||||
toRemove.forEach(node -> {
|
||||
switch (this.type) {
|
||||
case NORMAL:
|
||||
this.holder.unsetPermission(DataType.NORMAL, node);
|
||||
break;
|
||||
case TRANSIENT:
|
||||
this.holder.unsetPermission(DataType.TRANSIENT, node);
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
});
|
||||
|
||||
if (toRemove.isEmpty()) {
|
||||
if (!success) {
|
||||
return CompletableFuture.completedFuture(false);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user