Refactors for AvatarAPI

Won't compile yet because AvatarAPI isn't on maven yet.
This commit is contained in:
Matthew Messinger 2018-08-18 23:40:28 -04:00
parent c95d540923
commit a24b6a108c
25 changed files with 408 additions and 293 deletions

View file

@ -45,12 +45,16 @@ sourceSets {
ext.refMap = 'minelp.mixin.refmap.json'
}
}
repositories {
mavenLocal()
}
dependencies {
// use the same version as httpclient
compile('org.apache.httpcomponents:httpmime:4.3.2') {
transitive = false
}
deobfCompile 'com.minelittlepony:AvatarAPI:1.0-SNAPSHOT'
}
litemod {

View file

@ -6,11 +6,14 @@ import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.minelittlepony.avatar.texture.TextureData;
import com.minelittlepony.avatar.texture.TextureProfile;
import com.minelittlepony.avatar.texture.TextureType;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.minecraft.MinecraftProfileTexture;
import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type;
import com.mojang.authlib.properties.Property;
import com.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload;
@ -31,7 +34,6 @@ import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.resources.DefaultPlayerSkin;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.client.resources.IResourceManagerReloadListener;
import net.minecraft.client.resources.SkinManager.SkinAvailableCallback;
import net.minecraft.util.ResourceLocation;
import org.apache.commons.io.FileUtils;
import org.apache.http.impl.client.CloseableHttpClient;
@ -55,6 +57,7 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
@ -76,9 +79,10 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
private BiMap<String, Class<? extends SkinServer>> skinServerTypes = HashBiMap.create(2);
private List<SkinServer> skinServers = Lists.newArrayList();
private Map<UUID, Map<Type, ResourceLocation>> skinCache = Maps.newHashMap();
private Map<UUID, Map<TextureType, ResourceLocation>> skinCache = Maps.newHashMap();
private LoadingCache<GameProfile, Map<Type, MinecraftProfileTexture>> skins = CacheBuilder.newBuilder()
@Deprecated
private LoadingCache<GameProfile, Map<TextureType, TextureProfile>> skins = CacheBuilder.newBuilder()
.initialCapacity(20)
.maximumSize(100)
.expireAfterWrite(4, TimeUnit.HOURS)
@ -115,7 +119,8 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
return new GuiSkins();
}
public Optional<ResourceLocation> getSkinLocation(GameProfile profile1, final Type type, boolean loadIfAbsent) {
@Deprecated
public Optional<ResourceLocation> getSkinLocation(GameProfile profile1, final TextureType type, boolean loadIfAbsent) {
if (!enabled) {
return Optional.empty();
}
@ -161,7 +166,7 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
if (skin == null) {
if (loadIfAbsent && getProfileData(profile).containsKey(type)) {
skinCache.get(profile.getId()).put(type, LOADING);
loadTexture(profile, type, (t, loc, tex) -> skinCache.get(profile.getId()).put(t, loc));
loadTexture(profile, type, (t, loc) -> skinCache.get(profile.getId()).put(t, loc.getLocation()));
}
return Optional.empty();
}
@ -172,18 +177,19 @@ 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) {
@Deprecated
private void loadTexture(GameProfile profile, final TextureType type, final BiConsumer<TextureType, TextureData> callback) {
if (profile.getId() != null) {
Map<Type, MinecraftProfileTexture> data = getProfileData(profile);
final MinecraftProfileTexture texture = data.get(type);
Map<TextureType, TextureProfile> data = getProfileData(profile);
final TextureProfile 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;
final IImageBuffer imagebufferdownload = type == TextureType.SKIN ? new ImageBufferDownloadHD() : null;
ITextureObject texObject = new ThreadDownloadImageETag(file2, bustCache(texture.getUrl()),
ITextureObject texObject = new ThreadDownloadImageETag(file2, bustCache(texture.getUrl().toString()),
DefaultPlayerSkin.getDefaultSkinLegacy(),
new IImageBuffer() {
@Nonnull
@ -201,7 +207,7 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
if (imagebufferdownload != null) {
imagebufferdownload.skinAvailable();
}
callback.skinAvailable(type, skin, texture);
callback.accept(type, new TextureData(skin, texture));
}
});
@ -210,8 +216,9 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
}
}
private Map<Type, MinecraftProfileTexture> loadProfileData(GameProfile profile) {
Map<Type, MinecraftProfileTexture> textures = Maps.newEnumMap(Type.class);
@Deprecated
private Map<TextureType, TextureProfile> loadProfileData(GameProfile profile) {
Map<TextureType, TextureProfile> textures = Maps.newHashMap();
for (SkinServer server : skinServers) {
try {
server.loadProfileData(profile).getTextures().forEach(textures::putIfAbsent);
@ -226,9 +233,10 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
return textures;
}
public Map<Type, MinecraftProfileTexture> getProfileData(GameProfile profile) {
@Deprecated
public Map<TextureType, TextureProfile> getProfileData(GameProfile profile) {
boolean was = !skins.asMap().containsKey(profile);
Map<Type, MinecraftProfileTexture> textures = skins.getUnchecked(profile);
Map<TextureType, TextureProfile> textures = skins.getUnchecked(profile);
// This is the initial value. Refreshing will load it asynchronously.
if (was) {
skins.refresh(profile);
@ -259,12 +267,16 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
return this.skinServers.get(0);
}
public List<SkinServer> getSkinServers() {
return ImmutableList.copyOf(skinServers);
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public static CompletableFuture<PreviewTextureManager> getPreviewTextureManager(GameProfile profile) {
return INSTANCE.getGatewayServer().getPreviewTextures(profile).thenApply(PreviewTextureManager::new);
return INSTANCE.getGatewayServer().getPreviewTextures(profile).thenApply(p -> new PreviewTextureManager(p.getTextures()));
}
public void addClearListener(ISkinCacheClearListener listener) {

View file

@ -0,0 +1,149 @@
package com.voxelmodpack.hdskins;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.Iterables;
import com.minelittlepony.avatar.texture.TextureData;
import com.minelittlepony.avatar.texture.TextureProfile;
import com.minelittlepony.avatar.texture.TextureService;
import com.minelittlepony.avatar.texture.TextureType;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
import com.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload;
import com.voxelmodpack.hdskins.skins.CallableFutures;
import com.voxelmodpack.hdskins.skins.SkinServer;
import net.minecraft.client.renderer.IImageBuffer;
import net.minecraft.client.renderer.texture.ITextureObject;
import net.minecraft.client.resources.DefaultPlayerSkin;
import net.minecraft.launchwrapper.Launch;
import net.minecraft.util.ResourceLocation;
import org.apache.http.client.utils.URIBuilder;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import javax.annotation.Nullable;
public class HDSkinTextureService implements TextureService {
private static final Logger logger = LogManager.getLogger();
private static ExecutorService THREAD_POOL = Executors.newCachedThreadPool();
private final LoadingCache<GameProfile, CompletableFuture<Map<TextureType, TextureProfile>>> cache = CacheBuilder.newBuilder()
.expireAfterAccess(15, TimeUnit.SECONDS)
.build(new CacheLoader<GameProfile, CompletableFuture<Map<TextureType, TextureProfile>>>() {
@Override
public CompletableFuture<Map<TextureType, TextureProfile>> load(GameProfile key) {
return CallableFutures.asyncFailableFuture(() -> loadTexturesFromServer(key), THREAD_POOL)
.exceptionally(e -> {
logger.catching(e);
return Collections.emptyMap();
});
}
});
private BiMap<String, Class<? extends SkinServer>> skinServerTypes = HashBiMap.create(2);
@Override
public CompletableFuture<Map<TextureType, TextureProfile>> loadProfileTextures(GameProfile profile) {
// try to recreate a broken gameprofile
// happens when server sends a random profile with skin and displayname
Property textures = Iterables.getFirst(profile.getProperties().get("textures"), null);
if (textures != null) {
String json = new String(Base64.getDecoder().decode(textures.getValue()), StandardCharsets.UTF_8);
MinecraftTexturesPayload texturePayload = SkinServer.gson.fromJson(json, MinecraftTexturesPayload.class);
if (texturePayload != null) {
// name is optional
String name = texturePayload.getProfileName();
UUID uuid = texturePayload.getProfileId();
// uuid is required
if (uuid != null) {
profile = new GameProfile(uuid, name);
}
// probably uses this texture for a reason. Don't mess with it.
if (!texturePayload.getTextures().isEmpty() && texturePayload.getProfileId() == null) {
return CompletableFuture.completedFuture(Collections.emptyMap());
}
}
}
return cache.getUnchecked(profile);
}
private Map<TextureType, TextureProfile> loadTexturesFromServer(GameProfile profile) throws IOException {
Map<TextureType, TextureProfile> textures = new HashMap<>();
for (SkinServer server : HDSkinManager.INSTANCE.getSkinServers()) {
Map<TextureType, TextureProfile> payload = server.loadProfileData(profile).getTextures();
if (payload != null) {
payload.forEach(textures::putIfAbsent);
}
}
return textures;
}
@Override
public TextureData loadTexture(TextureType type, TextureProfile texture, @Nullable BiConsumer<TextureType, TextureData> callback) {
String url = bustCache(texture.getUrl());
String skinDir = type.toString().toLowerCase() + "s/";
final ResourceLocation skin = new ResourceLocation("hdskins", skinDir + texture.getHash());
TextureData data = new TextureData(skin, texture);
File file2 = new File(Launch.assetsDir, "hd/" + skinDir + texture.getHash().substring(0, 2) + "/" + texture.getHash());
final IImageBuffer buffer = type == TextureType.SKIN ? new ImageBufferDownloadHD() : null;
// an actual callback is not needed because that is handled by CompletableFuture
ITextureObject texObject = new ThreadDownloadImageETag(file2, url, DefaultPlayerSkin.getDefaultSkinLegacy(),
new IImageBuffer() {
@Override
public BufferedImage parseUserSkin(BufferedImage image) {
BufferedImage image1 = image;
if (buffer != null) {
image1 = buffer.parseUserSkin(image);
}
return image1 == null ? image : image1;
}
@Override
public void skinAvailable() {
if (callback != null) {
callback.accept(type, data);
}
}
});
TextureLoader.loadTexture(skin, texObject);
return new TextureData(skin, texture);
}
private static String bustCache(URI url) {
long time = Calendar.getInstance().getTimeInMillis();
return new URIBuilder(url).addParameter(Long.toString(time), null).toString();
}
}

View file

@ -1,20 +1,20 @@
package com.voxelmodpack.hdskins;
import com.minelittlepony.avatar.texture.TextureData;
import com.minelittlepony.avatar.texture.TextureType;
import com.mojang.authlib.GameProfile;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.util.ResourceLocation;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.function.BiConsumer;
import javax.imageio.ImageIO;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.resources.SkinManager.SkinAvailableCallback;
import net.minecraft.util.ResourceLocation;
public class LocalTexture {
private final TextureManager textureManager = Minecraft.getMinecraft().getTextureManager();
@ -27,13 +27,13 @@ public class LocalTexture {
private final IBlankSkinSupplier blank;
private final Type type;
private final TextureType type;
public LocalTexture(GameProfile profile, Type type, IBlankSkinSupplier blank) {
public LocalTexture(GameProfile profile, TextureType type, IBlankSkinSupplier blank) {
this.blank = blank;
this.type = type;
String file = type.name().toLowerCase() + "s/preview_${profile.getName()}.png";
String file = type.toString().toLowerCase() + "s/preview_${profile.getName()}.png";
remoteResource = new ResourceLocation(file);
textureManager.deleteTexture(remoteResource);
@ -73,7 +73,7 @@ public class LocalTexture {
return remote;
}
public void setRemote(PreviewTextureManager ptm, SkinAvailableCallback callback) {
public void setRemote(PreviewTextureManager ptm, BiConsumer<TextureType, TextureData> callback) {
clearRemote();
remote = ptm.getPreviewTexture(remoteResource, type, blank.getBlankSkin(type), callback);
@ -113,6 +113,6 @@ public class LocalTexture {
}
public interface IBlankSkinSupplier {
ResourceLocation getBlankSkin(Type type);
ResourceLocation getBlankSkin(TextureType type);
}
}

View file

@ -1,5 +1,6 @@
package com.voxelmodpack.hdskins;
import com.minelittlepony.avatar.texture.TextureProfile;
import net.minecraft.client.renderer.IImageBuffer;
import net.minecraft.client.renderer.ThreadDownloadImageData;
import net.minecraft.util.ResourceLocation;
@ -12,10 +13,10 @@ public class PreviewTexture extends ThreadDownloadImageData {
private String model;
public PreviewTexture(@Nullable String model, String url, ResourceLocation fallbackTexture, @Nullable IImageBuffer imageBuffer) {
super(null, url, fallbackTexture, imageBuffer);
public PreviewTexture(TextureProfile profile, ResourceLocation fallbackTexture, @Nullable IImageBuffer imageBuffer) {
super(null, profile.getUrl().toString(), fallbackTexture, imageBuffer);
this.model = model == null ? "default" : model;
this.model = profile.getMetadata("model").orElse("default");
}
public boolean isTextureUploaded() {

View file

@ -1,14 +1,14 @@
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.minelittlepony.avatar.texture.TextureData;
import com.minelittlepony.avatar.texture.TextureProfile;
import com.minelittlepony.avatar.texture.TextureType;
import net.minecraft.client.renderer.IImageBuffer;
import net.minecraft.client.resources.SkinManager;
import net.minecraft.util.ResourceLocation;
import java.awt.image.BufferedImage;
import java.util.Map;
import java.util.function.BiConsumer;
import javax.annotation.Nullable;
@ -18,22 +18,22 @@ import javax.annotation.Nullable;
*/
public class PreviewTextureManager {
private final Map<MinecraftProfileTexture.Type, MinecraftProfileTexture> textures;
private final Map<TextureType, TextureProfile> textures;
PreviewTextureManager(MinecraftTexturesPayload payload) {
this.textures = payload.getTextures();
PreviewTextureManager(Map<TextureType, TextureProfile> textures) {
this.textures = textures;
}
@Nullable
public PreviewTexture getPreviewTexture(ResourceLocation location, MinecraftProfileTexture.Type type, ResourceLocation def,
@Nullable SkinManager.SkinAvailableCallback callback) {
public PreviewTexture getPreviewTexture(ResourceLocation location, TextureType type, ResourceLocation def,
@Nullable BiConsumer<TextureType, TextureData> callback) {
if (!textures.containsKey(type)) {
return null;
}
MinecraftProfileTexture texture = textures.get(type);
TextureProfile texture = textures.get(type);
IImageBuffer buffer = new ImageBufferDownloadHD();
PreviewTexture skinTexture = new PreviewTexture(texture.getMetadata("model"), texture.getUrl(), def,
type == MinecraftProfileTexture.Type.SKIN ? new IImageBuffer() {
PreviewTexture skinTexture = new PreviewTexture(texture, def,
type == TextureType.SKIN ? new IImageBuffer() {
@Override
@Nullable
public BufferedImage parseUserSkin(BufferedImage image) {
@ -43,7 +43,7 @@ public class PreviewTextureManager {
@Override
public void skinAvailable() {
if (callback != null) {
callback.skinAvailable(type, location, new MinecraftProfileTexture(texture.getUrl(), Maps.newHashMap()));
callback.accept(type, new TextureData(location, texture));
}
}
} : null);
@ -52,4 +52,5 @@ public class PreviewTextureManager {
return skinTexture;
}
}

View file

@ -2,13 +2,13 @@ package com.voxelmodpack.hdskins.gui;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.minelittlepony.avatar.texture.TextureData;
import com.minelittlepony.avatar.texture.TextureType;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type;
import com.voxelmodpack.hdskins.HDSkinManager;
import com.voxelmodpack.hdskins.LocalTexture;
import com.voxelmodpack.hdskins.LocalTexture.IBlankSkinSupplier;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.SkinManager;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.ItemStack;
@ -17,6 +17,7 @@ import net.minecraft.util.ResourceLocation;
import java.io.File;
import java.util.Map;
import java.util.function.BiConsumer;
@SuppressWarnings("EntityConstructor")
public class EntityPlayerModel extends EntityLivingBase implements IBlankSkinSupplier {
@ -43,28 +44,28 @@ public class EntityPlayerModel extends EntityLivingBase implements IBlankSkinSup
super(new DummyWorld());
profile = gameprofile;
skin = new LocalTexture(profile, Type.SKIN, this);
elytra = new LocalTexture(profile, Type.ELYTRA, this);
skin = new LocalTexture(profile, TextureType.SKIN, this);
elytra = new LocalTexture(profile, TextureType.ELYTRA, this);
}
public void reloadRemoteSkin(SkinManager.SkinAvailableCallback listener) {
public void reloadRemoteSkin(BiConsumer<TextureType, TextureData> listener) {
HDSkinManager.getPreviewTextureManager(profile).thenAccept(ptm -> {
skin.setRemote(ptm, listener);
elytra.setRemote(ptm, listener);
});
}
public void setLocalTexture(File skinTextureFile, Type type) {
if (type == Type.SKIN) {
public void setLocalTexture(File skinTextureFile, TextureType type) {
if (type == TextureType.SKIN) {
skin.setLocal(skinTextureFile);
} else if (type == Type.ELYTRA) {
} else if (type == TextureType.ELYTRA) {
elytra.setLocal(skinTextureFile);
}
}
@Override
public ResourceLocation getBlankSkin(Type type) {
return type == Type.SKIN ? NO_SKIN : NO_ELYTRA;
public ResourceLocation getBlankSkin(TextureType type) {
return type == TextureType.SKIN ? NO_SKIN : NO_ELYTRA;
}
public boolean isUsingLocalTexture() {
@ -80,8 +81,8 @@ public class EntityPlayerModel extends EntityLivingBase implements IBlankSkinSup
elytra.clearLocal();
}
public LocalTexture getLocal(Type type) {
return type == Type.SKIN ? skin : elytra;
public LocalTexture getLocal(TextureType type) {
return type == TextureType.SKIN ? skin : elytra;
}
public void setPreviewThinArms(boolean thinArms) {

View file

@ -1,25 +1,20 @@
package com.voxelmodpack.hdskins.gui;
import static com.mojang.authlib.minecraft.MinecraftProfileTexture.Type.ELYTRA;
import static com.mojang.authlib.minecraft.MinecraftProfileTexture.Type.SKIN;
import static net.minecraft.client.renderer.GlStateManager.*;
import com.google.common.base.Splitter;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableMap;
import com.minelittlepony.avatar.texture.TextureData;
import com.minelittlepony.avatar.texture.TextureType;
import com.minelittlepony.gui.Button;
import com.minelittlepony.gui.GameGui;
import com.minelittlepony.gui.IconicButton;
import com.minelittlepony.gui.Label;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.minecraft.MinecraftProfileTexture;
import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type;
import com.mumfrey.liteloader.util.log.LiteLoaderLogger;
import com.voxelmodpack.hdskins.HDSkinManager;
import com.voxelmodpack.hdskins.skins.SkinUpload;
import com.voxelmodpack.hdskins.skins.SkinUploadResponse;
import com.voxelmodpack.hdskins.upload.awt.ThreadOpenFilePNG;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.PositionedSoundRecord;
import net.minecraft.client.gui.Gui;
@ -32,9 +27,7 @@ import net.minecraft.init.SoundEvents;
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper;
import org.apache.commons.io.FilenameUtils;
import org.apache.logging.log4j.LogManager;
import org.lwjgl.BufferUtils;
@ -52,6 +45,21 @@ import javax.annotation.Nullable;
import javax.imageio.ImageIO;
import javax.swing.UIManager;
import static com.minelittlepony.avatar.texture.TextureType.ELYTRA;
import static com.minelittlepony.avatar.texture.TextureType.SKIN;
import static net.minecraft.client.renderer.GlStateManager.depthMask;
import static net.minecraft.client.renderer.GlStateManager.disableColorMaterial;
import static net.minecraft.client.renderer.GlStateManager.disableDepth;
import static net.minecraft.client.renderer.GlStateManager.enableBlend;
import static net.minecraft.client.renderer.GlStateManager.enableColorMaterial;
import static net.minecraft.client.renderer.GlStateManager.enableDepth;
import static net.minecraft.client.renderer.GlStateManager.popAttrib;
import static net.minecraft.client.renderer.GlStateManager.popMatrix;
import static net.minecraft.client.renderer.GlStateManager.pushMatrix;
import static net.minecraft.client.renderer.GlStateManager.rotate;
import static net.minecraft.client.renderer.GlStateManager.scale;
import static net.minecraft.client.renderer.GlStateManager.translate;
public class GuiSkins extends GameGui {
private static final int MAX_SKIN_DIMENSION = 1024;
@ -94,14 +102,13 @@ public class GuiSkins extends GameGui {
private File selectedSkin;
private int lastMouseX = 0;
private static GuiSkins instance;
protected CubeMap panorama;
private MinecraftProfileTexture.Type textureType = SKIN;
private TextureType textureType = SKIN;
private boolean thinArmType = false;
static {
@ -186,10 +193,10 @@ public class GuiSkins extends GameGui {
}
protected void onSetRemoteSkin(Type type, ResourceLocation location, MinecraftProfileTexture profileTexture) {
protected void onSetRemoteSkin(TextureType type, TextureData texture) {
}
protected void onSetLocalSkin(Type type) {
protected void onSetLocalSkin(TextureType type) {
}
private void reloadRemoteSkin() {
@ -255,11 +262,12 @@ public class GuiSkins extends GameGui {
addButton(btnModeSkin = new IconicButton(width - 25, 75, sender -> {
switchSkinType(sender, SKIN);
}).setIcon(new ItemStack(Items.LEATHER_CHESTPLATE))).setEnabled(textureType == ELYTRA).setTooltip(format("hdskins.mode.skin", toTitleCase(SKIN.name())));
}).setIcon(new ItemStack(Items.LEATHER_CHESTPLATE))).setEnabled(textureType == ELYTRA)
.setTooltip(format("hdskins.mode.skin", toTitleCase(SKIN.toString())));
addButton(btnModeElytra = new IconicButton(width - 25, 94, sender -> {
switchSkinType(sender, ELYTRA);
}).setIcon(new ItemStack(Items.ELYTRA))).setEnabled(textureType == SKIN).setTooltip(format("hdskins.mode.skin", toTitleCase(ELYTRA.name())));
}).setIcon(new ItemStack(Items.ELYTRA))).setEnabled(textureType == SKIN).setTooltip(format("hdskins.mode.skin", toTitleCase(ELYTRA.toString())));
addButton(new Button(width - 25, height - 65, 20, 20, "?", sender -> {
@ -308,7 +316,7 @@ public class GuiSkins extends GameGui {
return isPowerOfTwo(w) && w == h * 2 || w == h && w <= MAX_SKIN_DIMENSION && h <= MAX_SKIN_DIMENSION;
}
protected void switchSkinType(Button sender, Type newType) {
protected void switchSkinType(Button sender, TextureType newType) {
mc.getSoundHandler().playSound(PositionedSoundRecord.getMasterRecord(SoundEvents.BLOCK_BREWING_STAND_BREW, 1));
textureType = newType;
@ -482,8 +490,9 @@ public class GuiSkins extends GameGui {
enableDepth();
}
private void renderPlayerModel(EntityPlayerModel thePlayer, float xPosition, float yPosition, float scale, float mouseY, float mouseX, float partialTick) {
mc.getTextureManager().bindTexture(thePlayer.getLocal(Type.SKIN).getTexture());
private void renderPlayerModel(EntityPlayerModel thePlayer, float xPosition, float yPosition, float scale, float mouseY, float mouseX,
float partialTick) {
mc.getTextureManager().bindTexture(thePlayer.getLocal(SKIN).getTexture());
enableColorMaterial();
pushMatrix();

View file

@ -1,5 +1,6 @@
package com.voxelmodpack.hdskins.gui;
import com.minelittlepony.avatar.texture.TextureType;
import net.minecraft.client.Minecraft;
import net.minecraft.client.model.ModelBiped.ArmPose;
import net.minecraft.client.model.ModelElytra;
@ -14,14 +15,18 @@ import net.minecraft.init.Items;
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;
import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type;
import java.util.Set;
import static net.minecraft.client.renderer.GlStateManager.*;
import static net.minecraft.client.renderer.GlStateManager.color;
import static net.minecraft.client.renderer.GlStateManager.disableBlend;
import static net.minecraft.client.renderer.GlStateManager.enableBlend;
import static net.minecraft.client.renderer.GlStateManager.popAttrib;
import static net.minecraft.client.renderer.GlStateManager.popMatrix;
import static net.minecraft.client.renderer.GlStateManager.pushMatrix;
import static net.minecraft.client.renderer.GlStateManager.scale;
import static net.minecraft.client.renderer.GlStateManager.translate;
public class RenderPlayerModel<M extends EntityPlayerModel> extends RenderLivingBase<M> {
@ -51,7 +56,7 @@ public class RenderPlayerModel<M extends EntityPlayerModel> extends RenderLiving
GlStateManager.enableBlend();
GlStateManager.blendFunc(GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
bindTexture(entity.getLocal(Type.ELYTRA).getTexture());
bindTexture(entity.getLocal(TextureType.ELYTRA).getTexture());
GlStateManager.pushMatrix();
GlStateManager.translate(0, 0, 0.125F);
@ -73,7 +78,7 @@ public class RenderPlayerModel<M extends EntityPlayerModel> extends RenderLiving
@Override
protected ResourceLocation getEntityTexture(M entity) {
return entity.getLocal(Type.SKIN).getTexture();
return entity.getLocal(TextureType.SKIN).getTexture();
}
@Override

View file

@ -1,68 +0,0 @@
package com.voxelmodpack.hdskins.mixin;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.minecraft.MinecraftProfileTexture;
import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type;
import com.voxelmodpack.hdskins.HDSkinManager;
import net.minecraft.client.network.NetworkPlayerInfo;
import net.minecraft.util.ResourceLocation;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Optional;
@Mixin(NetworkPlayerInfo.class)
public abstract class MixinPlayerInfo {
@Shadow
public abstract GameProfile getGameProfile();
@Inject(
method = "getLocationSkin",
cancellable = true,
at = @At("RETURN"))
private void getLocationSkin(CallbackInfoReturnable<ResourceLocation> ci) {
getTextureLocation(ci, Type.SKIN);
}
@Inject(
method = "getLocationCape",
cancellable = true,
at = @At("RETURN"))
private void getLocationCape(CallbackInfoReturnable<ResourceLocation> ci) {
getTextureLocation(ci, Type.CAPE);
}
@Inject(
method = "getLocationElytra",
cancellable = true,
at = @At("RETURN"))
private void getLocationElytra(CallbackInfoReturnable<ResourceLocation> ci) {
getTextureLocation(ci, Type.ELYTRA);
}
private void getTextureLocation(CallbackInfoReturnable<ResourceLocation> ci, Type type) {
Optional<ResourceLocation> texture = HDSkinManager.INSTANCE.getSkinLocation(getGameProfile(), type, true);
texture.ifPresent(ci::setReturnValue);
}
@Inject(
method = "getSkinType",
cancellable = true,
at = @At("RETURN"))
private void getSkinType(CallbackInfoReturnable<String> ci) {
MinecraftProfileTexture skin = HDSkinManager.INSTANCE.getProfileData(getGameProfile()).get(Type.SKIN);
if (skin != null) {
String type = skin.getMetadata("model");
if (type == null)
type = "default";
String type1 = type;
Optional<ResourceLocation> texture = HDSkinManager.INSTANCE.getSkinLocation(getGameProfile(), Type.SKIN, false);
texture.ifPresent((res) -> ci.setReturnValue(type1));
}
}
}

View file

@ -1,39 +0,0 @@
package com.voxelmodpack.hdskins.mixin;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type;
import com.voxelmodpack.hdskins.HDSkinManager;
import net.minecraft.client.renderer.tileentity.TileEntitySkullRenderer;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.tileentity.TileEntitySkull;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import javax.annotation.Nullable;
import java.util.Optional;
@Mixin(TileEntitySkullRenderer.class)
public abstract class MixinSkullRenderer extends TileEntitySpecialRenderer<TileEntitySkull> {
@Redirect(
method = "renderSkull",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/tileentity/TileEntitySkullRenderer;bindTexture(Lnet/minecraft/util/ResourceLocation;)V",
ordinal = 4))
private void onBindTexture(TileEntitySkullRenderer tesr, ResourceLocation rl, float x, float y, float z, EnumFacing facing, float rotation, int meta,
@Nullable GameProfile profile, int p_180543_8_, float ticks) {
if (profile != null) {
Optional<ResourceLocation> skin = HDSkinManager.INSTANCE.getSkinLocation(profile, Type.SKIN, true);
if (skin.isPresent())
// rebind
bindTexture(skin.get());
else
bindTexture(rl);
} else
bindTexture(rl);
}
}

View file

@ -1,7 +0,0 @@
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
package com.voxelmodpack.hdskins.mixin;
import mcp.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;

View file

@ -3,8 +3,8 @@ package com.voxelmodpack.hdskins.resource;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import com.google.gson.JsonParseException;
import com.minelittlepony.avatar.texture.TextureType;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type;
import com.mumfrey.liteloader.util.log.LiteLoaderLogger;
import net.minecraft.client.resources.IResource;
import net.minecraft.client.resources.IResourceManager;
@ -13,7 +13,6 @@ import net.minecraft.util.ResourceLocation;
import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.LogManager;
import javax.annotation.Nullable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@ -24,6 +23,8 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import javax.annotation.Nullable;
public class SkinResourceManager implements IResourceManagerReloadListener {
private ExecutorService executor = Executors.newSingleThreadExecutor();
@ -74,8 +75,8 @@ public class SkinResourceManager implements IResourceManagerReloadListener {
}
@Nullable
public ResourceLocation getPlayerTexture(GameProfile profile, Type type) {
if (type != Type.SKIN)
public ResourceLocation getPlayerTexture(GameProfile profile, TextureType type) {
if (type != TextureType.SKIN)
// not supported
return null;

View file

@ -4,7 +4,6 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.gson.annotations.Expose;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload;
import com.mojang.util.UUIDTypeAdapter;
import com.voxelmodpack.hdskins.HDSkinManager;
import net.minecraft.util.Session;
@ -27,14 +26,14 @@ public class BethlehemSkinServer implements SkinServer {
}
@Override
public MinecraftTexturesPayload loadProfileData(GameProfile profile) throws IOException {
public TexturesPayload loadProfileData(GameProfile profile) throws IOException {
// TODO: Fix this
try (MoreHttpResponses response = new NetClient("GET", getPath(profile)).send()) {
if (!response.ok()) {
throw new IOException(response.getResponse().getStatusLine().getReasonPhrase());
}
return response.json(MinecraftTexturesPayload.class);
return response.json(TexturesPayload.class);
}
}

View file

@ -3,9 +3,9 @@ package com.voxelmodpack.hdskins.skins;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.gson.annotations.Expose;
import com.minelittlepony.avatar.texture.TextureProfile;
import com.minelittlepony.avatar.texture.TextureType;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.minecraft.MinecraftProfileTexture;
import com.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload;
import com.mojang.util.UUIDTypeAdapter;
import com.voxelmodpack.hdskins.HDSkinManager;
import com.voxelmodpack.hdskins.upload.ThreadMultipartPostUpload;
@ -16,8 +16,7 @@ import org.apache.logging.log4j.Logger;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
@ -42,23 +41,23 @@ public class LegacySkinServer implements SkinServer {
}
@Override
public CompletableFuture<MinecraftTexturesPayload> getPreviewTextures(GameProfile profile) {
public CompletableFuture<TexturesPayload> getPreviewTextures(GameProfile profile) {
if (Strings.isNullOrEmpty(this.gateway)) {
return CallableFutures.failedFuture(gatewayUnsupported());
}
Map<MinecraftProfileTexture.Type, MinecraftProfileTexture> map = new EnumMap<>(MinecraftProfileTexture.Type.class);
for (MinecraftProfileTexture.Type type : MinecraftProfileTexture.Type.values()) {
map.put(type, new MinecraftProfileTexture(getPath(gateway, type, profile), null));
Map<TextureType, TextureProfile> map = new HashMap<>();
for (TextureType type : TextureType.values()) {
map.put(type, new TextureProfile(getPath(gateway, type, profile), null));
}
return CompletableFuture.completedFuture(TexturesPayloadBuilder.createTexturesPayload(profile, map));
return CompletableFuture.completedFuture(new TexturesPayload(profile, map));
}
@Override
public MinecraftTexturesPayload loadProfileData(GameProfile profile) throws IOException {
ImmutableMap.Builder<MinecraftProfileTexture.Type, MinecraftProfileTexture> builder = ImmutableMap.builder();
for (MinecraftProfileTexture.Type type : MinecraftProfileTexture.Type.values()) {
public TexturesPayload loadProfileData(GameProfile profile) throws IOException {
ImmutableMap.Builder<TextureType, TextureProfile> builder = ImmutableMap.builder();
for (TextureType type : TextureType.values()) {
String url = getPath(this.address, type, profile);
URI url = getPath(this.address, type, profile);
try {
builder.put(type, loadProfileTexture(profile, url));
} catch (IOException e) {
@ -66,20 +65,20 @@ public class LegacySkinServer implements SkinServer {
}
}
Map<MinecraftProfileTexture.Type, MinecraftProfileTexture> map = builder.build();
Map<TextureType, TextureProfile> map = builder.build();
if (map.isEmpty()) {
throw new IOException(String.format("No textures found for %s at %s", profile, this.address));
}
return TexturesPayloadBuilder.createTexturesPayload(profile, map);
return new TexturesPayload(profile, map);
}
private MinecraftProfileTexture loadProfileTexture(GameProfile profile, String url) throws IOException {
HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
private TextureProfile loadProfileTexture(GameProfile profile, URI url) throws IOException {
HttpURLConnection urlConnection = (HttpURLConnection) url.toURL().openConnection();
if (urlConnection.getResponseCode() / 100 != 2) {
throw new IOException("Bad response code: " + urlConnection.getResponseCode() + ". URL: " + url);
}
logger.debug("Found skin for {} at {}", profile.getName(), url);
return new MinecraftProfileTexture(url, null);
return new TextureProfile(url, null);
}
@SuppressWarnings("deprecation")
@ -91,7 +90,7 @@ public class LegacySkinServer implements SkinServer {
return CallableFutures.asyncFailableFuture(() -> {
URI image = skin.getImage();
MinecraftProfileTexture.Type type = skin.getType();
TextureType type = skin.getType();
Map<String, String> metadata = skin.getMetadata();
SkinServer.verifyServerConnection(session, SERVER_ID);
@ -114,7 +113,7 @@ public class LegacySkinServer implements SkinServer {
return new UnsupportedOperationException("Server does not have a gateway.");
}
private static Map<String, ?> getData(Session session, MinecraftProfileTexture.Type type, String model, String param, Object val) {
private static Map<String, ?> getData(Session session, TextureType type, String model, String param, Object val) {
return ImmutableMap.of(
"user", session.getUsername(),
"uuid", UUIDTypeAdapter.fromUUID(session.getProfile().getId()),
@ -123,18 +122,18 @@ public class LegacySkinServer implements SkinServer {
param, val);
}
private static Map<String, ?> getClearData(Session session, MinecraftProfileTexture.Type type) {
private static Map<String, ?> getClearData(Session session, TextureType type) {
return getData(session, type, "default", "clear", "1");
}
private static Map<String, ?> getUploadData(Session session, MinecraftProfileTexture.Type type, String model, URI skinFile) {
private static Map<String, ?> getUploadData(Session session, TextureType type, String model, URI skinFile) {
return getData(session, type, model, type.toString().toLowerCase(Locale.US), skinFile);
}
private static String getPath(String address, MinecraftProfileTexture.Type type, GameProfile profile) {
private static URI getPath(String address, TextureType type, GameProfile profile) {
String uuid = UUIDTypeAdapter.fromUUID(profile.getId());
String path = type.toString().toLowerCase() + "s";
return String.format("%s/%s/%s.png", address, path, uuid);
return URI.create(String.format("%s/%s/%s.png", address, path, uuid));
}
@Override

View file

@ -3,12 +3,11 @@ package com.voxelmodpack.hdskins.skins;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.minelittlepony.avatar.texture.TextureType;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.exceptions.AuthenticationException;
import com.mojang.authlib.minecraft.MinecraftSessionService;
import com.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload;
import com.mojang.util.UUIDTypeAdapter;
import com.mumfrey.liteloader.modconfig.Exposable;
import com.voxelmodpack.hdskins.HDSkinManager;
import net.minecraft.client.Minecraft;
import net.minecraft.util.Session;
@ -18,21 +17,22 @@ import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
public interface SkinServer extends Exposable {
public interface SkinServer {
Gson gson = new GsonBuilder()
.registerTypeAdapter(UUID.class, new UUIDTypeAdapter())
.registerTypeAdapter(TextureType.class, new TextureType.Serializer())
.create();
List<SkinServer> defaultServers = Lists.newArrayList(new LegacySkinServer(
"http://skins.voxelmodpack.com",
"http://skinmanager.voxelmodpack.com"));
MinecraftTexturesPayload loadProfileData(GameProfile profile) throws IOException;
TexturesPayload loadProfileData(GameProfile profile) throws IOException;
CompletableFuture<SkinUploadResponse> uploadSkin(Session session, SkinUpload upload);
default CompletableFuture<MinecraftTexturesPayload> getPreviewTextures(GameProfile profile) {
default CompletableFuture<TexturesPayload> getPreviewTextures(GameProfile profile) {
return CallableFutures.asyncFailableFuture(() -> loadProfileData(profile), HDSkinManager.skinDownloadExecutor);
}

View file

@ -1,6 +1,6 @@
package com.voxelmodpack.hdskins.skins;
import com.mojang.authlib.minecraft.MinecraftProfileTexture;
import com.minelittlepony.avatar.texture.TextureType;
import java.net.URI;
import java.util.Map;
@ -11,9 +11,9 @@ public class SkinUpload {
private URI image;
private Map<String, String> metadata;
private MinecraftProfileTexture.Type type;
private TextureType type;
public SkinUpload(MinecraftProfileTexture.Type type, @Nullable URI image, Map<String, String> metadata) {
public SkinUpload(TextureType type, @Nullable URI image, Map<String, String> metadata) {
this.image = image;
this.metadata = metadata;
this.type = type;
@ -28,7 +28,7 @@ public class SkinUpload {
return metadata;
}
public MinecraftProfileTexture.Type getType() {
public TextureType getType() {
return type;
}
}

View file

@ -0,0 +1,51 @@
package com.voxelmodpack.hdskins.skins;
import com.minelittlepony.avatar.texture.TextureProfile;
import com.minelittlepony.avatar.texture.TextureType;
import com.mojang.authlib.GameProfile;
import java.util.Map;
import java.util.UUID;
import javax.annotation.Nullable;
public class TexturesPayload {
private long timestamp;
private UUID profileId;
private String profileName;
private boolean isPublic;
private Map<TextureType, TextureProfile> textures;
public TexturesPayload(GameProfile profile, Map<TextureType, TextureProfile> textures) {
this.profileId = profile.getId();
this.profileName = profile.getName();
this.timestamp = System.currentTimeMillis();
this.isPublic = true;
this.textures = textures;
}
public long getTimestamp() {
return timestamp;
}
public UUID getProfileId() {
return profileId;
}
public String getProfileName() {
return profileName;
}
public boolean isPublic() {
return isPublic;
}
@Nullable
public Map<TextureType, TextureProfile> getTextures() {
return textures;
}
}

View file

@ -3,10 +3,9 @@ package com.voxelmodpack.hdskins.skins;
import com.google.common.base.Preconditions;
import com.google.gson.JsonObject;
import com.google.gson.annotations.Expose;
import com.minelittlepony.avatar.texture.TextureType;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.exceptions.AuthenticationException;
import com.mojang.authlib.minecraft.MinecraftProfileTexture;
import com.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload;
import com.mojang.util.UUIDTypeAdapter;
import com.voxelmodpack.hdskins.HDSkinManager;
import net.minecraft.client.Minecraft;
@ -43,12 +42,12 @@ public class ValhallaSkinServer implements SkinServer {
}
@Override
public MinecraftTexturesPayload loadProfileData(GameProfile profile) throws IOException {
public TexturesPayload loadProfileData(GameProfile profile) throws IOException {
try (MoreHttpResponses response = MoreHttpResponses.execute(HDSkinManager.httpClient, new HttpGet(getTexturesURI(profile)))) {
if (response.ok()) {
return readJson(response, MinecraftTexturesPayload.class);
return readJson(response, TexturesPayload.class);
}
throw new IOException("Server sent non-ok response code: " + response.getResponseCode());
}
@ -58,7 +57,7 @@ public class ValhallaSkinServer implements SkinServer {
public CompletableFuture<SkinUploadResponse> uploadSkin(Session session, SkinUpload skin) {
URI image = skin.getImage();
Map<String, String> metadata = skin.getMetadata();
MinecraftProfileTexture.Type type = skin.getType();
TextureType type = skin.getType();
return CallableFutures.asyncFailableFuture(() -> {
authorize(session);
@ -77,7 +76,7 @@ public class ValhallaSkinServer implements SkinServer {
}
private SkinUploadResponse upload(Session session, @Nullable URI image,
MinecraftProfileTexture.Type type, Map<String, String> metadata)
TextureType type, Map<String, String> metadata)
throws IOException {
GameProfile profile = session.getProfile();
@ -96,14 +95,14 @@ public class ValhallaSkinServer implements SkinServer {
}
private SkinUploadResponse resetSkin(GameProfile profile, MinecraftProfileTexture.Type type) throws IOException {
private SkinUploadResponse resetSkin(GameProfile profile, TextureType type) throws IOException {
return upload(RequestBuilder.delete()
.setUri(buildUserTextureUri(profile, type))
.addHeader(HttpHeaders.AUTHORIZATION, this.accessToken)
.build());
}
private SkinUploadResponse uploadFile(File file, GameProfile profile, MinecraftProfileTexture.Type type, Map<String, String> metadata) throws IOException {
private SkinUploadResponse uploadFile(File file, GameProfile profile, TextureType type, Map<String, String> metadata) throws IOException {
MultipartEntityBuilder b = MultipartEntityBuilder.create();
b.addBinaryBody("file", file, ContentType.create("image/png"), file.getName());
metadata.forEach(b::addTextBody);
@ -115,7 +114,7 @@ public class ValhallaSkinServer implements SkinServer {
.build());
}
private SkinUploadResponse uploadUrl(URI uri, GameProfile profile, MinecraftProfileTexture.Type type, Map<String, String> metadata) throws IOException {
private SkinUploadResponse uploadUrl(URI uri, GameProfile profile, TextureType type, Map<String, String> metadata) throws IOException {
return upload(RequestBuilder.post()
.setUri(buildUserTextureUri(profile, type))
@ -186,9 +185,9 @@ public class ValhallaSkinServer implements SkinServer {
}
}
private URI buildUserTextureUri(GameProfile profile, MinecraftProfileTexture.Type textureType) {
private URI buildUserTextureUri(GameProfile profile, TextureType textureType) {
String user = UUIDTypeAdapter.fromUUID(profile.getId());
String skinType = textureType.name().toLowerCase(Locale.US);
String skinType = textureType.toString().toLowerCase(Locale.US);
return URI.create(String.format("%s/user/%s/%s", this.address, user, skinType));
}

View file

@ -6,9 +6,7 @@ import com.google.gson.Gson;
import com.google.gson.JsonParseException;
import com.minelittlepony.pony.data.Pony;
import com.minelittlepony.pony.data.PonyLevel;
import com.voxelmodpack.hdskins.HDSkinManager;
import com.voxelmodpack.hdskins.ISkinCacheClearListener;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.AbstractClientPlayer;
import net.minecraft.client.network.NetworkPlayerInfo;
@ -84,7 +82,6 @@ public class PonyManager implements IResourceManagerReloadListener, ISkinCacheCl
public Pony getPony(NetworkPlayerInfo playerInfo) {
// force load HDSkins if they're not available
HDSkinManager.INSTANCE.getProfileData(playerInfo.getGameProfile());
ResourceLocation skin = playerInfo.getLocationSkin();
UUID uuid = playerInfo.getGameProfile().getId();

View file

@ -1,9 +1,8 @@
package com.minelittlepony.hdskins.gui;
import com.minelittlepony.avatar.texture.TextureType;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type;
import com.voxelmodpack.hdskins.gui.EntityPlayerModel;
import net.minecraft.util.ResourceLocation;
/**
@ -21,8 +20,8 @@ public class EntityPonyModel extends EntityPlayerModel {
}
@Override
public ResourceLocation getBlankSkin(Type type) {
if (type == Type.SKIN) {
public ResourceLocation getBlankSkin(TextureType type) {
if (type == TextureType.SKIN) {
return wet ? NO_SKIN_SEAPONY : NO_SKIN_PONY;
}
return super.getBlankSkin(type);

View file

@ -2,19 +2,17 @@ package com.minelittlepony.hdskins.gui;
import com.minelittlepony.MineLittlePony;
import com.minelittlepony.PonyManager;
import com.minelittlepony.avatar.texture.TextureData;
import com.minelittlepony.avatar.texture.TextureType;
import com.minelittlepony.gui.Button;
import com.minelittlepony.gui.IconicButton;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.minecraft.MinecraftProfileTexture;
import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type;
import com.voxelmodpack.hdskins.gui.EntityPlayerModel;
import com.voxelmodpack.hdskins.gui.GuiSkins;
import net.minecraft.client.audio.PositionedSoundRecord;
import net.minecraft.init.Items;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
/**
* Skin uploading GUI. Usually displayed over the main menu.
@ -77,18 +75,18 @@ public class GuiSkinsMineLP extends GuiSkins {
}
@Override
protected void onSetLocalSkin(Type type) {
protected void onSetLocalSkin(TextureType type) {
MineLittlePony.logger.debug("Invalidating old local skin, checking updated local skin");
if (type == Type.SKIN) {
ponyManager.removePony(localPlayer.getLocal(Type.SKIN).getTexture());
if (type == TextureType.SKIN) {
ponyManager.removePony(localPlayer.getLocal(TextureType.SKIN).getTexture());
}
}
@Override
protected void onSetRemoteSkin(Type type, ResourceLocation resource, MinecraftProfileTexture profileTexture) {
protected void onSetRemoteSkin(TextureType type, TextureData texture) {
MineLittlePony.logger.debug("Invalidating old remote skin, checking updated remote skin");
if (type == Type.SKIN) {
ponyManager.removePony(resource);
if (type == TextureType.SKIN) {
ponyManager.removePony(texture.getLocation());
}
}
}

View file

@ -1,16 +1,15 @@
package com.minelittlepony.hdskins.gui;
import com.minelittlepony.MineLittlePony;
import com.minelittlepony.avatar.texture.TextureType;
import com.minelittlepony.ducks.IRenderPony;
import com.minelittlepony.model.ModelWrapper;
import com.minelittlepony.model.player.PlayerModels;
import com.minelittlepony.pony.data.Pony;
import com.minelittlepony.pony.data.PonyRace;
import com.minelittlepony.render.layer.LayerPonyElytra;
import com.minelittlepony.render.RenderPony;
import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type;
import com.minelittlepony.render.layer.LayerPonyElytra;
import com.voxelmodpack.hdskins.gui.RenderPlayerModel;
import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelElytra;
import net.minecraft.client.model.ModelPlayer;
@ -79,7 +78,7 @@ public class RenderPonyModel extends RenderPlayerModel<EntityPonyModel> implemen
return super.getEntityModel(playermodel);
}
boolean canWet = playermodel.wet && (loc == playermodel.getBlankSkin(Type.SKIN) || race == PonyRace.SEAPONY);
boolean canWet = playermodel.wet && (loc == playermodel.getBlankSkin(TextureType.SKIN) || race == PonyRace.SEAPONY);
playerModel = canWet ? PlayerModels.SEAPONY.getModel(slim) : thePony.getModel(true);
playerModel.apply(thePony.getMetadata());
@ -110,7 +109,7 @@ public class RenderPonyModel extends RenderPlayerModel<EntityPonyModel> implemen
@Override
protected ResourceLocation getElytraTexture(EntityPonyModel entity) {
return entity.getLocal(Type.ELYTRA).getTexture();
return entity.getLocal(TextureType.ELYTRA).getTexture();
}
};
}

View file

@ -1,22 +1,20 @@
package com.minelittlepony.mixin;
import com.minelittlepony.MineLittlePony;
import com.minelittlepony.PonyManager;
import com.minelittlepony.avatar.impl.INetworkPlayerInfo;
import com.minelittlepony.avatar.texture.TextureData;
import com.minelittlepony.avatar.texture.TextureType;
import com.minelittlepony.ducks.IPlayerInfo;
import net.minecraft.client.network.NetworkPlayerInfo;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.minelittlepony.MineLittlePony;
import com.minelittlepony.PonyManager;
import com.minelittlepony.ducks.IPlayerInfo;
import com.mojang.authlib.minecraft.MinecraftProfileTexture;
import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type;
import com.voxelmodpack.hdskins.HDSkinManager;
import net.minecraft.client.network.NetworkPlayerInfo;
@Mixin(NetworkPlayerInfo.class)
public abstract class MixinNetworkPlayerInfo implements IPlayerInfo {
public abstract class MixinNetworkPlayerInfo implements IPlayerInfo, INetworkPlayerInfo {
@Shadow
private String skinType;
@ -29,10 +27,10 @@ public abstract class MixinNetworkPlayerInfo implements IPlayerInfo {
@Override
public boolean usesSlimArms() {
if (skinType == null) {
MinecraftProfileTexture skin = HDSkinManager.INSTANCE.getProfileData(unwrap().getGameProfile()).get(Type.SKIN);
TextureData skin = this.getPlayerTexture(TextureType.SKIN).orElse(null);
if (skin != null) {
return "slim".equals(skin.getMetadata("model"));
return "slim".equals(skin.getProfile().getMetadata("model").orElse(null));
}
return PonyManager.isSlimSkin(unwrap().getGameProfile().getId());

View file

@ -2,6 +2,10 @@ package com.minelittlepony.render.player;
import com.minelittlepony.MineLittlePony;
import com.minelittlepony.PonyConfig;
import com.minelittlepony.avatar.ServiceManager;
import com.minelittlepony.avatar.texture.TextureData;
import com.minelittlepony.avatar.texture.TextureService;
import com.minelittlepony.avatar.texture.TextureType;
import com.minelittlepony.ducks.IRenderPony;
import com.minelittlepony.model.ModelWrapper;
import com.minelittlepony.model.components.ModelDeadMau5Ears;
@ -20,7 +24,6 @@ import com.minelittlepony.render.layer.LayerPonyElytra;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.minecraft.MinecraftProfileTexture;
import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type;
import com.voxelmodpack.hdskins.HDSkinManager;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.AbstractClientPlayer;
import net.minecraft.client.renderer.GlStateManager;
@ -57,7 +60,11 @@ public class RenderPonyPlayer extends RenderPlayer implements IRenderPony<Abstra
if (profile != null) {
deadMau5.setVisible("deadmau5".equals(profile.getName()));
Optional<ResourceLocation> skin = HDSkinManager.INSTANCE.getSkinLocation(profile, Type.SKIN, true);
Optional<ResourceLocation> skin = ServiceManager.get(TextureService.class).map(service ->
service.getTextures(profile))
.map(m -> m.get(TextureType.SKIN))
.map(TextureData::getLocation);
if (skin.isPresent()) {
return skin.get();
}