From cddca0e1ea92f2faae5dc42f6b936a54847583ce Mon Sep 17 00:00:00 2001 From: Sollace Date: Fri, 10 Aug 2018 12:28:18 +0200 Subject: [PATCH] Format this to better convery what it's _trying_ to do. Killjoy pls --- .../voxelmodpack/hdskins/HDSkinManager.java | 104 +++++++++--------- .../hdskins/ImageBufferDownloadHD.java | 12 ++ .../voxelmodpack/hdskins/PreviewTexture.java | 19 +++- .../hdskins/PreviewTextureManager.java | 41 +++---- .../hdskins/ThreadDownloadImageETag.java | 80 +++++++------- .../hdskins/resource/SkinResourceManager.java | 72 ++++++------ 6 files changed, 170 insertions(+), 158 deletions(-) diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java b/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java index d60f0203..cce3a57d 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java @@ -26,7 +26,6 @@ import com.voxelmodpack.hdskins.skins.SkinServer; import com.voxelmodpack.hdskins.skins.ValhallaSkinServer; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.IImageBuffer; -import net.minecraft.client.renderer.texture.ITextureObject; import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.client.resources.DefaultPlayerSkin; import net.minecraft.client.resources.IResourceManager; @@ -88,12 +87,10 @@ public final class HDSkinManager implements IResourceManagerReloadListener { private List skinModifiers = Lists.newArrayList(); private SkinResourceManager resources = new SkinResourceManager(); - // private ExecutorService executor = Executors.newCachedThreadPool(); private Class skinsClass = null; private HDSkinManager() { - // register default skin server types addSkinServerType(LegacySkinServer.class); addSkinServerType(ValhallaSkinServer.class); @@ -173,46 +170,40 @@ public final class HDSkinManager implements IResourceManagerReloadListener { return url + (url.indexOf('?') > -1 ? '&' : '?') + Long.toString(new Date().getTime() / 1000); } - private void loadTexture(GameProfile profile, final Type type, final SkinAvailableCallback callback) { - if (profile.getId() != null) { - Map data = getProfileData(profile); - final MinecraftProfileTexture texture = data.get(type); - - String skinDir = type.toString().toLowerCase() + "s/"; - final ResourceLocation skin = new ResourceLocation("hdskins", skinDir + texture.getHash()); - File file2 = new File(LiteLoader.getAssetsDirectory(), "hd/" + skinDir + texture.getHash().substring(0, 2) + "/" + texture.getHash()); - - final IImageBuffer imagebufferdownload = type == Type.SKIN ? new ImageBufferDownloadHD() : null; - - ITextureObject texObject = new ThreadDownloadImageETag(file2, bustCache(texture.getUrl()), - DefaultPlayerSkin.getDefaultSkinLegacy(), - new IImageBuffer() { - @Nonnull - @Override - public BufferedImage parseUserSkin(@Nonnull BufferedImage image) { - BufferedImage image1 = image; - if (imagebufferdownload != null) { - image1 = imagebufferdownload.parseUserSkin(image); - } - return image1 == null ? image : image1; - } - - @Override - public void skinAvailable() { - if (imagebufferdownload != null) { - imagebufferdownload.skinAvailable(); - } - callback.skinAvailable(type, skin, texture); - } - }); - - // schedule texture loading on the main thread. - TextureLoader.loadTexture(skin, texObject); + private void loadTexture(GameProfile profile, Type type, SkinAvailableCallback callback) { + if (profile.getId() == null) { + return; } + + MinecraftProfileTexture texture = getProfileData(profile).get(type); + + String skinDir = type.toString().toLowerCase() + "s/"; + + ResourceLocation skin = new ResourceLocation("hdskins", skinDir + texture.getHash()); + + File etag = new File(LiteLoader.getAssetsDirectory(), "hd/" + skinDir + texture.getHash().substring(0, 2) + "/" + texture.getHash()); + + IImageBuffer buffer = new ImageBufferDownloadHD() { + @Nonnull + @Override + public BufferedImage parseUserSkin(@Nonnull BufferedImage image) { + if (type != Type.SKIN) { + return image; + } + + BufferedImage converted = super.parseUserSkin(image); + + return converted == null ? image : converted; + } + }.withCallback(() -> callback.skinAvailable(type, skin, texture)); + + // schedule texture loading on the main thread. + TextureLoader.loadTexture(skin, new ThreadDownloadImageETag(etag, bustCache(texture.getUrl()), DefaultPlayerSkin.getDefaultSkinLegacy(), buffer)); } private Map loadProfileData(GameProfile profile) { Map textures = Maps.newEnumMap(Type.class); + for (SkinServer server : skinServers) { try { server.loadProfileData(profile).getTextures().forEach(textures::putIfAbsent); @@ -222,43 +213,47 @@ public final class HDSkinManager implements IResourceManagerReloadListener { } catch (IOException e) { LogManager.getLogger().trace(e); } - } + return textures; } public Map getProfileData(GameProfile profile) { boolean was = !skins.asMap().containsKey(profile); + Map textures = skins.getUnchecked(profile); + // This is the initial value. Refreshing will load it asynchronously. if (was) { skins.refresh(profile); } + return textures; } public void addSkinServerType(Class type) { Preconditions.checkArgument(!type.isInterface(), "type cannot be an interface"); Preconditions.checkArgument(!Modifier.isAbstract(type.getModifiers()), "type cannot be abstract"); + ServerType st = type.getAnnotation(ServerType.class); - if (st == null) { - throw new IllegalArgumentException("class is not annotated with @ServerType"); - } - this.skinServerTypes.put(st.value(), type); + + Preconditions.checkArgument(st != null, "class is not annotated with @ServerType"); + + skinServerTypes.put(st.value(), type); } public Class getSkinServerClass(String type) { - return this.skinServerTypes.get(type); + return skinServerTypes.get(type); } public void addSkinServer(SkinServer skinServer) { - this.skinServers.add(skinServer); + skinServers.add(skinServer); } // TODO: Why is this deprecated? @Deprecated public SkinServer getGatewayServer() { - return this.skinServers.get(0); + return skinServers.get(0); } public void setEnabled(boolean enabled) { @@ -266,7 +261,9 @@ public final class HDSkinManager implements IResourceManagerReloadListener { } public static CompletableFuture getPreviewTextureManager(GameProfile profile) { - return INSTANCE.getGatewayServer().getPreviewTextures(profile).thenApply(PreviewTextureManager::new); + return INSTANCE.getGatewayServer().getPreviewTextures(profile).thenApply(mcu -> { + return new PreviewTextureManager(mcu.getTextures()); + }); } public void addClearListener(ISkinCacheClearListener listener) { @@ -279,6 +276,7 @@ public final class HDSkinManager implements IResourceManagerReloadListener { try { FileUtils.deleteDirectory(new File(LiteLoader.getAssetsDirectory(), "skins")); FileUtils.deleteDirectory(new File(LiteLoader.getAssetsDirectory(), "hd")); + TextureManager textures = Minecraft.getMinecraft().getTextureManager(); skinCache.values().stream() .flatMap(m -> m.values().stream()) @@ -313,14 +311,18 @@ public final class HDSkinManager implements IResourceManagerReloadListener { return loc == null ? res : loc; } + public void convertSkin(BufferedImage image) { + Graphics graphics = image.getGraphics(); + convertSkin(image, graphics); + graphics.dispose(); + } + public void convertSkin(BufferedImage image, Graphics dest) { - for (ISkinModifier skin : skinModifiers) { - skin.convertSkin(image, dest); - } + skinModifiers.forEach(a -> a.convertSkin(image, dest)); } @Override public void onResourceManagerReload(IResourceManager resourceManager) { - this.resources.onResourceManagerReload(resourceManager); + resources.onResourceManagerReload(resourceManager); } } diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/ImageBufferDownloadHD.java b/src/hdskins/java/com/voxelmodpack/hdskins/ImageBufferDownloadHD.java index a8257be3..7829408d 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/ImageBufferDownloadHD.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/ImageBufferDownloadHD.java @@ -3,6 +3,7 @@ package com.voxelmodpack.hdskins; import net.minecraft.client.renderer.IImageBuffer; import javax.annotation.Nullable; + import java.awt.Graphics; import java.awt.image.BufferedImage; @@ -12,6 +13,13 @@ public class ImageBufferDownloadHD implements IImageBuffer { private Graphics graphics; private BufferedImage image; + private Runnable callback; + + public ImageBufferDownloadHD withCallback(Runnable callback) { + this.callback = callback; + return this; + } + @Override @Nullable @SuppressWarnings({"SuspiciousNameCombination", "NullableProblems"}) @@ -19,6 +27,7 @@ public class ImageBufferDownloadHD implements IImageBuffer { if (downloadedImage == null) { return null; } + int imageWidth = downloadedImage.getWidth(); int imageHeight = downloadedImage.getHeight(); if (imageHeight == imageWidth) { @@ -61,5 +70,8 @@ public class ImageBufferDownloadHD implements IImageBuffer { @Override public void skinAvailable() { + if (callback != null) { + callback.run(); + } } } diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/PreviewTexture.java b/src/hdskins/java/com/voxelmodpack/hdskins/PreviewTexture.java index e5430ee2..8db435a8 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/PreviewTexture.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/PreviewTexture.java @@ -6,26 +6,31 @@ import net.minecraft.util.ResourceLocation; import javax.annotation.Nullable; +import com.mojang.authlib.minecraft.MinecraftProfileTexture; + public class PreviewTexture extends ThreadDownloadImageData { private boolean uploaded; private String model; - public PreviewTexture(@Nullable String model, String url, ResourceLocation fallbackTexture, @Nullable IImageBuffer imageBuffer) { - super(null, url, fallbackTexture, imageBuffer); + public PreviewTexture(MinecraftProfileTexture texture, ResourceLocation fallbackTexture, @Nullable IImageBuffer imageBuffer) { + super(null, texture.getUrl(), fallbackTexture, imageBuffer); - this.model = model == null ? "default" : model; + model = texture.getMetadata("model"); + if (model == null) { + model = "default"; + } } public boolean isTextureUploaded() { - return uploaded && this.getGlTextureId() > -1; + return uploaded && getGlTextureId() > -1; } @Override public void deleteGlTexture() { super.deleteGlTexture(); - this.uploaded = true; + uploaded = true; } public boolean hasModel() { @@ -35,4 +40,8 @@ public class PreviewTexture extends ThreadDownloadImageData { public boolean usesThinArms() { return "thin".equals(model); } + + public String getModel() { + return model; + } } diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/PreviewTextureManager.java b/src/hdskins/java/com/voxelmodpack/hdskins/PreviewTextureManager.java index 18cf587d..4b5ccd8d 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/PreviewTextureManager.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/PreviewTextureManager.java @@ -2,12 +2,13 @@ package com.voxelmodpack.hdskins; import com.google.common.collect.Maps; import com.mojang.authlib.minecraft.MinecraftProfileTexture; -import com.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload; +import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type; + +import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.IImageBuffer; -import net.minecraft.client.resources.SkinManager; +import net.minecraft.client.resources.SkinManager.SkinAvailableCallback; import net.minecraft.util.ResourceLocation; -import java.awt.image.BufferedImage; import java.util.Map; import javax.annotation.Nullable; @@ -18,37 +19,29 @@ import javax.annotation.Nullable; */ public class PreviewTextureManager { - private final Map textures; + private final Map textures; - PreviewTextureManager(MinecraftTexturesPayload payload) { - this.textures = payload.getTextures(); + PreviewTextureManager(Map textures) { + this.textures = textures; } @Nullable - public PreviewTexture getPreviewTexture(ResourceLocation location, MinecraftProfileTexture.Type type, ResourceLocation def, - @Nullable SkinManager.SkinAvailableCallback callback) { + public PreviewTexture getPreviewTexture(ResourceLocation location, Type type, ResourceLocation def, @Nullable SkinAvailableCallback callback) { if (!textures.containsKey(type)) { return null; } + MinecraftProfileTexture texture = textures.get(type); - IImageBuffer buffer = new ImageBufferDownloadHD(); - PreviewTexture skinTexture = new PreviewTexture(texture.getMetadata("model"), texture.getUrl(), def, - type == MinecraftProfileTexture.Type.SKIN ? new IImageBuffer() { - @Override - @Nullable - public BufferedImage parseUserSkin(BufferedImage image) { - return buffer.parseUserSkin(image); - } - @Override - public void skinAvailable() { - if (callback != null) { - callback.skinAvailable(type, location, new MinecraftProfileTexture(texture.getUrl(), Maps.newHashMap())); - } - } - } : null); + IImageBuffer buffer = type != Type.SKIN ? null : new ImageBufferDownloadHD().withCallback(() -> { + if (callback != null) { + callback.skinAvailable(type, location, new MinecraftProfileTexture(texture.getUrl(), Maps.newHashMap())); + } + }); - TextureLoader.loadTexture(location, skinTexture); + PreviewTexture skinTexture = new PreviewTexture(texture, def, buffer); + + Minecraft.getMinecraft().getTextureManager().loadTexture(location, skinTexture); return skinTexture; } diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/ThreadDownloadImageETag.java b/src/hdskins/java/com/voxelmodpack/hdskins/ThreadDownloadImageETag.java index 514aac1a..51b7aa71 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/ThreadDownloadImageETag.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/ThreadDownloadImageETag.java @@ -2,6 +2,9 @@ package com.voxelmodpack.hdskins; import com.google.common.base.Charsets; import com.google.common.io.Files; +import com.voxelmodpack.hdskins.skins.MoreHttpResponses; +import com.voxelmodpack.hdskins.skins.NetClient; + import net.minecraft.client.renderer.IImageBuffer; import net.minecraft.client.renderer.texture.SimpleTexture; import net.minecraft.client.renderer.texture.TextureUtil; @@ -10,12 +13,8 @@ import net.minecraft.util.ResourceLocation; import org.apache.commons.io.FileUtils; import org.apache.http.Header; import org.apache.http.HttpHeaders; -import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; -import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.util.EntityUtils; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -36,46 +35,48 @@ public class ThreadDownloadImageETag extends SimpleTexture { private final File cacheFile; private final File eTagFile; private final String imageUrl; + @Nullable private final IImageBuffer imageBuffer; @Nullable private BufferedImage bufferedImage; + @Nullable private Thread imageThread; private boolean textureUploaded; - public ThreadDownloadImageETag(@Nonnull File cacheFileIn, String imageUrlIn, ResourceLocation defLocation, @Nullable IImageBuffer imageBufferIn) { - super(defLocation); - this.cacheFile = cacheFileIn; - this.eTagFile = new File(cacheFile.getParentFile(), cacheFile.getName() + ".etag"); - this.imageUrl = imageUrlIn; - this.imageBuffer = imageBufferIn; + public ThreadDownloadImageETag(@Nonnull File cacheLocation, String url, ResourceLocation def, @Nullable IImageBuffer buffer) { + super(def); + cacheFile = cacheLocation; + eTagFile = new File(cacheFile.getParentFile(), cacheFile.getName() + ".etag"); + imageUrl = url; + imageBuffer = buffer; } private void checkTextureUploaded() { - if (!this.textureUploaded) { - if (this.bufferedImage != null) { - if (this.textureLocation != null) { - this.deleteGlTexture(); + if (!textureUploaded) { + if (bufferedImage != null) { + if (textureLocation != null) { + deleteGlTexture(); } - TextureUtil.uploadTextureImage(super.getGlTextureId(), this.bufferedImage); - this.textureUploaded = true; + TextureUtil.uploadTextureImage(super.getGlTextureId(), bufferedImage); + textureUploaded = true; } } } public int getGlTextureId() { - this.checkTextureUploaded(); + checkTextureUploaded(); return super.getGlTextureId(); } private void setBufferedImage(@Nonnull BufferedImage bufferedImageIn) { - this.bufferedImage = bufferedImageIn; + bufferedImage = bufferedImageIn; - if (this.imageBuffer != null) { - this.imageBuffer.skinAvailable(); + if (imageBuffer != null) { + imageBuffer.skinAvailable(); } } @@ -85,24 +86,20 @@ public class ThreadDownloadImageETag extends SimpleTexture { } public void loadTexture(IResourceManager resourceManager) throws IOException { - if (this.bufferedImage == null && this.textureLocation != null) { + if (bufferedImage == null && textureLocation != null) { super.loadTexture(resourceManager); } - if (this.imageThread == null) { - this.imageThread = new Thread(this::loadTexture, "Texture Downloader #" + THREAD_ID.incrementAndGet()); - this.imageThread.setDaemon(true); - this.imageThread.start(); + if (imageThread == null) { + imageThread = new Thread(this::loadTexture, "Texture Downloader #" + THREAD_ID.incrementAndGet()); + imageThread.setDaemon(true); + imageThread.start(); } } private void loadTexture() { - HttpResponse response = null; - try { - HttpClient client = HttpClientBuilder.create().build(); - response = client.execute(new HttpGet(imageUrl)); - int status = response.getStatusLine().getStatusCode(); - if (status == HttpStatus.SC_NOT_FOUND) { + try (MoreHttpResponses response = new NetClient("GET", imageUrl).send()) { + if (response.getResponseCode() == HttpStatus.SC_NOT_FOUND) { // delete the cache files in case we can't connect in the future clearCache(); } else if (checkETag(response)) { @@ -132,9 +129,6 @@ public class ThreadDownloadImageETag extends SimpleTexture { } } LOGGER.error("Couldn't load skin {} ", imageUrl, e); - } finally { - if (response != null) - EntityUtils.consumeQuietly(response.getEntity()); } } @@ -149,15 +143,15 @@ public class ThreadDownloadImageETag extends SimpleTexture { } private void clearCache() { - FileUtils.deleteQuietly(this.cacheFile); - FileUtils.deleteQuietly(this.eTagFile); + FileUtils.deleteQuietly(cacheFile); + FileUtils.deleteQuietly(eTagFile); } - private boolean checkETag(HttpResponse response) { + private boolean checkETag(MoreHttpResponses response) { try { if (cacheFile.isFile()) { String localETag = Files.readFirstLine(eTagFile, Charsets.UTF_8); - Header remoteETag = response.getFirstHeader(HttpHeaders.ETAG); + Header remoteETag = response.getResponse().getFirstHeader(HttpHeaders.ETAG); // true if no remote etag or does match return remoteETag == null || localETag.equals(remoteETag.getValue()); } @@ -168,18 +162,18 @@ public class ThreadDownloadImageETag extends SimpleTexture { } } - private void loadTextureFromServer(HttpResponse response) { + private void loadTextureFromServer(MoreHttpResponses response) { LOGGER.debug("Downloading http texture from {} to {}", imageUrl, cacheFile); try { - if (response.getStatusLine().getStatusCode() / 100 == 2) { + if (response.ok()) { BufferedImage bufferedimage; // write the image to disk - FileUtils.copyInputStreamToFile(response.getEntity().getContent(), cacheFile); + FileUtils.copyInputStreamToFile(response.getInputStream(), cacheFile); bufferedimage = ImageIO.read(cacheFile); // maybe write the etag to disk - Header eTag = response.getFirstHeader(HttpHeaders.ETAG); + Header eTag = response.getResponse().getFirstHeader(HttpHeaders.ETAG); if (eTag != null) { FileUtils.write(eTagFile, eTag.getValue(), Charsets.UTF_8); } diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/resource/SkinResourceManager.java b/src/hdskins/java/com/voxelmodpack/hdskins/resource/SkinResourceManager.java index d02b22df..59999b75 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/resource/SkinResourceManager.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/resource/SkinResourceManager.java @@ -17,6 +17,7 @@ import javax.annotation.Nullable; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.util.List; import java.util.Map; import java.util.UUID; import java.util.concurrent.CompletableFuture; @@ -25,6 +26,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; public class SkinResourceManager implements IResourceManagerReloadListener { + private final Gson GSON = new Gson(); private ExecutorService executor = Executors.newSingleThreadExecutor(); @@ -41,15 +43,16 @@ public class SkinResourceManager implements IResourceManagerReloadListener { executor = Executors.newSingleThreadExecutor(); inProgress.clear(); converted.clear(); + for (String domain : resourceManager.getResourceDomains()) { try { for (IResource res : resourceManager.getAllResources(new ResourceLocation(domain, "textures/skins/skins.json"))) { try { - SkinData data = getSkinData(res.getInputStream()); - for (Skin s : data.skins) { + for (Skin s : getSkinData(res.getInputStream())) { if (s.uuid != null) { uuidSkins.put(s.uuid, s); } + if (s.name != null) { namedSkins.put(s.name, s); } @@ -58,16 +61,13 @@ public class SkinResourceManager implements IResourceManagerReloadListener { LiteLoaderLogger.warning(je, "Invalid skins.json in %s", res.getResourcePackName()); } } - } catch (IOException e) { - // ignore - } + } catch (IOException ignored) { } } - } - private SkinData getSkinData(InputStream stream) { + private List getSkinData(InputStream stream) { try { - return new Gson().fromJson(new InputStreamReader(stream), SkinData.class); + return GSON.fromJson(new InputStreamReader(stream), SkinData.class).skins; } finally { IOUtils.closeQuietly(stream); } @@ -75,16 +75,14 @@ public class SkinResourceManager implements IResourceManagerReloadListener { @Nullable public ResourceLocation getPlayerTexture(GameProfile profile, Type type) { - if (type != Type.SKIN) - // not supported - return null; - - Skin skin = getSkin(profile); - if (skin != null) { - final ResourceLocation res = skin.getTexture(); - return getConvertedResource(res); + if (type == Type.SKIN) { + Skin skin = getSkin(profile); + if (skin != null) { + return getConvertedResource(skin.getTexture()); + } } - return null; + + return null; // not supported } /** @@ -99,31 +97,35 @@ public class SkinResourceManager implements IResourceManagerReloadListener { return converted.get(res); } - private void loadSkinResource(@Nullable final ResourceLocation res) { + /** + * read and convert in a new thread + */ + private void loadSkinResource(@Nullable ResourceLocation res) { if (res != null) { - // read and convert in a new thread - this.inProgress.computeIfAbsent(res, r -> CompletableFuture.supplyAsync(new ImageLoader(r), executor) - .whenComplete((loc, t) -> { - if (loc != null) - converted.put(res, loc); - else { - LogManager.getLogger().warn("Errored while processing {}. Using original.", res, t); - converted.put(res, res); - } - })); - - + if (!inProgress.containsKey(res)) { + inProgress.put(res, scheduleConvertion(res)); + } } + } + private Future scheduleConvertion(ResourceLocation res) { + return CompletableFuture.supplyAsync(new ImageLoader(res), executor).whenComplete((result, error) -> { + if (result == null) { + result = res; + LogManager.getLogger().warn("Errored while processing {}. Using original.", res, error); + } + + converted.put(res, result); + }); } @Nullable private Skin getSkin(GameProfile profile) { - Skin skin = this.uuidSkins.get(profile.getId()); - if (skin == null) { - skin = this.namedSkins.get(profile.getName()); + Skin skin = uuidSkins.get(profile.getId()); + if (skin != null) { + return skin; } - return skin; - } + return namedSkins.get(profile.getName()); + } }