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' ext.refMap = 'minelp.mixin.refmap.json'
} }
} }
repositories {
mavenLocal()
}
dependencies { dependencies {
// use the same version as httpclient // use the same version as httpclient
compile('org.apache.httpcomponents:httpmime:4.3.2') { compile('org.apache.httpcomponents:httpmime:4.3.2') {
transitive = false transitive = false
} }
deobfCompile 'com.minelittlepony:AvatarAPI:1.0-SNAPSHOT'
} }
litemod { litemod {

View file

@ -6,11 +6,14 @@ import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache; import com.google.common.cache.LoadingCache;
import com.google.common.collect.BiMap; import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap; import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; 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.GameProfile;
import com.mojang.authlib.minecraft.MinecraftProfileTexture;
import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type; import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type;
import com.mojang.authlib.properties.Property; import com.mojang.authlib.properties.Property;
import com.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload; 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.DefaultPlayerSkin;
import net.minecraft.client.resources.IResourceManager; import net.minecraft.client.resources.IResourceManager;
import net.minecraft.client.resources.IResourceManagerReloadListener; import net.minecraft.client.resources.IResourceManagerReloadListener;
import net.minecraft.client.resources.SkinManager.SkinAvailableCallback;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.apache.http.impl.client.CloseableHttpClient; 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.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.annotation.Nonnull; 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 BiMap<String, Class<? extends SkinServer>> skinServerTypes = HashBiMap.create(2);
private List<SkinServer> skinServers = Lists.newArrayList(); 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) .initialCapacity(20)
.maximumSize(100) .maximumSize(100)
.expireAfterWrite(4, TimeUnit.HOURS) .expireAfterWrite(4, TimeUnit.HOURS)
@ -115,7 +119,8 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
return new GuiSkins(); 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) { if (!enabled) {
return Optional.empty(); return Optional.empty();
} }
@ -161,7 +166,7 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
if (skin == null) { if (skin == null) {
if (loadIfAbsent && getProfileData(profile).containsKey(type)) { if (loadIfAbsent && getProfileData(profile).containsKey(type)) {
skinCache.get(profile.getId()).put(type, LOADING); 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(); return Optional.empty();
} }
@ -172,18 +177,19 @@ 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) { @Deprecated
private void loadTexture(GameProfile profile, final TextureType type, final BiConsumer<TextureType, TextureData> callback) {
if (profile.getId() != null) { if (profile.getId() != null) {
Map<Type, MinecraftProfileTexture> data = getProfileData(profile); Map<TextureType, TextureProfile> data = getProfileData(profile);
final MinecraftProfileTexture texture = data.get(type); final TextureProfile texture = data.get(type);
String skinDir = type.toString().toLowerCase() + "s/"; String skinDir = type.toString().toLowerCase() + "s/";
final ResourceLocation skin = new ResourceLocation("hdskins", skinDir + texture.getHash()); final ResourceLocation skin = new ResourceLocation("hdskins", skinDir + texture.getHash());
File file2 = new File(LiteLoader.getAssetsDirectory(), "hd/" + 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; 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(), DefaultPlayerSkin.getDefaultSkinLegacy(),
new IImageBuffer() { new IImageBuffer() {
@Nonnull @Nonnull
@ -201,7 +207,7 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
if (imagebufferdownload != null) { if (imagebufferdownload != null) {
imagebufferdownload.skinAvailable(); 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) { @Deprecated
Map<Type, MinecraftProfileTexture> textures = Maps.newEnumMap(Type.class); private Map<TextureType, TextureProfile> loadProfileData(GameProfile profile) {
Map<TextureType, TextureProfile> textures = Maps.newHashMap();
for (SkinServer server : skinServers) { for (SkinServer server : skinServers) {
try { try {
server.loadProfileData(profile).getTextures().forEach(textures::putIfAbsent); server.loadProfileData(profile).getTextures().forEach(textures::putIfAbsent);
@ -226,9 +233,10 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
return textures; return textures;
} }
public Map<Type, MinecraftProfileTexture> getProfileData(GameProfile profile) { @Deprecated
public Map<TextureType, TextureProfile> getProfileData(GameProfile profile) {
boolean was = !skins.asMap().containsKey(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. // This is the initial value. Refreshing will load it asynchronously.
if (was) { if (was) {
skins.refresh(profile); skins.refresh(profile);
@ -259,12 +267,16 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
return this.skinServers.get(0); return this.skinServers.get(0);
} }
public List<SkinServer> getSkinServers() {
return ImmutableList.copyOf(skinServers);
}
public void setEnabled(boolean enabled) { public void setEnabled(boolean enabled) {
this.enabled = enabled; this.enabled = enabled;
} }
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(p -> new PreviewTextureManager(p.getTextures()));
} }
public void addClearListener(ISkinCacheClearListener listener) { 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; 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.awt.image.BufferedImage;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.function.BiConsumer;
import javax.imageio.ImageIO; 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 { public class LocalTexture {
private final TextureManager textureManager = Minecraft.getMinecraft().getTextureManager(); private final TextureManager textureManager = Minecraft.getMinecraft().getTextureManager();
@ -27,13 +27,13 @@ public class LocalTexture {
private final IBlankSkinSupplier blank; 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.blank = blank;
this.type = type; 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); remoteResource = new ResourceLocation(file);
textureManager.deleteTexture(remoteResource); textureManager.deleteTexture(remoteResource);
@ -73,7 +73,7 @@ public class LocalTexture {
return remote; return remote;
} }
public void setRemote(PreviewTextureManager ptm, SkinAvailableCallback callback) { public void setRemote(PreviewTextureManager ptm, BiConsumer<TextureType, TextureData> callback) {
clearRemote(); clearRemote();
remote = ptm.getPreviewTexture(remoteResource, type, blank.getBlankSkin(type), callback); remote = ptm.getPreviewTexture(remoteResource, type, blank.getBlankSkin(type), callback);
@ -113,6 +113,6 @@ public class LocalTexture {
} }
public interface IBlankSkinSupplier { public interface IBlankSkinSupplier {
ResourceLocation getBlankSkin(Type type); ResourceLocation getBlankSkin(TextureType type);
} }
} }

View file

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

View file

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

View file

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

View file

@ -1,25 +1,20 @@
package com.voxelmodpack.hdskins.gui; 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.Splitter;
import com.google.common.base.Throwables; import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableMap; 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.Button;
import com.minelittlepony.gui.GameGui; import com.minelittlepony.gui.GameGui;
import com.minelittlepony.gui.IconicButton; import com.minelittlepony.gui.IconicButton;
import com.minelittlepony.gui.Label; import com.minelittlepony.gui.Label;
import com.mojang.authlib.GameProfile; 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.mumfrey.liteloader.util.log.LiteLoaderLogger;
import com.voxelmodpack.hdskins.HDSkinManager; import com.voxelmodpack.hdskins.HDSkinManager;
import com.voxelmodpack.hdskins.skins.SkinUpload; import com.voxelmodpack.hdskins.skins.SkinUpload;
import com.voxelmodpack.hdskins.skins.SkinUploadResponse; import com.voxelmodpack.hdskins.skins.SkinUploadResponse;
import com.voxelmodpack.hdskins.upload.awt.ThreadOpenFilePNG; import com.voxelmodpack.hdskins.upload.awt.ThreadOpenFilePNG;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.PositionedSoundRecord; import net.minecraft.client.audio.PositionedSoundRecord;
import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.Gui;
@ -32,9 +27,7 @@ import net.minecraft.init.SoundEvents;
import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand; import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.lwjgl.BufferUtils; import org.lwjgl.BufferUtils;
@ -52,6 +45,21 @@ import javax.annotation.Nullable;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.swing.UIManager; 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 { public class GuiSkins extends GameGui {
private static final int MAX_SKIN_DIMENSION = 1024; private static final int MAX_SKIN_DIMENSION = 1024;
@ -94,14 +102,13 @@ public class GuiSkins extends GameGui {
private File selectedSkin; private File selectedSkin;
private int lastMouseX = 0; private int lastMouseX = 0;
private static GuiSkins instance; private static GuiSkins instance;
protected CubeMap panorama; protected CubeMap panorama;
private MinecraftProfileTexture.Type textureType = SKIN; private TextureType textureType = SKIN;
private boolean thinArmType = false; private boolean thinArmType = false;
static { 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() { private void reloadRemoteSkin() {
@ -216,7 +223,7 @@ public class GuiSkins extends GameGui {
addButton(new Label(34, 34, "hdskins.local", 0xffffff)); addButton(new Label(34, 34, "hdskins.local", 0xffffff));
addButton(new Label(width / 2 + 34, 34, "hdskins.server", 0xffffff)); addButton(new Label(width / 2 + 34, 34, "hdskins.server", 0xffffff));
addButton(new Button(width / 2 - 150, height - 27, 90, 20, "hdskins.options.browse", sender ->{ addButton(new Button(width / 2 - 150, height - 27, 90, 20, "hdskins.options.browse", sender -> {
selectedSkin = null; selectedSkin = null;
localPlayer.releaseTextures(); localPlayer.releaseTextures();
openFileThread = new ThreadOpenFilePNG(mc, format("hdskins.open.title"), (fileDialog, dialogResult) -> { openFileThread = new ThreadOpenFilePNG(mc, format("hdskins.open.title"), (fileDialog, dialogResult) -> {
@ -255,11 +262,12 @@ public class GuiSkins extends GameGui {
addButton(btnModeSkin = new IconicButton(width - 25, 75, sender -> { addButton(btnModeSkin = new IconicButton(width - 25, 75, sender -> {
switchSkinType(sender, SKIN); 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 -> { addButton(btnModeElytra = new IconicButton(width - 25, 94, sender -> {
switchSkinType(sender, ELYTRA); 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 -> { 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; 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)); mc.getSoundHandler().playSound(PositionedSoundRecord.getMasterRecord(SoundEvents.BLOCK_BREWING_STAND_BREW, 1));
textureType = newType; textureType = newType;
@ -436,7 +444,7 @@ public class GuiSkins extends GameGui {
if (!localPlayer.isUsingLocalTexture()) { if (!localPlayer.isUsingLocalTexture()) {
Gui.drawRect(40, height / 2 - 12, width / 2 - 40, height / 2 + 12, 0xB0000000); Gui.drawRect(40, height / 2 - 12, width / 2 - 40, height / 2 + 12, 0xB0000000);
drawCenteredString(fontRenderer, localMessage, (int)xPos1, height / 2 - 4, 0xffffff); drawCenteredString(fontRenderer, localMessage, (int) xPos1, height / 2 - 4, 0xffffff);
} }
if (fetchingSkin) { if (fetchingSkin) {
@ -446,10 +454,10 @@ public class GuiSkins extends GameGui {
Gui.drawRect((int) (xPos2 - width / 4 + 40), height / 2 - lineHeight, width - 40, height / 2 + lineHeight, 0xB0000000); Gui.drawRect((int) (xPos2 - width / 4 + 40), height / 2 - lineHeight, width - 40, height / 2 + lineHeight, 0xB0000000);
if (throttledByMojang) { if (throttledByMojang) {
drawCenteredString(fontRenderer, format("hdskins.error.mojang"), (int)xPos2, height / 2 - 10, 0xffffff); drawCenteredString(fontRenderer, format("hdskins.error.mojang"), (int) xPos2, height / 2 - 10, 0xffffff);
drawCenteredString(fontRenderer, format("hdskins.error.mojang.wait"), (int)xPos2, height / 2 + 2, 0xffffff); drawCenteredString(fontRenderer, format("hdskins.error.mojang.wait"), (int) xPos2, height / 2 + 2, 0xffffff);
} else { } else {
drawCenteredString(fontRenderer, format("hdskins.fetch"), (int)xPos2, height / 2 - 4, 0xffffff); drawCenteredString(fontRenderer, format("hdskins.fetch"), (int) xPos2, height / 2 - 4, 0xffffff);
} }
} }
@ -482,8 +490,9 @@ public class GuiSkins extends GameGui {
enableDepth(); enableDepth();
} }
private void renderPlayerModel(EntityPlayerModel thePlayer, float xPosition, float yPosition, float scale, float mouseY, float mouseX, float partialTick) { private void renderPlayerModel(EntityPlayerModel thePlayer, float xPosition, float yPosition, float scale, float mouseY, float mouseX,
mc.getTextureManager().bindTexture(thePlayer.getLocal(Type.SKIN).getTexture()); float partialTick) {
mc.getTextureManager().bindTexture(thePlayer.getLocal(SKIN).getTexture());
enableColorMaterial(); enableColorMaterial();
pushMatrix(); pushMatrix();
@ -496,8 +505,8 @@ public class GuiSkins extends GameGui {
rotate(((updateCounter + partialTick) * 2.5F) % 360, 0, 1, 0); rotate(((updateCounter + partialTick) * 2.5F) % 360, 0, 1, 0);
thePlayer.rotationYawHead = (float)Math.atan(mouseX / 20) * 30; thePlayer.rotationYawHead = (float) Math.atan(mouseX / 20) * 30;
thePlayer.rotationPitch = (float)Math.atan(mouseY / 40) * -20; thePlayer.rotationPitch = (float) Math.atan(mouseY / 40) * -20;
mc.getRenderManager().renderEntity(thePlayer, 0, 0, 0, 0, 1, false); mc.getRenderManager().renderEntity(thePlayer, 0, 0, 0, 0, 1, false);

View file

@ -1,5 +1,6 @@
package com.voxelmodpack.hdskins.gui; package com.voxelmodpack.hdskins.gui;
import com.minelittlepony.avatar.texture.TextureType;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.model.ModelBiped.ArmPose; import net.minecraft.client.model.ModelBiped.ArmPose;
import net.minecraft.client.model.ModelElytra; import net.minecraft.client.model.ModelElytra;
@ -14,14 +15,18 @@ import net.minecraft.init.Items;
import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type;
import java.util.Set; 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> { public class RenderPlayerModel<M extends EntityPlayerModel> extends RenderLivingBase<M> {
@ -51,7 +56,7 @@ public class RenderPlayerModel<M extends EntityPlayerModel> extends RenderLiving
GlStateManager.enableBlend(); GlStateManager.enableBlend();
GlStateManager.blendFunc(GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); GlStateManager.blendFunc(GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
bindTexture(entity.getLocal(Type.ELYTRA).getTexture()); bindTexture(entity.getLocal(TextureType.ELYTRA).getTexture());
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
GlStateManager.translate(0, 0, 0.125F); GlStateManager.translate(0, 0, 0.125F);
@ -73,7 +78,7 @@ public class RenderPlayerModel<M extends EntityPlayerModel> extends RenderLiving
@Override @Override
protected ResourceLocation getEntityTexture(M entity) { protected ResourceLocation getEntityTexture(M entity) {
return entity.getLocal(Type.SKIN).getTexture(); return entity.getLocal(TextureType.SKIN).getTexture();
} }
@Override @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.common.collect.Maps;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
import com.minelittlepony.avatar.texture.TextureType;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type;
import com.mumfrey.liteloader.util.log.LiteLoaderLogger; import com.mumfrey.liteloader.util.log.LiteLoaderLogger;
import net.minecraft.client.resources.IResource; import net.minecraft.client.resources.IResource;
import net.minecraft.client.resources.IResourceManager; import net.minecraft.client.resources.IResourceManager;
@ -13,7 +13,6 @@ import net.minecraft.util.ResourceLocation;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
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;
@ -24,6 +23,8 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import javax.annotation.Nullable;
public class SkinResourceManager implements IResourceManagerReloadListener { public class SkinResourceManager implements IResourceManagerReloadListener {
private ExecutorService executor = Executors.newSingleThreadExecutor(); private ExecutorService executor = Executors.newSingleThreadExecutor();
@ -74,8 +75,8 @@ public class SkinResourceManager implements IResourceManagerReloadListener {
} }
@Nullable @Nullable
public ResourceLocation getPlayerTexture(GameProfile profile, Type type) { public ResourceLocation getPlayerTexture(GameProfile profile, TextureType type) {
if (type != Type.SKIN) if (type != TextureType.SKIN)
// not supported // not supported
return null; return null;

View file

@ -4,7 +4,6 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder; import com.google.common.collect.ImmutableMap.Builder;
import com.google.gson.annotations.Expose; import com.google.gson.annotations.Expose;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import com.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload;
import com.mojang.util.UUIDTypeAdapter; import com.mojang.util.UUIDTypeAdapter;
import com.voxelmodpack.hdskins.HDSkinManager; import com.voxelmodpack.hdskins.HDSkinManager;
import net.minecraft.util.Session; import net.minecraft.util.Session;
@ -27,14 +26,14 @@ public class BethlehemSkinServer implements SkinServer {
} }
@Override @Override
public MinecraftTexturesPayload loadProfileData(GameProfile profile) throws IOException { public TexturesPayload loadProfileData(GameProfile profile) throws IOException {
// TODO: Fix this // TODO: Fix this
try (MoreHttpResponses response = new NetClient("GET", getPath(profile)).send()) { try (MoreHttpResponses response = new NetClient("GET", getPath(profile)).send()) {
if (!response.ok()) { if (!response.ok()) {
throw new IOException(response.getResponse().getStatusLine().getReasonPhrase()); 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.base.Strings;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.gson.annotations.Expose; 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.GameProfile;
import com.mojang.authlib.minecraft.MinecraftProfileTexture;
import com.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload;
import com.mojang.util.UUIDTypeAdapter; import com.mojang.util.UUIDTypeAdapter;
import com.voxelmodpack.hdskins.HDSkinManager; import com.voxelmodpack.hdskins.HDSkinManager;
import com.voxelmodpack.hdskins.upload.ThreadMultipartPostUpload; import com.voxelmodpack.hdskins.upload.ThreadMultipartPostUpload;
@ -16,8 +16,7 @@ import org.apache.logging.log4j.Logger;
import java.io.IOException; import java.io.IOException;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URI; import java.net.URI;
import java.net.URL; import java.util.HashMap;
import java.util.EnumMap;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@ -42,23 +41,23 @@ public class LegacySkinServer implements SkinServer {
} }
@Override @Override
public CompletableFuture<MinecraftTexturesPayload> getPreviewTextures(GameProfile profile) { public CompletableFuture<TexturesPayload> getPreviewTextures(GameProfile profile) {
if (Strings.isNullOrEmpty(this.gateway)) { if (Strings.isNullOrEmpty(this.gateway)) {
return CallableFutures.failedFuture(gatewayUnsupported()); return CallableFutures.failedFuture(gatewayUnsupported());
} }
Map<MinecraftProfileTexture.Type, MinecraftProfileTexture> map = new EnumMap<>(MinecraftProfileTexture.Type.class); Map<TextureType, TextureProfile> map = new HashMap<>();
for (MinecraftProfileTexture.Type type : MinecraftProfileTexture.Type.values()) { for (TextureType type : TextureType.values()) {
map.put(type, new MinecraftProfileTexture(getPath(gateway, type, profile), null)); 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 @Override
public MinecraftTexturesPayload loadProfileData(GameProfile profile) throws IOException { public TexturesPayload loadProfileData(GameProfile profile) throws IOException {
ImmutableMap.Builder<MinecraftProfileTexture.Type, MinecraftProfileTexture> builder = ImmutableMap.builder(); ImmutableMap.Builder<TextureType, TextureProfile> builder = ImmutableMap.builder();
for (MinecraftProfileTexture.Type type : MinecraftProfileTexture.Type.values()) { for (TextureType type : TextureType.values()) {
String url = getPath(this.address, type, profile); URI url = getPath(this.address, type, profile);
try { try {
builder.put(type, loadProfileTexture(profile, url)); builder.put(type, loadProfileTexture(profile, url));
} catch (IOException e) { } 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()) { if (map.isEmpty()) {
throw new IOException(String.format("No textures found for %s at %s", profile, this.address)); 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 { private TextureProfile loadProfileTexture(GameProfile profile, URI url) throws IOException {
HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection(); HttpURLConnection urlConnection = (HttpURLConnection) url.toURL().openConnection();
if (urlConnection.getResponseCode() / 100 != 2) { if (urlConnection.getResponseCode() / 100 != 2) {
throw new IOException("Bad response code: " + urlConnection.getResponseCode() + ". URL: " + url); throw new IOException("Bad response code: " + urlConnection.getResponseCode() + ". URL: " + url);
} }
logger.debug("Found skin for {} at {}", profile.getName(), url); logger.debug("Found skin for {} at {}", profile.getName(), url);
return new MinecraftProfileTexture(url, null); return new TextureProfile(url, null);
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@ -91,7 +90,7 @@ public class LegacySkinServer implements SkinServer {
return CallableFutures.asyncFailableFuture(() -> { return CallableFutures.asyncFailableFuture(() -> {
URI image = skin.getImage(); URI image = skin.getImage();
MinecraftProfileTexture.Type type = skin.getType(); TextureType type = skin.getType();
Map<String, String> metadata = skin.getMetadata(); Map<String, String> metadata = skin.getMetadata();
SkinServer.verifyServerConnection(session, SERVER_ID); SkinServer.verifyServerConnection(session, SERVER_ID);
@ -114,7 +113,7 @@ public class LegacySkinServer implements SkinServer {
return new UnsupportedOperationException("Server does not have a gateway."); 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( return ImmutableMap.of(
"user", session.getUsername(), "user", session.getUsername(),
"uuid", UUIDTypeAdapter.fromUUID(session.getProfile().getId()), "uuid", UUIDTypeAdapter.fromUUID(session.getProfile().getId()),
@ -123,18 +122,18 @@ public class LegacySkinServer implements SkinServer {
param, val); 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"); 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); 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 uuid = UUIDTypeAdapter.fromUUID(profile.getId());
String path = type.toString().toLowerCase() + "s"; 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 @Override

View file

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

View file

@ -1,6 +1,6 @@
package com.voxelmodpack.hdskins.skins; package com.voxelmodpack.hdskins.skins;
import com.mojang.authlib.minecraft.MinecraftProfileTexture; import com.minelittlepony.avatar.texture.TextureType;
import java.net.URI; import java.net.URI;
import java.util.Map; import java.util.Map;
@ -11,9 +11,9 @@ public class SkinUpload {
private URI image; private URI image;
private Map<String, String> metadata; 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.image = image;
this.metadata = metadata; this.metadata = metadata;
this.type = type; this.type = type;
@ -28,7 +28,7 @@ public class SkinUpload {
return metadata; return metadata;
} }
public MinecraftProfileTexture.Type getType() { public TextureType getType() {
return type; 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.common.base.Preconditions;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.annotations.Expose; import com.google.gson.annotations.Expose;
import com.minelittlepony.avatar.texture.TextureType;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import com.mojang.authlib.exceptions.AuthenticationException; 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.mojang.util.UUIDTypeAdapter;
import com.voxelmodpack.hdskins.HDSkinManager; import com.voxelmodpack.hdskins.HDSkinManager;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
@ -43,12 +42,12 @@ public class ValhallaSkinServer implements SkinServer {
} }
@Override @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)))) { try (MoreHttpResponses response = MoreHttpResponses.execute(HDSkinManager.httpClient, new HttpGet(getTexturesURI(profile)))) {
if (response.ok()) { if (response.ok()) {
return readJson(response, MinecraftTexturesPayload.class); return readJson(response, TexturesPayload.class);
} }
throw new IOException("Server sent non-ok response code: " + response.getResponseCode()); 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) { public CompletableFuture<SkinUploadResponse> uploadSkin(Session session, SkinUpload skin) {
URI image = skin.getImage(); URI image = skin.getImage();
Map<String, String> metadata = skin.getMetadata(); Map<String, String> metadata = skin.getMetadata();
MinecraftProfileTexture.Type type = skin.getType(); TextureType type = skin.getType();
return CallableFutures.asyncFailableFuture(() -> { return CallableFutures.asyncFailableFuture(() -> {
authorize(session); authorize(session);
@ -77,7 +76,7 @@ public class ValhallaSkinServer implements SkinServer {
} }
private SkinUploadResponse upload(Session session, @Nullable URI image, private SkinUploadResponse upload(Session session, @Nullable URI image,
MinecraftProfileTexture.Type type, Map<String, String> metadata) TextureType type, Map<String, String> metadata)
throws IOException { throws IOException {
GameProfile profile = session.getProfile(); 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() return upload(RequestBuilder.delete()
.setUri(buildUserTextureUri(profile, type)) .setUri(buildUserTextureUri(profile, type))
.addHeader(HttpHeaders.AUTHORIZATION, this.accessToken) .addHeader(HttpHeaders.AUTHORIZATION, this.accessToken)
.build()); .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(); MultipartEntityBuilder b = MultipartEntityBuilder.create();
b.addBinaryBody("file", file, ContentType.create("image/png"), file.getName()); b.addBinaryBody("file", file, ContentType.create("image/png"), file.getName());
metadata.forEach(b::addTextBody); metadata.forEach(b::addTextBody);
@ -115,7 +114,7 @@ public class ValhallaSkinServer implements SkinServer {
.build()); .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() return upload(RequestBuilder.post()
.setUri(buildUserTextureUri(profile, type)) .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 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)); 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.google.gson.JsonParseException;
import com.minelittlepony.pony.data.Pony; import com.minelittlepony.pony.data.Pony;
import com.minelittlepony.pony.data.PonyLevel; import com.minelittlepony.pony.data.PonyLevel;
import com.voxelmodpack.hdskins.HDSkinManager;
import com.voxelmodpack.hdskins.ISkinCacheClearListener; import com.voxelmodpack.hdskins.ISkinCacheClearListener;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.AbstractClientPlayer; import net.minecraft.client.entity.AbstractClientPlayer;
import net.minecraft.client.network.NetworkPlayerInfo; import net.minecraft.client.network.NetworkPlayerInfo;
@ -84,7 +82,6 @@ public class PonyManager implements IResourceManagerReloadListener, ISkinCacheCl
public Pony getPony(NetworkPlayerInfo playerInfo) { public Pony getPony(NetworkPlayerInfo playerInfo) {
// force load HDSkins if they're not available // force load HDSkins if they're not available
HDSkinManager.INSTANCE.getProfileData(playerInfo.getGameProfile());
ResourceLocation skin = playerInfo.getLocationSkin(); ResourceLocation skin = playerInfo.getLocationSkin();
UUID uuid = playerInfo.getGameProfile().getId(); UUID uuid = playerInfo.getGameProfile().getId();

View file

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

View file

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

View file

@ -1,16 +1,15 @@
package com.minelittlepony.hdskins.gui; package com.minelittlepony.hdskins.gui;
import com.minelittlepony.MineLittlePony; import com.minelittlepony.MineLittlePony;
import com.minelittlepony.avatar.texture.TextureType;
import com.minelittlepony.ducks.IRenderPony; import com.minelittlepony.ducks.IRenderPony;
import com.minelittlepony.model.ModelWrapper; import com.minelittlepony.model.ModelWrapper;
import com.minelittlepony.model.player.PlayerModels; import com.minelittlepony.model.player.PlayerModels;
import com.minelittlepony.pony.data.Pony; import com.minelittlepony.pony.data.Pony;
import com.minelittlepony.pony.data.PonyRace; import com.minelittlepony.pony.data.PonyRace;
import com.minelittlepony.render.layer.LayerPonyElytra;
import com.minelittlepony.render.RenderPony; 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 com.voxelmodpack.hdskins.gui.RenderPlayerModel;
import net.minecraft.client.model.ModelBase; import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelElytra; import net.minecraft.client.model.ModelElytra;
import net.minecraft.client.model.ModelPlayer; import net.minecraft.client.model.ModelPlayer;
@ -79,7 +78,7 @@ public class RenderPonyModel extends RenderPlayerModel<EntityPonyModel> implemen
return super.getEntityModel(playermodel); 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 = canWet ? PlayerModels.SEAPONY.getModel(slim) : thePony.getModel(true);
playerModel.apply(thePony.getMetadata()); playerModel.apply(thePony.getMetadata());
@ -110,7 +109,7 @@ public class RenderPonyModel extends RenderPlayerModel<EntityPonyModel> implemen
@Override @Override
protected ResourceLocation getElytraTexture(EntityPonyModel entity) { 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; 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.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 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) @Mixin(NetworkPlayerInfo.class)
public abstract class MixinNetworkPlayerInfo implements IPlayerInfo { public abstract class MixinNetworkPlayerInfo implements IPlayerInfo, INetworkPlayerInfo {
@Shadow @Shadow
private String skinType; private String skinType;
@ -29,10 +27,10 @@ public abstract class MixinNetworkPlayerInfo implements IPlayerInfo {
@Override @Override
public boolean usesSlimArms() { public boolean usesSlimArms() {
if (skinType == null) { if (skinType == null) {
MinecraftProfileTexture skin = HDSkinManager.INSTANCE.getProfileData(unwrap().getGameProfile()).get(Type.SKIN); TextureData skin = this.getPlayerTexture(TextureType.SKIN).orElse(null);
if (skin != 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()); return PonyManager.isSlimSkin(unwrap().getGameProfile().getId());

View file

@ -2,6 +2,10 @@ package com.minelittlepony.render.player;
import com.minelittlepony.MineLittlePony; import com.minelittlepony.MineLittlePony;
import com.minelittlepony.PonyConfig; 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.ducks.IRenderPony;
import com.minelittlepony.model.ModelWrapper; import com.minelittlepony.model.ModelWrapper;
import com.minelittlepony.model.components.ModelDeadMau5Ears; 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.GameProfile;
import com.mojang.authlib.minecraft.MinecraftProfileTexture; import com.mojang.authlib.minecraft.MinecraftProfileTexture;
import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type; import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type;
import com.voxelmodpack.hdskins.HDSkinManager;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.AbstractClientPlayer; import net.minecraft.client.entity.AbstractClientPlayer;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
@ -57,7 +60,11 @@ public class RenderPonyPlayer extends RenderPlayer implements IRenderPony<Abstra
if (profile != null) { if (profile != null) {
deadMau5.setVisible("deadmau5".equals(profile.getName())); 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()) { if (skin.isPresent()) {
return skin.get(); return skin.get();
} }
@ -109,7 +116,7 @@ public class RenderPonyPlayer extends RenderPlayer implements IRenderPony<Abstra
public float prepareScale(AbstractClientPlayer player, float ticks) { public float prepareScale(AbstractClientPlayer player, float ticks) {
if (!player.isRiding() && !player.isPlayerSleeping()) { if (!player.isRiding() && !player.isPlayerSleeping()) {
float x = player.width/2; float x = player.width / 2;
float y = 0; float y = 0;
if (player.isSneaking()) { if (player.isSneaking()) {
@ -136,7 +143,7 @@ public class RenderPonyPlayer extends RenderPlayer implements IRenderPony<Abstra
@Override @Override
public void doRenderShadowAndFire(Entity player, double x, double y, double z, float yaw, float ticks) { public void doRenderShadowAndFire(Entity player, double x, double y, double z, float yaw, float ticks) {
if (player.isRiding() && ((AbstractClientPlayer)player).isPlayerSleeping()) { if (player.isRiding() && ((AbstractClientPlayer) player).isPlayerSleeping()) {
super.doRenderShadowAndFire(player, x, y, z, yaw, ticks); super.doRenderShadowAndFire(player, x, y, z, yaw, ticks);
} }
} }