mirror of
https://github.com/MineLittlePony/MineLittlePony.git
synced 2024-11-22 12:37:59 +01:00
Use an etag for caching instead of md5.
Release for 1.11.2
This commit is contained in:
parent
50e29823d7
commit
e87c550f2b
7 changed files with 183 additions and 47 deletions
|
@ -24,7 +24,7 @@ apply plugin: 'net.minecraftforge.gradle.liteloader'
|
|||
apply plugin: 'org.spongepowered.mixin'
|
||||
|
||||
group = 'com.minelittlepony'
|
||||
version = '1.11.2.0-SNAPSHOT'
|
||||
version = '1.11.2.0'
|
||||
description = 'Mine Little Pony'
|
||||
|
||||
targetCompatibility = 1.8
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#Build Number for ANT. Do not edit!
|
||||
#Sat Dec 24 04:16:32 EST 2016
|
||||
build.number=295
|
||||
#Tue Dec 27 18:55:42 EST 2016
|
||||
build.number=300
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
package com.voxelmodpack.hdskins;
|
||||
|
||||
import com.mojang.authlib.minecraft.MinecraftProfileTexture;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Profile texture with a custom hash which is not the file name.
|
||||
*/
|
||||
public class HDProfileTexture extends MinecraftProfileTexture {
|
||||
|
||||
private String hash;
|
||||
|
||||
public HDProfileTexture(String url, @Nullable String hash, Map<String, String> metadata) {
|
||||
super(url, metadata);
|
||||
this.hash = hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHash() {
|
||||
return this.hash == null ? super.getHash() : this.hash;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,12 +1,10 @@
|
|||
package com.voxelmodpack.hdskins;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.io.Resources;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
@ -21,7 +19,6 @@ import com.mumfrey.liteloader.util.log.LiteLoaderLogger;
|
|||
import com.voxelmodpack.hdskins.resource.SkinResourceManager;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.IImageBuffer;
|
||||
import net.minecraft.client.renderer.ThreadDownloadImageData;
|
||||
import net.minecraft.client.renderer.texture.ITextureObject;
|
||||
import net.minecraft.client.renderer.texture.TextureManager;
|
||||
import net.minecraft.client.resources.DefaultPlayerSkin;
|
||||
|
@ -38,7 +35,6 @@ import java.awt.*;
|
|||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
@ -127,9 +123,11 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
|
|||
|
||||
String skinDir = type.toString().toLowerCase() + "s/";
|
||||
final ResourceLocation skin = new ResourceLocation("hdskins", skinDir + texture.getHash());
|
||||
File file2 = new File(LiteLoader.getAssetsDirectory(), "skins/" + skinDir + texture.getHash().substring(0, 2) + "/" + 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;
|
||||
ThreadDownloadImageData threaddownloadimagedata = new ThreadDownloadImageData(file2, texture.getUrl(),
|
||||
|
||||
ITextureObject texObject = new ThreadDownloadImageETag(file2, texture.getUrl(),
|
||||
DefaultPlayerSkin.getDefaultSkinLegacy(),
|
||||
new IImageBuffer() {
|
||||
@Nonnull
|
||||
|
@ -152,7 +150,7 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
|
|||
});
|
||||
|
||||
// schedule texture loading on the main thread.
|
||||
TextureLoader.loadTexture(skin, threaddownloadimagedata);
|
||||
TextureLoader.loadTexture(skin, texObject);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,9 +169,8 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
|
|||
ImmutableMap.Builder<Type, MinecraftProfileTexture> builder = ImmutableMap.builder();
|
||||
for (Type type : Type.values()) {
|
||||
String url = getCustomTextureURLForId(type, uuid);
|
||||
String hash = getTextureHash(type, uuid);
|
||||
|
||||
builder.put(type, new HDProfileTexture(url, hash, null));
|
||||
builder.put(type, new MinecraftProfileTexture(url, null));
|
||||
}
|
||||
|
||||
Map<Type, MinecraftProfileTexture> textures = builder.build();
|
||||
|
@ -224,15 +221,6 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
|
|||
return getCustomTextureURLForId(type, uuid, false);
|
||||
}
|
||||
|
||||
private String getTextureHash(Type type, String uuid) {
|
||||
try {
|
||||
URL url = new URL(getCustomTextureURLForId(type, uuid) + ".md5");
|
||||
return Resources.asCharSource(url, Charsets.UTF_8).readFirstLine();
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
package com.voxelmodpack.hdskins;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.io.Files;
|
||||
import net.minecraft.client.renderer.IImageBuffer;
|
||||
import net.minecraft.client.renderer.texture.SimpleTexture;
|
||||
import net.minecraft.client.renderer.texture.TextureUtil;
|
||||
import net.minecraft.client.resources.IResourceManager;
|
||||
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.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;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class ThreadDownloadImageETag extends SimpleTexture {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
private static final AtomicInteger THREAD_ID = new AtomicInteger(0);
|
||||
@Nonnull
|
||||
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;
|
||||
}
|
||||
|
||||
private void checkTextureUploaded() {
|
||||
if (!this.textureUploaded) {
|
||||
if (this.bufferedImage != null) {
|
||||
if (this.textureLocation != null) {
|
||||
this.deleteGlTexture();
|
||||
}
|
||||
|
||||
TextureUtil.uploadTextureImage(super.getGlTextureId(), this.bufferedImage);
|
||||
this.textureUploaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getGlTextureId() {
|
||||
this.checkTextureUploaded();
|
||||
return super.getGlTextureId();
|
||||
}
|
||||
|
||||
private void setBufferedImage(BufferedImage bufferedImageIn) {
|
||||
this.bufferedImage = bufferedImageIn;
|
||||
|
||||
if (this.imageBuffer != null) {
|
||||
this.imageBuffer.skinAvailable();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public BufferedImage getBufferedImage() {
|
||||
return bufferedImage;
|
||||
}
|
||||
|
||||
public void loadTexture(IResourceManager resourceManager) throws IOException {
|
||||
if (this.bufferedImage == null && this.textureLocation != null) {
|
||||
super.loadTexture(resourceManager);
|
||||
}
|
||||
|
||||
if (this.imageThread == null) {
|
||||
loadTexture();
|
||||
}
|
||||
}
|
||||
|
||||
private void loadTexture() {
|
||||
this.imageThread = new Thread("Texture Downloader #" + THREAD_ID.incrementAndGet()) {
|
||||
@Override
|
||||
public void run() {
|
||||
HttpResponse response = null;
|
||||
try {
|
||||
HttpClient client = HttpClientBuilder.create().build();
|
||||
response = client.execute(new HttpGet(ThreadDownloadImageETag.this.imageUrl));
|
||||
if (checkEtag(response)) {
|
||||
LOGGER.debug("Loading http texture from local cache ({})", cacheFile);
|
||||
|
||||
try {
|
||||
bufferedImage = ImageIO.read(cacheFile);
|
||||
|
||||
if (imageBuffer != null) {
|
||||
setBufferedImage(imageBuffer.parseUserSkin(bufferedImage));
|
||||
}
|
||||
} catch (IOException ioexception) {
|
||||
LOGGER.error("Couldn't load skin {}", cacheFile, ioexception);
|
||||
loadTextureFromServer(response);
|
||||
}
|
||||
} else {
|
||||
loadTextureFromServer(response);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("Couldn't load skin {} ", imageUrl, e);
|
||||
} finally {
|
||||
if (response != null)
|
||||
EntityUtils.consumeQuietly(response.getEntity());
|
||||
}
|
||||
}
|
||||
};
|
||||
this.imageThread.setDaemon(true);
|
||||
this.imageThread.start();
|
||||
|
||||
}
|
||||
|
||||
private boolean checkEtag(HttpResponse response) {
|
||||
try {
|
||||
if (cacheFile.isFile()) {
|
||||
String localEtag = Files.readFirstLine(eTagFile, Charsets.UTF_8);
|
||||
Header remoteEtag = response.getFirstHeader(HttpHeaders.ETAG);
|
||||
// true if no remote etag or does match
|
||||
return remoteEtag == null || localEtag.equals(remoteEtag.getValue());
|
||||
}
|
||||
return false;
|
||||
} catch (IOException e) {
|
||||
// it failed, so re-fetch.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected void loadTextureFromServer(HttpResponse response) {
|
||||
LOGGER.debug("Downloading http texture from {} to {}", imageUrl, cacheFile);
|
||||
|
||||
try {
|
||||
|
||||
if (response.getStatusLine().getStatusCode() / 100 == 2) {
|
||||
BufferedImage bufferedimage;
|
||||
|
||||
FileUtils.copyInputStreamToFile(response.getEntity().getContent(), cacheFile);
|
||||
bufferedimage = ImageIO.read(cacheFile);
|
||||
|
||||
Header etag = response.getFirstHeader(HttpHeaders.ETAG);
|
||||
if (etag != null) {
|
||||
FileUtils.write(eTagFile, etag.getValue(), Charsets.UTF_8);
|
||||
}
|
||||
if (imageBuffer != null) {
|
||||
bufferedimage = imageBuffer.parseUserSkin(bufferedimage);
|
||||
}
|
||||
|
||||
setBufferedImage(bufferedimage);
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Couldn\'t download http texture", exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -83,7 +83,6 @@ public class MineLittlePony {
|
|||
|
||||
void postInit(Minecraft minecraft) {
|
||||
|
||||
HDSkinManager.clearSkinCache();
|
||||
HDSkinManager manager = HDSkinManager.INSTANCE;
|
||||
manager.setSkinUrl(SKIN_SERVER_URL);
|
||||
manager.setGatewayURL(GATEWAY_URL);
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.minelittlepony.model.PMAPI;
|
|||
import com.minelittlepony.model.PlayerModel;
|
||||
import com.minelittlepony.util.PonyFields;
|
||||
import com.voxelmodpack.hdskins.DynamicTextureImage;
|
||||
import com.voxelmodpack.hdskins.ThreadDownloadImageETag;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.entity.AbstractClientPlayer;
|
||||
import net.minecraft.client.renderer.ThreadDownloadImageData;
|
||||
|
@ -79,6 +80,8 @@ public class Pony {
|
|||
MineLittlePony.logger.debug("Successfully reflected downloadedImage from texture object", e);
|
||||
// this.checkSkin(skinImage);
|
||||
}
|
||||
} else if (e2 instanceof ThreadDownloadImageETag) {
|
||||
skinImage = ((ThreadDownloadImageETag) e2).getBufferedImage();
|
||||
} else if (e2 instanceof DynamicTextureImage) {
|
||||
skinImage = ((DynamicTextureImage) e2).getImage();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue