package net.rainbowcode.jpixelface.profile;
import com.google.gson.*;
import net.rainbowcode.jpixelface.*;
import net.rainbowcode.jpixelface.exceptions.MojangException;
import net.rainbowcode.jpixelface.redis.RedisKey;
import net.rainbowcode.jpixelface.redis.RedisUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.IOException;
import java.util.Base64;
import java.util.Optional;
import java.util.UUID;
import java.util.function.Supplier;
public class ProfileManager
{
private static final Logger LOGGER = LogManager.getLogger();
private static int getTicket()
{
while (HttpServer.requestCounter.get() == 1)
{
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
return HttpServer.requestCounter.decrementAndGet();
}
private static void commitProfile(Profile profile)
{
RedisUtils.setAndExpire(
RedisKey.PROFILE_UUID.buildKey(profile.getUuid().toString()),
profile.toJson().toString(), 14400);
RedisUtils.setAndExpire(
RedisKey.UUID_NAME.buildKey(profile.getName().toLowerCase()),
profile.getUuid().toString(), 14400);
}
public static Profile getProfileFromUUID(UUID uuid) throws MojangException, IOException
{
String key = RedisKey.PROFILE_UUID.buildKey(uuid.toString());
if (RedisUtils.exists(key))
{
return new Profile(RedisUtils.getAsJson(key));
}
else
{
String url = "https://sessionserver.mojang.com/session/minecraft/profile/"
+ uuid.toString().replaceAll("-", "");
getTicket();
HttpStringResponse response = HttpUtil.getAsString(url);
String string = response.getResponse();
if (response.getCode() != 200)
{
throw new MojangException(url, response.getCode());
}
else
{
JsonParser parser = new JsonParser();
JsonObject object = parser.parse(string).getAsJsonObject();
JsonArray properties = object.getAsJsonArray("properties");
String name = object.getAsJsonPrimitive("name")
.getAsString();
JsonObject textures = properties.get(0).getAsJsonObject();
String value = textures.get("value").getAsString();
String decoded = new String(Base64.getDecoder().decode(
value), "UTF-8");
JsonObject parse = parser.parse(decoded).getAsJsonObject();
JsonObject texturesOb = parse.getAsJsonObject("textures");
final String[] skinUrl = {null};
final String[] capeUrl = {null};
if (texturesOb != null)
{
resolve(() -> texturesOb.getAsJsonObject("SKIN").getAsJsonPrimitive("url").getAsString()).ifPresent(x -> skinUrl[0] = x);
resolve(() -> texturesOb.getAsJsonObject("CAPE").getAsJsonPrimitive("url").getAsString()).ifPresent(x -> capeUrl[0] = x);
}
Profile profile = new Profile(name, uuid, skinUrl[0], capeUrl[0]);
commitProfile(profile);
return profile;
}
}
}
private static UUID uuidFromName(String name) throws MojangException, IOException, JsonParseException
{
name = name.toLowerCase();
String key = RedisKey.UUID_NAME.buildKey(name);
if (RedisUtils.exists(key))
{
return UUID.fromString(RedisUtils.getAsString(key));
}
else
{
getTicket();
String path = "https://api.mojang.com/users/profiles/minecraft/" + name;
HttpStringResponse response = HttpUtil.getAsString(path);
String string = response.getResponse();
JsonParser parser = new JsonParser();
if (response.getCode() != 200)
{
throw new MojangException(path, response.getCode());
}
else
{
JsonElement parse = parser.parse(string);
JsonObject object = parse.getAsJsonObject();
UUID uuid = UUID.fromString(StringUtil.addDashes(object
.getAsJsonPrimitive("id").getAsString()));
RedisUtils.setAndExpire(key, uuid.toString(), 86400);
return uuid;
}
}
}
public static Profile getProfileFromName(String name) throws MojangException, IOException, JsonParseException
{
name = name.toLowerCase();
return getProfileFromUUID(uuidFromName(name));
}
/**
* Resolves optional objects, dealing with nulls.
* <p>
* Nicked from https://github.com/winterbe/java8-tutorial
* MIT: https://github.com/winterbe/java8-tutorial/blob/master/LICENSE
*
* @param resolver
* @param <T>
* @return
*/
public static <T> Optional<T> resolve(Supplier<T> resolver)
{
try
{
T result = resolver.get();
return Optional.ofNullable(result);
}
catch (NullPointerException e)
{
return Optional.empty();
}
}
}