From fb5925e1e85d9b0badaa51718fe503229b6973c4 Mon Sep 17 00:00:00 2001 From: Luck Date: Sun, 17 Dec 2017 12:59:36 +0000 Subject: [PATCH] Add user clone command (#530) --- .locale/en_US.yml | 42 ++++--- .../common/actionlog/ExtendedLogEntry.java | 7 +- .../delegates/model/ApiPermissionHolder.java | 17 +-- .../common/api/delegates/model/ApiUser.java | 3 +- .../impl/generic/parent/ParentAdd.java | 3 +- .../impl/generic/parent/ParentSet.java | 3 +- .../impl/generic/parent/ParentSetTrack.java | 3 +- .../commands/impl/group/GroupClone.java | 4 +- .../common/commands/impl/group/GroupInfo.java | 6 +- .../common/commands/impl/user/UserClone.java | 113 +++++++++++++++++ .../common/commands/impl/user/UserInfo.java | 6 +- .../commands/impl/user/UserMainCommand.java | 1 + .../impl/user/UserSwitchPrimaryGroup.java | 4 +- .../common/constants/CommandPermission.java | 1 + .../luckperms/common/locale/CommandSpec.java | 5 + .../luckperms/common/locale/Message.java | 1 + .../common/model/PermissionHolder.java | 119 +----------------- 17 files changed, 175 insertions(+), 163 deletions(-) create mode 100644 common/src/main/java/me/lucko/luckperms/common/commands/impl/user/UserClone.java diff --git a/.locale/en_US.yml b/.locale/en_US.yml index 6854029b9..4b79f941a 100644 --- a/.locale/en_US.yml +++ b/.locale/en_US.yml @@ -2,8 +2,8 @@ # Locale: en_US (English) # Author: Luck -prefix: "&7&l[&b&lL&3&lP&7&l] &c" -empty: "{0}" +prefix: "&7&l[&b&lL&3&lP&7&l] " +empty: "&c{0}" player-online: "&aOnline" player-offline: "&cOffline" loading-error: "&cPermissions data could not be loaded. Please try again later." @@ -45,10 +45,8 @@ tree-url: "&aPermission tree URL:" search-searching: "&aSearching for users and groups with &b{0}&a..." search-searching-members: "&aSearching for users and groups who inherit from &b{0}&a..." search-result: "&aFound &b{0}&a entries from &b{1}&a users and &b{2}&a groups." -search-showing-users: "&bShowing user entries:" -search-showing-groups: "&bShowing group entries:" -search-showing-users-with-page: "&bShowing user entries: {0}" -search-showing-groups-with-page: "&bShowing group entries: {0}" +search-showing-users: "&bShowing user entries: &7(showing page &f{0}&7 of &f{1}&7 - &f{2}&7 entries)" +search-showing-groups: "&bShowing group entries: &7(showing page &f{0}&7 of &f{1}&7 - &f{2}&7 entries)" apply-edits-invalid-code: "&cInvalid code. &7({0})" apply-edits-unable-to-read: "&cUnable to read data using the given code. &7({0})" apply-edits-no-target: "&cUnable to parse the target of the edit. Please supply it as an extra argument." @@ -60,8 +58,9 @@ apply-edits-success: "&aWeb editor data was applied to &b{0}&a successfully." apply-edits-success-summary: "&7(&a{0} &7{1} and &c{2} &7{3})" apply-edits-diff-added: "&a+ &f{0}" apply-edits-diff-removed: "&c- &f{0}" +editor-start: "&7Preparing a new editor sesssion. Please wait..." editor-upload-failure: "&cUnable to upload permission data to the editor." -editor-url: "&aEditor URL:" +editor-url: "&aClick the link below to open the editor:" check-result: "&aPermission check result on user &b{0}&a for permission &b{1}&a: &f{2}" create-success: "&b{0}&a was successfully created." delete-success: "&b{0}&a was successfully deleted." @@ -76,6 +75,7 @@ track-does-not-contain: "&b{0}&a doesn't contain &b{1}&a." track-ambiguous-call: "&4{0}&c is a member of multiple groups on this track. Unable to determine their location." already-exists: "&4{0}&c already exists!" does-not-exist: "&4{0}&c does not exist!" +user-load-error: "&cAn unexpected error occurred. User not loaded." group-load-error: "&cAn unexpected error occurred. Group not loaded." groups-load-error: "&cAn unexpected error occurred. Unable to load all groups." track-load-error: "&cAn unexpected error occurred. Track not loaded." @@ -111,15 +111,12 @@ groups-list: "&aGroups: &7(name, weight, tracks)" groups-list-entry: "&f- &3{0} &7- &b{1}" groups-list-entry-with-tracks: "&f- &3{0} &7- &b{1} &7- [&3{2}&7]" tracks-list: "&aTracks: {0}" -listnodes: "&b{0}'s Permissions:" -listnodes-with-page: "&b{0}'s Permissions: {1}" -listnodes-temp: "&b{0}'s Temporary Permissions:" -listnodes-temp-with-page: "&b{0}'s Temporary Permissions: {1}" -listparents: "&b{0}'s Parent Groups:" -listparents-temp: "&b{0}'s Temporary Parent Groups:" -list-tracks: > - &b{0}'s Tracks:\n - {1} +permission-info: "&b{0}'s Permissions: &7(showing page &f{1}&7 of &f{2}&7 - &f{3}&7 entries)" +permission-info-no-data: "&b{0}&a does not have any permissions set." +parent-info: "&b{0}'s Parents: &7(showing page &f{1}&7 of &f{2}&7 - &f{3}&7 entries)" +parent-info-no-data: "&b{0}&a does not have any parents defined." +list-tracks: "&b{0}'s Tracks:" +list-tracks-entry: "&a{0}: {1}" list-tracks-empty: "&b{0}&a is not on any tracks." context-pair-inline: "&3{0}=&b{1}" context-pair--global-inline: "&eglobal" @@ -413,6 +410,10 @@ command-specs: args: "track": "the track to demote the user down" "context...": "the contexts to demote the user in" + user-clone: + description: "Clone the user" + args: + "user": "the name/uuid of the user to clone onto" group-info: description: "Gives info about the group" group-listmembers: @@ -423,6 +424,10 @@ command-specs: description: "Set the groups weight" args: "weight": "the weight to set" + group-set-display-name: + description: "Set the groups display name" + args: + "name": "the name to set" group-rename: description: "Rename the group" args: @@ -449,7 +454,7 @@ command-specs: description: "Lists the permission nodes the object has" args: "page": "the page to view" - "filter": "the string to filter by" + "sort mode": "how to sort the entries" permission-set: description: "Sets a permission for the object" args: @@ -485,6 +490,9 @@ command-specs: "context...": "the contexts to check in" parent-info: description: "Lists the groups that this object inherits from" + args: + "page": "the page to view" + "sort mode": "how to sort the entries" parent-set: description: "Removes all other groups the object inherits already and adds them to the one given" args: diff --git a/common/src/main/java/me/lucko/luckperms/common/actionlog/ExtendedLogEntry.java b/common/src/main/java/me/lucko/luckperms/common/actionlog/ExtendedLogEntry.java index 49ec46420..9f522cd0f 100644 --- a/common/src/main/java/me/lucko/luckperms/common/actionlog/ExtendedLogEntry.java +++ b/common/src/main/java/me/lucko/luckperms/common/actionlog/ExtendedLogEntry.java @@ -62,12 +62,7 @@ public class ExtendedLogEntry implements LogEntry { private static final String FORMAT = "&8(&e%s&8) [&a%s&8] (&b%s&8) &7--> &f%s"; - /** - * Compares two LogEntries - * - * @since 3.3 - */ - public static final Comparator COMPARATOR = Comparator + private static final Comparator COMPARATOR = Comparator .comparingLong(LogEntry::getTimestamp) .thenComparing(LogEntry::getActor) .thenComparing(LogEntry::getActorName, String.CASE_INSENSITIVE_ORDER) diff --git a/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiPermissionHolder.java b/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiPermissionHolder.java index 9bd5781d4..5fd800ad6 100644 --- a/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiPermissionHolder.java +++ b/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiPermissionHolder.java @@ -54,6 +54,7 @@ import java.util.SortedSet; import java.util.TreeSet; import java.util.concurrent.CompletableFuture; import java.util.function.Predicate; +import java.util.stream.Collectors; @AllArgsConstructor public class ApiPermissionHolder implements PermissionHolder { @@ -179,7 +180,7 @@ public class ApiPermissionHolder implements PermissionHolder { } @Override - public void clearMatching(Predicate test) { + public void clearMatching(@NonNull Predicate test) { handle.removeIf(test); if (handle.getType().isUser()) { handle.getPlugin().getUserManager().giveDefaultIfNeeded((User) handle, false); @@ -187,7 +188,7 @@ public class ApiPermissionHolder implements PermissionHolder { } @Override - public void clearMatchingTransient(Predicate test) { + public void clearMatchingTransient(@NonNull Predicate test) { handle.removeIfTransient(test); } @@ -226,11 +227,6 @@ public class ApiPermissionHolder implements PermissionHolder { handle.clearTransientNodes(); } - @Override - public Set getTemporaryPermissionNodes() { - return handle.getTemporaryNodes(); - } - @Override public List resolveInheritances(Contexts contexts) { return handle.resolveInheritances(contexts); @@ -243,7 +239,12 @@ public class ApiPermissionHolder implements PermissionHolder { @Override public Set getPermanentPermissionNodes() { - return handle.getPermanentNodes(); + return handle.getOwnNodes().stream().filter(Node::isPermanent).collect(Collectors.toSet()); + } + + @Override + public Set getTemporaryPermissionNodes() { + return handle.getOwnNodes().stream().filter(Node::isPrefix).collect(Collectors.toSet()); } @Override diff --git a/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiUser.java b/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiUser.java index 37cbd1645..15c870a1f 100644 --- a/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiUser.java +++ b/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiUser.java @@ -33,6 +33,7 @@ import com.google.common.base.Preconditions; import me.lucko.luckperms.api.DataMutateResult; import me.lucko.luckperms.api.User; import me.lucko.luckperms.api.caching.UserData; +import me.lucko.luckperms.common.node.NodeFactory; import java.util.UUID; @@ -71,7 +72,7 @@ public final class ApiUser extends ApiPermissionHolder implements User { return DataMutateResult.ALREADY_HAS; } - if (!handle.hasPermission("group." + s.toLowerCase(), true)) { + if (!handle.hasPermission(NodeFactory.make("group." + s.toLowerCase(), true)).asBoolean()) { return DataMutateResult.FAIL; } diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/impl/generic/parent/ParentAdd.java b/common/src/main/java/me/lucko/luckperms/common/commands/impl/generic/parent/ParentAdd.java index 5a6c06a77..b17143083 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/impl/generic/parent/ParentAdd.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/impl/generic/parent/ParentAdd.java @@ -41,6 +41,7 @@ import me.lucko.luckperms.common.locale.LocaleManager; import me.lucko.luckperms.common.locale.Message; import me.lucko.luckperms.common.model.Group; import me.lucko.luckperms.common.model.PermissionHolder; +import me.lucko.luckperms.common.node.NodeFactory; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.utils.Predicates; @@ -84,7 +85,7 @@ public class ParentAdd extends SharedSubCommand { return CommandResult.NO_PERMISSION; } - DataMutateResult result = holder.setInheritGroup(group, context); + DataMutateResult result = holder.setPermission(NodeFactory.newBuilder("group." + group.getName()).withExtraContext(context).build()); if (result.asBoolean()) { Message.SET_INHERIT_SUCCESS.send(sender, holder.getFriendlyName(), group.getFriendlyName(), CommandUtils.contextSetToString(context)); diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/impl/generic/parent/ParentSet.java b/common/src/main/java/me/lucko/luckperms/common/commands/impl/generic/parent/ParentSet.java index df7a8b561..307a58400 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/impl/generic/parent/ParentSet.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/impl/generic/parent/ParentSet.java @@ -41,6 +41,7 @@ import me.lucko.luckperms.common.locale.Message; import me.lucko.luckperms.common.model.Group; import me.lucko.luckperms.common.model.PermissionHolder; import me.lucko.luckperms.common.model.User; +import me.lucko.luckperms.common.node.NodeFactory; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.utils.Predicates; @@ -85,7 +86,7 @@ public class ParentSet extends SharedSubCommand { } holder.clearParents(context, false); - holder.setInheritGroup(group, context); + holder.setPermission(NodeFactory.newBuilder("group." + group.getName()).withExtraContext(context).build()); if (holder.getType().isUser()) { ((User) holder).getPrimaryGroup().setStoredValue(group.getName()); } 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 26539fdf2..5ff1c3010 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 @@ -42,6 +42,7 @@ import me.lucko.luckperms.common.locale.Message; import me.lucko.luckperms.common.model.Group; import me.lucko.luckperms.common.model.PermissionHolder; import me.lucko.luckperms.common.model.Track; +import me.lucko.luckperms.common.node.NodeFactory; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.utils.Predicates; @@ -125,7 +126,7 @@ public class ParentSetTrack extends SharedSubCommand { } holder.removeIf(node -> node.isGroupNode() && node.getFullContexts().equals(context) && track.containsGroup(node.getGroupName())); - holder.setInheritGroup(group, context); + holder.setPermission(NodeFactory.newBuilder("group." + group.getName()).withExtraContext(context).build()); Message.SET_TRACK_PARENT_SUCCESS.send(sender, holder.getFriendlyName(), track.getName(), group.getFriendlyName(), CommandUtils.contextSetToString(context)); diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/impl/group/GroupClone.java b/common/src/main/java/me/lucko/luckperms/common/commands/impl/group/GroupClone.java index a711f8ea1..940e7ead3 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/impl/group/GroupClone.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/impl/group/GroupClone.java @@ -78,8 +78,8 @@ public class GroupClone extends SubCommand { Message.CLONE_SUCCESS.send(sender, group.getName(), newGroup.getName()); - ExtendedLogEntry.build().actor(sender).acted(group) - .action("clone", newGroup.getName()) + ExtendedLogEntry.build().actor(sender).acted(newGroup) + .action("clone", group.getName()) .build().submit(plugin, sender); save(newGroup, sender, plugin); diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/impl/group/GroupInfo.java b/common/src/main/java/me/lucko/luckperms/common/commands/impl/group/GroupInfo.java index 9c191adbd..350929ff0 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/impl/group/GroupInfo.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/impl/group/GroupInfo.java @@ -63,9 +63,9 @@ public class GroupInfo extends SubCommand { group.getWeight().isPresent() ? group.getWeight().getAsInt() : "None", group.getOwnNodes().size(), group.getOwnNodes().stream().filter(n -> !(n.isGroupNode() || n.isPrefix() || n.isSuffix() || n.isMeta())).mapToInt(n -> 1).sum(), - group.getPrefixNodes().size(), - group.getSuffixNodes().size(), - group.getMetaNodes().size() + group.getOwnNodes().stream().filter(Node::isPrefix).mapToInt(n -> 1).sum(), + group.getOwnNodes().stream().filter(Node::isSuffix).mapToInt(n -> 1).sum(), + group.getOwnNodes().stream().filter(Node::isMeta).mapToInt(n -> 1).sum() ); Set parents = group.getOwnNodesSet().stream() diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/impl/user/UserClone.java b/common/src/main/java/me/lucko/luckperms/common/commands/impl/user/UserClone.java new file mode 100644 index 000000000..4018c1cd8 --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/common/commands/impl/user/UserClone.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2017 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.common.commands.impl.user; + +import me.lucko.luckperms.common.actionlog.ExtendedLogEntry; +import me.lucko.luckperms.common.commands.ArgumentPermissions; +import me.lucko.luckperms.common.commands.CommandException; +import me.lucko.luckperms.common.commands.CommandResult; +import me.lucko.luckperms.common.commands.abstraction.SubCommand; +import me.lucko.luckperms.common.commands.sender.Sender; +import me.lucko.luckperms.common.commands.utils.CommandUtils; +import me.lucko.luckperms.common.config.ConfigKeys; +import me.lucko.luckperms.common.constants.CommandPermission; +import me.lucko.luckperms.common.constants.DataConstraints; +import me.lucko.luckperms.common.locale.CommandSpec; +import me.lucko.luckperms.common.locale.LocaleManager; +import me.lucko.luckperms.common.locale.Message; +import me.lucko.luckperms.common.model.User; +import me.lucko.luckperms.common.plugin.LuckPermsPlugin; +import me.lucko.luckperms.common.utils.Predicates; + +import java.util.List; +import java.util.UUID; + +public class UserClone extends SubCommand { + public UserClone(LocaleManager locale) { + super(CommandSpec.USER_CLONE.spec(locale), "clone", CommandPermission.USER_CLONE, Predicates.not(1)); + } + + @Override + public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List args, String label) throws CommandException { + if (ArgumentPermissions.checkViewPerms(plugin, sender, getPermission().get(), user)) { + Message.COMMAND_NO_PERMISSION.send(sender); + return CommandResult.NO_PERMISSION; + } + + String target = args.get(0); + + UUID uuid = CommandUtils.parseUuid(target.toLowerCase()); + if (uuid == null) { + if (!plugin.getConfiguration().get(ConfigKeys.ALLOW_INVALID_USERNAMES)) { + if (!DataConstraints.PLAYER_USERNAME_TEST.test(target)) { + Message.USER_INVALID_ENTRY.send(sender, target); + return CommandResult.INVALID_ARGS; + } + } else { + if (!DataConstraints.PLAYER_USERNAME_TEST_LENIENT.test(target)) { + Message.USER_INVALID_ENTRY.send(sender, target); + return CommandResult.INVALID_ARGS; + } + } + + uuid = plugin.getStorage().getUUID(target.toLowerCase()).join(); + if (uuid == null) { + if (!plugin.getConfiguration().get(ConfigKeys.USE_SERVER_UUID_CACHE)) { + Message.USER_NOT_FOUND.send(sender, target); + return CommandResult.INVALID_ARGS; + } + + uuid = plugin.lookupUuid(target).orElse(null); + if (uuid == null) { + Message.USER_NOT_FOUND.send(sender, target); + return CommandResult.INVALID_ARGS; + } + } + } + + plugin.getStorage().loadUser(uuid, null).join(); + User otherUser = plugin.getUserManager().getIfLoaded(uuid); + + if (otherUser == null) { + Message.USER_LOAD_ERROR.send(sender); + return CommandResult.LOADING_ERROR; + } + + if (ArgumentPermissions.checkModifyPerms(plugin, sender, getPermission().get(), otherUser)) { + Message.COMMAND_NO_PERMISSION.send(sender); + return CommandResult.NO_PERMISSION; + } + + otherUser.replaceEnduringNodes(user.getEnduringNodes()); + + Message.CLONE_SUCCESS.send(sender, user.getFriendlyName(), otherUser.getFriendlyName()); + + ExtendedLogEntry.build().actor(sender).acted(otherUser) + .action("clone", user.getName()) + .build().submit(plugin, sender); + + save(otherUser, sender, plugin); + plugin.getUserManager().cleanup(otherUser); + return CommandResult.SUCCESS; + } +} diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/impl/user/UserInfo.java b/common/src/main/java/me/lucko/luckperms/common/commands/impl/user/UserInfo.java index f29396dba..fe2b1cb4f 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/impl/user/UserInfo.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/impl/user/UserInfo.java @@ -67,9 +67,9 @@ public class UserInfo extends SubCommand { user.getPrimaryGroup().getValue(), user.getOwnNodes().size(), user.getOwnNodes().stream().filter(n -> !(n.isGroupNode() || n.isPrefix() || n.isSuffix() || n.isMeta())).mapToInt(n -> 1).sum(), - user.getPrefixNodes().size(), - user.getSuffixNodes().size(), - user.getMetaNodes().size() + user.getOwnNodes().stream().filter(Node::isPrefix).mapToInt(n -> 1).sum(), + user.getOwnNodes().stream().filter(Node::isSuffix).mapToInt(n -> 1).sum(), + user.getOwnNodes().stream().filter(Node::isMeta).mapToInt(n -> 1).sum() ); Set parents = user.getOwnNodesSet().stream() diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/impl/user/UserMainCommand.java b/common/src/main/java/me/lucko/luckperms/common/commands/impl/user/UserMainCommand.java index 96f4ddfb3..022c99fef 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/impl/user/UserMainCommand.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/impl/user/UserMainCommand.java @@ -76,6 +76,7 @@ public class UserMainCommand extends MainCommand { .add(new UserDemote(locale)) .add(new HolderShowTracks<>(locale, true)) .add(new HolderClear<>(locale, true)) + .add(new UserClone(locale)) .build() ); } diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/impl/user/UserSwitchPrimaryGroup.java b/common/src/main/java/me/lucko/luckperms/common/commands/impl/user/UserSwitchPrimaryGroup.java index 5d7ef235e..99ba19656 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/impl/user/UserSwitchPrimaryGroup.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/impl/user/UserSwitchPrimaryGroup.java @@ -25,7 +25,6 @@ package me.lucko.luckperms.common.commands.impl.user; -import me.lucko.luckperms.api.context.ContextSet; import me.lucko.luckperms.common.actionlog.ExtendedLogEntry; import me.lucko.luckperms.common.commands.ArgumentPermissions; import me.lucko.luckperms.common.commands.CommandException; @@ -39,6 +38,7 @@ import me.lucko.luckperms.common.locale.LocaleManager; import me.lucko.luckperms.common.locale.Message; import me.lucko.luckperms.common.model.Group; import me.lucko.luckperms.common.model.User; +import me.lucko.luckperms.common.node.NodeFactory; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.utils.Predicates; @@ -74,7 +74,7 @@ public class UserSwitchPrimaryGroup extends SubCommand { if (!user.inheritsGroup(group)) { Message.USER_PRIMARYGROUP_ERROR_NOTMEMBER.send(sender, user.getFriendlyName(), group.getName()); - user.setInheritGroup(group, ContextSet.empty()); + user.setPermission(NodeFactory.newBuilder("group." + group.getName()).build()); } user.getPrimaryGroup().setStoredValue(group.getName()); diff --git a/common/src/main/java/me/lucko/luckperms/common/constants/CommandPermission.java b/common/src/main/java/me/lucko/luckperms/common/constants/CommandPermission.java index ee4843d81..99f7da72b 100644 --- a/common/src/main/java/me/lucko/luckperms/common/constants/CommandPermission.java +++ b/common/src/main/java/me/lucko/luckperms/common/constants/CommandPermission.java @@ -100,6 +100,7 @@ public enum CommandPermission { USER_PROMOTE("promote", USER), USER_DEMOTE("demote", USER), USER_CLEAR("clear", USER), + USER_CLONE("clone", USER), GROUP_INFO("info", GROUP), GROUP_PERM_INFO("permission.info", GROUP), diff --git a/common/src/main/java/me/lucko/luckperms/common/locale/CommandSpec.java b/common/src/main/java/me/lucko/luckperms/common/locale/CommandSpec.java index e54998506..9c76ac05a 100644 --- a/common/src/main/java/me/lucko/luckperms/common/locale/CommandSpec.java +++ b/common/src/main/java/me/lucko/luckperms/common/locale/CommandSpec.java @@ -148,6 +148,11 @@ public enum CommandSpec { Arg.create("context...", false, "the contexts to demote the user in") ) ), + USER_CLONE("Clone the user", + Arg.list( + Arg.create("user", true, "the name/uuid of the user to clone onto") + ) + ), GROUP_INFO("Gives info about the group"), GROUP_LISTMEMBERS("Show the users/groups who inherit from this group", diff --git a/common/src/main/java/me/lucko/luckperms/common/locale/Message.java b/common/src/main/java/me/lucko/luckperms/common/locale/Message.java index 2470d1011..759bf347e 100644 --- a/common/src/main/java/me/lucko/luckperms/common/locale/Message.java +++ b/common/src/main/java/me/lucko/luckperms/common/locale/Message.java @@ -152,6 +152,7 @@ public enum Message { ALREADY_EXISTS("&4{}&c already exists!", true), DOES_NOT_EXIST("&4{}&c does not exist!", true), + USER_LOAD_ERROR("&cAn unexpected error occurred. User not loaded.", true), GROUP_LOAD_ERROR("&cAn unexpected error occurred. Group not loaded.", true), GROUPS_LOAD_ERROR("&cAn unexpected error occurred. Unable to load all groups.", true), diff --git a/common/src/main/java/me/lucko/luckperms/common/model/PermissionHolder.java b/common/src/main/java/me/lucko/luckperms/common/model/PermissionHolder.java index dcde8632a..e03d5eca5 100644 --- a/common/src/main/java/me/lucko/luckperms/common/model/PermissionHolder.java +++ b/common/src/main/java/me/lucko/luckperms/common/model/PermissionHolder.java @@ -975,30 +975,6 @@ public abstract class PermissionHolder { return hasPermission(node, false); } - public boolean hasPermission(String node, boolean value) { - return hasPermission(NodeFactory.make(node, value)).asBoolean() == value; - } - - public boolean hasPermission(String node, boolean value, String server) { - return hasPermission(NodeFactory.make(node, value, server)).asBoolean() == value; - } - - public boolean hasPermission(String node, boolean value, String server, String world) { - return hasPermission(NodeFactory.make(node, value, server, world)).asBoolean() == value; - } - - public boolean hasPermission(String node, boolean value, boolean temporary) { - return hasPermission(NodeFactory.make(node, value, temporary)).asBoolean() == value; - } - - public boolean hasPermission(String node, boolean value, String server, boolean temporary) { - return hasPermission(NodeFactory.make(node, value, server, temporary)).asBoolean() == value; - } - - public boolean hasPermission(String node, boolean value, String server, String world, boolean temporary) { - return hasPermission(NodeFactory.make(node, value, server, world, temporary)).asBoolean() == value; - } - /** * Check if the holder inherits a node * @@ -1025,30 +1001,6 @@ public abstract class PermissionHolder { return inheritsPermissionInfo(node).getResult(); } - public boolean inheritsPermission(String node, boolean value) { - return inheritsPermission(NodeFactory.make(node, value)).asBoolean() == value; - } - - public boolean inheritsPermission(String node, boolean value, String server) { - return inheritsPermission(NodeFactory.make(node, value, server)).asBoolean() == value; - } - - public boolean inheritsPermission(String node, boolean value, String server, String world) { - return inheritsPermission(NodeFactory.make(node, value, server, world)).asBoolean() == value; - } - - public boolean inheritsPermission(String node, boolean value, boolean temporary) { - return inheritsPermission(NodeFactory.make(node, value, temporary)).asBoolean() == value; - } - - public boolean inheritsPermission(String node, boolean value, String server, boolean temporary) { - return inheritsPermission(NodeFactory.make(node, value, server, temporary)).asBoolean() == value; - } - - public boolean inheritsPermission(String node, boolean value, String server, String world, boolean temporary) { - return inheritsPermission(NodeFactory.make(node, value, server, world, temporary)).asBoolean() == value; - } - /** * Sets a permission node * @@ -1201,33 +1153,6 @@ public abstract class PermissionHolder { return DataMutateResult.SUCCESS; } - /** - * Unsets a permission node - * - * @param node the node to unset - */ - public DataMutateResult unsetPermissionExact(Node node) { - ImmutableCollection before = getEnduringNodes().values(); - - nodesLock.lock(); - try { - nodes.get(node.getFullContexts().makeImmutable()).removeIf(e -> e.equals(node)); - } finally { - nodesLock.unlock(); - } - - invalidateCache(); - - ImmutableCollection after = getEnduringNodes().values(); - - if (before.size() == after.size()) { - return DataMutateResult.LACKS; - } - - plugin.getApiProvider().getEventFactory().handleNodeRemove(node, this, before, after); - return DataMutateResult.SUCCESS; - } - /** * Unsets a transient permission node * @@ -1255,29 +1180,13 @@ public abstract class PermissionHolder { } public boolean inheritsGroup(Group group) { - return group.getName().equalsIgnoreCase(this.getObjectName()) || hasPermission("group." + group.getName(), true); + return group.getName().equalsIgnoreCase(this.getObjectName()) || hasPermission(NodeFactory.make("group." + group.getName(), true)).asBoolean(); } public boolean inheritsGroup(Group group, ContextSet contextSet) { return group.getName().equalsIgnoreCase(this.getObjectName()) || hasPermission(NodeFactory.newBuilder("group." + group.getName()).withExtraContext(contextSet).build()).asBoolean(); } - public boolean inheritsGroup(Group group, String server) { - return group.getName().equalsIgnoreCase(this.getObjectName()) || hasPermission("group." + group.getName(), true, server); - } - - public boolean inheritsGroup(Group group, String server, String world) { - return group.getName().equalsIgnoreCase(this.getObjectName()) || hasPermission("group." + group.getName(), true, server, world); - } - - public DataMutateResult setInheritGroup(Group group, ContextSet contexts) { - return setPermission(NodeFactory.newBuilder("group." + group.getName()).withExtraContext(contexts).build()); - } - - public DataMutateResult unsetInheritGroup(Group group, ContextSet contexts) { - return unsetPermission(NodeFactory.newBuilder("group." + group.getName()).withExtraContext(contexts).build()); - } - /** * Clear all of the holders permission nodes */ @@ -1478,32 +1387,6 @@ public abstract class PermissionHolder { return true; } - /** - * @return The temporary nodes held by the holder - */ - public Set getTemporaryNodes() { - return getOwnNodes().stream().filter(Node::isTemporary).collect(Collectors.toSet()); - } - - /** - * @return The permanent nodes held by the holder - */ - public Set getPermanentNodes() { - return getOwnNodes().stream().filter(Node::isPermanent).collect(Collectors.toSet()); - } - - public Set getPrefixNodes() { - return getOwnNodes().stream().filter(Node::isPrefix).collect(Collectors.toSet()); - } - - public Set getSuffixNodes() { - return getOwnNodes().stream().filter(Node::isSuffix).collect(Collectors.toSet()); - } - - public Set getMetaNodes() { - return getOwnNodes().stream().filter(Node::isMeta).collect(Collectors.toSet()); - } - public OptionalInt getWeight() { return weightCache.get(); }