mirror of
https://github.com/LuckPerms/LuckPerms.git
synced 2024-12-02 23:53:25 +01:00
Optimizations to the core PermissionHolder class
- Remove usage of Java 8 streams from frequently called methods - Use LinkedLists where appropriate to improve Iterator#remove speed - Cache immutable multimap conversion - Rename some methods to make the intended use/behaviour clearer
This commit is contained in:
parent
d98b464ce9
commit
a40421fa1f
@ -330,7 +330,7 @@ public class VaultChatHook extends Chat {
|
|||||||
world = perms.correctWorld(world);
|
world = perms.correctWorld(world);
|
||||||
perms.log("Getting meta: '" + node + "' for group " + group.getName() + " on world " + world + ", server " + perms.getServer());
|
perms.log("Getting meta: '" + node + "' for group " + group.getName() + " on world " + world + ", server " + perms.getServer());
|
||||||
|
|
||||||
for (Node n : group.mergePermissionsToList()) {
|
for (Node n : group.getOwnNodes()) {
|
||||||
if (!n.getValue()) continue;
|
if (!n.getValue()) continue;
|
||||||
if (!n.isMeta()) continue;
|
if (!n.isMeta()) continue;
|
||||||
if (!n.shouldApplyWithContext(perms.createContextForWorldLookup(world).getContexts())) continue;
|
if (!n.shouldApplyWithContext(perms.createContextForWorldLookup(world).getContexts())) continue;
|
||||||
|
@ -225,7 +225,7 @@ public class VaultPermissionHook extends Permission {
|
|||||||
if (group == null) return false;
|
if (group == null) return false;
|
||||||
|
|
||||||
// This is a nasty call. Groups aren't cached. :(
|
// This is a nasty call. Groups aren't cached. :(
|
||||||
Map<String, Boolean> permissions = group.exportNodes(ExtractedContexts.generate(createContextForWorldLookup(world)), true);
|
Map<String, Boolean> permissions = group.exportNodesAndShorthand(ExtractedContexts.generate(createContextForWorldLookup(world)), true);
|
||||||
return permissions.containsKey(permission.toLowerCase()) && permissions.get(permission.toLowerCase());
|
return permissions.containsKey(permission.toLowerCase()) && permissions.get(permission.toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,7 +350,7 @@ public class VaultPermissionHook extends Permission {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String w = world; // screw effectively final
|
String w = world; // screw effectively final
|
||||||
return user.getNodes().values().stream()
|
return user.getEnduringNodes().values().stream()
|
||||||
.filter(Node::isGroupNode)
|
.filter(Node::isGroupNode)
|
||||||
.filter(n -> n.shouldApplyWithContext(createContextForWorldLookup(player, w).getContexts()))
|
.filter(n -> n.shouldApplyWithContext(createContextForWorldLookup(player, w).getContexts()))
|
||||||
.map(Node::getGroupName)
|
.map(Node::getGroupName)
|
||||||
@ -418,7 +418,7 @@ public class VaultPermissionHook extends Permission {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// we need to check the users permissions only
|
// we need to check the users permissions only
|
||||||
for (Node node : user.mergePermissionsToList()) {
|
for (Node node : user.getOwnNodes()) {
|
||||||
if (!node.getValue()) continue;
|
if (!node.getValue()) continue;
|
||||||
if (!node.getPermission().toLowerCase().startsWith("vault.primarygroup.")) continue;
|
if (!node.getPermission().toLowerCase().startsWith("vault.primarygroup.")) continue;
|
||||||
if (!node.shouldApplyOnServer(getServer(), isIncludeGlobal(), false)) continue;
|
if (!node.shouldApplyOnServer(getServer(), isIncludeGlobal(), false)) continue;
|
||||||
@ -433,7 +433,7 @@ public class VaultPermissionHook extends Permission {
|
|||||||
|
|
||||||
if (isPgoCheckMemberOf()) {
|
if (isPgoCheckMemberOf()) {
|
||||||
String finalWorld = world;
|
String finalWorld = world;
|
||||||
List<String> localGroups = user.mergePermissionsToList().stream()
|
List<String> localGroups = user.getOwnNodes().stream()
|
||||||
.filter(Node::isGroupNode)
|
.filter(Node::isGroupNode)
|
||||||
.filter(n -> n.shouldApplyOnWorld(finalWorld, isIncludeGlobal(), true))
|
.filter(n -> n.shouldApplyOnWorld(finalWorld, isIncludeGlobal(), true))
|
||||||
.filter(n -> n.shouldApplyOnServer(getServer(), isIncludeGlobal(), true))
|
.filter(n -> n.shouldApplyOnServer(getServer(), isIncludeGlobal(), true))
|
||||||
|
@ -153,7 +153,7 @@ public final class GroupDelegate extends PermissionHolderDelegate implements Gro
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getGroupNames() {
|
public List<String> getGroupNames() {
|
||||||
return handle.mergePermissionsToList().stream()
|
return handle.getOwnNodes().stream()
|
||||||
.filter(Node::isGroupNode)
|
.filter(Node::isGroupNode)
|
||||||
.map(Node::getGroupName)
|
.map(Node::getGroupName)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
@ -161,7 +161,7 @@ public final class GroupDelegate extends PermissionHolderDelegate implements Gro
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getLocalGroups(@NonNull String server, @NonNull String world) {
|
public List<String> getLocalGroups(@NonNull String server, @NonNull String world) {
|
||||||
return handle.mergePermissionsToList().stream()
|
return handle.getOwnNodes().stream()
|
||||||
.filter(Node::isGroupNode)
|
.filter(Node::isGroupNode)
|
||||||
.filter(n -> n.shouldApplyOnWorld(world, false, true))
|
.filter(n -> n.shouldApplyOnWorld(world, false, true))
|
||||||
.filter(n -> n.shouldApplyOnServer(server, false, true))
|
.filter(n -> n.shouldApplyOnServer(server, false, true))
|
||||||
@ -176,7 +176,7 @@ public final class GroupDelegate extends PermissionHolderDelegate implements Gro
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getLocalGroups(@NonNull String server) {
|
public List<String> getLocalGroups(@NonNull String server) {
|
||||||
return handle.mergePermissionsToList().stream()
|
return handle.getOwnNodes().stream()
|
||||||
.filter(Node::isGroupNode)
|
.filter(Node::isGroupNode)
|
||||||
.filter(n -> n.shouldApplyOnServer(server, false, true))
|
.filter(n -> n.shouldApplyOnServer(server, false, true))
|
||||||
.map(Node::getGroupName)
|
.map(Node::getGroupName)
|
||||||
|
@ -74,12 +74,12 @@ public class PermissionHolderDelegate implements PermissionHolder {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SortedSet<? extends Node> getPermissions() {
|
public SortedSet<? extends Node> getPermissions() {
|
||||||
return ImmutableSortedSet.copyOfSorted(handle.mergePermissionsToSortedSet());
|
return ImmutableSortedSet.copyOfSorted(handle.getOwnNodesSorted());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Node> getEnduringPermissions() {
|
public Set<Node> getEnduringPermissions() {
|
||||||
return ImmutableSet.copyOf(handle.getNodes().values());
|
return ImmutableSet.copyOf(handle.getEnduringNodes().values());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -99,7 +99,7 @@ public class PermissionHolderDelegate implements PermissionHolder {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Boolean> exportNodes(Contexts contexts, boolean lowerCase) {
|
public Map<String, Boolean> exportNodes(Contexts contexts, boolean lowerCase) {
|
||||||
return new HashMap<>(handle.exportNodes(ExtractedContexts.generate(contexts), lowerCase));
|
return new HashMap<>(handle.exportNodesAndShorthand(ExtractedContexts.generate(contexts), lowerCase));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -198,7 +198,7 @@ public final class UserDelegate extends PermissionHolderDelegate implements User
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getGroupNames() {
|
public List<String> getGroupNames() {
|
||||||
return handle.mergePermissionsToList().stream()
|
return handle.getOwnNodes().stream()
|
||||||
.filter(Node::isGroupNode)
|
.filter(Node::isGroupNode)
|
||||||
.map(Node::getGroupName)
|
.map(Node::getGroupName)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
@ -206,7 +206,7 @@ public final class UserDelegate extends PermissionHolderDelegate implements User
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getLocalGroups(@NonNull String server, @NonNull String world) {
|
public List<String> getLocalGroups(@NonNull String server, @NonNull String world) {
|
||||||
return handle.mergePermissionsToList().stream()
|
return handle.getOwnNodes().stream()
|
||||||
.filter(Node::isGroupNode)
|
.filter(Node::isGroupNode)
|
||||||
.filter(n -> n.shouldApplyOnWorld(world, false, true))
|
.filter(n -> n.shouldApplyOnWorld(world, false, true))
|
||||||
.filter(n -> n.shouldApplyOnServer(server, false, true))
|
.filter(n -> n.shouldApplyOnServer(server, false, true))
|
||||||
@ -216,7 +216,7 @@ public final class UserDelegate extends PermissionHolderDelegate implements User
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getLocalGroups(@NonNull String server) {
|
public List<String> getLocalGroups(@NonNull String server) {
|
||||||
return handle.mergePermissionsToList().stream()
|
return handle.getOwnNodes().stream()
|
||||||
.filter(Node::isGroupNode)
|
.filter(Node::isGroupNode)
|
||||||
.filter(n -> n.shouldApplyOnServer(server, false, true))
|
.filter(n -> n.shouldApplyOnServer(server, false, true))
|
||||||
.map(Node::getGroupName)
|
.map(Node::getGroupName)
|
||||||
|
@ -29,7 +29,6 @@ import lombok.RequiredArgsConstructor;
|
|||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thread-safe caching utility
|
* Thread-safe caching utility
|
||||||
@ -37,37 +36,43 @@ import java.util.function.Supplier;
|
|||||||
* @param <T> the type being stored
|
* @param <T> the type being stored
|
||||||
*/
|
*/
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class Cache<T> {
|
public abstract class Cache<T> {
|
||||||
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
||||||
private final Supplier<T> supplier;
|
|
||||||
|
|
||||||
private T cached = null;
|
private T cached = null;
|
||||||
|
|
||||||
public T get() {
|
protected abstract T supply();
|
||||||
|
|
||||||
|
public final T get() {
|
||||||
|
// try to just read from the cached value
|
||||||
lock.readLock().lock();
|
lock.readLock().lock();
|
||||||
try {
|
try {
|
||||||
if (cached != null) {
|
if (cached != null) {
|
||||||
return cached;
|
return cached;
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
// we have to release the read lock, as it is not possible
|
||||||
|
// to acquire the write lock whilst holding a read lock
|
||||||
lock.readLock().unlock();
|
lock.readLock().unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
lock.writeLock().lock();
|
lock.writeLock().lock();
|
||||||
try {
|
try {
|
||||||
// Check again
|
// Since the lock was unlocked momentarily, we need
|
||||||
|
// to check again for a cached value
|
||||||
if (cached != null) {
|
if (cached != null) {
|
||||||
return cached;
|
return cached;
|
||||||
}
|
}
|
||||||
|
|
||||||
cached = supplier.get();
|
// call the supplier and set the cached value
|
||||||
|
cached = supply();
|
||||||
return cached;
|
return cached;
|
||||||
} finally {
|
} finally {
|
||||||
lock.writeLock().unlock();
|
lock.writeLock().unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<T> getIfPresent() {
|
public final Optional<T> getIfPresent() {
|
||||||
lock.readLock().lock();
|
lock.readLock().lock();
|
||||||
try {
|
try {
|
||||||
return Optional.ofNullable(cached);
|
return Optional.ofNullable(cached);
|
||||||
@ -76,7 +81,7 @@ public class Cache<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void invalidate() {
|
public final void invalidate() {
|
||||||
lock.writeLock().lock();
|
lock.writeLock().lock();
|
||||||
try {
|
try {
|
||||||
cached = null;
|
cached = null;
|
||||||
|
@ -61,33 +61,11 @@ public class UserCache implements UserData {
|
|||||||
|
|
||||||
private final LoadingCache<Contexts, PermissionCache> permission = Caffeine.newBuilder()
|
private final LoadingCache<Contexts, PermissionCache> permission = Caffeine.newBuilder()
|
||||||
.expireAfterAccess(10, TimeUnit.MINUTES)
|
.expireAfterAccess(10, TimeUnit.MINUTES)
|
||||||
.build(new CacheLoader<Contexts, PermissionCache>() {
|
.build(new PermissionCacheLoader());
|
||||||
@Override
|
|
||||||
public PermissionCache load(Contexts contexts) {
|
|
||||||
return calculatePermissions(contexts);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PermissionCache reload(Contexts contexts, PermissionCache oldData) {
|
|
||||||
oldData.comparePermissions(user.exportNodes(ExtractedContexts.generate(contexts), true));
|
|
||||||
return oldData;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
private final LoadingCache<MetaContexts, MetaCache> meta = Caffeine.newBuilder()
|
private final LoadingCache<MetaContexts, MetaCache> meta = Caffeine.newBuilder()
|
||||||
.expireAfterAccess(10, TimeUnit.MINUTES)
|
.expireAfterAccess(10, TimeUnit.MINUTES)
|
||||||
.build(new CacheLoader<MetaContexts, MetaCache>() {
|
.build(new MetaCacheLoader());
|
||||||
@Override
|
|
||||||
public MetaCache load(MetaContexts contexts) {
|
|
||||||
return calculateMeta(contexts);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MetaCache reload(MetaContexts contexts, MetaCache oldData) {
|
|
||||||
oldData.loadMeta(user.accumulateMeta(newAccumulator(contexts), null, ExtractedContexts.generate(contexts.getContexts())));
|
|
||||||
return oldData;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PermissionData getPermissionData(@NonNull Contexts contexts) {
|
public PermissionData getPermissionData(@NonNull Contexts contexts) {
|
||||||
@ -108,7 +86,7 @@ public class UserCache implements UserData {
|
|||||||
@Override
|
@Override
|
||||||
public PermissionCache calculatePermissions(@NonNull Contexts contexts) {
|
public PermissionCache calculatePermissions(@NonNull Contexts contexts) {
|
||||||
PermissionCache data = new PermissionCache(contexts, user, user.getPlugin().getCalculatorFactory());
|
PermissionCache data = new PermissionCache(contexts, user, user.getPlugin().getCalculatorFactory());
|
||||||
data.setPermissions(user.exportNodes(ExtractedContexts.generate(contexts), true));
|
data.setPermissions(user.exportNodesAndShorthand(ExtractedContexts.generate(contexts), true));
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,6 +161,32 @@ public class UserCache implements UserData {
|
|||||||
meta.invalidateAll();
|
meta.invalidateAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final class PermissionCacheLoader implements CacheLoader<Contexts, PermissionCache> {
|
||||||
|
@Override
|
||||||
|
public PermissionCache load(Contexts contexts) {
|
||||||
|
return calculatePermissions(contexts);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PermissionCache reload(Contexts contexts, PermissionCache oldData) {
|
||||||
|
oldData.comparePermissions(user.exportNodesAndShorthand(ExtractedContexts.generate(contexts), true));
|
||||||
|
return oldData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class MetaCacheLoader implements CacheLoader<MetaContexts, MetaCache> {
|
||||||
|
@Override
|
||||||
|
public MetaCache load(MetaContexts contexts) {
|
||||||
|
return calculateMeta(contexts);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MetaCache reload(MetaContexts contexts, MetaCache oldData) {
|
||||||
|
oldData.loadMeta(user.accumulateMeta(newAccumulator(contexts), null, ExtractedContexts.generate(contexts.getContexts())));
|
||||||
|
return oldData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static MetaContexts makeFromMetaContextsConfig(Contexts contexts, LuckPermsPlugin plugin) {
|
private static MetaContexts makeFromMetaContextsConfig(Contexts contexts, LuckPermsPlugin plugin) {
|
||||||
return new MetaContexts(
|
return new MetaContexts(
|
||||||
contexts,
|
contexts,
|
||||||
|
@ -57,7 +57,7 @@ public class MetaClear extends SharedSubCommand {
|
|||||||
return CommandResult.NO_PERMISSION;
|
return CommandResult.NO_PERMISSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
int before = holder.getNodes().size();
|
int before = holder.getEnduringNodes().size();
|
||||||
|
|
||||||
MutableContextSet context = ArgumentUtils.handleContext(0, args, plugin);
|
MutableContextSet context = ArgumentUtils.handleContext(0, args, plugin);
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ public class MetaClear extends SharedSubCommand {
|
|||||||
holder.clearMeta(context);
|
holder.clearMeta(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
int changed = before - holder.getNodes().size();
|
int changed = before - holder.getEnduringNodes().size();
|
||||||
if (changed == 1) {
|
if (changed == 1) {
|
||||||
Message.META_CLEAR_SUCCESS_SINGULAR.send(sender, holder.getFriendlyName(), Util.contextSetToString(context), changed);
|
Message.META_CLEAR_SUCCESS_SINGULAR.send(sender, holder.getFriendlyName(), Util.contextSetToString(context), changed);
|
||||||
} else {
|
} else {
|
||||||
|
@ -59,7 +59,7 @@ public class HolderClear<T extends PermissionHolder> extends SubCommand<T> {
|
|||||||
return CommandResult.NO_PERMISSION;
|
return CommandResult.NO_PERMISSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
int before = holder.getNodes().size();
|
int before = holder.getEnduringNodes().size();
|
||||||
|
|
||||||
MutableContextSet context = ArgumentUtils.handleContext(0, args, plugin);
|
MutableContextSet context = ArgumentUtils.handleContext(0, args, plugin);
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ public class HolderClear<T extends PermissionHolder> extends SubCommand<T> {
|
|||||||
holder.clearNodes(context);
|
holder.clearNodes(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
int changed = before - holder.getNodes().size();
|
int changed = before - holder.getEnduringNodes().size();
|
||||||
if (changed == 1) {
|
if (changed == 1) {
|
||||||
Message.CLEAR_SUCCESS_SINGULAR.send(sender, holder.getFriendlyName(), Util.contextSetToString(context), changed);
|
Message.CLEAR_SUCCESS_SINGULAR.send(sender, holder.getFriendlyName(), Util.contextSetToString(context), changed);
|
||||||
} else {
|
} else {
|
||||||
|
@ -83,7 +83,7 @@ public class HolderEditor<T extends PermissionHolder> extends SubCommand<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
JsonObject data = new JsonObject();
|
JsonObject data = new JsonObject();
|
||||||
Set<NodeModel> nodes = holder.getNodes().values().stream().map(NodeModel::fromNode).collect(Collectors.toCollection(LinkedHashSet::new));
|
Set<NodeModel> nodes = holder.getEnduringNodes().values().stream().map(NodeModel::fromNode).collect(Collectors.toCollection(LinkedHashSet::new));
|
||||||
data.add("nodes", serializePermissions(nodes));
|
data.add("nodes", serializePermissions(nodes));
|
||||||
data.addProperty("who", id(holder));
|
data.addProperty("who", id(holder));
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ public class HolderShowTracks<T extends PermissionHolder> extends SubCommand<T>
|
|||||||
return CommandResult.LOADING_ERROR;
|
return CommandResult.LOADING_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<Node> nodes = holder.getNodes().values().stream()
|
Set<Node> nodes = holder.getEnduringNodes().values().stream()
|
||||||
.filter(Node::isGroupNode)
|
.filter(Node::isGroupNode)
|
||||||
.filter(Node::isPermanent)
|
.filter(Node::isPermanent)
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
|
@ -57,7 +57,7 @@ public class ParentClear extends SharedSubCommand {
|
|||||||
return CommandResult.NO_PERMISSION;
|
return CommandResult.NO_PERMISSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
int before = holder.getNodes().size();
|
int before = holder.getEnduringNodes().size();
|
||||||
|
|
||||||
MutableContextSet context = ArgumentUtils.handleContext(0, args, plugin);
|
MutableContextSet context = ArgumentUtils.handleContext(0, args, plugin);
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ public class ParentClear extends SharedSubCommand {
|
|||||||
holder.clearParents(context, true);
|
holder.clearParents(context, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
int changed = before - holder.getNodes().size();
|
int changed = before - holder.getEnduringNodes().size();
|
||||||
if (changed == 1) {
|
if (changed == 1) {
|
||||||
Message.PARENT_CLEAR_SUCCESS_SINGULAR.send(sender, holder.getFriendlyName(), Util.contextSetToString(context), changed);
|
Message.PARENT_CLEAR_SUCCESS_SINGULAR.send(sender, holder.getFriendlyName(), Util.contextSetToString(context), changed);
|
||||||
} else {
|
} else {
|
||||||
|
@ -84,7 +84,7 @@ public class ParentClearTrack extends SharedSubCommand {
|
|||||||
return CommandResult.STATE_ERROR;
|
return CommandResult.STATE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
int before = holder.getNodes().size();
|
int before = holder.getEnduringNodes().size();
|
||||||
|
|
||||||
MutableContextSet context = ArgumentUtils.handleContext(1, args, plugin);
|
MutableContextSet context = ArgumentUtils.handleContext(1, args, plugin);
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ public class ParentClearTrack extends SharedSubCommand {
|
|||||||
plugin.getUserManager().giveDefaultIfNeeded(((User) holder), false);
|
plugin.getUserManager().giveDefaultIfNeeded(((User) holder), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
int changed = before - holder.getNodes().size();
|
int changed = before - holder.getEnduringNodes().size();
|
||||||
|
|
||||||
if (changed == 1) {
|
if (changed == 1) {
|
||||||
Message.PARENT_CLEAR_TRACK_SUCCESS_SINGULAR.send(sender, holder.getFriendlyName(), track.getName(), Util.contextSetToString(context), changed);
|
Message.PARENT_CLEAR_TRACK_SUCCESS_SINGULAR.send(sender, holder.getFriendlyName(), track.getName(), Util.contextSetToString(context), changed);
|
||||||
|
@ -69,11 +69,11 @@ public class ParentInfo extends SharedSubCommand {
|
|||||||
return CommandResult.NO_PERMISSION;
|
return CommandResult.NO_PERMISSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
Component ent = permGroupsToMessage(holder.mergePermissionsToSortedSet(), holder, label);
|
Component ent = permGroupsToMessage(holder.getOwnNodesSorted(), holder, label);
|
||||||
Message.LISTNODES.send(sender, holder.getFriendlyName());
|
Message.LISTNODES.send(sender, holder.getFriendlyName());
|
||||||
sender.sendMessage(ent);
|
sender.sendMessage(ent);
|
||||||
|
|
||||||
Component tempEnt = tempGroupsToMessage(holder.mergePermissionsToSortedSet(), holder, label);
|
Component tempEnt = tempGroupsToMessage(holder.getOwnNodesSorted(), holder, label);
|
||||||
Message.LISTNODES_TEMP.send(sender, holder.getFriendlyName());
|
Message.LISTNODES_TEMP.send(sender, holder.getFriendlyName());
|
||||||
sender.sendMessage(tempEnt);
|
sender.sendMessage(tempEnt);
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ public class PermissionInfo extends SharedSubCommand {
|
|||||||
|
|
||||||
int page = ArgumentUtils.handleIntOrElse(0, args, 1);
|
int page = ArgumentUtils.handleIntOrElse(0, args, 1);
|
||||||
|
|
||||||
Map.Entry<Component, String> ent = nodesToMessage(false, filter, holder.mergePermissionsToSortedSet(), holder, label, page, sender.isConsole());
|
Map.Entry<Component, String> ent = nodesToMessage(false, filter, holder.getOwnNodesSorted(), holder, label, page, sender.isConsole());
|
||||||
if (ent.getValue() != null) {
|
if (ent.getValue() != null) {
|
||||||
Message.LISTNODES_WITH_PAGE.send(sender, holder.getFriendlyName(), ent.getValue());
|
Message.LISTNODES_WITH_PAGE.send(sender, holder.getFriendlyName(), ent.getValue());
|
||||||
sender.sendMessage(ent.getKey());
|
sender.sendMessage(ent.getKey());
|
||||||
@ -97,7 +97,7 @@ public class PermissionInfo extends SharedSubCommand {
|
|||||||
sender.sendMessage(ent.getKey());
|
sender.sendMessage(ent.getKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
Map.Entry<Component, String> tempEnt = nodesToMessage(true, filter, holder.mergePermissionsToSortedSet(), holder, label, page, sender.isConsole());
|
Map.Entry<Component, String> tempEnt = nodesToMessage(true, filter, holder.getOwnNodesSorted(), holder, label, page, sender.isConsole());
|
||||||
if (tempEnt.getValue() != null) {
|
if (tempEnt.getValue() != null) {
|
||||||
Message.LISTNODES_TEMP_WITH_PAGE.send(sender, holder.getFriendlyName(), tempEnt.getValue());
|
Message.LISTNODES_TEMP_WITH_PAGE.send(sender, holder.getFriendlyName(), tempEnt.getValue());
|
||||||
sender.sendMessage(tempEnt.getKey());
|
sender.sendMessage(tempEnt.getKey());
|
||||||
|
@ -74,7 +74,7 @@ public class GroupClone extends SubCommand<Group> {
|
|||||||
return CommandResult.NO_PERMISSION;
|
return CommandResult.NO_PERMISSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
newGroup.replaceNodes(group.getNodes());
|
newGroup.replaceEnduringNodes(group.getEnduringNodes());
|
||||||
|
|
||||||
Message.CLONE_SUCCESS.send(sender, group.getName(), newGroup.getName());
|
Message.CLONE_SUCCESS.send(sender, group.getName(), newGroup.getName());
|
||||||
LogEntry.build().actor(sender).acted(group).action("clone " + newGroup.getName()).build().submit(plugin, sender);
|
LogEntry.build().actor(sender).acted(group).action("clone " + newGroup.getName()).build().submit(plugin, sender);
|
||||||
|
@ -68,12 +68,12 @@ public class GroupInfo extends SubCommand<Group> {
|
|||||||
group.getMetaNodes().size()
|
group.getMetaNodes().size()
|
||||||
);
|
);
|
||||||
|
|
||||||
Set<Node> parents = group.mergePermissions().stream()
|
Set<Node> parents = group.getOwnNodesSet().stream()
|
||||||
.filter(Node::isGroupNode)
|
.filter(Node::isGroupNode)
|
||||||
.filter(Node::isPermanent)
|
.filter(Node::isPermanent)
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
Set<Node> tempParents = group.mergePermissions().stream()
|
Set<Node> tempParents = group.getOwnNodesSet().stream()
|
||||||
.filter(Node::isGroupNode)
|
.filter(Node::isGroupNode)
|
||||||
.filter(Node::isTemporary)
|
.filter(Node::isTemporary)
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
|
@ -77,7 +77,7 @@ public class GroupRename extends SubCommand<Group> {
|
|||||||
return CommandResult.FAILURE;
|
return CommandResult.FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
newGroup.replaceNodes(group.getNodes());
|
newGroup.replaceEnduringNodes(group.getEnduringNodes());
|
||||||
|
|
||||||
Message.RENAME_SUCCESS.send(sender, group.getName(), newGroup.getName());
|
Message.RENAME_SUCCESS.send(sender, group.getName(), newGroup.getName());
|
||||||
LogEntry.build().actor(sender).acted(group).action("rename " + newGroup.getName()).build().submit(plugin, sender);
|
LogEntry.build().actor(sender).acted(group).action("rename " + newGroup.getName()).build().submit(plugin, sender);
|
||||||
|
@ -141,7 +141,7 @@ public class ApplyEditsCommand extends SingleCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Set<NodeModel> nodes = deserializePermissions(data.getAsJsonArray("nodes"));
|
Set<NodeModel> nodes = deserializePermissions(data.getAsJsonArray("nodes"));
|
||||||
holder.setNodes(nodes.stream().map(NodeModel::toNode).collect(Collectors.toSet()));
|
holder.setEnduringNodes(nodes.stream().map(NodeModel::toNode).collect(Collectors.toSet()));
|
||||||
Message.APPLY_EDITS_SUCCESS.send(sender, nodes.size(), holder.getFriendlyName());
|
Message.APPLY_EDITS_SUCCESS.send(sender, nodes.size(), holder.getFriendlyName());
|
||||||
SharedSubCommand.save(holder, sender, plugin);
|
SharedSubCommand.save(holder, sender, plugin);
|
||||||
return CommandResult.SUCCESS;
|
return CommandResult.SUCCESS;
|
||||||
|
@ -97,7 +97,7 @@ public class UserDemote extends SubCommand<User> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load applicable groups
|
// Load applicable groups
|
||||||
Set<Node> nodes = user.getNodes().values().stream()
|
Set<Node> nodes = user.getEnduringNodes().values().stream()
|
||||||
.filter(Node::isGroupNode)
|
.filter(Node::isGroupNode)
|
||||||
.filter(Node::getValue)
|
.filter(Node::getValue)
|
||||||
.filter(node -> node.getFullContexts().makeImmutable().equals(context.makeImmutable()))
|
.filter(node -> node.getFullContexts().makeImmutable().equals(context.makeImmutable()))
|
||||||
|
@ -72,12 +72,12 @@ public class UserInfo extends SubCommand<User> {
|
|||||||
user.getMetaNodes().size()
|
user.getMetaNodes().size()
|
||||||
);
|
);
|
||||||
|
|
||||||
Set<Node> parents = user.mergePermissions().stream()
|
Set<Node> parents = user.getOwnNodesSet().stream()
|
||||||
.filter(Node::isGroupNode)
|
.filter(Node::isGroupNode)
|
||||||
.filter(Node::isPermanent)
|
.filter(Node::isPermanent)
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
Set<Node> tempParents = user.mergePermissions().stream()
|
Set<Node> tempParents = user.getOwnNodesSet().stream()
|
||||||
.filter(Node::isGroupNode)
|
.filter(Node::isGroupNode)
|
||||||
.filter(Node::isTemporary)
|
.filter(Node::isTemporary)
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
|
@ -95,7 +95,7 @@ public class UserPromote extends SubCommand<User> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load applicable groups
|
// Load applicable groups
|
||||||
Set<Node> nodes = user.getNodes().values().stream()
|
Set<Node> nodes = user.getEnduringNodes().values().stream()
|
||||||
.filter(Node::isGroupNode)
|
.filter(Node::isGroupNode)
|
||||||
.filter(Node::getValue)
|
.filter(Node::getValue)
|
||||||
.filter(node -> node.getFullContexts().makeImmutable().equals(context.makeImmutable()))
|
.filter(node -> node.getFullContexts().makeImmutable().equals(context.makeImmutable()))
|
||||||
|
@ -131,7 +131,7 @@ public class Exporter implements Runnable {
|
|||||||
})
|
})
|
||||||
.forEach(group -> {
|
.forEach(group -> {
|
||||||
write(writer, "# Export group: " + group.getName());
|
write(writer, "# Export group: " + group.getName());
|
||||||
for (Node node : group.getNodes().values()) {
|
for (Node node : group.getEnduringNodes().values()) {
|
||||||
write(writer, NodeFactory.nodeAsCommand(node, group.getName(), true, true));
|
write(writer, NodeFactory.nodeAsCommand(node, group.getName(), true, true));
|
||||||
}
|
}
|
||||||
write(writer, "");
|
write(writer, "");
|
||||||
@ -234,7 +234,7 @@ public class Exporter implements Runnable {
|
|||||||
output.add("# Export user: " + user.getUuid().toString() + " - " + user.getName().orElse("unknown username"));
|
output.add("# Export user: " + user.getUuid().toString() + " - " + user.getName().orElse("unknown username"));
|
||||||
|
|
||||||
boolean inDefault = false;
|
boolean inDefault = false;
|
||||||
for (Node node : user.getNodes().values()) {
|
for (Node node : user.getEnduringNodes().values()) {
|
||||||
if (node.isGroupNode() && node.getGroupName().equalsIgnoreCase("default")) {
|
if (node.isGroupNode() && node.getGroupName().equalsIgnoreCase("default")) {
|
||||||
inDefault = true;
|
inDefault = true;
|
||||||
continue;
|
continue;
|
||||||
|
@ -67,8 +67,8 @@ import me.lucko.luckperms.common.model.PermissionHolder;
|
|||||||
import me.lucko.luckperms.common.model.Track;
|
import me.lucko.luckperms.common.model.Track;
|
||||||
import me.lucko.luckperms.common.model.User;
|
import me.lucko.luckperms.common.model.User;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ public final class EventFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void handleGroupDelete(Group group, DeletionCause cause) {
|
public void handleGroupDelete(Group group, DeletionCause cause) {
|
||||||
EventGroupDelete event = new EventGroupDelete(group.getName(), ImmutableSet.copyOf(group.getNodes().values()), cause);
|
EventGroupDelete event = new EventGroupDelete(group.getName(), ImmutableSet.copyOf(group.getEnduringNodes().values()), cause);
|
||||||
fireEvent(event);
|
fireEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,17 +114,17 @@ public final class EventFactory {
|
|||||||
return cancel.get();
|
return cancel.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleNodeAdd(Node node, PermissionHolder target, Set<Node> before, Set<Node> after) {
|
public void handleNodeAdd(Node node, PermissionHolder target, Collection<Node> before, Collection<Node> after) {
|
||||||
EventNodeAdd event = new EventNodeAdd(node, target.getDelegate(), ImmutableSet.copyOf(before), ImmutableSet.copyOf(after));
|
EventNodeAdd event = new EventNodeAdd(node, target.getDelegate(), ImmutableSet.copyOf(before), ImmutableSet.copyOf(after));
|
||||||
fireEvent(event);
|
fireEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleNodeClear(PermissionHolder target, Set<Node> before, Set<Node> after) {
|
public void handleNodeClear(PermissionHolder target, Collection<Node> before, Collection<Node> after) {
|
||||||
EventNodeClear event = new EventNodeClear(target.getDelegate(), ImmutableSet.copyOf(before), ImmutableSet.copyOf(after));
|
EventNodeClear event = new EventNodeClear(target.getDelegate(), ImmutableSet.copyOf(before), ImmutableSet.copyOf(after));
|
||||||
fireEvent(event);
|
fireEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleNodeRemove(Node node, PermissionHolder target, Set<Node> before, Set<Node> after) {
|
public void handleNodeRemove(Node node, PermissionHolder target, Collection<Node> before, Collection<Node> after) {
|
||||||
EventNodeRemove event = new EventNodeRemove(node, target.getDelegate(), ImmutableSet.copyOf(before), ImmutableSet.copyOf(after));
|
EventNodeRemove event = new EventNodeRemove(node, target.getDelegate(), ImmutableSet.copyOf(before), ImmutableSet.copyOf(after));
|
||||||
fireEvent(event);
|
fireEvent(event);
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ public class GenericUserManager extends AbstractManager<UserIdentifier, User> im
|
|||||||
boolean hasGroup = false;
|
boolean hasGroup = false;
|
||||||
|
|
||||||
if (user.getPrimaryGroup().getStoredValue() != null && !user.getPrimaryGroup().getStoredValue().isEmpty()) {
|
if (user.getPrimaryGroup().getStoredValue() != null && !user.getPrimaryGroup().getStoredValue().isEmpty()) {
|
||||||
for (Node node : user.getNodes().values()) {
|
for (Node node : user.getEnduringNodes().values()) {
|
||||||
if (node.hasSpecificContext()) {
|
if (node.hasSpecificContext()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -85,11 +85,11 @@ public class GenericUserManager extends AbstractManager<UserIdentifier, User> im
|
|||||||
* @return true if the user should be saved
|
* @return true if the user should be saved
|
||||||
*/
|
*/
|
||||||
public static boolean shouldSave(User user) {
|
public static boolean shouldSave(User user) {
|
||||||
if (user.getNodes().size() != 1) {
|
if (user.getEnduringNodes().size() != 1) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Node node : user.getNodes().values()) {
|
for (Node node : user.getEnduringNodes().values()) {
|
||||||
// There's only one.
|
// There's only one.
|
||||||
if (!node.isGroupNode()) {
|
if (!node.isGroupNode()) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -50,12 +50,12 @@ public class Group extends PermissionHolder implements Identifiable<String> {
|
|||||||
|
|
||||||
public Group(String name, LuckPermsPlugin plugin) {
|
public Group(String name, LuckPermsPlugin plugin) {
|
||||||
super(name, plugin);
|
super(name, plugin);
|
||||||
this.name = name;
|
this.name = name.toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return name.toLowerCase();
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRawDisplayName() {
|
public String getRawDisplayName() {
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -57,6 +57,6 @@ public final class ImmutableLocalizedNode implements LocalizedNode {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
return node.equals(obj);
|
return this == obj || node.equals(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
package me.lucko.luckperms.common.node;
|
package me.lucko.luckperms.common.node;
|
||||||
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
|
|
||||||
@ -44,7 +43,6 @@ import me.lucko.luckperms.common.utils.PatternCache;
|
|||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@ -56,82 +54,8 @@ import java.util.stream.Collectors;
|
|||||||
* An immutable permission node
|
* An immutable permission node
|
||||||
*/
|
*/
|
||||||
@ToString(of = {"permission", "value", "override", "server", "world", "expireAt", "contexts"})
|
@ToString(of = {"permission", "value", "override", "server", "world", "expireAt", "contexts"})
|
||||||
@EqualsAndHashCode(of = {"permission", "value", "override", "server", "world", "expireAt", "contexts"})
|
|
||||||
public final class ImmutableNode implements Node {
|
public final class ImmutableNode implements Node {
|
||||||
|
|
||||||
private static boolean shouldApply(String str, boolean applyRegex, String thisStr) {
|
|
||||||
if (str.equalsIgnoreCase(thisStr)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<String> expandedStr = ShorthandParser.parseShorthand(str, false);
|
|
||||||
Set<String> expandedThisStr = ShorthandParser.parseShorthand(thisStr, false);
|
|
||||||
|
|
||||||
if (str.toLowerCase().startsWith("r=") && applyRegex) {
|
|
||||||
Pattern p = PatternCache.compile(str.substring(2));
|
|
||||||
if (p == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String s : expandedThisStr) {
|
|
||||||
if (p.matcher(s).matches()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (thisStr.toLowerCase().startsWith("r=") && applyRegex) {
|
|
||||||
Pattern p = PatternCache.compile(thisStr.substring(2));
|
|
||||||
if (p == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String s : expandedStr) {
|
|
||||||
if (p.matcher(s).matches()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (expandedStr.size() <= 1 && expandedThisStr.size() <= 1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String t : expandedThisStr) {
|
|
||||||
for (String s : expandedStr) {
|
|
||||||
if (t.equalsIgnoreCase(s)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
|
||||||
private static boolean isInt(String a, String b) {
|
|
||||||
try {
|
|
||||||
Integer.parseInt(a);
|
|
||||||
Integer.parseInt(b);
|
|
||||||
return true;
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isChar(String a, String b) {
|
|
||||||
return a.length() == 1 && b.length() == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Set<String> getCharRange(char a, char b) {
|
|
||||||
Set<String> s = new HashSet<>();
|
|
||||||
for (char c = a; c <= b; c++) {
|
|
||||||
s.add(Character.toString(c));
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private final String permission;
|
private final String permission;
|
||||||
|
|
||||||
@ -509,6 +433,49 @@ public final class ImmutableNode implements Node {
|
|||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (o == this) return true;
|
||||||
|
if (!(o instanceof Node)) return false;
|
||||||
|
final Node other = (Node) o;
|
||||||
|
|
||||||
|
if (!this.permission.equals(other.getPermission())) return false;
|
||||||
|
if (!this.getValue().equals(other.getValue())) return false;
|
||||||
|
if (this.override != other.isOverride()) return false;
|
||||||
|
|
||||||
|
final String thisServer = this.getServer().orElse(null);
|
||||||
|
final String otherServer = other.getServer().orElse(null);
|
||||||
|
if (thisServer == null ? otherServer != null : !thisServer.equals(otherServer)) return false;
|
||||||
|
|
||||||
|
final String thisWorld = this.getWorld().orElse(null);
|
||||||
|
final String otherWorld = other.getWorld().orElse(null);
|
||||||
|
if (thisWorld == null ? otherWorld != null : !thisWorld.equals(otherWorld)) return false;
|
||||||
|
|
||||||
|
final long thisExpireAt = this.isTemporary() ? this.getExpiryUnixTime() : 0L;
|
||||||
|
final long otherExpireAt = other.isTemporary() ? other.getExpiryUnixTime() : 0L;
|
||||||
|
|
||||||
|
return thisExpireAt == otherExpireAt && this.getContexts().equals(other.getContexts());
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
final int PRIME = 59;
|
||||||
|
int result = 1;
|
||||||
|
|
||||||
|
result = result * PRIME + this.permission.hashCode();
|
||||||
|
result = result * PRIME + Boolean.hashCode(this.value);
|
||||||
|
result = result * PRIME + (this.override ? 79 : 97);
|
||||||
|
|
||||||
|
final String server = this.getServer().orElse(null);
|
||||||
|
result = result * PRIME + (server == null ? 43 : server.hashCode());
|
||||||
|
|
||||||
|
final String world = this.getWorld().orElse(null);
|
||||||
|
result = result * PRIME + (world == null ? 43 : world.hashCode());
|
||||||
|
|
||||||
|
result = result * PRIME + (int) (this.expireAt >>> 32 ^ this.expireAt);
|
||||||
|
result = result * PRIME + this.contexts.hashCode();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equalsIgnoringValue(Node other) {
|
public boolean equalsIgnoringValue(Node other) {
|
||||||
if (!other.getPermission().equalsIgnoreCase(this.getPermission())) {
|
if (!other.getPermission().equalsIgnoreCase(this.getPermission())) {
|
||||||
@ -619,4 +586,55 @@ public final class ImmutableNode implements Node {
|
|||||||
public String getKey() {
|
public String getKey() {
|
||||||
return getPermission();
|
return getPermission();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean shouldApply(String str, boolean applyRegex, String thisStr) {
|
||||||
|
if (str.equalsIgnoreCase(thisStr)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> expandedStr = ShorthandParser.parseShorthand(str, false);
|
||||||
|
Set<String> expandedThisStr = ShorthandParser.parseShorthand(thisStr, false);
|
||||||
|
|
||||||
|
if (str.toLowerCase().startsWith("r=") && applyRegex) {
|
||||||
|
Pattern p = PatternCache.compile(str.substring(2));
|
||||||
|
if (p == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String s : expandedThisStr) {
|
||||||
|
if (p.matcher(s).matches()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thisStr.toLowerCase().startsWith("r=") && applyRegex) {
|
||||||
|
Pattern p = PatternCache.compile(thisStr.substring(2));
|
||||||
|
if (p == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String s : expandedStr) {
|
||||||
|
if (p.matcher(s).matches()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expandedStr.size() <= 1 && expandedThisStr.size() <= 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String t : expandedThisStr) {
|
||||||
|
for (String s : expandedStr) {
|
||||||
|
if (t.equalsIgnoreCase(s)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ public class NodeComparator implements Comparator<Node> {
|
|||||||
return o1.getWildcardLevel() > o2.getWildcardLevel() ? 1 : -1;
|
return o1.getWildcardLevel() > o2.getWildcardLevel() ? 1 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NodePriorityComparator.get().compareStrings(o1.getPermission(), o2.getPermission()) == 1 ? -1 : 1;
|
return NodeWithContextComparator.get().compareStrings(o1.getPermission(), o2.getPermission()) == 1 ? -1 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -43,10 +43,10 @@ import java.util.Locale;
|
|||||||
* Compares permission nodes based upon their supposed "priority".
|
* Compares permission nodes based upon their supposed "priority".
|
||||||
*/
|
*/
|
||||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
public class NodePriorityComparator implements Comparator<LocalizedNode> {
|
public class NodeWithContextComparator implements Comparator<LocalizedNode> {
|
||||||
|
|
||||||
private static final NodePriorityComparator INSTANCE = new NodePriorityComparator();
|
private static final NodeWithContextComparator INSTANCE = new NodeWithContextComparator();
|
||||||
public static NodePriorityComparator get() {
|
public static NodeWithContextComparator get() {
|
||||||
return INSTANCE;
|
return INSTANCE;
|
||||||
}
|
}
|
||||||
public static Comparator<LocalizedNode> reverse() {
|
public static Comparator<LocalizedNode> reverse() {
|
@ -55,7 +55,7 @@ public class ParentsByWeightHolder extends StoredHolder {
|
|||||||
|
|
||||||
Contexts contexts = user.getPlugin().getContextForUser(user);
|
Contexts contexts = user.getPlugin().getContextForUser(user);
|
||||||
ContextSet contextSet = contexts != null ? contexts.getContexts() : user.getPlugin().getContextManager().getStaticContexts();
|
ContextSet contextSet = contexts != null ? contexts.getContexts() : user.getPlugin().getContextManager().getStaticContexts();
|
||||||
cachedValue = user.flattenAndMergeNodesToList(contextSet).stream()
|
cachedValue = user.filterNodes(contextSet).stream()
|
||||||
.filter(Node::isGroupNode)
|
.filter(Node::isGroupNode)
|
||||||
.filter(Node::getValue)
|
.filter(Node::getValue)
|
||||||
.map(n -> Optional.ofNullable(user.getPlugin().getGroupManager().getIfLoaded(n.getGroupName())))
|
.map(n -> Optional.ofNullable(user.getPlugin().getGroupManager().getIfLoaded(n.getGroupName())))
|
||||||
|
@ -170,7 +170,7 @@ public class JSONBacking extends FlatfileBacking {
|
|||||||
|
|
||||||
Set<NodeModel> data = deserializePermissions(object.get("permissions").getAsJsonArray());
|
Set<NodeModel> data = deserializePermissions(object.get("permissions").getAsJsonArray());
|
||||||
Set<Node> nodes = data.stream().map(NodeModel::toNode).collect(Collectors.toSet());
|
Set<Node> nodes = data.stream().map(NodeModel::toNode).collect(Collectors.toSet());
|
||||||
user.setNodes(nodes);
|
user.setEnduringNodes(nodes);
|
||||||
user.setName(name, true);
|
user.setName(name, true);
|
||||||
|
|
||||||
boolean save = plugin.getUserManager().giveDefaultIfNeeded(user, false);
|
boolean save = plugin.getUserManager().giveDefaultIfNeeded(user, false);
|
||||||
@ -222,7 +222,7 @@ public class JSONBacking extends FlatfileBacking {
|
|||||||
data.addProperty("name", user.getName().orElse("null"));
|
data.addProperty("name", user.getName().orElse("null"));
|
||||||
data.addProperty("primaryGroup", user.getPrimaryGroup().getStoredValue());
|
data.addProperty("primaryGroup", user.getPrimaryGroup().getStoredValue());
|
||||||
|
|
||||||
Set<NodeModel> nodes = user.getNodes().values().stream().map(NodeModel::fromNode).collect(Collectors.toCollection(LinkedHashSet::new));
|
Set<NodeModel> nodes = user.getEnduringNodes().values().stream().map(NodeModel::fromNode).collect(Collectors.toCollection(LinkedHashSet::new));
|
||||||
data.add("permissions", serializePermissions(nodes));
|
data.add("permissions", serializePermissions(nodes));
|
||||||
|
|
||||||
return writeElementToFile(userFile, data);
|
return writeElementToFile(userFile, data);
|
||||||
@ -311,7 +311,7 @@ public class JSONBacking extends FlatfileBacking {
|
|||||||
JsonObject object = readObjectFromFile(groupFile);
|
JsonObject object = readObjectFromFile(groupFile);
|
||||||
Set<NodeModel> data = deserializePermissions(object.get("permissions").getAsJsonArray());
|
Set<NodeModel> data = deserializePermissions(object.get("permissions").getAsJsonArray());
|
||||||
Set<Node> nodes = data.stream().map(NodeModel::toNode).collect(Collectors.toSet());
|
Set<Node> nodes = data.stream().map(NodeModel::toNode).collect(Collectors.toSet());
|
||||||
group.setNodes(nodes);
|
group.setEnduringNodes(nodes);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
groupFile.createNewFile();
|
groupFile.createNewFile();
|
||||||
@ -319,7 +319,7 @@ public class JSONBacking extends FlatfileBacking {
|
|||||||
JsonObject data = new JsonObject();
|
JsonObject data = new JsonObject();
|
||||||
data.addProperty("name", group.getName());
|
data.addProperty("name", group.getName());
|
||||||
|
|
||||||
Set<NodeModel> nodes = group.getNodes().values().stream().map(NodeModel::fromNode).collect(Collectors.toCollection(LinkedHashSet::new));
|
Set<NodeModel> nodes = group.getEnduringNodes().values().stream().map(NodeModel::fromNode).collect(Collectors.toCollection(LinkedHashSet::new));
|
||||||
data.add("permissions", serializePermissions(nodes));
|
data.add("permissions", serializePermissions(nodes));
|
||||||
|
|
||||||
return writeElementToFile(groupFile, data);
|
return writeElementToFile(groupFile, data);
|
||||||
@ -346,7 +346,7 @@ public class JSONBacking extends FlatfileBacking {
|
|||||||
JsonObject object = readObjectFromFile(groupFile);
|
JsonObject object = readObjectFromFile(groupFile);
|
||||||
Set<NodeModel> data = deserializePermissions(object.get("permissions").getAsJsonArray());
|
Set<NodeModel> data = deserializePermissions(object.get("permissions").getAsJsonArray());
|
||||||
Set<Node> nodes = data.stream().map(NodeModel::toNode).collect(Collectors.toSet());
|
Set<Node> nodes = data.stream().map(NodeModel::toNode).collect(Collectors.toSet());
|
||||||
group.setNodes(nodes);
|
group.setEnduringNodes(nodes);
|
||||||
return true;
|
return true;
|
||||||
}, false);
|
}, false);
|
||||||
} finally {
|
} finally {
|
||||||
@ -368,7 +368,7 @@ public class JSONBacking extends FlatfileBacking {
|
|||||||
|
|
||||||
JsonObject data = new JsonObject();
|
JsonObject data = new JsonObject();
|
||||||
data.addProperty("name", group.getName());
|
data.addProperty("name", group.getName());
|
||||||
Set<NodeModel> nodes = group.getNodes().values().stream().map(NodeModel::fromNode).collect(Collectors.toCollection(LinkedHashSet::new));
|
Set<NodeModel> nodes = group.getEnduringNodes().values().stream().map(NodeModel::fromNode).collect(Collectors.toCollection(LinkedHashSet::new));
|
||||||
data.add("permissions", serializePermissions(nodes));
|
data.add("permissions", serializePermissions(nodes));
|
||||||
return writeElementToFile(groupFile, data);
|
return writeElementToFile(groupFile, data);
|
||||||
}, false);
|
}, false);
|
||||||
|
@ -174,7 +174,7 @@ public class YAMLBacking extends FlatfileBacking {
|
|||||||
|
|
||||||
Set<NodeModel> data = deserializePermissions((List<Object>) values.get("permissions"));
|
Set<NodeModel> data = deserializePermissions((List<Object>) values.get("permissions"));
|
||||||
Set<Node> nodes = data.stream().map(NodeModel::toNode).collect(Collectors.toSet());
|
Set<Node> nodes = data.stream().map(NodeModel::toNode).collect(Collectors.toSet());
|
||||||
user.setNodes(nodes);
|
user.setEnduringNodes(nodes);
|
||||||
user.setName(name, true);
|
user.setName(name, true);
|
||||||
|
|
||||||
boolean save = plugin.getUserManager().giveDefaultIfNeeded(user, false);
|
boolean save = plugin.getUserManager().giveDefaultIfNeeded(user, false);
|
||||||
@ -224,7 +224,7 @@ public class YAMLBacking extends FlatfileBacking {
|
|||||||
values.put("name", user.getName().orElse("null"));
|
values.put("name", user.getName().orElse("null"));
|
||||||
values.put("primary-group", user.getPrimaryGroup().getStoredValue());
|
values.put("primary-group", user.getPrimaryGroup().getStoredValue());
|
||||||
|
|
||||||
Set<NodeModel> data = user.getNodes().values().stream().map(NodeModel::fromNode).collect(Collectors.toCollection(LinkedHashSet::new));
|
Set<NodeModel> data = user.getEnduringNodes().values().stream().map(NodeModel::fromNode).collect(Collectors.toCollection(LinkedHashSet::new));
|
||||||
values.put("permissions", serializePermissions(data));
|
values.put("permissions", serializePermissions(data));
|
||||||
|
|
||||||
return writeMapToFile(userFile, values);
|
return writeMapToFile(userFile, values);
|
||||||
@ -313,14 +313,14 @@ public class YAMLBacking extends FlatfileBacking {
|
|||||||
Map<String, Object> values = readMapFromFile(groupFile);
|
Map<String, Object> values = readMapFromFile(groupFile);
|
||||||
Set<NodeModel> data = deserializePermissions((List<Object>) values.get("permissions"));
|
Set<NodeModel> data = deserializePermissions((List<Object>) values.get("permissions"));
|
||||||
Set<Node> nodes = data.stream().map(NodeModel::toNode).collect(Collectors.toSet());
|
Set<Node> nodes = data.stream().map(NodeModel::toNode).collect(Collectors.toSet());
|
||||||
group.setNodes(nodes);
|
group.setEnduringNodes(nodes);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
groupFile.createNewFile();
|
groupFile.createNewFile();
|
||||||
|
|
||||||
Map<String, Object> values = new LinkedHashMap<>();
|
Map<String, Object> values = new LinkedHashMap<>();
|
||||||
values.put("name", group.getName());
|
values.put("name", group.getName());
|
||||||
Set<NodeModel> data = group.getNodes().values().stream().map(NodeModel::fromNode).collect(Collectors.toCollection(LinkedHashSet::new));
|
Set<NodeModel> data = group.getEnduringNodes().values().stream().map(NodeModel::fromNode).collect(Collectors.toCollection(LinkedHashSet::new));
|
||||||
values.put("permissions", serializePermissions(data));
|
values.put("permissions", serializePermissions(data));
|
||||||
return writeMapToFile(groupFile, values);
|
return writeMapToFile(groupFile, values);
|
||||||
}
|
}
|
||||||
@ -346,7 +346,7 @@ public class YAMLBacking extends FlatfileBacking {
|
|||||||
Map<String, Object> values = readMapFromFile(groupFile);
|
Map<String, Object> values = readMapFromFile(groupFile);
|
||||||
Set<NodeModel> data = deserializePermissions((List<Object>) values.get("permissions"));
|
Set<NodeModel> data = deserializePermissions((List<Object>) values.get("permissions"));
|
||||||
Set<Node> nodes = data.stream().map(NodeModel::toNode).collect(Collectors.toSet());
|
Set<Node> nodes = data.stream().map(NodeModel::toNode).collect(Collectors.toSet());
|
||||||
group.setNodes(nodes);
|
group.setEnduringNodes(nodes);
|
||||||
return true;
|
return true;
|
||||||
}, false);
|
}, false);
|
||||||
} finally {
|
} finally {
|
||||||
@ -368,7 +368,7 @@ public class YAMLBacking extends FlatfileBacking {
|
|||||||
|
|
||||||
Map<String, Object> values = new LinkedHashMap<>();
|
Map<String, Object> values = new LinkedHashMap<>();
|
||||||
values.put("name", group.getName());
|
values.put("name", group.getName());
|
||||||
Set<NodeModel> data = group.getNodes().values().stream().map(NodeModel::fromNode).collect(Collectors.toCollection(LinkedHashSet::new));
|
Set<NodeModel> data = group.getEnduringNodes().values().stream().map(NodeModel::fromNode).collect(Collectors.toCollection(LinkedHashSet::new));
|
||||||
values.put("permissions", serializePermissions(data));
|
values.put("permissions", serializePermissions(data));
|
||||||
return writeMapToFile(groupFile, values);
|
return writeMapToFile(groupFile, values);
|
||||||
}, false);
|
}, false);
|
||||||
|
@ -106,7 +106,7 @@ public class MongoDBBacking extends AbstractBacking {
|
|||||||
.append("primaryGroup", user.getPrimaryGroup().getStoredValue());
|
.append("primaryGroup", user.getPrimaryGroup().getStoredValue());
|
||||||
|
|
||||||
Document perms = new Document();
|
Document perms = new Document();
|
||||||
for (Map.Entry<String, Boolean> e : convert(exportToLegacy(user.getNodes().values())).entrySet()) {
|
for (Map.Entry<String, Boolean> e : convert(exportToLegacy(user.getEnduringNodes().values())).entrySet()) {
|
||||||
perms.append(e.getKey(), e.getValue());
|
perms.append(e.getKey(), e.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ public class MongoDBBacking extends AbstractBacking {
|
|||||||
Document main = new Document("_id", group.getName());
|
Document main = new Document("_id", group.getName());
|
||||||
|
|
||||||
Document perms = new Document();
|
Document perms = new Document();
|
||||||
for (Map.Entry<String, Boolean> e : convert(exportToLegacy(group.getNodes().values())).entrySet()) {
|
for (Map.Entry<String, Boolean> e : convert(exportToLegacy(group.getEnduringNodes().values())).entrySet()) {
|
||||||
perms.append(e.getKey(), e.getValue());
|
perms.append(e.getKey(), e.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,7 +348,7 @@ public class MongoDBBacking extends AbstractBacking {
|
|||||||
if (cursor.hasNext()) {
|
if (cursor.hasNext()) {
|
||||||
// User exists, let's load.
|
// User exists, let's load.
|
||||||
Document d = cursor.next();
|
Document d = cursor.next();
|
||||||
user.setNodes(revert((Map<String, Boolean>) d.get("perms")).entrySet().stream()
|
user.setEnduringNodes(revert((Map<String, Boolean>) d.get("perms")).entrySet().stream()
|
||||||
.map(e -> NodeFactory.fromSerializedNode(e.getKey(), e.getValue()))
|
.map(e -> NodeFactory.fromSerializedNode(e.getKey(), e.getValue()))
|
||||||
.collect(Collectors.toSet())
|
.collect(Collectors.toSet())
|
||||||
);
|
);
|
||||||
@ -476,7 +476,7 @@ public class MongoDBBacking extends AbstractBacking {
|
|||||||
if (cursor.hasNext()) {
|
if (cursor.hasNext()) {
|
||||||
// Group exists, let's load.
|
// Group exists, let's load.
|
||||||
Document d = cursor.next();
|
Document d = cursor.next();
|
||||||
group.setNodes(revert((Map<String, Boolean>) d.get("perms")).entrySet().stream()
|
group.setEnduringNodes(revert((Map<String, Boolean>) d.get("perms")).entrySet().stream()
|
||||||
.map(e -> NodeFactory.fromSerializedNode(e.getKey(), e.getValue()))
|
.map(e -> NodeFactory.fromSerializedNode(e.getKey(), e.getValue()))
|
||||||
.collect(Collectors.toSet())
|
.collect(Collectors.toSet())
|
||||||
);
|
);
|
||||||
@ -503,7 +503,7 @@ public class MongoDBBacking extends AbstractBacking {
|
|||||||
if (cursor.hasNext()) {
|
if (cursor.hasNext()) {
|
||||||
Document d = cursor.next();
|
Document d = cursor.next();
|
||||||
|
|
||||||
group.setNodes(revert((Map<String, Boolean>) d.get("perms")).entrySet().stream()
|
group.setEnduringNodes(revert((Map<String, Boolean>) d.get("perms")).entrySet().stream()
|
||||||
.map(e -> NodeFactory.fromSerializedNode(e.getKey(), e.getValue()))
|
.map(e -> NodeFactory.fromSerializedNode(e.getKey(), e.getValue()))
|
||||||
.collect(Collectors.toSet())
|
.collect(Collectors.toSet())
|
||||||
);
|
);
|
||||||
|
@ -359,7 +359,7 @@ public class SQLBacking extends AbstractBacking {
|
|||||||
// If the user has any data in storage
|
// If the user has any data in storage
|
||||||
if (!data.isEmpty()) {
|
if (!data.isEmpty()) {
|
||||||
Set<Node> nodes = data.stream().map(NodeModel::toNode).collect(Collectors.toSet());
|
Set<Node> nodes = data.stream().map(NodeModel::toNode).collect(Collectors.toSet());
|
||||||
user.setNodes(nodes);
|
user.setEnduringNodes(nodes);
|
||||||
|
|
||||||
// Save back to the store if data was changed
|
// Save back to the store if data was changed
|
||||||
if (plugin.getUserManager().giveDefaultIfNeeded(user, false)) {
|
if (plugin.getUserManager().giveDefaultIfNeeded(user, false)) {
|
||||||
@ -428,7 +428,7 @@ public class SQLBacking extends AbstractBacking {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<NodeModel> local = user.getNodes().values().stream().map(NodeModel::fromNode).collect(Collectors.toSet());
|
Set<NodeModel> local = user.getEnduringNodes().values().stream().map(NodeModel::fromNode).collect(Collectors.toSet());
|
||||||
|
|
||||||
Map.Entry<Set<NodeModel>, Set<NodeModel>> diff = compareSets(local, remote);
|
Map.Entry<Set<NodeModel>, Set<NodeModel>> diff = compareSets(local, remote);
|
||||||
|
|
||||||
@ -626,7 +626,7 @@ public class SQLBacking extends AbstractBacking {
|
|||||||
|
|
||||||
if (!data.isEmpty()) {
|
if (!data.isEmpty()) {
|
||||||
Set<Node> nodes = data.stream().map(NodeModel::toNode).collect(Collectors.toSet());
|
Set<Node> nodes = data.stream().map(NodeModel::toNode).collect(Collectors.toSet());
|
||||||
group.setNodes(nodes);
|
group.setEnduringNodes(nodes);
|
||||||
} else {
|
} else {
|
||||||
group.clearNodes();
|
group.clearNodes();
|
||||||
}
|
}
|
||||||
@ -675,7 +675,7 @@ public class SQLBacking extends AbstractBacking {
|
|||||||
group.getIoLock().lock();
|
group.getIoLock().lock();
|
||||||
try {
|
try {
|
||||||
// Empty data, just delete.
|
// Empty data, just delete.
|
||||||
if (group.getNodes().isEmpty()) {
|
if (group.getEnduringNodes().isEmpty()) {
|
||||||
try (Connection c = provider.getConnection()) {
|
try (Connection c = provider.getConnection()) {
|
||||||
try (PreparedStatement ps = c.prepareStatement(prefix.apply(GROUP_PERMISSIONS_DELETE))) {
|
try (PreparedStatement ps = c.prepareStatement(prefix.apply(GROUP_PERMISSIONS_DELETE))) {
|
||||||
ps.setString(1, group.getName());
|
ps.setString(1, group.getName());
|
||||||
@ -711,7 +711,7 @@ public class SQLBacking extends AbstractBacking {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<NodeModel> local = group.getNodes().values().stream().map(NodeModel::fromNode).collect(Collectors.toSet());
|
Set<NodeModel> local = group.getEnduringNodes().values().stream().map(NodeModel::fromNode).collect(Collectors.toSet());
|
||||||
|
|
||||||
Map.Entry<Set<NodeModel>, Set<NodeModel>> diff = compareSets(local, remote);
|
Map.Entry<Set<NodeModel>, Set<NodeModel>> diff = compareSets(local, remote);
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ public class MigrationPermissionManager extends SubCommand<Object> {
|
|||||||
// Make a LuckPerms user for the one being migrated
|
// Make a LuckPerms user for the one being migrated
|
||||||
plugin.getStorage().loadUser(uuid, "null").join();
|
plugin.getStorage().loadUser(uuid, "null").join();
|
||||||
User user = plugin.getUserManager().getIfLoaded(uuid);
|
User user = plugin.getUserManager().getIfLoaded(uuid);
|
||||||
if (user.getNodes().size() <= 1) {
|
if (user.getEnduringNodes().size() <= 1) {
|
||||||
user.clearNodes(false);
|
user.clearNodes(false);
|
||||||
}
|
}
|
||||||
migrateSubject(pmUser, user, 100);
|
migrateSubject(pmUser, user, 100);
|
||||||
|
@ -186,7 +186,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
|||||||
// Make a LuckPerms user for the one being migrated
|
// Make a LuckPerms user for the one being migrated
|
||||||
plugin.getStorage().loadUser(uuid, "null").join();
|
plugin.getStorage().loadUser(uuid, "null").join();
|
||||||
User user = plugin.getUserManager().getIfLoaded(uuid);
|
User user = plugin.getUserManager().getIfLoaded(uuid);
|
||||||
if (user.getNodes().size() <= 1) {
|
if (user.getEnduringNodes().size() <= 1) {
|
||||||
user.clearNodes(false);
|
user.clearNodes(false);
|
||||||
}
|
}
|
||||||
migrateSubject(pexUser, user, maxWeight);
|
migrateSubject(pexUser, user, maxWeight);
|
||||||
|
@ -78,7 +78,7 @@ public class LuckPermsSubjectData implements LPSubjectData {
|
|||||||
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_GET_PERMISSIONS)) {
|
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_GET_PERMISSIONS)) {
|
||||||
Map<ImmutableContextSet, ImmutableMap.Builder<String, Boolean>> perms = new HashMap<>();
|
Map<ImmutableContextSet, ImmutableMap.Builder<String, Boolean>> perms = new HashMap<>();
|
||||||
|
|
||||||
for (Map.Entry<ImmutableContextSet, Collection<Node>> e : (enduring ? holder.getNodes() : holder.getTransientNodes()).asMap().entrySet()) {
|
for (Map.Entry<ImmutableContextSet, Collection<Node>> e : (enduring ? holder.getEnduringNodes() : holder.getTransientNodes()).asMap().entrySet()) {
|
||||||
ImmutableMap.Builder<String, Boolean> results = ImmutableMap.builder();
|
ImmutableMap.Builder<String, Boolean> results = ImmutableMap.builder();
|
||||||
for (Node n : e.getValue()) {
|
for (Node n : e.getValue()) {
|
||||||
results.put(n.getPermission(), n.getValue());
|
results.put(n.getPermission(), n.getValue());
|
||||||
@ -184,7 +184,7 @@ public class LuckPermsSubjectData implements LPSubjectData {
|
|||||||
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_GET_PARENTS)) {
|
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_GET_PARENTS)) {
|
||||||
Map<ImmutableContextSet, ImmutableList.Builder<SubjectReference>> parents = new HashMap<>();
|
Map<ImmutableContextSet, ImmutableList.Builder<SubjectReference>> parents = new HashMap<>();
|
||||||
|
|
||||||
for (Map.Entry<ImmutableContextSet, Collection<Node>> e : (enduring ? holder.getNodes() : holder.getTransientNodes()).asMap().entrySet()) {
|
for (Map.Entry<ImmutableContextSet, Collection<Node>> e : (enduring ? holder.getEnduringNodes() : holder.getTransientNodes()).asMap().entrySet()) {
|
||||||
ImmutableList.Builder<SubjectReference> results = ImmutableList.builder();
|
ImmutableList.Builder<SubjectReference> results = ImmutableList.builder();
|
||||||
for (Node n : e.getValue()) {
|
for (Node n : e.getValue()) {
|
||||||
if (n.isGroupNode()) {
|
if (n.isGroupNode()) {
|
||||||
@ -321,7 +321,7 @@ public class LuckPermsSubjectData implements LPSubjectData {
|
|||||||
Map<ImmutableContextSet, Integer> minPrefixPriority = new HashMap<>();
|
Map<ImmutableContextSet, Integer> minPrefixPriority = new HashMap<>();
|
||||||
Map<ImmutableContextSet, Integer> minSuffixPriority = new HashMap<>();
|
Map<ImmutableContextSet, Integer> minSuffixPriority = new HashMap<>();
|
||||||
|
|
||||||
for (Node n : enduring ? holder.getNodes().values() : holder.getTransientNodes().values()) {
|
for (Node n : enduring ? holder.getEnduringNodes().values() : holder.getTransientNodes().values()) {
|
||||||
if (!n.getValue()) continue;
|
if (!n.getValue()) continue;
|
||||||
if (!n.isMeta() && !n.isPrefix() && !n.isSuffix()) continue;
|
if (!n.isMeta() && !n.isPrefix() && !n.isSuffix()) continue;
|
||||||
|
|
||||||
@ -460,7 +460,7 @@ public class LuckPermsSubjectData implements LPSubjectData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Stream<Node> streamNodes(boolean enduring) {
|
private Stream<Node> streamNodes(boolean enduring) {
|
||||||
return (enduring ? holder.getNodes() : holder.getTransientNodes()).values().stream();
|
return (enduring ? holder.getEnduringNodes() : holder.getTransientNodes()).values().stream();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Consumer<Node> makeUnsetConsumer(boolean enduring) {
|
private Consumer<Node> makeUnsetConsumer(boolean enduring) {
|
||||||
|
@ -37,7 +37,7 @@ import com.google.gson.JsonObject;
|
|||||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||||
import me.lucko.luckperms.common.contexts.ContextSetComparator;
|
import me.lucko.luckperms.common.contexts.ContextSetComparator;
|
||||||
import me.lucko.luckperms.common.node.NodeModel;
|
import me.lucko.luckperms.common.node.NodeModel;
|
||||||
import me.lucko.luckperms.common.node.NodePriorityComparator;
|
import me.lucko.luckperms.common.node.NodeWithContextComparator;
|
||||||
import me.lucko.luckperms.sponge.service.calculated.CalculatedSubjectData;
|
import me.lucko.luckperms.sponge.service.calculated.CalculatedSubjectData;
|
||||||
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
|
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
|
||||||
import me.lucko.luckperms.sponge.service.model.SubjectReference;
|
import me.lucko.luckperms.sponge.service.model.SubjectReference;
|
||||||
@ -194,7 +194,7 @@ public class SubjectStorageModel {
|
|||||||
|
|
||||||
// sort alphabetically.
|
// sort alphabetically.
|
||||||
List<Map.Entry<String, Boolean>> perms = new ArrayList<>(e.getValue().entrySet());
|
List<Map.Entry<String, Boolean>> perms = new ArrayList<>(e.getValue().entrySet());
|
||||||
perms.sort((o1, o2) -> NodePriorityComparator.get().compareStrings(o1.getKey(), o2.getKey()));
|
perms.sort((o1, o2) -> NodeWithContextComparator.get().compareStrings(o1.getKey(), o2.getKey()));
|
||||||
|
|
||||||
for (Map.Entry<String, Boolean> ent : perms) {
|
for (Map.Entry<String, Boolean> ent : perms) {
|
||||||
data.addProperty(ent.getKey(), ent.getValue());
|
data.addProperty(ent.getKey(), ent.getValue());
|
||||||
@ -218,7 +218,7 @@ public class SubjectStorageModel {
|
|||||||
|
|
||||||
// sort alphabetically.
|
// sort alphabetically.
|
||||||
List<Map.Entry<String, String>> opts = new ArrayList<>(e.getValue().entrySet());
|
List<Map.Entry<String, String>> opts = new ArrayList<>(e.getValue().entrySet());
|
||||||
opts.sort((o1, o2) -> NodePriorityComparator.get().compareStrings(o1.getKey(), o2.getKey()));
|
opts.sort((o1, o2) -> NodeWithContextComparator.get().compareStrings(o1.getKey(), o2.getKey()));
|
||||||
|
|
||||||
for (Map.Entry<String, String> ent : opts) {
|
for (Map.Entry<String, String> ent : opts) {
|
||||||
data.addProperty(ent.getKey(), ent.getValue());
|
data.addProperty(ent.getKey(), ent.getValue());
|
||||||
|
Loading…
Reference in New Issue
Block a user