Add basic support for skin meta using webprefs

This commit is contained in:
Matthew Messinger 2016-05-10 15:12:29 -04:00
parent 5ca99920c7
commit c7cf2f3de2
2 changed files with 40 additions and 41 deletions

View file

@ -18,6 +18,7 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import com.mojang.authlib.minecraft.InsecureTextureException; import com.mojang.authlib.minecraft.InsecureTextureException;
import com.mojang.authlib.minecraft.MinecraftProfileTexture; import com.mojang.authlib.minecraft.MinecraftProfileTexture;
@ -27,6 +28,8 @@ import com.mojang.authlib.properties.Property;
import com.mojang.util.UUIDTypeAdapter; import com.mojang.util.UUIDTypeAdapter;
import com.mumfrey.liteloader.core.LiteLoader; import com.mumfrey.liteloader.core.LiteLoader;
import com.mumfrey.liteloader.util.log.LiteLoaderLogger; import com.mumfrey.liteloader.util.log.LiteLoaderLogger;
import com.mumfrey.webprefs.WebPreferencesManager;
import com.mumfrey.webprefs.interfaces.IWebPreferences;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.IImageBuffer; import net.minecraft.client.renderer.IImageBuffer;
@ -36,7 +39,6 @@ import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.resources.DefaultPlayerSkin; import net.minecraft.client.resources.DefaultPlayerSkin;
import net.minecraft.client.resources.SkinManager.SkinAvailableCallback; import net.minecraft.client.resources.SkinManager.SkinAvailableCallback;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StringUtils;
public final class HDSkinManager { public final class HDSkinManager {
@ -51,6 +53,8 @@ public final class HDSkinManager {
private Map<UUID, Map<Type, ResourceLocation>> skinCache = Maps.newHashMap(); private Map<UUID, Map<Type, ResourceLocation>> skinCache = Maps.newHashMap();
private List<ISkinModifier> skinModifiers = Lists.newArrayList(); private List<ISkinModifier> skinModifiers = Lists.newArrayList();
private WebPreferencesManager webprefs = WebPreferencesManager.getDefault();
private HDSkinManager() {} private HDSkinManager() {}
public Optional<ResourceLocation> getSkinLocation(GameProfile profile1, Type type, boolean loadIfAbsent) { public Optional<ResourceLocation> getSkinLocation(GameProfile profile1, Type type, boolean loadIfAbsent) {
@ -103,6 +107,7 @@ public final class HDSkinManager {
if (texture == null) { if (texture == null) {
return; return;
} }
String dir = type.toString().toLowerCase() + "s/"; String dir = type.toString().toLowerCase() + "s/";
final ResourceLocation skin = new ResourceLocation(dir + texture.getHash()); final ResourceLocation skin = new ResourceLocation(dir + texture.getHash());
File file1 = new File(new File("assets/" + dir), texture.getHash().substring(0, 2)); File file1 = new File(new File("assets/" + dir), texture.getHash().substring(0, 2));
@ -135,14 +140,18 @@ public final class HDSkinManager {
Map<Type, MinecraftProfileTexture> textures = this.profileTextures.get(profile.getId()); Map<Type, MinecraftProfileTexture> textures = this.profileTextures.get(profile.getId());
if (textures == null) { if (textures == null) {
IWebPreferences prefs = this.webprefs.getPreferences(profile);
Map<String, String> metadata = new Gson().fromJson(prefs.get("hdskins.metadata"), new TypeToken<Map<String, String>>() {}.getType());
String uuid = UUIDTypeAdapter.fromUUID(profile.getId()); String uuid = UUIDTypeAdapter.fromUUID(profile.getId());
String skinUrl = getCustomSkinURLForId(uuid, false); String skinUrl = getCustomTextureURLForId(Type.SKIN, uuid, false);
String capeUrl = getCustomCloakURLForId(uuid); String capeUrl = getCustomTextureURLForId(Type.CAPE, uuid);
String elytraUrl = getCustomTextureURLForId(Type.ELYTRA, uuid);
// TODO metadata (needs server support) // TODO metadata (needs server support)
textures = ImmutableMap.of( textures = ImmutableMap.of(
Type.SKIN, new MinecraftProfileTexture(skinUrl, null), Type.SKIN, new MinecraftProfileTexture(skinUrl, metadata),
Type.CAPE, new MinecraftProfileTexture(capeUrl, null)); Type.CAPE, new MinecraftProfileTexture(capeUrl, null),
Type.ELYTRA, new MinecraftProfileTexture(elytraUrl, null));
this.profileTextures.put(profile.getId(), textures); this.profileTextures.put(profile.getId(), textures);
} }
return textures; return textures;
@ -184,13 +193,14 @@ public final class HDSkinManager {
return String.format("http://%s/", gatewayUrl); return String.format("http://%s/", gatewayUrl);
} }
public String getCustomSkinURLForId(String uuid, boolean gateway) { public String getCustomTextureURLForId(Type type, String uuid, boolean gateway) {
uuid = StringUtils.stripControlCodes(uuid); String server = gateway ? gatewayUrl : skinUrl;
return String.format("http://%s/skins/%s.png", gateway ? gatewayUrl : skinUrl, uuid); String path = type.toString().toLowerCase() + "s";
return String.format("http://%s/%s/%s.png", server, path, uuid);
} }
public String getCustomCloakURLForId(String uuid) { public String getCustomTextureURLForId(Type type, String uuid) {
return String.format("http://%s/capes/%s.png", skinUrl, StringUtils.stripControlCodes(uuid)); return getCustomTextureURLForId(type, uuid, false);
} }
public void setEnabled(boolean enabled) { public void setEnabled(boolean enabled) {
@ -203,7 +213,7 @@ public final class HDSkinManager {
Map<Type, MinecraftProfileTexture> textures = getTexturesForProfile(profile); Map<Type, MinecraftProfileTexture> textures = getTexturesForProfile(profile);
MinecraftProfileTexture skin = textures.get(Type.SKIN); MinecraftProfileTexture skin = textures.get(Type.SKIN);
if (skin != null) { if (skin != null) {
String url = INSTANCE.getCustomSkinURLForId(UUIDTypeAdapter.fromUUID(profile.getId()), true); String url = INSTANCE.getCustomTextureURLForId(Type.SKIN, UUIDTypeAdapter.fromUUID(profile.getId()), true);
skinTexture = new PreviewTexture(url, DefaultPlayerSkin.getDefaultSkin(profile.getId()), new ImageBufferDownloadHD()); skinTexture = new PreviewTexture(url, DefaultPlayerSkin.getDefaultSkin(profile.getId()), new ImageBufferDownloadHD());
textureManager.loadTexture(skinResource, skinTexture); textureManager.loadTexture(skinResource, skinTexture);
} }

View file

@ -1,6 +1,5 @@
package com.voxelmodpack.hdskins.mixin; package com.voxelmodpack.hdskins.mixin;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
@ -19,36 +18,15 @@ import net.minecraft.util.ResourceLocation;
@Mixin(NetworkPlayerInfo.class) @Mixin(NetworkPlayerInfo.class)
public abstract class MixinPlayerInfo { public abstract class MixinPlayerInfo {
@Final
@Shadow @Shadow
private GameProfile gameProfile; public abstract GameProfile getGameProfile();
@Shadow
private ResourceLocation locationSkin;
@Shadow
public String skinType;
@Inject(
method = "hasLocationSkin",
cancellable = true,
at = @At("RETURN"))
private void hasLocationSkin(CallbackInfoReturnable<Boolean> ci) {
if (locationSkin == null) {
// in case has no skin
Optional<ResourceLocation> skin = HDSkinManager.INSTANCE.getSkinLocation(gameProfile, Type.SKIN, false);
ci.setReturnValue(skin.isPresent());
}
}
@Inject( @Inject(
method = "getLocationSkin", method = "getLocationSkin",
cancellable = true, cancellable = true,
at = @At("RETURN")) at = @At("RETURN"))
private void getLocationSkin(CallbackInfoReturnable<ResourceLocation> ci) { private void getLocationSkin(CallbackInfoReturnable<ResourceLocation> ci) {
Optional<ResourceLocation> skin = HDSkinManager.INSTANCE.getSkinLocation(gameProfile, Type.SKIN, true); getTextureLocation(ci, Type.SKIN);
if (skin.isPresent()) {
// set the skin
ci.setReturnValue(skin.get());
}
} }
@Inject( @Inject(
@ -56,10 +34,21 @@ public abstract class MixinPlayerInfo {
cancellable = true, cancellable = true,
at = @At("RETURN")) at = @At("RETURN"))
private void getLocationCape(CallbackInfoReturnable<ResourceLocation> ci) { private void getLocationCape(CallbackInfoReturnable<ResourceLocation> ci) {
Optional<ResourceLocation> cape = HDSkinManager.INSTANCE.getSkinLocation(gameProfile, Type.CAPE, true); getTextureLocation(ci, Type.CAPE);
if (cape.isPresent()) { }
// set the cape
ci.setReturnValue(cape.get()); @Inject(
method = "getLocationElytra",
cancellable = true,
at = @At("RETURN"))
private void getLocationElytra(CallbackInfoReturnable<ResourceLocation> ci) {
getTextureLocation(ci, Type.ELYTRA);
}
private void getTextureLocation(CallbackInfoReturnable<ResourceLocation> ci, Type type) {
Optional<ResourceLocation> texture = HDSkinManager.INSTANCE.getSkinLocation(getGameProfile(), type, true);
if (texture.isPresent()) {
ci.setReturnValue(texture.get());
} }
} }
@ -68,10 +57,10 @@ public abstract class MixinPlayerInfo {
cancellable = true, cancellable = true,
at = @At("RETURN")) at = @At("RETURN"))
private void getSkinType(CallbackInfoReturnable<String> ci) { private void getSkinType(CallbackInfoReturnable<String> ci) {
MinecraftProfileTexture data = HDSkinManager.INSTANCE.getProfileData(gameProfile).get(Type.SKIN); MinecraftProfileTexture data = HDSkinManager.INSTANCE.getProfileData(getGameProfile()).get(Type.SKIN);
if (data != null) { if (data != null) {
String type = data.getMetadata("model"); String type = data.getMetadata("model");
boolean hasSkin = HDSkinManager.INSTANCE.getSkinLocation(gameProfile, Type.SKIN, false).isPresent(); boolean hasSkin = HDSkinManager.INSTANCE.getSkinLocation(getGameProfile(), Type.SKIN, false).isPresent();
if (hasSkin) { if (hasSkin) {
if (type == null) if (type == null)
type = "default"; type = "default";