From 4346ccda3765d175befe3b0f9e19e5bfe3867279 Mon Sep 17 00:00:00 2001 From: Matthew Messinger Date: Mon, 27 Aug 2018 19:22:34 -0400 Subject: [PATCH 1/3] Fix noskins --- .../mixin/MixinDefaultPlayerSkin.java | 55 +++++++++++++++++++ src/main/resources/minelp.mixin.json | 7 ++- 2 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/minelittlepony/mixin/MixinDefaultPlayerSkin.java diff --git a/src/main/java/com/minelittlepony/mixin/MixinDefaultPlayerSkin.java b/src/main/java/com/minelittlepony/mixin/MixinDefaultPlayerSkin.java new file mode 100644 index 00000000..af248960 --- /dev/null +++ b/src/main/java/com/minelittlepony/mixin/MixinDefaultPlayerSkin.java @@ -0,0 +1,55 @@ +package com.minelittlepony.mixin; + +import com.minelittlepony.MineLittlePony; +import com.minelittlepony.PonyManager; +import com.minelittlepony.pony.data.PonyLevel; +import net.minecraft.client.resources.DefaultPlayerSkin; +import net.minecraft.util.ResourceLocation; +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.CallbackInfoReturnable; + +import java.util.UUID; + +@Mixin(DefaultPlayerSkin.class) +public abstract class MixinDefaultPlayerSkin { + + @Shadow + private static boolean isSlimSkin(UUID playerUUID) { + return false; + } + + @Shadow + public static ResourceLocation getDefaultSkin(UUID playerUUID) { + return null; + } + + @Inject(method = "getDefaultSkinLegacy", at = @At("HEAD"), cancellable = true) + private static void legacySkin(CallbackInfoReturnable cir) { + if (MineLittlePony.getConfig().getPonyLevel() == PonyLevel.PONIES) { + cir.setReturnValue(PonyManager.STEVE); + } + } + + @Inject(method = "getDefaultSkin", at = @At("HEAD"), cancellable = true) + private static void defaultSkin(UUID uuid, CallbackInfoReturnable cir) { + if (MineLittlePony.getConfig().getPonyLevel() == PonyLevel.PONIES) { + cir.setReturnValue(isSlimSkin(uuid) ? PonyManager.ALEX : PonyManager.STEVE); + } + } + + @Inject(method = "getSkinType", at = @At("HEAD"), cancellable = true) + private static void skinType(UUID uuid, CallbackInfoReturnable cir) { + if (MineLittlePony.getConfig().getPonyLevel() == PonyLevel.PONIES) { + + cir.setReturnValue(MineLittlePony.getInstance().getManager() + .getPony(getDefaultSkin(uuid), uuid) + .getRace(false) + .getModel() + .getId(isSlimSkin(uuid))); + } + } + +} diff --git a/src/main/resources/minelp.mixin.json b/src/main/resources/minelp.mixin.json index b9626380..690c59c4 100644 --- a/src/main/resources/minelp.mixin.json +++ b/src/main/resources/minelp.mixin.json @@ -5,10 +5,11 @@ "refmap": "minelp.mixin.refmap.json", "compatibilityLevel": "JAVA_8", "mixins": [ - "MixinThreadDownloadImageData", - "MixinRenderItem", + "MixinDefaultPlayerSkin", + "MixinGlStateManager", "MixinItemRenderer", + "MixinRenderItem", "MixinRenderManager", - "MixinGlStateManager" + "MixinThreadDownloadImageData" ] } From f04d67cabaffdc38b333486f0861c3afd1ff43bd Mon Sep 17 00:00:00 2001 From: Matthew Messinger Date: Wed, 29 Aug 2018 20:03:42 -0400 Subject: [PATCH 2/3] Forge doesn't like notch names and neither do I. --- .../java/com/minelittlepony/PonyManager.java | 2 +- .../mixin/MixinDefaultPlayerSkin.java | 17 +++-------------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/minelittlepony/PonyManager.java b/src/main/java/com/minelittlepony/PonyManager.java index 9ea6ec97..bc91dcc2 100644 --- a/src/main/java/com/minelittlepony/PonyManager.java +++ b/src/main/java/com/minelittlepony/PonyManager.java @@ -164,7 +164,7 @@ public class PonyManager implements IResourceManagerReloadListener, ISkinCacheCl MineLittlePony.logger.info("Detected {} background ponies installed.", getNumberOfPonies()); } - private ResourceLocation getDefaultSkin(UUID uuid) { + public static ResourceLocation getDefaultSkin(UUID uuid) { return isSlimSkin(uuid) ? ALEX : STEVE; } diff --git a/src/main/java/com/minelittlepony/mixin/MixinDefaultPlayerSkin.java b/src/main/java/com/minelittlepony/mixin/MixinDefaultPlayerSkin.java index af248960..30e97ac0 100644 --- a/src/main/java/com/minelittlepony/mixin/MixinDefaultPlayerSkin.java +++ b/src/main/java/com/minelittlepony/mixin/MixinDefaultPlayerSkin.java @@ -6,7 +6,6 @@ import com.minelittlepony.pony.data.PonyLevel; import net.minecraft.client.resources.DefaultPlayerSkin; import net.minecraft.util.ResourceLocation; 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.CallbackInfoReturnable; @@ -16,16 +15,6 @@ import java.util.UUID; @Mixin(DefaultPlayerSkin.class) public abstract class MixinDefaultPlayerSkin { - @Shadow - private static boolean isSlimSkin(UUID playerUUID) { - return false; - } - - @Shadow - public static ResourceLocation getDefaultSkin(UUID playerUUID) { - return null; - } - @Inject(method = "getDefaultSkinLegacy", at = @At("HEAD"), cancellable = true) private static void legacySkin(CallbackInfoReturnable cir) { if (MineLittlePony.getConfig().getPonyLevel() == PonyLevel.PONIES) { @@ -36,7 +25,7 @@ public abstract class MixinDefaultPlayerSkin { @Inject(method = "getDefaultSkin", at = @At("HEAD"), cancellable = true) private static void defaultSkin(UUID uuid, CallbackInfoReturnable cir) { if (MineLittlePony.getConfig().getPonyLevel() == PonyLevel.PONIES) { - cir.setReturnValue(isSlimSkin(uuid) ? PonyManager.ALEX : PonyManager.STEVE); + cir.setReturnValue(PonyManager.getDefaultSkin(uuid)); } } @@ -45,10 +34,10 @@ public abstract class MixinDefaultPlayerSkin { if (MineLittlePony.getConfig().getPonyLevel() == PonyLevel.PONIES) { cir.setReturnValue(MineLittlePony.getInstance().getManager() - .getPony(getDefaultSkin(uuid), uuid) + .getPony(PonyManager.getDefaultSkin(uuid), uuid) .getRace(false) .getModel() - .getId(isSlimSkin(uuid))); + .getId(PonyManager.isSlimSkin(uuid))); } } From 031d1ddd338c5d61f819d933b1769b05332a34a9 Mon Sep 17 00:00:00 2001 From: Matthew Messinger Date: Wed, 29 Aug 2018 23:03:50 -0400 Subject: [PATCH 3/3] Fix model updating on NPCs that are not in the player list. --- .../voxelmodpack/hdskins/HDSkinManager.java | 25 +++++++++++++++---- .../hdskins/mixin/MixinNetworkPlayerInfo.java | 6 +++++ .../voxelmodpack/hdskins/util/PlayerUtil.java | 25 +++++++++++++++++++ 3 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 src/hdskins/java/com/voxelmodpack/hdskins/util/PlayerUtil.java diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java b/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java index 528321eb..8208b363 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java @@ -24,8 +24,11 @@ import com.voxelmodpack.hdskins.skins.LegacySkinServer; import com.voxelmodpack.hdskins.skins.ServerType; import com.voxelmodpack.hdskins.skins.SkinServer; import com.voxelmodpack.hdskins.skins.ValhallaSkinServer; +import com.voxelmodpack.hdskins.util.PlayerUtil; import com.voxelmodpack.hdskins.util.ProfileTextureUtil; import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.AbstractClientPlayer; +import net.minecraft.client.multiplayer.WorldClient; import net.minecraft.client.network.NetHandlerPlayClient; import net.minecraft.client.network.NetworkPlayerInfo; import net.minecraft.client.renderer.texture.ITextureObject; @@ -33,6 +36,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.util.EntitySelectors; import net.minecraft.util.ResourceLocation; import org.apache.commons.io.FileUtils; import org.apache.http.impl.client.CloseableHttpClient; @@ -57,6 +61,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.function.Function; +import java.util.stream.Stream; import javax.annotation.Nullable; public final class HDSkinManager implements IResourceManagerReloadListener { @@ -230,10 +235,10 @@ public final class HDSkinManager implements IResourceManagerReloadListener { private boolean onSkinCacheCleared(ISkinCacheClearListener callback) { try { - return callback.onSkinCacheCleared(); + return !callback.onSkinCacheCleared(); } catch (Exception e) { logger.warn("Exception encountered calling skin listener '{}'. It will be removed.", callback.getClass().getName(), e); - return false; + return true; } } @@ -258,14 +263,25 @@ public final class HDSkinManager implements IResourceManagerReloadListener { public void reloadSkins() { - NetHandlerPlayClient playClient = Minecraft.getMinecraft().getConnection(); + Stream stream = Stream.empty(); + + Minecraft mc = Minecraft.getMinecraft(); + NetHandlerPlayClient playClient = mc.getConnection(); if (playClient != null) { - playClient.getPlayerInfoMap().forEach(this::clearNetworkSkin); + stream = playClient.getPlayerInfoMap().stream(); } + // NPCs might not be in the player list + WorldClient world = mc.world; + if (world != null) { + stream = Stream.concat(stream, world.getPlayers(AbstractClientPlayer.class, EntitySelectors.IS_ALIVE).stream().map(PlayerUtil::getInfo)); + } + stream.distinct().forEach(this::clearNetworkSkin); + clearListeners.removeIf(this::onSkinCacheCleared); } public void parseSkin(GameProfile profile, Type type, ResourceLocation resource, MinecraftProfileTexture texture) { + // grab the metadata object via reflection. Object is live. Map metadata = ProfileTextureUtil.getMetadata(texture); boolean wasNull = metadata == null; @@ -280,7 +296,6 @@ public final class HDSkinManager implements IResourceManagerReloadListener { } } - @Override public void onResourceManagerReload(IResourceManager resourceManager) { this.resources.onResourceManagerReload(resourceManager); diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinNetworkPlayerInfo.java b/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinNetworkPlayerInfo.java index 3948599d..b48501ac 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinNetworkPlayerInfo.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinNetworkPlayerInfo.java @@ -32,6 +32,8 @@ public abstract class MixinNetworkPlayerInfo implements INetworkPlayerInfo { @Shadow private boolean playerTexturesLoaded; @Shadow private String skinType; + @Shadow private Map playerTextures; + @SuppressWarnings("InvalidMemberReference") // mc-dev bug? @Redirect(method = { "getLocationSkin", @@ -95,6 +97,10 @@ public abstract class MixinNetworkPlayerInfo implements INetworkPlayerInfo { @Override public void reloadTextures() { synchronized (this) { + this.playerTextures.clear(); + this.customProfiles.clear(); + this.customTextures.clear(); + this.skinType = null; this.playerTexturesLoaded = false; if (this.gameProfile.getId().equals(Minecraft.getMinecraft().getSession().getProfile().getId())) { // local client skin doesn't have a signature. diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/util/PlayerUtil.java b/src/hdskins/java/com/voxelmodpack/hdskins/util/PlayerUtil.java new file mode 100644 index 00000000..99324fad --- /dev/null +++ b/src/hdskins/java/com/voxelmodpack/hdskins/util/PlayerUtil.java @@ -0,0 +1,25 @@ +package com.voxelmodpack.hdskins.util; + +import net.minecraft.client.entity.AbstractClientPlayer; +import net.minecraft.client.network.NetworkPlayerInfo; +import org.apache.commons.lang3.reflect.FieldUtils; + +import java.lang.reflect.Field; + +public class PlayerUtil { + + private static final Field playerInfo = FieldUtils.getAllFields(AbstractClientPlayer.class)[0]; + + public static NetworkPlayerInfo getInfo(AbstractClientPlayer player) { + try { + if (!playerInfo.isAccessible()) { + playerInfo.setAccessible(true); + } + return (NetworkPlayerInfo) FieldUtils.readField(playerInfo, player); + } catch (IllegalAccessException e) { + e.printStackTrace(); + return null; + } + } + +}