From aa9cd16293e662135fdf7d334d06674873768526 Mon Sep 17 00:00:00 2001 From: Matthew Messinger Date: Thu, 28 Jan 2016 22:10:28 -0500 Subject: [PATCH] Add support for model types. Still needs server support Add back capes --- liteloader/build.gradle | 2 +- .../voxelmodpack/hdskins/HDSkinManager.java | 62 ++++++++++++------- .../hdskins/mixin/MixinPlayerInfo.java | 39 ++++++++++-- .../hdskins/mixin/MixinSkullRenderer.java | 3 +- .../minelittlepony/MineLittlePony.java | 1 - 5 files changed, 76 insertions(+), 31 deletions(-) diff --git a/liteloader/build.gradle b/liteloader/build.gradle index f711eb28..c09b9e0e 100644 --- a/liteloader/build.gradle +++ b/liteloader/build.gradle @@ -68,7 +68,7 @@ repositories { } dependencies { - compile 'org.spongepowered:mixin:0.4.17-20160126.141141-3' + compile 'org.spongepowered:mixin:0.4.17-SNAPSHOT' compile 'org.ow2.asm:asm-debug-all:5.0.3' compile 'com.google.guava:guava:17.0' compile 'com.google.code.gson:gson:2.2.4' diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java b/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java index 6f3e4eb5..697b00ee 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java @@ -10,6 +10,7 @@ import java.util.Map; import org.apache.commons.io.FileUtils; import com.google.common.base.Optional; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.mojang.authlib.GameProfile; @@ -41,26 +42,30 @@ public final class HDSkinManager { private String skinUrl = "skins.voxelmodpack.com"; private boolean enabled = true; - private Map skinCache = Maps.newHashMap(); + private Map> profileTextures = Maps.newHashMap(); + private Map> skinCache = Maps.newHashMap(); private List skinModifiers = Lists.newArrayList(); private HDSkinManager() {} - public static Optional getSkin(GameProfile profile, boolean loadIfAbsent) { - return INSTANCE.getSkinLocation(profile, loadIfAbsent); - } - - private Optional getSkinLocation(final GameProfile profile, boolean loadIfAbsent) { + public Optional getSkinLocation(final GameProfile profile, Type type, boolean loadIfAbsent) { if (!enabled) return Optional.absent(); - ResourceLocation skin = skinCache.get(profile); + if (!this.skinCache.containsKey(profile)) { + this.skinCache.put(profile, Maps. newHashMap()); + } + ResourceLocation skin = this.skinCache.get(profile).get(type); if (skin == null) { if (loadIfAbsent) { - skinCache.put(profile, LOADING); - loadTexture(profile, Type.SKIN, new SkinAvailableCallback() { + skinCache.get(profile).put(type, LOADING); + loadTexture(profile, type, new SkinAvailableCallback() { @Override public void skinAvailable(Type type, ResourceLocation location, MinecraftProfileTexture profileTexture) { - skinCache.put(profile, location); + skinCache.get(profile).put(type, location); + if (!profileTextures.containsKey(profile)) { + profileTextures.put(profile, Maps. newHashMap()); + } + profileTextures.get(profile).put(type, profileTexture); } }); } @@ -71,26 +76,17 @@ public final class HDSkinManager { private void loadTexture(GameProfile profile, final Type type, final SkinAvailableCallback callback) { if (profile != null && profile.getId() != null) { - String uuid = UUIDTypeAdapter.fromUUID(profile.getId()); - String url; - switch (type) { - case SKIN: - url = getCustomSkinURLForId(uuid, false); - break; - case CAPE: - url = getCustomCloakURLForId(uuid); - break; - default: - throw new NullPointerException("Skin type was null."); + Map data = getProfileData(profile); + final MinecraftProfileTexture texture = data.get(type); + if (texture == null) { + return; } - // TODO use cache - final MinecraftProfileTexture texture = new MinecraftProfileTexture(url, null); final ResourceLocation skin = new ResourceLocation("skins/" + texture.getHash()); File file1 = new File(skinCacheDir, texture.getHash().substring(0, 2)); @SuppressWarnings("unused") File file2 = new File(file1, texture.getHash()); final IImageBuffer imagebufferdownload = new ImageBufferDownloadHD(); - ThreadDownloadImageData threaddownloadimagedata = new ThreadDownloadImageData(null, url, + ThreadDownloadImageData threaddownloadimagedata = new ThreadDownloadImageData(null, texture.getUrl(), DefaultPlayerSkin.getDefaultSkinLegacy(), new IImageBuffer() { public BufferedImage parseUserSkin(BufferedImage image) { @@ -109,6 +105,24 @@ public final class HDSkinManager { } } + public Map getProfileData(GameProfile profile) { + if (!enabled) + return ImmutableMap.of(); + Map textures = this.profileTextures.get(profile); + if (textures == null) { + String uuid = UUIDTypeAdapter.fromUUID(profile.getId()); + String skinUrl = getCustomSkinURLForId(uuid, false); + String capeUrl = getCustomCloakURLForId(uuid); + + // TODO metadata (needs server support) + textures = ImmutableMap.of( + Type.SKIN, new MinecraftProfileTexture(skinUrl, null), + Type.CAPE, new MinecraftProfileTexture(capeUrl, null)); + // this.profileTextures.put(profile, textures); + } + return textures; + } + private static Map getTexturesForProfile(GameProfile profile) { LiteLoaderLogger.debug("Get textures for " + profile.getId(), new Object[0]); diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinPlayerInfo.java b/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinPlayerInfo.java index a4da6d0b..c67fb092 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinPlayerInfo.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinPlayerInfo.java @@ -8,6 +8,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import com.google.common.base.Optional; 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; @@ -18,15 +20,21 @@ public abstract class MixinPlayerInfo { @Shadow private GameProfile gameProfile; + @Shadow + private ResourceLocation locationSkin; + @Shadow + private ResourceLocation locationCape; + @Shadow + public String skinType; @Inject(method = "hasLocationSkin", cancellable = true, at = @At("RETURN") ) private void hasLocationSkin(CallbackInfoReturnable ci) { - boolean has = ci.getReturnValueZ(); - if (!has) { + if (locationSkin == null) { // in case has no skin - ci.setReturnValue(HDSkinManager.getSkin(gameProfile, false).isPresent()); + Optional skin = HDSkinManager.INSTANCE.getSkinLocation(gameProfile, Type.SKIN, false); + ci.setReturnValue(skin.isPresent()); } } @@ -34,10 +42,33 @@ public abstract class MixinPlayerInfo { cancellable = true, at = @At("RETURN") ) private void getLocationSkin(CallbackInfoReturnable ci) { - Optional skin = HDSkinManager.getSkin(gameProfile, true); + Optional skin = HDSkinManager.INSTANCE.getSkinLocation(gameProfile, Type.SKIN, true); if (skin.isPresent()) { // set the skin ci.setReturnValue(skin.get()); } } + + @Inject(method = "getLocationCape", + cancellable = true, + at = @At("RETURN") ) + private void getLocationCape(CallbackInfoReturnable ci) { + Optional cape = HDSkinManager.INSTANCE.getSkinLocation(gameProfile, Type.CAPE, true); + if (cape.isPresent()) { + // set the cape + ci.setReturnValue(cape.get()); + } + } + + @Inject(method = "getSkinType", + cancellable = true, + at = @At("RETURN") ) + private void getSkinType(CallbackInfoReturnable ci) { + MinecraftProfileTexture data = HDSkinManager.INSTANCE.getProfileData(gameProfile).get(Type.SKIN); + if (data != null) { + String type = data.getMetadata("model"); + if (type != null) + ci.setReturnValue(type); + } + } } diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinSkullRenderer.java b/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinSkullRenderer.java index 48c0bdaa..38def3e8 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinSkullRenderer.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinSkullRenderer.java @@ -8,6 +8,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.google.common.base.Optional; import com.mojang.authlib.GameProfile; +import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type; import com.voxelmodpack.hdskins.HDSkinManager; import net.minecraft.client.renderer.tileentity.TileEntitySkullRenderer; @@ -27,7 +28,7 @@ public abstract class MixinSkullRenderer extends TileEntitySpecialRenderer { private void onBindTexture(float x, float y, float z, EnumFacing facing, float rotation, int meta, GameProfile profile, int p_180543_8_, CallbackInfo ci) { if (profile != null) { - Optional skin = HDSkinManager.getSkin(profile, true); + Optional skin = HDSkinManager.INSTANCE.getSkinLocation(profile, Type.SKIN, true); if (skin.isPresent()) // rebind bindTexture(skin.get()); diff --git a/src/main/java/com/brohoof/minelittlepony/MineLittlePony.java b/src/main/java/com/brohoof/minelittlepony/MineLittlePony.java index 77981086..6a57a4ce 100644 --- a/src/main/java/com/brohoof/minelittlepony/MineLittlePony.java +++ b/src/main/java/com/brohoof/minelittlepony/MineLittlePony.java @@ -6,7 +6,6 @@ import com.brohoof.minelittlepony.gui.PonySettingPanel; import com.brohoof.minelittlepony.hdskins.gui.EntityPonyModel; import com.brohoof.minelittlepony.hdskins.gui.GuiSkinsMineLP; import com.brohoof.minelittlepony.hdskins.gui.RenderPonyModel; -import com.brohoof.minelittlepony.model.PMAPI; import com.brohoof.minelittlepony.renderer.RenderPonySkeleton; import com.brohoof.minelittlepony.renderer.RenderPonyVillager; import com.brohoof.minelittlepony.renderer.RenderPonyZombie;