mirror of
https://github.com/LuckPerms/LuckPerms.git
synced 2024-12-29 12:37:40 +01:00
Add UserManager/GroupManager searchAll method
This commit is contained in:
parent
1af55e3720
commit
7ae532f082
@ -39,6 +39,7 @@ import net.luckperms.api.model.group.GroupManager;
|
||||
import net.luckperms.api.model.user.User;
|
||||
import net.luckperms.api.model.user.UserManager;
|
||||
import net.luckperms.api.node.NodeBuilderRegistry;
|
||||
import net.luckperms.api.node.matcher.NodeMatcherFactory;
|
||||
import net.luckperms.api.platform.Platform;
|
||||
import net.luckperms.api.platform.PluginMetadata;
|
||||
import net.luckperms.api.query.QueryOptionsRegistry;
|
||||
@ -192,6 +193,14 @@ public interface LuckPerms {
|
||||
*/
|
||||
@NonNull MetaStackFactory getMetaStackFactory();
|
||||
|
||||
/**
|
||||
* Gets the {@link NodeMatcherFactory}.
|
||||
*
|
||||
* @return the node matcher factory
|
||||
* @since 5.1
|
||||
*/
|
||||
@NonNull NodeMatcherFactory getNodeMatcherFactory();
|
||||
|
||||
/**
|
||||
* Schedules the execution of an update task, and returns an encapsulation
|
||||
* of the task as a {@link CompletableFuture}.
|
||||
|
@ -26,11 +26,15 @@
|
||||
package net.luckperms.api.model.group;
|
||||
|
||||
import net.luckperms.api.node.HeldNode;
|
||||
import net.luckperms.api.node.Node;
|
||||
import net.luckperms.api.node.matcher.NodeMatcher;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@ -105,13 +109,25 @@ public interface GroupManager {
|
||||
*/
|
||||
@NonNull CompletableFuture<Void> loadAllGroups();
|
||||
|
||||
/**
|
||||
* Searches the {@link Group#data() normal node maps} of all known {@link Group}s for {@link Node}
|
||||
* entries matching the given {@link NodeMatcher matcher}.
|
||||
*
|
||||
* @param matcher the matcher
|
||||
* @return the entries which matched
|
||||
* @since 5.1
|
||||
*/
|
||||
@NonNull <T extends Node> CompletableFuture<Map<String, Collection<T>>> searchAll(@NonNull NodeMatcher<? extends T> matcher);
|
||||
|
||||
/**
|
||||
* Searches for a list of groups with a given permission.
|
||||
*
|
||||
* @param permission the permission to search for
|
||||
* @return a list of held permissions, or null if the operation failed
|
||||
* @throws NullPointerException if the permission is null
|
||||
* @deprecated use {@link #searchAll(NodeMatcher)}
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull CompletableFuture<List<HeldNode<String>>> getWithPermission(@NonNull String permission);
|
||||
|
||||
/**
|
||||
|
@ -27,11 +27,15 @@ package net.luckperms.api.model.user;
|
||||
|
||||
import net.luckperms.api.model.PlayerSaveResult;
|
||||
import net.luckperms.api.node.HeldNode;
|
||||
import net.luckperms.api.node.Node;
|
||||
import net.luckperms.api.node.matcher.NodeMatcher;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@ -131,13 +135,25 @@ public interface UserManager {
|
||||
*/
|
||||
@NonNull CompletableFuture<Set<UUID>> getUniqueUsers();
|
||||
|
||||
/**
|
||||
* Searches the {@link User#data() normal node maps} of all known {@link User}s for {@link Node}
|
||||
* entries matching the given {@link NodeMatcher matcher}.
|
||||
*
|
||||
* @param matcher the matcher
|
||||
* @return the entries which matched
|
||||
* @since 5.1
|
||||
*/
|
||||
@NonNull <T extends Node> CompletableFuture<Map<UUID, Collection<T>>> searchAll(@NonNull NodeMatcher<? extends T> matcher);
|
||||
|
||||
/**
|
||||
* Searches for a list of users with a given permission.
|
||||
*
|
||||
* @param permission the permission to search for
|
||||
* @return a list of held permissions
|
||||
* @throws NullPointerException if the permission is null
|
||||
* @deprecated use {@link #searchAll(NodeMatcher)}
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull CompletableFuture<List<HeldNode<UUID>>> getWithPermission(@NonNull String permission);
|
||||
|
||||
/**
|
||||
|
@ -34,6 +34,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
*
|
||||
* @param <T> the identifier type of the holder
|
||||
*/
|
||||
@Deprecated
|
||||
public interface HeldNode<T> {
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* 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 net.luckperms.api.node.matcher;
|
||||
|
||||
import net.luckperms.api.LuckPerms;
|
||||
import net.luckperms.api.LuckPermsProvider;
|
||||
import net.luckperms.api.node.Node;
|
||||
import net.luckperms.api.node.NodeEqualityPredicate;
|
||||
import net.luckperms.api.node.NodeType;
|
||||
import net.luckperms.api.node.types.MetaNode;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* A predicate which matches certain {@link Node}s.
|
||||
*
|
||||
* @param <T> the node type matched
|
||||
* @since 5.1
|
||||
*/
|
||||
public interface NodeMatcher<T extends Node> extends Predicate<Node> {
|
||||
|
||||
/**
|
||||
* Gets a {@link NodeMatcher} which matches nodes with the same {@link Node#getKey() key}.
|
||||
*
|
||||
* <p>The {@link String#equalsIgnoreCase(String)} method is used to test key equality.</p>
|
||||
*
|
||||
* @param key the key
|
||||
* @return the matcher
|
||||
*/
|
||||
static @NonNull NodeMatcher<Node> key(@NonNull String key) {
|
||||
return LuckPermsProvider.get().getNodeMatcherFactory().key(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a {@link NodeMatcher} which matches nodes with the same {@link Node#getKey() key}.
|
||||
*
|
||||
* <p>The {@link String#equalsIgnoreCase(String)} method is used to test key equality.</p>
|
||||
*
|
||||
* @param node the node to use for the key
|
||||
* @param <T> the node type
|
||||
* @return the matcher
|
||||
*/
|
||||
static <T extends Node> @NonNull NodeMatcher<T> key(@NonNull T node) {
|
||||
return LuckPermsProvider.get().getNodeMatcherFactory().key(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a {@link NodeMatcher} which matches nodes with a {@link Node#getKey() key} starting
|
||||
* with the given string.
|
||||
*
|
||||
* @param startingWith the string to match
|
||||
* @return the matcher
|
||||
*/
|
||||
static @NonNull NodeMatcher<Node> keyStartsWith(@NonNull String startingWith) {
|
||||
return LuckPermsProvider.get().getNodeMatcherFactory().keyStartsWith(startingWith);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a {@link NodeMatcher} which matches nodes which are
|
||||
* {@link Node#equals(Node, NodeEqualityPredicate) equal to} the given {@code other} node
|
||||
* according to the {@link NodeEqualityPredicate}.
|
||||
*
|
||||
* @param other the other node to test against
|
||||
* @param equalityPredicate the equality predicate
|
||||
* @param <T> the node type
|
||||
* @return the matcher
|
||||
*/
|
||||
static <T extends Node> @NonNull NodeMatcher<T> equals(@NonNull T other, @NonNull NodeEqualityPredicate equalityPredicate) {
|
||||
return LuckPermsProvider.get().getNodeMatcherFactory().equals(other, equalityPredicate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a {@link NodeMatcher} which matches {@link MetaNode}s with the same
|
||||
* {@link MetaNode#getMetaKey() meta key}.
|
||||
*
|
||||
* <p>The {@link String#equalsIgnoreCase(String)} method is used to test key equality.</p>
|
||||
*
|
||||
* @param metaKey the meta key
|
||||
* @return the matcher
|
||||
*/
|
||||
static @NonNull NodeMatcher<MetaNode> metaKey(@NonNull String metaKey) {
|
||||
return LuckPermsProvider.get().getNodeMatcherFactory().metaKey(metaKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a {@link NodeMatcher} which matches {@link MetaNode}s with the same
|
||||
* {@link MetaNode#getMetaKey() meta key}.
|
||||
*
|
||||
* <p>The {@link String#equalsIgnoreCase(String)} method is used to test key equality.</p>
|
||||
*
|
||||
* @param metaNode the meta node to use for the meta key
|
||||
* @return the matcher
|
||||
*/
|
||||
static @NonNull NodeMatcher<MetaNode> metaKey(@NonNull MetaNode metaNode) {
|
||||
return metaKey(metaNode.getMetaKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a {@link NodeMatcher} which matches {@link Node}s with the same
|
||||
* type as the given {@link NodeType}.
|
||||
*
|
||||
* <p>{@link NodeType#PERMISSION}, {@link NodeType#CHAT_META} and
|
||||
* {@link NodeType#META_OR_CHAT_META} are not supported by this method.</p>
|
||||
*
|
||||
* @param type the node type
|
||||
* @param <T> the node type
|
||||
* @return the matcher
|
||||
*/
|
||||
static <T extends Node> @NonNull NodeMatcher<T> type(NodeType<? extends T> type) {
|
||||
return LuckPermsProvider.get().getNodeMatcherFactory().type(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests to see if the given {@link Node} matches.
|
||||
*
|
||||
* @param node the node to test
|
||||
* @return true if the node matched
|
||||
*/
|
||||
@Override
|
||||
boolean test(@NonNull Node node);
|
||||
}
|
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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 net.luckperms.api.node.matcher;
|
||||
|
||||
import net.luckperms.api.node.Node;
|
||||
import net.luckperms.api.node.NodeEqualityPredicate;
|
||||
import net.luckperms.api.node.NodeType;
|
||||
import net.luckperms.api.node.types.MetaNode;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
/**
|
||||
* A factory which creates {@link NodeMatcher}s.
|
||||
*
|
||||
* @since 5.1
|
||||
*/
|
||||
public interface NodeMatcherFactory {
|
||||
|
||||
/**
|
||||
* Gets a {@link NodeMatcher} which matches nodes with the same {@link Node#getKey() key}.
|
||||
*
|
||||
* <p>The {@link String#equalsIgnoreCase(String)} method is used to test key equality.</p>
|
||||
*
|
||||
* <p>Prefer using the {@link NodeMatcher#key(String)} accessor.</p>
|
||||
*
|
||||
* @param key the key
|
||||
* @return the matcher
|
||||
*/
|
||||
@NonNull NodeMatcher<Node> key(@NonNull String key);
|
||||
|
||||
/**
|
||||
* Gets a {@link NodeMatcher} which matches nodes with the same {@link Node#getKey() key}.
|
||||
*
|
||||
* <p>The {@link String#equalsIgnoreCase(String)} method is used to test key equality.</p>
|
||||
*
|
||||
* <p>Prefer using the {@link NodeMatcher#key(Node)} accessor.</p>
|
||||
*
|
||||
* @param node the node to use for the key
|
||||
* @param <T> the node type
|
||||
* @return the matcher
|
||||
*/
|
||||
<T extends Node> @NonNull NodeMatcher<T> key(@NonNull T node);
|
||||
|
||||
/**
|
||||
* Gets a {@link NodeMatcher} which matches nodes with a {@link Node#getKey() key} starting
|
||||
* with the given string.
|
||||
*
|
||||
* <p>Prefer using the {@link NodeMatcher#keyStartsWith(String)} accessor.</p>
|
||||
*
|
||||
* @param startingWith the string to match
|
||||
* @return the matcher
|
||||
*/
|
||||
@NonNull NodeMatcher<Node> keyStartsWith(@NonNull String startingWith);
|
||||
|
||||
/**
|
||||
* Gets a {@link NodeMatcher} which matches nodes which are
|
||||
* {@link Node#equals(Node, NodeEqualityPredicate) equal to} the given {@code other} node
|
||||
* according to the {@link NodeEqualityPredicate}.
|
||||
*
|
||||
* <p>Prefer using the {@link NodeMatcher#equals(Node, NodeEqualityPredicate)} accessor.</p>
|
||||
*
|
||||
* @param other the other node to test against
|
||||
* @param equalityPredicate the equality predicate
|
||||
* @param <T> the node type
|
||||
* @return the matcher
|
||||
*/
|
||||
@NonNull <T extends Node> NodeMatcher<T> equals(@NonNull T other, @NonNull NodeEqualityPredicate equalityPredicate);
|
||||
|
||||
/**
|
||||
* Gets a {@link NodeMatcher} which matches {@link MetaNode}s with the same
|
||||
* {@link MetaNode#getMetaKey() meta key}.
|
||||
*
|
||||
* <p>The {@link String#equalsIgnoreCase(String)} method is used to test key equality.</p>
|
||||
*
|
||||
* <p>Prefer using the {@link NodeMatcher#metaKey(String)} accessor.</p>
|
||||
*
|
||||
* @param metaKey the meta key
|
||||
* @return the matcher
|
||||
*/
|
||||
@NonNull NodeMatcher<MetaNode> metaKey(@NonNull String metaKey);
|
||||
|
||||
/**
|
||||
* Gets a {@link NodeMatcher} which matches {@link Node}s with the same
|
||||
* type as the given {@link NodeType}.
|
||||
*
|
||||
* <p>{@link NodeType#PERMISSION}, {@link NodeType#CHAT_META} and
|
||||
* {@link NodeType#META_OR_CHAT_META} are not supported by this method.</p>
|
||||
*
|
||||
* <p>Prefer using the {@link NodeMatcher#type(NodeType)} accessor.</p>
|
||||
*
|
||||
* @param type the node type
|
||||
* @param <T> the node type
|
||||
* @return the matcher
|
||||
*/
|
||||
<T extends Node> @NonNull NodeMatcher<T> type(NodeType<? extends T> type);
|
||||
|
||||
}
|
@ -31,6 +31,7 @@ import me.lucko.luckperms.common.api.implementation.ApiGroupManager;
|
||||
import me.lucko.luckperms.common.api.implementation.ApiMessagingService;
|
||||
import me.lucko.luckperms.common.api.implementation.ApiMetaStackFactory;
|
||||
import me.lucko.luckperms.common.api.implementation.ApiNodeBuilderRegistry;
|
||||
import me.lucko.luckperms.common.api.implementation.ApiNodeMatcherFactory;
|
||||
import me.lucko.luckperms.common.api.implementation.ApiPlatform;
|
||||
import me.lucko.luckperms.common.api.implementation.ApiQueryOptionsRegistry;
|
||||
import me.lucko.luckperms.common.api.implementation.ApiTrackManager;
|
||||
@ -49,6 +50,7 @@ import net.luckperms.api.metastacking.MetaStackFactory;
|
||||
import net.luckperms.api.model.group.GroupManager;
|
||||
import net.luckperms.api.model.user.UserManager;
|
||||
import net.luckperms.api.node.NodeBuilderRegistry;
|
||||
import net.luckperms.api.node.matcher.NodeMatcherFactory;
|
||||
import net.luckperms.api.platform.Platform;
|
||||
import net.luckperms.api.platform.PluginMetadata;
|
||||
import net.luckperms.api.query.QueryOptionsRegistry;
|
||||
@ -163,4 +165,9 @@ public class LuckPermsApiProvider implements LuckPerms {
|
||||
return this.metaStackFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull NodeMatcherFactory getNodeMatcherFactory() {
|
||||
return ApiNodeMatcherFactory.INSTANCE;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -25,21 +25,28 @@
|
||||
|
||||
package me.lucko.luckperms.common.api.implementation;
|
||||
|
||||
import com.google.common.collect.ImmutableListMultimap;
|
||||
|
||||
import me.lucko.luckperms.common.api.ApiUtils;
|
||||
import me.lucko.luckperms.common.bulkupdate.comparison.Constraint;
|
||||
import me.lucko.luckperms.common.bulkupdate.comparison.StandardComparison;
|
||||
import me.lucko.luckperms.common.model.Group;
|
||||
import me.lucko.luckperms.common.model.manager.group.GroupManager;
|
||||
import me.lucko.luckperms.common.node.matcher.ConstraintNodeMatcher;
|
||||
import me.lucko.luckperms.common.node.matcher.StandardNodeMatchers;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.storage.misc.NodeEntry;
|
||||
import me.lucko.luckperms.common.util.ImmutableCollectors;
|
||||
|
||||
import net.luckperms.api.event.cause.CreationCause;
|
||||
import net.luckperms.api.event.cause.DeletionCause;
|
||||
import net.luckperms.api.node.HeldNode;
|
||||
import net.luckperms.api.node.Node;
|
||||
import net.luckperms.api.node.matcher.NodeMatcher;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
@ -89,10 +96,26 @@ public class ApiGroupManager extends ApiAbstractManager<Group, net.luckperms.api
|
||||
return this.plugin.getStorage().loadAllGroups();
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
@Override
|
||||
@Deprecated
|
||||
public @NonNull CompletableFuture<List<HeldNode<String>>> getWithPermission(@NonNull String permission) {
|
||||
Objects.requireNonNull(permission, "permission");
|
||||
return this.plugin.getStorage().getGroupsWithPermission(Constraint.of(StandardComparison.EQUAL, permission));
|
||||
return (CompletableFuture) this.plugin.getStorage().getUsersWithPermission(StandardNodeMatchers.key(permission));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public @NonNull <T extends Node> CompletableFuture<Map<String, Collection<T>>> searchAll(@NonNull NodeMatcher<? extends T> matcher) {
|
||||
Objects.requireNonNull(matcher, "matcher");
|
||||
ConstraintNodeMatcher<? extends T> constraint = (ConstraintNodeMatcher<? extends T>) matcher;
|
||||
return this.plugin.getStorage().getGroupsWithPermission(constraint).thenApply(list -> {
|
||||
ImmutableListMultimap.Builder<String, T> builder = ImmutableListMultimap.builder();
|
||||
for (NodeEntry<String, ? extends T> row : list) {
|
||||
builder.put(row.getHolder(), row.getNode());
|
||||
}
|
||||
return builder.build().asMap();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.api.implementation;
|
||||
|
||||
import me.lucko.luckperms.common.node.matcher.StandardNodeMatchers;
|
||||
|
||||
import net.luckperms.api.node.Node;
|
||||
import net.luckperms.api.node.NodeEqualityPredicate;
|
||||
import net.luckperms.api.node.NodeType;
|
||||
import net.luckperms.api.node.matcher.NodeMatcher;
|
||||
import net.luckperms.api.node.matcher.NodeMatcherFactory;
|
||||
import net.luckperms.api.node.types.MetaNode;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public final class ApiNodeMatcherFactory implements NodeMatcherFactory {
|
||||
public static final ApiNodeMatcherFactory INSTANCE = new ApiNodeMatcherFactory();
|
||||
|
||||
private ApiNodeMatcherFactory() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull NodeMatcher<Node> key(@NonNull String key) {
|
||||
Objects.requireNonNull(key, "key");
|
||||
return StandardNodeMatchers.key(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull <T extends Node> NodeMatcher<T> key(@NonNull T node) {
|
||||
return StandardNodeMatchers.key(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull NodeMatcher<Node> keyStartsWith(@NonNull String startingWith) {
|
||||
Objects.requireNonNull(startingWith, "startingWith");
|
||||
return StandardNodeMatchers.keyStartsWith(startingWith);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Node> @NonNull NodeMatcher<T> equals(@NonNull T other, @NonNull NodeEqualityPredicate equalityPredicate) {
|
||||
Objects.requireNonNull(other, "other");
|
||||
Objects.requireNonNull(equalityPredicate, "equalityPredicate");
|
||||
return StandardNodeMatchers.equals(other, equalityPredicate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull NodeMatcher<MetaNode> metaKey(@NonNull String metaKey) {
|
||||
Objects.requireNonNull(metaKey, "metaKey");
|
||||
return StandardNodeMatchers.metaKey(metaKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull <T extends Node> NodeMatcher<T> type(NodeType<? extends T> type) {
|
||||
Objects.requireNonNull(type, "type");
|
||||
return StandardNodeMatchers.type(type);
|
||||
}
|
||||
}
|
@ -25,21 +25,28 @@
|
||||
|
||||
package me.lucko.luckperms.common.api.implementation;
|
||||
|
||||
import com.google.common.collect.ImmutableListMultimap;
|
||||
|
||||
import me.lucko.luckperms.common.api.ApiUtils;
|
||||
import me.lucko.luckperms.common.bulkupdate.comparison.Constraint;
|
||||
import me.lucko.luckperms.common.bulkupdate.comparison.StandardComparison;
|
||||
import me.lucko.luckperms.common.model.User;
|
||||
import me.lucko.luckperms.common.model.manager.user.UserManager;
|
||||
import me.lucko.luckperms.common.node.matcher.ConstraintNodeMatcher;
|
||||
import me.lucko.luckperms.common.node.matcher.StandardNodeMatchers;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.storage.misc.NodeEntry;
|
||||
import me.lucko.luckperms.common.util.ImmutableCollectors;
|
||||
|
||||
import net.luckperms.api.model.PlayerSaveResult;
|
||||
import net.luckperms.api.node.HeldNode;
|
||||
import net.luckperms.api.node.Node;
|
||||
import net.luckperms.api.node.matcher.NodeMatcher;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
@ -98,10 +105,26 @@ public class ApiUserManager extends ApiAbstractManager<User, net.luckperms.api.m
|
||||
return this.plugin.getStorage().getUniqueUsers();
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
@Override
|
||||
@Deprecated
|
||||
public @NonNull CompletableFuture<List<HeldNode<UUID>>> getWithPermission(@NonNull String permission) {
|
||||
Objects.requireNonNull(permission, "permission");
|
||||
return this.plugin.getStorage().getUsersWithPermission(Constraint.of(StandardComparison.EQUAL, permission));
|
||||
return (CompletableFuture) this.plugin.getStorage().getUsersWithPermission(StandardNodeMatchers.key(permission));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T extends Node> @NonNull CompletableFuture<Map<UUID, Collection<T>>> searchAll(@NonNull NodeMatcher<? extends T> matcher) {
|
||||
Objects.requireNonNull(matcher, "matcher");
|
||||
ConstraintNodeMatcher<? extends T> constraint = (ConstraintNodeMatcher<? extends T>) matcher;
|
||||
return this.plugin.getStorage().getUsersWithPermission(constraint).thenApply(list -> {
|
||||
ImmutableListMultimap.Builder<UUID, T> builder = ImmutableListMultimap.builder();
|
||||
for (NodeEntry<UUID, ? extends T> row : list) {
|
||||
builder.put(row.getHolder(), row.getNode());
|
||||
}
|
||||
return builder.build().asMap();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -64,6 +64,9 @@ public enum StandardComparison implements Comparison {
|
||||
}
|
||||
};
|
||||
|
||||
public static final String WILDCARD = "%";
|
||||
public static final String WILDCARD_ONE = "_";
|
||||
|
||||
private final String symbol;
|
||||
private final String asSql;
|
||||
|
||||
@ -101,8 +104,8 @@ public enum StandardComparison implements Comparison {
|
||||
expression = expression.replace(".", "\\.");
|
||||
|
||||
// convert from SQL LIKE syntax to regex
|
||||
expression = expression.replace("_", ".");
|
||||
expression = expression.replace("%", ".*");
|
||||
expression = expression.replace(WILDCARD_ONE, ".");
|
||||
expression = expression.replace(WILDCARD, ".*");
|
||||
|
||||
return Pattern.compile(expression);
|
||||
}
|
||||
|
@ -27,8 +27,6 @@ package me.lucko.luckperms.common.commands.group;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import me.lucko.luckperms.common.bulkupdate.comparison.Constraint;
|
||||
import me.lucko.luckperms.common.bulkupdate.comparison.StandardComparison;
|
||||
import me.lucko.luckperms.common.cache.LoadingMap;
|
||||
import me.lucko.luckperms.common.command.CommandResult;
|
||||
import me.lucko.luckperms.common.command.abstraction.ChildCommand;
|
||||
@ -42,11 +40,14 @@ import me.lucko.luckperms.common.locale.command.CommandSpec;
|
||||
import me.lucko.luckperms.common.locale.message.Message;
|
||||
import me.lucko.luckperms.common.model.Group;
|
||||
import me.lucko.luckperms.common.model.HolderType;
|
||||
import me.lucko.luckperms.common.node.comparator.HeldNodeComparator;
|
||||
import me.lucko.luckperms.common.node.comparator.NodeEntryComparator;
|
||||
import me.lucko.luckperms.common.node.factory.NodeCommandFactory;
|
||||
import me.lucko.luckperms.common.node.matcher.ConstraintNodeMatcher;
|
||||
import me.lucko.luckperms.common.node.matcher.StandardNodeMatchers;
|
||||
import me.lucko.luckperms.common.node.types.Inheritance;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.storage.misc.NodeEntry;
|
||||
import me.lucko.luckperms.common.util.DurationFormatter;
|
||||
import me.lucko.luckperms.common.util.Iterators;
|
||||
import me.lucko.luckperms.common.util.Predicates;
|
||||
@ -56,7 +57,6 @@ import net.kyori.text.ComponentBuilder;
|
||||
import net.kyori.text.TextComponent;
|
||||
import net.kyori.text.event.ClickEvent;
|
||||
import net.kyori.text.event.HoverEvent;
|
||||
import net.luckperms.api.node.HeldNode;
|
||||
import net.luckperms.api.node.Node;
|
||||
import net.luckperms.api.node.types.InheritanceNode;
|
||||
|
||||
@ -80,16 +80,16 @@ public class GroupListMembers extends ChildCommand<Group> {
|
||||
return CommandResult.NO_PERMISSION;
|
||||
}
|
||||
|
||||
Constraint constraint = Constraint.of(StandardComparison.EQUAL, Inheritance.key(group.getName()));
|
||||
ConstraintNodeMatcher<InheritanceNode> matcher = StandardNodeMatchers.key(Inheritance.builder(group.getName()).build());
|
||||
int page = ArgumentParser.parseIntOrElse(0, args, 1);
|
||||
|
||||
Message.SEARCH_SEARCHING_MEMBERS.send(sender, group.getName());
|
||||
|
||||
List<HeldNode<UUID>> matchedUsers = plugin.getStorage().getUsersWithPermission(constraint).join().stream()
|
||||
List<NodeEntry<UUID, InheritanceNode>> matchedUsers = plugin.getStorage().getUsersWithPermission(matcher).join().stream()
|
||||
.filter(n -> n.getNode().getValue())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<HeldNode<String>> matchedGroups = plugin.getStorage().getGroupsWithPermission(constraint).join().stream()
|
||||
List<NodeEntry<String, InheritanceNode>> matchedGroups = plugin.getStorage().getGroupsWithPermission(matcher).join().stream()
|
||||
.filter(n -> n.getNode().getValue())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
@ -124,28 +124,28 @@ public class GroupListMembers extends ChildCommand<Group> {
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
|
||||
private static <T extends Comparable<T>> void sendResult(Sender sender, List<HeldNode<T>> results, Function<T, String> lookupFunction, Message headerMessage, HolderType holderType, String label, int page) {
|
||||
private static <T extends Comparable<T>> void sendResult(Sender sender, List<NodeEntry<T, InheritanceNode>> results, Function<T, String> lookupFunction, Message headerMessage, HolderType holderType, String label, int page) {
|
||||
results = new ArrayList<>(results);
|
||||
results.sort(HeldNodeComparator.normal());
|
||||
results.sort(NodeEntryComparator.normal());
|
||||
|
||||
int pageIndex = page - 1;
|
||||
List<List<HeldNode<T>>> pages = Iterators.divideIterable(results, 15);
|
||||
List<List<NodeEntry<T, InheritanceNode>>> pages = Iterators.divideIterable(results, 15);
|
||||
|
||||
if (pageIndex < 0 || pageIndex >= pages.size()) {
|
||||
page = 1;
|
||||
pageIndex = 0;
|
||||
}
|
||||
|
||||
List<HeldNode<T>> content = pages.get(pageIndex);
|
||||
List<NodeEntry<T, InheritanceNode>> content = pages.get(pageIndex);
|
||||
|
||||
List<Map.Entry<String, HeldNode<T>>> mappedContent = content.stream()
|
||||
List<Map.Entry<String, NodeEntry<T, InheritanceNode>>> mappedContent = content.stream()
|
||||
.map(hp -> Maps.immutableEntry(lookupFunction.apply(hp.getHolder()), hp))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// send header
|
||||
headerMessage.send(sender, page, pages.size(), results.size());
|
||||
|
||||
for (Map.Entry<String, HeldNode<T>> ent : mappedContent) {
|
||||
for (Map.Entry<String, NodeEntry<T, InheritanceNode>> ent : mappedContent) {
|
||||
String s = "&3> &b" + ent.getKey() + " " + getNodeExpiryString(ent.getValue().getNode()) + MessageUtils.getAppendableNodeContextString(sender.getPlugin().getLocaleManager(), ent.getValue().getNode());
|
||||
TextComponent message = TextUtils.fromLegacy(s, TextUtils.AMPERSAND_CHAR).toBuilder().applyDeep(makeFancy(ent.getKey(), holderType, label, ent.getValue(), sender.getPlugin())).build();
|
||||
sender.sendMessage(message);
|
||||
@ -160,7 +160,7 @@ public class GroupListMembers extends ChildCommand<Group> {
|
||||
return " &8(&7expires in " + DurationFormatter.LONG.format(node.getExpiryDuration()) + "&8)";
|
||||
}
|
||||
|
||||
private static Consumer<ComponentBuilder<? ,?>> makeFancy(String holderName, HolderType holderType, String label, HeldNode<?> perm, LuckPermsPlugin plugin) {
|
||||
private static Consumer<ComponentBuilder<? ,?>> makeFancy(String holderName, HolderType holderType, String label, NodeEntry<?, ?> perm, LuckPermsPlugin plugin) {
|
||||
HoverEvent hoverEvent = HoverEvent.showText(TextUtils.fromLegacy(TextUtils.joinNewline(
|
||||
"&3> &b" + ((InheritanceNode) perm.getNode()).getGroupName(),
|
||||
" ",
|
||||
|
@ -43,10 +43,13 @@ import me.lucko.luckperms.common.locale.LocaleManager;
|
||||
import me.lucko.luckperms.common.locale.command.CommandSpec;
|
||||
import me.lucko.luckperms.common.locale.message.Message;
|
||||
import me.lucko.luckperms.common.model.HolderType;
|
||||
import me.lucko.luckperms.common.node.comparator.HeldNodeComparator;
|
||||
import me.lucko.luckperms.common.node.comparator.NodeEntryComparator;
|
||||
import me.lucko.luckperms.common.node.factory.NodeCommandFactory;
|
||||
import me.lucko.luckperms.common.node.matcher.ConstraintNodeMatcher;
|
||||
import me.lucko.luckperms.common.node.matcher.StandardNodeMatchers;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.storage.misc.NodeEntry;
|
||||
import me.lucko.luckperms.common.util.DurationFormatter;
|
||||
import me.lucko.luckperms.common.util.Iterators;
|
||||
import me.lucko.luckperms.common.util.Predicates;
|
||||
@ -56,7 +59,6 @@ import net.kyori.text.ComponentBuilder;
|
||||
import net.kyori.text.TextComponent;
|
||||
import net.kyori.text.event.ClickEvent;
|
||||
import net.kyori.text.event.HoverEvent;
|
||||
import net.luckperms.api.node.HeldNode;
|
||||
import net.luckperms.api.node.Node;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -80,13 +82,13 @@ public class SearchCommand extends SingleCommand {
|
||||
args.add(0, "==");
|
||||
}
|
||||
|
||||
Constraint query = Constraint.of(comparison, args.get(1));
|
||||
ConstraintNodeMatcher<Node> matcher = StandardNodeMatchers.of(Constraint.of(comparison, args.get(1)));
|
||||
int page = ArgumentParser.parseIntOrElse(2, args, 1);
|
||||
|
||||
Message.SEARCH_SEARCHING.send(sender, query);
|
||||
Message.SEARCH_SEARCHING.send(sender, matcher);
|
||||
|
||||
List<HeldNode<UUID>> matchedUsers = plugin.getStorage().getUsersWithPermission(query).join();
|
||||
List<HeldNode<String>> matchedGroups = plugin.getStorage().getGroupsWithPermission(query).join();
|
||||
List<NodeEntry<UUID, Node>> matchedUsers = plugin.getStorage().getUsersWithPermission(matcher).join();
|
||||
List<NodeEntry<String, Node>> matchedGroups = plugin.getStorage().getGroupsWithPermission(matcher).join();
|
||||
|
||||
int users = matchedUsers.size();
|
||||
int groups = matchedGroups.size();
|
||||
@ -126,28 +128,28 @@ public class SearchCommand extends SingleCommand {
|
||||
.complete(args);
|
||||
}
|
||||
|
||||
private static <T extends Comparable<T>> void sendResult(Sender sender, List<HeldNode<T>> results, Function<T, String> lookupFunction, Message headerMessage, HolderType holderType, String label, int page, Comparison comparison) {
|
||||
private static <T extends Comparable<T>> void sendResult(Sender sender, List<NodeEntry<T, Node>> results, Function<T, String> lookupFunction, Message headerMessage, HolderType holderType, String label, int page, Comparison comparison) {
|
||||
results = new ArrayList<>(results);
|
||||
results.sort(HeldNodeComparator.normal());
|
||||
results.sort(NodeEntryComparator.normal());
|
||||
|
||||
int pageIndex = page - 1;
|
||||
List<List<HeldNode<T>>> pages = Iterators.divideIterable(results, 15);
|
||||
List<List<NodeEntry<T, Node>>> pages = Iterators.divideIterable(results, 15);
|
||||
|
||||
if (pageIndex < 0 || pageIndex >= pages.size()) {
|
||||
page = 1;
|
||||
pageIndex = 0;
|
||||
}
|
||||
|
||||
List<HeldNode<T>> content = pages.get(pageIndex);
|
||||
List<NodeEntry<T, Node>> content = pages.get(pageIndex);
|
||||
|
||||
List<Map.Entry<String, HeldNode<T>>> mappedContent = content.stream()
|
||||
List<Map.Entry<String, NodeEntry<T, Node>>> mappedContent = content.stream()
|
||||
.map(hp -> Maps.immutableEntry(lookupFunction.apply(hp.getHolder()), hp))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// send header
|
||||
headerMessage.send(sender, page, pages.size(), results.size());
|
||||
|
||||
for (Map.Entry<String, HeldNode<T>> ent : mappedContent) {
|
||||
for (Map.Entry<String, NodeEntry<T, Node>> ent : mappedContent) {
|
||||
// only show the permission in the results if the comparison isn't equals
|
||||
String permission = "";
|
||||
if (comparison != StandardComparison.EQUAL) {
|
||||
@ -168,7 +170,7 @@ public class SearchCommand extends SingleCommand {
|
||||
return " &8(&7expires in " + DurationFormatter.LONG.format(node.getExpiryDuration()) + "&8)";
|
||||
}
|
||||
|
||||
private static Consumer<ComponentBuilder<?, ?>> makeFancy(String holderName, HolderType holderType, String label, HeldNode<?> perm, LuckPermsPlugin plugin) {
|
||||
private static Consumer<ComponentBuilder<?, ?>> makeFancy(String holderName, HolderType holderType, String label, NodeEntry<?, ?> perm, LuckPermsPlugin plugin) {
|
||||
HoverEvent hoverEvent = HoverEvent.showText(TextUtils.fromLegacy(TextUtils.joinNewline(
|
||||
"&3> " + (perm.getNode().getValue() ? "&a" : "&c") + perm.getNode().getKey(),
|
||||
" ",
|
||||
|
@ -23,7 +23,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.node.model;
|
||||
package me.lucko.luckperms.common.model;
|
||||
|
||||
import net.luckperms.api.model.PermissionHolder;
|
||||
import net.luckperms.api.node.metadata.types.InheritanceOriginMetadata;
|
@ -34,7 +34,6 @@ import me.lucko.luckperms.common.cache.Cache;
|
||||
import me.lucko.luckperms.common.context.ContextSetComparator;
|
||||
import me.lucko.luckperms.common.node.comparator.NodeComparator;
|
||||
import me.lucko.luckperms.common.node.comparator.NodeWithContextComparator;
|
||||
import me.lucko.luckperms.common.node.model.InheritanceOrigin;
|
||||
import me.lucko.luckperms.common.query.QueryOptionsImpl;
|
||||
|
||||
import net.luckperms.api.context.ContextSet;
|
||||
|
@ -25,22 +25,22 @@
|
||||
|
||||
package me.lucko.luckperms.common.node.comparator;
|
||||
|
||||
import net.luckperms.api.node.HeldNode;
|
||||
import me.lucko.luckperms.common.storage.misc.NodeEntry;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
public class HeldNodeComparator<T extends Comparable<T>> implements Comparator<HeldNode<T>> {
|
||||
public class NodeEntryComparator<T extends Comparable<T>> implements Comparator<NodeEntry<T, ?>> {
|
||||
|
||||
public static <T extends Comparable<T>> Comparator<? super HeldNode<T>> normal() {
|
||||
return new HeldNodeComparator<>();
|
||||
public static <T extends Comparable<T>> Comparator<? super NodeEntry<T, ?>> normal() {
|
||||
return new NodeEntryComparator<>();
|
||||
}
|
||||
|
||||
public static <T extends Comparable<T>> Comparator<? super HeldNode<T>> reverse() {
|
||||
return HeldNodeComparator.<T>normal().reversed();
|
||||
public static <T extends Comparable<T>> Comparator<? super NodeEntry<T, ?>> reverse() {
|
||||
return NodeEntryComparator.<T>normal().reversed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(HeldNode<T> o1, HeldNode<T> o2) {
|
||||
public int compare(NodeEntry<T, ?> o1, NodeEntry<T, ?> o2) {
|
||||
int i = NodeWithContextComparator.normal().compare(o1.getNode(), o2.getNode());
|
||||
if (i != 0) {
|
||||
return i;
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.node.matcher;
|
||||
|
||||
import me.lucko.luckperms.common.bulkupdate.comparison.Constraint;
|
||||
|
||||
import net.luckperms.api.node.Node;
|
||||
import net.luckperms.api.node.matcher.NodeMatcher;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Abstract implementation of {@link NodeMatcher} backed by a {@link Constraint}.
|
||||
*/
|
||||
public abstract class ConstraintNodeMatcher<T extends Node> implements NodeMatcher<T> {
|
||||
private final Constraint constraint;
|
||||
|
||||
protected ConstraintNodeMatcher(Constraint constraint) {
|
||||
this.constraint = constraint;
|
||||
}
|
||||
|
||||
public Constraint getConstraint() {
|
||||
return this.constraint;
|
||||
}
|
||||
|
||||
public abstract @Nullable T filterConstraintMatch(@NonNull Node node);
|
||||
|
||||
public @Nullable T match(Node node) {
|
||||
return getConstraint().eval(node.getKey()) ? filterConstraintMatch(node) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(@NonNull Node node) {
|
||||
return match(node) != null;
|
||||
}
|
||||
}
|
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.node.matcher;
|
||||
|
||||
import me.lucko.luckperms.common.bulkupdate.comparison.Constraint;
|
||||
import me.lucko.luckperms.common.bulkupdate.comparison.StandardComparison;
|
||||
import me.lucko.luckperms.common.node.AbstractNode;
|
||||
import me.lucko.luckperms.common.node.types.DisplayName;
|
||||
import me.lucko.luckperms.common.node.types.Inheritance;
|
||||
import me.lucko.luckperms.common.node.types.Meta;
|
||||
import me.lucko.luckperms.common.node.types.Prefix;
|
||||
import me.lucko.luckperms.common.node.types.RegexPermission;
|
||||
import me.lucko.luckperms.common.node.types.Suffix;
|
||||
import me.lucko.luckperms.common.node.types.Weight;
|
||||
|
||||
import net.luckperms.api.node.Node;
|
||||
import net.luckperms.api.node.NodeEqualityPredicate;
|
||||
import net.luckperms.api.node.NodeType;
|
||||
import net.luckperms.api.node.types.MetaNode;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public final class StandardNodeMatchers {
|
||||
private StandardNodeMatchers() {}
|
||||
|
||||
public static ConstraintNodeMatcher<Node> of(Constraint constraint) {
|
||||
return new Generic(constraint);
|
||||
}
|
||||
|
||||
public static ConstraintNodeMatcher<Node> key(String key) {
|
||||
return new Generic(Constraint.of(StandardComparison.EQUAL, key));
|
||||
}
|
||||
|
||||
public static <T extends Node> ConstraintNodeMatcher<T> key(T node) {
|
||||
return new NodeEquals<>(node, NodeEqualityPredicate.ONLY_KEY);
|
||||
}
|
||||
|
||||
public static ConstraintNodeMatcher<Node> keyStartsWith(String startsWith) {
|
||||
return new Generic(Constraint.of(StandardComparison.SIMILAR, startsWith + StandardComparison.WILDCARD));
|
||||
}
|
||||
|
||||
public static <T extends Node> ConstraintNodeMatcher<T> equals(T other, NodeEqualityPredicate equalityPredicate) {
|
||||
return new NodeEquals<>(other, equalityPredicate);
|
||||
}
|
||||
|
||||
public static ConstraintNodeMatcher<MetaNode> metaKey(String metaKey) {
|
||||
return new MetaKeyEquals(metaKey);
|
||||
}
|
||||
|
||||
public static <T extends Node> ConstraintNodeMatcher<T> type(NodeType<? extends T> type) {
|
||||
return new TypeEquals<>(type);
|
||||
}
|
||||
|
||||
private static class Generic extends ConstraintNodeMatcher<Node> {
|
||||
Generic(Constraint constraint) {
|
||||
super(constraint);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Node filterConstraintMatch(@NonNull Node node) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class NodeEquals<T extends Node> extends ConstraintNodeMatcher<T> {
|
||||
private final T node;
|
||||
private final NodeEqualityPredicate equalityPredicate;
|
||||
|
||||
NodeEquals(T node, NodeEqualityPredicate equalityPredicate) {
|
||||
super(Constraint.of(StandardComparison.EQUAL, node.getKey()));
|
||||
this.node = node;
|
||||
this.equalityPredicate = equalityPredicate;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public @Nullable T filterConstraintMatch(@NonNull Node node) {
|
||||
if (this.equalityPredicate == NodeEqualityPredicate.ONLY_KEY || this.node.equals(node, this.equalityPredicate)) {
|
||||
return (T) node;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class MetaKeyEquals extends ConstraintNodeMatcher<MetaNode> {
|
||||
MetaKeyEquals(String metaKey) {
|
||||
super(Constraint.of(StandardComparison.SIMILAR, Meta.key(metaKey, StandardComparison.WILDCARD)));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public MetaNode filterConstraintMatch(@NonNull Node node) {
|
||||
return NodeType.META.tryCast(node).orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class TypeEquals<T extends Node> extends ConstraintNodeMatcher<T> {
|
||||
private final NodeType<? extends T> type;
|
||||
|
||||
protected TypeEquals(NodeType<? extends T> type) {
|
||||
super(getConstraintForType(type));
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public T filterConstraintMatch(@NonNull Node node) {
|
||||
return this.type.tryCast(node).orElse(null);
|
||||
}
|
||||
|
||||
private static Constraint getConstraintForType(NodeType<?> type) {
|
||||
if (type == NodeType.REGEX_PERMISSION) {
|
||||
return Constraint.of(StandardComparison.SIMILAR, RegexPermission.key(StandardComparison.WILDCARD));
|
||||
} else if (type == NodeType.INHERITANCE) {
|
||||
return Constraint.of(StandardComparison.SIMILAR, Inheritance.key(StandardComparison.WILDCARD));
|
||||
} else if (type == NodeType.PREFIX) {
|
||||
return Constraint.of(StandardComparison.SIMILAR, Prefix.NODE_MARKER + StandardComparison.WILDCARD + AbstractNode.NODE_SEPARATOR + StandardComparison.WILDCARD);
|
||||
} else if (type == NodeType.SUFFIX) {
|
||||
return Constraint.of(StandardComparison.SIMILAR, Suffix.NODE_MARKER + StandardComparison.WILDCARD + AbstractNode.NODE_SEPARATOR + StandardComparison.WILDCARD);
|
||||
} else if (type == NodeType.META) {
|
||||
return Constraint.of(StandardComparison.SIMILAR, Meta.key(StandardComparison.WILDCARD, StandardComparison.WILDCARD));
|
||||
} else if (type == NodeType.WEIGHT) {
|
||||
return Constraint.of(StandardComparison.SIMILAR, Weight.NODE_MARKER + StandardComparison.WILDCARD);
|
||||
} else if (type == NodeType.DISPLAY_NAME) {
|
||||
return Constraint.of(StandardComparison.SIMILAR, DisplayName.key(StandardComparison.WILDCARD));
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unable to create a NodeMatcher for NodeType " + type.name());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -29,20 +29,21 @@ import com.google.common.collect.ImmutableList;
|
||||
|
||||
import me.lucko.luckperms.common.actionlog.Log;
|
||||
import me.lucko.luckperms.common.bulkupdate.BulkUpdate;
|
||||
import me.lucko.luckperms.common.bulkupdate.comparison.Constraint;
|
||||
import me.lucko.luckperms.common.model.Group;
|
||||
import me.lucko.luckperms.common.model.Track;
|
||||
import me.lucko.luckperms.common.model.User;
|
||||
import me.lucko.luckperms.common.node.matcher.ConstraintNodeMatcher;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.storage.implementation.StorageImplementation;
|
||||
import me.lucko.luckperms.common.storage.implementation.split.SplitStorage;
|
||||
import me.lucko.luckperms.common.storage.misc.NodeEntry;
|
||||
import me.lucko.luckperms.common.util.Throwing;
|
||||
|
||||
import net.luckperms.api.actionlog.Action;
|
||||
import net.luckperms.api.event.cause.CreationCause;
|
||||
import net.luckperms.api.event.cause.DeletionCause;
|
||||
import net.luckperms.api.model.PlayerSaveResult;
|
||||
import net.luckperms.api.node.HeldNode;
|
||||
import net.luckperms.api.node.Node;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@ -161,9 +162,9 @@ public class Storage {
|
||||
return makeFuture(this.implementation::getUniqueUsers);
|
||||
}
|
||||
|
||||
public CompletableFuture<List<HeldNode<UUID>>> getUsersWithPermission(Constraint constraint) {
|
||||
public <N extends Node> CompletableFuture<List<NodeEntry<UUID, N>>> getUsersWithPermission(ConstraintNodeMatcher<N> constraint) {
|
||||
return makeFuture(() -> {
|
||||
List<HeldNode<UUID>> result = this.implementation.getUsersWithPermission(constraint);
|
||||
List<NodeEntry<UUID, N>> result = this.implementation.getUsersWithPermission(constraint);
|
||||
result.removeIf(entry -> entry.getNode().hasExpired());
|
||||
return ImmutableList.copyOf(result);
|
||||
});
|
||||
@ -207,9 +208,9 @@ public class Storage {
|
||||
});
|
||||
}
|
||||
|
||||
public CompletableFuture<List<HeldNode<String>>> getGroupsWithPermission(Constraint constraint) {
|
||||
public <N extends Node> CompletableFuture<List<NodeEntry<String, N>>> getGroupsWithPermission(ConstraintNodeMatcher<N> constraint) {
|
||||
return makeFuture(() -> {
|
||||
List<HeldNode<String>> result = this.implementation.getGroupsWithPermission(constraint);
|
||||
List<NodeEntry<String, N>> result = this.implementation.getGroupsWithPermission(constraint);
|
||||
result.removeIf(entry -> entry.getNode().hasExpired());
|
||||
return ImmutableList.copyOf(result);
|
||||
});
|
||||
|
@ -27,15 +27,16 @@ package me.lucko.luckperms.common.storage.implementation;
|
||||
|
||||
import me.lucko.luckperms.common.actionlog.Log;
|
||||
import me.lucko.luckperms.common.bulkupdate.BulkUpdate;
|
||||
import me.lucko.luckperms.common.bulkupdate.comparison.Constraint;
|
||||
import me.lucko.luckperms.common.model.Group;
|
||||
import me.lucko.luckperms.common.model.Track;
|
||||
import me.lucko.luckperms.common.model.User;
|
||||
import me.lucko.luckperms.common.node.matcher.ConstraintNodeMatcher;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.storage.misc.NodeEntry;
|
||||
|
||||
import net.luckperms.api.actionlog.Action;
|
||||
import net.luckperms.api.model.PlayerSaveResult;
|
||||
import net.luckperms.api.node.HeldNode;
|
||||
import net.luckperms.api.node.Node;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
@ -71,7 +72,7 @@ public interface StorageImplementation {
|
||||
|
||||
Set<UUID> getUniqueUsers() throws Exception;
|
||||
|
||||
List<HeldNode<UUID>> getUsersWithPermission(Constraint constraint) throws Exception;
|
||||
<N extends Node> List<NodeEntry<UUID, N>> getUsersWithPermission(ConstraintNodeMatcher<N> constraint) throws Exception;
|
||||
|
||||
Group createAndLoadGroup(String name) throws Exception;
|
||||
|
||||
@ -83,7 +84,7 @@ public interface StorageImplementation {
|
||||
|
||||
void deleteGroup(Group group) throws Exception;
|
||||
|
||||
List<HeldNode<String>> getGroupsWithPermission(Constraint constraint) throws Exception;
|
||||
<N extends Node> List<NodeEntry<String, N>> getGroupsWithPermission(ConstraintNodeMatcher<N> constraint) throws Exception;
|
||||
|
||||
Track createAndLoadTrack(String name) throws Exception;
|
||||
|
||||
|
@ -26,14 +26,13 @@
|
||||
package me.lucko.luckperms.common.storage.implementation.file;
|
||||
|
||||
import me.lucko.luckperms.common.bulkupdate.BulkUpdate;
|
||||
import me.lucko.luckperms.common.bulkupdate.comparison.Constraint;
|
||||
import me.lucko.luckperms.common.node.model.HeldNodeImpl;
|
||||
import me.lucko.luckperms.common.node.matcher.ConstraintNodeMatcher;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.storage.implementation.file.loader.ConfigurateLoader;
|
||||
import me.lucko.luckperms.common.storage.implementation.file.watcher.FileWatcher;
|
||||
import me.lucko.luckperms.common.storage.misc.NodeEntry;
|
||||
import me.lucko.luckperms.common.util.Iterators;
|
||||
|
||||
import net.luckperms.api.node.HeldNode;
|
||||
import net.luckperms.api.node.Node;
|
||||
|
||||
import ninja.leaping.configurate.ConfigurationNode;
|
||||
@ -262,8 +261,8 @@ public class CombinedConfigurateStorage extends AbstractConfigurateStorage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HeldNode<UUID>> getUsersWithPermission(Constraint constraint) throws Exception {
|
||||
List<HeldNode<UUID>> held = new ArrayList<>();
|
||||
public <N extends Node> List<NodeEntry<UUID, N>> getUsersWithPermission(ConstraintNodeMatcher<N> constraint) throws Exception {
|
||||
List<NodeEntry<UUID, N>> held = new ArrayList<>();
|
||||
this.usersLoader.apply(false, true, root -> {
|
||||
for (Map.Entry<Object, ? extends ConfigurationNode> entry : root.getChildrenMap().entrySet()) {
|
||||
try {
|
||||
@ -272,10 +271,10 @@ public class CombinedConfigurateStorage extends AbstractConfigurateStorage {
|
||||
|
||||
Set<Node> nodes = readNodes(object);
|
||||
for (Node e : nodes) {
|
||||
if (!constraint.eval(e.getKey())) {
|
||||
continue;
|
||||
N match = constraint.match(e);
|
||||
if (match != null) {
|
||||
held.add(NodeEntry.of(holder, match));
|
||||
}
|
||||
held.add(HeldNodeImpl.of(holder, e));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@ -302,8 +301,8 @@ public class CombinedConfigurateStorage extends AbstractConfigurateStorage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HeldNode<String>> getGroupsWithPermission(Constraint constraint) throws Exception {
|
||||
List<HeldNode<String>> held = new ArrayList<>();
|
||||
public <N extends Node> List<NodeEntry<String, N>> getGroupsWithPermission(ConstraintNodeMatcher<N> constraint) throws Exception {
|
||||
List<NodeEntry<String, N>> held = new ArrayList<>();
|
||||
this.groupsLoader.apply(false, true, root -> {
|
||||
for (Map.Entry<Object, ? extends ConfigurationNode> entry : root.getChildrenMap().entrySet()) {
|
||||
try {
|
||||
@ -312,10 +311,10 @@ public class CombinedConfigurateStorage extends AbstractConfigurateStorage {
|
||||
|
||||
Set<Node> nodes = readNodes(object);
|
||||
for (Node e : nodes) {
|
||||
if (!constraint.eval(e.getKey())) {
|
||||
continue;
|
||||
N match = constraint.match(e);
|
||||
if (match != null) {
|
||||
held.add(NodeEntry.of(holder, match));
|
||||
}
|
||||
held.add(HeldNodeImpl.of(holder, e));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
@ -26,17 +26,16 @@
|
||||
package me.lucko.luckperms.common.storage.implementation.file;
|
||||
|
||||
import me.lucko.luckperms.common.bulkupdate.BulkUpdate;
|
||||
import me.lucko.luckperms.common.bulkupdate.comparison.Constraint;
|
||||
import me.lucko.luckperms.common.model.User;
|
||||
import me.lucko.luckperms.common.node.model.HeldNodeImpl;
|
||||
import me.lucko.luckperms.common.node.matcher.ConstraintNodeMatcher;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.storage.implementation.file.loader.ConfigurateLoader;
|
||||
import me.lucko.luckperms.common.storage.implementation.file.watcher.FileWatcher;
|
||||
import me.lucko.luckperms.common.storage.misc.NodeEntry;
|
||||
import me.lucko.luckperms.common.util.Iterators;
|
||||
import me.lucko.luckperms.common.util.MoreFiles;
|
||||
import me.lucko.luckperms.common.util.Uuids;
|
||||
|
||||
import net.luckperms.api.node.HeldNode;
|
||||
import net.luckperms.api.node.Node;
|
||||
|
||||
import ninja.leaping.configurate.ConfigurationNode;
|
||||
@ -255,8 +254,8 @@ public class SeparatedConfigurateStorage extends AbstractConfigurateStorage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HeldNode<UUID>> getUsersWithPermission(Constraint constraint) throws Exception {
|
||||
List<HeldNode<UUID>> held = new ArrayList<>();
|
||||
public <N extends Node> List<NodeEntry<UUID, N>> getUsersWithPermission(ConstraintNodeMatcher<N> constraint) throws Exception {
|
||||
List<NodeEntry<UUID, N>> held = new ArrayList<>();
|
||||
try (Stream<Path> stream = Files.list(getDirectory(StorageLocation.USER))) {
|
||||
stream.filter(getFileTypeFilter())
|
||||
.forEach(file -> {
|
||||
@ -267,10 +266,10 @@ public class SeparatedConfigurateStorage extends AbstractConfigurateStorage {
|
||||
UUID holder = UUID.fromString(fileName.substring(0, fileName.length() - this.fileExtension.length()));
|
||||
Set<Node> nodes = readNodes(object);
|
||||
for (Node e : nodes) {
|
||||
if (!constraint.eval(e.getKey())) {
|
||||
continue;
|
||||
N match = constraint.match(e);
|
||||
if (match != null) {
|
||||
held.add(NodeEntry.of(holder, match));
|
||||
}
|
||||
held.add(HeldNodeImpl.of(holder, e));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw reportException(file.getFileName().toString(), e);
|
||||
@ -298,8 +297,8 @@ public class SeparatedConfigurateStorage extends AbstractConfigurateStorage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HeldNode<String>> getGroupsWithPermission(Constraint constraint) throws Exception {
|
||||
List<HeldNode<String>> held = new ArrayList<>();
|
||||
public <N extends Node> List<NodeEntry<String, N>> getGroupsWithPermission(ConstraintNodeMatcher<N> constraint) throws Exception {
|
||||
List<NodeEntry<String, N>> held = new ArrayList<>();
|
||||
try (Stream<Path> stream = Files.list(getDirectory(StorageLocation.GROUP))) {
|
||||
stream.filter(getFileTypeFilter())
|
||||
.forEach(file -> {
|
||||
@ -310,10 +309,10 @@ public class SeparatedConfigurateStorage extends AbstractConfigurateStorage {
|
||||
String holder = fileName.substring(0, fileName.length() - this.fileExtension.length());
|
||||
Set<Node> nodes = readNodes(object);
|
||||
for (Node e : nodes) {
|
||||
if (!constraint.eval(e.getKey())) {
|
||||
continue;
|
||||
N match = constraint.match(e);
|
||||
if (match != null) {
|
||||
held.add(NodeEntry.of(holder, match));
|
||||
}
|
||||
held.add(HeldNodeImpl.of(holder, e));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw reportException(file.getFileName().toString(), e);
|
||||
|
@ -40,16 +40,16 @@ import com.mongodb.client.model.ReplaceOptions;
|
||||
import me.lucko.luckperms.common.actionlog.Log;
|
||||
import me.lucko.luckperms.common.actionlog.LoggedAction;
|
||||
import me.lucko.luckperms.common.bulkupdate.BulkUpdate;
|
||||
import me.lucko.luckperms.common.bulkupdate.comparison.Constraint;
|
||||
import me.lucko.luckperms.common.context.contextset.MutableContextSetImpl;
|
||||
import me.lucko.luckperms.common.model.Group;
|
||||
import me.lucko.luckperms.common.model.Track;
|
||||
import me.lucko.luckperms.common.model.User;
|
||||
import me.lucko.luckperms.common.model.manager.group.GroupManager;
|
||||
import me.lucko.luckperms.common.node.factory.NodeBuilders;
|
||||
import me.lucko.luckperms.common.node.model.HeldNodeImpl;
|
||||
import me.lucko.luckperms.common.node.matcher.ConstraintNodeMatcher;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.storage.implementation.StorageImplementation;
|
||||
import me.lucko.luckperms.common.storage.misc.NodeEntry;
|
||||
import me.lucko.luckperms.common.storage.misc.PlayerSaveResultImpl;
|
||||
import me.lucko.luckperms.common.storage.misc.StorageCredentials;
|
||||
import me.lucko.luckperms.common.util.Iterators;
|
||||
@ -61,7 +61,6 @@ import net.luckperms.api.context.DefaultContextKeys;
|
||||
import net.luckperms.api.context.MutableContextSet;
|
||||
import net.luckperms.api.model.PlayerSaveResult;
|
||||
import net.luckperms.api.model.data.DataType;
|
||||
import net.luckperms.api.node.HeldNode;
|
||||
import net.luckperms.api.node.Node;
|
||||
import net.luckperms.api.node.NodeBuilder;
|
||||
|
||||
@ -361,8 +360,8 @@ public class MongoStorage implements StorageImplementation {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HeldNode<UUID>> getUsersWithPermission(Constraint constraint) {
|
||||
List<HeldNode<UUID>> held = new ArrayList<>();
|
||||
public <N extends Node> List<NodeEntry<UUID, N>> getUsersWithPermission(ConstraintNodeMatcher<N> constraint) throws Exception {
|
||||
List<NodeEntry<UUID, N>> held = new ArrayList<>();
|
||||
MongoCollection<Document> c = this.database.getCollection(this.prefix + "users");
|
||||
try (MongoCursor<Document> cursor = c.find().iterator()) {
|
||||
while (cursor.hasNext()) {
|
||||
@ -371,10 +370,10 @@ public class MongoStorage implements StorageImplementation {
|
||||
|
||||
Set<Node> nodes = new HashSet<>(nodesFromDoc(d));
|
||||
for (Node e : nodes) {
|
||||
if (!constraint.eval(e.getKey())) {
|
||||
continue;
|
||||
N match = constraint.match(e);
|
||||
if (match != null) {
|
||||
held.add(NodeEntry.of(holder, match));
|
||||
}
|
||||
held.add(HeldNodeImpl.of(holder, e));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -471,8 +470,8 @@ public class MongoStorage implements StorageImplementation {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HeldNode<String>> getGroupsWithPermission(Constraint constraint) {
|
||||
List<HeldNode<String>> held = new ArrayList<>();
|
||||
public <N extends Node> List<NodeEntry<String, N>> getGroupsWithPermission(ConstraintNodeMatcher<N> constraint) throws Exception {
|
||||
List<NodeEntry<String, N>> held = new ArrayList<>();
|
||||
MongoCollection<Document> c = this.database.getCollection(this.prefix + "groups");
|
||||
try (MongoCursor<Document> cursor = c.find().iterator()) {
|
||||
while (cursor.hasNext()) {
|
||||
@ -481,10 +480,10 @@ public class MongoStorage implements StorageImplementation {
|
||||
|
||||
Set<Node> nodes = new HashSet<>(nodesFromDoc(d));
|
||||
for (Node e : nodes) {
|
||||
if (!constraint.eval(e.getKey())) {
|
||||
continue;
|
||||
N match = constraint.match(e);
|
||||
if (match != null) {
|
||||
held.add(NodeEntry.of(holder, match));
|
||||
}
|
||||
held.add(HeldNodeImpl.of(holder, e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,17 +29,18 @@ import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import me.lucko.luckperms.common.actionlog.Log;
|
||||
import me.lucko.luckperms.common.bulkupdate.BulkUpdate;
|
||||
import me.lucko.luckperms.common.bulkupdate.comparison.Constraint;
|
||||
import me.lucko.luckperms.common.model.Group;
|
||||
import me.lucko.luckperms.common.model.Track;
|
||||
import me.lucko.luckperms.common.model.User;
|
||||
import me.lucko.luckperms.common.node.matcher.ConstraintNodeMatcher;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.storage.StorageType;
|
||||
import me.lucko.luckperms.common.storage.implementation.StorageImplementation;
|
||||
import me.lucko.luckperms.common.storage.misc.NodeEntry;
|
||||
|
||||
import net.luckperms.api.actionlog.Action;
|
||||
import net.luckperms.api.model.PlayerSaveResult;
|
||||
import net.luckperms.api.node.HeldNode;
|
||||
import net.luckperms.api.node.Node;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
@ -153,7 +154,7 @@ public class SplitStorage implements StorageImplementation {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HeldNode<UUID>> getUsersWithPermission(Constraint constraint) throws Exception {
|
||||
public <N extends Node> List<NodeEntry<UUID, N>> getUsersWithPermission(ConstraintNodeMatcher<N> constraint) throws Exception {
|
||||
return implFor(SplitStorageType.USER).getUsersWithPermission(constraint);
|
||||
}
|
||||
|
||||
@ -183,7 +184,7 @@ public class SplitStorage implements StorageImplementation {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HeldNode<String>> getGroupsWithPermission(Constraint constraint) throws Exception {
|
||||
public <N extends Node> List<NodeEntry<String, N>> getGroupsWithPermission(ConstraintNodeMatcher<N> constraint) throws Exception {
|
||||
return implFor(SplitStorageType.GROUP).getGroupsWithPermission(constraint);
|
||||
}
|
||||
|
||||
|
@ -32,16 +32,16 @@ import me.lucko.luckperms.common.actionlog.Log;
|
||||
import me.lucko.luckperms.common.actionlog.LoggedAction;
|
||||
import me.lucko.luckperms.common.bulkupdate.BulkUpdate;
|
||||
import me.lucko.luckperms.common.bulkupdate.PreparedStatementBuilder;
|
||||
import me.lucko.luckperms.common.bulkupdate.comparison.Constraint;
|
||||
import me.lucko.luckperms.common.context.ContextSetJsonSerializer;
|
||||
import me.lucko.luckperms.common.model.Group;
|
||||
import me.lucko.luckperms.common.model.Track;
|
||||
import me.lucko.luckperms.common.model.User;
|
||||
import me.lucko.luckperms.common.model.manager.group.GroupManager;
|
||||
import me.lucko.luckperms.common.node.model.HeldNodeImpl;
|
||||
import me.lucko.luckperms.common.node.matcher.ConstraintNodeMatcher;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.storage.implementation.StorageImplementation;
|
||||
import me.lucko.luckperms.common.storage.implementation.sql.connection.ConnectionFactory;
|
||||
import me.lucko.luckperms.common.storage.misc.NodeEntry;
|
||||
import me.lucko.luckperms.common.storage.misc.PlayerSaveResultImpl;
|
||||
import me.lucko.luckperms.common.util.Iterators;
|
||||
import me.lucko.luckperms.common.util.gson.GsonProvider;
|
||||
@ -49,7 +49,6 @@ import me.lucko.luckperms.common.util.gson.GsonProvider;
|
||||
import net.luckperms.api.actionlog.Action;
|
||||
import net.luckperms.api.model.PlayerSaveResult;
|
||||
import net.luckperms.api.model.data.DataType;
|
||||
import net.luckperms.api.node.HeldNode;
|
||||
import net.luckperms.api.node.Node;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -363,18 +362,22 @@ public class SqlStorage implements StorageImplementation {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HeldNode<UUID>> getUsersWithPermission(Constraint constraint) throws SQLException {
|
||||
public <N extends Node> List<NodeEntry<UUID, N>> getUsersWithPermission(ConstraintNodeMatcher<N> constraint) throws SQLException {
|
||||
PreparedStatementBuilder builder = new PreparedStatementBuilder().append(USER_PERMISSIONS_SELECT_PERMISSION);
|
||||
constraint.appendSql(builder, "permission");
|
||||
constraint.getConstraint().appendSql(builder, "permission");
|
||||
|
||||
List<HeldNode<UUID>> held = new ArrayList<>();
|
||||
List<NodeEntry<UUID, N>> held = new ArrayList<>();
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = builder.build(c, this.statementProcessor)) {
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
UUID holder = UUID.fromString(rs.getString("uuid"));
|
||||
Node node = readNode(rs).toNode();
|
||||
held.add(HeldNodeImpl.of(holder, node));
|
||||
|
||||
N match = constraint.filterConstraintMatch(node);
|
||||
if (match != null) {
|
||||
held.add(NodeEntry.of(holder, match));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -490,18 +493,22 @@ public class SqlStorage implements StorageImplementation {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HeldNode<String>> getGroupsWithPermission(Constraint constraint) throws SQLException {
|
||||
public <N extends Node> List<NodeEntry<String, N>> getGroupsWithPermission(ConstraintNodeMatcher<N> constraint) throws SQLException {
|
||||
PreparedStatementBuilder builder = new PreparedStatementBuilder().append(GROUP_PERMISSIONS_SELECT_PERMISSION);
|
||||
constraint.appendSql(builder, "permission");
|
||||
constraint.getConstraint().appendSql(builder, "permission");
|
||||
|
||||
List<HeldNode<String>> held = new ArrayList<>();
|
||||
List<NodeEntry<String, N>> held = new ArrayList<>();
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = builder.build(c, this.statementProcessor)) {
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
String holder = rs.getString("name");
|
||||
Node node = readNode(rs).toNode();
|
||||
held.add(HeldNodeImpl.of(holder, node));
|
||||
|
||||
N match = constraint.filterConstraintMatch(node);
|
||||
if (match != null) {
|
||||
held.add(NodeEntry.of(holder, match));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,42 +23,42 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.node.model;
|
||||
package me.lucko.luckperms.common.storage.misc;
|
||||
|
||||
import net.luckperms.api.node.HeldNode;
|
||||
import net.luckperms.api.node.Node;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
public final class HeldNodeImpl<T extends Comparable<T>> implements HeldNode<T> {
|
||||
public final class NodeEntry<H extends Comparable<H>, N extends Node> implements HeldNode<H> {
|
||||
|
||||
public static <T extends Comparable<T>> HeldNodeImpl<T> of(T holder, Node node) {
|
||||
return new HeldNodeImpl<>(holder, node);
|
||||
public static <H extends Comparable<H>, N extends Node> NodeEntry<H, N> of(H holder, N node) {
|
||||
return new NodeEntry<>(holder, node);
|
||||
}
|
||||
|
||||
private final T holder;
|
||||
private final Node node;
|
||||
private final H holder;
|
||||
private final N node;
|
||||
|
||||
private HeldNodeImpl(T holder, Node node) {
|
||||
private NodeEntry(H holder, N node) {
|
||||
this.holder = holder;
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Node getNode() {
|
||||
return this.node;
|
||||
public @NonNull H getHolder() {
|
||||
return this.holder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull T getHolder() {
|
||||
return this.holder;
|
||||
public @NonNull N getNode() {
|
||||
return this.node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) return true;
|
||||
if (!(o instanceof HeldNodeImpl)) return false;
|
||||
final HeldNodeImpl<?> other = (HeldNodeImpl<?>) o;
|
||||
if (!(o instanceof NodeEntry)) return false;
|
||||
final NodeEntry<?, ?> other = (NodeEntry<?, ?>) o;
|
||||
return this.getHolder().equals(other.getHolder()) && this.getNode().equals(other.getNode());
|
||||
}
|
||||
|
@ -32,11 +32,11 @@ import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import me.lucko.luckperms.common.bulkupdate.comparison.Constraint;
|
||||
import me.lucko.luckperms.common.bulkupdate.comparison.StandardComparison;
|
||||
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
|
||||
import me.lucko.luckperms.common.model.manager.group.AbstractGroupManager;
|
||||
import me.lucko.luckperms.common.node.matcher.StandardNodeMatchers;
|
||||
import me.lucko.luckperms.common.storage.misc.DataConstraints;
|
||||
import me.lucko.luckperms.common.storage.misc.NodeEntry;
|
||||
import me.lucko.luckperms.common.util.ImmutableCollectors;
|
||||
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
||||
import me.lucko.luckperms.sponge.model.SpongeGroup;
|
||||
@ -48,7 +48,7 @@ import me.lucko.luckperms.sponge.service.model.LPSubjectReference;
|
||||
|
||||
import net.luckperms.api.context.ImmutableContextSet;
|
||||
import net.luckperms.api.event.cause.CreationCause;
|
||||
import net.luckperms.api.node.HeldNode;
|
||||
import net.luckperms.api.node.Node;
|
||||
import net.luckperms.api.util.Tristate;
|
||||
|
||||
import org.spongepowered.api.service.permission.PermissionService;
|
||||
@ -193,8 +193,8 @@ public class SpongeGroupManager extends AbstractGroupManager<SpongeGroup> implem
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
ImmutableMap.Builder<LPSubjectReference, Boolean> builder = ImmutableMap.builder();
|
||||
|
||||
List<HeldNode<String>> lookup = this.plugin.getStorage().getGroupsWithPermission(Constraint.of(StandardComparison.EQUAL, permission)).join();
|
||||
for (HeldNode<String> holder : lookup) {
|
||||
List<NodeEntry<String, Node>> lookup = this.plugin.getStorage().getGroupsWithPermission(StandardNodeMatchers.key(permission)).join();
|
||||
for (NodeEntry<String, Node> holder : lookup) {
|
||||
if (holder.getNode().getContexts().equals(ImmutableContextSetImpl.EMPTY)) {
|
||||
builder.put(getService().getReferenceFactory().obtain(getIdentifier(), holder.getHolder()), holder.getNode().getValue());
|
||||
}
|
||||
@ -209,8 +209,8 @@ public class SpongeGroupManager extends AbstractGroupManager<SpongeGroup> implem
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
ImmutableMap.Builder<LPSubjectReference, Boolean> builder = ImmutableMap.builder();
|
||||
|
||||
List<HeldNode<String>> lookup = this.plugin.getStorage().getGroupsWithPermission(Constraint.of(StandardComparison.EQUAL, permission)).join();
|
||||
for (HeldNode<String> holder : lookup) {
|
||||
List<NodeEntry<String, Node>> lookup = this.plugin.getStorage().getGroupsWithPermission(StandardNodeMatchers.key(permission)).join();
|
||||
for (NodeEntry<String, Node> holder : lookup) {
|
||||
if (holder.getNode().getContexts().equals(contexts)) {
|
||||
builder.put(getService().getReferenceFactory().obtain(getIdentifier(), holder.getHolder()), holder.getNode().getValue());
|
||||
}
|
||||
|
@ -32,11 +32,11 @@ import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import me.lucko.luckperms.common.bulkupdate.comparison.Constraint;
|
||||
import me.lucko.luckperms.common.bulkupdate.comparison.StandardComparison;
|
||||
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
|
||||
import me.lucko.luckperms.common.model.manager.user.AbstractUserManager;
|
||||
import me.lucko.luckperms.common.model.manager.user.UserHousekeeper;
|
||||
import me.lucko.luckperms.common.node.matcher.StandardNodeMatchers;
|
||||
import me.lucko.luckperms.common.storage.misc.NodeEntry;
|
||||
import me.lucko.luckperms.common.util.ImmutableCollectors;
|
||||
import me.lucko.luckperms.common.util.Uuids;
|
||||
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
||||
@ -48,7 +48,7 @@ import me.lucko.luckperms.sponge.service.model.LPSubjectCollection;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectReference;
|
||||
|
||||
import net.luckperms.api.context.ImmutableContextSet;
|
||||
import net.luckperms.api.node.HeldNode;
|
||||
import net.luckperms.api.node.Node;
|
||||
import net.luckperms.api.util.Tristate;
|
||||
|
||||
import org.spongepowered.api.service.permission.PermissionService;
|
||||
@ -212,8 +212,8 @@ public class SpongeUserManager extends AbstractUserManager<SpongeUser> implement
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
ImmutableMap.Builder<LPSubjectReference, Boolean> builder = ImmutableMap.builder();
|
||||
|
||||
List<HeldNode<UUID>> lookup = this.plugin.getStorage().getUsersWithPermission(Constraint.of(StandardComparison.EQUAL, permission)).join();
|
||||
for (HeldNode<UUID> holder : lookup) {
|
||||
List<NodeEntry<UUID, Node>> lookup = this.plugin.getStorage().getUsersWithPermission(StandardNodeMatchers.key(permission)).join();
|
||||
for (NodeEntry<UUID, Node> holder : lookup) {
|
||||
if (holder.getNode().getContexts().equals(ImmutableContextSetImpl.EMPTY)) {
|
||||
builder.put(getService().getReferenceFactory().obtain(getIdentifier(), holder.getHolder().toString()), holder.getNode().getValue());
|
||||
}
|
||||
@ -228,8 +228,8 @@ public class SpongeUserManager extends AbstractUserManager<SpongeUser> implement
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
ImmutableMap.Builder<LPSubjectReference, Boolean> builder = ImmutableMap.builder();
|
||||
|
||||
List<HeldNode<UUID>> lookup = this.plugin.getStorage().getUsersWithPermission(Constraint.of(StandardComparison.EQUAL, permission)).join();
|
||||
for (HeldNode<UUID> holder : lookup) {
|
||||
List<NodeEntry<UUID, Node>> lookup = this.plugin.getStorage().getUsersWithPermission(StandardNodeMatchers.key(permission)).join();
|
||||
for (NodeEntry<UUID, Node> holder : lookup) {
|
||||
if (holder.getNode().getContexts().equals(contexts)) {
|
||||
builder.put(getService().getReferenceFactory().obtain(getIdentifier(), holder.getHolder().toString()), holder.getNode().getValue());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user