diff --git a/src/main/java/net/silentclient/client/Client.java b/src/main/java/net/silentclient/client/Client.java index 13a6a40..1cbaaf5 100644 --- a/src/main/java/net/silentclient/client/Client.java +++ b/src/main/java/net/silentclient/client/Client.java @@ -81,6 +81,7 @@ public class Client { public static BackgroundPanorama backgroundPanorama; private KeyBindManager keyBindManager; private IMetadataSerializer iMetadataSerializer; + private CustomSkin customSkin = new CustomSkin(); public static void memoryDebug(String paramString) { LogManager.getLogger().info("-- Start Memory Debug -- " + paramString); @@ -254,7 +255,6 @@ public class Client { logger.info("STARTING > news"); String content = Requests.get("https://api.silentclient.net/_next/news/latest"); - if(content != null) { try { NewsResponse newsResponse = getGson().fromJson(content, NewsResponse.class); @@ -264,6 +264,10 @@ public class Client { logger.catching(err); } } + + if(account.getCustomSkin()) { + logger.info("STARTING > custom-skin"); + } } catch(Exception err) { logger.info("STARTING > ERROR: " + err.getMessage()); throw err; @@ -555,4 +559,8 @@ public class Client { public void setiMetadataSerializer(IMetadataSerializer iMetadataSerializer) { this.iMetadataSerializer = iMetadataSerializer; } + + public CustomSkin getCustomSkin() { + return customSkin; + } } diff --git a/src/main/java/net/silentclient/client/mixin/accessors/AbstractClientPlayerAccessor.java b/src/main/java/net/silentclient/client/mixin/accessors/AbstractClientPlayerAccessor.java new file mode 100644 index 0000000..fed1cb9 --- /dev/null +++ b/src/main/java/net/silentclient/client/mixin/accessors/AbstractClientPlayerAccessor.java @@ -0,0 +1,12 @@ +package net.silentclient.client.mixin.accessors; + +import net.minecraft.client.entity.AbstractClientPlayer; +import net.minecraft.client.network.NetworkPlayerInfo; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(AbstractClientPlayer.class) +public interface AbstractClientPlayerAccessor { + @Accessor + NetworkPlayerInfo getPlayerInfo(); +} diff --git a/src/main/java/net/silentclient/client/mixin/accessors/NetworkPlayerInfoAccessor.java b/src/main/java/net/silentclient/client/mixin/accessors/NetworkPlayerInfoAccessor.java new file mode 100644 index 0000000..888ca85 --- /dev/null +++ b/src/main/java/net/silentclient/client/mixin/accessors/NetworkPlayerInfoAccessor.java @@ -0,0 +1,10 @@ +package net.silentclient.client.mixin.accessors; + +import net.minecraft.client.network.NetworkPlayerInfo; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(NetworkPlayerInfo.class) +public interface NetworkPlayerInfoAccessor { + @Accessor("skinType") String silent$getSkinType(); +} diff --git a/src/main/java/net/silentclient/client/mixin/mixins/AbstractClientPlayerMixin.java b/src/main/java/net/silentclient/client/mixin/mixins/AbstractClientPlayerMixin.java index 2161c15..6bf364e 100644 --- a/src/main/java/net/silentclient/client/mixin/mixins/AbstractClientPlayerMixin.java +++ b/src/main/java/net/silentclient/client/mixin/mixins/AbstractClientPlayerMixin.java @@ -3,6 +3,10 @@ package net.silentclient.client.mixin.mixins; import com.mojang.authlib.GameProfile; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.AbstractClientPlayer; +import net.minecraft.client.network.NetworkPlayerInfo; +import net.minecraft.client.renderer.texture.DynamicTexture; +import net.minecraft.client.resources.DefaultPlayerSkin; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.StringUtils; import net.minecraft.world.World; import net.silentclient.client.Client; @@ -10,20 +14,31 @@ import net.silentclient.client.admin.AdminRender; import net.silentclient.client.cosmetics.*; import net.silentclient.client.cosmetics.dynamiccurved.DynamicCape; import net.silentclient.client.event.impl.EventFovUpdate; +import net.silentclient.client.mixin.accessors.AbstractClientPlayerAccessor; +import net.silentclient.client.mixin.accessors.NetworkPlayerInfoAccessor; import net.silentclient.client.mixin.ducks.AbstractClientPlayerExt; +import net.silentclient.client.mods.player.NickHiderMod; import net.silentclient.client.mods.render.AnimationsMod; import net.silentclient.client.mods.settings.CosmeticsMod; import net.silentclient.client.utils.Players; +import net.silentclient.client.utils.SCTextureManager; import net.silentclient.client.utils.types.PlayerResponse; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import java.util.Random; + @Mixin(AbstractClientPlayer.class) public abstract class AbstractClientPlayerMixin implements AbstractClientPlayerExt { + @Shadow protected abstract NetworkPlayerInfo getPlayerInfo(); + + @Shadow public abstract String getSkinType(); + @Unique private AnimatedResourceLocation silent$cape; @Unique private AnimatedResourceLocation silent$bandana; @Unique private HatData silent$hat; @@ -72,15 +87,46 @@ public abstract class AbstractClientPlayerMixin implements AbstractClientPlayerE cir.cancel(); } if(Client.getInstance().getModInstances().getModByClass(AnimationsMod.class).isEnabled() && Client.getInstance().getSettingsManager().getSettingByClass(AnimationsMod.class, "1.7 Skins").getValBoolean()) { - cir.setReturnValue("default"); - cir.cancel(); + cir.setReturnValue("default"); + cir.cancel(); + return; } - if(this.silent$getNameClear().toLowerCase().equals(Client.getInstance().getAccount().getUsername().toLowerCase()) && Client.getInstance().getAccount().getCustomSkin()) { + + if(silent$getNameClear().toLowerCase().equals(Client.getInstance().getAccount().getUsername().toLowerCase()) && Client.getInstance().getAccount().getCustomSkin()) { cir.setReturnValue(Client.getInstance().getAccount().getSkinType()); cir.cancel(); } } + @Inject(method = "getLocationSkin()Lnet/minecraft/util/ResourceLocation;", at = @At("HEAD"), cancellable = true) + public void mixinSkinLocation(CallbackInfoReturnable cir) { + if(Minecraft.getMinecraft().currentScreen instanceof AdminRender) { + cir.setReturnValue(new ResourceLocation("textures/entity/steve.png")); + cir.cancel(); + return; + } + + if(silent$getNameClear().toLowerCase().equals(Client.getInstance().getAccount().getUsername().toLowerCase()) && Client.getInstance().getAccount().getCustomSkin()) { + if(Client.getInstance().getCustomSkin().getLocation() == null && !Client.getInstance().getCustomSkin().isLoading()) { + Client.getInstance().getCustomSkin().setLoading(true); + (new Thread("CustomSkinThread") { + public void run() { + Client.logger.info("Downloading Custom Skin"); + Client.getInstance().getCustomSkin().setImage(SCTextureManager.getImage("https://cdn.silentclient.net/skins/" + silent$nameClear.toLowerCase() + ".png")); + } + }).start(); + } + if(Client.getInstance().getCustomSkin().getImage() != null && !Client.getInstance().getCustomSkin().isInitialized()) { + Client.getInstance().getCustomSkin().setLocation(Minecraft.getMinecraft().getTextureManager().getDynamicTextureLocation("custom_skin_" + new Random().nextLong(), new DynamicTexture(Client.getInstance().getCustomSkin().getImage()))); + Client.getInstance().getCustomSkin().setInitialized(true); + } + if(Client.getInstance().getCustomSkin().getLocation() != null) { + cir.setReturnValue(Client.getInstance().getCustomSkin().getLocation()); + cir.cancel(); + } + } + } + @Override public String silent$getCapeType() { return silent$capeType; diff --git a/src/main/java/net/silentclient/client/mixin/mixins/NetworkPlayerInfoMixin.java b/src/main/java/net/silentclient/client/mixin/mixins/NetworkPlayerInfoMixin.java new file mode 100644 index 0000000..55b9686 --- /dev/null +++ b/src/main/java/net/silentclient/client/mixin/mixins/NetworkPlayerInfoMixin.java @@ -0,0 +1,31 @@ +package net.silentclient.client.mixin.mixins; + +import com.mojang.authlib.GameProfile; +import net.minecraft.client.Minecraft; +import net.minecraft.client.network.NetworkPlayerInfo; +import net.minecraft.client.resources.DefaultPlayerSkin; +import net.silentclient.client.Client; +import net.silentclient.client.mixin.accessors.AbstractClientPlayerAccessor; +import net.silentclient.client.mixin.accessors.NetworkPlayerInfoAccessor; +import net.silentclient.client.mods.player.NickHiderMod; +import net.silentclient.client.mods.render.AnimationsMod; +import org.spongepowered.asm.mixin.Final; +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; + +@Mixin(NetworkPlayerInfo.class) +public abstract class NetworkPlayerInfoMixin { + @Shadow @Final private GameProfile gameProfile; + + @Shadow private String skinType; + + @Shadow public abstract GameProfile getGameProfile(); + + @Inject(method = "getSkinType", at = @At("HEAD")) + public void customSkinType(CallbackInfoReturnable cir) { + + } +} diff --git a/src/main/java/net/silentclient/client/utils/CustomSkin.java b/src/main/java/net/silentclient/client/utils/CustomSkin.java new file mode 100644 index 0000000..8855420 --- /dev/null +++ b/src/main/java/net/silentclient/client/utils/CustomSkin.java @@ -0,0 +1,44 @@ +package net.silentclient.client.utils; + +import net.minecraft.util.ResourceLocation; + +import java.awt.image.BufferedImage; + +public class CustomSkin { + private boolean loading = false; + private BufferedImage image; + private ResourceLocation location; + private boolean initialized = false; + + public BufferedImage getImage() { + return image; + } + + public ResourceLocation getLocation() { + return location; + } + + public boolean isInitialized() { + return initialized; + } + + public boolean isLoading() { + return loading; + } + + public void setImage(BufferedImage image) { + this.image = image; + } + + public void setInitialized(boolean initialized) { + this.initialized = initialized; + } + + public void setLoading(boolean loading) { + this.loading = loading; + } + + public void setLocation(ResourceLocation location) { + this.location = location; + } +}