mirror of
https://github.com/MineLittlePony/MineLittlePony.git
synced 2025-02-13 16:24:23 +01:00
Properly schedule updating the skin
This commit is contained in:
parent
d78bd02d7b
commit
898f5c9ff9
5 changed files with 35 additions and 52 deletions
|
@ -38,6 +38,7 @@ 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;
|
import net.minecraft.client.resources.SkinManager;
|
||||||
|
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;
|
||||||
|
@ -165,9 +166,7 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
|
||||||
public void fetchAndLoadSkins(GameProfile profile, SkinManager.SkinAvailableCallback callback) {
|
public void fetchAndLoadSkins(GameProfile profile, SkinManager.SkinAvailableCallback callback) {
|
||||||
loadProfileTextures(profile).thenAcceptAsync(m -> m.forEach((type, pp) -> {
|
loadProfileTextures(profile).thenAcceptAsync(m -> m.forEach((type, pp) -> {
|
||||||
loadTexture(type, pp, (typeIn, location, profileTexture) -> {
|
loadTexture(type, pp, (typeIn, location, profileTexture) -> {
|
||||||
parseSkin(profile, typeIn, location, profileTexture);
|
parseSkin(profile, typeIn, location, profileTexture, callback);
|
||||||
|
|
||||||
callback.skinAvailable(typeIn, location, profileTexture);
|
|
||||||
});
|
});
|
||||||
}), Minecraft.getMinecraft()::addScheduledTask);
|
}), Minecraft.getMinecraft()::addScheduledTask);
|
||||||
}
|
}
|
||||||
|
@ -301,7 +300,8 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
|
||||||
.flatMap(a -> a.getPlayerInfoMap().stream());
|
.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(() -> {
|
CallableFutures.scheduleTask(() -> {
|
||||||
|
|
||||||
|
@ -325,6 +325,8 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
|
||||||
if (wasNull && !metadata.isEmpty()) {
|
if (wasNull && !metadata.isEmpty()) {
|
||||||
ProfileTextureUtil.setMetadata(texture, metadata);
|
ProfileTextureUtil.setMetadata(texture, metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
callback.skinAvailable(type, resource, texture);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -8,6 +8,7 @@ import com.voxelmodpack.hdskins.INetworkPlayerInfo;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.network.NetworkPlayerInfo;
|
import net.minecraft.client.network.NetworkPlayerInfo;
|
||||||
|
import net.minecraft.client.resources.SkinManager;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
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
|
@Override
|
||||||
public void reloadTextures() {
|
public void reloadTextures() {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.voxelmodpack.hdskins.util;
|
package com.voxelmodpack.hdskins.util;
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.Runnables;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
@ -32,17 +33,24 @@ public class CallableFutures {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <U, T> BiFunction<? super T, Throwable, ? extends U> callback(Runnable c) {
|
public static <T> BiFunction<? super T, Throwable, Void> callback(Runnable c) {
|
||||||
return (o, t) -> {
|
return (o, t) -> {
|
||||||
c.run();
|
if (t != null) {
|
||||||
|
t.printStackTrace();
|
||||||
|
} else {
|
||||||
|
c.run();
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void scheduleTask(Runnable task) {
|
public static CompletableFuture<Void> scheduleTask(Runnable task) {
|
||||||
// schedule a task for next tick.
|
// schedule a task for next tick.
|
||||||
executor.schedule(() -> {
|
return CompletableFuture.runAsync(Runnables.doNothing(), delayed(50, TimeUnit.MILLISECONDS))
|
||||||
Minecraft.getMinecraft().addScheduledTask(task);
|
.handleAsync(callback(task), Minecraft.getMinecraft()::addScheduledTask);
|
||||||
}, 50, TimeUnit.MILLISECONDS);
|
}
|
||||||
|
|
||||||
|
private static Executor delayed(long time, TimeUnit unit) {
|
||||||
|
return (task) -> executor.schedule(task, time, unit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
"MixinGuiMainMenu",
|
"MixinGuiMainMenu",
|
||||||
"MixinImageBufferDownload",
|
"MixinImageBufferDownload",
|
||||||
"MixinNetworkPlayerInfo",
|
"MixinNetworkPlayerInfo",
|
||||||
"MixinNetworkPlayerInfo$1",
|
|
||||||
"MixinSkullRenderer"
|
"MixinSkullRenderer"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue