diff --git a/LaunchServer/source/texture/AuthlibTextureProvider.java b/LaunchServer/source/texture/AuthlibTextureProvider.java index 64c95b2..88fb22d 100644 --- a/LaunchServer/source/texture/AuthlibTextureProvider.java +++ b/LaunchServer/source/texture/AuthlibTextureProvider.java @@ -1,24 +1,9 @@ package launchserver.texture; -import com.eclipsesource.json.Json; -import com.eclipsesource.json.JsonArray; -import com.eclipsesource.json.JsonObject; -import com.eclipsesource.json.JsonValue; -import launcher.LauncherAPI; import launcher.client.PlayerProfile.Texture; -import launcher.helper.IOHelper; -import launcher.helper.JVMHelper; -import launcher.helper.LogHelper; -import launcher.helper.VerifyHelper; import launcher.serialize.config.entry.BlockConfigEntry; import launcher.serialize.config.entry.StringConfigEntry; -import launchserver.helpers.HTTPRequestHelper; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.Base64; -import java.util.HashMap; -import java.util.Map; import java.util.UUID; public class AuthlibTextureProvider extends TextureProvider @@ -26,14 +11,7 @@ // Instance private final String setUuidURL; private final String setProfileURL; - - @LauncherAPI - public static final long CACHE_DURATION_MS = VerifyHelper.verifyLong( - Long.parseLong(System.getProperty("launcher.mysql.cacheDurationHours", Integer.toString(24))), - VerifyHelper.L_NOT_NEGATIVE, "launcher.mysql.cacheDurationHours can't be < 0") * 60L * 60L * 1000L; - - // Instance - private final Map cache = new HashMap<>(1024); + protected CacheTextureProvider cacheTextureProvider; public AuthlibTextureProvider(BlockConfigEntry block) { @@ -49,125 +27,14 @@ } @Override - public synchronized Texture getCloakTexture(UUID uuid, String username) + public synchronized Texture getSkinTexture(UUID uuid, String username) { - return getCached(uuid, username).cloak; + return cacheTextureProvider.getCached(uuid, username, setUuidURL, setProfileURL, "Authlib").skin; } @Override - public synchronized Texture getSkinTexture(UUID uuid, String username) + public synchronized Texture getCloakTexture(UUID uuid, String username) { - return getCached(uuid, username).skin; - } - - private CacheData getCached(UUID uuid, String username) - { - CacheData result = cache.get(username); - - // Have cached result? - if (result != null && System.currentTimeMillis() < result.until) - { - if (result.exc != null) - { - JVMHelper.UNSAFE.throwException(result.exc); - } - return result; - } - - try - { - // TODO Don't query UUID by username if using mojang auth handler (not implemented yet) - URL uuidURL = new URL(setUuidURL + IOHelper.urlEncode(username)); - JsonObject uuidResponse = HTTPRequestHelper.makeAuthlibRequest(uuidURL, null, "Authlib"); - if (uuidResponse == null) - { - throw new IllegalArgumentException("Empty UUID response"); - } - String uuidResolved = uuidResponse.get("id").asString(); - - // Obtain player profile - URL profileURL = new URL(setProfileURL + uuidResolved); - JsonObject profileResponse = HTTPRequestHelper.makeAuthlibRequest(profileURL, null, "Authlib"); - if (profileResponse == null) - { - throw new IllegalArgumentException("Empty Authlib response"); - } - JsonArray properties = (JsonArray) profileResponse.get("properties"); - if (properties == null) - { - LogHelper.subDebug("No properties"); - return cache(username, null, null, null); - } - - // Find textures property - JsonObject texturesProperty = null; - for (JsonValue property : properties) - { - JsonObject property0 = property.asObject(); - if (property0.get("name").asString().equals("textures")) - { - byte[] asBytes = Base64.getDecoder().decode(property0.get("value").asString()); - String asString = new String(asBytes, StandardCharsets.UTF_8); - texturesProperty = Json.parse(asString).asObject(); - break; - } - } - if (texturesProperty == null) - { - LogHelper.subDebug("No textures property"); - return cache(username, null, null, null); - } - - // Extract skin&cloak texture - texturesProperty = (JsonObject) texturesProperty.get("textures"); - JsonObject skinProperty = (JsonObject) texturesProperty.get("SKIN"); - Texture skinTexture = skinProperty == null ? null : new Texture(skinProperty.get("url").asString(), false); - JsonObject cloakProperty = (JsonObject) texturesProperty.get("CAPE"); - Texture cloakTexture = cloakProperty == null ? null : new Texture(cloakProperty.get("url").asString(), true); - - // We're done - return cache(username, skinTexture, cloakTexture, null); - } - catch (Throwable exc) - { - cache(username, null, null, exc); - JVMHelper.UNSAFE.throwException(exc); - } - - // We're dones - return result; - } - - private CacheData cache(String username, Texture skin, Texture cloak, Throwable exc) - { - long until = CACHE_DURATION_MS == 0L ? Long.MIN_VALUE : System.currentTimeMillis() + CACHE_DURATION_MS; - CacheData data = exc == null ? new CacheData(skin, cloak, until) : new CacheData(exc, until); - if (CACHE_DURATION_MS != 0L) - { - cache.put(username, data); - } - return data; - } - - private static final class CacheData - { - private final Texture skin, cloak; - private final Throwable exc; - private final long until; - - private CacheData(Texture skin, Texture cloak, long until) - { - this.skin = skin; - this.cloak = cloak; - this.until = until; - exc = null; - } - - private CacheData(Throwable exc, long until) - { - this.exc = exc; - this.until = until; - skin = cloak = null; - } + return cacheTextureProvider.getCached(uuid, username, setUuidURL, setProfileURL, "Authlib").cloak; } } diff --git a/LaunchServer/source/texture/CacheTextureProvider.java b/LaunchServer/source/texture/CacheTextureProvider.java new file mode 100644 index 0000000..0edd284 --- /dev/null +++ b/LaunchServer/source/texture/CacheTextureProvider.java @@ -0,0 +1,142 @@ +package launchserver.texture; + +import com.eclipsesource.json.Json; +import com.eclipsesource.json.JsonArray; +import com.eclipsesource.json.JsonObject; +import com.eclipsesource.json.JsonValue; +import launcher.LauncherAPI; +import launcher.client.PlayerProfile.Texture; +import launcher.helper.IOHelper; +import launcher.helper.JVMHelper; +import launcher.helper.LogHelper; +import launcher.helper.VerifyHelper; +import launchserver.helpers.HTTPRequestHelper; + +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class CacheTextureProvider +{ + @LauncherAPI + public static final long CACHE_DURATION_MS = VerifyHelper.verifyLong( + Long.parseLong(System.getProperty("launcher.mysql.cacheDurationHours", Integer.toString(24))), + VerifyHelper.L_NOT_NEGATIVE, "launcher.mysql.cacheDurationHours can't be < 0") * 60L * 60L * 1000L; + + // Instance + private final Map cache = new HashMap<>(1024); + + protected CacheData getCached(UUID uuid, String username, String in_usersURL, String in_profileURL, String serviceName) + { + CacheData result = cache.get(username); + + // Have cached result? + if (result != null && System.currentTimeMillis() < result.until) + { + if (result.exc != null) + { + JVMHelper.UNSAFE.throwException(result.exc); + } + return result; + } + + try + { + // TODO Don't query UUID by username if using mojang auth handler (not implemented yet) + URL uuidURL = new URL(in_usersURL + IOHelper.urlEncode(username)); + JsonObject uuidResponse = HTTPRequestHelper.makeAuthlibRequest(uuidURL, null, serviceName); + if (uuidResponse == null) + { + throw new IllegalArgumentException("Empty UUID response"); + } + String uuidResolved = uuidResponse.get("id").asString(); + + // Obtain player profile + URL profileURL = new URL(in_profileURL + uuidResolved); + JsonObject profileResponse = HTTPRequestHelper.makeAuthlibRequest(profileURL, null, serviceName); + if (profileResponse == null) + { + throw new IllegalArgumentException("Empty Authlib response"); + } + JsonArray properties = (JsonArray) profileResponse.get("properties"); + if (properties == null) + { + LogHelper.subDebug("No properties"); + return cache(username, null, null, null); + } + + // Find textures property + JsonObject texturesProperty = null; + for (JsonValue property : properties) + { + JsonObject property0 = property.asObject(); + if (property0.get("name").asString().equals("textures")) + { + byte[] asBytes = Base64.getDecoder().decode(property0.get("value").asString()); + String asString = new String(asBytes, StandardCharsets.UTF_8); + texturesProperty = Json.parse(asString).asObject(); + break; + } + } + if (texturesProperty == null) + { + LogHelper.subDebug("No textures property"); + return cache(username, null, null, null); + } + + // Extract skin&cloak texture + texturesProperty = (JsonObject) texturesProperty.get("textures"); + JsonObject skinProperty = (JsonObject) texturesProperty.get("SKIN"); + Texture skinTexture = skinProperty == null ? null : new Texture(skinProperty.get("url").asString(), false); + JsonObject cloakProperty = (JsonObject) texturesProperty.get("CAPE"); + Texture cloakTexture = cloakProperty == null ? null : new Texture(cloakProperty.get("url").asString(), true); + + // We're done + return cache(username, skinTexture, cloakTexture, null); + } + catch (Throwable exc) + { + cache(username, null, null, exc); + JVMHelper.UNSAFE.throwException(exc); + } + + // We're dones + return result; + } + + private CacheData cache(String username, Texture skin, Texture cloak, Throwable exc) + { + long until = CACHE_DURATION_MS == 0L ? Long.MIN_VALUE : System.currentTimeMillis() + CACHE_DURATION_MS; + CacheData data = exc == null ? new CacheData(skin, cloak, until) : new CacheData(exc, until); + if (CACHE_DURATION_MS != 0L) + { + cache.put(username, data); + } + return data; + } + + protected static final class CacheData + { + protected final Texture skin, cloak; + protected final Throwable exc; + protected final long until; + + private CacheData(Texture skin, Texture cloak, long until) + { + this.skin = skin; + this.cloak = cloak; + this.until = until; + exc = null; + } + + private CacheData(Throwable exc, long until) + { + this.exc = exc; + this.until = until; + skin = cloak = null; + } + } +} diff --git a/LaunchServer/source/texture/ElyByTextureProvider.java b/LaunchServer/source/texture/ElyByTextureProvider.java index 4bca71e..b2b1f04 100644 --- a/LaunchServer/source/texture/ElyByTextureProvider.java +++ b/LaunchServer/source/texture/ElyByTextureProvider.java @@ -1,34 +1,19 @@ package launchserver.texture; import launcher.client.PlayerProfile.Texture; -import launcher.helper.LogHelper; import launcher.serialize.config.entry.BlockConfigEntry; -import java.io.FileNotFoundException; -import java.io.IOException; import java.util.UUID; public class ElyByTextureProvider extends TextureProvider { + protected CacheTextureProvider cacheTextureProvider; + public ElyByTextureProvider(BlockConfigEntry block) { super(block); } - private static Texture getTexture(String url, boolean cloak) throws IOException - { - LogHelper.debug("Getting texture: '%s'", url); - try - { - return new Texture(url, cloak); - } - catch (FileNotFoundException ignored) - { - if (LogHelper.isDebugEnabled()) LogHelper.subDebug("Texture not set or not found! Maybe problem with you proxy!"); - return null; // Simply not found - } - } - @Override public void close() { @@ -36,14 +21,14 @@ } @Override - public Texture getCloakTexture(UUID uuid, String username) throws IOException + public synchronized Texture getSkinTexture(UUID uuid, String username) { - return getTexture(String.format("http://skinsystem.ely.by/cloaks/%s.png", username), true); + return cacheTextureProvider.getCached(uuid, username, "http://skinsystem.ely.by/profile/", "https://sessionserver.minesocial.net/session/minecraft/profile/", "ElyBy").skin; } @Override - public Texture getSkinTexture(UUID uuid, String username) throws IOException + public synchronized Texture getCloakTexture(UUID uuid, String username) { - return getTexture(String.format("http://skinsystem.ely.by/skins/%s.png", username), false); + return cacheTextureProvider.getCached(uuid, username, "http://skinsystem.ely.by/profile/", "https://sessionserver.minesocial.net/session/minecraft/profile/", "ElyBy").cloak; } } diff --git a/LaunchServer/source/texture/MineSocialTextureProvider.java b/LaunchServer/source/texture/MineSocialTextureProvider.java index e396535..6ea5995 100644 --- a/LaunchServer/source/texture/MineSocialTextureProvider.java +++ b/LaunchServer/source/texture/MineSocialTextureProvider.java @@ -1,38 +1,13 @@ package launchserver.texture; -import com.eclipsesource.json.Json; -import com.eclipsesource.json.JsonArray; -import com.eclipsesource.json.JsonObject; -import com.eclipsesource.json.JsonValue; -import launcher.LauncherAPI; -import launcher.client.PlayerProfile; -import launcher.helper.IOHelper; -import launcher.helper.JVMHelper; -import launcher.helper.LogHelper; -import launcher.helper.VerifyHelper; +import launcher.client.PlayerProfile.Texture; import launcher.serialize.config.entry.BlockConfigEntry; -import launchserver.auth.provider.MineSocialAuthProvider; -import launchserver.helpers.HTTPRequestHelper; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.Base64; -import java.util.HashMap; -import java.util.Map; import java.util.UUID; public class MineSocialTextureProvider extends TextureProvider { - @LauncherAPI - public static final long CACHE_DURATION_MS = VerifyHelper.verifyLong( - Long.parseLong( - System.getProperty("launcher.mysql.cacheDurationHours", Integer.toString(24)) - ), - VerifyHelper.L_NOT_NEGATIVE, "launcher.mysql.cacheDurationHours can't be < 0") * 60L * 60L * 1000L; - - // Instance - private final Map cache = new HashMap<>(1024); - + protected CacheTextureProvider cacheTextureProvider; public MineSocialTextureProvider(BlockConfigEntry block) { super(block); @@ -45,124 +20,14 @@ } @Override - public synchronized PlayerProfile.Texture getCloakTexture(UUID uuid, String username) + public synchronized Texture getSkinTexture(UUID uuid, String username) { - return getCached(uuid, username).cloak; + return cacheTextureProvider.getCached(uuid, username, "https://api.minesocial.net/users/profiles/minecraft/", "https://sessionserver.minesocial.net/session/minecraft/profile/", "MineSocial").skin; } @Override - public synchronized PlayerProfile.Texture getSkinTexture(UUID uuid, String username) + public synchronized Texture getCloakTexture(UUID uuid, String username) { - return getCached(uuid, username).skin; - } - - private MineSocialTextureProvider.CacheData getCached(UUID uuid, String username) - { - MineSocialTextureProvider.CacheData result = cache.get(username); - - // Have cached result? - if (result != null && System.currentTimeMillis() < result.until) - { - if (result.exc != null) - { - JVMHelper.UNSAFE.throwException(result.exc); - } - return result; - } - - try - { - URL uuidURL = new URL("https://api.minesocial.net/users/profiles/minecraft/" + IOHelper.urlEncode(username)); - JsonObject uuidResponse = HTTPRequestHelper.makeAuthlibRequest(uuidURL, null, "MineSocial"); - if (uuidResponse == null) - { - throw new IllegalArgumentException("Empty MineSocial UUID response!"); - } - String uuidResolved = uuidResponse.get("id").asString(); - - // Obtain player profile - URL profileURL = new URL("https://sessionserver.minesocial.net/session/minecraft/profile/" + uuidResolved); - JsonObject profileResponse = HTTPRequestHelper.makeAuthlibRequest(profileURL, null, "MineSocial"); - if (profileResponse == null) - { - throw new IllegalArgumentException("Empty MineSocial profile response!"); - } - JsonArray properties = (JsonArray) profileResponse.get("properties"); - if (properties == null) - { - LogHelper.subDebug("Not get MineSocial properties!"); - return cache(username, null, null, null); - } - - // Find textures property - JsonObject texturesProperty = null; - for (JsonValue property : properties) - { - JsonObject property0 = property.asObject(); - if (property0.get("name").asString().equals("textures")) - { - byte[] asBytes = Base64.getDecoder().decode(property0.get("value").asString()); - String asString = new String(asBytes, StandardCharsets.UTF_8); - texturesProperty = Json.parse(asString).asObject(); - break; - } - } - if (texturesProperty == null) - { - LogHelper.subDebug("Not get MineSocial textures property!"); - return cache(username, null, null, null); - } - - // Extract skin&cloak texture - texturesProperty = (JsonObject) texturesProperty.get("textures"); - JsonObject skinProperty = (JsonObject) texturesProperty.get("SKIN"); - PlayerProfile.Texture skinTexture = skinProperty == null ? null : new PlayerProfile.Texture(skinProperty.get("url").asString(), false); - JsonObject cloakProperty = (JsonObject) texturesProperty.get("CAPE"); - PlayerProfile.Texture cloakTexture = cloakProperty == null ? null : new PlayerProfile.Texture(cloakProperty.get("url").asString(), true); - - // We're done - return cache(username, skinTexture, cloakTexture, null); - } - catch (Throwable exc) - { - cache(username, null, null, exc); - JVMHelper.UNSAFE.throwException(exc); - } - - // We're dones - return result; - } - - private MineSocialTextureProvider.CacheData cache(String username, PlayerProfile.Texture skin, PlayerProfile.Texture cloak, Throwable exc) - { - long until = CACHE_DURATION_MS == 0L ? Long.MIN_VALUE : System.currentTimeMillis() + CACHE_DURATION_MS; - MineSocialTextureProvider.CacheData data = exc == null ? new MineSocialTextureProvider.CacheData(skin, cloak, until) : new MineSocialTextureProvider.CacheData(exc, until); - if (CACHE_DURATION_MS != 0L) - { - cache.put(username, data); - } - return data; - } - - private static final class CacheData - { - private final PlayerProfile.Texture skin, cloak; - private final Throwable exc; - private final long until; - - private CacheData(PlayerProfile.Texture skin, PlayerProfile.Texture cloak, long until) - { - this.skin = skin; - this.cloak = cloak; - this.until = until; - exc = null; - } - - private CacheData(Throwable exc, long until) - { - this.exc = exc; - this.until = until; - skin = cloak = null; - } + return cacheTextureProvider.getCached(uuid, username, "https://api.minesocial.net/users/profiles/minecraft/", "https://sessionserver.minesocial.net/session/minecraft/profile/", "MineSocial").cloak; } } diff --git a/LaunchServer/source/texture/MojangTextureProvider.java b/LaunchServer/source/texture/MojangTextureProvider.java index cd5be61..b2d5b25 100644 --- a/LaunchServer/source/texture/MojangTextureProvider.java +++ b/LaunchServer/source/texture/MojangTextureProvider.java @@ -1,40 +1,19 @@ package launchserver.texture; -import com.eclipsesource.json.Json; -import com.eclipsesource.json.JsonArray; -import com.eclipsesource.json.JsonObject; -import com.eclipsesource.json.JsonValue; -import launcher.LauncherAPI; import launcher.client.PlayerProfile.Texture; -import launcher.helper.IOHelper; -import launcher.helper.JVMHelper; -import launcher.helper.LogHelper; -import launcher.helper.VerifyHelper; import launcher.serialize.config.entry.BlockConfigEntry; -import launchserver.helpers.HTTPRequestHelper; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.Base64; -import java.util.HashMap; -import java.util.Map; import java.util.UUID; public final class MojangTextureProvider extends TextureProvider { - @LauncherAPI - public static final long CACHE_DURATION_MS = VerifyHelper.verifyLong( - Long.parseLong(System.getProperty("launcher.mysql.cacheDurationHours", Integer.toString(24))), - VerifyHelper.L_NOT_NEGATIVE, "launcher.mysql.cacheDurationHours can't be < 0") * 60L * 60L * 1000L; - - // Instance - private final Map cache = new HashMap<>(1024); - public MojangTextureProvider(BlockConfigEntry block) { super(block); } + protected CacheTextureProvider cacheTextureProvider; + @Override public void close() { @@ -42,125 +21,14 @@ } @Override - public synchronized Texture getCloakTexture(UUID uuid, String username) + public synchronized Texture getSkinTexture(UUID uuid, String username) { - return getCached(uuid, username).cloak; + return cacheTextureProvider.getCached(uuid, username, "https://api.mojang.com/users/profiles/minecraft/", "https://sessionserver.mojang.com/session/minecraft/profile/", "Mojang").skin; } @Override - public synchronized Texture getSkinTexture(UUID uuid, String username) + public synchronized Texture getCloakTexture(UUID uuid, String username) { - return getCached(uuid, username).skin; - } - - private CacheData getCached(UUID uuid, String username) - { - CacheData result = cache.get(username); - - // Have cached result? - if (result != null && System.currentTimeMillis() < result.until) - { - if (result.exc != null) - { - JVMHelper.UNSAFE.throwException(result.exc); - } - return result; - } - - try - { - // TODO Don't query UUID by username if using mojang auth handler (not implemented yet) - URL uuidURL = new URL("https://api.mojang.com/users/profiles/minecraft/" + IOHelper.urlEncode(username)); - JsonObject uuidResponse = HTTPRequestHelper.makeAuthlibRequest(uuidURL, null, "Mojang"); - if (uuidResponse == null) - { - throw new IllegalArgumentException("Empty UUID response"); - } - String uuidResolved = uuidResponse.get("id").asString(); - - // Obtain player profile - URL profileURL = new URL("https://sessionserver.mojang.com/session/minecraft/profile/" + uuidResolved); - JsonObject profileResponse = HTTPRequestHelper.makeAuthlibRequest(profileURL, null, "Mojang"); - if (profileResponse == null) - { - throw new IllegalArgumentException("Empty Mojang response"); - } - JsonArray properties = (JsonArray) profileResponse.get("properties"); - if (properties == null) - { - LogHelper.subDebug("No properties"); - return cache(username, null, null, null); - } - - // Find textures property - JsonObject texturesProperty = null; - for (JsonValue property : properties) - { - JsonObject property0 = property.asObject(); - if (property0.get("name").asString().equals("textures")) - { - byte[] asBytes = Base64.getDecoder().decode(property0.get("value").asString()); - String asString = new String(asBytes, StandardCharsets.UTF_8); - texturesProperty = Json.parse(asString).asObject(); - break; - } - } - if (texturesProperty == null) - { - LogHelper.subDebug("No textures property"); - return cache(username, null, null, null); - } - - // Extract skin&cloak texture - texturesProperty = (JsonObject) texturesProperty.get("textures"); - JsonObject skinProperty = (JsonObject) texturesProperty.get("SKIN"); - Texture skinTexture = skinProperty == null ? null : new Texture(skinProperty.get("url").asString(), false); - JsonObject cloakProperty = (JsonObject) texturesProperty.get("CAPE"); - Texture cloakTexture = cloakProperty == null ? null : new Texture(cloakProperty.get("url").asString(), true); - - // We're done - return cache(username, skinTexture, cloakTexture, null); - } - catch (Throwable exc) - { - cache(username, null, null, exc); - JVMHelper.UNSAFE.throwException(exc); - } - - // We're dones - return result; - } - - private CacheData cache(String username, Texture skin, Texture cloak, Throwable exc) - { - long until = CACHE_DURATION_MS == 0L ? Long.MIN_VALUE : System.currentTimeMillis() + CACHE_DURATION_MS; - CacheData data = exc == null ? new CacheData(skin, cloak, until) : new CacheData(exc, until); - if (CACHE_DURATION_MS != 0L) - { - cache.put(username, data); - } - return data; - } - - private static final class CacheData - { - private final Texture skin, cloak; - private final Throwable exc; - private final long until; - - private CacheData(Texture skin, Texture cloak, long until) - { - this.skin = skin; - this.cloak = cloak; - this.until = until; - exc = null; - } - - private CacheData(Throwable exc, long until) - { - this.exc = exc; - this.until = until; - skin = cloak = null; - } + return cacheTextureProvider.getCached(uuid, username, "https://api.mojang.com/users/profiles/minecraft/", "https://sessionserver.mojang.com/session/minecraft/profile/", "Mojang").cloak; } } diff --git a/LaunchServer/source/texture/RequestTextureProvider.java b/LaunchServer/source/texture/RequestTextureProvider.java index 1b678bd..81a6712 100644 --- a/LaunchServer/source/texture/RequestTextureProvider.java +++ b/LaunchServer/source/texture/RequestTextureProvider.java @@ -58,14 +58,14 @@ } @Override - public Texture getCloakTexture(UUID uuid, String username) throws IOException - { - return getTexture(getTextureURL(cloakURL, uuid, username), true); - } - - @Override public Texture getSkinTexture(UUID uuid, String username) throws IOException { return getTexture(getTextureURL(skinURL, uuid, username), false); } + + @Override + public Texture getCloakTexture(UUID uuid, String username) throws IOException + { + return getTexture(getTextureURL(cloakURL, uuid, username), true); + } }