diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/LPSpongePlugin.java b/sponge/src/main/java/me/lucko/luckperms/sponge/LPSpongePlugin.java index 08edd3b05..9bcd6981e 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/LPSpongePlugin.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/LPSpongePlugin.java @@ -87,7 +87,9 @@ import java.util.stream.Collectors; authors = {"Luck"}, description = "A permissions plugin", dependencies = { - @Dependency(id = "permissionsex", optional = true) // Needed for migration. + // Needed for migration. + @Dependency(id = "permissionsex", optional = true), + @Dependency(id = "permissionmanager", optional = true) } ) public class LPSpongePlugin implements LuckPermsPlugin { diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/migration/MigrationPermissionManager.java b/sponge/src/main/java/me/lucko/luckperms/sponge/migration/MigrationPermissionManager.java new file mode 100644 index 000000000..729fdc5e3 --- /dev/null +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/migration/MigrationPermissionManager.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2016 Lucko (Luck) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.lucko.luckperms.sponge.migration; + +import me.lucko.luckperms.api.Logger; +import me.lucko.luckperms.common.LuckPermsPlugin; +import me.lucko.luckperms.common.commands.CommandException; +import me.lucko.luckperms.common.commands.CommandResult; +import me.lucko.luckperms.common.commands.SubCommand; +import me.lucko.luckperms.common.commands.sender.Sender; +import me.lucko.luckperms.common.commands.utils.Util; +import me.lucko.luckperms.common.constants.Permission; +import me.lucko.luckperms.common.groups.Group; +import me.lucko.luckperms.common.users.User; +import me.lucko.luckperms.common.utils.Predicates; +import org.spongepowered.api.Sponge; +import org.spongepowered.api.plugin.PluginContainer; +import org.spongepowered.api.service.permission.PermissionService; +import org.spongepowered.api.service.permission.Subject; + +import java.lang.reflect.Method; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import static me.lucko.luckperms.sponge.migration.MigrationUtils.migrateSubject; + +public class MigrationPermissionManager extends SubCommand { + public MigrationPermissionManager() { + super("permissionmanager", "Migration from PermissionManager", Permission.MIGRATION, Predicates.alwaysFalse(), null); + } + + @Override + public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Object o, List args, String label) throws CommandException { + final Logger log = plugin.getLog(); + + Optional pm = Sponge.getPluginManager().getPlugin("permissionmanager"); + if (!pm.isPresent()) { + log.severe("PermissionManager Migration: Error -> PermissionManager is not loaded."); + return CommandResult.STATE_ERROR; + } + + // Cast to PermissionService. PEX has all of it's damned classes defined as package private. + PermissionService pmService = (PermissionService) pm.get().getInstance().get(); + + // Migrate groups + log.info("PermissionManager Migration: Starting group migration."); + + // Forcefully load all groups. + try { + Method method = pmService.getGroupSubjects().getClass().getMethod("load"); + method.invoke(pmService.getGroupSubjects()); + } catch (Throwable t) { + t.printStackTrace(); + } + + int groupCount = 0; + for (Subject pmGroup : pmService.getGroupSubjects().getAllSubjects()) { + groupCount++; + + // Make a LuckPerms group for the one being migrated + plugin.getDatastore().createAndLoadGroup(pmGroup.getIdentifier().toLowerCase()).getUnchecked(); + Group group = plugin.getGroupManager().get(pmGroup.getIdentifier().toLowerCase()); + migrateSubject(pmGroup, group); + plugin.getDatastore().saveGroup(group); + } + log.info("PermissionManager Migration: Migrated " + groupCount + " groups"); + + // Migrate users + log.info("PermissionManager Migration: Starting user migration."); + + // Forcefully load all users. + try { + Method method = pmService.getUserSubjects().getClass().getMethod("load"); + method.invoke(pmService.getUserSubjects()); + } catch (Throwable t) { + t.printStackTrace(); + } + + int userCount = 0; + for (Subject pmUser : pmService.getUserSubjects().getAllSubjects()) { + userCount++; + UUID uuid = Util.parseUuid(pmUser.getIdentifier()); + if (uuid == null) { + log.severe("PermissionManager Migration: Error -> Could not parse UUID for user: " + pmUser.getIdentifier()); + continue; + } + + // Make a LuckPerms user for the one being migrated + plugin.getDatastore().loadUser(uuid, "null").getUnchecked(); + User user = plugin.getUserManager().get(uuid); + migrateSubject(pmUser, user); + plugin.getDatastore().saveUser(user); + plugin.getUserManager().cleanup(user); + } + + log.info("PermissionManager Migration: Migrated " + userCount + " users."); + log.info("PermissionManager Migration: Success! Completed without any errors."); + return CommandResult.SUCCESS; + } +} diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/migration/MigrationPermissionsEx.java b/sponge/src/main/java/me/lucko/luckperms/sponge/migration/MigrationPermissionsEx.java index 6b3985b9c..d8ed57e1d 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/migration/MigrationPermissionsEx.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/migration/MigrationPermissionsEx.java @@ -23,8 +23,6 @@ package me.lucko.luckperms.sponge.migration; import me.lucko.luckperms.api.Logger; -import me.lucko.luckperms.api.context.ContextSet; -import me.lucko.luckperms.api.context.MutableContextSet; import me.lucko.luckperms.common.LuckPermsPlugin; import me.lucko.luckperms.common.commands.CommandException; import me.lucko.luckperms.common.commands.CommandResult; @@ -32,20 +30,19 @@ import me.lucko.luckperms.common.commands.SubCommand; import me.lucko.luckperms.common.commands.sender.Sender; import me.lucko.luckperms.common.commands.utils.Util; import me.lucko.luckperms.common.constants.Permission; -import me.lucko.luckperms.common.core.NodeBuilder; -import me.lucko.luckperms.common.core.PermissionHolder; import me.lucko.luckperms.common.groups.Group; import me.lucko.luckperms.common.users.User; import me.lucko.luckperms.common.utils.Predicates; -import me.lucko.luckperms.exceptions.ObjectAlreadyHasException; -import me.lucko.luckperms.sponge.service.LuckPermsService; import org.spongepowered.api.Sponge; import org.spongepowered.api.plugin.PluginContainer; -import org.spongepowered.api.service.context.Context; import org.spongepowered.api.service.permission.PermissionService; import org.spongepowered.api.service.permission.Subject; -import java.util.*; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import static me.lucko.luckperms.sponge.migration.MigrationUtils.migrateSubject; public class MigrationPermissionsEx extends SubCommand { public MigrationPermissionsEx() { @@ -102,70 +99,4 @@ public class MigrationPermissionsEx extends SubCommand { log.info("PermissionsEx Migration: Success! Completed without any errors."); return CommandResult.SUCCESS; } - - private static void migrateSubject(Subject subject, PermissionHolder holder) { - // Migrate permissions - Map, Map> perms = subject.getSubjectData().getAllPermissions(); - for (Map.Entry, Map> e : perms.entrySet()) { - ContextSet context = LuckPermsService.convertContexts(e.getKey()); - - MutableContextSet contexts = MutableContextSet.fromSet(context); - String server = contexts.getValues("server").stream().findAny().orElse(null); - String world = contexts.getValues("world").stream().findAny().orElse(null); - contexts.removeAll("server"); - contexts.removeAll("world"); - - for (Map.Entry perm : e.getValue().entrySet()) { - try { - holder.setPermission(new NodeBuilder(perm.getKey()).setServerRaw(server).setWorld(world).withExtraContext(contexts).setValue(perm.getValue()).build()); - } catch (ObjectAlreadyHasException ignored) {} - } - } - - // Migrate options - Map, Map> opts = subject.getSubjectData().getAllOptions(); - for (Map.Entry, Map> e : opts.entrySet()) { - ContextSet context = LuckPermsService.convertContexts(e.getKey()); - - MutableContextSet contexts = MutableContextSet.fromSet(context); - String server = contexts.getValues("server").stream().findAny().orElse(null); - String world = contexts.getValues("world").stream().findAny().orElse(null); - contexts.removeAll("server"); - contexts.removeAll("world"); - - for (Map.Entry opt : e.getValue().entrySet()) { - if (opt.getKey().equalsIgnoreCase("prefix") || opt.getKey().equalsIgnoreCase("suffix")) { - try { - holder.setPermission(new NodeBuilder(opt.getKey().toLowerCase() + ".100." + opt.getValue()).setServerRaw(server).setWorld(world).withExtraContext(contexts).setValue(true).build()); - } catch (ObjectAlreadyHasException ignored) {} - } else { - try { - holder.setPermission(new NodeBuilder("meta." + opt.getKey() + "." + opt.getValue()).setServerRaw(server).setWorld(world).withExtraContext(contexts).setValue(true).build()); - } catch (ObjectAlreadyHasException ignored) {} - } - } - } - - // Migrate parents - Map, List> parents = subject.getSubjectData().getAllParents(); - for (Map.Entry, List> e : parents.entrySet()) { - ContextSet context = LuckPermsService.convertContexts(e.getKey()); - - MutableContextSet contexts = MutableContextSet.fromSet(context); - String server = contexts.getValues("server").stream().findAny().orElse(null); - String world = contexts.getValues("world").stream().findAny().orElse(null); - contexts.removeAll("server"); - contexts.removeAll("world"); - - for (Subject s : e.getValue()) { - if (!s.getContainingCollection().getIdentifier().equalsIgnoreCase(PermissionService.SUBJECTS_GROUP)) { - continue; // LuckPerms does not support persisting other subject types. - } - - try { - holder.setPermission(new NodeBuilder("group." + s.getIdentifier().toLowerCase()).setServerRaw(server).setWorld(world).withExtraContext(contexts).setValue(true).build()); - } catch (ObjectAlreadyHasException ignored) {} - } - } - } } diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/migration/MigrationUtils.java b/sponge/src/main/java/me/lucko/luckperms/sponge/migration/MigrationUtils.java new file mode 100644 index 000000000..befa45753 --- /dev/null +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/migration/MigrationUtils.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2016 Lucko (Luck) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.lucko.luckperms.sponge.migration; + +import lombok.experimental.UtilityClass; +import me.lucko.luckperms.api.context.ContextSet; +import me.lucko.luckperms.api.context.MutableContextSet; +import me.lucko.luckperms.common.core.NodeBuilder; +import me.lucko.luckperms.common.core.PermissionHolder; +import me.lucko.luckperms.exceptions.ObjectAlreadyHasException; +import me.lucko.luckperms.sponge.service.LuckPermsService; +import org.spongepowered.api.service.context.Context; +import org.spongepowered.api.service.permission.PermissionService; +import org.spongepowered.api.service.permission.Subject; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +@UtilityClass +public class MigrationUtils { + + public static void migrateSubject(Subject subject, PermissionHolder holder) { + // Migrate permissions + Map, Map> perms = subject.getSubjectData().getAllPermissions(); + for (Map.Entry, Map> e : perms.entrySet()) { + ContextSet context = LuckPermsService.convertContexts(e.getKey()); + + MutableContextSet contexts = MutableContextSet.fromSet(context); + String server = contexts.getValues("server").stream().findAny().orElse(null); + String world = contexts.getValues("world").stream().findAny().orElse(null); + contexts.removeAll("server"); + contexts.removeAll("world"); + + for (Map.Entry perm : e.getValue().entrySet()) { + try { + holder.setPermission(new NodeBuilder(perm.getKey()).setServerRaw(server).setWorld(world).withExtraContext(contexts).setValue(perm.getValue()).build()); + } catch (ObjectAlreadyHasException ignored) {} + } + } + + // Migrate options + Map, Map> opts = subject.getSubjectData().getAllOptions(); + for (Map.Entry, Map> e : opts.entrySet()) { + ContextSet context = LuckPermsService.convertContexts(e.getKey()); + + MutableContextSet contexts = MutableContextSet.fromSet(context); + String server = contexts.getValues("server").stream().findAny().orElse(null); + String world = contexts.getValues("world").stream().findAny().orElse(null); + contexts.removeAll("server"); + contexts.removeAll("world"); + + for (Map.Entry opt : e.getValue().entrySet()) { + if (opt.getKey().equalsIgnoreCase("prefix") || opt.getKey().equalsIgnoreCase("suffix")) { + try { + holder.setPermission(new NodeBuilder(opt.getKey().toLowerCase() + ".100." + opt.getValue()).setServerRaw(server).setWorld(world).withExtraContext(contexts).setValue(true).build()); + } catch (ObjectAlreadyHasException ignored) {} + } else { + try { + holder.setPermission(new NodeBuilder("meta." + opt.getKey() + "." + opt.getValue()).setServerRaw(server).setWorld(world).withExtraContext(contexts).setValue(true).build()); + } catch (ObjectAlreadyHasException ignored) {} + } + } + } + + // Migrate parents + Map, List> parents = subject.getSubjectData().getAllParents(); + for (Map.Entry, List> e : parents.entrySet()) { + ContextSet context = LuckPermsService.convertContexts(e.getKey()); + + MutableContextSet contexts = MutableContextSet.fromSet(context); + String server = contexts.getValues("server").stream().findAny().orElse(null); + String world = contexts.getValues("world").stream().findAny().orElse(null); + contexts.removeAll("server"); + contexts.removeAll("world"); + + for (Subject s : e.getValue()) { + if (!s.getContainingCollection().getIdentifier().equalsIgnoreCase(PermissionService.SUBJECTS_GROUP)) { + continue; // LuckPerms does not support persisting other subject types. + } + + try { + holder.setPermission(new NodeBuilder("group." + s.getIdentifier().toLowerCase()).setServerRaw(server).setWorld(world).withExtraContext(contexts).setValue(true).build()); + } catch (ObjectAlreadyHasException ignored) {} + } + } + } + +}