From 898f5c9ff90b07620772b93fcdcc68a87294c3e0 Mon Sep 17 00:00:00 2001 From: Matthew Messinger Date: Wed, 5 Sep 2018 21:08:08 -0400 Subject: [PATCH] Properly schedule updating the skin --- .../voxelmodpack/hdskins/HDSkinManager.java | 10 +++-- .../mixin/MixinNetworkPlayerInfo$1.java | 41 ------------------- .../hdskins/mixin/MixinNetworkPlayerInfo.java | 15 +++++++ .../hdskins/util/CallableFutures.java | 20 ++++++--- src/hdskins/resources/hdskins.mixin.json | 1 - 5 files changed, 35 insertions(+), 52 deletions(-) delete mode 100644 src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinNetworkPlayerInfo$1.java diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java b/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java index 3aa17a32..f48f78fc 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java @@ -38,6 +38,7 @@ 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; @@ -165,9 +166,7 @@ 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.skinAvailable(typeIn, location, profileTexture); + parseSkin(profile, typeIn, location, profileTexture, callback); }); }), Minecraft.getMinecraft()::addScheduledTask); } @@ -301,7 +300,8 @@ public final class HDSkinManager implements IResourceManagerReloadListener { .flatMap(a -> a.getPlayerInfoMap().stream()); } - public void parseSkin(GameProfile profile, Type type, ResourceLocation resource, MinecraftProfileTexture texture) { + public void parseSkin(GameProfile profile, Type type, ResourceLocation resource, MinecraftProfileTexture texture, + SkinAvailableCallback callback) { CallableFutures.scheduleTask(() -> { @@ -325,6 +325,8 @@ public final class HDSkinManager implements IResourceManagerReloadListener { if (wasNull && !metadata.isEmpty()) { ProfileTextureUtil.setMetadata(texture, metadata); } + + callback.skinAvailable(type, resource, texture); }); } diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinNetworkPlayerInfo$1.java b/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinNetworkPlayerInfo$1.java deleted file mode 100644 index 5209d857..00000000 --- a/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinNetworkPlayerInfo$1.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.voxelmodpack.hdskins.mixin; - -import com.mojang.authlib.minecraft.MinecraftProfileTexture; -import com.voxelmodpack.hdskins.HDSkinManager; -import com.voxelmodpack.hdskins.INetworkPlayerInfo; -import net.minecraft.client.network.NetworkPlayerInfo; -import net.minecraft.client.resources.SkinManager; -import net.minecraft.util.ResourceLocation; -import org.spongepowered.asm.mixin.Final; -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.CallbackInfo; - -import java.util.concurrent.CompletableFuture; - -@Mixin(targets = "net.minecraft.client.network.NetworkPlayerInfo$1") -public abstract class MixinNetworkPlayerInfo$1 implements SkinManager.SkinAvailableCallback { - - @Shadow(remap = false, aliases = {"this$0", "field_177224_a", "a"}) - @Final - private NetworkPlayerInfo player; - - @Inject(method = "skinAvailable(" - + "Lcom/mojang/authlib/minecraft/MinecraftProfileTexture$Type;" - + "Lnet/minecraft/util/ResourceLocation;" - + "Lcom/mojang/authlib/minecraft/MinecraftProfileTexture;" - + ")V", - at = @At(value = "HEAD")) - private void skinAvailable(MinecraftProfileTexture.Type typeIn, ResourceLocation location, MinecraftProfileTexture profileTexture, CallbackInfo ci) { - CompletableFuture.runAsync(() -> { - // schedule parsing next tick, texture may not be uploaded at this point - HDSkinManager.INSTANCE.parseSkin(player.getGameProfile(), typeIn, location, profileTexture); - - // reset the skin type because vanilla has already set it - String model = profileTexture.getMetadata("model"); - ((INetworkPlayerInfo) player).setSkinType(model != null ? model : "default"); - }); - } -} diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinNetworkPlayerInfo.java b/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinNetworkPlayerInfo.java index 7d366b4c..ff131648 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinNetworkPlayerInfo.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinNetworkPlayerInfo.java @@ -8,6 +8,7 @@ import com.voxelmodpack.hdskins.INetworkPlayerInfo; import net.minecraft.client.Minecraft; import net.minecraft.client.network.NetworkPlayerInfo; +import net.minecraft.client.resources.SkinManager; import net.minecraft.util.ResourceLocation; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -81,6 +82,20 @@ public abstract class MixinNetworkPlayerInfo implements INetworkPlayerInfo { }); } + @Redirect(method = "loadPlayerTextures", + at = @At(value = "INVOKE", + target = "Lnet/minecraft/client/resources/SkinManager;loadProfileTextures(" + + "Lcom/mojang/authlib/GameProfile;" + + "Lnet/minecraft/client/resources/SkinManager$SkinAvailableCallback;" + + "Z)V")) + 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); + }, requireSecure); + } + + @Override public void reloadTextures() { synchronized (this) { diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/util/CallableFutures.java b/src/hdskins/java/com/voxelmodpack/hdskins/util/CallableFutures.java index 4b98f309..11112f8e 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/util/CallableFutures.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/util/CallableFutures.java @@ -1,5 +1,6 @@ package com.voxelmodpack.hdskins.util; +import com.google.common.util.concurrent.Runnables; import net.minecraft.client.Minecraft; import java.util.concurrent.Callable; @@ -32,17 +33,24 @@ public class CallableFutures { return ret; } - public static BiFunction callback(Runnable c) { + public static BiFunction callback(Runnable c) { return (o, t) -> { - c.run(); + if (t != null) { + t.printStackTrace(); + } else { + c.run(); + } return null; }; } - public static void scheduleTask(Runnable task) { + public static CompletableFuture scheduleTask(Runnable task) { // schedule a task for next tick. - executor.schedule(() -> { - Minecraft.getMinecraft().addScheduledTask(task); - }, 50, TimeUnit.MILLISECONDS); + return CompletableFuture.runAsync(Runnables.doNothing(), delayed(50, TimeUnit.MILLISECONDS)) + .handleAsync(callback(task), Minecraft.getMinecraft()::addScheduledTask); + } + + private static Executor delayed(long time, TimeUnit unit) { + return (task) -> executor.schedule(task, time, unit); } } diff --git a/src/hdskins/resources/hdskins.mixin.json b/src/hdskins/resources/hdskins.mixin.json index 3b14e566..eccc7930 100644 --- a/src/hdskins/resources/hdskins.mixin.json +++ b/src/hdskins/resources/hdskins.mixin.json @@ -8,7 +8,6 @@ "MixinGuiMainMenu", "MixinImageBufferDownload", "MixinNetworkPlayerInfo", - "MixinNetworkPlayerInfo$1", "MixinSkullRenderer" ] }