From 25551641fc3d72b76c4f2c12ff006762cd936c68 Mon Sep 17 00:00:00 2001 From: Luck Date: Thu, 28 May 2020 21:36:06 +0100 Subject: [PATCH] Add option to merge into instead of overriding existing data in imports (#2324) --- .../lucko/luckperms/common/backup/Importer.java | 16 +++++++++++++--- .../common/commands/group/GroupClone.java | 2 +- .../common/commands/group/GroupRename.java | 2 +- .../common/commands/misc/ImportCommand.java | 4 ++-- .../common/commands/user/UserClone.java | 2 +- .../common/locale/command/CommandSpec.java | 6 ++++-- .../lucko/luckperms/common/model/NodeMap.java | 17 ++++++++++------- .../common/model/PermissionHolder.java | 9 +++++++-- 8 files changed, 39 insertions(+), 19 deletions(-) diff --git a/common/src/main/java/me/lucko/luckperms/common/backup/Importer.java b/common/src/main/java/me/lucko/luckperms/common/backup/Importer.java index 2c79a5c55..0fec4d633 100644 --- a/common/src/main/java/me/lucko/luckperms/common/backup/Importer.java +++ b/common/src/main/java/me/lucko/luckperms/common/backup/Importer.java @@ -66,8 +66,9 @@ public class Importer implements Runnable { private final LuckPermsPlugin plugin; private final Set notify; private final JsonObject data; + private final boolean merge; - public Importer(LuckPermsPlugin plugin, Sender executor, JsonObject data) { + public Importer(LuckPermsPlugin plugin, Sender executor, JsonObject data, boolean merge) { this.plugin = plugin; if (executor.isConsole()) { @@ -76,6 +77,7 @@ public class Importer implements Runnable { this.notify = ImmutableSet.of(executor, plugin.getConsoleSender()); } this.data = data; + this.merge = merge; } private static final class UserData { @@ -92,7 +94,11 @@ public class Importer implements Runnable { private void processGroup(String groupName, Set nodes) { Group group = this.plugin.getStorage().createAndLoadGroup(groupName, CreationCause.INTERNAL).join(); - group.setNodes(DataType.NORMAL, nodes); + if (this.merge) { + group.mergeNodes(DataType.NORMAL, nodes); + } else { + group.setNodes(DataType.NORMAL, nodes); + } this.plugin.getStorage().saveGroup(group); } @@ -107,7 +113,11 @@ public class Importer implements Runnable { if (userData.primaryGroup != null) { user.getPrimaryGroup().setStoredValue(userData.primaryGroup); } - user.setNodes(DataType.NORMAL, userData.nodes); + if (this.merge) { + user.mergeNodes(DataType.NORMAL, userData.nodes); + } else { + user.setNodes(DataType.NORMAL, userData.nodes); + } this.plugin.getStorage().saveUser(user).join(); this.plugin.getUserManager().getHouseKeeper().cleanup(user.getUniqueId()); } diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupClone.java b/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupClone.java index 6c77e99f8..2644433fa 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupClone.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupClone.java @@ -74,7 +74,7 @@ public class GroupClone extends ChildCommand { return CommandResult.NO_PERMISSION; } - newGroup.replaceNodes(DataType.NORMAL, group.normalData().immutable()); + newGroup.setNodes(DataType.NORMAL, group.normalData().immutable()); Message.CLONE_SUCCESS.send(sender, group.getName(), newGroup.getName()); diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupRename.java b/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupRename.java index fac75daf7..f94f2b228 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupRename.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupRename.java @@ -80,7 +80,7 @@ public class GroupRename extends ChildCommand { return CommandResult.FAILURE; } - newGroup.replaceNodes(DataType.NORMAL, group.normalData().immutable()); + newGroup.setNodes(DataType.NORMAL, group.normalData().immutable()); Message.RENAME_SUCCESS.send(sender, group.getName(), newGroup.getName()); diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/misc/ImportCommand.java b/common/src/main/java/me/lucko/luckperms/common/commands/misc/ImportCommand.java index e10caf4e9..364f53d13 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/misc/ImportCommand.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/misc/ImportCommand.java @@ -53,7 +53,7 @@ public class ImportCommand extends SingleCommand { private final AtomicBoolean running = new AtomicBoolean(false); public ImportCommand(LocaleManager locale) { - super(CommandSpec.IMPORT.localize(locale), "Import", CommandPermission.IMPORT, Predicates.not(1)); + super(CommandSpec.IMPORT.localize(locale), "Import", CommandPermission.IMPORT, Predicates.notInRange(1, 2)); } @Override @@ -105,7 +105,7 @@ public class ImportCommand extends SingleCommand { return CommandResult.FAILURE; } - Importer importer = new Importer(plugin, sender, data); + Importer importer = new Importer(plugin, sender, data, args.contains("--merge")); // Run the importer in its own thread. plugin.getBootstrap().getScheduler().executeAsync(() -> { diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/user/UserClone.java b/common/src/main/java/me/lucko/luckperms/common/commands/user/UserClone.java index 06edb94ea..dd83a2256 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/user/UserClone.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/user/UserClone.java @@ -73,7 +73,7 @@ public class UserClone extends ChildCommand { return CommandResult.NO_PERMISSION; } - otherUser.replaceNodes(DataType.NORMAL, user.normalData().immutable()); + otherUser.setNodes(DataType.NORMAL, user.normalData().immutable()); Message.CLONE_SUCCESS.send(sender, user.getFormattedDisplayName(), otherUser.getFormattedDisplayName()); diff --git a/common/src/main/java/me/lucko/luckperms/common/locale/command/CommandSpec.java b/common/src/main/java/me/lucko/luckperms/common/locale/command/CommandSpec.java index 2be663abf..2a9a25e6d 100644 --- a/common/src/main/java/me/lucko/luckperms/common/locale/command/CommandSpec.java +++ b/common/src/main/java/me/lucko/luckperms/common/locale/command/CommandSpec.java @@ -89,12 +89,14 @@ public enum CommandSpec { NETWORK_SYNC("Sync changes with the storage and request that all other servers on the network do the same", "/%s networksync"), IMPORT("Imports data from a (previously created) export file", "/%s import ", Argument.list( - Argument.create("file", true, "the file to import from") + Argument.create("file", true, "the file to import from"), + Argument.create("--merge", false, "merge import into existing data") ) ), EXPORT("Exports all permissions data to an 'export' file. Can be re-imported at a later time.", "/%s export ", Argument.list( - Argument.create("file", true, "the file to export to") + Argument.create("file", true, "the file to export to"), + Argument.create("--without-users", false, "exclude users from the export") ) ), RELOAD_CONFIG("Reload some of the config options", "/%s reloadconfig"), diff --git a/common/src/main/java/me/lucko/luckperms/common/model/NodeMap.java b/common/src/main/java/me/lucko/luckperms/common/model/NodeMap.java index ee69bb7af..10885ef97 100644 --- a/common/src/main/java/me/lucko/luckperms/common/model/NodeMap.java +++ b/common/src/main/java/me/lucko/luckperms/common/model/NodeMap.java @@ -28,7 +28,6 @@ package me.lucko.luckperms.common.model; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSetMultimap; -import com.google.common.collect.Multimap; import me.lucko.luckperms.common.cache.Cache; import me.lucko.luckperms.common.config.ConfigKeys; @@ -336,19 +335,23 @@ public final class NodeMap { void setContent(Iterable set) { this.map.clear(); this.inheritanceMap.clear(); - for (Node n : set) { - add(n); - } + mergeContent(set); } void setContent(Stream stream) { this.map.clear(); this.inheritanceMap.clear(); - stream.forEach(this::add); + mergeContent(stream); } - void setContent(Multimap multimap) { - setContent(multimap.values()); + void mergeContent(Iterable set) { + for (Node n : set) { + add(n); + } + } + + void mergeContent(Stream stream) { + stream.forEach(this::add); } boolean removeIf(Predicate predicate) { 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 703fca4be..79c807b3f 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 @@ -253,8 +253,13 @@ public abstract class PermissionHolder { invalidateCache(); } - public void replaceNodes(DataType type, Multimap multimap) { - getData(type).setContent(multimap); + public void setNodes(DataType type, Multimap multimap) { + getData(type).setContent(multimap.values()); + invalidateCache(); + } + + public void mergeNodes(DataType type, Iterable set) { + getData(type).mergeContent(set); invalidateCache(); }