@Command(name = "pex",
syntax = "convert uuid [force]",
permission = "permissions.convert",
description = "Bulk convert user data to UUID-based storage")
public void convertUUID(final PermissionsEx plugin, final CommandSender sender, Map<String, String> 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;
}
final ProfileRepository repo = new HttpProfileRepository("minecraft");
final Collection<String> userIdentifiers = new HashSet<>(backend.getUserIdentifiers());
for (Iterator<String> it = userIdentifiers.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);
final Iterator<List<String>> 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<String> names = splitIdentifiers.next();
try {
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);
}
} 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);
}
}
});
}