2014-04-20 05:12:28 +00:00
|
|
|
/**
|
|
|
|
* Copyright © 2013 tuxed <write@imaginarycode.com>
|
|
|
|
* This work is free. You can redistribute it and/or modify it under the
|
|
|
|
* terms of the Do What The Fuck You Want To Public License, Version 2,
|
|
|
|
* as published by Sam Hocevar. See http://www.wtfpl.net/ for more details.
|
|
|
|
*/
|
|
|
|
package com.imaginarycode.minecraft.redisbungee.util;
|
|
|
|
|
|
|
|
import com.google.common.base.Charsets;
|
|
|
|
import com.google.common.collect.BiMap;
|
|
|
|
import com.google.common.collect.HashBiMap;
|
|
|
|
import com.google.common.collect.Maps;
|
|
|
|
import com.imaginarycode.minecraft.redisbungee.RedisBungee;
|
2014-05-28 06:06:17 +00:00
|
|
|
import lombok.NonNull;
|
2014-04-20 05:12:28 +00:00
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
|
import net.md_5.bungee.api.ProxyServer;
|
|
|
|
import redis.clients.jedis.Jedis;
|
|
|
|
|
|
|
|
import java.util.Collections;
|
2014-04-26 23:43:40 +00:00
|
|
|
import java.util.Map;
|
2014-04-20 05:12:28 +00:00
|
|
|
import java.util.UUID;
|
|
|
|
import java.util.logging.Level;
|
|
|
|
import java.util.regex.Pattern;
|
|
|
|
|
|
|
|
@RequiredArgsConstructor
|
|
|
|
public class UUIDTranslator {
|
|
|
|
private final RedisBungee plugin;
|
|
|
|
private BiMap<String, UUID> uuidMap = Maps.synchronizedBiMap(HashBiMap.<String, UUID>create());
|
|
|
|
public static final Pattern UUID_PATTERN = Pattern.compile("[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}");
|
2014-05-23 14:53:38 +00:00
|
|
|
public static final Pattern MOJANGIAN_UUID_PATTERN = Pattern.compile("[a-fA-F0-9]{32}");
|
2014-04-20 05:12:28 +00:00
|
|
|
|
2014-05-28 06:06:17 +00:00
|
|
|
public UUID getTranslatedUuid(@NonNull String player) {
|
2014-04-20 05:12:28 +00:00
|
|
|
if (ProxyServer.getInstance().getPlayer(player) != null)
|
|
|
|
return ProxyServer.getInstance().getPlayer(player).getUniqueId();
|
|
|
|
|
|
|
|
UUID uuid = uuidMap.get(player);
|
|
|
|
if (uuid != null)
|
|
|
|
return uuid;
|
|
|
|
|
2014-05-23 14:50:05 +00:00
|
|
|
if (UUID_PATTERN.matcher(player).find()) {
|
|
|
|
return UUID.fromString(player);
|
|
|
|
}
|
|
|
|
|
2014-05-23 14:53:38 +00:00
|
|
|
if (MOJANGIAN_UUID_PATTERN.matcher(player).find()) {
|
|
|
|
// Reconstruct the UUID
|
|
|
|
return UUIDFetcher.getUUID(player);
|
|
|
|
}
|
|
|
|
|
2014-04-20 05:12:28 +00:00
|
|
|
if (!plugin.getProxy().getConfig().isOnlineMode()) {
|
|
|
|
uuid = UUID.nameUUIDFromBytes(("OfflinePlayer:" + player).getBytes(Charsets.UTF_8));
|
|
|
|
uuidMap.put(player, uuid);
|
|
|
|
return uuid;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Okay, it wasn't locally cached. Let's try Redis.
|
|
|
|
Jedis jedis = plugin.getPool().getResource();
|
|
|
|
try {
|
2014-04-27 02:28:17 +00:00
|
|
|
String stored = jedis.hget("uuids", player.toLowerCase());
|
2014-04-20 05:12:28 +00:00
|
|
|
if (stored != null && UUID_PATTERN.matcher(stored).find()) {
|
|
|
|
// This is it!
|
|
|
|
uuid = UUID.fromString(stored);
|
2014-04-23 22:05:42 +00:00
|
|
|
storeInfo(player, uuid, jedis);
|
|
|
|
uuidMap.put(player, uuid);
|
2014-04-20 05:12:28 +00:00
|
|
|
return uuid;
|
|
|
|
}
|
|
|
|
|
|
|
|
// That didn't work. Let's ask Mojang.
|
2014-04-26 23:43:40 +00:00
|
|
|
for (Map.Entry<String, UUID> entry : new UUIDFetcher(Collections.singletonList(player)).call().entrySet()) {
|
|
|
|
if (entry.getKey().equalsIgnoreCase(player)) {
|
|
|
|
uuidMap.put(player, entry.getValue());
|
|
|
|
storeInfo(player, entry.getValue(), jedis);
|
|
|
|
return entry.getValue();
|
|
|
|
}
|
2014-04-20 05:12:28 +00:00
|
|
|
}
|
|
|
|
|
2014-04-26 23:43:40 +00:00
|
|
|
return null;
|
2014-04-20 05:12:28 +00:00
|
|
|
} catch (Exception e) {
|
|
|
|
plugin.getLogger().log(Level.SEVERE, "Unable to fetch UUID for " + player, e);
|
|
|
|
return null;
|
|
|
|
} finally {
|
|
|
|
plugin.getPool().returnResource(jedis);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-28 06:06:17 +00:00
|
|
|
public String getNameFromUuid(@NonNull UUID player) {
|
2014-04-20 05:12:28 +00:00
|
|
|
if (ProxyServer.getInstance().getPlayer(player) != null)
|
|
|
|
return ProxyServer.getInstance().getPlayer(player).getName();
|
|
|
|
|
|
|
|
String name = uuidMap.inverse().get(player);
|
|
|
|
|
|
|
|
if (name != null)
|
|
|
|
return name;
|
|
|
|
|
|
|
|
// Okay, it wasn't locally cached. Let's try Redis.
|
|
|
|
Jedis jedis = plugin.getPool().getResource();
|
|
|
|
try {
|
|
|
|
String stored = jedis.hget("player:" + player, "name");
|
|
|
|
if (stored != null) {
|
|
|
|
name = stored;
|
|
|
|
uuidMap.put(name, player);
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
|
|
|
// That didn't work. Let's ask Mojang.
|
|
|
|
name = new NameFetcher(Collections.singletonList(player)).call().get(player);
|
|
|
|
|
|
|
|
if (name != null) {
|
2014-04-23 22:05:42 +00:00
|
|
|
storeInfo(name, player, jedis);
|
2014-04-20 05:12:28 +00:00
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
} catch (Exception e) {
|
|
|
|
plugin.getLogger().log(Level.SEVERE, "Unable to fetch name for " + player, e);
|
|
|
|
return null;
|
|
|
|
} finally {
|
|
|
|
plugin.getPool().returnResource(jedis);
|
|
|
|
}
|
|
|
|
}
|
2014-04-23 22:05:42 +00:00
|
|
|
|
|
|
|
private static void storeInfo(String name, UUID uuid, Jedis jedis) {
|
2014-04-27 02:28:17 +00:00
|
|
|
jedis.hset("uuids", name.toLowerCase(), uuid.toString());
|
2014-04-23 22:05:42 +00:00
|
|
|
jedis.hset("player:" + uuid, "name", name);
|
|
|
|
}
|
2014-04-20 05:12:28 +00:00
|
|
|
}
|