From 882d1c5c7c805a16175e90a826d1b2a86f377b53 Mon Sep 17 00:00:00 2001 From: Matthew Messinger Date: Sat, 6 Oct 2018 13:43:56 -0400 Subject: [PATCH] Changing pony level is now instant. --- .../voxelmodpack/hdskins/HDSkinManager.java | 13 ++--- .../hdskins/ducks/INetworkPlayerInfo.java | 2 - .../hdskins/mixin/MixinNetworkPlayerInfo.java | 54 ++++++++++--------- 3 files changed, 35 insertions(+), 34 deletions(-) diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java b/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java index 2292689c..4d902abf 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java @@ -41,7 +41,6 @@ import net.minecraft.client.resources.DefaultPlayerSkin; import net.minecraft.client.resources.IResourceManager; import net.minecraft.client.resources.IResourceManagerReloadListener; import net.minecraft.client.resources.SkinManager; -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; @@ -173,7 +172,8 @@ public final class HDSkinManager implements IResourceManagerReloadListener { public void fetchAndLoadSkins(GameProfile profile, SkinManager.SkinAvailableCallback callback) { loadProfileTextures(profile).thenAcceptAsync(m -> m.forEach((type, pp) -> { loadTexture(type, pp, (typeIn, location, profileTexture) -> { - parseSkin(profile, typeIn, location, profileTexture, callback); + parseSkin(profile, typeIn, location, profileTexture) + .thenRun(() -> callback.skinAvailable(typeIn, location, profileTexture)); }); }), Minecraft.getMinecraft()::addScheduledTask); } @@ -307,10 +307,9 @@ public final class HDSkinManager implements IResourceManagerReloadListener { .flatMap(a -> a.getPlayerInfoMap().stream()); } - public void parseSkin(GameProfile profile, Type type, ResourceLocation resource, MinecraftProfileTexture texture, - SkinAvailableCallback callback) { + public CompletableFuture parseSkin(GameProfile profile, Type type, ResourceLocation resource, MinecraftProfileTexture texture) { - CallableFutures.scheduleTask(() -> { + return CallableFutures.scheduleTask(() -> { // grab the metadata object via reflection. Object is live. Map metadata = ProfileTextureUtil.getMetadata(texture); @@ -319,6 +318,9 @@ public final class HDSkinManager implements IResourceManagerReloadListener { if (wasNull) { metadata = new HashMap<>(); + } else if (metadata.containsKey("model")) { + // try to reset the model. + metadata.put("model", metadata.get("model").contains("slim") ? "slim" : "default"); } for (ISkinParser parser : skinParsers) { @@ -333,7 +335,6 @@ public final class HDSkinManager implements IResourceManagerReloadListener { ProfileTextureUtil.setMetadata(texture, metadata); } - callback.skinAvailable(type, resource, texture); }); } diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/ducks/INetworkPlayerInfo.java b/src/hdskins/java/com/voxelmodpack/hdskins/ducks/INetworkPlayerInfo.java index 4585518b..2a4365f8 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/ducks/INetworkPlayerInfo.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/ducks/INetworkPlayerInfo.java @@ -3,6 +3,4 @@ package com.voxelmodpack.hdskins.ducks; public interface INetworkPlayerInfo { void reloadTextures(); - - void setSkinType(String type); } diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinNetworkPlayerInfo.java b/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinNetworkPlayerInfo.java index ba4fb4c3..85bd0085 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinNetworkPlayerInfo.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinNetworkPlayerInfo.java @@ -5,8 +5,6 @@ import com.mojang.authlib.minecraft.MinecraftProfileTexture; import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type; import com.voxelmodpack.hdskins.HDSkinManager; import com.voxelmodpack.hdskins.ducks.INetworkPlayerInfo; - -import net.minecraft.client.Minecraft; import net.minecraft.client.network.NetworkPlayerInfo; import net.minecraft.client.resources.SkinManager; import net.minecraft.util.ResourceLocation; @@ -20,6 +18,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.HashMap; import java.util.Map; +import javax.annotation.Nullable; @Mixin(NetworkPlayerInfo.class) public abstract class MixinNetworkPlayerInfo implements INetworkPlayerInfo { @@ -27,20 +26,15 @@ public abstract class MixinNetworkPlayerInfo implements INetworkPlayerInfo { private Map customTextures = new HashMap<>(); private Map customProfiles = new HashMap<>(); + private Map vanillaProfiles = new HashMap<>(); + @Shadow @Final private GameProfile gameProfile; - @Shadow - private boolean playerTexturesLoaded; - - @Shadow - private String skinType; - - @Shadow - private Map playerTextures; + @Shadow Map playerTextures; @SuppressWarnings("InvalidMemberReference") // mc-dev bug? - @Redirect(method = { "getLocationSkin", "getLocationCape", "getLocationElytra" }, + @Redirect(method = {"getLocationSkin", "getLocationCape", "getLocationElytra"}, at = @At(value = "INVOKE", target = "Ljava/util/Map;get(Ljava/lang/Object;)Ljava/lang/Object;", remap = false)) // synthetic private Object getSkin(Map playerTextures, Object key) { @@ -56,16 +50,25 @@ public abstract class MixinNetworkPlayerInfo implements INetworkPlayerInfo { return playerTextures.get(type); } + @Nullable @Redirect(method = "getSkinType", at = @At(value = "FIELD", target = "Lnet/minecraft/client/network/NetworkPlayerInfo;skinType:Ljava/lang/String;")) private String getTextureModel(NetworkPlayerInfo self) { - if (customProfiles.containsKey(Type.SKIN)) { - String model = customProfiles.get(Type.SKIN).getMetadata("model"); + String model = getModelFrom(customProfiles); + if (model != null) { + return model; + } + return getModelFrom(vanillaProfiles); + } + + @Nullable + private static String getModelFrom(Map texture) { + if (texture.containsKey(Type.SKIN)) { + String model = texture.get(Type.SKIN).getMetadata("model"); return model != null ? model : "default"; } - - return skinType; + return null; } @Inject(method = "loadPlayerTextures", @@ -91,24 +94,23 @@ public abstract class MixinNetworkPlayerInfo implements INetworkPlayerInfo { private void redirectLoadPlayerTextures(SkinManager skinManager, GameProfile profile, SkinManager.SkinAvailableCallback callback, boolean requireSecure) { skinManager.loadProfileTextures(profile, (typeIn, location, profileTexture) -> { - HDSkinManager.INSTANCE.parseSkin(profile, typeIn, location, profileTexture, callback); + HDSkinManager.INSTANCE.parseSkin(profile, typeIn, location, profileTexture) + .thenAccept(v -> { + playerTextures.put(typeIn, location); + vanillaProfiles.put(typeIn, profileTexture); + }); }, requireSecure); } - @Override public void reloadTextures() { synchronized (this) { - this.playerTexturesLoaded = false; - if (this.gameProfile.getId().equals(Minecraft.getMinecraft().getSession().getProfile().getId())) { - // local client skin doesn't have a signature. - this.gameProfile.getProperties().removeAll("textures"); + for (Map.Entry entry : customProfiles.entrySet()) { + HDSkinManager.INSTANCE.parseSkin(gameProfile, entry.getKey(), customTextures.get(entry.getKey()), entry.getValue()); + } + for (Map.Entry entry : vanillaProfiles.entrySet()) { + HDSkinManager.INSTANCE.parseSkin(gameProfile, entry.getKey(), playerTextures.get(entry.getKey()), entry.getValue()); } } } - - @Override - public void setSkinType(String skinType) { - this.skinType = skinType; - } }