From d29dd35689952a9f7514d9d88b77536d41d9c59b Mon Sep 17 00:00:00 2001 From: Luck Date: Tue, 13 Sep 2016 20:14:16 +0100 Subject: [PATCH] Support the latest powerfulperms so-called "api" --- .../subcommands/MigrationPowerfulPerms.java | 434 ++++++++++-------- .../subcommands/utils/LPResultRunnable.java | 41 ++ 2 files changed, 295 insertions(+), 180 deletions(-) create mode 100644 common/src/main/java/me/lucko/luckperms/commands/migration/subcommands/utils/LPResultRunnable.java diff --git a/common/src/main/java/me/lucko/luckperms/commands/migration/subcommands/MigrationPowerfulPerms.java b/common/src/main/java/me/lucko/luckperms/commands/migration/subcommands/MigrationPowerfulPerms.java index 70aaebe5d..482f78527 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/migration/subcommands/MigrationPowerfulPerms.java +++ b/common/src/main/java/me/lucko/luckperms/commands/migration/subcommands/MigrationPowerfulPerms.java @@ -23,14 +23,17 @@ package me.lucko.luckperms.commands.migration.subcommands; import com.github.cheesesoftware.PowerfulPermsAPI.*; +import com.google.common.util.concurrent.ListenableFuture; import com.zaxxer.hikari.HikariDataSource; import lombok.Cleanup; import me.lucko.luckperms.LuckPermsPlugin; import me.lucko.luckperms.api.Logger; +import me.lucko.luckperms.api.data.Callback; import me.lucko.luckperms.commands.CommandResult; import me.lucko.luckperms.commands.Predicate; import me.lucko.luckperms.commands.Sender; import me.lucko.luckperms.commands.SubCommand; +import me.lucko.luckperms.commands.migration.subcommands.utils.LPResultRunnable; import me.lucko.luckperms.constants.Constants; import me.lucko.luckperms.core.PermissionHolder; import me.lucko.luckperms.data.LogEntry; @@ -45,39 +48,72 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.*; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; import static me.lucko.luckperms.constants.Permission.MIGRATION; +@SuppressWarnings("unchecked") public class MigrationPowerfulPerms extends SubCommand { /* + The PowerfulPerms API is a complete joke. Seriously, it would probably be easier reflecting into the actual plugin. + Methods move about randomly every version... + What kind of API requires reflection to function with multiple versions... Doesn't that just defeat the whole god damn point of having an API in the first place? - Whatever happened to the concept of depreciation and responsible API creation? - I tried to keep reflection to a minimum, but in some places there's no other option. - This class is a complete fucking mess for that reason. I sad now :( - */ + Whatever happened to depreciation? + */ + + private static Method getPlayerPermissionsMethod = null; private static Method getPlayerGroupsMethod = null; private static Method getGroupMethod = null; + + // lol + private static boolean superLegacy = false; private static boolean legacy = false; static { try { - getPlayerGroupsMethod = PermissionManager.class.getMethod("getPlayerOwnGroups", UUID.class, ResultRunnable.class); - getPlayerGroupsMethod.setAccessible(true); - } catch (NoSuchMethodException e) { + Class.forName("com.github.cheesesoftware.PowerfulPermsAPI.ResponseRunnable"); + legacy = true; + } catch (ClassNotFoundException ignored) {} + + if (legacy) { try { - getPlayerGroupsMethod = PermissionManager.class.getMethod("getPlayerGroups", UUID.class, ResultRunnable.class); - getPlayerGroupsMethod.setAccessible(true); - } catch (NoSuchMethodException e1) { - e1.printStackTrace(); - } + getPlayerPermissionsMethod = PermissionManager.class.getMethod("getPlayerOwnPermissions", UUID.class, ResultRunnable.class); + getPlayerPermissionsMethod.setAccessible(true); + } catch (NoSuchMethodException ignored) {} + } else { + try { + getPlayerPermissionsMethod = PermissionManager.class.getMethod("getPlayerOwnPermissions", UUID.class); + getPlayerPermissionsMethod.setAccessible(true); + } catch (NoSuchMethodException ignored) {} } try { getGroupMethod = CachedGroup.class.getMethod("getGroup"); getGroupMethod.setAccessible(true); - legacy = true; - } catch (NoSuchMethodException ignored) { + superLegacy = true; + } catch (NoSuchMethodException ignored) {} + + if (!legacy) { + try { + getPlayerGroupsMethod = PermissionManager.class.getMethod("getPlayerOwnGroups", UUID.class); + getPlayerGroupsMethod.setAccessible(true); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } + } else { + try { + getPlayerGroupsMethod = PermissionManager.class.getMethod("getPlayerOwnGroups", UUID.class, ResultRunnable.class); + getPlayerGroupsMethod.setAccessible(true); + } catch (NoSuchMethodException e) { + try { + getPlayerGroupsMethod = PermissionManager.class.getMethod("getPlayerGroups", UUID.class, ResultRunnable.class); + getPlayerGroupsMethod.setAccessible(true); + } catch (NoSuchMethodException e1) { + e1.printStackTrace(); + } + } } } @@ -97,6 +133,42 @@ public class MigrationPowerfulPerms extends SubCommand { } } + private static void getPlayerPermissions(PermissionManager manager, UUID uuid, Callback> callback) { + if (legacy) { + try { + getPlayerPermissionsMethod.invoke(manager, uuid, new LPResultRunnable>() { + @Override + public void run() { + callback.onComplete(getResult()); + } + }); + } catch (IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + } else { + try { + ListenableFuture> lf = (ListenableFuture>) getPlayerPermissionsMethod.invoke(manager, uuid); + try { + if (lf.isDone()) { + callback.onComplete(lf.get()); + } else { + lf.addListener(() -> { + try { + callback.onComplete(lf.get()); + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); + } + }, Runnable::run); + } + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); + } + } catch (IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + } + } + private CommandResult run(LuckPermsPlugin plugin, List args) { final Logger log = plugin.getLog(); if (!plugin.isPluginLoaded("PowerfulPerms")) { @@ -168,7 +240,7 @@ public class MigrationPowerfulPerms extends SubCommand { // Groups first. log.info("PowerfulPerms Migration: Starting group migration."); - Map groups = pm.getGroups(); + Map groups = pm.getGroups(); // All versions for (Group g : groups.values()) { plugin.getDatastore().createAndLoadGroup(g.getName().toLowerCase()); final me.lucko.luckperms.groups.Group group = plugin.getGroupManager().get(g.getName().toLowerCase()); @@ -181,16 +253,16 @@ public class MigrationPowerfulPerms extends SubCommand { ex.printStackTrace(); } - for (Permission p : g.getOwnPermissions()) { + for (Permission p : g.getOwnPermissions()) { // All versions applyPerm(group, p, plugin); } - for (Group parent : g.getParents()) { + for (Group parent : g.getParents()) { // All versions try { group.setPermission("group." + parent.getName().toLowerCase(), true); LogEntry.build() .actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName()) - .acted(group).action("setinherit " + parent.getName().toLowerCase()) + .acted(group).action("setinherit " + parent.getName().toLowerCase()) // All versions .build().submit(plugin); } catch (Exception ex) { if (!(ex instanceof ObjectAlreadyHasException)) { @@ -216,156 +288,176 @@ public class MigrationPowerfulPerms extends SubCommand { User user = plugin.getUserManager().get(uuid); // Get a list of Permissions held by the user from the PP API. - pm.getPlayerOwnPermissions(uuid, new LPResultRunnable>() { - @Override - public void run() { - List perms = this.getResult(); - perms.forEach(p -> applyPerm(user, p, plugin)); + getPlayerPermissions(pm, uuid, perms -> { // Changes each version + perms.forEach(p -> applyPerm(user, p, plugin)); - // Update the progress so the user can be saved and unloaded. - synchronized (progress) { - progress.get(uuid).countDown(); - if (progress.get(uuid).getCount() == 0) { - plugin.getDatastore().saveUser(user); - plugin.getUserManager().cleanup(user); - } + // Update the progress so the user can be saved and unloaded. + synchronized (progress) { + progress.get(uuid).countDown(); + if (progress.get(uuid).getCount() == 0) { + plugin.getDatastore().saveUser(user); + plugin.getUserManager().cleanup(user); } - } }); // Migrate the user's groups to LuckPerms from PP. - try { - getPlayerGroupsMethod.invoke(pm, uuid, new LPResultRunnable>>() { - @Override - public void run() { - Map> groups = getResult(); - - for (Map.Entry> e : groups.entrySet()) { - final String server; - if (e.getKey() != null && (e.getKey().equals("") || e.getKey().equalsIgnoreCase("all"))) { - server = null; - } else { - server = e.getKey(); - } - - // This is horrible. So many random API changes through versions, no depreciation. - if (legacy) { - e.getValue().stream() - .filter(cg -> !cg.isNegated()) - .map(cg -> { - try { - return (Group) getGroupMethod.invoke(cg); - } catch (IllegalAccessException | InvocationTargetException e1) { - e1.printStackTrace(); - return null; - } - }) - .forEach(g -> { - if (g != null) { - if (server == null) { - try { - user.setPermission("group." + g.getName().toLowerCase(), true); - LogEntry.build() - .actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName()) - .acted(user).action("addgroup " + g.getName().toLowerCase()) - .build().submit(plugin); - } catch (Exception ex) { - if (!(ex instanceof ObjectAlreadyHasException)) { - ex.printStackTrace(); - } - } - } else { - try { - user.setPermission("group." + g.getName().toLowerCase(), true, server); - LogEntry.build() - .actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName()) - .acted(user).action("addgroup " + g.getName().toLowerCase() + " " + server) - .build().submit(plugin); - } catch (Exception ex) { - if (!(ex instanceof ObjectAlreadyHasException)) { - ex.printStackTrace(); - } - } - } - } - }); - } else { - e.getValue().stream() - .filter(g -> !g.hasExpired() && !g.isNegated()) - .forEach(g -> { - final Group group = pm.getGroup(g.getGroupId()); - if (g.willExpire()) { - if (server == null) { - try { - user.setPermission("group." + group.getName().toLowerCase(), true, g.getExpirationDate().getTime() / 1000L); - LogEntry.build() - .actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName()) - .acted(user).action("addtempgroup " + group.getName().toLowerCase() + " " + g.getExpirationDate().getTime() / 1000L) - .build().submit(plugin); - } catch (Exception ex) { - if (!(ex instanceof ObjectAlreadyHasException)) { - ex.printStackTrace(); - } - } - } else { - try { - user.setPermission("group." + group.getName().toLowerCase(), true, server, g.getExpirationDate().getTime() / 1000L); - LogEntry.build() - .actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName()) - .acted(user).action("addtempgroup " + group.getName().toLowerCase() + " " + g.getExpirationDate().getTime() / 1000L + " " + server) - .build().submit(plugin); - } catch (Exception ex) { - if (!(ex instanceof ObjectAlreadyHasException)) { - ex.printStackTrace(); - } - } - } - - } else { - if (server == null) { - try { - user.setPermission("group." + group.getName().toLowerCase(), true); - LogEntry.build() - .actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName()) - .acted(user).action("addgroup " + group.getName().toLowerCase()) - .build().submit(plugin); - } catch (Exception ex) { - if (!(ex instanceof ObjectAlreadyHasException)) { - ex.printStackTrace(); - } - } - } else { - try { - user.setPermission("group." + group.getName().toLowerCase(), true, server); - LogEntry.build() - .actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName()) - .acted(user).action("addgroup " + group.getName().toLowerCase() + " " + server) - .build().submit(plugin); - } catch (Exception ex) { - if (!(ex instanceof ObjectAlreadyHasException)) { - ex.printStackTrace(); - } - } - } - } - }); - } - } - - // Update the progress so the user can be saved and unloaded. - synchronized (progress) { - progress.get(uuid).countDown(); - if (progress.get(uuid).getCount() == 0) { - plugin.getDatastore().saveUser(user); - plugin.getUserManager().cleanup(user); - } - } + Callback>> callback = groups1 -> { + for (Map.Entry> e : groups1.entrySet()) { + final String server; + if (e.getKey() != null && (e.getKey().equals("") || e.getKey().equalsIgnoreCase("all"))) { + server = null; + } else { + server = e.getKey(); } - }); - } catch (IllegalAccessException | InvocationTargetException e) { - log.info("PowerfulPerms Migration: Error"); - e.printStackTrace(); + + if (superLegacy) { + e.getValue().stream() + .filter(cg -> !cg.isNegated()) + .map(cg -> { + try { + return (Group) getGroupMethod.invoke(cg); + } catch (IllegalAccessException | InvocationTargetException e1) { + e1.printStackTrace(); + return null; + } + }) + .forEach(g -> { + if (g != null) { + if (server == null) { + try { + user.setPermission("group." + g.getName().toLowerCase(), true); + LogEntry.build() + .actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName()) + .acted(user).action("addgroup " + g.getName().toLowerCase()) + .build().submit(plugin); + } catch (Exception ex) { + if (!(ex instanceof ObjectAlreadyHasException)) { + ex.printStackTrace(); + } + } + } else { + try { + user.setPermission("group." + g.getName().toLowerCase(), true, server); + LogEntry.build() + .actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName()) + .acted(user).action("addgroup " + g.getName().toLowerCase() + " " + server) + .build().submit(plugin); + } catch (Exception ex) { + if (!(ex instanceof ObjectAlreadyHasException)) { + ex.printStackTrace(); + } + } + } + } + }); + } else { + e.getValue().stream() + .filter(g -> !g.hasExpired() && !g.isNegated()) + .forEach(g -> { + final Group group = pm.getGroup(g.getGroupId()); + if (g.willExpire()) { + if (server == null) { + try { + user.setPermission("group." + group.getName().toLowerCase(), true, g.getExpirationDate().getTime() / 1000L); + LogEntry.build() + .actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName()) + .acted(user).action("addtempgroup " + group.getName().toLowerCase() + " " + g.getExpirationDate().getTime() / 1000L) + .build().submit(plugin); + } catch (Exception ex) { + if (!(ex instanceof ObjectAlreadyHasException)) { + ex.printStackTrace(); + } + } + } else { + try { + user.setPermission("group." + group.getName().toLowerCase(), true, server, g.getExpirationDate().getTime() / 1000L); + LogEntry.build() + .actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName()) + .acted(user).action("addtempgroup " + group.getName().toLowerCase() + " " + g.getExpirationDate().getTime() / 1000L + " " + server) + .build().submit(plugin); + } catch (Exception ex) { + if (!(ex instanceof ObjectAlreadyHasException)) { + ex.printStackTrace(); + } + } + } + + } else { + if (server == null) { + try { + user.setPermission("group." + group.getName().toLowerCase(), true); + LogEntry.build() + .actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName()) + .acted(user).action("addgroup " + group.getName().toLowerCase()) + .build().submit(plugin); + } catch (Exception ex) { + if (!(ex instanceof ObjectAlreadyHasException)) { + ex.printStackTrace(); + } + } + } else { + try { + user.setPermission("group." + group.getName().toLowerCase(), true, server); + LogEntry.build() + .actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName()) + .acted(user).action("addgroup " + group.getName().toLowerCase() + " " + server) + .build().submit(plugin); + } catch (Exception ex) { + if (!(ex instanceof ObjectAlreadyHasException)) { + ex.printStackTrace(); + } + } + } + } + }); + } + } + + // Update the progress so the user can be saved and unloaded. + synchronized (progress) { + progress.get(uuid).countDown(); + if (progress.get(uuid).getCount() == 0) { + plugin.getDatastore().saveUser(user); + plugin.getUserManager().cleanup(user); + } + } + }; + + if (!legacy) { + try { + ListenableFuture>> future = (ListenableFuture>>) getPlayerGroupsMethod.invoke(pm, uuid); + try { + if (future.isDone()) { + callback.onComplete(future.get()); + } else { + future.addListener(() -> { + try { + callback.onComplete(future.get()); + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); + } + }, Runnable::run); + } + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); + } + } catch (IllegalAccessException | InvocationTargetException e) { + log.info("PowerfulPerms Migration: Error"); + e.printStackTrace(); + } + } else { + try { + getPlayerGroupsMethod.invoke(pm, uuid, new LPResultRunnable>>() { + @Override + public void run() { + callback.onComplete(getResult()); + } + }); + } catch (IllegalAccessException | InvocationTargetException e) { + log.info("PowerfulPerms Migration: Error"); + e.printStackTrace(); + } } } @@ -417,7 +509,7 @@ public class MigrationPowerfulPerms extends SubCommand { } long expireAt = 0L; - if (!legacy) { + if (!superLegacy) { if (p.willExpire()) { expireAt = p.getExpirationDate().getTime() / 1000L; } @@ -508,22 +600,4 @@ public class MigrationPowerfulPerms extends SubCommand { } } } - - /** - * Overrides the default ResultRunnable, callbacks will always run in the same thread. (an async one, hopefully.) - * @param type - */ - @SuppressWarnings("WeakerAccess") - public abstract class LPResultRunnable extends ResultRunnable { - - public LPResultRunnable() { - super(); - super.sameThread = true; - } - - public T getResult() { - return super.result; - } - - } } diff --git a/common/src/main/java/me/lucko/luckperms/commands/migration/subcommands/utils/LPResultRunnable.java b/common/src/main/java/me/lucko/luckperms/commands/migration/subcommands/utils/LPResultRunnable.java new file mode 100644 index 000000000..cee24c8e9 --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/commands/migration/subcommands/utils/LPResultRunnable.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016 Lucko (Luck) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.lucko.luckperms.commands.migration.subcommands.utils; + +import com.github.cheesesoftware.PowerfulPermsAPI.ResultRunnable; + +/** + * Overrides the default ResultRunnable, callbacks will always run in the same thread. (an async one, hopefully.) + * @param type + */ +public abstract class LPResultRunnable extends ResultRunnable { + public LPResultRunnable() { + super(); + super.sameThread = true; + } + + public T getResult() { + return super.result; + } + +} \ No newline at end of file