diff --git a/build.gradle b/build.gradle index 59efd0c3..03d2586a 100644 --- a/build.gradle +++ b/build.gradle @@ -45,16 +45,12 @@ sourceSets { ext.refMap = 'minelp.mixin.refmap.json' } } -repositories { - mavenLocal() -} dependencies { // use the same version as httpclient compile('org.apache.httpcomponents:httpmime:4.3.2') { transitive = false } - deobfCompile 'com.minelittlepony:AvatarAPI:1.0-SNAPSHOT' } litemod { diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java b/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java index d756d630..4daeaf5d 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java @@ -6,14 +6,11 @@ import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; -import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import com.minelittlepony.avatar.texture.TextureData; -import com.minelittlepony.avatar.texture.TextureProfile; -import com.minelittlepony.avatar.texture.TextureType; import com.mojang.authlib.GameProfile; +import com.mojang.authlib.minecraft.MinecraftProfileTexture; import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type; import com.mojang.authlib.properties.Property; import com.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload; @@ -34,6 +31,7 @@ import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.client.resources.DefaultPlayerSkin; import net.minecraft.client.resources.IResourceManager; import net.minecraft.client.resources.IResourceManagerReloadListener; +import net.minecraft.client.resources.SkinManager.SkinAvailableCallback; import net.minecraft.util.ResourceLocation; import org.apache.commons.io.FileUtils; import org.apache.http.impl.client.CloseableHttpClient; @@ -57,7 +55,6 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; -import java.util.function.BiConsumer; import java.util.stream.Collectors; import javax.annotation.Nonnull; @@ -79,10 +76,9 @@ public final class HDSkinManager implements IResourceManagerReloadListener { private BiMap> skinServerTypes = HashBiMap.create(2); private List skinServers = Lists.newArrayList(); - private Map> skinCache = Maps.newHashMap(); + private Map> skinCache = Maps.newHashMap(); - @Deprecated - private LoadingCache> skins = CacheBuilder.newBuilder() + private LoadingCache> skins = CacheBuilder.newBuilder() .initialCapacity(20) .maximumSize(100) .expireAfterWrite(4, TimeUnit.HOURS) @@ -119,8 +115,7 @@ public final class HDSkinManager implements IResourceManagerReloadListener { return new GuiSkins(); } - @Deprecated - public Optional getSkinLocation(GameProfile profile1, final TextureType type, boolean loadIfAbsent) { + public Optional getSkinLocation(GameProfile profile1, final Type type, boolean loadIfAbsent) { if (!enabled) { return Optional.empty(); } @@ -166,7 +161,7 @@ public final class HDSkinManager implements IResourceManagerReloadListener { if (skin == null) { if (loadIfAbsent && getProfileData(profile).containsKey(type)) { skinCache.get(profile.getId()).put(type, LOADING); - loadTexture(profile, type, (t, loc) -> skinCache.get(profile.getId()).put(t, loc.getLocation())); + loadTexture(profile, type, (t, loc, tex) -> skinCache.get(profile.getId()).put(t, loc)); } return Optional.empty(); } @@ -177,19 +172,18 @@ public final class HDSkinManager implements IResourceManagerReloadListener { return url + (url.indexOf('?') > -1 ? '&' : '?') + Long.toString(new Date().getTime() / 1000); } - @Deprecated - private void loadTexture(GameProfile profile, final TextureType type, final BiConsumer callback) { + private void loadTexture(GameProfile profile, final Type type, final SkinAvailableCallback callback) { if (profile.getId() != null) { - Map data = getProfileData(profile); - final TextureProfile texture = data.get(type); + Map data = getProfileData(profile); + final MinecraftProfileTexture texture = data.get(type); String skinDir = type.toString().toLowerCase() + "s/"; final ResourceLocation skin = new ResourceLocation("hdskins", skinDir + texture.getHash()); File file2 = new File(LiteLoader.getAssetsDirectory(), "hd/" + skinDir + texture.getHash().substring(0, 2) + "/" + texture.getHash()); - final IImageBuffer imagebufferdownload = type == TextureType.SKIN ? new ImageBufferDownloadHD() : null; + final IImageBuffer imagebufferdownload = type == Type.SKIN ? new ImageBufferDownloadHD() : null; - ITextureObject texObject = new ThreadDownloadImageETag(file2, bustCache(texture.getUrl().toString()), + ITextureObject texObject = new ThreadDownloadImageETag(file2, bustCache(texture.getUrl()), DefaultPlayerSkin.getDefaultSkinLegacy(), new IImageBuffer() { @Nonnull @@ -207,7 +201,7 @@ public final class HDSkinManager implements IResourceManagerReloadListener { if (imagebufferdownload != null) { imagebufferdownload.skinAvailable(); } - callback.accept(type, new TextureData(skin, texture)); + callback.skinAvailable(type, skin, texture); } }); @@ -216,9 +210,8 @@ public final class HDSkinManager implements IResourceManagerReloadListener { } } - @Deprecated - private Map loadProfileData(GameProfile profile) { - Map textures = Maps.newHashMap(); + private Map loadProfileData(GameProfile profile) { + Map textures = Maps.newEnumMap(Type.class); for (SkinServer server : skinServers) { try { server.loadProfileData(profile).getTextures().forEach(textures::putIfAbsent); @@ -233,10 +226,9 @@ public final class HDSkinManager implements IResourceManagerReloadListener { return textures; } - @Deprecated - public Map getProfileData(GameProfile profile) { + public Map getProfileData(GameProfile profile) { boolean was = !skins.asMap().containsKey(profile); - Map textures = skins.getUnchecked(profile); + Map textures = skins.getUnchecked(profile); // This is the initial value. Refreshing will load it asynchronously. if (was) { skins.refresh(profile); @@ -267,16 +259,12 @@ public final class HDSkinManager implements IResourceManagerReloadListener { return this.skinServers.get(0); } - public List getSkinServers() { - return ImmutableList.copyOf(skinServers); - } - public void setEnabled(boolean enabled) { this.enabled = enabled; } public static CompletableFuture getPreviewTextureManager(GameProfile profile) { - return INSTANCE.getGatewayServer().getPreviewTextures(profile).thenApply(p -> new PreviewTextureManager(p.getTextures())); + return INSTANCE.getGatewayServer().getPreviewTextures(profile).thenApply(PreviewTextureManager::new); } public void addClearListener(ISkinCacheClearListener listener) { diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinTextureService.java b/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinTextureService.java deleted file mode 100644 index 20e384d4..00000000 --- a/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinTextureService.java +++ /dev/null @@ -1,149 +0,0 @@ -package com.voxelmodpack.hdskins; - -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; -import com.google.common.collect.Iterables; -import com.minelittlepony.avatar.texture.TextureData; -import com.minelittlepony.avatar.texture.TextureProfile; -import com.minelittlepony.avatar.texture.TextureService; -import com.minelittlepony.avatar.texture.TextureType; -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.properties.Property; -import com.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload; -import com.voxelmodpack.hdskins.skins.CallableFutures; -import com.voxelmodpack.hdskins.skins.SkinServer; -import net.minecraft.client.renderer.IImageBuffer; -import net.minecraft.client.renderer.texture.ITextureObject; -import net.minecraft.client.resources.DefaultPlayerSkin; -import net.minecraft.launchwrapper.Launch; -import net.minecraft.util.ResourceLocation; -import org.apache.http.client.utils.URIBuilder; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; -import java.net.URI; -import java.nio.charset.StandardCharsets; -import java.util.Base64; -import java.util.Calendar; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.function.BiConsumer; - -import javax.annotation.Nullable; - -public class HDSkinTextureService implements TextureService { - - private static final Logger logger = LogManager.getLogger(); - private static ExecutorService THREAD_POOL = Executors.newCachedThreadPool(); - - private final LoadingCache>> cache = CacheBuilder.newBuilder() - .expireAfterAccess(15, TimeUnit.SECONDS) - .build(new CacheLoader>>() { - @Override - public CompletableFuture> load(GameProfile key) { - return CallableFutures.asyncFailableFuture(() -> loadTexturesFromServer(key), THREAD_POOL) - .exceptionally(e -> { - logger.catching(e); - return Collections.emptyMap(); - }); - } - }); - - private BiMap> skinServerTypes = HashBiMap.create(2); - - @Override - public CompletableFuture> loadProfileTextures(GameProfile profile) { - // try to recreate a broken gameprofile - // happens when server sends a random profile with skin and displayname - Property textures = Iterables.getFirst(profile.getProperties().get("textures"), null); - if (textures != null) { - String json = new String(Base64.getDecoder().decode(textures.getValue()), StandardCharsets.UTF_8); - MinecraftTexturesPayload texturePayload = SkinServer.gson.fromJson(json, MinecraftTexturesPayload.class); - if (texturePayload != null) { - // name is optional - String name = texturePayload.getProfileName(); - UUID uuid = texturePayload.getProfileId(); - // uuid is required - if (uuid != null) { - profile = new GameProfile(uuid, name); - } - - // probably uses this texture for a reason. Don't mess with it. - if (!texturePayload.getTextures().isEmpty() && texturePayload.getProfileId() == null) { - return CompletableFuture.completedFuture(Collections.emptyMap()); - } - } - } - return cache.getUnchecked(profile); - } - - private Map loadTexturesFromServer(GameProfile profile) throws IOException { - - Map textures = new HashMap<>(); - for (SkinServer server : HDSkinManager.INSTANCE.getSkinServers()) { - Map payload = server.loadProfileData(profile).getTextures(); - if (payload != null) { - payload.forEach(textures::putIfAbsent); - } - } - return textures; - } - - @Override - public TextureData loadTexture(TextureType type, TextureProfile texture, @Nullable BiConsumer callback) { - - String url = bustCache(texture.getUrl()); - String skinDir = type.toString().toLowerCase() + "s/"; - final ResourceLocation skin = new ResourceLocation("hdskins", skinDir + texture.getHash()); - TextureData data = new TextureData(skin, texture); - - File file2 = new File(Launch.assetsDir, "hd/" + skinDir + texture.getHash().substring(0, 2) + "/" + texture.getHash()); - - final IImageBuffer buffer = type == TextureType.SKIN ? new ImageBufferDownloadHD() : null; - - - // an actual callback is not needed because that is handled by CompletableFuture - ITextureObject texObject = new ThreadDownloadImageETag(file2, url, DefaultPlayerSkin.getDefaultSkinLegacy(), - new IImageBuffer() { - @Override - public BufferedImage parseUserSkin(BufferedImage image) { - BufferedImage image1 = image; - if (buffer != null) { - image1 = buffer.parseUserSkin(image); - } - return image1 == null ? image : image1; - } - - @Override - public void skinAvailable() { - if (callback != null) { - callback.accept(type, data); - } - } - - }); - TextureLoader.loadTexture(skin, texObject); - - return new TextureData(skin, texture); - } - - private static String bustCache(URI url) { - - long time = Calendar.getInstance().getTimeInMillis(); - - return new URIBuilder(url).addParameter(Long.toString(time), null).toString(); - } - -} diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/LocalTexture.java b/src/hdskins/java/com/voxelmodpack/hdskins/LocalTexture.java index 1b416191..6b2ee1a7 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/LocalTexture.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/LocalTexture.java @@ -1,20 +1,20 @@ package com.voxelmodpack.hdskins; -import com.minelittlepony.avatar.texture.TextureData; -import com.minelittlepony.avatar.texture.TextureType; -import com.mojang.authlib.GameProfile; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.texture.DynamicTexture; -import net.minecraft.client.renderer.texture.TextureManager; -import net.minecraft.util.ResourceLocation; - import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; -import java.util.function.BiConsumer; import javax.imageio.ImageIO; +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.texture.DynamicTexture; +import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.client.resources.SkinManager.SkinAvailableCallback; +import net.minecraft.util.ResourceLocation; + public class LocalTexture { private final TextureManager textureManager = Minecraft.getMinecraft().getTextureManager(); @@ -27,13 +27,13 @@ public class LocalTexture { private final IBlankSkinSupplier blank; - private final TextureType type; + private final Type type; - public LocalTexture(GameProfile profile, TextureType type, IBlankSkinSupplier blank) { + public LocalTexture(GameProfile profile, Type type, IBlankSkinSupplier blank) { this.blank = blank; this.type = type; - String file = type.toString().toLowerCase() + "s/preview_${profile.getName()}.png"; + String file = type.name().toLowerCase() + "s/preview_${profile.getName()}.png"; remoteResource = new ResourceLocation(file); textureManager.deleteTexture(remoteResource); @@ -73,7 +73,7 @@ public class LocalTexture { return remote; } - public void setRemote(PreviewTextureManager ptm, BiConsumer callback) { + public void setRemote(PreviewTextureManager ptm, SkinAvailableCallback callback) { clearRemote(); remote = ptm.getPreviewTexture(remoteResource, type, blank.getBlankSkin(type), callback); @@ -113,6 +113,6 @@ public class LocalTexture { } public interface IBlankSkinSupplier { - ResourceLocation getBlankSkin(TextureType type); + ResourceLocation getBlankSkin(Type type); } } diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/PreviewTexture.java b/src/hdskins/java/com/voxelmodpack/hdskins/PreviewTexture.java index abbc638b..e5430ee2 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/PreviewTexture.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/PreviewTexture.java @@ -1,6 +1,5 @@ package com.voxelmodpack.hdskins; -import com.minelittlepony.avatar.texture.TextureProfile; import net.minecraft.client.renderer.IImageBuffer; import net.minecraft.client.renderer.ThreadDownloadImageData; import net.minecraft.util.ResourceLocation; @@ -13,10 +12,10 @@ public class PreviewTexture extends ThreadDownloadImageData { private String model; - public PreviewTexture(TextureProfile profile, ResourceLocation fallbackTexture, @Nullable IImageBuffer imageBuffer) { - super(null, profile.getUrl().toString(), fallbackTexture, imageBuffer); + public PreviewTexture(@Nullable String model, String url, ResourceLocation fallbackTexture, @Nullable IImageBuffer imageBuffer) { + super(null, url, fallbackTexture, imageBuffer); - this.model = profile.getMetadata("model").orElse("default"); + this.model = model == null ? "default" : model; } public boolean isTextureUploaded() { diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/PreviewTextureManager.java b/src/hdskins/java/com/voxelmodpack/hdskins/PreviewTextureManager.java index 535961a8..18cf587d 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/PreviewTextureManager.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/PreviewTextureManager.java @@ -1,14 +1,14 @@ package com.voxelmodpack.hdskins; -import com.minelittlepony.avatar.texture.TextureData; -import com.minelittlepony.avatar.texture.TextureProfile; -import com.minelittlepony.avatar.texture.TextureType; +import com.google.common.collect.Maps; +import com.mojang.authlib.minecraft.MinecraftProfileTexture; +import com.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload; import net.minecraft.client.renderer.IImageBuffer; +import net.minecraft.client.resources.SkinManager; import net.minecraft.util.ResourceLocation; import java.awt.image.BufferedImage; import java.util.Map; -import java.util.function.BiConsumer; import javax.annotation.Nullable; @@ -18,22 +18,22 @@ import javax.annotation.Nullable; */ public class PreviewTextureManager { - private final Map textures; + private final Map textures; - PreviewTextureManager(Map textures) { - this.textures = textures; + PreviewTextureManager(MinecraftTexturesPayload payload) { + this.textures = payload.getTextures(); } @Nullable - public PreviewTexture getPreviewTexture(ResourceLocation location, TextureType type, ResourceLocation def, - @Nullable BiConsumer callback) { + public PreviewTexture getPreviewTexture(ResourceLocation location, MinecraftProfileTexture.Type type, ResourceLocation def, + @Nullable SkinManager.SkinAvailableCallback callback) { if (!textures.containsKey(type)) { return null; } - TextureProfile texture = textures.get(type); + MinecraftProfileTexture texture = textures.get(type); IImageBuffer buffer = new ImageBufferDownloadHD(); - PreviewTexture skinTexture = new PreviewTexture(texture, def, - type == TextureType.SKIN ? new IImageBuffer() { + PreviewTexture skinTexture = new PreviewTexture(texture.getMetadata("model"), texture.getUrl(), def, + type == MinecraftProfileTexture.Type.SKIN ? new IImageBuffer() { @Override @Nullable public BufferedImage parseUserSkin(BufferedImage image) { @@ -43,7 +43,7 @@ public class PreviewTextureManager { @Override public void skinAvailable() { if (callback != null) { - callback.accept(type, new TextureData(location, texture)); + callback.skinAvailable(type, location, new MinecraftProfileTexture(texture.getUrl(), Maps.newHashMap())); } } } : null); @@ -52,5 +52,4 @@ public class PreviewTextureManager { return skinTexture; } - } diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/gui/EntityPlayerModel.java b/src/hdskins/java/com/voxelmodpack/hdskins/gui/EntityPlayerModel.java index f857c144..ede55f4f 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/gui/EntityPlayerModel.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/gui/EntityPlayerModel.java @@ -2,13 +2,13 @@ package com.voxelmodpack.hdskins.gui; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; -import com.minelittlepony.avatar.texture.TextureData; -import com.minelittlepony.avatar.texture.TextureType; import com.mojang.authlib.GameProfile; +import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type; import com.voxelmodpack.hdskins.HDSkinManager; import com.voxelmodpack.hdskins.LocalTexture; import com.voxelmodpack.hdskins.LocalTexture.IBlankSkinSupplier; import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.SkinManager; import net.minecraft.entity.EntityLivingBase; import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.ItemStack; @@ -17,7 +17,6 @@ import net.minecraft.util.ResourceLocation; import java.io.File; import java.util.Map; -import java.util.function.BiConsumer; @SuppressWarnings("EntityConstructor") public class EntityPlayerModel extends EntityLivingBase implements IBlankSkinSupplier { @@ -44,28 +43,28 @@ public class EntityPlayerModel extends EntityLivingBase implements IBlankSkinSup super(new DummyWorld()); profile = gameprofile; - skin = new LocalTexture(profile, TextureType.SKIN, this); - elytra = new LocalTexture(profile, TextureType.ELYTRA, this); + skin = new LocalTexture(profile, Type.SKIN, this); + elytra = new LocalTexture(profile, Type.ELYTRA, this); } - public void reloadRemoteSkin(BiConsumer listener) { + public void reloadRemoteSkin(SkinManager.SkinAvailableCallback listener) { HDSkinManager.getPreviewTextureManager(profile).thenAccept(ptm -> { skin.setRemote(ptm, listener); elytra.setRemote(ptm, listener); }); } - public void setLocalTexture(File skinTextureFile, TextureType type) { - if (type == TextureType.SKIN) { + public void setLocalTexture(File skinTextureFile, Type type) { + if (type == Type.SKIN) { skin.setLocal(skinTextureFile); - } else if (type == TextureType.ELYTRA) { + } else if (type == Type.ELYTRA) { elytra.setLocal(skinTextureFile); } } @Override - public ResourceLocation getBlankSkin(TextureType type) { - return type == TextureType.SKIN ? NO_SKIN : NO_ELYTRA; + public ResourceLocation getBlankSkin(Type type) { + return type == Type.SKIN ? NO_SKIN : NO_ELYTRA; } public boolean isUsingLocalTexture() { @@ -81,8 +80,8 @@ public class EntityPlayerModel extends EntityLivingBase implements IBlankSkinSup elytra.clearLocal(); } - public LocalTexture getLocal(TextureType type) { - return type == TextureType.SKIN ? skin : elytra; + public LocalTexture getLocal(Type type) { + return type == Type.SKIN ? skin : elytra; } public void setPreviewThinArms(boolean thinArms) { diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiSkins.java b/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiSkins.java index 6b05c8e6..5a98ef9e 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiSkins.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiSkins.java @@ -1,20 +1,25 @@ package com.voxelmodpack.hdskins.gui; +import static com.mojang.authlib.minecraft.MinecraftProfileTexture.Type.ELYTRA; +import static com.mojang.authlib.minecraft.MinecraftProfileTexture.Type.SKIN; +import static net.minecraft.client.renderer.GlStateManager.*; + import com.google.common.base.Splitter; import com.google.common.base.Throwables; import com.google.common.collect.ImmutableMap; -import com.minelittlepony.avatar.texture.TextureData; -import com.minelittlepony.avatar.texture.TextureType; import com.minelittlepony.gui.Button; import com.minelittlepony.gui.GameGui; import com.minelittlepony.gui.IconicButton; import com.minelittlepony.gui.Label; import com.mojang.authlib.GameProfile; +import com.mojang.authlib.minecraft.MinecraftProfileTexture; +import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type; import com.mumfrey.liteloader.util.log.LiteLoaderLogger; import com.voxelmodpack.hdskins.HDSkinManager; import com.voxelmodpack.hdskins.skins.SkinUpload; import com.voxelmodpack.hdskins.skins.SkinUploadResponse; import com.voxelmodpack.hdskins.upload.awt.ThreadOpenFilePNG; + import net.minecraft.client.Minecraft; import net.minecraft.client.audio.PositionedSoundRecord; import net.minecraft.client.gui.Gui; @@ -27,7 +32,9 @@ import net.minecraft.init.SoundEvents; import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.MathHelper; + import org.apache.commons.io.FilenameUtils; import org.apache.logging.log4j.LogManager; import org.lwjgl.BufferUtils; @@ -45,21 +52,6 @@ import javax.annotation.Nullable; import javax.imageio.ImageIO; import javax.swing.UIManager; -import static com.minelittlepony.avatar.texture.TextureType.ELYTRA; -import static com.minelittlepony.avatar.texture.TextureType.SKIN; -import static net.minecraft.client.renderer.GlStateManager.depthMask; -import static net.minecraft.client.renderer.GlStateManager.disableColorMaterial; -import static net.minecraft.client.renderer.GlStateManager.disableDepth; -import static net.minecraft.client.renderer.GlStateManager.enableBlend; -import static net.minecraft.client.renderer.GlStateManager.enableColorMaterial; -import static net.minecraft.client.renderer.GlStateManager.enableDepth; -import static net.minecraft.client.renderer.GlStateManager.popAttrib; -import static net.minecraft.client.renderer.GlStateManager.popMatrix; -import static net.minecraft.client.renderer.GlStateManager.pushMatrix; -import static net.minecraft.client.renderer.GlStateManager.rotate; -import static net.minecraft.client.renderer.GlStateManager.scale; -import static net.minecraft.client.renderer.GlStateManager.translate; - public class GuiSkins extends GameGui { private static final int MAX_SKIN_DIMENSION = 1024; @@ -102,13 +94,14 @@ public class GuiSkins extends GameGui { private File selectedSkin; + private int lastMouseX = 0; private static GuiSkins instance; protected CubeMap panorama; - private TextureType textureType = SKIN; + private MinecraftProfileTexture.Type textureType = SKIN; private boolean thinArmType = false; static { @@ -193,10 +186,10 @@ public class GuiSkins extends GameGui { } - protected void onSetRemoteSkin(TextureType type, TextureData texture) { + protected void onSetRemoteSkin(Type type, ResourceLocation location, MinecraftProfileTexture profileTexture) { } - protected void onSetLocalSkin(TextureType type) { + protected void onSetLocalSkin(Type type) { } private void reloadRemoteSkin() { @@ -223,7 +216,7 @@ public class GuiSkins extends GameGui { addButton(new Label(34, 34, "hdskins.local", 0xffffff)); addButton(new Label(width / 2 + 34, 34, "hdskins.server", 0xffffff)); - addButton(new Button(width / 2 - 150, height - 27, 90, 20, "hdskins.options.browse", sender -> { + addButton(new Button(width / 2 - 150, height - 27, 90, 20, "hdskins.options.browse", sender ->{ selectedSkin = null; localPlayer.releaseTextures(); openFileThread = new ThreadOpenFilePNG(mc, format("hdskins.open.title"), (fileDialog, dialogResult) -> { @@ -262,12 +255,11 @@ public class GuiSkins extends GameGui { addButton(btnModeSkin = new IconicButton(width - 25, 75, sender -> { switchSkinType(sender, SKIN); - }).setIcon(new ItemStack(Items.LEATHER_CHESTPLATE))).setEnabled(textureType == ELYTRA) - .setTooltip(format("hdskins.mode.skin", toTitleCase(SKIN.toString()))); + }).setIcon(new ItemStack(Items.LEATHER_CHESTPLATE))).setEnabled(textureType == ELYTRA).setTooltip(format("hdskins.mode.skin", toTitleCase(SKIN.name()))); addButton(btnModeElytra = new IconicButton(width - 25, 94, sender -> { switchSkinType(sender, ELYTRA); - }).setIcon(new ItemStack(Items.ELYTRA))).setEnabled(textureType == SKIN).setTooltip(format("hdskins.mode.skin", toTitleCase(ELYTRA.toString()))); + }).setIcon(new ItemStack(Items.ELYTRA))).setEnabled(textureType == SKIN).setTooltip(format("hdskins.mode.skin", toTitleCase(ELYTRA.name()))); addButton(new Button(width - 25, height - 65, 20, 20, "?", sender -> { @@ -316,7 +308,7 @@ public class GuiSkins extends GameGui { return isPowerOfTwo(w) && w == h * 2 || w == h && w <= MAX_SKIN_DIMENSION && h <= MAX_SKIN_DIMENSION; } - protected void switchSkinType(Button sender, TextureType newType) { + protected void switchSkinType(Button sender, Type newType) { mc.getSoundHandler().playSound(PositionedSoundRecord.getMasterRecord(SoundEvents.BLOCK_BREWING_STAND_BREW, 1)); textureType = newType; @@ -444,7 +436,7 @@ public class GuiSkins extends GameGui { if (!localPlayer.isUsingLocalTexture()) { Gui.drawRect(40, height / 2 - 12, width / 2 - 40, height / 2 + 12, 0xB0000000); - drawCenteredString(fontRenderer, localMessage, (int) xPos1, height / 2 - 4, 0xffffff); + drawCenteredString(fontRenderer, localMessage, (int)xPos1, height / 2 - 4, 0xffffff); } if (fetchingSkin) { @@ -454,10 +446,10 @@ public class GuiSkins extends GameGui { Gui.drawRect((int) (xPos2 - width / 4 + 40), height / 2 - lineHeight, width - 40, height / 2 + lineHeight, 0xB0000000); if (throttledByMojang) { - drawCenteredString(fontRenderer, format("hdskins.error.mojang"), (int) xPos2, height / 2 - 10, 0xffffff); - drawCenteredString(fontRenderer, format("hdskins.error.mojang.wait"), (int) xPos2, height / 2 + 2, 0xffffff); + drawCenteredString(fontRenderer, format("hdskins.error.mojang"), (int)xPos2, height / 2 - 10, 0xffffff); + drawCenteredString(fontRenderer, format("hdskins.error.mojang.wait"), (int)xPos2, height / 2 + 2, 0xffffff); } else { - drawCenteredString(fontRenderer, format("hdskins.fetch"), (int) xPos2, height / 2 - 4, 0xffffff); + drawCenteredString(fontRenderer, format("hdskins.fetch"), (int)xPos2, height / 2 - 4, 0xffffff); } } @@ -490,9 +482,8 @@ public class GuiSkins extends GameGui { enableDepth(); } - private void renderPlayerModel(EntityPlayerModel thePlayer, float xPosition, float yPosition, float scale, float mouseY, float mouseX, - float partialTick) { - mc.getTextureManager().bindTexture(thePlayer.getLocal(SKIN).getTexture()); + private void renderPlayerModel(EntityPlayerModel thePlayer, float xPosition, float yPosition, float scale, float mouseY, float mouseX, float partialTick) { + mc.getTextureManager().bindTexture(thePlayer.getLocal(Type.SKIN).getTexture()); enableColorMaterial(); pushMatrix(); @@ -505,8 +496,8 @@ public class GuiSkins extends GameGui { rotate(((updateCounter + partialTick) * 2.5F) % 360, 0, 1, 0); - thePlayer.rotationYawHead = (float) Math.atan(mouseX / 20) * 30; - thePlayer.rotationPitch = (float) Math.atan(mouseY / 40) * -20; + thePlayer.rotationYawHead = (float)Math.atan(mouseX / 20) * 30; + thePlayer.rotationPitch = (float)Math.atan(mouseY / 40) * -20; mc.getRenderManager().renderEntity(thePlayer, 0, 0, 0, 0, 1, false); diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/gui/RenderPlayerModel.java b/src/hdskins/java/com/voxelmodpack/hdskins/gui/RenderPlayerModel.java index 0f99befa..9b2d37dd 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/gui/RenderPlayerModel.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/gui/RenderPlayerModel.java @@ -1,6 +1,5 @@ package com.voxelmodpack.hdskins.gui; -import com.minelittlepony.avatar.texture.TextureType; import net.minecraft.client.Minecraft; import net.minecraft.client.model.ModelBiped.ArmPose; import net.minecraft.client.model.ModelElytra; @@ -15,18 +14,14 @@ import net.minecraft.init.Items; import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.ItemStack; import net.minecraft.util.ResourceLocation; + import org.lwjgl.opengl.GL11; +import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type; + import java.util.Set; -import static net.minecraft.client.renderer.GlStateManager.color; -import static net.minecraft.client.renderer.GlStateManager.disableBlend; -import static net.minecraft.client.renderer.GlStateManager.enableBlend; -import static net.minecraft.client.renderer.GlStateManager.popAttrib; -import static net.minecraft.client.renderer.GlStateManager.popMatrix; -import static net.minecraft.client.renderer.GlStateManager.pushMatrix; -import static net.minecraft.client.renderer.GlStateManager.scale; -import static net.minecraft.client.renderer.GlStateManager.translate; +import static net.minecraft.client.renderer.GlStateManager.*; public class RenderPlayerModel extends RenderLivingBase { @@ -56,7 +51,7 @@ public class RenderPlayerModel extends RenderLiving GlStateManager.enableBlend(); GlStateManager.blendFunc(GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); - bindTexture(entity.getLocal(TextureType.ELYTRA).getTexture()); + bindTexture(entity.getLocal(Type.ELYTRA).getTexture()); GlStateManager.pushMatrix(); GlStateManager.translate(0, 0, 0.125F); @@ -78,7 +73,7 @@ public class RenderPlayerModel extends RenderLiving @Override protected ResourceLocation getEntityTexture(M entity) { - return entity.getLocal(TextureType.SKIN).getTexture(); + return entity.getLocal(Type.SKIN).getTexture(); } @Override diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinPlayerInfo.java b/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinPlayerInfo.java new file mode 100644 index 00000000..432c383d --- /dev/null +++ b/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinPlayerInfo.java @@ -0,0 +1,68 @@ +package com.voxelmodpack.hdskins.mixin; + +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.minecraft.MinecraftProfileTexture; +import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type; +import com.voxelmodpack.hdskins.HDSkinManager; +import net.minecraft.client.network.NetworkPlayerInfo; +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.Optional; + +@Mixin(NetworkPlayerInfo.class) +public abstract class MixinPlayerInfo { + + @Shadow + public abstract GameProfile getGameProfile(); + + @Inject( + method = "getLocationSkin", + cancellable = true, + at = @At("RETURN")) + private void getLocationSkin(CallbackInfoReturnable ci) { + getTextureLocation(ci, Type.SKIN); + } + + @Inject( + method = "getLocationCape", + cancellable = true, + at = @At("RETURN")) + private void getLocationCape(CallbackInfoReturnable ci) { + getTextureLocation(ci, Type.CAPE); + } + + @Inject( + method = "getLocationElytra", + cancellable = true, + at = @At("RETURN")) + private void getLocationElytra(CallbackInfoReturnable ci) { + getTextureLocation(ci, Type.ELYTRA); + } + + private void getTextureLocation(CallbackInfoReturnable ci, Type type) { + Optional texture = HDSkinManager.INSTANCE.getSkinLocation(getGameProfile(), type, true); + texture.ifPresent(ci::setReturnValue); + } + + @Inject( + method = "getSkinType", + cancellable = true, + at = @At("RETURN")) + private void getSkinType(CallbackInfoReturnable ci) { + MinecraftProfileTexture skin = HDSkinManager.INSTANCE.getProfileData(getGameProfile()).get(Type.SKIN); + if (skin != null) { + String type = skin.getMetadata("model"); + if (type == null) + type = "default"; + String type1 = type; + Optional texture = HDSkinManager.INSTANCE.getSkinLocation(getGameProfile(), Type.SKIN, false); + + texture.ifPresent((res) -> ci.setReturnValue(type1)); + } + } +} diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinSkullRenderer.java b/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinSkullRenderer.java new file mode 100644 index 00000000..dda9662c --- /dev/null +++ b/src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinSkullRenderer.java @@ -0,0 +1,39 @@ +package com.voxelmodpack.hdskins.mixin; + +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type; +import com.voxelmodpack.hdskins.HDSkinManager; +import net.minecraft.client.renderer.tileentity.TileEntitySkullRenderer; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.tileentity.TileEntitySkull; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import javax.annotation.Nullable; +import java.util.Optional; + +@Mixin(TileEntitySkullRenderer.class) +public abstract class MixinSkullRenderer extends TileEntitySpecialRenderer { + + @Redirect( + method = "renderSkull", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/renderer/tileentity/TileEntitySkullRenderer;bindTexture(Lnet/minecraft/util/ResourceLocation;)V", + ordinal = 4)) + private void onBindTexture(TileEntitySkullRenderer tesr, ResourceLocation rl, float x, float y, float z, EnumFacing facing, float rotation, int meta, + @Nullable GameProfile profile, int p_180543_8_, float ticks) { + if (profile != null) { + Optional skin = HDSkinManager.INSTANCE.getSkinLocation(profile, Type.SKIN, true); + if (skin.isPresent()) + // rebind + bindTexture(skin.get()); + else + bindTexture(rl); + } else + bindTexture(rl); + } +} diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/mixin/package-info.java b/src/hdskins/java/com/voxelmodpack/hdskins/mixin/package-info.java new file mode 100644 index 00000000..e502527b --- /dev/null +++ b/src/hdskins/java/com/voxelmodpack/hdskins/mixin/package-info.java @@ -0,0 +1,7 @@ +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package com.voxelmodpack.hdskins.mixin; + +import mcp.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/resource/SkinResourceManager.java b/src/hdskins/java/com/voxelmodpack/hdskins/resource/SkinResourceManager.java index 4a34778b..d02b22df 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/resource/SkinResourceManager.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/resource/SkinResourceManager.java @@ -3,8 +3,8 @@ package com.voxelmodpack.hdskins.resource; import com.google.common.collect.Maps; import com.google.gson.Gson; import com.google.gson.JsonParseException; -import com.minelittlepony.avatar.texture.TextureType; import com.mojang.authlib.GameProfile; +import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type; import com.mumfrey.liteloader.util.log.LiteLoaderLogger; import net.minecraft.client.resources.IResource; import net.minecraft.client.resources.IResourceManager; @@ -13,6 +13,7 @@ import net.minecraft.util.ResourceLocation; import org.apache.commons.io.IOUtils; import org.apache.logging.log4j.LogManager; +import javax.annotation.Nullable; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -23,8 +24,6 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; -import javax.annotation.Nullable; - public class SkinResourceManager implements IResourceManagerReloadListener { private ExecutorService executor = Executors.newSingleThreadExecutor(); @@ -75,8 +74,8 @@ public class SkinResourceManager implements IResourceManagerReloadListener { } @Nullable - public ResourceLocation getPlayerTexture(GameProfile profile, TextureType type) { - if (type != TextureType.SKIN) + public ResourceLocation getPlayerTexture(GameProfile profile, Type type) { + if (type != Type.SKIN) // not supported return null; diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/skins/BethlehemSkinServer.java b/src/hdskins/java/com/voxelmodpack/hdskins/skins/BethlehemSkinServer.java index 5e8b1509..0ae82762 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/skins/BethlehemSkinServer.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/skins/BethlehemSkinServer.java @@ -4,6 +4,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap.Builder; import com.google.gson.annotations.Expose; import com.mojang.authlib.GameProfile; +import com.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload; import com.mojang.util.UUIDTypeAdapter; import com.voxelmodpack.hdskins.HDSkinManager; import net.minecraft.util.Session; @@ -26,14 +27,14 @@ public class BethlehemSkinServer implements SkinServer { } @Override - public TexturesPayload loadProfileData(GameProfile profile) throws IOException { + public MinecraftTexturesPayload loadProfileData(GameProfile profile) throws IOException { // TODO: Fix this try (MoreHttpResponses response = new NetClient("GET", getPath(profile)).send()) { if (!response.ok()) { throw new IOException(response.getResponse().getStatusLine().getReasonPhrase()); } - return response.json(TexturesPayload.class); + return response.json(MinecraftTexturesPayload.class); } } diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/skins/LegacySkinServer.java b/src/hdskins/java/com/voxelmodpack/hdskins/skins/LegacySkinServer.java index 741564b8..9ea4318b 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/skins/LegacySkinServer.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/skins/LegacySkinServer.java @@ -3,9 +3,9 @@ package com.voxelmodpack.hdskins.skins; import com.google.common.base.Strings; import com.google.common.collect.ImmutableMap; import com.google.gson.annotations.Expose; -import com.minelittlepony.avatar.texture.TextureProfile; -import com.minelittlepony.avatar.texture.TextureType; import com.mojang.authlib.GameProfile; +import com.mojang.authlib.minecraft.MinecraftProfileTexture; +import com.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload; import com.mojang.util.UUIDTypeAdapter; import com.voxelmodpack.hdskins.HDSkinManager; import com.voxelmodpack.hdskins.upload.ThreadMultipartPostUpload; @@ -16,7 +16,8 @@ import org.apache.logging.log4j.Logger; import java.io.IOException; import java.net.HttpURLConnection; import java.net.URI; -import java.util.HashMap; +import java.net.URL; +import java.util.EnumMap; import java.util.Locale; import java.util.Map; import java.util.concurrent.CompletableFuture; @@ -41,23 +42,23 @@ public class LegacySkinServer implements SkinServer { } @Override - public CompletableFuture getPreviewTextures(GameProfile profile) { + public CompletableFuture getPreviewTextures(GameProfile profile) { if (Strings.isNullOrEmpty(this.gateway)) { return CallableFutures.failedFuture(gatewayUnsupported()); } - Map map = new HashMap<>(); - for (TextureType type : TextureType.values()) { - map.put(type, new TextureProfile(getPath(gateway, type, profile), null)); + Map map = new EnumMap<>(MinecraftProfileTexture.Type.class); + for (MinecraftProfileTexture.Type type : MinecraftProfileTexture.Type.values()) { + map.put(type, new MinecraftProfileTexture(getPath(gateway, type, profile), null)); } - return CompletableFuture.completedFuture(new TexturesPayload(profile, map)); + return CompletableFuture.completedFuture(TexturesPayloadBuilder.createTexturesPayload(profile, map)); } @Override - public TexturesPayload loadProfileData(GameProfile profile) throws IOException { - ImmutableMap.Builder builder = ImmutableMap.builder(); - for (TextureType type : TextureType.values()) { + public MinecraftTexturesPayload loadProfileData(GameProfile profile) throws IOException { + ImmutableMap.Builder builder = ImmutableMap.builder(); + for (MinecraftProfileTexture.Type type : MinecraftProfileTexture.Type.values()) { - URI url = getPath(this.address, type, profile); + String url = getPath(this.address, type, profile); try { builder.put(type, loadProfileTexture(profile, url)); } catch (IOException e) { @@ -65,20 +66,20 @@ public class LegacySkinServer implements SkinServer { } } - Map map = builder.build(); + Map map = builder.build(); if (map.isEmpty()) { throw new IOException(String.format("No textures found for %s at %s", profile, this.address)); } - return new TexturesPayload(profile, map); + return TexturesPayloadBuilder.createTexturesPayload(profile, map); } - private TextureProfile loadProfileTexture(GameProfile profile, URI url) throws IOException { - HttpURLConnection urlConnection = (HttpURLConnection) url.toURL().openConnection(); + private MinecraftProfileTexture loadProfileTexture(GameProfile profile, String url) throws IOException { + HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection(); if (urlConnection.getResponseCode() / 100 != 2) { throw new IOException("Bad response code: " + urlConnection.getResponseCode() + ". URL: " + url); } logger.debug("Found skin for {} at {}", profile.getName(), url); - return new TextureProfile(url, null); + return new MinecraftProfileTexture(url, null); } @SuppressWarnings("deprecation") @@ -90,7 +91,7 @@ public class LegacySkinServer implements SkinServer { return CallableFutures.asyncFailableFuture(() -> { URI image = skin.getImage(); - TextureType type = skin.getType(); + MinecraftProfileTexture.Type type = skin.getType(); Map metadata = skin.getMetadata(); SkinServer.verifyServerConnection(session, SERVER_ID); @@ -113,7 +114,7 @@ public class LegacySkinServer implements SkinServer { return new UnsupportedOperationException("Server does not have a gateway."); } - private static Map getData(Session session, TextureType type, String model, String param, Object val) { + private static Map getData(Session session, MinecraftProfileTexture.Type type, String model, String param, Object val) { return ImmutableMap.of( "user", session.getUsername(), "uuid", UUIDTypeAdapter.fromUUID(session.getProfile().getId()), @@ -122,18 +123,18 @@ public class LegacySkinServer implements SkinServer { param, val); } - private static Map getClearData(Session session, TextureType type) { + private static Map getClearData(Session session, MinecraftProfileTexture.Type type) { return getData(session, type, "default", "clear", "1"); } - private static Map getUploadData(Session session, TextureType type, String model, URI skinFile) { + private static Map getUploadData(Session session, MinecraftProfileTexture.Type type, String model, URI skinFile) { return getData(session, type, model, type.toString().toLowerCase(Locale.US), skinFile); } - private static URI getPath(String address, TextureType type, GameProfile profile) { + private static String getPath(String address, MinecraftProfileTexture.Type type, GameProfile profile) { String uuid = UUIDTypeAdapter.fromUUID(profile.getId()); String path = type.toString().toLowerCase() + "s"; - return URI.create(String.format("%s/%s/%s.png", address, path, uuid)); + return String.format("%s/%s/%s.png", address, path, uuid); } @Override diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/skins/SkinServer.java b/src/hdskins/java/com/voxelmodpack/hdskins/skins/SkinServer.java index 8ab3b3f9..48f55b51 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/skins/SkinServer.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/skins/SkinServer.java @@ -3,11 +3,12 @@ package com.voxelmodpack.hdskins.skins; import com.google.common.collect.Lists; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import com.minelittlepony.avatar.texture.TextureType; import com.mojang.authlib.GameProfile; import com.mojang.authlib.exceptions.AuthenticationException; import com.mojang.authlib.minecraft.MinecraftSessionService; +import com.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload; import com.mojang.util.UUIDTypeAdapter; +import com.mumfrey.liteloader.modconfig.Exposable; import com.voxelmodpack.hdskins.HDSkinManager; import net.minecraft.client.Minecraft; import net.minecraft.util.Session; @@ -17,22 +18,21 @@ import java.util.List; import java.util.UUID; import java.util.concurrent.CompletableFuture; -public interface SkinServer { +public interface SkinServer extends Exposable { Gson gson = new GsonBuilder() .registerTypeAdapter(UUID.class, new UUIDTypeAdapter()) - .registerTypeAdapter(TextureType.class, new TextureType.Serializer()) .create(); List defaultServers = Lists.newArrayList(new LegacySkinServer( "http://skins.voxelmodpack.com", "http://skinmanager.voxelmodpack.com")); - TexturesPayload loadProfileData(GameProfile profile) throws IOException; + MinecraftTexturesPayload loadProfileData(GameProfile profile) throws IOException; CompletableFuture uploadSkin(Session session, SkinUpload upload); - default CompletableFuture getPreviewTextures(GameProfile profile) { + default CompletableFuture getPreviewTextures(GameProfile profile) { return CallableFutures.asyncFailableFuture(() -> loadProfileData(profile), HDSkinManager.skinDownloadExecutor); } diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/skins/SkinUpload.java b/src/hdskins/java/com/voxelmodpack/hdskins/skins/SkinUpload.java index e2ae3ad3..dbcd20bd 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/skins/SkinUpload.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/skins/SkinUpload.java @@ -1,6 +1,6 @@ package com.voxelmodpack.hdskins.skins; -import com.minelittlepony.avatar.texture.TextureType; +import com.mojang.authlib.minecraft.MinecraftProfileTexture; import java.net.URI; import java.util.Map; @@ -11,9 +11,9 @@ public class SkinUpload { private URI image; private Map metadata; - private TextureType type; + private MinecraftProfileTexture.Type type; - public SkinUpload(TextureType type, @Nullable URI image, Map metadata) { + public SkinUpload(MinecraftProfileTexture.Type type, @Nullable URI image, Map metadata) { this.image = image; this.metadata = metadata; this.type = type; @@ -28,7 +28,7 @@ public class SkinUpload { return metadata; } - public TextureType getType() { + public MinecraftProfileTexture.Type getType() { return type; } } diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/skins/TexturesPayload.java b/src/hdskins/java/com/voxelmodpack/hdskins/skins/TexturesPayload.java deleted file mode 100644 index 85c36196..00000000 --- a/src/hdskins/java/com/voxelmodpack/hdskins/skins/TexturesPayload.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.voxelmodpack.hdskins.skins; - -import com.minelittlepony.avatar.texture.TextureProfile; -import com.minelittlepony.avatar.texture.TextureType; -import com.mojang.authlib.GameProfile; - -import java.util.Map; -import java.util.UUID; - -import javax.annotation.Nullable; - -public class TexturesPayload { - - private long timestamp; - private UUID profileId; - private String profileName; - private boolean isPublic; - private Map textures; - - public TexturesPayload(GameProfile profile, Map textures) { - this.profileId = profile.getId(); - this.profileName = profile.getName(); - this.timestamp = System.currentTimeMillis(); - - this.isPublic = true; - - this.textures = textures; - } - - public long getTimestamp() { - return timestamp; - } - - public UUID getProfileId() { - return profileId; - } - - public String getProfileName() { - return profileName; - } - - public boolean isPublic() { - return isPublic; - } - - @Nullable - public Map getTextures() { - return textures; - } - -} diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/skins/ValhallaSkinServer.java b/src/hdskins/java/com/voxelmodpack/hdskins/skins/ValhallaSkinServer.java index 22bbd9a0..4271d36f 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/skins/ValhallaSkinServer.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/skins/ValhallaSkinServer.java @@ -3,9 +3,10 @@ package com.voxelmodpack.hdskins.skins; import com.google.common.base.Preconditions; import com.google.gson.JsonObject; import com.google.gson.annotations.Expose; -import com.minelittlepony.avatar.texture.TextureType; import com.mojang.authlib.GameProfile; import com.mojang.authlib.exceptions.AuthenticationException; +import com.mojang.authlib.minecraft.MinecraftProfileTexture; +import com.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload; import com.mojang.util.UUIDTypeAdapter; import com.voxelmodpack.hdskins.HDSkinManager; import net.minecraft.client.Minecraft; @@ -42,12 +43,12 @@ public class ValhallaSkinServer implements SkinServer { } @Override - public TexturesPayload loadProfileData(GameProfile profile) throws IOException { + public MinecraftTexturesPayload loadProfileData(GameProfile profile) throws IOException { try (MoreHttpResponses response = MoreHttpResponses.execute(HDSkinManager.httpClient, new HttpGet(getTexturesURI(profile)))) { if (response.ok()) { - return readJson(response, TexturesPayload.class); + return readJson(response, MinecraftTexturesPayload.class); } throw new IOException("Server sent non-ok response code: " + response.getResponseCode()); } @@ -57,7 +58,7 @@ public class ValhallaSkinServer implements SkinServer { public CompletableFuture uploadSkin(Session session, SkinUpload skin) { URI image = skin.getImage(); Map metadata = skin.getMetadata(); - TextureType type = skin.getType(); + MinecraftProfileTexture.Type type = skin.getType(); return CallableFutures.asyncFailableFuture(() -> { authorize(session); @@ -76,7 +77,7 @@ public class ValhallaSkinServer implements SkinServer { } private SkinUploadResponse upload(Session session, @Nullable URI image, - TextureType type, Map metadata) + MinecraftProfileTexture.Type type, Map metadata) throws IOException { GameProfile profile = session.getProfile(); @@ -95,14 +96,14 @@ public class ValhallaSkinServer implements SkinServer { } - private SkinUploadResponse resetSkin(GameProfile profile, TextureType type) throws IOException { + private SkinUploadResponse resetSkin(GameProfile profile, MinecraftProfileTexture.Type type) throws IOException { return upload(RequestBuilder.delete() .setUri(buildUserTextureUri(profile, type)) .addHeader(HttpHeaders.AUTHORIZATION, this.accessToken) .build()); } - private SkinUploadResponse uploadFile(File file, GameProfile profile, TextureType type, Map metadata) throws IOException { + private SkinUploadResponse uploadFile(File file, GameProfile profile, MinecraftProfileTexture.Type type, Map metadata) throws IOException { MultipartEntityBuilder b = MultipartEntityBuilder.create(); b.addBinaryBody("file", file, ContentType.create("image/png"), file.getName()); metadata.forEach(b::addTextBody); @@ -114,7 +115,7 @@ public class ValhallaSkinServer implements SkinServer { .build()); } - private SkinUploadResponse uploadUrl(URI uri, GameProfile profile, TextureType type, Map metadata) throws IOException { + private SkinUploadResponse uploadUrl(URI uri, GameProfile profile, MinecraftProfileTexture.Type type, Map metadata) throws IOException { return upload(RequestBuilder.post() .setUri(buildUserTextureUri(profile, type)) @@ -185,9 +186,9 @@ public class ValhallaSkinServer implements SkinServer { } } - private URI buildUserTextureUri(GameProfile profile, TextureType textureType) { + private URI buildUserTextureUri(GameProfile profile, MinecraftProfileTexture.Type textureType) { String user = UUIDTypeAdapter.fromUUID(profile.getId()); - String skinType = textureType.toString().toLowerCase(Locale.US); + String skinType = textureType.name().toLowerCase(Locale.US); return URI.create(String.format("%s/user/%s/%s", this.address, user, skinType)); } diff --git a/src/main/java/com/minelittlepony/PonyManager.java b/src/main/java/com/minelittlepony/PonyManager.java index d7c05a6c..ac31d982 100644 --- a/src/main/java/com/minelittlepony/PonyManager.java +++ b/src/main/java/com/minelittlepony/PonyManager.java @@ -6,7 +6,9 @@ import com.google.gson.Gson; import com.google.gson.JsonParseException; import com.minelittlepony.pony.data.Pony; import com.minelittlepony.pony.data.PonyLevel; +import com.voxelmodpack.hdskins.HDSkinManager; import com.voxelmodpack.hdskins.ISkinCacheClearListener; + import net.minecraft.client.Minecraft; import net.minecraft.client.entity.AbstractClientPlayer; import net.minecraft.client.network.NetworkPlayerInfo; @@ -82,6 +84,7 @@ public class PonyManager implements IResourceManagerReloadListener, ISkinCacheCl public Pony getPony(NetworkPlayerInfo playerInfo) { // force load HDSkins if they're not available + HDSkinManager.INSTANCE.getProfileData(playerInfo.getGameProfile()); ResourceLocation skin = playerInfo.getLocationSkin(); UUID uuid = playerInfo.getGameProfile().getId(); diff --git a/src/main/java/com/minelittlepony/hdskins/gui/EntityPonyModel.java b/src/main/java/com/minelittlepony/hdskins/gui/EntityPonyModel.java index 2c05d0b4..843fdc7c 100644 --- a/src/main/java/com/minelittlepony/hdskins/gui/EntityPonyModel.java +++ b/src/main/java/com/minelittlepony/hdskins/gui/EntityPonyModel.java @@ -1,8 +1,9 @@ package com.minelittlepony.hdskins.gui; -import com.minelittlepony.avatar.texture.TextureType; import com.mojang.authlib.GameProfile; +import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type; import com.voxelmodpack.hdskins.gui.EntityPlayerModel; + import net.minecraft.util.ResourceLocation; /** @@ -20,8 +21,8 @@ public class EntityPonyModel extends EntityPlayerModel { } @Override - public ResourceLocation getBlankSkin(TextureType type) { - if (type == TextureType.SKIN) { + public ResourceLocation getBlankSkin(Type type) { + if (type == Type.SKIN) { return wet ? NO_SKIN_SEAPONY : NO_SKIN_PONY; } return super.getBlankSkin(type); diff --git a/src/main/java/com/minelittlepony/hdskins/gui/GuiSkinsMineLP.java b/src/main/java/com/minelittlepony/hdskins/gui/GuiSkinsMineLP.java index e1e0e87b..2f3afad7 100644 --- a/src/main/java/com/minelittlepony/hdskins/gui/GuiSkinsMineLP.java +++ b/src/main/java/com/minelittlepony/hdskins/gui/GuiSkinsMineLP.java @@ -2,17 +2,19 @@ package com.minelittlepony.hdskins.gui; import com.minelittlepony.MineLittlePony; import com.minelittlepony.PonyManager; -import com.minelittlepony.avatar.texture.TextureData; -import com.minelittlepony.avatar.texture.TextureType; import com.minelittlepony.gui.Button; import com.minelittlepony.gui.IconicButton; import com.mojang.authlib.GameProfile; +import com.mojang.authlib.minecraft.MinecraftProfileTexture; +import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type; import com.voxelmodpack.hdskins.gui.EntityPlayerModel; import com.voxelmodpack.hdskins.gui.GuiSkins; + import net.minecraft.client.audio.PositionedSoundRecord; import net.minecraft.init.Items; import net.minecraft.init.SoundEvents; import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; /** * Skin uploading GUI. Usually displayed over the main menu. @@ -75,18 +77,18 @@ public class GuiSkinsMineLP extends GuiSkins { } @Override - protected void onSetLocalSkin(TextureType type) { + protected void onSetLocalSkin(Type type) { MineLittlePony.logger.debug("Invalidating old local skin, checking updated local skin"); - if (type == TextureType.SKIN) { - ponyManager.removePony(localPlayer.getLocal(TextureType.SKIN).getTexture()); + if (type == Type.SKIN) { + ponyManager.removePony(localPlayer.getLocal(Type.SKIN).getTexture()); } } @Override - protected void onSetRemoteSkin(TextureType type, TextureData texture) { + protected void onSetRemoteSkin(Type type, ResourceLocation resource, MinecraftProfileTexture profileTexture) { MineLittlePony.logger.debug("Invalidating old remote skin, checking updated remote skin"); - if (type == TextureType.SKIN) { - ponyManager.removePony(texture.getLocation()); + if (type == Type.SKIN) { + ponyManager.removePony(resource); } } } diff --git a/src/main/java/com/minelittlepony/hdskins/gui/RenderPonyModel.java b/src/main/java/com/minelittlepony/hdskins/gui/RenderPonyModel.java index 0c09c601..27853cae 100644 --- a/src/main/java/com/minelittlepony/hdskins/gui/RenderPonyModel.java +++ b/src/main/java/com/minelittlepony/hdskins/gui/RenderPonyModel.java @@ -1,15 +1,16 @@ package com.minelittlepony.hdskins.gui; import com.minelittlepony.MineLittlePony; -import com.minelittlepony.avatar.texture.TextureType; import com.minelittlepony.ducks.IRenderPony; import com.minelittlepony.model.ModelWrapper; import com.minelittlepony.model.player.PlayerModels; import com.minelittlepony.pony.data.Pony; import com.minelittlepony.pony.data.PonyRace; -import com.minelittlepony.render.RenderPony; import com.minelittlepony.render.layer.LayerPonyElytra; +import com.minelittlepony.render.RenderPony; +import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type; import com.voxelmodpack.hdskins.gui.RenderPlayerModel; + import net.minecraft.client.model.ModelBase; import net.minecraft.client.model.ModelElytra; import net.minecraft.client.model.ModelPlayer; @@ -78,7 +79,7 @@ public class RenderPonyModel extends RenderPlayerModel implemen return super.getEntityModel(playermodel); } - boolean canWet = playermodel.wet && (loc == playermodel.getBlankSkin(TextureType.SKIN) || race == PonyRace.SEAPONY); + boolean canWet = playermodel.wet && (loc == playermodel.getBlankSkin(Type.SKIN) || race == PonyRace.SEAPONY); playerModel = canWet ? PlayerModels.SEAPONY.getModel(slim) : thePony.getModel(true); playerModel.apply(thePony.getMetadata()); @@ -109,7 +110,7 @@ public class RenderPonyModel extends RenderPlayerModel implemen @Override protected ResourceLocation getElytraTexture(EntityPonyModel entity) { - return entity.getLocal(TextureType.ELYTRA).getTexture(); + return entity.getLocal(Type.ELYTRA).getTexture(); } }; } diff --git a/src/main/java/com/minelittlepony/mixin/MixinNetworkPlayerInfo.java b/src/main/java/com/minelittlepony/mixin/MixinNetworkPlayerInfo.java index 4219d09a..a24eb269 100644 --- a/src/main/java/com/minelittlepony/mixin/MixinNetworkPlayerInfo.java +++ b/src/main/java/com/minelittlepony/mixin/MixinNetworkPlayerInfo.java @@ -1,20 +1,22 @@ package com.minelittlepony.mixin; -import com.minelittlepony.MineLittlePony; -import com.minelittlepony.PonyManager; -import com.minelittlepony.avatar.impl.INetworkPlayerInfo; -import com.minelittlepony.avatar.texture.TextureData; -import com.minelittlepony.avatar.texture.TextureType; -import com.minelittlepony.ducks.IPlayerInfo; -import net.minecraft.client.network.NetworkPlayerInfo; 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 com.minelittlepony.MineLittlePony; +import com.minelittlepony.PonyManager; +import com.minelittlepony.ducks.IPlayerInfo; +import com.mojang.authlib.minecraft.MinecraftProfileTexture; +import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type; +import com.voxelmodpack.hdskins.HDSkinManager; + +import net.minecraft.client.network.NetworkPlayerInfo; + @Mixin(NetworkPlayerInfo.class) -public abstract class MixinNetworkPlayerInfo implements IPlayerInfo, INetworkPlayerInfo { +public abstract class MixinNetworkPlayerInfo implements IPlayerInfo { @Shadow private String skinType; @@ -27,10 +29,10 @@ public abstract class MixinNetworkPlayerInfo implements IPlayerInfo, INetworkPla @Override public boolean usesSlimArms() { if (skinType == null) { - TextureData skin = this.getPlayerTexture(TextureType.SKIN).orElse(null); + MinecraftProfileTexture skin = HDSkinManager.INSTANCE.getProfileData(unwrap().getGameProfile()).get(Type.SKIN); if (skin != null) { - return "slim".equals(skin.getProfile().getMetadata("model").orElse(null)); + return "slim".equals(skin.getMetadata("model")); } return PonyManager.isSlimSkin(unwrap().getGameProfile().getId()); diff --git a/src/main/java/com/minelittlepony/render/player/RenderPonyPlayer.java b/src/main/java/com/minelittlepony/render/player/RenderPonyPlayer.java index a40df45a..dbe19ff7 100644 --- a/src/main/java/com/minelittlepony/render/player/RenderPonyPlayer.java +++ b/src/main/java/com/minelittlepony/render/player/RenderPonyPlayer.java @@ -2,10 +2,6 @@ package com.minelittlepony.render.player; import com.minelittlepony.MineLittlePony; import com.minelittlepony.PonyConfig; -import com.minelittlepony.avatar.ServiceManager; -import com.minelittlepony.avatar.texture.TextureData; -import com.minelittlepony.avatar.texture.TextureService; -import com.minelittlepony.avatar.texture.TextureType; import com.minelittlepony.ducks.IRenderPony; import com.minelittlepony.model.ModelWrapper; import com.minelittlepony.model.components.ModelDeadMau5Ears; @@ -24,6 +20,7 @@ import com.minelittlepony.render.layer.LayerPonyElytra; import com.mojang.authlib.GameProfile; import com.mojang.authlib.minecraft.MinecraftProfileTexture; import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type; +import com.voxelmodpack.hdskins.HDSkinManager; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.AbstractClientPlayer; import net.minecraft.client.renderer.GlStateManager; @@ -60,11 +57,7 @@ public class RenderPonyPlayer extends RenderPlayer implements IRenderPony skin = ServiceManager.get(TextureService.class).map(service -> - service.getTextures(profile)) - .map(m -> m.get(TextureType.SKIN)) - .map(TextureData::getLocation); - + Optional skin = HDSkinManager.INSTANCE.getSkinLocation(profile, Type.SKIN, true); if (skin.isPresent()) { return skin.get(); } @@ -116,7 +109,7 @@ public class RenderPonyPlayer extends RenderPlayer implements IRenderPony