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