From b475a49e81b187185a5a4468e39b24ed34916099 Mon Sep 17 00:00:00 2001 From: zml Date: Tue, 2 Sep 2014 16:47:28 -0700 Subject: [PATCH] Modify bulk UUID conversion command to use bulk reqs Unfortunately the Mojang AccountsClient is not yet available in any Maven repo, so modifying the AccountsClient build.gradle is necessary to build for now. --- pom.xml | 13 ++++ .../permissions/PermissionManager.java | 4 + .../bukkit/commands/UtilityCommands.java | 75 ++++++++++++------- 3 files changed, 67 insertions(+), 25 deletions(-) diff --git a/pom.xml b/pom.xml index 4378eaf69..e3c0e7c2b 100644 --- a/pom.xml +++ b/pom.xml @@ -57,6 +57,14 @@ org.apache ru.tehkode.libs.org.apache + + com.mojang + ru.tehkode.libs.com.mojang + + + com.google.gson + ru.tehkode.libs.com.google.gson + @@ -150,6 +158,11 @@ updater LATEST + + com.mojang + AccountsClient + unspecified + diff --git a/src/main/java/ru/tehkode/permissions/PermissionManager.java b/src/main/java/ru/tehkode/permissions/PermissionManager.java index 21f219019..cfbfbd3ee 100644 --- a/src/main/java/ru/tehkode/permissions/PermissionManager.java +++ b/src/main/java/ru/tehkode/permissions/PermissionManager.java @@ -707,4 +707,8 @@ public Collection getGroupNames() { public Logger getLogger() { return logger; } + + public ScheduledExecutorService getExecutor() { + return executor; + } } diff --git a/src/main/java/ru/tehkode/permissions/bukkit/commands/UtilityCommands.java b/src/main/java/ru/tehkode/permissions/bukkit/commands/UtilityCommands.java index b67cd5fc0..a5d9d9729 100644 --- a/src/main/java/ru/tehkode/permissions/bukkit/commands/UtilityCommands.java +++ b/src/main/java/ru/tehkode/permissions/bukkit/commands/UtilityCommands.java @@ -18,6 +18,10 @@ */ package ru.tehkode.permissions.bukkit.commands; +import com.google.common.collect.Iterables; +import com.mojang.api.profiles.HttpProfileRepository; +import com.mojang.api.profiles.Profile; +import com.mojang.api.profiles.ProfileRepository; import org.bukkit.ChatColor; import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; @@ -34,9 +38,12 @@ import java.io.File; import java.util.Collection; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.UUID; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Level; public class UtilityCommands extends PermissionsCommand { @@ -151,41 +158,59 @@ public void printHierarchy(PermissionsEx plugin, CommandSender sender, Map args) { - PermissionBackend backend = plugin.getPermissionsManager().getBackend(); + public void convertUUID(final PermissionsEx plugin, final CommandSender sender, Map args) { + final PermissionBackend backend = plugin.getPermissionsManager().getBackend(); if (!plugin.getServer().getOnlineMode() && !"force".equals(args.get("force"))) { sender.sendMessage(ChatColor.RED + "This server is running in offline mode and UUIDs may not be stable. Please run '/pex convert uuid force' to perform conversion anyway, or switch to online mode."); return; } - int count = 0; - sender.sendMessage("Beginning conversion to UUID (This may take a while (a long while))"); + final ProfileRepository repo = new HttpProfileRepository("minecraft"); + final Collection userIdentifiers = backend.getUserIdentifiers(); + for (Iterator it = backend.getUserIdentifiers().iterator(); it.hasNext(); ) { + try { + UUID.fromString(it.next()); + it.remove(); + } catch (IllegalArgumentException ex) { + } + } + + if (userIdentifiers.isEmpty()) { + sender.sendMessage(ChatColor.RED + "No users to convert!"); + return; + } + + sender.sendMessage("Beginning conversion to UUID in " + (int) Math.ceil(userIdentifiers.size() / 50000.0) + " batches of max 50k (1 batch is executed every 10 minutes)"); backend.setPersistent(false); - try { - Collection userIdentifiers = backend.getUserIdentifiers(); - for (String name : backend.getUserIdentifiers()) { + final Iterator> splitIdentifiers = Iterables.partition(userIdentifiers, 50 * 1000).iterator(); // 50k users per 10 minutes + final AtomicInteger batchNum = new AtomicInteger(1); + + plugin.getPermissionsManager().getExecutor().execute(new Runnable() { + @Override + public void run() { + List names = splitIdentifiers.next(); try { - UUID uid = UUID.fromString(name); - continue; - } catch (IllegalArgumentException ex) { - // We aren't doing uuid - OfflinePlayer player = plugin.getServer().getOfflinePlayer(name); - if (player.getName() == null || player.getUniqueId() == null) { - sender.sendMessage("Unable to convert user named " + name + " because name or UUID in profile was null!"); - continue; + for (Profile profile : repo.findProfilesByNames(names.toArray(new String[names.size()]))) { + PermissionsUserData data = backend.getUserData(profile.getName()); + data.setIdentifier(profile.getId().replaceFirst("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})", "$1-$2-$3-$4-$5")); + data.setOption("name", profile.getName(), null); } - - PermissionsUserData userData = backend.getUserData(name); - userData.setIdentifier(player.getUniqueId().toString()); - userData.setOption("name", player.getName(), null); - if (++count % 100 == 0) { - sender.sendMessage(ChatColor.GRAY + "Converted " + count + " of " + userIdentifiers.size() + " users"); + } catch (Exception e) { + ErrorReport.handleError("While converting batch " + batchNum.get() + " to UUID", e); + backend.setPersistent(true); + return; + } + if (splitIdentifiers.hasNext()) { + plugin.getPermissionsManager().getExecutor().schedule(this, 10, TimeUnit.MINUTES); + plugin.getLogger().info("Completed conversion batch " + batchNum.getAndIncrement() + " of " + (int) Math.ceil(userIdentifiers.size() / 50000.0)); + } else { + plugin.getLogger().info("UUID conversion complete"); + if (!(sender instanceof Player) || ((Player) sender).isOnline()) { + sender.sendMessage("UUID conversion complete"); } + backend.setPersistent(true); } } - } finally { - backend.setPersistent(true); - } - sender.sendMessage(ChatColor.GREEN + "Conversion to UUID complete!"); + }); } @Command(name = "pex",