This commit is contained in:
Sollace 2018-08-30 13:30:46 +02:00
commit 0debe17afe
6 changed files with 100 additions and 9 deletions

View file

@ -24,8 +24,11 @@ import com.voxelmodpack.hdskins.skins.LegacySkinServer;
import com.voxelmodpack.hdskins.skins.ServerType; import com.voxelmodpack.hdskins.skins.ServerType;
import com.voxelmodpack.hdskins.skins.SkinServer; import com.voxelmodpack.hdskins.skins.SkinServer;
import com.voxelmodpack.hdskins.skins.ValhallaSkinServer; import com.voxelmodpack.hdskins.skins.ValhallaSkinServer;
import com.voxelmodpack.hdskins.util.PlayerUtil;
import com.voxelmodpack.hdskins.util.ProfileTextureUtil; import com.voxelmodpack.hdskins.util.ProfileTextureUtil;
import net.minecraft.client.Minecraft; 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.NetHandlerPlayClient;
import net.minecraft.client.network.NetworkPlayerInfo; import net.minecraft.client.network.NetworkPlayerInfo;
import net.minecraft.client.renderer.texture.ITextureObject; 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.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.util.EntitySelectors;
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;
@ -57,6 +61,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Stream;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public final class HDSkinManager implements IResourceManagerReloadListener { public final class HDSkinManager implements IResourceManagerReloadListener {
@ -230,10 +235,10 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
private boolean onSkinCacheCleared(ISkinCacheClearListener callback) { private boolean onSkinCacheCleared(ISkinCacheClearListener callback) {
try { try {
return callback.onSkinCacheCleared(); return !callback.onSkinCacheCleared();
} catch (Exception e) { } catch (Exception e) {
logger.warn("Exception encountered calling skin listener '{}'. It will be removed.", callback.getClass().getName(), 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() { public void reloadSkins() {
NetHandlerPlayClient playClient = Minecraft.getMinecraft().getConnection(); Stream<NetworkPlayerInfo> stream = Stream.empty();
Minecraft mc = Minecraft.getMinecraft();
NetHandlerPlayClient playClient = mc.getConnection();
if (playClient != null) { 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); clearListeners.removeIf(this::onSkinCacheCleared);
} }
public void parseSkin(GameProfile profile, Type type, ResourceLocation resource, MinecraftProfileTexture texture) { public void parseSkin(GameProfile profile, Type type, ResourceLocation resource, MinecraftProfileTexture texture) {
// grab the metadata object via reflection. Object is live. // grab the metadata object via reflection. Object is live.
Map<String, String> metadata = ProfileTextureUtil.getMetadata(texture); Map<String, String> metadata = ProfileTextureUtil.getMetadata(texture);
boolean wasNull = metadata == null; boolean wasNull = metadata == null;
@ -280,7 +296,6 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
} }
} }
@Override @Override
public void onResourceManagerReload(IResourceManager resourceManager) { public void onResourceManagerReload(IResourceManager resourceManager) {
this.resources.onResourceManagerReload(resourceManager); this.resources.onResourceManagerReload(resourceManager);

View file

@ -32,6 +32,8 @@ public abstract class MixinNetworkPlayerInfo implements INetworkPlayerInfo {
@Shadow private boolean playerTexturesLoaded; @Shadow private boolean playerTexturesLoaded;
@Shadow private String skinType; @Shadow private String skinType;
@Shadow private Map<Type, ResourceLocation> playerTextures;
@SuppressWarnings("InvalidMemberReference") // mc-dev bug? @SuppressWarnings("InvalidMemberReference") // mc-dev bug?
@Redirect(method = { @Redirect(method = {
"getLocationSkin", "getLocationSkin",
@ -95,6 +97,10 @@ public abstract class MixinNetworkPlayerInfo implements INetworkPlayerInfo {
@Override @Override
public void reloadTextures() { public void reloadTextures() {
synchronized (this) { synchronized (this) {
this.playerTextures.clear();
this.customProfiles.clear();
this.customTextures.clear();
this.skinType = null;
this.playerTexturesLoaded = false; this.playerTexturesLoaded = false;
if (this.gameProfile.getId().equals(Minecraft.getMinecraft().getSession().getProfile().getId())) { if (this.gameProfile.getId().equals(Minecraft.getMinecraft().getSession().getProfile().getId())) {
// local client skin doesn't have a signature. // local client skin doesn't have a signature.

View file

@ -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;
}
}
}

View file

@ -164,7 +164,7 @@ public class PonyManager implements IResourceManagerReloadListener, ISkinCacheCl
MineLittlePony.logger.info("Detected {} background ponies installed.", getNumberOfPonies()); MineLittlePony.logger.info("Detected {} background ponies installed.", getNumberOfPonies());
} }
private ResourceLocation getDefaultSkin(UUID uuid) { public static ResourceLocation getDefaultSkin(UUID uuid) {
return isSlimSkin(uuid) ? ALEX : STEVE; return isSlimSkin(uuid) ? ALEX : STEVE;
} }

View file

@ -0,0 +1,44 @@
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.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 {
@Inject(method = "getDefaultSkinLegacy", at = @At("HEAD"), cancellable = true)
private static void legacySkin(CallbackInfoReturnable<ResourceLocation> 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<ResourceLocation> cir) {
if (MineLittlePony.getConfig().getPonyLevel() == PonyLevel.PONIES) {
cir.setReturnValue(PonyManager.getDefaultSkin(uuid));
}
}
@Inject(method = "getSkinType", at = @At("HEAD"), cancellable = true)
private static void skinType(UUID uuid, CallbackInfoReturnable<String> cir) {
if (MineLittlePony.getConfig().getPonyLevel() == PonyLevel.PONIES) {
cir.setReturnValue(MineLittlePony.getInstance().getManager()
.getPony(PonyManager.getDefaultSkin(uuid), uuid)
.getRace(false)
.getModel()
.getId(PonyManager.isSlimSkin(uuid)));
}
}
}

View file

@ -5,10 +5,11 @@
"refmap": "minelp.mixin.refmap.json", "refmap": "minelp.mixin.refmap.json",
"compatibilityLevel": "JAVA_8", "compatibilityLevel": "JAVA_8",
"mixins": [ "mixins": [
"MixinThreadDownloadImageData", "MixinDefaultPlayerSkin",
"MixinRenderItem", "MixinGlStateManager",
"MixinItemRenderer", "MixinItemRenderer",
"MixinRenderItem",
"MixinRenderManager", "MixinRenderManager",
"MixinGlStateManager" "MixinThreadDownloadImageData"
] ]
} }