diff --git a/common/src/main/java/me/lucko/luckperms/commands/CommandManager.java b/common/src/main/java/me/lucko/luckperms/commands/CommandManager.java index cd6807cb1..5a2dda683 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/CommandManager.java +++ b/common/src/main/java/me/lucko/luckperms/commands/CommandManager.java @@ -39,6 +39,7 @@ import me.lucko.luckperms.commands.track.DeleteTrack; import me.lucko.luckperms.commands.track.ListTracks; import me.lucko.luckperms.commands.track.TrackMainCommand; import me.lucko.luckperms.commands.user.UserMainCommand; +import me.lucko.luckperms.commands.usersbulkedit.UsersBulkEditMainCommand; import java.util.ArrayList; import java.util.Collections; @@ -64,6 +65,7 @@ public class CommandManager { .add(new ExportCommand()) .add(new QueueCommand()) .add(new MigrationMainCommand()) + .add(new UsersBulkEditMainCommand()) .add(new CreateGroup()) .add(new DeleteGroup()) .add(new ListGroups()) diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserBulkChange.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserBulkChange.java index e58180f56..6ed2d1bda 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserBulkChange.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserBulkChange.java @@ -63,6 +63,11 @@ public class UserBulkChange extends SubCommand { if (type.equals("world")) { while (iterator.hasNext()) { Node element = iterator.next(); + + if (element.isGroupNode()) { + continue; + } + String world = element.getWorld().orElse("null"); if (!world.equals(from)) { continue; @@ -74,6 +79,11 @@ public class UserBulkChange extends SubCommand { } else { while (iterator.hasNext()) { Node element = iterator.next(); + + if (element.isGroupNode()) { + continue; + } + String server = element.getServer().orElse("global"); if (!server.equals(from)) { continue; diff --git a/common/src/main/java/me/lucko/luckperms/commands/usersbulkedit/UsersBulkEditMainCommand.java b/common/src/main/java/me/lucko/luckperms/commands/usersbulkedit/UsersBulkEditMainCommand.java new file mode 100644 index 000000000..9da6b87a4 --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/commands/usersbulkedit/UsersBulkEditMainCommand.java @@ -0,0 +1,94 @@ +/* + * 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.commands.usersbulkedit; + +import com.google.common.collect.ImmutableList; +import me.lucko.luckperms.LuckPermsPlugin; +import me.lucko.luckperms.commands.MainCommand; +import me.lucko.luckperms.commands.Sender; +import me.lucko.luckperms.commands.SubCommand; +import me.lucko.luckperms.commands.usersbulkedit.subcommands.BulkEditGroup; +import me.lucko.luckperms.commands.usersbulkedit.subcommands.BulkEditPermission; +import me.lucko.luckperms.storage.Datastore; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +public class UsersBulkEditMainCommand extends MainCommand { + + public UsersBulkEditMainCommand() { + super("UsersBulkEdit", "/%s usersbulkedit", 1, ImmutableList.>builder() + .add(new BulkEditGroup()) + .add(new BulkEditPermission()) + .build() + ); + } + + @Override + protected Datastore getTarget(String target, LuckPermsPlugin plugin, Sender sender) { + return plugin.getDatastore(); + } + + @Override + protected void cleanup(Datastore datastore, LuckPermsPlugin plugin) { + + } + + @Override + protected List getObjects(LuckPermsPlugin plugin) { + return null; + } + + @Override + protected List onTabComplete(Sender sender, List args, LuckPermsPlugin plugin) { + final List> subs = getSubCommands().stream() + .filter(s -> s.isAuthorized(sender)) + .collect(Collectors.toList()); + + if (args.size() <= 1) { + if (args.isEmpty() || args.get(0).equalsIgnoreCase("")) { + return subs.stream() + .map(m -> m.getName().toLowerCase()) + .collect(Collectors.toList()); + } + + return subs.stream() + .map(m -> m.getName().toLowerCase()) + .filter(s -> s.toLowerCase().startsWith(args.get(0).toLowerCase())) + .collect(Collectors.toList()); + } + + Optional> o = subs.stream() + .filter(s -> s.getName().equalsIgnoreCase(args.get(0))) + .limit(1) + .findAny(); + + if (!o.isPresent()) { + return Collections.emptyList(); + } + + return o.get().onTabComplete(plugin, sender, args.subList(1, args.size())); + } +} diff --git a/common/src/main/java/me/lucko/luckperms/commands/usersbulkedit/subcommands/BulkEditGroup.java b/common/src/main/java/me/lucko/luckperms/commands/usersbulkedit/subcommands/BulkEditGroup.java new file mode 100644 index 000000000..8d6119dce --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/commands/usersbulkedit/subcommands/BulkEditGroup.java @@ -0,0 +1,128 @@ +/* + * 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.commands.usersbulkedit.subcommands; + +import me.lucko.luckperms.LuckPermsPlugin; +import me.lucko.luckperms.api.Node; +import me.lucko.luckperms.commands.CommandResult; +import me.lucko.luckperms.commands.Predicate; +import me.lucko.luckperms.commands.Sender; +import me.lucko.luckperms.commands.SubCommand; +import me.lucko.luckperms.constants.Message; +import me.lucko.luckperms.constants.Permission; +import me.lucko.luckperms.storage.Datastore; +import me.lucko.luckperms.users.User; + +import java.util.*; + +public class BulkEditGroup extends SubCommand { + public BulkEditGroup() { + super("group", "Bulk edit group memberships", " ", Permission.USER_BULKCHANGE, + Predicate.not(4)); + } + + @Override + public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Datastore datastore, List args, String label) { + String group = args.get(0); + String type = args.get(1).toLowerCase(); + String from = args.get(2); + String to = args.get(3); + if (to.equals("null")) { + to = null; + } + + if (!type.equals("world") && !type.equals("server")) { + Message.BULK_CHANGE_TYPE_ERROR.send(sender); + return CommandResult.FAILURE; + } + + Set uuids = datastore.getUniqueUsers(); + + for (UUID u : uuids) { + plugin.getDatastore().loadUser(u, "null"); + User user = plugin.getUserManager().get(u); + if (user == null) { + continue; + } + + Set toAdd = new HashSet<>(); + Iterator iterator = user.getNodes().iterator(); + if (type.equals("world")) { + while (iterator.hasNext()) { + Node element = iterator.next(); + + if (!element.isGroupNode()) { + continue; + } + + if (element.getGroupName().equals(user.getPrimaryGroup())) { + continue; + } + + if (!group.equals("null") && !element.getGroupName().equals(group)) { + continue; + } + + String world = element.getWorld().orElse("null"); + if (!world.equals(from)) { + continue; + } + + iterator.remove(); + toAdd.add(me.lucko.luckperms.core.Node.builderFromExisting(element).setWorld(to).build()); + } + } else { + while (iterator.hasNext()) { + Node element = iterator.next(); + + if (!element.isGroupNode()) { + continue; + } + + if (element.getGroupName().equals(user.getPrimaryGroup())) { + continue; + } + + if (!group.equals("null") && !element.getGroupName().equals(group)) { + continue; + } + + String server = element.getServer().orElse("global"); + if (!server.equals(from)) { + continue; + } + + iterator.remove(); + toAdd.add(me.lucko.luckperms.core.Node.builderFromExisting(element).setServer(to).build()); + } + } + + user.getNodes().addAll(toAdd); + plugin.getUserManager().cleanup(user); + plugin.getDatastore().saveUser(user); + } + + Message.BULK_CHANGE_SUCCESS.send(sender, uuids.size()); + return CommandResult.SUCCESS; + } +} diff --git a/common/src/main/java/me/lucko/luckperms/commands/usersbulkedit/subcommands/BulkEditPermission.java b/common/src/main/java/me/lucko/luckperms/commands/usersbulkedit/subcommands/BulkEditPermission.java new file mode 100644 index 000000000..071a41678 --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/commands/usersbulkedit/subcommands/BulkEditPermission.java @@ -0,0 +1,120 @@ +/* + * 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.commands.usersbulkedit.subcommands; + +import me.lucko.luckperms.LuckPermsPlugin; +import me.lucko.luckperms.api.Node; +import me.lucko.luckperms.commands.CommandResult; +import me.lucko.luckperms.commands.Predicate; +import me.lucko.luckperms.commands.Sender; +import me.lucko.luckperms.commands.SubCommand; +import me.lucko.luckperms.constants.Message; +import me.lucko.luckperms.constants.Permission; +import me.lucko.luckperms.storage.Datastore; +import me.lucko.luckperms.users.User; + +import java.util.*; + +public class BulkEditPermission extends SubCommand { + public BulkEditPermission() { + super("permission", "Bulk edit permissions", " ", Permission.USER_BULKCHANGE, + Predicate.not(4)); + } + + @Override + public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Datastore datastore, List args, String label) { + String node = args.get(0); + String type = args.get(1).toLowerCase(); + String from = args.get(2); + String to = args.get(3); + if (to.equals("null")) { + to = null; + } + + if (!type.equals("world") && !type.equals("server")) { + Message.BULK_CHANGE_TYPE_ERROR.send(sender); + return CommandResult.FAILURE; + } + + Set uuids = datastore.getUniqueUsers(); + + for (UUID u : uuids) { + plugin.getDatastore().loadUser(u, "null"); + User user = plugin.getUserManager().get(u); + if (user == null) { + continue; + } + + Set toAdd = new HashSet<>(); + Iterator iterator = user.getNodes().iterator(); + if (type.equals("world")) { + while (iterator.hasNext()) { + Node element = iterator.next(); + + if (element.isGroupNode()) { + continue; + } + + if (!node.equals("null") && !element.getPermission().equals(node)) { + continue; + } + + String world = element.getWorld().orElse("null"); + if (!world.equals(from)) { + continue; + } + + iterator.remove(); + toAdd.add(me.lucko.luckperms.core.Node.builderFromExisting(element).setWorld(to).build()); + } + } else { + while (iterator.hasNext()) { + Node element = iterator.next(); + + if (element.isGroupNode()) { + continue; + } + + if (!node.equals("null") && !element.getPermission().equals(node)) { + continue; + } + + String server = element.getServer().orElse("global"); + if (!server.equals(from)) { + continue; + } + + iterator.remove(); + toAdd.add(me.lucko.luckperms.core.Node.builderFromExisting(element).setServer(to).build()); + } + } + + user.getNodes().addAll(toAdd); + plugin.getUserManager().cleanup(user); + plugin.getDatastore().saveUser(user); + } + + Message.BULK_CHANGE_SUCCESS.send(sender, uuids.size()); + return CommandResult.SUCCESS; + } +} diff --git a/common/src/main/java/me/lucko/luckperms/users/UserManager.java b/common/src/main/java/me/lucko/luckperms/users/UserManager.java index 3f6b79fed..e4da6d427 100644 --- a/common/src/main/java/me/lucko/luckperms/users/UserManager.java +++ b/common/src/main/java/me/lucko/luckperms/users/UserManager.java @@ -74,10 +74,13 @@ public abstract class UserManager extends AbstractManager { */ public void giveDefaultIfNeeded(User user, boolean save) { boolean hasGroup = false; - for (Node node : user.getPermissions(false)) { - if (node.isGroupNode()) { - hasGroup = true; - break; + + if (user.getPrimaryGroup() != null && !user.getPrimaryGroup().isEmpty()) { + for (Node node : user.getPermissions(false)) { + if (node.isGroupNode()) { + hasGroup = true; + break; + } } }