getUUIDFromName(String username) {
+
+ username = username.toLowerCase();
+
+ synchronized (mapNameUUID) {
+ if (mapNameUUID.containsKey(username)) {
+ return Optional.of(mapNameUUID.get(username));
+ }
+ }
+
+ return Optional.empty();
+
+ }
+
+ /**
+ * Register a player as online
+ * Also performs any setup needed to equip nicknames etc.
+ * @param player
+ */
+ public void registerPlayer(Player player) {
+
+ UUID uuid = player.getUniqueId();
+ String username = player.getName();
+ String oldUsername;
+
+ synchronized (mapUUIDName) {
+
+ if (mapUUIDName.containsKey(uuid)) {
+
+ oldUsername = mapUUIDName.get(uuid);
+
+ if (!oldUsername.equalsIgnoreCase(username)) {
+
+ synchronized (mapNameUUID) {
+
+ mapUUIDName.remove(uuid);
+ mapUUIDName.put(uuid, username.toLowerCase());
+ mapNameUUID.remove(oldUsername);
+ mapNameUUID.put(username.toLowerCase(), uuid);
+
+ }
+
+ }
+
+ mapNameFormatted.remove(oldUsername);
+ mapNameFormatted.put(username.toLowerCase(), username);
+
+ } else {
+
+ synchronized (mapNameUUID) {
+
+ mapUUIDName.put(uuid, username.toLowerCase());
+ mapNameUUID.put(username.toLowerCase(), uuid);
+ mapNameFormatted.put(username.toLowerCase(), username);
+
+ }
+
+ }
+
+ }
+
+ online.add(uuid);
+ Bukkit.getLogger().info("[+] " + username + " has joined this server.");
+
+ }
+
+ /**
+ * Register a player into the system without them being online
+ * Used mainly for legacy conversion of old nickname file
+ * @param uuid Player's UUID
+ */
+ public void registerOfflinePlayerByUUID(UUID uuid, String username) {
+
+ synchronized (mapUUIDName) {
+
+ if (mapUUIDName.containsKey(uuid)) {
+
+ /*
+ * EMPTY : Player does not need registering
+ */
+
+ } else {
+
+ synchronized (mapNameUUID) {
+
+ mapUUIDName.put(uuid, username.toLowerCase());
+ mapNameUUID.put(username.toLowerCase(), uuid);
+ mapNameFormatted.put(username.toLowerCase(), username);
+
+ }
+
+ }
+
+ }
+
+ }
+
+ /**
+ * Register a player as offline
+ * @param player
+ */
+ public void unregisterPlayer(Player player) {
+
+ online.remove(player.getUniqueId());
+ Bukkit.getLogger().info("[-] " + player.getName() + " has left this server.");
+
+ }
+
+ /**
+ * Set the nickname of a player
+ * @param uuid
+ * @param nickname
+ */
+ public void setNickname(UUID uuid, String nickname) {
+
+ if (!mapUUIDName.containsKey(uuid)) {
+ return;
+ }
+
+ if (mapUUIDNick.containsKey(uuid)) {
+ removeNickname(uuid);
+ }
+
+ String unformattedNickname = stripAllFormattingCodes(nickname.toLowerCase());
+
+ synchronized (mapNickUUID) {
+
+ // Check for duplicates
+ if (mapNickUUID.containsKey(unformattedNickname)) {
+ if (mapNickUUID.get(unformattedNickname) != uuid) {
+ return;
+ }
+ }
+
+ mapUUIDNick.put(uuid, unformattedNickname);
+ mapNickUUID.put(unformattedNickname, uuid);
+ mapNickFormatted.put(unformattedNickname, nickname);
+
+ }
+
+ }
+
+ /**
+ * @param username
+ * @return If this player has logged into the server before
+ */
+ public boolean existsPlayer(String username) {
+ return mapNameUUID.containsKey(username.toLowerCase());
+ }
+
+ /**
+ * @param nickname
+ * @return If this nickname is currently in use
+ */
+ public boolean existsNickname(String nickname) {
+ return mapNickUUID.containsKey(stripAllFormattingCodes(nickname.toLowerCase()));
+ }
+
+ /**
+ * Return the UUIDs of players who have nicknames containing characters provided in the nickname argument
+ * @param nickname The characters of the nickname to check
+ * @return An optional which might contain a players UUID if a partial match was found
+ */
+ public Optional> getPartialNicknameMatches(String nickname) {
+
+ Set nickSet = mapNickUUID.keySet();
+ nickname = stripAllFormattingCodes(nickname.toLowerCase());
+ Set uuidSet = new HashSet();
+
+ for (String nick : nickSet) {
+
+ if (nick.startsWith(nickname)) {
+ uuidSet.add(mapNickUUID.get(nick));
+ }
+
+ }
+
+ if (!uuidSet.isEmpty()) return Optional.of(uuidSet);
+
+ for (String nick : nickSet) {
+
+ if (nick.contains(nickname)) {
+ uuidSet.add(mapNickUUID.get(nick));
+ }
+
+ }
+
+ if (!uuidSet.isEmpty()) return Optional.of(uuidSet);
+
+ try {
+ for (String nick : nickSet) {
+
+ if (nick.matches(nickname)) {
+ uuidSet.add(mapNickUUID.get(nick));
+ }
+
+ }
+ } catch (PatternSyntaxException e) {
+ /*
+ * Its not a valid regex, so we will just say there are no matches!
+ */
+ }
+
+ if (!uuidSet.isEmpty()) return Optional.of(uuidSet);
+
+ return Optional.empty();
+
+ }
+
+ /**
+ * Return the UUIDs of players who have names containing characters provided in the name argument
+ * @param name The characters of the name to check
+ * @return An optional which might contain a players UUID if a partial match was found
+ */
+ public Optional> getPartialNameMatches(String name) {
+
+ Set nameSet = mapNameUUID.keySet();
+ name = stripAllFormattingCodes(name.toLowerCase());
+ Set uuidSet = new HashSet();
+
+ for (String n : nameSet) {
+
+ if (n.startsWith(name)) {
+ uuidSet.add(mapNameUUID.get(n));
+ }
+
+ }
+
+ if (!uuidSet.isEmpty()) return Optional.of(uuidSet);
+
+ for (String n : nameSet) {
+
+ if (n.contains(name)) {
+ uuidSet.add(mapNameUUID.get(n));
+ }
+
+ }
+
+ if (!uuidSet.isEmpty()) return Optional.of(uuidSet);
+
+ try {
+ for (String n : nameSet) {
+
+ if (n.matches(name)) {
+ uuidSet.add(mapNameUUID.get(n));
+ }
+
+ }
+ } catch (PatternSyntaxException e) {
+ /*
+ * Its not a valid regex, so we will just say there are no matches!
+ */
+ }
+
+ if (!uuidSet.isEmpty()) return Optional.of(uuidSet);
+
+ return Optional.empty();
+
+ }
+
+ /**
+ * @param uuid
+ * @return If this player is currently online on the server
+ */
+ public boolean isOnline(UUID uuid) {
+ return online.contains(uuid);
+ }
+
+ /**
+ * Removes the nickname for a specified player
+ * @param uuid
+ */
+ public void removeNickname(UUID uuid) {
+
+ synchronized (mapUUIDNick) {
+
+ if (!mapUUIDNick.containsKey(uuid)) {
+ return;
+ }
+
+ String nickname = mapUUIDNick.get(uuid);
+
+ mapUUIDNick.remove(uuid);
+ mapNickUUID.remove(nickname);
+ mapNickFormatted.remove(nickname);
+
+ }
+
+ }
+
+ /**
+ * Save all persistent nickname data to file
+ *
+ * @param saveFile The file output stream to use
+ */
+ public void saveNicknameData(FileOutputStream saveFile) {
+
+ try {
+
+ ObjectOutputStream out = new ObjectOutputStream(saveFile);
+
+ out.writeObject(mapUUIDNick);
+ out.writeObject(mapUUIDName);
+ out.writeObject(mapNickUUID);
+ out.writeObject(mapNameUUID);
+ out.writeObject(mapNickFormatted);
+ out.writeObject(mapNameFormatted);
+
+ out.close();
+ Bukkit.getLogger().info("The nicknames file was successfully saved!");
+
+ } catch (IOException e) {
+
+ Bukkit.getLogger().info("An error has occured writing the nicknames file!");
+ e.printStackTrace();
+
+ }
+
+ }
+
+ // /**
+ // * Save all persistent nickname data to file
+ // *
+ // * @param configLoader Configuration file loader to use
+ // */
+ // @SuppressWarnings("serial")
+ // public void SPONGE_saveNicknameData(ConfigurationLoader configLoader) {
+ //
+ // ConfigurationNode rootNode;
+ //
+ // rootNode = configLoader.createEmptyNode();
+ //
+ // try {
+ //
+ // rootNode.getNode("nickname_uuidnick").setValue(new TypeToken