diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java b/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java index ea94d0ec..5a1e9021 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java @@ -160,6 +160,16 @@ public final class HDSkinManager implements IResourceManagerReloadListener { return skins.getUnchecked(profile); } + 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); + }); + }), Minecraft.getMinecraft()::addScheduledTask); + } + public ResourceLocation loadTexture(Type type, MinecraftProfileTexture texture, @Nullable SkinManager.SkinAvailableCallback callback) { String skinDir = type.toString().toLowerCase() + "s/"; @@ -295,10 +305,13 @@ public final class HDSkinManager implements IResourceManagerReloadListener { // grab the metadata object via reflection. Object is live. Map metadata = ProfileTextureUtil.getMetadata(texture); + boolean wasNull = metadata == null; + if (wasNull) { metadata = new HashMap<>(); } + for (ISkinParser parser : skinParsers) { try { parser.parse(profile, type, resource, metadata); @@ -306,6 +319,7 @@ public final class HDSkinManager implements IResourceManagerReloadListener { logger.error("Exception thrown while parsing skin: ", t); } } + if (wasNull && !metadata.isEmpty()) { ProfileTextureUtil.setMetadata(texture, metadata); } diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/INetworkPlayerInfo.java b/src/hdskins/java/com/voxelmodpack/hdskins/INetworkPlayerInfo.java index c653ce57..2720bb4d 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/INetworkPlayerInfo.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/INetworkPlayerInfo.java @@ -1,16 +1,7 @@ package com.voxelmodpack.hdskins; -import com.mojang.authlib.minecraft.MinecraftProfileTexture; -import net.minecraft.util.ResourceLocation; - -import java.util.Optional; - public interface INetworkPlayerInfo { - Optional getResourceLocation(MinecraftProfileTexture.Type type); - - Optional getProfileTexture(MinecraftProfileTexture.Type type); - 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 e8730a11..583f9c8a 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinNetworkPlayerInfo.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinNetworkPlayerInfo.java @@ -5,6 +5,7 @@ import com.mojang.authlib.minecraft.MinecraftProfileTexture; import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type; import com.voxelmodpack.hdskins.HDSkinManager; import com.voxelmodpack.hdskins.INetworkPlayerInfo; + import net.minecraft.client.Minecraft; import net.minecraft.client.network.NetworkPlayerInfo; import net.minecraft.util.ResourceLocation; @@ -18,8 +19,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.HashMap; import java.util.Map; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; @Mixin(NetworkPlayerInfo.class) public abstract class MixinNetworkPlayerInfo implements INetworkPlayerInfo { @@ -34,14 +33,8 @@ public abstract class MixinNetworkPlayerInfo implements INetworkPlayerInfo { @Shadow private Map playerTextures; @SuppressWarnings("InvalidMemberReference") // mc-dev bug? - @Redirect(method = { - "getLocationSkin", - "getLocationCape", - "getLocationElytra" - }, - at = @At(value = "INVOKE", - target = "Ljava/util/Map;get(Ljava/lang/Object;)Ljava/lang/Object;", - remap = false)) + @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) { return getSkin(playerTextures, (Type) key); @@ -49,16 +42,23 @@ public abstract class MixinNetworkPlayerInfo implements INetworkPlayerInfo { // with generics private ResourceLocation getSkin(Map playerTextures, Type type) { - return getResourceLocation(type).orElseGet(() -> playerTextures.get(type)); + if (this.customTextures.containsKey(type)) { + return this.customTextures.get(type); + } + + return playerTextures.get(type); } @Redirect(method = "getSkinType", at = @At(value = "FIELD", target = "Lnet/minecraft/client/network/NetworkPlayerInfo;skinType:Ljava/lang/String;")) private String getTextureModel(NetworkPlayerInfo self) { - return getProfileTexture(Type.SKIN).map(profile -> { - String model = profile.getMetadata("model"); + if (customProfiles.containsKey(Type.SKIN)) { + String model = customProfiles.get(Type.SKIN).getMetadata("model"); + return model != null ? model : "default"; - }).orElse(this.skinType); + } + + return skinType; } @Inject(method = "loadPlayerTextures", @@ -69,26 +69,10 @@ public abstract class MixinNetworkPlayerInfo implements INetworkPlayerInfo { + "Z)V", shift = At.Shift.BEFORE)) private void onLoadTexture(CallbackInfo ci) { - HDSkinManager.INSTANCE.loadProfileTextures(this.gameProfile) - .thenAcceptAsync(m -> m.forEach((type, profile) -> { - HDSkinManager.INSTANCE.loadTexture(type, profile, (typeIn, location, profileTexture) -> { - CompletableFuture.runAsync(() -> { - HDSkinManager.INSTANCE.parseSkin(gameProfile, typeIn, location, profileTexture); - }); - customTextures.put(type, location); - customProfiles.put(type, profileTexture); - }); - }), Minecraft.getMinecraft()::addScheduledTask); - } - - @Override - public Optional getResourceLocation(Type type) { - return Optional.ofNullable(this.customTextures.get(type)); - } - - @Override - public Optional getProfileTexture(Type type) { - return Optional.ofNullable(this.customProfiles.get(type)); + HDSkinManager.INSTANCE.fetchAndLoadSkins(gameProfile, (type, location, profileTexture) -> { + customTextures.put(type, location); + customProfiles.put(type, profileTexture); + }); } @Override