From a32ab4bf7f306f69773cd2eb3f1966aed2309d1e Mon Sep 17 00:00:00 2001 From: Luck Date: Fri, 30 Sep 2016 19:21:19 +0100 Subject: [PATCH] Show where a permission was inherited from in the inheritsperm command --- .../lucko/luckperms/api/PermissionHolder.java | 2 +- .../internal/PermissionHolderLink.java | 2 +- .../me/lucko/luckperms/commands/Util.java | 25 +- .../group/subcommands/GroupHasPerm.java | 7 +- .../group/subcommands/GroupInheritsPerm.java | 21 +- .../commands/log/subcommands/LogRecent.java | 2 - .../log/subcommands/LogUserHistory.java | 2 - .../commands/user/UserMainCommand.java | 2 - .../user/subcommands/UserHasPerm.java | 7 +- .../user/subcommands/UserInheritsPerm.java | 21 +- .../me/lucko/luckperms/constants/Message.java | 1 - .../lucko/luckperms/core/InheritanceInfo.java | 53 ++++ .../lucko/luckperms/core/LocalizedNode.java | 248 ++++++++++++++++++ .../luckperms/core/PermissionHolder.java | 96 +++---- .../luckperms/core/PriorityComparator.java | 11 +- 15 files changed, 425 insertions(+), 75 deletions(-) create mode 100644 common/src/main/java/me/lucko/luckperms/core/InheritanceInfo.java create mode 100644 common/src/main/java/me/lucko/luckperms/core/LocalizedNode.java diff --git a/api/src/main/java/me/lucko/luckperms/api/PermissionHolder.java b/api/src/main/java/me/lucko/luckperms/api/PermissionHolder.java index 2ad8e19c9..92704e2c5 100644 --- a/api/src/main/java/me/lucko/luckperms/api/PermissionHolder.java +++ b/api/src/main/java/me/lucko/luckperms/api/PermissionHolder.java @@ -47,7 +47,7 @@ public interface PermissionHolder { * @return an immutable set of permissions in priority order * @since 2.6 */ - SortedSet getPermissions(); + SortedSet getPermissions(); /** * Similar to {@link #getPermissions()}, except excluding transient permissions diff --git a/common/src/main/java/me/lucko/luckperms/api/implementation/internal/PermissionHolderLink.java b/common/src/main/java/me/lucko/luckperms/api/implementation/internal/PermissionHolderLink.java index fcc044a79..7e1874f24 100644 --- a/common/src/main/java/me/lucko/luckperms/api/implementation/internal/PermissionHolderLink.java +++ b/common/src/main/java/me/lucko/luckperms/api/implementation/internal/PermissionHolderLink.java @@ -52,7 +52,7 @@ public class PermissionHolderLink implements PermissionHolder { } @Override - public SortedSet getPermissions() { + public SortedSet getPermissions() { return Collections.unmodifiableSortedSet(master.getPermissions(false)); } diff --git a/common/src/main/java/me/lucko/luckperms/commands/Util.java b/common/src/main/java/me/lucko/luckperms/commands/Util.java index 597562413..7fbee63ba 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/Util.java +++ b/common/src/main/java/me/lucko/luckperms/commands/Util.java @@ -24,8 +24,10 @@ package me.lucko.luckperms.commands; import lombok.experimental.UtilityClass; import me.lucko.luckperms.api.Node; +import me.lucko.luckperms.api.Tristate; import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Patterns; +import me.lucko.luckperms.core.LocalizedNode; import me.lucko.luckperms.utils.DateUtil; import java.util.*; @@ -79,8 +81,19 @@ public class Util { return b ? "&atrue" : "&cfalse"; } - public static void sendBoolean(Sender sender, String node, boolean b) { - sender.sendMessage(Util.color("&b" + node + ": " + formatBoolean(b))); + public static String formatTristate(Tristate t) { + switch (t) { + case TRUE: + return "&atrue"; + case FALSE: + return "&cfalse"; + default: + return "&cundefined"; + } + } + + public static void sendTristate(Sender sender, String node, Tristate t) { + sender.sendMessage(Util.color("&b" + node + ": " + formatTristate(t))); } public static String listToCommaSep(List strings) { @@ -129,7 +142,7 @@ public class Util { return sb.delete(sb.length() - 6, sb.length()).toString(); } - public static String permNodesToString(SortedSet nodes) { + public static String permNodesToString(SortedSet nodes) { StringBuilder sb = new StringBuilder(); for (Node node : nodes) { if (node.isTemporary()) { @@ -154,7 +167,7 @@ public class Util { return sb.toString(); } - public static String tempNodesToString(SortedSet nodes) { + public static String tempNodesToString(SortedSet nodes) { StringBuilder sb = new StringBuilder(); for (Node node : nodes) { @@ -181,7 +194,7 @@ public class Util { return sb.toString(); } - public static String permGroupsToString(SortedSet nodes) { + public static String permGroupsToString(SortedSet nodes) { StringBuilder sb = new StringBuilder(); for (Node node : nodes) { if (!node.isGroupNode()) { @@ -209,7 +222,7 @@ public class Util { return sb.toString(); } - public static String tempGroupsToString(SortedSet nodes) { + public static String tempGroupsToString(SortedSet nodes) { StringBuilder sb = new StringBuilder(); for (Node node : nodes) { diff --git a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupHasPerm.java b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupHasPerm.java index ac7a18efe..db2ceef20 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupHasPerm.java +++ b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupHasPerm.java @@ -26,6 +26,7 @@ import me.lucko.luckperms.LuckPermsPlugin; import me.lucko.luckperms.commands.*; import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; +import me.lucko.luckperms.core.Node; import me.lucko.luckperms.groups.Group; import me.lucko.luckperms.utils.ArgumentChecker; @@ -52,13 +53,13 @@ public class GroupHasPerm extends SubCommand { } if (args.size() == 2) { - Util.sendBoolean(sender, args.get(0), group.hasPermission(args.get(0), true, args.get(1))); + Util.sendTristate(sender, args.get(0), group.hasPermission(new Node.Builder(args.get(0)).setServer(args.get(1)).build())); } else { - Util.sendBoolean(sender, args.get(0), group.hasPermission(args.get(0), true, args.get(1), args.get(2))); + Util.sendTristate(sender, args.get(0), group.hasPermission(new Node.Builder(args.get(0)).setServer(args.get(1)).setWorld(args.get(2)).build())); } } else { - Util.sendBoolean(sender, args.get(0), group.hasPermission(args.get(0), true, "global")); + Util.sendTristate(sender, args.get(0), group.hasPermission(new Node.Builder(args.get(0)).build())); } return CommandResult.SUCCESS; } diff --git a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupInheritsPerm.java b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupInheritsPerm.java index e6768ec62..58f25d07c 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupInheritsPerm.java +++ b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupInheritsPerm.java @@ -26,6 +26,8 @@ import me.lucko.luckperms.LuckPermsPlugin; import me.lucko.luckperms.commands.*; import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; +import me.lucko.luckperms.core.InheritanceInfo; +import me.lucko.luckperms.core.Node; import me.lucko.luckperms.groups.Group; import me.lucko.luckperms.utils.ArgumentChecker; @@ -45,6 +47,7 @@ public class GroupInheritsPerm extends SubCommand { @Override public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List args, String label) { + InheritanceInfo result; if (args.size() >= 2) { if (ArgumentChecker.checkServer(args.get(1))) { Message.SERVER_INVALID_ENTRY.send(sender); @@ -52,14 +55,26 @@ public class GroupInheritsPerm extends SubCommand { } if (args.size() == 2) { - Util.sendBoolean(sender, args.get(0), group.inheritsPermission(args.get(0), true, args.get(1))); + result = group.inheritsPermissionInfo(new Node.Builder(args.get(0)).setServer(args.get(1)).build()); } else { - Util.sendBoolean(sender, args.get(0), group.inheritsPermission(args.get(0), true, args.get(1), args.get(2))); + result = group.inheritsPermissionInfo(new Node.Builder(args.get(0)).setServer(args.get(1)).setWorld(args.get(2)).build()); } } else { - Util.sendBoolean(sender, args.get(0), group.inheritsPermission(args.get(0), true)); + result = group.inheritsPermissionInfo(new Node.Builder(args.get(0)).build()); } + + String location = null; + if (result.getLocation().isPresent()) { + if (result.getLocation().get().equals(group.getObjectName())) { + location = "self"; + } else { + location = result.getLocation().get(); + } + } + + Util.sendPluginMessage(sender, "&b" + args.get(0) + ": " + Util.formatTristate(result.getResult()) + + (result.getLocation().isPresent() ? " &7(inherited from &a" + location + "&7)" : "")); return CommandResult.SUCCESS; } } diff --git a/common/src/main/java/me/lucko/luckperms/commands/log/subcommands/LogRecent.java b/common/src/main/java/me/lucko/luckperms/commands/log/subcommands/LogRecent.java index 273ec7ee6..3e4b1bac9 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/log/subcommands/LogRecent.java +++ b/common/src/main/java/me/lucko/luckperms/commands/log/subcommands/LogRecent.java @@ -74,8 +74,6 @@ public class LogRecent extends SubCommand { return CommandResult.INVALID_ARGS; } - Message.USER_ATTEMPTING_LOOKUP.send(sender); - UUID uuid = plugin.getDatastore().getUUID(s); if (uuid == null) { diff --git a/common/src/main/java/me/lucko/luckperms/commands/log/subcommands/LogUserHistory.java b/common/src/main/java/me/lucko/luckperms/commands/log/subcommands/LogUserHistory.java index f4a6edd40..a5139db62 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/log/subcommands/LogUserHistory.java +++ b/common/src/main/java/me/lucko/luckperms/commands/log/subcommands/LogUserHistory.java @@ -76,8 +76,6 @@ public class LogUserHistory extends SubCommand { return CommandResult.INVALID_ARGS; } - Message.USER_ATTEMPTING_LOOKUP.send(sender); - UUID uuid1 = plugin.getDatastore().getUUID(user); if (uuid1 == null) { diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/UserMainCommand.java b/common/src/main/java/me/lucko/luckperms/commands/user/UserMainCommand.java index 2277d0d78..25324a126 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/UserMainCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/UserMainCommand.java @@ -83,8 +83,6 @@ public class UserMainCommand extends MainCommand { return null; } - Message.USER_ATTEMPTING_LOOKUP.send(sender); - u = plugin.getDatastore().getUUID(target); if (u == null) { Message.USER_NOT_FOUND.send(sender); diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserHasPerm.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserHasPerm.java index 561fbd1c8..82d927738 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserHasPerm.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserHasPerm.java @@ -26,6 +26,7 @@ import me.lucko.luckperms.LuckPermsPlugin; import me.lucko.luckperms.commands.*; import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; +import me.lucko.luckperms.core.Node; import me.lucko.luckperms.users.User; import me.lucko.luckperms.utils.ArgumentChecker; @@ -52,13 +53,13 @@ public class UserHasPerm extends SubCommand { } if (args.size() == 2) { - Util.sendBoolean(sender, args.get(0), user.hasPermission(args.get(0), true, args.get(1))); + Util.sendTristate(sender, args.get(0), user.hasPermission(new Node.Builder(args.get(0)).setServer(args.get(1)).build())); } else { - Util.sendBoolean(sender, args.get(0), user.hasPermission(args.get(0), true, args.get(1), args.get(2))); + Util.sendTristate(sender, args.get(0), user.hasPermission(new Node.Builder(args.get(0)).setServer(args.get(1)).setWorld(args.get(2)).build())); } } else { - Util.sendBoolean(sender, args.get(0), user.hasPermission(args.get(0), true, "global")); + Util.sendTristate(sender, args.get(0), user.hasPermission(new Node.Builder(args.get(0)).build())); } return CommandResult.SUCCESS; } diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserInheritsPerm.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserInheritsPerm.java index 032c766ee..8a61e588e 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserInheritsPerm.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserInheritsPerm.java @@ -26,6 +26,8 @@ import me.lucko.luckperms.LuckPermsPlugin; import me.lucko.luckperms.commands.*; import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; +import me.lucko.luckperms.core.InheritanceInfo; +import me.lucko.luckperms.core.Node; import me.lucko.luckperms.users.User; import me.lucko.luckperms.utils.ArgumentChecker; @@ -45,6 +47,7 @@ public class UserInheritsPerm extends SubCommand { @Override public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List args, String label) { + InheritanceInfo result; if (args.size() >= 2) { if (ArgumentChecker.checkServer(args.get(1))) { Message.SERVER_INVALID_ENTRY.send(sender); @@ -52,14 +55,26 @@ public class UserInheritsPerm extends SubCommand { } if (args.size() == 2) { - Util.sendBoolean(sender, args.get(0), user.inheritsPermission(args.get(0), true, args.get(1))); + result = user.inheritsPermissionInfo(new Node.Builder(args.get(0)).setServer(args.get(1)).build()); } else { - Util.sendBoolean(sender, args.get(0), user.inheritsPermission(args.get(0), true, args.get(1), args.get(2))); + result = user.inheritsPermissionInfo(new Node.Builder(args.get(0)).setServer(args.get(1)).setWorld(args.get(2)).build()); } } else { - Util.sendBoolean(sender, args.get(0), user.inheritsPermission(args.get(0), true)); + result = user.inheritsPermissionInfo(new Node.Builder(args.get(0)).build()); } + + String location = null; + if (result.getLocation().isPresent()) { + if (result.getLocation().get().equals(user.getObjectName())) { + location = "self"; + } else { + location = result.getLocation().get(); + } + } + + Util.sendPluginMessage(sender, "&b" + args.get(0) + ": " + Util.formatTristate(result.getResult()) + + (result.getLocation().isPresent() ? " &7(inherited from &a" + location + "&7)" : "")); return CommandResult.SUCCESS; } } diff --git a/common/src/main/java/me/lucko/luckperms/constants/Message.java b/common/src/main/java/me/lucko/luckperms/constants/Message.java index a9d479499..1e6be46cf 100644 --- a/common/src/main/java/me/lucko/luckperms/constants/Message.java +++ b/common/src/main/java/me/lucko/luckperms/constants/Message.java @@ -58,7 +58,6 @@ public enum Message { USER_NOT_FOUND("&bUser could not be found.", true), USER_SAVE_SUCCESS("&7(User data was saved to the datastore)", true), USER_SAVE_ERROR("There was an error whilst saving the user.", true), - USER_ATTEMPTING_LOOKUP("&7(Attempting UUID lookup, since you specified a username)", true), USER_CREATE_FAIL("There was an error whilst creating a new user.", true), GROUP_NOT_FOUND("&bGroup could not be found.", true), diff --git a/common/src/main/java/me/lucko/luckperms/core/InheritanceInfo.java b/common/src/main/java/me/lucko/luckperms/core/InheritanceInfo.java new file mode 100644 index 000000000..47188e1b4 --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/core/InheritanceInfo.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2016 Lucko (Luck) + * + * 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.core; + +import lombok.*; +import me.lucko.luckperms.api.Tristate; + +import java.util.Optional; + +/** + * The result of an inheritance lookup + */ +@ToString +@EqualsAndHashCode +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class InheritanceInfo { + public static InheritanceInfo of(@NonNull LocalizedNode node) { + return new InheritanceInfo(node.getTristate(), node.getLocation()); + } + + public static InheritanceInfo empty() { + return new InheritanceInfo(Tristate.UNDEFINED, null); + } + + @Getter + private final Tristate result; + private final String location; + + public Optional getLocation() { + return Optional.ofNullable(location); + } + +} diff --git a/common/src/main/java/me/lucko/luckperms/core/LocalizedNode.java b/common/src/main/java/me/lucko/luckperms/core/LocalizedNode.java new file mode 100644 index 000000000..884efd0f3 --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/core/LocalizedNode.java @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2016 Lucko (Luck) + * + * 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.core; + +import lombok.*; +import me.lucko.luckperms.api.Node; +import me.lucko.luckperms.api.Tristate; + +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +/** + * Holds a Node and where it was inherited from + */ +@Getter +@ToString +@EqualsAndHashCode +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class LocalizedNode implements me.lucko.luckperms.api.Node { + public static LocalizedNode of(@NonNull me.lucko.luckperms.api.Node node, @NonNull String location) { + return new LocalizedNode(node, location); + } + + private final me.lucko.luckperms.api.Node node; + private final String location; + + @Override + public String getPermission() { + return node.getPermission(); + } + + @Override + public String getKey() { + return node.getKey(); + } + + @Override + public Boolean getValue() { + return node.getValue(); + } + + @Override + public Boolean setValue(Boolean value) { + return node.setValue(value); + } + + @Override + public Tristate getTristate() { + return node.getTristate(); + } + + @Override + public boolean isNegated() { + return node.isNegated(); + } + + @Override + public boolean isOverride() { + return node.isOverride(); + } + + @Override + public Optional getServer() { + return node.getServer(); + } + + @Override + public Optional getWorld() { + return node.getWorld(); + } + + @Override + public boolean isServerSpecific() { + return node.isServerSpecific(); + } + + @Override + public boolean isWorldSpecific() { + return node.isWorldSpecific(); + } + + @Override + public boolean shouldApplyOnServer(String server, boolean includeGlobal, boolean applyRegex) { + return node.shouldApplyOnServer(server, includeGlobal, applyRegex); + } + + @Override + public boolean shouldApplyOnWorld(String world, boolean includeGlobal, boolean applyRegex) { + return node.shouldApplyOnWorld(world, includeGlobal, applyRegex); + } + + @Override + public boolean shouldApplyWithContext(Map context, boolean worldAndServer) { + return node.shouldApplyWithContext(context, worldAndServer); + } + + @Override + public boolean shouldApplyWithContext(Map context) { + return node.shouldApplyWithContext(context); + } + + @Override + public boolean shouldApplyOnAnyServers(List servers, boolean includeGlobal) { + return node.shouldApplyOnAnyServers(servers, includeGlobal); + } + + @Override + public boolean shouldApplyOnAnyWorlds(List worlds, boolean includeGlobal) { + return node.shouldApplyOnAnyWorlds(worlds, includeGlobal); + } + + @Override + public List resolveWildcard(List possibleNodes) { + return node.resolveWildcard(possibleNodes); + } + + @Override + public List resolveShorthand() { + return node.resolveShorthand(); + } + + @Override + public boolean isTemporary() { + return node.isTemporary(); + } + + @Override + public boolean isPermanent() { + return node.isPermanent(); + } + + @Override + public long getExpiryUnixTime() { + return node.getExpiryUnixTime(); + } + + @Override + public Date getExpiry() { + return node.getExpiry(); + } + + @Override + public long getSecondsTilExpiry() { + return node.getSecondsTilExpiry(); + } + + @Override + public boolean hasExpired() { + return node.hasExpired(); + } + + @Override + public Map getExtraContexts() { + return node.getExtraContexts(); + } + + @Override + public String toSerializedNode() { + return node.toSerializedNode(); + } + + @Override + public boolean isGroupNode() { + return node.isGroupNode(); + } + + @Override + public String getGroupName() { + return node.getGroupName(); + } + + @Override + public boolean isWildcard() { + return node.isWildcard(); + } + + @Override + public int getWildcardLevel() { + return node.getWildcardLevel(); + } + + @Override + public boolean isMeta() { + return node.isMeta(); + } + + @Override + public Map.Entry getMeta() { + return node.getMeta(); + } + + @Override + public boolean isPrefix() { + return node.isPrefix(); + } + + @Override + public Map.Entry getPrefix() { + return node.getPrefix(); + } + + @Override + public boolean isSuffix() { + return node.isSuffix(); + } + + @Override + public Map.Entry getSuffix() { + return node.getSuffix(); + } + + @Override + public boolean equalsIgnoringValue(Node other) { + return node.equalsIgnoringValue(other); + } + + @Override + public boolean almostEquals(Node other) { + return node.almostEquals(other); + } + + @Override + public boolean equalsIgnoringValueOrTemp(Node other) { + return node.equalsIgnoringValueOrTemp(other); + } +} diff --git a/common/src/main/java/me/lucko/luckperms/core/PermissionHolder.java b/common/src/main/java/me/lucko/luckperms/core/PermissionHolder.java index e74608d1c..68ea90594 100644 --- a/common/src/main/java/me/lucko/luckperms/core/PermissionHolder.java +++ b/common/src/main/java/me/lucko/luckperms/core/PermissionHolder.java @@ -78,26 +78,20 @@ public abstract class PermissionHolder { * Returns a Set of nodes in priority order * @return the holders transient and permanent nodes */ - public SortedSet getPermissions(boolean mergeTemp) { + public SortedSet getPermissions(boolean mergeTemp) { // Returns no duplicate nodes. as in, nodes with the same value. - TreeSet combined = new TreeSet<>(PriorityComparator.reverse()); - combined.addAll(nodes); - combined.addAll(transientNodes); + TreeSet combined = new TreeSet<>(PriorityComparator.reverse()); + nodes.stream().map(n -> LocalizedNode.of(n, getObjectName())).forEach(combined::add); + transientNodes.stream().map(n -> LocalizedNode.of(n, getObjectName())).forEach(combined::add); - TreeSet permissions = new TreeSet<>(PriorityComparator.reverse()); + TreeSet permissions = new TreeSet<>(PriorityComparator.reverse()); combined: - for (Node node : combined) { - for (Node other : permissions) { - if (mergeTemp) { - if (node.equalsIgnoringValueOrTemp(other)) { - continue combined; - } - } else { - if (node.almostEquals(other)) { - continue combined; - } + for (LocalizedNode node : combined) { + for (LocalizedNode other : permissions) { + if (mergeTemp ? node.getNode().equalsIgnoringValueOrTemp(other.getNode()) : node.getNode().almostEquals(other.getNode())) { + continue combined; } } @@ -144,8 +138,8 @@ public abstract class PermissionHolder { * @param excludedGroups a list of groups to exclude * @return a set of nodes */ - public SortedSet getAllNodes(List excludedGroups, Contexts context) { - SortedSet all = getPermissions(true); + public SortedSet getAllNodes(List excludedGroups, Contexts context) { + SortedSet all = getPermissions(true); if (excludedGroups == null) { excludedGroups = new ArrayList<>(); @@ -154,6 +148,7 @@ public abstract class PermissionHolder { excludedGroups.add(getObjectName().toLowerCase()); Set parents = getPermissions(true).stream() + .map(LocalizedNode::getNode) .filter(Node::isGroupNode) .collect(Collectors.toSet()); @@ -194,9 +189,9 @@ public abstract class PermissionHolder { } inherited: - for (Node inherited : group.getAllNodes(excludedGroups, context)) { - for (Node existing : all) { - if (existing.almostEquals(inherited)) { + for (LocalizedNode inherited : group.getAllNodes(excludedGroups, context)) { + for (LocalizedNode existing : all) { + if (existing.getNode().almostEquals(inherited.getNode())) { continue inherited; } } @@ -213,9 +208,9 @@ public abstract class PermissionHolder { * @param context the context for this request * @return a map of permissions */ - public Set getAllNodesFiltered(Contexts context) { - Set perms = ConcurrentHashMap.newKeySet(); - SortedSet allNodes; + public Set getAllNodesFiltered(Contexts context) { + Set perms = ConcurrentHashMap.newKeySet(); + SortedSet allNodes; if (context.isApplyGroups()) { allNodes = getAllNodes(null, context); @@ -230,7 +225,8 @@ public abstract class PermissionHolder { contexts.remove("world"); all: - for (Node node : allNodes) { + for (LocalizedNode ln : allNodes) { + Node node = ln.getNode(); if (!node.shouldApplyOnServer(server, context.isIncludeGlobal(), plugin.getConfiguration().isApplyingRegex())) { continue; } @@ -244,13 +240,13 @@ public abstract class PermissionHolder { } // Force higher priority nodes to override - for (Node alreadyIn : perms) { - if (node.getPermission().equals(alreadyIn.getPermission())) { + for (LocalizedNode alreadyIn : perms) { + if (node.getPermission().equals(alreadyIn.getNode().getPermission())) { continue all; } } - perms.add(node); + perms.add(ln); } return perms; @@ -265,7 +261,8 @@ public abstract class PermissionHolder { public Map exportNodes(Contexts context, List possibleNodes, boolean lowerCase) { Map perms = new HashMap<>(); - for (Node node : getAllNodesFiltered(context)) { + for (LocalizedNode ln : getAllNodesFiltered(context)) { + Node node = ln.getNode(); if (possibleNodes != null && !possibleNodes.isEmpty()) { if (node.getPermission().equals("*") || node.getPermission().equals("'*'")) { if (plugin.getConfiguration().isApplyingWildcards()) { @@ -332,16 +329,6 @@ public abstract class PermissionHolder { auditTemporaryPermissions(); } - private static Tristate hasPermission(Set toQuery, Node node) { - for (Node n : toQuery) { - if (n.almostEquals(node)) { - return n.getTristate(); - } - } - - return Tristate.UNDEFINED; - } - /** * Check if the holder has a permission node * @param node the node to check @@ -349,7 +336,13 @@ public abstract class PermissionHolder { * @return a tristate */ public Tristate hasPermission(Node node, boolean t) { - return hasPermission(t ? transientNodes : nodes, node); + for (Node n : t ? transientNodes : nodes) { + if (n.almostEquals(node)) { + return n.getTristate(); + } + } + + return Tristate.UNDEFINED; } public Tristate hasPermission(Node node) { @@ -383,10 +376,25 @@ public abstract class PermissionHolder { /** * Check if the holder inherits a node * @param node the node to check - * @return a tristate + * @return the result of the lookup + */ + public InheritanceInfo inheritsPermissionInfo(Node node) { + for (LocalizedNode n : getAllNodes(null, Contexts.allowAll())) { + if (n.getNode().almostEquals(node)) { + return InheritanceInfo.of(n); + } + } + + return InheritanceInfo.empty(); + } + + /** + * Check if the holder inherits a node + * @param node the node to check + * @return the Tristate result */ public Tristate inheritsPermission(Node node) { - return hasPermission(getAllNodes(null, Contexts.allowAll()), node); + return inheritsPermissionInfo(node).getResult(); } public boolean inheritsPermission(String node, boolean b) { @@ -556,7 +564,7 @@ public abstract class PermissionHolder { } /** - * Get a {@link List} of all of the groups the group inherits, on all servers + * Get a {@link List} of all of the groups the holder inherits, on all servers * @return a {@link List} of group names */ public List getGroupNames() { @@ -567,7 +575,7 @@ public abstract class PermissionHolder { } /** - * Get a {@link List} of the groups the group inherits on a specific server + * Get a {@link List} of the groups the holder inherits on a specific server and world * @param server the server to check * @param world the world to check * @return a {@link List} of group names @@ -582,7 +590,7 @@ public abstract class PermissionHolder { } /** - * Get a {@link List} of the groups the group inherits on a specific server + * Get a {@link List} of the groups the holder inherits on a specific server * @param server the server to check * @return a {@link List} of group names */ diff --git a/common/src/main/java/me/lucko/luckperms/core/PriorityComparator.java b/common/src/main/java/me/lucko/luckperms/core/PriorityComparator.java index 77662d0f4..cc3800bb0 100644 --- a/common/src/main/java/me/lucko/luckperms/core/PriorityComparator.java +++ b/common/src/main/java/me/lucko/luckperms/core/PriorityComparator.java @@ -31,21 +31,24 @@ import java.util.Comparator; import java.util.Locale; @NoArgsConstructor(access = AccessLevel.PRIVATE) -public class PriorityComparator implements Comparator { +public class PriorityComparator implements Comparator { private static final PriorityComparator INSTANCE = new PriorityComparator(); - public static Comparator get() { + public static Comparator get() { return INSTANCE; } - public static Comparator reverse() { + public static Comparator reverse() { return INSTANCE.reversed(); } private final Collator collator = Collator.getInstance(Locale.ENGLISH); @Override - public int compare(Node o1, Node o2) { + public int compare(LocalizedNode one, LocalizedNode two) { + Node o1 = one.getNode(); + Node o2 = two.getNode(); + if (o1.equals(o2)) { return 0; }