Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use a more efficient Name -> UUID conversion #29

Open
GuntherDW opened this issue Dec 30, 2014 · 0 comments
Open

Use a more efficient Name -> UUID conversion #29

GuntherDW opened this issue Dec 30, 2014 · 0 comments

Comments

@GuntherDW
Copy link

With the current method of looping through every folder and checking every player one by one, it can take a serious amount of time to fetch all those UUID's like that.

We have about 4600 inventory yml's in our system. On our first run it was running for more than half an hour and it still didn't even get half-way.
There however is a HTTP accessible API from mojang with which you can fetch multiple UUID's at the same time. Up to 100 even.

By using evilimidget's UUIDFetcher (ready-to-implement code) the effects of this speedup really are enormous
His code can be found here : https://gist.github.com/evilmidget38/26d70114b834f71fb3b4

So then when I changed converToUUID() to something like this (Yes it can be optimised even further, but this is just to prove my point)

    private void convertToUUID() {
        File groupsfolder = new File(getDataFolder(), "Groups");
        File uuidgroupsfolder = new File(getDataFolder(), "UUIDGroups");
        groupsfolder.renameTo(uuidgroupsfolder);
        List<String> playerNameList = new ArrayList<String>();
        if (uuidgroupsfolder.exists() && uuidgroupsfolder.isDirectory()) {
            File[] groups = uuidgroupsfolder.listFiles();
            for (File gfolder : groups) {
                if (gfolder.isDirectory()) {
                    File[] users = gfolder.listFiles();
                    for (File user : users) {
                        if (user.isFile()) {
                            String filename = user.getName();
                            if (filename.endsWith(".ec.yml")) {
                                String username = filename.substring(0, filename.indexOf("."));
                                if (!playerNameList.contains(username)) {
                                    playerNameList.add(username);
                                }
                            } else if (filename.endsWith(".yml")) {
                                String username = filename.substring(0, filename.lastIndexOf("."));
                                if (!playerNameList.contains(username)) {
                                    playerNameList.add(username);
                                }
                            }
                        }
                    }
                }
            }
        }
        Map<String, UUID> uuids = new HashMap<String, UUID>();
        try {
            com.evilmidget38.UUIDFetcher uuidFetcher = new com.evilmidget38.UUIDFetcher(playerNameList, true);
            uuids = uuidFetcher.call();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (uuidgroupsfolder.exists() && uuidgroupsfolder.isDirectory()) {
            File[] groups = uuidgroupsfolder.listFiles();
            for (File gfolder : groups) {
                if (gfolder.isDirectory()) {
                    File[] users = gfolder.listFiles();
                    for (File user : users) {
                        if (user.isFile()) {
                            String filename = user.getName();
                            if (filename.endsWith(".ec.yml")) {
                                String username = filename.substring(0, filename.indexOf("."));
                                String newName = "";
                                log.debug("Converting " + username + "'s enderchest file.");
                                if (uuids.containsKey(username)) {
                                    newName = uuids.get(username).toString();
                                } else {
                                    OfflinePlayer ouser = Bukkit.getOfflinePlayer(username);
                                    newName = ouser.getUniqueId().toString();
                                    uuids.put(username, ouser.getUniqueId());
                                }
                                File newname = new File(user.getParent(), newName + ".ec.yml");
                                user.renameTo(newname);
                            } else if (filename.endsWith(".yml")) {
                                String username = filename.substring(0, filename.lastIndexOf("."));
                                String newName = "";
                                log.debug("Converting " + username + "'s inventory file.");
                                if (uuids.containsKey(username)) {
                                    newName = uuids.get(username).toString();
                                } else {
                                    OfflinePlayer ouser = Bukkit.getOfflinePlayer(username);
                                    newName = ouser.getUniqueId().toString();
                                    uuids.put(username, ouser.getUniqueId());
                                }
                                File newname = new File(user.getParent(), newName + ".yml");
                                user.renameTo(newname);
                            }
                        }
                    }
                }
            }
        }
    }

The time it took to convert our ~4500-4600 yml's was less than 1 minute. Including the hits that it didn't get.

[21:45:58 INFO]: [MultiInv] Enabling MultiInv v3.3.1
[21:45:58 INFO]: [MultiInv] MC 1.3 or above found, enabling version 2 XP handling.
[21:45:58 INFO]: [MultiInv] Older data folder detected. Converting users to UUID, please wait...
[21:46:11 INFO]: Username not in map : InvictusFortis
[21:46:12 INFO]: Username not in map : johndecker
[21:46:12 INFO]: Username not in map : DutchSynapse
[21:46:12 INFO]: Username not in map : TheUberdude14.yml.bak-2014-06-05-1630
[21:46:12 INFO]: Username not in map : qazeds12
[21:46:13 INFO]: [MultiInv] Conversion complete!

Compared to 30+ minutes (and me just shutting the server down because it was taking too long) this is blazingly fast. I'm sure that if you optimise the code a bit it could get even faster, but this will help other server owners with big servers just like this I suppose. There are obvious copy/paste issues like checking for the folder twice but this is just a POC, not a beauty contest :P.

@GuntherDW GuntherDW changed the title Use more efficient Name -> UUID conversion Use a more efficient Name -> UUID conversion Dec 30, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant