diff --git a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java index f0b54c94cee..c36da635b34 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java @@ -954,17 +954,7 @@ public User getUser(final UUID base) { //This will return null if there is not a match. @Override public User getOfflineUser(final String name) { - final User user = userMap.getUser(name); - if (user != null && user.getBase() instanceof OfflinePlayerStub) { - //This code should attempt to use the last known name of a user, if Bukkit returns name as null. - final String lastName = user.getLastAccountName(); - if (lastName != null) { - ((OfflinePlayerStub) user.getBase()).setName(lastName); - } else { - ((OfflinePlayerStub) user.getBase()).setName(name); - } - } - return user; + return userMap.getUser(name); } @Override @@ -1067,19 +1057,9 @@ public User getUser(final Player base) { return null; } - User user = userMap.getUser(base.getUniqueId()); - - if (user == null) { - if (getSettings().isDebug()) { - LOGGER.log(Level.INFO, "Constructing new userfile from base player " + base.getName()); - } - user = userMap.loadUncachedUser(base); + final User user = userMap.getUser(base); - // The above method will end up creating a new user, but it will not be added to the cache. - // Since we already call UserMap#getUser() above, we are already okay with adding the user to the cache, - // so we need to manually add the user to the cache in order to avoid a memory leak and maintain behavior. - userMap.addCachedUser(user); - } else if (base.getClass() != UUIDPlayer.class || user.getBase() == null) { + if (base.getClass() != UUIDPlayer.class || user.getBase() == null) { user.update(base); } return user; diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java index ab3d46185f6..33fc06fb438 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java @@ -963,7 +963,7 @@ public void generateUidCache() { } } - uuids.put(uuid, config.getLong("timestamps.logout", 0L)); + uuids.put(uuid, time); nameToUuidMap.put(name, uuid); } } catch (IllegalArgumentException | IndexOutOfBoundsException ignored) { diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandessentials.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandessentials.java index 2ada7553218..f32cc655a48 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandessentials.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandessentials.java @@ -700,6 +700,8 @@ private void runUserMap(final CommandSource sender, final String[] args) { } ess.getLogger().info("Found " + total + " orphaned userdata files."); }); + } else if (args[1].equalsIgnoreCase("cache")) { + sender.sendMessage(tl("usermapKnown", ess.getUsers().getAllUserUUIDs().size(), ess.getUsers().getNameCache().size())); } else { try { final UUID uuid = UUID.fromString(args[1]); diff --git a/Essentials/src/main/java/com/earth2me/essentials/userstorage/ModernUserMap.java b/Essentials/src/main/java/com/earth2me/essentials/userstorage/ModernUserMap.java index c0ab51c8fe7..150c85fa7b8 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/userstorage/ModernUserMap.java +++ b/Essentials/src/main/java/com/earth2me/essentials/userstorage/ModernUserMap.java @@ -166,19 +166,29 @@ public User loadUncachedUser(final UUID uuid) { if (userFile.exists()) { player = new OfflinePlayerStub(uuid, ess.getServer()); user = new User(player, ess); - ((OfflinePlayerStub) player).setName(user.getLastAccountName()); - uuidCache.updateCache(uuid, null); + final String accName = user.getLastAccountName(); + ((OfflinePlayerStub) player).setName(accName); + // Check to see if there is already a UUID mapping for the name in the name cache before updating it. + // Since this code is ran for offline players, there's a chance we could be overriding the mapping + // for a player who changed their name to an older player's name, let that be handled during join. + // + // Here is a senerio which could take place if didn't do the containsKey check; + // "JRoyLULW" joins the server - "JRoyLULW" is mapped to 86f39a70-eda7-44a2-88f8-0ade4e1ec8c0 + // "JRoyLULW" changes their name to "mbax" - Nothing happens, they are yet to join the server + // "mdcfe" changes their name to "JRoyLULW" - Nothing happens, they are yet to join the server + // "JRoyLULW" (formally "mdcfe") joins the server - "JRoyLULW" is mapped to 62a6a4bb-a2b8-4796-bfe6-63067250990a + // The /baltop command is ran, iterating over all players. + // + // During the baltop iteration, two uuids have the `last-account-name` of "JRoyLULW" creating the + // potential that "JRoyLULW" is mapped back to 86f39a70-eda7-44a2-88f8-0ade4e1ec8c0 when the true + // bearer of that name is now 62a6a4bb-a2b8-4796-bfe6-63067250990a. + uuidCache.updateCache(uuid, (accName == null || uuidCache.getNameCache().containsKey(accName)) ? null : accName); return user; } return null; } - public void addCachedUser(final User user) { - userCache.put(user.getUUID(), user); - debugLogCache(user); - } - @Override public Map getNameCache() { return uuidCache.getNameCache(); diff --git a/Essentials/src/main/resources/messages.properties b/Essentials/src/main/resources/messages.properties index 3801a8a18ad..2a84084233b 100644 --- a/Essentials/src/main/resources/messages.properties +++ b/Essentials/src/main/resources/messages.properties @@ -1462,6 +1462,7 @@ userIsAwaySelfWithMessage=\u00a77You are now AFK. userIsNotAwaySelf=\u00a77You are no longer AFK. userJailed=\u00a76You have been jailed\! usermapEntry=\u00a7c{0} \u00a76is mapped to \u00a7c{1}\u00a76. +usermapKnown=\u00a76There are \u00a7c{0} \u00a76known users to the user cache with \u00a7c{1} \u00a76name to UUID pairs. usermapPurge=\u00a76Checking for files in userdata that are not mapped, results will be logged to console. Destructive Mode: {0} usermapSize=\u00a76Current cached users in user map is \u00a7c{0}\u00a76/\u00a7c{1}\u00a76/\u00a7c{2}\u00a76. userUnknown=\u00a74Warning\: The user ''\u00a7c{0}\u00a74'' has never joined this server.