From 8cf32752e9c4b71dfaaceaee91582ba08413bfac Mon Sep 17 00:00:00 2001 From: Luck Date: Thu, 11 May 2017 19:46:28 +0100 Subject: [PATCH] Fix meta info only showing values in global context --- .../commands/impl/generic/meta/MetaInfo.java | 14 ++-- .../impl/generic/parent/ParentSetTrack.java | 6 +- .../common/core/model/ImmutableNode.java | 2 +- .../common/core/model/PermissionHolder.java | 72 +++++++++++++++++++ 4 files changed, 86 insertions(+), 8 deletions(-) diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/impl/generic/meta/MetaInfo.java b/common/src/main/java/me/lucko/luckperms/common/commands/impl/generic/meta/MetaInfo.java index 43fbcbc92..191631935 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/impl/generic/meta/MetaInfo.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/impl/generic/meta/MetaInfo.java @@ -25,7 +25,6 @@ package me.lucko.luckperms.common.commands.impl.generic.meta; -import me.lucko.luckperms.api.Contexts; import me.lucko.luckperms.api.LocalizedNode; import me.lucko.luckperms.common.commands.CommandException; import me.lucko.luckperms.common.commands.CommandResult; @@ -37,7 +36,6 @@ import me.lucko.luckperms.common.constants.Message; import me.lucko.luckperms.common.constants.Permission; import me.lucko.luckperms.common.core.model.PermissionHolder; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; -import me.lucko.luckperms.common.utils.ExtractedContexts; import me.lucko.luckperms.common.utils.Predicates; import java.util.AbstractMap; @@ -53,6 +51,10 @@ public class MetaInfo extends SharedSubCommand { return node.getLocation().equalsIgnoreCase(holder.getObjectName()) ? "self" : node.getLocation(); } + public static String formatMetaValue(String val) { + return val.replace("&", "{color char}"); + } + public MetaInfo() { super("info", "Shows all chat meta", Permission.USER_META_INFO, Permission.GROUP_META_INFO, Predicates.alwaysFalse(), null); } @@ -64,7 +66,7 @@ public class MetaInfo extends SharedSubCommand { Set meta = new HashSet<>(); // Collect data - for (LocalizedNode node : holder.resolveInheritancesAlmostEqual(ExtractedContexts.generate(Contexts.allowAll()))) { + for (LocalizedNode node : holder.resolveInheritances()) { if (!node.isSuffix() && !node.isPrefix() && !node.isMeta()) { continue; } @@ -99,7 +101,7 @@ public class MetaInfo extends SharedSubCommand { Message.CHAT_META_SUFFIX_HEADER.send(sender, holder.getFriendlyName()); for (Map.Entry e : suffixes) { String location = processLocation(e.getValue(), holder); - if (e.getValue().isServerSpecific() || e.getValue().isWorldSpecific() || !e.getValue().getContexts().isEmpty()) { + if (e.getValue().hasSpecificContext()) { String context = Util.getAppendableNodeContextString(e.getValue()); Message.CHAT_META_ENTRY_WITH_CONTEXT.send(sender, e.getKey(), e.getValue().getSuffix().getValue(), location, context); } else { @@ -114,11 +116,11 @@ public class MetaInfo extends SharedSubCommand { Message.META_HEADER.send(sender, holder.getFriendlyName()); for (LocalizedNode m : meta) { String location = processLocation(m, holder); - if (m.isServerSpecific() || m.isWorldSpecific() || !m.getContexts().isEmpty()) { + if (m.hasSpecificContext()) { String context = Util.getAppendableNodeContextString(m); Message.META_ENTRY_WITH_CONTEXT.send(sender, m.getMeta().getKey(), m.getMeta().getValue(), location, context); } else { - Message.META_ENTRY.send(sender, m.getMeta().getKey(), m.getMeta().getValue(), location); + Message.META_ENTRY.send(sender, m.getMeta().getKey(), formatMetaValue(m.getMeta().getValue()), location); } } } diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/impl/generic/parent/ParentSetTrack.java b/common/src/main/java/me/lucko/luckperms/common/commands/impl/generic/parent/ParentSetTrack.java index 19c18d637..cfc1dfccb 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/impl/generic/parent/ParentSetTrack.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/impl/generic/parent/ParentSetTrack.java @@ -50,7 +50,7 @@ import static me.lucko.luckperms.common.commands.abstraction.SubCommand.getTrack public class ParentSetTrack extends SharedSubCommand { public ParentSetTrack() { - super("settrack", "Removes all other groups the object inherits from already on the given track and adds them to the one given group", + super("settrack", "Removes all other groups the object inherits from already on the given track and adds them to the one given", Permission.USER_PARENT_SET_TRACK, Permission.GROUP_PARENT_SET_TRACK, Predicates.is(0), Arg.list( Arg.create("track", true, "the track to set on"), @@ -95,6 +95,10 @@ public class ParentSetTrack extends SharedSubCommand { groupName = track.getGroups().get(index - 1); } else { groupName = ArgumentUtils.handleName(1, args); + if (!track.containsGroup(groupName)) { + Message.TRACK_DOES_NOT_CONTAIN.send(sender, track.getName(), groupName); + return CommandResult.INVALID_ARGS; + } } MutableContextSet context = ArgumentUtils.handleContext(2, args, plugin); diff --git a/common/src/main/java/me/lucko/luckperms/common/core/model/ImmutableNode.java b/common/src/main/java/me/lucko/luckperms/common/core/model/ImmutableNode.java index bf5d2ece9..7f9ed3984 100644 --- a/common/src/main/java/me/lucko/luckperms/common/core/model/ImmutableNode.java +++ b/common/src/main/java/me/lucko/luckperms/common/core/model/ImmutableNode.java @@ -302,7 +302,7 @@ public final class ImmutableNode implements Node { @Override public boolean hasSpecificContext() { - return server != null && world != null && !contexts.isEmpty(); + return server != null || world != null || !contexts.isEmpty(); } @Override diff --git a/common/src/main/java/me/lucko/luckperms/common/core/model/PermissionHolder.java b/common/src/main/java/me/lucko/luckperms/common/core/model/PermissionHolder.java index 84481f3c8..316b456d6 100644 --- a/common/src/main/java/me/lucko/luckperms/common/core/model/PermissionHolder.java +++ b/common/src/main/java/me/lucko/luckperms/common/core/model/PermissionHolder.java @@ -532,6 +532,78 @@ public abstract class PermissionHolder { return ret; } + /** + * Resolves inherited nodes and returns them + * + * @param excludedGroups a list of groups to exclude + * @return a set of nodes + */ + protected List resolveInheritances(List accumulator, Set excludedGroups) { + if (accumulator == null) { + accumulator = new ArrayList<>(); + } + + if (excludedGroups == null) { + excludedGroups = new HashSet<>(); + } + + if (this instanceof Group) { + excludedGroups.add(getObjectName().toLowerCase()); + } + + // get and add the objects own nodes + List nodes = mergePermissionsToList(); + nodes.stream() + .map(n -> ImmutableLocalizedNode.of(n, getObjectName())) + .forEach(accumulator::add); + + // screw effectively final + Set finalExcludedGroups = excludedGroups; + List finalAccumulator = accumulator; + + // this allows you to negate parent permissions lower down the inheritance tree. + // we can negate parent groups in a specific context at this level and prevent them from being applied. + // there's no way to distinct the stream below based on a custom comparator. + NodeTools.removeSamePermission(nodes.iterator()); + + nodes.stream() + .filter(Node::getValue) + .filter(Node::isGroupNode) + .map(Node::getGroupName) + .distinct() + .map(n -> Optional.ofNullable(plugin.getGroupManager().getIfLoaded(n))) + .filter(Optional::isPresent) + .map(Optional::get) + .filter(g -> !finalExcludedGroups.contains(g.getObjectName().toLowerCase())) + .sorted((o1, o2) -> { + int result = Integer.compare(o1.getWeight().orElse(0), o2.getWeight().orElse(0)); + return result == 1 ? -1 : 1; + }) + .forEach(group -> group.resolveInheritances(finalAccumulator, finalExcludedGroups)); + + return accumulator; + } + + public List resolveInheritances() { + return resolveInheritances(null, null); + } + + public SortedSet resolveInheritancesAlmostEqual() { + List nodes = resolveInheritances(null, null); + NodeTools.removeAlmostEqual(nodes.iterator()); + SortedSet ret = new TreeSet<>(PriorityComparator.reverse()); + ret.addAll(nodes); + return ret; + } + + public SortedSet resolveInheritancesMergeTemp() { + List nodes = resolveInheritances(null, null); + NodeTools.removeIgnoreValueOrTemp(nodes.iterator()); + SortedSet ret = new TreeSet<>(PriorityComparator.reverse()); + ret.addAll(nodes); + return ret; + } + public SortedSet getAllNodes(ExtractedContexts context) { Contexts contexts = context.getContexts();