mirror of
https://github.com/lucko/LuckPerms.git
synced 2025-09-09 05:40:47 +02:00
Move migration commands to a separate jar
This commit is contained in:
@@ -17,25 +17,6 @@ dependencies {
|
||||
exclude(module: 'bukkit')
|
||||
}
|
||||
compileOnly 'lilypad.client.connect:api:0.0.1-SNAPSHOT'
|
||||
|
||||
// migration plugins
|
||||
compileOnly 'org.tyrannyofheaven.bukkit:zPermissions:1.3'
|
||||
compileOnly('ru.tehkode:PermissionsEx:1.23.5') {
|
||||
exclude(module: 'bukkit')
|
||||
exclude(module: 'updater')
|
||||
exclude(module: 'commons-dbcp')
|
||||
exclude(module: 'AccountsClient')
|
||||
}
|
||||
compileOnly 'com.github.gustav9797:PowerfulPermsAPI:4.5.2'
|
||||
compileOnly 'org.anjocaido:GroupManager:1.4'
|
||||
compileOnly('nl.svenar:powerranks:1.9.2') {
|
||||
exclude(module: 'nametagedit')
|
||||
}
|
||||
compileOnly 'de.bananaco:bpermissions-api:2.12'
|
||||
compileOnly('com.platymuus:bukkit-permissions:2.5') {
|
||||
exclude(module: 'bukkit')
|
||||
exclude(module: 'metrics')
|
||||
}
|
||||
}
|
||||
|
||||
processResources {
|
||||
|
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* 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.bukkit.migration;
|
||||
|
||||
import me.lucko.luckperms.common.util.ProgressLogger;
|
||||
import me.lucko.luckperms.common.util.Uuids;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public final class BukkitUuids {
|
||||
private BukkitUuids() {}
|
||||
|
||||
public static UUID lookupUuid(ProgressLogger log, String s) {
|
||||
UUID uuid = Uuids.parse(s);
|
||||
if (uuid == null) {
|
||||
try {
|
||||
//noinspection deprecation
|
||||
uuid = Bukkit.getOfflinePlayer(s).getUniqueId();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (uuid == null) {
|
||||
log.logError("Unable to get a UUID for user identifier: " + s);
|
||||
}
|
||||
return uuid;
|
||||
}
|
||||
|
||||
}
|
@@ -1,236 +0,0 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* 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.bukkit.migration;
|
||||
|
||||
import de.bananaco.bpermissions.api.Calculable;
|
||||
import de.bananaco.bpermissions.api.CalculableType;
|
||||
import de.bananaco.bpermissions.api.Permission;
|
||||
import de.bananaco.bpermissions.api.World;
|
||||
import de.bananaco.bpermissions.api.WorldManager;
|
||||
|
||||
import me.lucko.luckperms.common.command.CommandResult;
|
||||
import me.lucko.luckperms.common.command.abstraction.ChildCommand;
|
||||
import me.lucko.luckperms.common.command.access.CommandPermission;
|
||||
import me.lucko.luckperms.common.command.spec.CommandSpec;
|
||||
import me.lucko.luckperms.common.command.utils.ArgumentList;
|
||||
import me.lucko.luckperms.common.commands.migration.MigrationUtils;
|
||||
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.model.manager.group.GroupManager;
|
||||
import me.lucko.luckperms.common.node.factory.NodeBuilders;
|
||||
import me.lucko.luckperms.common.node.types.Inheritance;
|
||||
import me.lucko.luckperms.common.node.types.Meta;
|
||||
import me.lucko.luckperms.common.node.types.Prefix;
|
||||
import me.lucko.luckperms.common.node.types.Suffix;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.util.Iterators;
|
||||
import me.lucko.luckperms.common.util.Predicates;
|
||||
import me.lucko.luckperms.common.util.ProgressLogger;
|
||||
|
||||
import net.luckperms.api.context.DefaultContextKeys;
|
||||
import net.luckperms.api.event.cause.CreationCause;
|
||||
import net.luckperms.api.model.data.DataType;
|
||||
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class MigrationBPermissions extends ChildCommand<Object> {
|
||||
private static final Field UCONFIG_FIELD;
|
||||
static {
|
||||
try {
|
||||
UCONFIG_FIELD = Class.forName("de.bananaco.bpermissions.imp.YamlWorld").getDeclaredField("uconfig");
|
||||
UCONFIG_FIELD.setAccessible(true);
|
||||
} catch (ClassNotFoundException | NoSuchFieldException e) {
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public MigrationBPermissions() {
|
||||
super(CommandSpec.MIGRATION_COMMAND, "bpermissions", CommandPermission.MIGRATION, Predicates.alwaysFalse());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Object ignored, ArgumentList args, String label) {
|
||||
ProgressLogger log = new ProgressLogger(Message.MIGRATION_LOG, Message.MIGRATION_LOG_PROGRESS, "bPermissions");
|
||||
log.addListener(plugin.getConsoleSender());
|
||||
log.addListener(sender);
|
||||
|
||||
log.log("Starting.");
|
||||
|
||||
WorldManager worldManager = WorldManager.getInstance();
|
||||
if (worldManager == null) {
|
||||
log.logError("Plugin not loaded.");
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
|
||||
log.log("Forcing the plugin to load all data. This could take a while.");
|
||||
for (World world : worldManager.getAllWorlds()) {
|
||||
log.log("Loading users in world " + world.getName());
|
||||
|
||||
YamlConfiguration yamlWorldUsers = null;
|
||||
try {
|
||||
yamlWorldUsers = (YamlConfiguration) UCONFIG_FIELD.get(world);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
|
||||
if (yamlWorldUsers == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ConfigurationSection configSection = yamlWorldUsers.getConfigurationSection("users");
|
||||
if (configSection == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Set<String> users = configSection.getKeys(false);
|
||||
if (users == null) {
|
||||
log.logError("Couldn't get a list of users.");
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
AtomicInteger userLoadCount = new AtomicInteger(0);
|
||||
for (String user : users) {
|
||||
world.loadOne(user, CalculableType.USER);
|
||||
log.logProgress("Forcefully loaded {} users so far.", userLoadCount.incrementAndGet(), ProgressLogger.DEFAULT_NOTIFY_FREQUENCY);
|
||||
}
|
||||
}
|
||||
log.log("Forcefully loaded all users.");
|
||||
|
||||
// Migrate one world at a time.
|
||||
log.log("Starting world migration.");
|
||||
Iterators.tryIterate(worldManager.getAllWorlds(), world -> {
|
||||
log.log("Migrating world: " + world.getName());
|
||||
|
||||
// Migrate all groups
|
||||
log.log("Starting group migration in world " + world.getName() + ".");
|
||||
AtomicInteger groupCount = new AtomicInteger(0);
|
||||
|
||||
Iterators.tryIterate(world.getAll(CalculableType.GROUP), group -> {
|
||||
String groupName = MigrationUtils.standardizeName(group.getName());
|
||||
if (group.getName().equalsIgnoreCase(world.getDefaultGroup())) {
|
||||
groupName = GroupManager.DEFAULT_GROUP_NAME;
|
||||
}
|
||||
|
||||
// Make a LuckPerms group for the one being migrated.
|
||||
Group lpGroup = plugin.getStorage().createAndLoadGroup(groupName, CreationCause.INTERNAL).join();
|
||||
|
||||
MigrationUtils.setGroupWeight(lpGroup, group.getPriority());
|
||||
migrateHolder(world, group, lpGroup);
|
||||
|
||||
plugin.getStorage().saveGroup(lpGroup);
|
||||
|
||||
log.logAllProgress("Migrated {} groups so far.", groupCount.incrementAndGet());
|
||||
});
|
||||
log.log("Migrated " + groupCount.get() + " groups in world " + world.getName() + ".");
|
||||
|
||||
|
||||
// Migrate all users
|
||||
log.log("Starting user migration in world " + world.getName() + ".");
|
||||
AtomicInteger userCount = new AtomicInteger(0);
|
||||
Iterators.tryIterate(world.getAll(CalculableType.USER), user -> {
|
||||
// There is no mention of UUIDs in the API. I assume that name = uuid. idk?
|
||||
UUID uuid = BukkitUuids.lookupUuid(log, user.getName());
|
||||
if (uuid == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Make a LuckPerms user for the one being migrated.
|
||||
User lpUser = plugin.getStorage().loadUser(uuid, null).join();
|
||||
|
||||
migrateHolder(world, user, lpUser);
|
||||
|
||||
plugin.getStorage().saveUser(lpUser);
|
||||
plugin.getUserManager().getHouseKeeper().cleanup(lpUser.getUniqueId());
|
||||
|
||||
log.logProgress("Migrated {} users so far.", userCount.incrementAndGet(), ProgressLogger.DEFAULT_NOTIFY_FREQUENCY);
|
||||
});
|
||||
|
||||
log.log("Migrated " + userCount.get() + " users in world " + world.getName() + ".");
|
||||
});
|
||||
|
||||
log.log("Success! Migration complete.");
|
||||
log.log("Don't forget to remove the bPermissions jar from your plugins folder & restart the server. " +
|
||||
"LuckPerms may not take over as the server permission handler until this is done.");
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
|
||||
private static void migrateHolder(World world, Calculable c, PermissionHolder holder) {
|
||||
// Migrate the groups permissions in this world
|
||||
for (Permission p : c.getPermissions()) {
|
||||
if (p.name().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
holder.setNode(DataType.NORMAL, NodeBuilders.determineMostApplicable(p.name()).value(p.isTrue()).withContext(DefaultContextKeys.SERVER_KEY, "global").withContext(DefaultContextKeys.WORLD_KEY, world.getName()).build(), true);
|
||||
|
||||
// Include any child permissions
|
||||
for (Map.Entry<String, Boolean> child : p.getChildren().entrySet()) {
|
||||
if (child.getKey().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
holder.setNode(DataType.NORMAL, NodeBuilders.determineMostApplicable(child.getKey()).value((boolean) child.getValue()).withContext(DefaultContextKeys.SERVER_KEY, "global").withContext(DefaultContextKeys.WORLD_KEY, world.getName()).build(), true);
|
||||
}
|
||||
}
|
||||
|
||||
// Migrate any inherited groups
|
||||
c.getGroups().forEach(parent -> {
|
||||
String parentName = MigrationUtils.standardizeName(parent.getName());
|
||||
if (parent.getName().equalsIgnoreCase(world.getDefaultGroup())) {
|
||||
parentName = GroupManager.DEFAULT_GROUP_NAME;
|
||||
}
|
||||
|
||||
holder.setNode(DataType.NORMAL, Inheritance.builder(parentName).value(true).withContext(DefaultContextKeys.SERVER_KEY, "global").withContext(DefaultContextKeys.WORLD_KEY, world.getName()).build(), true);
|
||||
});
|
||||
|
||||
// Migrate existing meta
|
||||
for (Map.Entry<String, String> meta : c.getMeta().entrySet()) {
|
||||
if (meta.getKey().isEmpty() || meta.getValue().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (meta.getKey().equalsIgnoreCase("prefix")) {
|
||||
holder.setNode(DataType.NORMAL, Prefix.builder(meta.getValue(), c.getPriority()).withContext(DefaultContextKeys.WORLD_KEY, world.getName()).build(), true);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (meta.getKey().equalsIgnoreCase("suffix")) {
|
||||
holder.setNode(DataType.NORMAL, Suffix.builder(meta.getValue(), c.getPriority()).withContext(DefaultContextKeys.WORLD_KEY, world.getName()).build(), true);
|
||||
continue;
|
||||
}
|
||||
|
||||
holder.setNode(DataType.NORMAL, Meta.builder(meta.getKey(), meta.getValue()).withContext(DefaultContextKeys.WORLD_KEY, world.getName()).build(), true);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,269 +0,0 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* 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.bukkit.migration;
|
||||
|
||||
import me.lucko.luckperms.common.command.CommandResult;
|
||||
import me.lucko.luckperms.common.command.abstraction.ChildCommand;
|
||||
import me.lucko.luckperms.common.command.access.CommandPermission;
|
||||
import me.lucko.luckperms.common.command.spec.CommandSpec;
|
||||
import me.lucko.luckperms.common.command.utils.ArgumentList;
|
||||
import me.lucko.luckperms.common.commands.migration.MigrationUtils;
|
||||
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.model.UserIdentifier;
|
||||
import me.lucko.luckperms.common.node.types.Inheritance;
|
||||
import me.lucko.luckperms.common.node.types.Meta;
|
||||
import me.lucko.luckperms.common.node.types.Prefix;
|
||||
import me.lucko.luckperms.common.node.types.Suffix;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.util.Iterators;
|
||||
import me.lucko.luckperms.common.util.Predicates;
|
||||
import me.lucko.luckperms.common.util.ProgressLogger;
|
||||
import me.lucko.luckperms.common.util.Uuids;
|
||||
|
||||
import net.luckperms.api.context.DefaultContextKeys;
|
||||
import net.luckperms.api.event.cause.CreationCause;
|
||||
import net.luckperms.api.model.data.DataType;
|
||||
import net.luckperms.api.node.Node;
|
||||
|
||||
import org.anjocaido.groupmanager.GlobalGroups;
|
||||
import org.anjocaido.groupmanager.GroupManager;
|
||||
import org.anjocaido.groupmanager.dataholder.WorldDataHolder;
|
||||
import org.anjocaido.groupmanager.dataholder.worlds.WorldsHolder;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MigrationGroupManager extends ChildCommand<Object> {
|
||||
public MigrationGroupManager() {
|
||||
super(CommandSpec.MIGRATION_GROUPMANAGER, "groupmanager", CommandPermission.MIGRATION, Predicates.is(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Object ignored, ArgumentList args, String label) {
|
||||
ProgressLogger log = new ProgressLogger(Message.MIGRATION_LOG, Message.MIGRATION_LOG_PROGRESS, "GroupManager");
|
||||
log.addListener(plugin.getConsoleSender());
|
||||
log.addListener(sender);
|
||||
|
||||
log.log("Starting.");
|
||||
|
||||
if (!args.get(0).equalsIgnoreCase("true") && !args.get(0).equalsIgnoreCase("false")) {
|
||||
log.logError("Was expecting true/false, but got " + args.get(0) + " instead.");
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
final boolean migrateAsGlobal = Boolean.parseBoolean(args.get(0));
|
||||
final Function<String, String> worldMappingFunc = s -> migrateAsGlobal || s == null ? "global" : s;
|
||||
|
||||
if (!Bukkit.getPluginManager().isPluginEnabled("GroupManager")) {
|
||||
log.logError("Plugin not loaded.");
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
|
||||
List<String> worlds = Bukkit.getWorlds().stream().map(World::getName).map(String::toLowerCase).collect(Collectors.toList());
|
||||
GroupManager gm = (GroupManager) Bukkit.getPluginManager().getPlugin("GroupManager");
|
||||
|
||||
// Migrate Global Groups
|
||||
log.log("Starting global group migration.");
|
||||
GlobalGroups gg = GroupManager.getGlobalGroups();
|
||||
|
||||
AtomicInteger globalGroupCount = new AtomicInteger(0);
|
||||
Iterators.tryIterate(gg.getGroupList(), g -> {
|
||||
String groupName = MigrationUtils.standardizeName(g.getName());
|
||||
Group group = plugin.getStorage().createAndLoadGroup(groupName, CreationCause.INTERNAL).join();
|
||||
|
||||
for (String node : g.getPermissionList()) {
|
||||
if (node.isEmpty()) continue;
|
||||
group.setNode(DataType.NORMAL, MigrationUtils.parseNode(node, true).build(), true);
|
||||
}
|
||||
for (String s : g.getInherits()) {
|
||||
if (s.isEmpty()) continue;
|
||||
group.setNode(DataType.NORMAL, Inheritance.builder(MigrationUtils.standardizeName(s)).build(), true);
|
||||
}
|
||||
|
||||
plugin.getStorage().saveGroup(group);
|
||||
log.logAllProgress("Migrated {} groups so far.", globalGroupCount.incrementAndGet());
|
||||
});
|
||||
log.log("Migrated " + globalGroupCount.get() + " global groups");
|
||||
|
||||
// Collect data
|
||||
Map<UserIdentifier, Set<Node>> users = new HashMap<>();
|
||||
Map<UUID, String> primaryGroups = new HashMap<>();
|
||||
Map<String, Set<Node>> groups = new HashMap<>();
|
||||
|
||||
WorldsHolder wh = gm.getWorldsHolder();
|
||||
|
||||
// Collect data for all users and groups.
|
||||
log.log("Collecting user and group data.");
|
||||
Iterators.tryIterate(worlds, String::toLowerCase, world -> {
|
||||
log.log("Querying world " + world);
|
||||
|
||||
WorldDataHolder wdh = wh.getWorldData(world);
|
||||
|
||||
AtomicInteger groupWorldCount = new AtomicInteger(0);
|
||||
Iterators.tryIterate(wdh.getGroupList(), group -> {
|
||||
String groupName = MigrationUtils.standardizeName(group.getName());
|
||||
|
||||
groups.putIfAbsent(groupName, new HashSet<>());
|
||||
|
||||
for (String node : group.getPermissionList()) {
|
||||
if (node.isEmpty()) continue;
|
||||
groups.get(groupName).add(MigrationUtils.parseNode(node, true).withContext(DefaultContextKeys.WORLD_KEY, worldMappingFunc.apply(world)).build());
|
||||
}
|
||||
for (String s : group.getInherits()) {
|
||||
if (s.isEmpty()) continue;
|
||||
groups.get(groupName).add(Inheritance.builder(MigrationUtils.standardizeName(s)).value(true).withContext(DefaultContextKeys.WORLD_KEY, worldMappingFunc.apply(world)).build());
|
||||
}
|
||||
|
||||
String[] metaKeys = group.getVariables().getVarKeyList();
|
||||
for (String key : metaKeys) {
|
||||
String value = group.getVariables().getVarString(key);
|
||||
key = key.toLowerCase();
|
||||
if (key.isEmpty() || value.isEmpty()) continue;
|
||||
if (key.equals("build")) continue;
|
||||
|
||||
if (key.equals("prefix")) {
|
||||
groups.get(groupName).add(Prefix.builder(value, 50).withContext(DefaultContextKeys.WORLD_KEY, worldMappingFunc.apply(world)).build());
|
||||
} else if (key.equals("suffix")) {
|
||||
groups.get(groupName).add(Suffix.builder(value, 50).withContext(DefaultContextKeys.WORLD_KEY, worldMappingFunc.apply(world)).build());
|
||||
} else {
|
||||
groups.get(groupName).add(Meta.builder(key, value).withContext(DefaultContextKeys.WORLD_KEY, worldMappingFunc.apply(world)).build());
|
||||
}
|
||||
}
|
||||
|
||||
log.logAllProgress("Migrated {} groups so far in world " + world, groupWorldCount.incrementAndGet());
|
||||
});
|
||||
log.log("Migrated " + groupWorldCount.get() + " groups in world " + world);
|
||||
|
||||
AtomicInteger userWorldCount = new AtomicInteger(0);
|
||||
Iterators.tryIterate(wdh.getUserList(), user -> {
|
||||
UUID uuid = BukkitUuids.lookupUuid(log, user.getUUID());
|
||||
if (uuid == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String lastName = user.getLastName();
|
||||
if (lastName != null && Uuids.parse(lastName) != null) {
|
||||
lastName = null;
|
||||
}
|
||||
|
||||
UserIdentifier id = UserIdentifier.of(uuid, lastName);
|
||||
|
||||
users.putIfAbsent(id, new HashSet<>());
|
||||
|
||||
for (String node : user.getPermissionList()) {
|
||||
if (node.isEmpty()) continue;
|
||||
users.get(id).add(MigrationUtils.parseNode(node, true).withContext(DefaultContextKeys.WORLD_KEY, worldMappingFunc.apply(world)).build());
|
||||
}
|
||||
|
||||
// Collect sub groups
|
||||
String finalWorld = worldMappingFunc.apply(world);
|
||||
users.get(id).addAll(user.subGroupListStringCopy().stream()
|
||||
.filter(n -> !n.isEmpty())
|
||||
.map(MigrationUtils::standardizeName)
|
||||
.map(n -> Inheritance.builder(n).value(true).withContext(DefaultContextKeys.WORLD_KEY, finalWorld).build())
|
||||
.collect(Collectors.toSet())
|
||||
);
|
||||
|
||||
// Get primary group
|
||||
primaryGroups.put(uuid, MigrationUtils.standardizeName(user.getGroupName()));
|
||||
|
||||
String[] metaKeys = user.getVariables().getVarKeyList();
|
||||
for (String key : metaKeys) {
|
||||
String value = user.getVariables().getVarString(key);
|
||||
key = key.toLowerCase();
|
||||
if (key.isEmpty() || value.isEmpty()) continue;
|
||||
if (key.equals("build")) continue;
|
||||
|
||||
if (key.equals("prefix")) {
|
||||
users.get(id).add(Prefix.builder(value, 100).withContext(DefaultContextKeys.WORLD_KEY, worldMappingFunc.apply(world)).build());
|
||||
} else if (key.equals("suffix")) {
|
||||
users.get(id).add(Suffix.builder(value, 100).withContext(DefaultContextKeys.WORLD_KEY, worldMappingFunc.apply(world)).build());
|
||||
} else {
|
||||
users.get(id).add(Meta.builder(key, value).withContext(DefaultContextKeys.WORLD_KEY, worldMappingFunc.apply(world)).build());
|
||||
}
|
||||
}
|
||||
|
||||
log.logProgress("Migrated {} users so far in world " + world, userWorldCount.incrementAndGet(), ProgressLogger.DEFAULT_NOTIFY_FREQUENCY);
|
||||
});
|
||||
log.log("Migrated " + userWorldCount.get() + " users in world " + world);
|
||||
});
|
||||
|
||||
log.log("All data has now been processed, now starting the import process.");
|
||||
log.log("Found a total of " + users.size() + " users and " + groups.size() + " groups.");
|
||||
|
||||
log.log("Starting group migration.");
|
||||
AtomicInteger groupCount = new AtomicInteger(0);
|
||||
Iterators.tryIterate(groups.entrySet(), e -> {
|
||||
Group group = plugin.getStorage().createAndLoadGroup(e.getKey(), CreationCause.INTERNAL).join();
|
||||
|
||||
for (Node node : e.getValue()) {
|
||||
group.setNode(DataType.NORMAL, node, true);
|
||||
}
|
||||
|
||||
plugin.getStorage().saveGroup(group);
|
||||
log.logAllProgress("Migrated {} groups so far.", groupCount.incrementAndGet());
|
||||
});
|
||||
log.log("Migrated " + groupCount.get() + " groups");
|
||||
|
||||
log.log("Starting user migration.");
|
||||
AtomicInteger userCount = new AtomicInteger(0);
|
||||
Iterators.tryIterate(users.entrySet(), e -> {
|
||||
User user = plugin.getStorage().loadUser(e.getKey().getUniqueId(), e.getKey().getUsername().orElse(null)).join();
|
||||
|
||||
for (Node node : e.getValue()) {
|
||||
user.setNode(DataType.NORMAL, node, true);
|
||||
}
|
||||
|
||||
String primaryGroup = primaryGroups.get(e.getKey().getUniqueId());
|
||||
if (primaryGroup != null && !primaryGroup.isEmpty()) {
|
||||
user.setNode(DataType.NORMAL, Inheritance.builder(primaryGroup).build(), true);
|
||||
user.getPrimaryGroup().setStoredValue(primaryGroup);
|
||||
user.unsetNode(DataType.NORMAL, Inheritance.builder(me.lucko.luckperms.common.model.manager.group.GroupManager.DEFAULT_GROUP_NAME).build());
|
||||
}
|
||||
|
||||
plugin.getStorage().saveUser(user);
|
||||
plugin.getUserManager().getHouseKeeper().cleanup(user.getUniqueId());
|
||||
log.logProgress("Migrated {} users so far.", userCount.incrementAndGet(), ProgressLogger.DEFAULT_NOTIFY_FREQUENCY);
|
||||
});
|
||||
|
||||
log.log("Migrated " + userCount.get() + " users.");
|
||||
log.log("Success! Migration complete.");
|
||||
log.log("Don't forget to remove the GroupManager jar from your plugins folder & restart the server. " +
|
||||
"LuckPerms may not take over as the server permission handler until this is done.");
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
}
|
@@ -1,169 +0,0 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* 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.bukkit.migration;
|
||||
|
||||
import com.platymuus.bukkit.permissions.PermissionsPlugin;
|
||||
|
||||
import me.lucko.luckperms.common.command.CommandResult;
|
||||
import me.lucko.luckperms.common.command.abstraction.ChildCommand;
|
||||
import me.lucko.luckperms.common.command.access.CommandPermission;
|
||||
import me.lucko.luckperms.common.command.spec.CommandSpec;
|
||||
import me.lucko.luckperms.common.command.utils.ArgumentList;
|
||||
import me.lucko.luckperms.common.commands.migration.MigrationUtils;
|
||||
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.types.Inheritance;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.util.Iterators;
|
||||
import me.lucko.luckperms.common.util.Predicates;
|
||||
import me.lucko.luckperms.common.util.ProgressLogger;
|
||||
|
||||
import net.luckperms.api.context.DefaultContextKeys;
|
||||
import net.luckperms.api.event.cause.CreationCause;
|
||||
import net.luckperms.api.model.data.DataType;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class MigrationPermissionsBukkit extends ChildCommand<Object> {
|
||||
public MigrationPermissionsBukkit() {
|
||||
super(CommandSpec.MIGRATION_COMMAND, "permissionsbukkit", CommandPermission.MIGRATION, Predicates.alwaysFalse());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Object ignored, ArgumentList args, String label) {
|
||||
ProgressLogger log = new ProgressLogger(Message.MIGRATION_LOG, Message.MIGRATION_LOG_PROGRESS, "PermissionsBukkit");
|
||||
log.addListener(plugin.getConsoleSender());
|
||||
log.addListener(sender);
|
||||
|
||||
log.log("Starting.");
|
||||
|
||||
if (!Bukkit.getPluginManager().isPluginEnabled("PermissionsBukkit")) {
|
||||
log.logError("Plugin not loaded.");
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
|
||||
PermissionsPlugin permissionsBukkit = (PermissionsPlugin) Bukkit.getPluginManager().getPlugin("PermissionsBukkit");
|
||||
FileConfiguration config = permissionsBukkit.getConfig();
|
||||
|
||||
// Migrate all groups
|
||||
log.log("Starting group migration.");
|
||||
AtomicInteger groupCount = new AtomicInteger(0);
|
||||
|
||||
ConfigurationSection groupsSection = config.getConfigurationSection("groups");
|
||||
|
||||
Iterators.tryIterate(groupsSection.getKeys(false), key -> {
|
||||
final String groupName = MigrationUtils.standardizeName(key);
|
||||
Group lpGroup = plugin.getStorage().createAndLoadGroup(groupName, CreationCause.INTERNAL).join();
|
||||
|
||||
// migrate data
|
||||
if (groupsSection.isConfigurationSection(key)) {
|
||||
migrate(lpGroup, groupsSection.getConfigurationSection(key));
|
||||
}
|
||||
|
||||
plugin.getStorage().saveGroup(lpGroup).join();
|
||||
log.logAllProgress("Migrated {} groups so far.", groupCount.incrementAndGet());
|
||||
});
|
||||
log.log("Migrated " + groupCount.get() + " groups");
|
||||
|
||||
// Migrate all users
|
||||
log.log("Starting user migration.");
|
||||
AtomicInteger userCount = new AtomicInteger(0);
|
||||
|
||||
ConfigurationSection usersSection = config.getConfigurationSection("users");
|
||||
|
||||
Iterators.tryIterate(usersSection.getKeys(false), key -> {
|
||||
UUID uuid = BukkitUuids.lookupUuid(log, key);
|
||||
if (uuid == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
User lpUser = plugin.getStorage().loadUser(uuid, null).join();
|
||||
|
||||
// migrate data
|
||||
if (usersSection.isConfigurationSection(key)) {
|
||||
migrate(lpUser, usersSection.getConfigurationSection(key));
|
||||
}
|
||||
|
||||
plugin.getUserManager().getHouseKeeper().cleanup(lpUser.getUniqueId());
|
||||
plugin.getStorage().saveUser(lpUser);
|
||||
log.logProgress("Migrated {} users so far.", userCount.incrementAndGet(), ProgressLogger.DEFAULT_NOTIFY_FREQUENCY);
|
||||
});
|
||||
|
||||
log.log("Migrated " + userCount.get() + " users.");
|
||||
log.log("Success! Migration complete.");
|
||||
log.log("Don't forget to remove the PermissionsBukkit jar from your plugins folder & restart the server. " +
|
||||
"LuckPerms may not take over as the server permission handler until this is done.");
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
|
||||
private static void migrate(PermissionHolder holder, ConfigurationSection data) {
|
||||
// migrate permissions
|
||||
if (data.isConfigurationSection("permissions")) {
|
||||
ConfigurationSection permsSection = data.getConfigurationSection("permissions");
|
||||
for (String perm : permsSection.getKeys(false)) {
|
||||
boolean value = permsSection.getBoolean(perm);
|
||||
holder.setNode(DataType.NORMAL, MigrationUtils.parseNode(perm, value).build(), true);
|
||||
}
|
||||
}
|
||||
|
||||
if (data.isConfigurationSection("worlds")) {
|
||||
ConfigurationSection worldSection = data.getConfigurationSection("worlds");
|
||||
for (String world : worldSection.getKeys(false)) {
|
||||
if (worldSection.isConfigurationSection(world)) {
|
||||
ConfigurationSection permsSection = worldSection.getConfigurationSection(world);
|
||||
for (String perm : permsSection.getKeys(false)) {
|
||||
boolean value = permsSection.getBoolean(perm);
|
||||
holder.setNode(DataType.NORMAL, MigrationUtils.parseNode(perm, value).withContext(DefaultContextKeys.WORLD_KEY, world).build(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// migrate parents
|
||||
if (data.isList("groups")) {
|
||||
List<String> groups = data.getStringList("groups");
|
||||
for (String group : groups) {
|
||||
holder.setNode(DataType.NORMAL, Inheritance.builder(MigrationUtils.standardizeName(group)).build(), true);
|
||||
}
|
||||
}
|
||||
if (data.isList("inheritance")) {
|
||||
List<String> groups = data.getStringList("inheritance");
|
||||
for (String group : groups) {
|
||||
holder.setNode(DataType.NORMAL, Inheritance.builder(MigrationUtils.standardizeName(group)).build(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,418 +0,0 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* 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.bukkit.migration;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
import me.lucko.luckperms.common.command.CommandResult;
|
||||
import me.lucko.luckperms.common.command.abstraction.ChildCommand;
|
||||
import me.lucko.luckperms.common.command.access.CommandPermission;
|
||||
import me.lucko.luckperms.common.command.spec.CommandSpec;
|
||||
import me.lucko.luckperms.common.command.utils.ArgumentList;
|
||||
import me.lucko.luckperms.common.commands.migration.MigrationUtils;
|
||||
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.model.User;
|
||||
import me.lucko.luckperms.common.model.manager.group.GroupManager;
|
||||
import me.lucko.luckperms.common.node.types.Inheritance;
|
||||
import me.lucko.luckperms.common.node.types.Meta;
|
||||
import me.lucko.luckperms.common.node.types.Prefix;
|
||||
import me.lucko.luckperms.common.node.types.Suffix;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.util.Iterators;
|
||||
import me.lucko.luckperms.common.util.Predicates;
|
||||
import me.lucko.luckperms.common.util.ProgressLogger;
|
||||
|
||||
import net.luckperms.api.context.DefaultContextKeys;
|
||||
import net.luckperms.api.event.cause.CreationCause;
|
||||
import net.luckperms.api.model.data.DataType;
|
||||
import net.luckperms.api.node.Node;
|
||||
import net.luckperms.api.node.types.InheritanceNode;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import ru.tehkode.permissions.NativeInterface;
|
||||
import ru.tehkode.permissions.PermissionEntity;
|
||||
import ru.tehkode.permissions.PermissionGroup;
|
||||
import ru.tehkode.permissions.PermissionManager;
|
||||
import ru.tehkode.permissions.PermissionUser;
|
||||
import ru.tehkode.permissions.PermissionsData;
|
||||
import ru.tehkode.permissions.bukkit.PermissionsEx;
|
||||
import ru.tehkode.permissions.events.PermissionEvent;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MigrationPermissionsEx extends ChildCommand<Object> {
|
||||
private static final Method GET_DATA_METHOD;
|
||||
private static final Field TIMED_PERMISSIONS_FIELD;
|
||||
private static final Field TIMED_PERMISSIONS_TIME_FIELD;
|
||||
private static final Field NATIVE_INTERFACE_FIELD;
|
||||
static {
|
||||
try {
|
||||
GET_DATA_METHOD = PermissionEntity.class.getDeclaredMethod("getData");
|
||||
GET_DATA_METHOD.setAccessible(true);
|
||||
|
||||
TIMED_PERMISSIONS_FIELD = PermissionEntity.class.getDeclaredField("timedPermissions");
|
||||
TIMED_PERMISSIONS_FIELD.setAccessible(true);
|
||||
|
||||
TIMED_PERMISSIONS_TIME_FIELD = PermissionEntity.class.getDeclaredField("timedPermissionsTime");
|
||||
TIMED_PERMISSIONS_TIME_FIELD.setAccessible(true);
|
||||
|
||||
NATIVE_INTERFACE_FIELD = PermissionManager.class.getDeclaredField("nativeI");
|
||||
NATIVE_INTERFACE_FIELD.setAccessible(true);
|
||||
} catch (NoSuchMethodException | NoSuchFieldException e) {
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public MigrationPermissionsEx() {
|
||||
super(CommandSpec.MIGRATION_COMMAND, "permissionsex", CommandPermission.MIGRATION, Predicates.alwaysFalse());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Object ignored, ArgumentList args, String label) {
|
||||
ProgressLogger log = new ProgressLogger(Message.MIGRATION_LOG, Message.MIGRATION_LOG_PROGRESS, "PermissionsEx");
|
||||
log.addListener(plugin.getConsoleSender());
|
||||
log.addListener(sender);
|
||||
|
||||
log.log("Starting.");
|
||||
|
||||
if (!Bukkit.getPluginManager().isPluginEnabled("PermissionsEx")) {
|
||||
log.logError("Plugin not loaded.");
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
|
||||
PermissionsEx pex = (PermissionsEx) Bukkit.getPluginManager().getPlugin("PermissionsEx");
|
||||
PermissionManager manager = pex.getPermissionsManager();
|
||||
|
||||
// hack to work around accessing pex async
|
||||
try {
|
||||
disablePexEvents(manager);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
log.log("Calculating group weightings.");
|
||||
int i = 0;
|
||||
for (PermissionGroup group : manager.getGroupList()) {
|
||||
i = Math.max(i, group.getRank());
|
||||
}
|
||||
int maxWeight = i + 5;
|
||||
|
||||
// Migrate all groups.
|
||||
log.log("Starting group migration.");
|
||||
AtomicInteger groupCount = new AtomicInteger(0);
|
||||
Set<String> ladders = new HashSet<>();
|
||||
Iterators.tryIterate(manager.getGroupList(), group -> {
|
||||
int groupWeight = maxWeight - group.getRank();
|
||||
|
||||
final String groupName = MigrationUtils.standardizeName(group.getName());
|
||||
Group lpGroup = plugin.getStorage().createAndLoadGroup(groupName, CreationCause.INTERNAL).join();
|
||||
|
||||
MigrationUtils.setGroupWeight(lpGroup, groupWeight);
|
||||
|
||||
// migrate data
|
||||
migrateEntity(group, lpGroup, groupWeight);
|
||||
|
||||
// remember known ladders
|
||||
if (group.isRanked()) {
|
||||
ladders.add(group.getRankLadder().toLowerCase());
|
||||
}
|
||||
|
||||
plugin.getStorage().saveGroup(lpGroup).join();
|
||||
log.logAllProgress("Migrated {} groups so far.", groupCount.incrementAndGet());
|
||||
});
|
||||
log.log("Migrated " + groupCount.get() + " groups");
|
||||
|
||||
// Migrate all ladders/tracks.
|
||||
log.log("Starting tracks migration.");
|
||||
for (String rankLadder : ladders) {
|
||||
Track track = plugin.getStorage().createAndLoadTrack(rankLadder, CreationCause.INTERNAL).join();
|
||||
|
||||
// Get a list of all groups in a ladder
|
||||
List<String> ladder = manager.getRankLadder(rankLadder).entrySet().stream()
|
||||
.sorted(Comparator.<Map.Entry<Integer, PermissionGroup>>comparingInt(Map.Entry::getKey).reversed())
|
||||
.map(e -> MigrationUtils.standardizeName(e.getValue().getName()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
track.setGroups(ladder);
|
||||
plugin.getStorage().saveTrack(track);
|
||||
}
|
||||
log.log("Migrated " + ladders.size() + " tracks");
|
||||
|
||||
// Migrate all users
|
||||
log.log("Starting user migration.");
|
||||
AtomicInteger userCount = new AtomicInteger(0);
|
||||
|
||||
// Increment the max weight from the group migrations. All user meta should override.
|
||||
int userWeight = maxWeight + 5;
|
||||
|
||||
Collection<String> userIdentifiers = manager.getBackend().getUserIdentifiers();
|
||||
Iterators.tryIterate(userIdentifiers, id -> {
|
||||
PermissionUser user = new PermissionUser(id, manager.getBackend().getUserData(id), manager);
|
||||
if (isUserEmpty(user)) {
|
||||
return;
|
||||
}
|
||||
|
||||
UUID u = BukkitUuids.lookupUuid(log, id);
|
||||
if (u == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// load in a user instance
|
||||
User lpUser = plugin.getStorage().loadUser(u, user.getName()).join();
|
||||
|
||||
// migrate data
|
||||
migrateEntity(user, lpUser, userWeight);
|
||||
|
||||
plugin.getUserManager().getHouseKeeper().cleanup(lpUser.getUniqueId());
|
||||
plugin.getStorage().saveUser(lpUser);
|
||||
log.logProgress("Migrated {} users so far.", userCount.incrementAndGet(), ProgressLogger.DEFAULT_NOTIFY_FREQUENCY);
|
||||
});
|
||||
|
||||
// re-enable events
|
||||
try {
|
||||
enablePexEvents(manager);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
log.log("Migrated " + userCount.get() + " users.");
|
||||
log.log("Success! Migration complete.");
|
||||
log.log("Don't forget to remove the PermissionsEx jar from your plugins folder & restart the server. " +
|
||||
"LuckPerms may not take over as the server permission handler until this is done.");
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
|
||||
private static Map<String, List<String>> getPermanentPermissions(PermissionEntity entity) {
|
||||
try {
|
||||
PermissionsData data = (PermissionsData) GET_DATA_METHOD.invoke(entity);
|
||||
return data.getPermissionsMap();
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isUserEmpty(PermissionUser user) {
|
||||
for (List<String> permissions : user.getAllPermissions().values()) {
|
||||
if (!permissions.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (List<PermissionGroup> parents : user.getAllParents().values()) {
|
||||
if (!parents.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (Map<String, String> options : user.getAllOptions().values()) {
|
||||
if (!options.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void migrateEntity(PermissionEntity entity, PermissionHolder holder, int weight) {
|
||||
// migrate permanent permissions
|
||||
for (Map.Entry<String, List<String>> worldData : getPermanentPermissions(entity).entrySet()) {
|
||||
String world = standardizeWorld(worldData.getKey());
|
||||
for (String node : worldData.getValue()) {
|
||||
if (node.isEmpty()) continue;
|
||||
holder.setNode(DataType.NORMAL, MigrationUtils.parseNode(node, true).withContext(DefaultContextKeys.WORLD_KEY, world).build(), true);
|
||||
}
|
||||
}
|
||||
|
||||
// migrate temporary permissions
|
||||
Map<String, List<String>> timedPermissions;
|
||||
Map<String, Long> timedPermissionsTime;
|
||||
|
||||
try {
|
||||
//noinspection unchecked
|
||||
timedPermissions = (Map<String, List<String>>) TIMED_PERMISSIONS_FIELD.get(entity);
|
||||
//noinspection unchecked
|
||||
timedPermissionsTime = (Map<String, Long>) TIMED_PERMISSIONS_TIME_FIELD.get(entity);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
for (Map.Entry<String, List<String>> worldData : timedPermissions.entrySet()) {
|
||||
String world = standardizeWorld(worldData.getKey());
|
||||
for (String node : worldData.getValue()) {
|
||||
if (node.isEmpty()) continue;
|
||||
long expiry = timedPermissionsTime.getOrDefault(Strings.nullToEmpty(world) + ":" + node, 0L);
|
||||
Node n = MigrationUtils.parseNode(node, true).withContext(DefaultContextKeys.WORLD_KEY, world).expiry(expiry).build();
|
||||
if (!n.hasExpired()) {
|
||||
holder.setNode(DataType.NORMAL, n, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// migrate parents
|
||||
for (Map.Entry<String, List<PermissionGroup>> worldData : entity.getAllParents().entrySet()) {
|
||||
String world = standardizeWorld(worldData.getKey());
|
||||
|
||||
// keep track of primary group
|
||||
String primary = null;
|
||||
int primaryWeight = Integer.MAX_VALUE;
|
||||
|
||||
for (PermissionGroup parent : worldData.getValue()) {
|
||||
String parentName = parent.getName();
|
||||
long expiry = 0L;
|
||||
|
||||
// check for temporary parent
|
||||
if (entity instanceof PermissionUser) {
|
||||
String expiryOption = entity.getOption("group-" + parentName + "-until", world);
|
||||
if (expiryOption != null) {
|
||||
try {
|
||||
expiry = Long.parseLong(expiryOption);
|
||||
} catch (NumberFormatException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InheritanceNode n = Inheritance.builder(MigrationUtils.standardizeName(parentName)).withContext(DefaultContextKeys.WORLD_KEY, world).expiry(expiry).build();
|
||||
if (n.hasExpired()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
holder.setNode(DataType.NORMAL, n, true);
|
||||
|
||||
// migrate primary groups
|
||||
if (world.equals("global") && holder instanceof User && expiry == 0) {
|
||||
if (parent.getRank() < primaryWeight) {
|
||||
primary = parent.getName();
|
||||
primaryWeight = parent.getRank();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (primary != null && !primary.isEmpty() && !primary.equalsIgnoreCase(GroupManager.DEFAULT_GROUP_NAME)) {
|
||||
User user = ((User) holder);
|
||||
user.getPrimaryGroup().setStoredValue(primary);
|
||||
holder.unsetNode(DataType.NORMAL, Inheritance.builder(GroupManager.DEFAULT_GROUP_NAME).build());
|
||||
}
|
||||
}
|
||||
|
||||
// migrate prefix / suffix
|
||||
String prefix = entity.getOwnPrefix();
|
||||
String suffix = entity.getOwnSuffix();
|
||||
|
||||
if (prefix != null && !prefix.isEmpty()) {
|
||||
holder.setNode(DataType.NORMAL, Prefix.builder(prefix, weight).build(), true);
|
||||
}
|
||||
|
||||
if (suffix != null && !suffix.isEmpty()) {
|
||||
holder.setNode(DataType.NORMAL, Suffix.builder(suffix, weight).build(), true);
|
||||
}
|
||||
|
||||
// migrate options
|
||||
for (Map.Entry<String, Map<String, String>> worldData : entity.getAllOptions().entrySet()) {
|
||||
String world = standardizeWorld(worldData.getKey());
|
||||
for (Map.Entry<String, String> opt : worldData.getValue().entrySet()) {
|
||||
if (opt.getKey() == null || opt.getKey().isEmpty() || opt.getValue() == null || opt.getValue().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String key = opt.getKey().toLowerCase();
|
||||
boolean ignore = key.equals("prefix") ||
|
||||
key.equals("suffix") ||
|
||||
key.equals("weight") ||
|
||||
key.equals("rank") ||
|
||||
key.equals("rank-ladder") ||
|
||||
key.equals("name") ||
|
||||
key.equals("username") ||
|
||||
(key.startsWith("group-") && key.endsWith("-until"));
|
||||
|
||||
if (ignore) {
|
||||
continue;
|
||||
}
|
||||
|
||||
holder.setNode(DataType.NORMAL, Meta.builder(opt.getKey(), opt.getValue()).withContext(DefaultContextKeys.WORLD_KEY, world).build(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String standardizeWorld(String world) {
|
||||
if (world == null || world.isEmpty() || world.equals("*")) {
|
||||
world = "global";
|
||||
}
|
||||
return world.toLowerCase();
|
||||
}
|
||||
|
||||
/*
|
||||
* Hack to workaround issue with accessing PEX async.
|
||||
* See: https://github.com/lucko/LuckPerms/issues/2102
|
||||
*/
|
||||
|
||||
private static void disablePexEvents(PermissionManager manager) throws ReflectiveOperationException {
|
||||
NativeInterface nativeInterface = (NativeInterface) NATIVE_INTERFACE_FIELD.get(manager);
|
||||
NATIVE_INTERFACE_FIELD.set(manager, new DisabledEventsNativeInterface(nativeInterface));
|
||||
}
|
||||
|
||||
private static void enablePexEvents(PermissionManager manager) throws ReflectiveOperationException {
|
||||
NativeInterface nativeInterface = (NativeInterface) NATIVE_INTERFACE_FIELD.get(manager);
|
||||
while (nativeInterface instanceof DisabledEventsNativeInterface) {
|
||||
nativeInterface = ((DisabledEventsNativeInterface) nativeInterface).delegate;
|
||||
NATIVE_INTERFACE_FIELD.set(manager, nativeInterface);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class DisabledEventsNativeInterface implements NativeInterface {
|
||||
private final NativeInterface delegate;
|
||||
|
||||
private DisabledEventsNativeInterface(NativeInterface delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void callEvent(PermissionEvent permissionEvent) {
|
||||
// do nothing!
|
||||
}
|
||||
|
||||
@Override public String UUIDToName(UUID uuid) { return this.delegate.UUIDToName(uuid); }
|
||||
@Override public UUID nameToUUID(String s) { return this.delegate.nameToUUID(s); }
|
||||
@Override public boolean isOnline(UUID uuid) { return this.delegate.isOnline(uuid); }
|
||||
@Override public UUID getServerUUID() { return this.delegate.getServerUUID(); }
|
||||
}
|
||||
}
|
@@ -1,148 +0,0 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* 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.bukkit.migration;
|
||||
|
||||
import me.lucko.luckperms.common.command.CommandResult;
|
||||
import me.lucko.luckperms.common.command.abstraction.ChildCommand;
|
||||
import me.lucko.luckperms.common.command.access.CommandPermission;
|
||||
import me.lucko.luckperms.common.command.spec.CommandSpec;
|
||||
import me.lucko.luckperms.common.command.utils.ArgumentList;
|
||||
import me.lucko.luckperms.common.commands.migration.MigrationUtils;
|
||||
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.types.Inheritance;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.util.Predicates;
|
||||
import me.lucko.luckperms.common.util.ProgressLogger;
|
||||
|
||||
import net.luckperms.api.context.DefaultContextKeys;
|
||||
import net.luckperms.api.event.cause.CreationCause;
|
||||
import net.luckperms.api.model.data.DataType;
|
||||
|
||||
import nl.svenar.PowerRanks.Cache.CachedPlayers;
|
||||
import nl.svenar.PowerRanks.Cache.PowerConfigurationSection;
|
||||
import nl.svenar.PowerRanks.Data.Users;
|
||||
import nl.svenar.PowerRanks.PowerRanks;
|
||||
import nl.svenar.PowerRanks.api.PowerRanksAPI;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class MigrationPowerRanks extends ChildCommand<Object> {
|
||||
public MigrationPowerRanks() {
|
||||
super(CommandSpec.MIGRATION_COMMAND, "powerranks", CommandPermission.MIGRATION, Predicates.alwaysFalse());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Object ignored, ArgumentList args, String label) {
|
||||
ProgressLogger log = new ProgressLogger(Message.MIGRATION_LOG, Message.MIGRATION_LOG_PROGRESS, "PowerRanks");
|
||||
log.addListener(plugin.getConsoleSender());
|
||||
log.addListener(sender);
|
||||
|
||||
log.log("Starting.");
|
||||
|
||||
if (!Bukkit.getPluginManager().isPluginEnabled("PowerRanks")) {
|
||||
log.logError("Plugin not loaded.");
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
|
||||
PowerRanks pr = (PowerRanks) Bukkit.getServer().getPluginManager().getPlugin("PowerRanks");
|
||||
PowerRanksAPI prApi = (pr).loadAPI();
|
||||
Users prUsers = new Users(pr);
|
||||
|
||||
// Migrate all groups
|
||||
log.log("Starting groups migration.");
|
||||
Set<String> ranks = prApi.getRanks();
|
||||
AtomicInteger groupCount = new AtomicInteger(0);
|
||||
for (String rank : ranks) {
|
||||
Group group = plugin.getStorage().createAndLoadGroup(rank, CreationCause.INTERNAL).join();
|
||||
|
||||
for (String node : prApi.getPermissions(rank)) {
|
||||
if (node.isEmpty()) continue;
|
||||
group.setNode(DataType.NORMAL, MigrationUtils.parseNode(node, true).build(), true);
|
||||
}
|
||||
|
||||
for (String parent : prApi.getInheritances(rank)) {
|
||||
if (parent.isEmpty()) continue;
|
||||
group.setNode(DataType.NORMAL, Inheritance.builder(MigrationUtils.standardizeName(parent)).build(), true);
|
||||
}
|
||||
|
||||
plugin.getStorage().saveGroup(group);
|
||||
log.logAllProgress("Migrated {} groups so far.", groupCount.incrementAndGet());
|
||||
}
|
||||
log.log("Migrated " + groupCount.get() + " groups");
|
||||
|
||||
// Migrate all users
|
||||
log.log("Starting user migration.");
|
||||
Set<String> playerUuids = prUsers.getCachedPlayers();
|
||||
AtomicInteger userCount = new AtomicInteger(0);
|
||||
for (String uuidString : playerUuids) {
|
||||
UUID uuid = BukkitUuids.lookupUuid(log, uuidString);
|
||||
if (uuid == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
User user = plugin.getStorage().loadUser(uuid, null).join();
|
||||
|
||||
user.setNode(DataType.NORMAL, Inheritance.builder(CachedPlayers.getString("players." + uuidString + ".rank")).build(), true);
|
||||
|
||||
final PowerConfigurationSection subGroups = CachedPlayers.getConfigurationSection("players." + uuidString + ".subranks");
|
||||
if (subGroups != null) {
|
||||
for (String subGroup : subGroups.getKeys(false)) {
|
||||
Inheritance.Builder builder = Inheritance.builder(subGroup);
|
||||
for (String worldName : CachedPlayers.getStringList("players." + uuidString + ".subranks." + subGroup + ".worlds")) {
|
||||
if (!worldName.equalsIgnoreCase("all")) {
|
||||
builder.withContext(DefaultContextKeys.WORLD_KEY, worldName);
|
||||
}
|
||||
}
|
||||
user.setNode(DataType.NORMAL, builder.build(), true);
|
||||
}
|
||||
}
|
||||
|
||||
for (String node : CachedPlayers.getStringList("players." + uuidString + ".permissions")) {
|
||||
if (node.isEmpty()) continue;
|
||||
user.setNode(DataType.NORMAL, MigrationUtils.parseNode(node, true).build(), true);
|
||||
}
|
||||
|
||||
user.getPrimaryGroup().setStoredValue(CachedPlayers.getString("players." + uuidString + ".rank"));
|
||||
|
||||
plugin.getUserManager().getHouseKeeper().cleanup(user.getUniqueId());
|
||||
plugin.getStorage().saveUser(user);
|
||||
log.logAllProgress("Migrated {} users so far.", userCount.incrementAndGet());
|
||||
}
|
||||
|
||||
log.log("Migrated " + userCount.get() + " users.");
|
||||
log.log("Success! Migration complete.");
|
||||
log.log("Don't forget to remove the PowerRanks jar from your plugins folder & restart the server. " +
|
||||
"LuckPerms may not take over as the server permission handler until this is done.");
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
}
|
@@ -1,401 +0,0 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* 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.bukkit.migration;
|
||||
|
||||
import com.github.gustav9797.PowerfulPermsAPI.CachedGroup;
|
||||
import com.github.gustav9797.PowerfulPermsAPI.Group;
|
||||
import com.github.gustav9797.PowerfulPermsAPI.Permission;
|
||||
import com.github.gustav9797.PowerfulPermsAPI.PermissionManager;
|
||||
import com.github.gustav9797.PowerfulPermsAPI.PowerfulPermsPlugin;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
|
||||
import me.lucko.luckperms.common.command.CommandResult;
|
||||
import me.lucko.luckperms.common.command.abstraction.ChildCommand;
|
||||
import me.lucko.luckperms.common.command.access.CommandPermission;
|
||||
import me.lucko.luckperms.common.command.spec.CommandSpec;
|
||||
import me.lucko.luckperms.common.command.utils.ArgumentList;
|
||||
import me.lucko.luckperms.common.commands.migration.MigrationUtils;
|
||||
import me.lucko.luckperms.common.config.ConfigKeys;
|
||||
import me.lucko.luckperms.common.locale.Message;
|
||||
import me.lucko.luckperms.common.model.PermissionHolder;
|
||||
import me.lucko.luckperms.common.model.User;
|
||||
import me.lucko.luckperms.common.model.manager.group.GroupManager;
|
||||
import me.lucko.luckperms.common.node.factory.NodeBuilders;
|
||||
import me.lucko.luckperms.common.node.types.Inheritance;
|
||||
import me.lucko.luckperms.common.node.types.Prefix;
|
||||
import me.lucko.luckperms.common.node.types.Suffix;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.storage.StorageType;
|
||||
import me.lucko.luckperms.common.util.Iterators;
|
||||
import me.lucko.luckperms.common.util.Predicates;
|
||||
import me.lucko.luckperms.common.util.ProgressLogger;
|
||||
|
||||
import net.luckperms.api.context.DefaultContextKeys;
|
||||
import net.luckperms.api.event.cause.CreationCause;
|
||||
import net.luckperms.api.model.data.DataType;
|
||||
import net.luckperms.api.node.NodeBuilder;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
// Only supports the latest versions of the PP API. (it seems to change randomly almost every release)
|
||||
public class MigrationPowerfulPerms extends ChildCommand<Object> {
|
||||
public MigrationPowerfulPerms() {
|
||||
super(CommandSpec.MIGRATION_POWERFULPERMS, "powerfulperms", CommandPermission.MIGRATION, Predicates.not(5));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Object ignored, ArgumentList args, String label) {
|
||||
ProgressLogger log = new ProgressLogger(Message.MIGRATION_LOG, Message.MIGRATION_LOG_PROGRESS, "PowerfulPerms");
|
||||
log.addListener(plugin.getConsoleSender());
|
||||
log.addListener(sender);
|
||||
|
||||
log.log("Starting.");
|
||||
|
||||
if (!Bukkit.getPluginManager().isPluginEnabled("PowerfulPerms")) {
|
||||
log.logError("Plugin not loaded.");
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
|
||||
StorageType type = plugin.getConfiguration().get(ConfigKeys.STORAGE_METHOD);
|
||||
if (type != StorageType.MYSQL) {
|
||||
// We need to load the Hikari/MySQL stuff.
|
||||
plugin.getDependencyManager().loadStorageDependencies(ImmutableSet.of(StorageType.MYSQL));
|
||||
}
|
||||
|
||||
String address = args.get(0);
|
||||
String database = args.get(1);
|
||||
String username = args.get(2);
|
||||
String password = args.get(3);
|
||||
String dbTable = args.get(4);
|
||||
|
||||
// Find a list of UUIDs
|
||||
log.log("Getting a list of UUIDs to migrate.");
|
||||
Set<UUID> uuids = new HashSet<>();
|
||||
|
||||
try (HikariSupplier hikari = new HikariSupplier(address, database, username, password)) {
|
||||
hikari.setup("powerfulperms-migrator-pool");
|
||||
|
||||
try (Connection c = hikari.getConnection()) {
|
||||
DatabaseMetaData meta = c.getMetaData();
|
||||
try (ResultSet rs = meta.getTables(null, null, dbTable, null)) {
|
||||
if (!rs.next()) {
|
||||
log.log("Error - Couldn't find table.");
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try (Connection c = hikari.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement("SELECT COLUMN_NAME, COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=?")) {
|
||||
ps.setString(1, dbTable);
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
log.log("Found table: " + dbTable);
|
||||
while (rs.next()) {
|
||||
log.log(rs.getString("COLUMN_NAME") + " - " + rs.getString("COLUMN_TYPE"));
|
||||
}
|
||||
}
|
||||
}
|
||||
try (PreparedStatement ps = c.prepareStatement("SELECT `uuid` FROM " + dbTable)) {
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
uuids.add(UUID.fromString(rs.getString("uuid")));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (uuids.isEmpty()) {
|
||||
log.logError("Unable to find any UUIDs to migrate.");
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
|
||||
log.log("Found " + uuids.size() + " uuids. Starting migration.");
|
||||
|
||||
PowerfulPermsPlugin ppPlugin = (PowerfulPermsPlugin) Bukkit.getPluginManager().getPlugin("PowerfulPerms");
|
||||
PermissionManager pm = ppPlugin.getPermissionManager();
|
||||
|
||||
Collection<Group> groups = pm.getGroups().values();
|
||||
|
||||
AtomicInteger maxWeight = new AtomicInteger(0);
|
||||
|
||||
// Groups first.
|
||||
log.log("Starting group migration.");
|
||||
AtomicInteger groupCount = new AtomicInteger(0);
|
||||
Iterators.tryIterate(groups, g -> {
|
||||
maxWeight.set(Math.max(maxWeight.get(), g.getRank()));
|
||||
|
||||
String groupName = MigrationUtils.standardizeName(g.getName());
|
||||
me.lucko.luckperms.common.model.Group group = plugin.getStorage().createAndLoadGroup(groupName, CreationCause.INTERNAL).join();
|
||||
|
||||
MigrationUtils.setGroupWeight(group, g.getRank());
|
||||
|
||||
for (Permission p : g.getOwnPermissions()) {
|
||||
applyPerm(group, p);
|
||||
}
|
||||
|
||||
for (Group parent : g.getParents()) {
|
||||
group.setNode(DataType.NORMAL, Inheritance.builder(parent.getName().toLowerCase()).build(), true);
|
||||
}
|
||||
|
||||
// server --> prefix afaik
|
||||
for (Map.Entry<String, String> prefix : g.getPrefixes().entrySet()) {
|
||||
if (prefix.getValue().isEmpty()) continue;
|
||||
|
||||
String server = prefix.getKey().toLowerCase();
|
||||
if (prefix.getKey().equals("*") || prefix.getKey().equals("all")) {
|
||||
server = null;
|
||||
}
|
||||
|
||||
if (server != null) {
|
||||
group.setNode(DataType.NORMAL, Prefix.builder(prefix.getValue(), g.getRank()).withContext(DefaultContextKeys.SERVER_KEY, server).build(), true);
|
||||
} else {
|
||||
group.setNode(DataType.NORMAL, Prefix.builder(prefix.getValue(), g.getRank()).build(), true);
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<String, String> suffix : g.getSuffixes().entrySet()) {
|
||||
if (suffix.getValue().isEmpty()) continue;
|
||||
|
||||
String server = suffix.getKey().toLowerCase();
|
||||
if (suffix.getKey().equals("*") || suffix.getKey().equals("all")) {
|
||||
server = null;
|
||||
}
|
||||
|
||||
if (server != null) {
|
||||
group.setNode(DataType.NORMAL, Suffix.builder(suffix.getValue(), g.getRank()).withContext(DefaultContextKeys.SERVER_KEY, server).build(), true);
|
||||
} else {
|
||||
group.setNode(DataType.NORMAL, Suffix.builder(suffix.getValue(), g.getRank()).build(), true);
|
||||
}
|
||||
}
|
||||
|
||||
plugin.getStorage().saveGroup(group);
|
||||
log.logAllProgress("Migrated {} groups so far.", groupCount.incrementAndGet());
|
||||
});
|
||||
log.log("Migrated " + groupCount.get() + " groups");
|
||||
|
||||
// Migrate all users
|
||||
log.log("Starting user migration.");
|
||||
AtomicInteger userCount = new AtomicInteger(0);
|
||||
|
||||
// Increment the max weight from the group migrations. All user meta should override.
|
||||
maxWeight.addAndGet(5);
|
||||
|
||||
// Migrate all users and their groups
|
||||
Iterators.tryIterate(uuids, uuid -> {
|
||||
|
||||
// Create a LuckPerms user for the UUID
|
||||
User user = plugin.getStorage().loadUser(uuid, null).join();
|
||||
|
||||
List<Permission> permissions = joinFuture(pm.getPlayerOwnPermissions(uuid));
|
||||
|
||||
for (Permission p : permissions) {
|
||||
applyPerm(user, p);
|
||||
}
|
||||
|
||||
// server --> list of groups
|
||||
Map<String, List<CachedGroup>> parents = joinFuture(pm.getPlayerOwnGroups(uuid));
|
||||
for (Map.Entry<String, List<CachedGroup>> parent : parents.entrySet()) {
|
||||
String server = parent.getKey().toLowerCase();
|
||||
if (parent.getKey().equals("*") || parent.getKey().equals("all")) {
|
||||
server = null;
|
||||
}
|
||||
|
||||
for (CachedGroup group : parent.getValue()) {
|
||||
applyGroup(pm, user, group, server);
|
||||
}
|
||||
}
|
||||
|
||||
String prefix = joinFuture(pm.getPlayerOwnPrefix(uuid));
|
||||
String suffix = joinFuture(pm.getPlayerOwnSuffix(uuid));
|
||||
|
||||
if (prefix != null && !prefix.isEmpty()) {
|
||||
user.setNode(DataType.NORMAL, Prefix.builder(prefix, maxWeight.get()).build(), true);
|
||||
}
|
||||
|
||||
if (suffix != null && !suffix.isEmpty()) {
|
||||
user.setNode(DataType.NORMAL, Suffix.builder(suffix, maxWeight.get()).build(), true);
|
||||
}
|
||||
|
||||
Group primaryGroup = joinFuture(pm.getPlayerPrimaryGroup(uuid));
|
||||
if (primaryGroup != null && primaryGroup.getName() != null) {
|
||||
String primary = primaryGroup.getName().toLowerCase();
|
||||
if (!primary.equals(GroupManager.DEFAULT_GROUP_NAME)) {
|
||||
user.setNode(DataType.NORMAL, Inheritance.builder(primary).build(), true);
|
||||
user.getPrimaryGroup().setStoredValue(primary);
|
||||
}
|
||||
}
|
||||
|
||||
plugin.getUserManager().getHouseKeeper().cleanup(user.getUniqueId());
|
||||
plugin.getStorage().saveUser(user);
|
||||
log.logProgress("Migrated {} users so far.", userCount.incrementAndGet(), ProgressLogger.DEFAULT_NOTIFY_FREQUENCY);
|
||||
});
|
||||
|
||||
log.log("Migrated " + userCount.get() + " users.");
|
||||
log.log("Success! Migration complete.");
|
||||
log.log("Don't forget to remove the PowerfulPerms jar from your plugins folder & restart the server. " +
|
||||
"LuckPerms may not take over as the server permission handler until this is done.");
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
|
||||
private void applyPerm(PermissionHolder holder, Permission p) {
|
||||
String node = p.getPermissionString();
|
||||
boolean value = true;
|
||||
if (node.startsWith("!") || node.startsWith("-")) {
|
||||
node = node.substring(1);
|
||||
value = false;
|
||||
}
|
||||
|
||||
if (node.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String server = p.getServer();
|
||||
if (server != null && (server.equalsIgnoreCase("all") || server.equalsIgnoreCase("*") || server.isEmpty())) {
|
||||
server = null;
|
||||
}
|
||||
|
||||
String world = p.getWorld();
|
||||
if (world != null && (world.equalsIgnoreCase("all") || world.equalsIgnoreCase("*") || world.isEmpty())) {
|
||||
world = null;
|
||||
}
|
||||
|
||||
long expireAt = 0L;
|
||||
if (p.willExpire()) {
|
||||
expireAt = p.getExpirationDate().getTime() / 1000L;
|
||||
}
|
||||
|
||||
if (world != null && server == null) {
|
||||
server = "global";
|
||||
}
|
||||
|
||||
NodeBuilder<?, ?> nb = NodeBuilders.determineMostApplicable(node).value(value);
|
||||
if (expireAt != 0) nb.expiry(expireAt);
|
||||
if (server != null) nb.withContext(DefaultContextKeys.SERVER_KEY, server);
|
||||
if (world != null) nb.withContext(DefaultContextKeys.WORLD_KEY, world);
|
||||
|
||||
holder.setNode(DataType.NORMAL, nb.build(), true);
|
||||
}
|
||||
|
||||
private void applyGroup(PermissionManager pm, PermissionHolder holder, CachedGroup g, String server) {
|
||||
Group group = pm.getGroup(g.getGroupId());
|
||||
|
||||
long expireAt = 0L;
|
||||
if (g.willExpire()) {
|
||||
expireAt = g.getExpirationDate().getTime() / 1000L;
|
||||
}
|
||||
|
||||
NodeBuilder<?, ?> nb = Inheritance.builder(MigrationUtils.standardizeName(group.getName()));
|
||||
|
||||
if (expireAt != 0) {
|
||||
nb.expiry(expireAt);
|
||||
}
|
||||
|
||||
if (server != null) {
|
||||
nb.withContext(DefaultContextKeys.SERVER_KEY, server);
|
||||
}
|
||||
|
||||
holder.setNode(DataType.NORMAL, nb.build(), true);
|
||||
}
|
||||
|
||||
private static <T> T joinFuture(Future<T> future) {
|
||||
try {
|
||||
return future.get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple hikari wrapper
|
||||
*/
|
||||
public static final class HikariSupplier implements AutoCloseable {
|
||||
|
||||
private final String host;
|
||||
private final String port;
|
||||
private final String database;
|
||||
private final String username;
|
||||
private final String password;
|
||||
|
||||
private HikariDataSource hikari;
|
||||
|
||||
public HikariSupplier(String address, String database, String username, String password) {
|
||||
this.database = database;
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
|
||||
String[] split = address.split(":");
|
||||
if (split.length != 2) {
|
||||
throw new IllegalArgumentException("Address argument should be in the format hostname:port");
|
||||
}
|
||||
|
||||
this.host = split[0];
|
||||
this.port = split[1];
|
||||
}
|
||||
|
||||
public void setup(String poolName) {
|
||||
this.hikari = new HikariDataSource();
|
||||
this.hikari.setPoolName(poolName);
|
||||
this.hikari.setMaximumPoolSize(2);
|
||||
this.hikari.setDataSourceClassName("com.mysql.jdbc.jdbc2.optional.MysqlDataSource");
|
||||
this.hikari.addDataSourceProperty("serverName", this.host);
|
||||
this.hikari.addDataSourceProperty("port", this.port);
|
||||
this.hikari.addDataSourceProperty("databaseName", this.database);
|
||||
this.hikari.addDataSourceProperty("user", this.username);
|
||||
this.hikari.addDataSourceProperty("password", this.password);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
this.hikari.close();
|
||||
}
|
||||
|
||||
public Connection getConnection() throws SQLException {
|
||||
return this.hikari.getConnection();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -1,238 +0,0 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* 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.bukkit.migration;
|
||||
|
||||
import me.lucko.luckperms.common.command.CommandResult;
|
||||
import me.lucko.luckperms.common.command.abstraction.ChildCommand;
|
||||
import me.lucko.luckperms.common.command.access.CommandPermission;
|
||||
import me.lucko.luckperms.common.command.spec.CommandSpec;
|
||||
import me.lucko.luckperms.common.command.utils.ArgumentList;
|
||||
import me.lucko.luckperms.common.commands.migration.MigrationUtils;
|
||||
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.model.User;
|
||||
import me.lucko.luckperms.common.node.factory.NodeBuilders;
|
||||
import me.lucko.luckperms.common.node.types.Inheritance;
|
||||
import me.lucko.luckperms.common.node.types.Meta;
|
||||
import me.lucko.luckperms.common.node.types.Prefix;
|
||||
import me.lucko.luckperms.common.node.types.Suffix;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.util.Iterators;
|
||||
import me.lucko.luckperms.common.util.Predicates;
|
||||
import me.lucko.luckperms.common.util.ProgressLogger;
|
||||
|
||||
import net.luckperms.api.context.DefaultContextKeys;
|
||||
import net.luckperms.api.event.cause.CreationCause;
|
||||
import net.luckperms.api.model.data.DataType;
|
||||
import net.luckperms.api.node.Node;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.tyrannyofheaven.bukkit.zPermissions.ZPermissionsService;
|
||||
import org.tyrannyofheaven.bukkit.zPermissions.dao.PermissionService;
|
||||
import org.tyrannyofheaven.bukkit.zPermissions.model.EntityMetadata;
|
||||
import org.tyrannyofheaven.bukkit.zPermissions.model.Entry;
|
||||
import org.tyrannyofheaven.bukkit.zPermissions.model.Membership;
|
||||
import org.tyrannyofheaven.bukkit.zPermissions.model.PermissionEntity;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class MigrationZPermissions extends ChildCommand<Object> {
|
||||
public MigrationZPermissions() {
|
||||
super(CommandSpec.MIGRATION_COMMAND, "zpermissions", CommandPermission.MIGRATION, Predicates.alwaysFalse());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Object ignored, ArgumentList args, String label) {
|
||||
ProgressLogger log = new ProgressLogger(Message.MIGRATION_LOG, Message.MIGRATION_LOG_PROGRESS, "zPermissions");
|
||||
log.addListener(plugin.getConsoleSender());
|
||||
log.addListener(sender);
|
||||
|
||||
log.log("Starting.");
|
||||
|
||||
if (!Bukkit.getPluginManager().isPluginEnabled("zPermissions")) {
|
||||
log.logError("Plugin not loaded.");
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
|
||||
if (!Bukkit.getServicesManager().isProvidedFor(ZPermissionsService.class)) {
|
||||
log.logError("Plugin not loaded.");
|
||||
return CommandResult.STATE_ERROR;
|
||||
}
|
||||
|
||||
ZPermissionsService service = Bukkit.getServicesManager().getRegistration(ZPermissionsService.class).getProvider();
|
||||
|
||||
PermissionService internalService;
|
||||
try {
|
||||
Field psField = service.getClass().getDeclaredField("permissionService");
|
||||
psField.setAccessible(true);
|
||||
internalService = (PermissionService) psField.get(service);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
|
||||
// Migrate all groups
|
||||
log.log("Starting group migration.");
|
||||
|
||||
Map<UUID, Set<Node>> userParents = new HashMap<>();
|
||||
|
||||
AtomicInteger groupCount = new AtomicInteger(0);
|
||||
AtomicInteger maxWeight = new AtomicInteger(0);
|
||||
Iterators.tryIterate(internalService.getEntities(true), entity -> {
|
||||
String groupName = MigrationUtils.standardizeName(entity.getDisplayName());
|
||||
Group group = plugin.getStorage().createAndLoadGroup(groupName, CreationCause.INTERNAL).join();
|
||||
|
||||
int weight = entity.getPriority();
|
||||
maxWeight.set(Math.max(maxWeight.get(), weight));
|
||||
migrateEntity(group, entity, weight);
|
||||
MigrationUtils.setGroupWeight(group, weight);
|
||||
|
||||
// store user data for later
|
||||
Set<Membership> members = entity.getMemberships();
|
||||
for (Membership membership : members) {
|
||||
UUID uuid = BukkitUuids.lookupUuid(log, membership.getMember());
|
||||
if (uuid == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Set<Node> nodes = userParents.computeIfAbsent(uuid, u -> new HashSet<>());
|
||||
if (membership.getExpiration() == null) {
|
||||
nodes.add(Inheritance.builder(groupName).build());
|
||||
} else {
|
||||
long expiry = membership.getExpiration().toInstant().getEpochSecond();
|
||||
nodes.add(Inheritance.builder(groupName).expiry(expiry).build());
|
||||
}
|
||||
}
|
||||
|
||||
plugin.getStorage().saveGroup(group);
|
||||
log.logAllProgress("Migrated {} groups so far.", groupCount.incrementAndGet());
|
||||
});
|
||||
log.log("Migrated " + groupCount.get() + " groups");
|
||||
|
||||
// Migrate all tracks
|
||||
log.log("Starting track migration.");
|
||||
AtomicInteger trackCount = new AtomicInteger(0);
|
||||
Iterators.tryIterate(service.getAllTracks(), t -> {
|
||||
String trackName = MigrationUtils.standardizeName(t);
|
||||
Track track = plugin.getStorage().createAndLoadTrack(trackName, CreationCause.INTERNAL).join();
|
||||
track.setGroups(service.getTrackGroups(t));
|
||||
plugin.getStorage().saveTrack(track);
|
||||
|
||||
log.logAllProgress("Migrated {} tracks so far.", trackCount.incrementAndGet());
|
||||
});
|
||||
log.log("Migrated " + trackCount.get() + " tracks");
|
||||
|
||||
// Migrate all users.
|
||||
log.log("Starting user migration.");
|
||||
maxWeight.addAndGet(10);
|
||||
AtomicInteger userCount = new AtomicInteger(0);
|
||||
|
||||
Set<UUID> usersToMigrate = new HashSet<>(userParents.keySet());
|
||||
usersToMigrate.addAll(service.getAllPlayersUUID());
|
||||
|
||||
Iterators.tryIterate(usersToMigrate, u -> {
|
||||
PermissionEntity entity = internalService.getEntity(null, u, false);
|
||||
|
||||
String username = null;
|
||||
if (entity != null) {
|
||||
username = entity.getDisplayName();
|
||||
}
|
||||
|
||||
User user = plugin.getStorage().loadUser(u, username).join();
|
||||
|
||||
// migrate permissions & meta
|
||||
if (entity != null) {
|
||||
migrateEntity(user, entity, maxWeight.get());
|
||||
}
|
||||
|
||||
// migrate groups
|
||||
Set<Node> parents = userParents.get(u);
|
||||
if (parents != null) {
|
||||
parents.forEach(node -> user.setNode(DataType.NORMAL, node, true));
|
||||
}
|
||||
|
||||
user.getPrimaryGroup().setStoredValue(MigrationUtils.standardizeName(service.getPlayerPrimaryGroup(u)));
|
||||
|
||||
plugin.getUserManager().getHouseKeeper().cleanup(user.getUniqueId());
|
||||
plugin.getStorage().saveUser(user);
|
||||
log.logProgress("Migrated {} users so far.", userCount.incrementAndGet(), ProgressLogger.DEFAULT_NOTIFY_FREQUENCY);
|
||||
});
|
||||
|
||||
log.log("Migrated " + userCount.get() + " users.");
|
||||
log.log("Success! Migration complete.");
|
||||
log.log("Don't forget to remove the zPermissions jar from your plugins folder & restart the server. " +
|
||||
"LuckPerms may not take over as the server permission handler until this is done.");
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
|
||||
private void migrateEntity(PermissionHolder holder, PermissionEntity entity, int weight) {
|
||||
for (Entry e : entity.getPermissions()) {
|
||||
if (e.getPermission().isEmpty()) continue;
|
||||
|
||||
if (e.getWorld() != null && !e.getWorld().getName().isEmpty()) {
|
||||
holder.setNode(DataType.NORMAL, NodeBuilders.determineMostApplicable(e.getPermission()).value(e.isValue()).withContext(DefaultContextKeys.WORLD_KEY, e.getWorld().getName()).build(), true);
|
||||
} else {
|
||||
holder.setNode(DataType.NORMAL, NodeBuilders.determineMostApplicable(e.getPermission()).value(e.isValue()).build(), true);
|
||||
}
|
||||
}
|
||||
|
||||
// only migrate inheritances for groups
|
||||
if (entity.isGroup()) {
|
||||
for (PermissionEntity inheritance : entity.getParents()) {
|
||||
if (!inheritance.getDisplayName().equals(holder.getObjectName())) {
|
||||
holder.setNode(DataType.NORMAL, Inheritance.builder(MigrationUtils.standardizeName(inheritance.getDisplayName())).build(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (EntityMetadata metadata : entity.getMetadata()) {
|
||||
String key = metadata.getName().toLowerCase();
|
||||
Object value = metadata.getValue();
|
||||
|
||||
if (key.isEmpty() || value == null) continue;
|
||||
|
||||
String valueString = value.toString();
|
||||
if (valueString.isEmpty()) continue;
|
||||
|
||||
if (key.equals("prefix")) {
|
||||
holder.setNode(DataType.NORMAL, Prefix.builder(valueString, weight).build(), true);
|
||||
} else if (key.equals("suffix")) {
|
||||
holder.setNode(DataType.NORMAL, Suffix.builder(valueString, weight).build(), true);
|
||||
} else {
|
||||
holder.setNode(DataType.NORMAL, Meta.builder(key, valueString).build(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -56,9 +56,6 @@ luckperms {
|
||||
}
|
||||
}
|
||||
}
|
||||
migration {
|
||||
plugin brigadier:string single_word;
|
||||
}
|
||||
translations {
|
||||
install;
|
||||
}
|
||||
|
Reference in New Issue
Block a user