diff --git a/src/main/java/net/shadow/client/feature/command/impl/Find.java b/src/main/java/net/shadow/client/feature/command/impl/Find.java index d2dba38..7e7ef46 100644 --- a/src/main/java/net/shadow/client/feature/command/impl/Find.java +++ b/src/main/java/net/shadow/client/feature/command/impl/Find.java @@ -42,7 +42,6 @@ public class Find extends Command { public Find() { super("Find", "Nocom 2 (requires creative)", "find", "findPlayer"); - System.out.println("instanced"); Events.registerEventHandlerClass(this); } diff --git a/src/main/java/net/shadow/client/feature/command/impl/Help.java b/src/main/java/net/shadow/client/feature/command/impl/Help.java index 3cbd783..e0dd6c5 100644 --- a/src/main/java/net/shadow/client/feature/command/impl/Help.java +++ b/src/main/java/net/shadow/client/feature/command/impl/Help.java @@ -44,7 +44,7 @@ public class Help extends Command { message("All commands and their description"); for (Command command : CommandRegistry.getCommands()) { message(command.getName() + ": " + command.getDescription()); - message0(" " + String.join(", ", command.getAliases()), Color.GRAY); + message(" " + String.join(", ", command.getAliases()), Color.GRAY); } } else { String s = args[0]; @@ -52,8 +52,8 @@ public class Help extends Command { if (c == null) error("Command \"" + s + "\" was not found"); else { message("Command " + c.getName()); - message0(c.getDescription(), Color.GRAY); - message0("Aliases: " + String.join(", ", c.getAliases()), Color.GRAY); + message(c.getDescription(), Color.GRAY); + message("Aliases: " + String.join(", ", c.getAliases()), Color.GRAY); message(""); ExamplesEntry e = c.getExampleArguments(); if (e == null) { diff --git a/src/main/java/net/shadow/client/feature/command/impl/OnlineAPI.java b/src/main/java/net/shadow/client/feature/command/impl/OnlineAPI.java index 240eeac..82f4764 100644 --- a/src/main/java/net/shadow/client/feature/command/impl/OnlineAPI.java +++ b/src/main/java/net/shadow/client/feature/command/impl/OnlineAPI.java @@ -16,6 +16,7 @@ import net.shadow.client.helper.ShadowAPIWrapper; import net.shadow.client.helper.event.EventType; import net.shadow.client.helper.event.Events; import org.apache.commons.io.FileUtils; +import org.apache.logging.log4j.Level; import java.io.File; import java.nio.charset.StandardCharsets; @@ -45,13 +46,13 @@ public class OnlineAPI extends Command { String session = FileUtils.readFileToString(SESSION_KEY_FILE, StandardCharsets.UTF_8); if (!session.isEmpty()) { if (ShadowAPIWrapper.loginWithKey(session)) { - System.out.println("recovered previous session from backup file"); + ShadowMain.log(Level.INFO, "recovered previous session from backup file"); } else { - System.out.println("server said no to session recovery, moving on"); + ShadowMain.log(Level.INFO, "server said no to session recovery, moving on"); } } } catch (Exception e) { - System.out.println("failed to recover session :("); + ShadowMain.log(Level.ERROR, "failed to recover session :("); e.printStackTrace(); } } diff --git a/src/main/java/net/shadow/client/feature/command/impl/SocketKick.java b/src/main/java/net/shadow/client/feature/command/impl/SocketKick.java index 19a9e07..9c77baf 100644 --- a/src/main/java/net/shadow/client/feature/command/impl/SocketKick.java +++ b/src/main/java/net/shadow/client/feature/command/impl/SocketKick.java @@ -4,7 +4,7 @@ package net.shadow.client.feature.command.impl; -import net.minecraft.client.network.PlayerListEntry; +import com.mojang.authlib.GameProfile; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.network.ClientConnection; import net.minecraft.network.NetworkState; @@ -20,7 +20,6 @@ import net.minecraft.text.Text; import net.shadow.client.ShadowMain; import net.shadow.client.feature.command.Command; import net.shadow.client.feature.command.argument.PlayerFromNameArgumentParser; -import net.shadow.client.feature.command.argument.StreamlineArgumentParser; import net.shadow.client.feature.command.coloring.ArgumentType; import net.shadow.client.feature.command.coloring.PossibleArgument; import net.shadow.client.feature.command.coloring.StaticArgumentServer; @@ -30,8 +29,6 @@ import net.shadow.client.feature.command.exception.CommandException; import java.net.InetSocketAddress; import java.util.Objects; -import com.mojang.authlib.GameProfile; - public class SocketKick extends Command { public SocketKick() { super("SocketKick", "Kicks people out of the server using sockets!!", "socketkick", "skick", "sockkick"); diff --git a/src/main/java/net/shadow/client/feature/gui/notifications/hudNotif/HudNotification.java b/src/main/java/net/shadow/client/feature/gui/notifications/hudNotif/HudNotification.java new file mode 100644 index 0000000..c51c170 --- /dev/null +++ b/src/main/java/net/shadow/client/feature/gui/notifications/hudNotif/HudNotification.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) Shadow client, 0x150, Saturn5VFive 2022. All rights reserved. + */ + +package net.shadow.client.feature.gui.notifications.hudNotif; + +import com.mojang.blaze3d.systems.RenderSystem; +import lombok.AccessLevel; +import lombok.RequiredArgsConstructor; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Quaternion; +import net.shadow.client.helper.GameTexture; +import net.shadow.client.helper.Texture; +import net.shadow.client.helper.font.FontRenderers; +import net.shadow.client.helper.font.adapter.FontAdapter; +import net.shadow.client.helper.render.ClipStack; +import net.shadow.client.helper.render.Rectangle; +import net.shadow.client.helper.render.Renderer; + +import java.awt.Color; + +@RequiredArgsConstructor(access = AccessLevel.PRIVATE) +public class HudNotification { + final String content; + final long duration; + final Type type; + long creation = System.currentTimeMillis(); + double texDim = 16; + double pad = 2; + long fadeTime = 1200; + + public static HudNotification create(String content, long duration, Type type) { + HudNotification n = new HudNotification(content, duration, type); + HudNotificationRenderer.instance.addNotification(n); + return n; + } + + public long getRemainingLifeTime() { + return Math.max(0, (creation + duration) - System.currentTimeMillis()); + } + + public boolean isDead() { + return getRemainingLifeTime() == 0; + } + + public double getHeight() { + return pad + Math.max(FontRenderers.getRenderer().getFontHeight(), texDim) + pad; + } + + public double easeInOutBack(double x) { + double c1 = 1.70158; + double c2 = c1 * 1.525; + + return x < 0.5 + ? (Math.pow(2 * x, 2) * ((c2 + 1) * 2 * x - c2)) / 2 + : (Math.pow(2 * x - 2, 2) * ((c2 + 1) * (x * 2 - 2) + c2) + 2) / 2; + + } + + double getAnimProg() { + long remainingLife = getRemainingLifeTime(); + long timeExpired = duration - remainingLife; + double animAccordingToTime = (double) Math.min(timeExpired, fadeTime) / fadeTime; + double animAccordingToRemaining = (double) Math.min(remainingLife, fadeTime) / fadeTime; + return Math.min(animAccordingToRemaining, animAccordingToTime) * 1.1; + } + + public void render(MatrixStack stack, double x, double y) { + FontAdapter fa = FontRenderers.getRenderer(); + double anim = getAnimProg(); + double moveAnim = easeInOutBack(MathHelper.clamp(anim, 0, 0.5) * 2); + double expandAnim = easeInOutBack(MathHelper.clamp(anim, 0.1, 1.1) - .1); + + double notifWidthWithText = Math.max(pad + fa.getStringWidth(content) + pad + texDim + pad, 100); + double notifWidthWithoutText = pad + texDim + pad; + double notifWidth = MathHelper.lerp(Math.max(expandAnim, 0), notifWidthWithoutText, notifWidthWithText); + double notifHeight = getHeight(); + double rootX = x - notifWidth; + double rootY = MathHelper.lerp(moveAnim, -notifHeight, y); + Renderer.R2D.renderRoundedQuadWithShadow(stack, new Color(10, 10, 20), rootX, rootY, rootX + notifWidth, rootY + notifHeight, 3, 20); + RenderSystem.setShaderTexture(0, type.i); + RenderSystem.setShaderColor(1f, 1f, 1f, 1f); + stack.push(); + stack.translate(rootX + notifWidth - pad - texDim + texDim / 2d, rootY + pad + texDim / 2d, 0); + stack.multiply(new Quaternion(0f, 0f, (float) (expandAnim * 360f), true)); + Renderer.R2D.renderTexture(stack, -texDim / 2d, -texDim / 2d, texDim, texDim, 0, 0, texDim, texDim, texDim, texDim); + stack.pop(); + ClipStack.globalInstance.addWindow(stack, new Rectangle(rootX + pad, rootY, rootX + notifWidth - pad - texDim - pad, rootY + notifHeight)); + fa.drawString(stack, content, rootX + pad, rootY + notifHeight / 2d - fa.getFontHeight() / 2d, 0xFFFFFF); + ClipStack.globalInstance.popWindow(); + } + + public enum Type { + SUCCESS(GameTexture.NOTIF_SUCCESS.getWhere(), new Color(58, 223, 118)), INFO(GameTexture.NOTIF_INFO.getWhere(), new Color(39, 186, 253)), + WARNING(GameTexture.NOTIF_WARNING.getWhere(), new Color(255, 189, 17)), ERROR(GameTexture.NOTIF_ERROR.getWhere(), new Color(254, 92, 92)); + final Color c; + final Texture i; + + Type(Texture icon, Color color) { + this.i = icon; + this.c = color; + } + + public Texture getI() { + return i; + } + + public Color getC() { + return c; + } + } +} diff --git a/src/main/java/net/shadow/client/feature/gui/notifications/hudNotif/HudNotificationRenderer.java b/src/main/java/net/shadow/client/feature/gui/notifications/hudNotif/HudNotificationRenderer.java new file mode 100644 index 0000000..4f4ace4 --- /dev/null +++ b/src/main/java/net/shadow/client/feature/gui/notifications/hudNotif/HudNotificationRenderer.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) Shadow client, 0x150, Saturn5VFive 2022. All rights reserved. + */ + +package net.shadow.client.feature.gui.notifications.hudNotif; + +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.util.math.MathHelper; +import net.shadow.client.ShadowMain; +import net.shadow.client.helper.render.MSAAFramebuffer; + +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +public class HudNotificationRenderer { + public static final HudNotificationRenderer instance = new HudNotificationRenderer(); + List<HudNotification> notifs = new CopyOnWriteArrayList<>(); + + void addNotification(HudNotification notif) { + this.notifs.add(notif); + } + + public void render(MatrixStack stack) { + notifs.removeIf(HudNotification::isDead); + double x = ShadowMain.client.getWindow().getScaledWidth() - 5; + final double[] y = {5}; + MSAAFramebuffer.use(MSAAFramebuffer.MAX_SAMPLES, () -> { + for (HudNotification notif : notifs) { + notif.render(stack, x, y[0]); + + double moveAnim = MathHelper.clamp(notif.easeInOutBack(MathHelper.clamp(notif.getAnimProg(), 0, 0.5) * 2), 0, 1); + y[0] += (notif.getHeight() + 5) * moveAnim; + } + }); + } +} diff --git a/src/main/java/net/shadow/client/feature/gui/screen/AltManagerScreen.java b/src/main/java/net/shadow/client/feature/gui/screen/AltManagerScreen.java index 8d28189..3b094e9 100644 --- a/src/main/java/net/shadow/client/feature/gui/screen/AltManagerScreen.java +++ b/src/main/java/net/shadow/client/feature/gui/screen/AltManagerScreen.java @@ -15,14 +15,13 @@ import me.x150.authlib.login.mojang.profile.MinecraftProfile; import net.minecraft.client.gui.Element; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.render.GameRenderer; -import net.minecraft.client.texture.NativeImage; -import net.minecraft.client.texture.NativeImageBackedTexture; import net.minecraft.client.util.DefaultSkinHelper; import net.minecraft.client.util.Session; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.util.math.MathHelper; import net.shadow.client.ShadowMain; import net.shadow.client.feature.gui.FastTickable; +import net.shadow.client.feature.gui.notifications.hudNotif.HudNotification; import net.shadow.client.feature.gui.widget.RoundButton; import net.shadow.client.feature.gui.widget.RoundTextFieldWidget; import net.shadow.client.helper.Texture; @@ -30,6 +29,7 @@ import net.shadow.client.helper.font.FontRenderers; import net.shadow.client.helper.font.adapter.FontAdapter; import net.shadow.client.helper.render.ClipStack; import net.shadow.client.helper.render.MSAAFramebuffer; +import net.shadow.client.helper.render.PlayerHeadResolver; import net.shadow.client.helper.render.Rectangle; import net.shadow.client.helper.render.Renderer; import net.shadow.client.helper.util.Transitions; @@ -37,19 +37,11 @@ import net.shadow.client.mixin.IMinecraftClientAccessor; import net.shadow.client.mixin.SessionAccessor; import org.apache.commons.io.FileUtils; import org.apache.logging.log4j.Level; -import org.lwjgl.BufferUtils; import org.lwjgl.opengl.GL40C; -import javax.imageio.ImageIO; import java.awt.Color; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.File; -import java.net.URI; import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; @@ -89,7 +81,7 @@ public class AltManagerScreen extends ClientScreen implements FastTickable { double scroll = 0; double scrollSmooth = 0; Texture currentAccountTexture = new Texture("dynamic/currentaccount"); - boolean currentAccountTextureLoaded = false; + boolean currentAccountTextureLoaded = true; private AltManagerScreen() { super(MSAAFramebuffer.MAX_SAMPLES); @@ -233,32 +225,7 @@ public class AltManagerScreen extends ClientScreen implements FastTickable { void updateCurrentAccount() { UUID uid = ShadowMain.client.getSession().getProfile().getId(); - if (texCache.containsKey(uid)) { - this.currentAccountTexture = texCache.get(uid); - currentAccountTextureLoaded = true; - return; - } - - HttpRequest hr = HttpRequest.newBuilder().uri(URI.create("https://crafatar.com/avatars/" + uid + "?overlay")).header("User-Agent", "why").build(); - downloader.sendAsync(hr, HttpResponse.BodyHandlers.ofByteArray()).thenAccept(httpResponse -> { - try { - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - ImageIO.write(ImageIO.read(new ByteArrayInputStream(httpResponse.body())), "png", stream); - byte[] bytes = stream.toByteArray(); - - ByteBuffer data = BufferUtils.createByteBuffer(bytes.length).put(bytes); - data.flip(); - NativeImage img = NativeImage.read(data); - NativeImageBackedTexture texture = new NativeImageBackedTexture(img); - - ShadowMain.client.execute(() -> { - ShadowMain.client.getTextureManager().registerTexture(currentAccountTexture, texture); - currentAccountTextureLoaded = true; - }); - } catch (Exception e) { - e.printStackTrace(); - } - }); + this.currentAccountTexture = PlayerHeadResolver.resolve(uid); } void login() { @@ -270,11 +237,14 @@ public class AltManagerScreen extends ClientScreen implements FastTickable { this.selectedAlt.login(); isLoggingIn.set(false); if (!this.selectedAlt.storage.valid) { + HudNotification.create("Failed to log in", 5000, HudNotification.Type.ERROR); return; } Session newSession = new Session(selectedAlt.storage.cachedName, selectedAlt.storage.cachedUuid.toString(), selectedAlt.storage.accessToken, Optional.empty(), Optional.empty(), Session.AccountType.MOJANG); ((IMinecraftClientAccessor) ShadowMain.client).setSession(newSession); + HudNotification.create("Logged into account " + newSession.getUsername(), 5000, HudNotification.Type.INFO); updateCurrentAccount(); + }).start(); } @@ -916,28 +886,7 @@ public class AltManagerScreen extends ClientScreen implements FastTickable { } void downloadTexture() { - HttpRequest hr = HttpRequest.newBuilder().uri(URI.create("https://crafatar.com/avatars/" + this.storage.cachedUuid + "?overlay")).header("User-Agent", "why").build(); - downloader.sendAsync(hr, HttpResponse.BodyHandlers.ofByteArray()).thenAccept(httpResponse -> { - try { - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - ImageIO.write(ImageIO.read(new ByteArrayInputStream(httpResponse.body())), "png", stream); - byte[] bytes = stream.toByteArray(); - - ByteBuffer data = BufferUtils.createByteBuffer(bytes.length).put(bytes); - data.flip(); - NativeImage img = NativeImage.read(data); - NativeImageBackedTexture texture = new NativeImageBackedTexture(img); - - ShadowMain.client.execute(() -> { - this.tex = new Texture(("dynamic/tex_" + this.storage.cachedUuid.hashCode() + "_" + (Math.random() + "").split("\\.")[1]).toLowerCase()); - ShadowMain.client.getTextureManager().registerTexture(this.tex, texture); - texCache.put(this.storage.cachedUuid, this.tex); - texLoaded = true; - }); - } catch (Exception e) { - e.printStackTrace(); - } - }); + this.tex = PlayerHeadResolver.resolve(this.storage.cachedUuid); } public double getHeight() { @@ -1025,11 +974,7 @@ public class AltManagerScreen extends ClientScreen implements FastTickable { RenderSystem.blendFunc(GL40C.GL_DST_ALPHA, GL40C.GL_ONE_MINUS_DST_ALPHA); RenderSystem.setShaderTexture(0, tex); - if (texLoaded) { - Renderer.R2D.renderTexture(stack, originX + padding, originY + padding, texWidth, texHeight, 0, 0, 64, 64, 64, 64); - } else { - Renderer.R2D.renderTexture(stack, originX + padding, originY + padding, texWidth, texHeight, 8, 8, 8, 8, 64, 64); // default skin - } + Renderer.R2D.renderTexture(stack, originX + padding, originY + padding, texWidth, texHeight, 0, 0, 64, 64, 64, 64); String mail; if (this.storage.type != AddScreenOverlay.AccountType.CRACKED) { mail = this.storage.email; diff --git a/src/main/java/net/shadow/client/feature/gui/screen/HomeScreen.java b/src/main/java/net/shadow/client/feature/gui/screen/HomeScreen.java index 68a8c9c..1edd7ec 100644 --- a/src/main/java/net/shadow/client/feature/gui/screen/HomeScreen.java +++ b/src/main/java/net/shadow/client/feature/gui/screen/HomeScreen.java @@ -12,8 +12,6 @@ import net.minecraft.client.gui.screen.option.OptionsScreen; import net.minecraft.client.gui.screen.world.SelectWorldScreen; import net.minecraft.client.realms.gui.screen.RealmsMainScreen; import net.minecraft.client.render.GameRenderer; -import net.minecraft.client.texture.NativeImage; -import net.minecraft.client.texture.NativeImageBackedTexture; import net.minecraft.client.util.DefaultSkinHelper; import net.minecraft.client.util.math.MatrixStack; import net.shadow.client.ShadowMain; @@ -24,21 +22,14 @@ import net.shadow.client.helper.Texture; import net.shadow.client.helper.font.FontRenderers; import net.shadow.client.helper.font.adapter.FontAdapter; import net.shadow.client.helper.render.MSAAFramebuffer; +import net.shadow.client.helper.render.PlayerHeadResolver; import net.shadow.client.helper.render.Renderer; import org.apache.commons.io.IOUtils; -import org.lwjgl.BufferUtils; import org.lwjgl.opengl.GL40C; -import javax.imageio.ImageIO; import java.awt.Color; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.File; -import java.net.URI; import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.time.Duration; import java.util.AbstractMap; @@ -108,7 +99,10 @@ public class HomeScreen extends ClientScreen { buttonsMap.add(new AbstractMap.SimpleEntry<>("Singleplayer", () -> ShadowMain.client.setScreen(new SelectWorldScreen(this)))); buttonsMap.add(new AbstractMap.SimpleEntry<>("Multiplayer", () -> ShadowMain.client.setScreen(new MultiplayerScreen(this)))); buttonsMap.add(new AbstractMap.SimpleEntry<>("Realms", () -> ShadowMain.client.setScreen(new RealmsMainScreen(this)))); - buttonsMap.add(new AbstractMap.SimpleEntry<>("Alts", () -> ShadowMain.client.setScreen(AltManagerScreen.instance()))); + buttonsMap.add(new AbstractMap.SimpleEntry<>("Alts", () -> { + ShadowMain.client.setScreen(AltManagerScreen.instance()); +// Notification.create(RandomStringUtils.randomPrint(20), RandomUtils.nextLong(4000, 7000), Notification.Type.INFO); + })); buttonsMap.add(new AbstractMap.SimpleEntry<>("Settings", () -> ShadowMain.client.setScreen(new OptionsScreen(this, ShadowMain.client.options)))); buttonsMap.add(new AbstractMap.SimpleEntry<>("Quit", ShadowMain.client::scheduleStop)); // buttonsMap.add(new AbstractMap.SimpleEntry<>("reinit", this::init)); @@ -155,30 +149,9 @@ public class HomeScreen extends ClientScreen { return; } previousChecked = uid; - - HttpRequest hr = HttpRequest.newBuilder().uri(URI.create("https://crafatar.com/avatars/" + uid + "?overlay")).header("User-Agent", "why").timeout(Duration.ofSeconds(5)).build(); - downloader.sendAsync(hr, HttpResponse.BodyHandlers.ofByteArray()).thenAccept(httpResponse -> { - try { - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - ImageIO.write(ImageIO.read(new ByteArrayInputStream(httpResponse.body())), "png", stream); - byte[] bytes = stream.toByteArray(); - - ByteBuffer data = BufferUtils.createByteBuffer(bytes.length).put(bytes); - data.flip(); - NativeImage img = NativeImage.read(data); -// System.out.println(img); - NativeImageBackedTexture texture = new NativeImageBackedTexture(img); - - ShadowMain.client.execute(() -> { - ShadowMain.client.getTextureManager().registerTexture(currentAccountTexture, texture); - currentAccountTextureLoaded = true; - callback.run(); - }); - } catch (Exception e) { - e.printStackTrace(); - callback.run(); - } - }); + PlayerHeadResolver.resolve(uid, this.currentAccountTexture); + currentAccountTextureLoaded = true; + callback.run(); } @Override diff --git a/src/main/java/net/shadow/client/feature/gui/screen/OnlineServicesDashboardScreen.java b/src/main/java/net/shadow/client/feature/gui/screen/OnlineServicesDashboardScreen.java index dd67042..7243f8d 100644 --- a/src/main/java/net/shadow/client/feature/gui/screen/OnlineServicesDashboardScreen.java +++ b/src/main/java/net/shadow/client/feature/gui/screen/OnlineServicesDashboardScreen.java @@ -13,6 +13,7 @@ import net.minecraft.client.gui.Selectable; import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; import net.minecraft.client.util.math.MatrixStack; import net.shadow.client.feature.gui.FastTickable; +import net.shadow.client.feature.gui.notifications.hudNotif.HudNotification; import net.shadow.client.feature.gui.widget.RoundButton; import net.shadow.client.feature.gui.widget.RoundTextFieldWidget; import net.shadow.client.helper.IRCWebSocket; @@ -57,6 +58,7 @@ public class OnlineServicesDashboardScreen extends ClientScreen implements FastT if (ShadowAPIWrapper.getAuthKey() != null) { logs.clear(); logsSocket = new SimpleWebsocket(URI.create(ShadowAPIWrapper.BASE_WS + "/admin/logs"), Map.of("Authorization", ShadowAPIWrapper.getAuthKey()), () -> { + HudNotification.create("Websocket disconnected, reconnecting in 3 seconds", 3000, HudNotification.Type.INFO); reconnectTime = System.currentTimeMillis() + Duration.ofSeconds(3).toMillis(); logs.clear(); }, this::socketMessageRecieved); @@ -152,6 +154,7 @@ public class OnlineServicesDashboardScreen extends ClientScreen implements FastT BiConsumer<String, String> r; RoundTextFieldWidget user, pass; RoundButton reg; + public RegisterAccountViewer(double x, double y, double width, double height, BiConsumer<String, String> onReg) { super("", "", x, y, width, height, () -> { }); @@ -247,12 +250,12 @@ public class OnlineServicesDashboardScreen extends ClientScreen implements FastT @Override public void onFastTick() { - deleteBtn.onFastTick(); + if (deleteBtn != null) deleteBtn.onFastTick(); } @Override public boolean mouseClicked(double mouseX, double mouseY, int button) { - return deleteBtn.mouseClicked(mouseX, mouseY, button); + return deleteBtn != null && deleteBtn.mouseClicked(mouseX, mouseY, button); } } diff --git a/src/main/java/net/shadow/client/feature/module/impl/crash/ErrorCrash.java b/src/main/java/net/shadow/client/feature/module/impl/crash/ErrorCrash.java index b470a6d..2130b2d 100644 --- a/src/main/java/net/shadow/client/feature/module/impl/crash/ErrorCrash.java +++ b/src/main/java/net/shadow/client/feature/module/impl/crash/ErrorCrash.java @@ -4,21 +4,19 @@ package net.shadow.client.feature.module.impl.crash; -import net.minecraft.client.util.math.MatrixStack; -import net.shadow.client.feature.module.ModuleType; -import net.shadow.client.feature.config.DoubleSetting; -import net.shadow.client.feature.config.EnumSetting; -import net.shadow.client.feature.gui.notifications.Notification; -import net.shadow.client.feature.module.Module; import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import net.minecraft.client.util.math.MatrixStack; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.network.packet.c2s.play.ButtonClickC2SPacket; import net.minecraft.network.packet.c2s.play.ClickSlotC2SPacket; import net.minecraft.network.packet.c2s.play.SelectMerchantTradeC2SPacket; -import net.minecraft.network.packet.c2s.play.UpdateSelectedSlotC2SPacket; import net.minecraft.screen.slot.SlotActionType; +import net.shadow.client.feature.config.DoubleSetting; +import net.shadow.client.feature.config.EnumSetting; +import net.shadow.client.feature.module.Module; +import net.shadow.client.feature.module.ModuleType; public class ErrorCrash extends Module { @@ -32,7 +30,7 @@ public class ErrorCrash extends Module { @Override public void tick() { - switch(mode.getValue()){ + switch (mode.getValue()) { case Click -> { Int2ObjectMap<ItemStack> ripbozo = new Int2ObjectArrayMap(); ripbozo.put(0, new ItemStack(Items.ACACIA_BOAT, 1)); diff --git a/src/main/java/net/shadow/client/feature/module/impl/crash/LoominaCrash.java b/src/main/java/net/shadow/client/feature/module/impl/crash/LoominaCrash.java index d4d3b17..5082fb6 100644 --- a/src/main/java/net/shadow/client/feature/module/impl/crash/LoominaCrash.java +++ b/src/main/java/net/shadow/client/feature/module/impl/crash/LoominaCrash.java @@ -79,7 +79,6 @@ public class LoominaCrash extends Module { void simplePacketMove(int slotId) { - //System.out.println(client.player.currentScreenHandler.getSlot(slotId).getStack().getName().getString()); ScreenHandler screenHandler = client.player.currentScreenHandler; Int2ObjectOpenHashMap<ItemStack> int2ObjectMap = new Int2ObjectOpenHashMap<>(); int2ObjectMap.put(slotId, client.player.currentScreenHandler.getSlot(slotId).getStack().copy()); diff --git a/src/main/java/net/shadow/client/feature/module/impl/crash/SSRFCrash.java b/src/main/java/net/shadow/client/feature/module/impl/crash/SSRFCrash.java index 51ed7fa..54bf78b 100644 --- a/src/main/java/net/shadow/client/feature/module/impl/crash/SSRFCrash.java +++ b/src/main/java/net/shadow/client/feature/module/impl/crash/SSRFCrash.java @@ -17,7 +17,6 @@ import net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket; import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.Direction; -import net.minecraft.util.math.Vec3d; import net.shadow.client.feature.module.Module; import net.shadow.client.feature.module.ModuleType; diff --git a/src/main/java/net/shadow/client/feature/module/impl/misc/IRC.java b/src/main/java/net/shadow/client/feature/module/impl/misc/IRC.java index 65ff34b..e4daafd 100644 --- a/src/main/java/net/shadow/client/feature/module/impl/misc/IRC.java +++ b/src/main/java/net/shadow/client/feature/module/impl/misc/IRC.java @@ -19,7 +19,7 @@ import java.net.URI; public class IRC extends Module { static String ircPrefix = "#"; - IRCWebSocket wsS; + public IRCWebSocket wsS; public IRC() { super("IRC", "Chat with others using the client", ModuleType.MISC); @@ -48,6 +48,9 @@ public class IRC extends Module { setEnabled(false); return; } + initSock(); + } + void initSock() { this.wsS = new IRCWebSocket(URI.create(ShadowAPIWrapper.BASE_WS + "/irc"), ShadowAPIWrapper.getAuthKey(), () -> { this.wsS = null; if (this.isEnabled()) this.setEnabled(false); @@ -60,6 +63,11 @@ public class IRC extends Module { if (this.wsS != null) this.wsS.close(); } + public void reconnect() { + if (this.wsS != null) this.wsS.close(); + initSock(); + } + @Override public String getContext() { return null; diff --git a/src/main/java/net/shadow/client/feature/module/impl/render/NameTags.java b/src/main/java/net/shadow/client/feature/module/impl/render/NameTags.java index 2888446..968af6d 100644 --- a/src/main/java/net/shadow/client/feature/module/impl/render/NameTags.java +++ b/src/main/java/net/shadow/client/feature/module/impl/render/NameTags.java @@ -4,6 +4,7 @@ package net.shadow.client.feature.module.impl.render; +import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.network.AbstractClientPlayerEntity; import net.minecraft.client.network.PlayerListEntry; import net.minecraft.client.util.math.MatrixStack; @@ -13,6 +14,8 @@ import net.minecraft.util.math.Vec3d; import net.minecraft.world.GameMode; import net.shadow.client.feature.module.Module; import net.shadow.client.feature.module.ModuleType; +import net.shadow.client.helper.GameTexture; +import net.shadow.client.helper.IRCWebSocket; import net.shadow.client.helper.font.FontRenderers; import net.shadow.client.helper.font.adapter.FontAdapter; import net.shadow.client.helper.render.Renderer; @@ -74,11 +77,28 @@ public class NameTags extends Module { } MatrixStack stack1 = Renderer.R3D.getEmptyMatrixStack(); Vec3d actual = new Vec3d(screenPos.x, screenPos.y - labelHeight, screenPos.z); - float fontWidth = nameDrawer.getStringWidth(text) + 4; - float width = fontWidth; - width = Math.max(width, 70); + float width = nameDrawer.getStringWidth(text) + 4; + width = Math.max(width, 60); + boolean in = IRCWebSocket.knownIRCPlayers.stream().anyMatch(playerEntry -> playerEntry.uuid().equals(entity.getUuid())); + + double origWidth = 782; + double origHeight = 1000; + double newHeight = nameDrawer.getFontHeight(); + double newWidth = origWidth*(newHeight /origHeight); + double req = newWidth+5; + + if (in) { + + if (width-req < nameDrawer.getStringWidth(text)) width += newWidth+5; // make sure we always have some space to draw the icon + } Renderer.R2D.renderRoundedQuad(stack1, new Color(0, 0, 5, 200), actual.x - width / 2d, actual.y, actual.x + width / 2d, actual.y + labelHeight, 3, 20); - nameDrawer.drawString(stack1, text, actual.x - fontWidth / 2d + 2, actual.y + 2, 0xFFFFFF); + nameDrawer.drawString(stack1, text, actual.x + width/2d - nameDrawer.getStringWidth(text)-2, actual.y + 2, 0xFFFFFF); + + if (in) { + RenderSystem.setShaderTexture(0, GameTexture.TEXTURE_ICON.getWhere()); + Renderer.R2D.renderTexture(stack1, actual.x -width/2d+2,actual.y+2, newWidth,newHeight,0,0, newWidth,newHeight, newWidth,newHeight); + } + infoDrawer.drawString(stack1, gmString, actual.x + width / 2d - infoDrawer.getStringWidth(gmString) - 2, actual.y + 2 + nameDrawer.getFontHeight(), 0xAAAAAA); if (ping != -1) infoDrawer.drawString(stack1, pingStr, actual.x - width / 2d + 2, actual.y + 2 + nameDrawer.getFontHeight(), 0xAAAAAA); diff --git a/src/main/java/net/shadow/client/feature/module/impl/render/TargetHud.java b/src/main/java/net/shadow/client/feature/module/impl/render/TargetHud.java index 41eaa25..d0fcf5c 100644 --- a/src/main/java/net/shadow/client/feature/module/impl/render/TargetHud.java +++ b/src/main/java/net/shadow/client/feature/module/impl/render/TargetHud.java @@ -20,6 +20,7 @@ import net.shadow.client.feature.module.ModuleType; import net.shadow.client.helper.Texture; import net.shadow.client.helper.font.FontRenderers; import net.shadow.client.helper.manager.AttackManager; +import net.shadow.client.helper.render.PlayerHeadResolver; import net.shadow.client.helper.render.Renderer; import net.shadow.client.helper.util.Transitions; import net.shadow.client.helper.util.Utils; @@ -150,7 +151,7 @@ public class TargetHud extends Module { double textLeftAlign = 32 + 10; Renderer.R2D.renderRoundedQuad(stack, new Color(20, 20, 20, 200), 0, 0, modalWidth, modalHeight, 5, 10); - Texture tex = new Texture(Utils.Textures.getSkinPreviewTexture(entity.getUuid())); + Texture tex = PlayerHeadResolver.resolve(entity.getUuid()); RenderSystem.setShaderTexture(0, tex); RenderSystem.enableBlend(); @@ -193,4 +194,3 @@ public class TargetHud extends Module { } } - diff --git a/src/main/java/net/shadow/client/helper/ConfigContainer.java b/src/main/java/net/shadow/client/helper/ConfigContainer.java index a2af521..5134f5a 100644 --- a/src/main/java/net/shadow/client/helper/ConfigContainer.java +++ b/src/main/java/net/shadow/client/helper/ConfigContainer.java @@ -46,7 +46,6 @@ public class ConfigContainer { } void write(String data) { - System.out.println("writing " + data); try { FileUtils.write(path, data, StandardCharsets.UTF_8); } catch (Exception e) { diff --git a/src/main/java/net/shadow/client/helper/IRCWebSocket.java b/src/main/java/net/shadow/client/helper/IRCWebSocket.java index ddaef08..0562057 100644 --- a/src/main/java/net/shadow/client/helper/IRCWebSocket.java +++ b/src/main/java/net/shadow/client/helper/IRCWebSocket.java @@ -5,6 +5,7 @@ package net.shadow.client.helper; import com.google.gson.Gson; +import com.google.gson.internal.LinkedTreeMap; import lombok.AllArgsConstructor; import net.minecraft.text.Text; import net.minecraft.util.Formatting; @@ -14,18 +15,25 @@ import org.java_websocket.client.WebSocketClient; import org.java_websocket.handshake.ServerHandshake; import java.net.URI; +import java.util.ArrayList; +import java.util.List; import java.util.Map; +import java.util.UUID; +import java.util.concurrent.CopyOnWriteArrayList; public class IRCWebSocket extends WebSocketClient { + public record PlayerEntry(String username, UUID uuid) { + + } + public static List<PlayerEntry> knownIRCPlayers = new CopyOnWriteArrayList<>(); String authToken; Runnable onClose; public IRCWebSocket(URI serverUri, String authToken, Runnable onClose) { - super(serverUri, Map.of("Authorization", authToken)); + super(serverUri, Map.of("Authorization", authToken, "X-MC-UUID", ShadowMain.client.getSession().getUuid(), "X-MC-USERNAME", ShadowMain.client.getSession().getUsername())); this.authToken = authToken; this.onClose = onClose; } - @Override public void onOpen(ServerHandshake handshakedata) { Utils.Logging.success("Connected to IRC"); @@ -38,20 +46,35 @@ public class IRCWebSocket extends WebSocketClient { case "message" -> { String uname = p.data.get("who").toString(); String msg = p.data.get("message").toString(); - ShadowMain.client.player.sendMessage(Text.of(String.format("%s[IRC] %s[%s] %s", Formatting.AQUA, Formatting.BLUE, uname, msg)), false); + Utils.Logging.message(Text.of(String.format("%s[IRC] %s[%s] %s", Formatting.AQUA, Formatting.BLUE, uname, msg))); } case "userJoined" -> { String uname = p.data.get("who").toString(); - ShadowMain.client.player.sendMessage(Text.of(String.format("%s[IRC] %s%s joined the IRC", Formatting.AQUA, Formatting.GREEN, uname)), false); + Utils.Logging.message(Text.of(String.format("%s[IRC] %s%s joined the IRC", Formatting.AQUA, Formatting.GREEN, uname))); } case "userLeft" -> { String uname = p.data.get("who").toString(); - ShadowMain.client.player.sendMessage(Text.of(String.format("%s[IRC] %s%s left the IRC", Formatting.AQUA, Formatting.RED, uname)), false); + Utils.Logging.message(Text.of(String.format("%s[IRC] %s%s left the IRC", Formatting.AQUA, Formatting.RED, uname))); } case "connectFailed" -> { String reason = p.data.get("reason").toString(); Utils.Logging.error("Failed to establish connection, server said: " + reason); } + case "usersList" -> { + knownIRCPlayers.clear(); + for (LinkedTreeMap<String, String> who : ((ArrayList<LinkedTreeMap<String, String>>) p.data.get("who"))) { + String u = who.get("username"); + UUID uuid; + try { + uuid = UUID.fromString(who.get("uuid")); + } catch (Exception ignored) { + continue; + } + PlayerEntry pe = new PlayerEntry(u,uuid); + if(!knownIRCPlayers.contains(pe)) knownIRCPlayers.add(pe); + } + + } } } @@ -59,6 +82,7 @@ public class IRCWebSocket extends WebSocketClient { public void onClose(int code, String reason, boolean remote) { Utils.Logging.error("IRC Disconnected"); this.onClose.run(); + knownIRCPlayers.clear(); } @Override diff --git a/src/main/java/net/shadow/client/helper/render/Cursor.java b/src/main/java/net/shadow/client/helper/render/Cursor.java index e20cf14..19d18dc 100644 --- a/src/main/java/net/shadow/client/helper/render/Cursor.java +++ b/src/main/java/net/shadow/client/helper/render/Cursor.java @@ -16,12 +16,6 @@ public class Cursor { public static void setGlfwCursor(long cursor) { if (currentCursor == cursor) return; - String cname = "(unknown)"; - if (CLICK == cursor) cname = "CLICK"; - if (STANDARD == cursor) cname = "STANDARD"; - if (TEXT_EDIT == cursor) cname = "TEXT_EDIT"; - if (HSLIDER == cursor) cname = "HSLIDER"; - System.out.println("set cursor: 0x" + Long.toHexString(cursor).toUpperCase() + ": " + cname); currentCursor = cursor; GLFW.glfwSetCursor(ShadowMain.client.getWindow().getHandle(), cursor); } diff --git a/src/main/java/net/shadow/client/helper/render/PlayerHeadResolver.java b/src/main/java/net/shadow/client/helper/render/PlayerHeadResolver.java new file mode 100644 index 0000000..007a529 --- /dev/null +++ b/src/main/java/net/shadow/client/helper/render/PlayerHeadResolver.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) Shadow client, 0x150, Saturn5VFive 2022. All rights reserved. + */ + +package net.shadow.client.helper.render; + +import net.minecraft.client.texture.NativeImage; +import net.minecraft.client.texture.NativeImageBackedTexture; +import net.shadow.client.ShadowMain; +import net.shadow.client.helper.Texture; +import org.lwjgl.BufferUtils; + +import javax.imageio.ImageIO; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class PlayerHeadResolver { + static final NativeImageBackedTexture EMPTY = new NativeImageBackedTexture(1, 1, false); + static HttpClient client = HttpClient.newBuilder().followRedirects(HttpClient.Redirect.ALWAYS).build(); + static Map<UUID, NativeImageBackedTexture> imageCache = new HashMap<>(); + + public static void resolve(UUID uuid, Texture texture) { + if (imageCache.containsKey(uuid)) { + ShadowMain.client.execute(() -> ShadowMain.client.getTextureManager().registerTexture(texture, imageCache.get(uuid))); + return; + } + imageCache.put(uuid, EMPTY); + ShadowMain.client.execute(() -> ShadowMain.client.getTextureManager().registerTexture(texture, EMPTY)); + URI u = URI.create("https://mc-heads.net/avatar/" + uuid); + HttpRequest hr = HttpRequest.newBuilder().uri(u).header("user-agent", "shadow/1.0").build(); + System.out.println("getting " + uuid.toString()); + client.sendAsync(hr, HttpResponse.BodyHandlers.ofByteArray()).thenAccept(httpResponse -> { + try { + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + ImageIO.write(ImageIO.read(new ByteArrayInputStream(httpResponse.body())), "png", stream); + byte[] bytes = stream.toByteArray(); + + ByteBuffer data = BufferUtils.createByteBuffer(bytes.length).put(bytes); + data.flip(); + NativeImage img = NativeImage.read(data); + NativeImageBackedTexture nib = new NativeImageBackedTexture(img); + + ShadowMain.client.execute(() -> ShadowMain.client.getTextureManager().registerTexture(texture, nib)); + imageCache.put(uuid, nib); + + } catch (Exception e) { + e.printStackTrace(); + } + }).exceptionally(throwable -> { + throwable.printStackTrace(); + return null; + }); + + } + + public static Texture resolve(UUID uuid) { + Texture tex = new Texture(String.format("skin_preview-%s", uuid.toString())); + resolve(uuid, tex); + return tex; + } +} diff --git a/src/main/java/net/shadow/client/helper/util/Utils.java b/src/main/java/net/shadow/client/helper/util/Utils.java index 67d27ce..df97423 100644 --- a/src/main/java/net/shadow/client/helper/util/Utils.java +++ b/src/main/java/net/shadow/client/helper/util/Utils.java @@ -16,6 +16,7 @@ import net.minecraft.nbt.StringNbtReader; import net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket; import net.minecraft.screen.slot.SlotActionType; import net.minecraft.text.LiteralText; +import net.minecraft.text.Text; import net.minecraft.text.TextColor; import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; @@ -46,11 +47,13 @@ import java.net.http.HttpResponse; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.time.Duration; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Queue; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; @@ -367,27 +370,37 @@ public class Utils { } public static class Logging { + static Queue<Text> messageQueue = new ArrayDeque<>(); + static void sendMessages() { + if (ShadowMain.client.player != null) { + Text next; + while((next = messageQueue.poll()) != null) { + ShadowMain.client.player.sendMessage(next, false); + } + } + } public static void warn(String n) { - message0(n, Color.YELLOW); + message(n, Color.YELLOW); } public static void success(String n) { - message0(n, new Color(65, 217, 101)); + message(n, new Color(65, 217, 101)); } public static void error(String n) { - message0(n, new Color(214, 93, 62)); + message(n, new Color(214, 93, 62)); } public static void message(String n) { - message0(n, Color.WHITE); + message(n, Color.WHITE); } - - public static void message0(String n, Color c) { + public static void message(Text text) { + messageQueue.add(text); + } + public static void message(String n, Color c) { LiteralText t = new LiteralText(n); t.setStyle(t.getStyle().withColor(TextColor.fromRgb(c.getRGB()))); - if (ShadowMain.client.player != null) if (!(ShadowMain.client.currentScreen instanceof ConsoleScreen)) - ShadowMain.client.player.sendMessage(t, false); + if (!(ShadowMain.client.currentScreen instanceof ConsoleScreen)) message(t); // if (c.equals(Color.WHITE)) c = Color.BLACK; ConsoleScreen.instance().addLog(new ConsoleScreen.LogEntry(n, c)); } @@ -404,6 +417,7 @@ public class Utils { } public static void tick() { + Logging.sendMessages(); for (TickEntry entry : entries.toArray(new TickEntry[0])) { entry.v--; if (entry.v <= 0) { diff --git a/src/main/java/net/shadow/client/mixin/GameRendererMixin.java b/src/main/java/net/shadow/client/mixin/GameRendererMixin.java index 350db95..0f3855d 100644 --- a/src/main/java/net/shadow/client/mixin/GameRendererMixin.java +++ b/src/main/java/net/shadow/client/mixin/GameRendererMixin.java @@ -15,6 +15,7 @@ import net.minecraft.util.math.Vec3d; import net.minecraft.world.RaycastContext; import net.shadow.client.ShadowMain; import net.shadow.client.feature.gui.DoesMSAA; +import net.shadow.client.feature.gui.notifications.hudNotif.HudNotificationRenderer; import net.shadow.client.feature.gui.screen.ClientScreen; import net.shadow.client.feature.module.Module; import net.shadow.client.feature.module.ModuleRegistry; @@ -107,4 +108,9 @@ public class GameRendererMixin { double zv = ModuleRegistry.getByClass(Zoom.class).getZoomValue(cir.getReturnValue()); cir.setReturnValue(zv); } + + @Inject(method = "render", at = @At("RETURN")) + void a(float tickDelta, long startTime, boolean tick, CallbackInfo ci) { + HudNotificationRenderer.instance.render(Renderer.R3D.getEmptyMatrixStack()); + } } diff --git a/src/main/java/net/shadow/client/mixin/MinecraftClientMixin.java b/src/main/java/net/shadow/client/mixin/MinecraftClientMixin.java index ca7ad23..228d368 100644 --- a/src/main/java/net/shadow/client/mixin/MinecraftClientMixin.java +++ b/src/main/java/net/shadow/client/mixin/MinecraftClientMixin.java @@ -7,15 +7,20 @@ package net.shadow.client.mixin; import net.minecraft.client.MinecraftClient; import net.minecraft.client.RunArgs; import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.util.Session; import net.shadow.client.ShadowMain; import net.shadow.client.feature.module.ModuleRegistry; +import net.shadow.client.feature.module.impl.misc.IRC; import net.shadow.client.feature.module.impl.world.FastUse; import net.shadow.client.helper.event.EventType; import net.shadow.client.helper.event.Events; import net.shadow.client.helper.event.events.base.NonCancellableEvent; import net.shadow.client.helper.manager.ConfigManager; +import net.shadow.client.mixinUtil.MinecraftClientDuck; import org.objectweb.asm.Opcodes; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -25,16 +30,29 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.Objects; @Mixin(MinecraftClient.class) -public class MinecraftClientMixin { +public class MinecraftClientMixin implements MinecraftClientDuck { @Shadow private int itemUseCooldown; + @Mutable + @Shadow @Final private Session session; + @Inject(method = "stop", at = @At("HEAD")) void real(CallbackInfo ci) { ConfigManager.saveState(); Events.fireEvent(EventType.GAME_EXIT, new NonCancellableEvent()); } + @Override + public void setSession(Session newSession) { + this.session = newSession; + IRC i = ModuleRegistry.getByClass(IRC.class); + // reconnect to the irc with the new session to stay up to date + if (i.isEnabled()) { + i.reconnect(); + } + } + @Inject(method = "<init>", at = @At("TAIL")) void postInit(RunArgs args, CallbackInfo ci) { ShadowMain.INSTANCE.postWindowInit(); diff --git a/src/main/java/net/shadow/client/mixin/PlayerListHudMixin.java b/src/main/java/net/shadow/client/mixin/PlayerListHudMixin.java new file mode 100644 index 0000000..50e6e8f --- /dev/null +++ b/src/main/java/net/shadow/client/mixin/PlayerListHudMixin.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) Shadow client, 0x150, Saturn5VFive 2022. All rights reserved. + */ + +package net.shadow.client.mixin; + +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.gui.hud.PlayerListHud; +import net.minecraft.client.network.PlayerListEntry; +import net.minecraft.client.util.math.MatrixStack; +import net.shadow.client.helper.GameTexture; +import net.shadow.client.helper.IRCWebSocket; +import net.shadow.client.helper.render.Renderer; +import net.shadow.client.helper.util.Utils; +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.CallbackInfo; + +@Mixin(PlayerListHud.class) +public abstract class PlayerListHudMixin { + @Inject(method="renderLatencyIcon",at=@At("HEAD"),cancellable = true) + void a(MatrixStack matrices, int width, int x, int y, PlayerListEntry entry, CallbackInfo ci) { + if (IRCWebSocket.knownIRCPlayers.stream().anyMatch(playerEntry -> playerEntry.uuid().equals(entry.getProfile().getId()))) { + ci.cancel(); + double supposedWidth = 10; + double origWidth = 782; + double origHeight = 1000; + double newHeight = 8; + double newWidth = origWidth*(newHeight /origHeight); + Utils.TickManager.runOnNextRender(() -> { + RenderSystem.setShaderTexture(0, GameTexture.TEXTURE_ICON.getWhere()); + Renderer.R2D.renderTexture(matrices,x + width - supposedWidth/2d - newWidth/2d -1,y, newWidth,newHeight,0,0, newWidth,newHeight, newWidth,newHeight); + }); + } + } +} diff --git a/src/main/java/net/shadow/client/mixin/PlayerSkinMixin.java b/src/main/java/net/shadow/client/mixin/PlayerSkinMixin.java deleted file mode 100644 index cbb7b48..0000000 --- a/src/main/java/net/shadow/client/mixin/PlayerSkinMixin.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) Shadow client, 0x150, Saturn5VFive 2022. All rights reserved. - */ - -package net.shadow.client.mixin; - -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.minecraft.MinecraftProfileTexture; -import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type; -import com.mojang.authlib.minecraft.MinecraftSessionService; -import net.minecraft.client.texture.PlayerSkinProvider; -import net.minecraft.util.Identifier; -import org.jetbrains.annotations.Nullable; -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.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; - -import java.io.InputStreamReader; -import java.net.URL; -import java.util.Map; - -@Mixin(PlayerSkinProvider.class) -public class PlayerSkinMixin { - private static JsonObject capes; - @Shadow - @Final - private MinecraftSessionService sessionService; - - //I cant even launch mc with this! it doesnt work - // skill issue, i would say - @Inject(method = "method_4653", at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/MinecraftClient;execute(Ljava/lang/Runnable;)V", - shift = At.Shift.BEFORE - ), locals = LocalCapture.CAPTURE_FAILEXCEPTION) - void real(GameProfile gameProfile, boolean bl, PlayerSkinProvider.SkinTextureAvailableCallback skinTextureAvailableCallback, CallbackInfo ci, Map<Type, MinecraftProfileTexture> map) { - addCape(gameProfile, map); - } - - private void addCape(GameProfile profile, - Map<MinecraftProfileTexture.Type, MinecraftProfileTexture> map) { - String name = profile.getName(); - String uuid = profile.getId().toString(); - - try { - if (capes == null) - setupCapes(); - - if (capes.has(name)) { - String capeURL = capes.get(name).getAsString(); - map.put(Type.CAPE, new MinecraftProfileTexture(capeURL, null)); - - } else if (capes.has(uuid)) { - String capeURL = capes.get(uuid).getAsString(); - map.put(Type.CAPE, new MinecraftProfileTexture(capeURL, null)); - } - - } catch (Exception e) { - System.err.println("[Shadow] Failed to load cape for '" + name - + "' (" + uuid + ")"); - - e.printStackTrace(); - } - } - - private void setupCapes() { - try { - URL url = new URL("https://moleapi.pythonanywhere.com/retrieve"); - capes = JsonParser.parseReader(new InputStreamReader(url.openStream())).getAsJsonObject(); - } catch (Exception e) { - System.err.println("[Shadow] Failed to load capes from API"); - e.printStackTrace(); - } - } - - @Shadow - private Identifier loadSkin(MinecraftProfileTexture profileTexture, - Type type, - @Nullable PlayerSkinProvider.SkinTextureAvailableCallback callback) { - return null; - } -} diff --git a/src/main/java/net/shadow/client/mixinUtil/MinecraftClientDuck.java b/src/main/java/net/shadow/client/mixinUtil/MinecraftClientDuck.java new file mode 100644 index 0000000..c184ef0 --- /dev/null +++ b/src/main/java/net/shadow/client/mixinUtil/MinecraftClientDuck.java @@ -0,0 +1,11 @@ +/* + * Copyright (c) Shadow client, 0x150, Saturn5VFive 2022. All rights reserved. + */ + +package net.shadow.client.mixinUtil; + +import net.minecraft.client.util.Session; + +public interface MinecraftClientDuck { + void setSession(Session newSession); +} diff --git a/src/main/resources/shadow.mixins.json b/src/main/resources/shadow.mixins.json index bfe07cf..0b2596c 100644 --- a/src/main/resources/shadow.mixins.json +++ b/src/main/resources/shadow.mixins.json @@ -33,6 +33,7 @@ "IClientPlayerInteractionManagerAccessor", "ICustomPayloadC2SPacketAccessor", "IDebugHudAccessor", + "IdentifierAccessor", "IEntityVelocityUpdateS2CPacketMixin", "IInGameHudAccessor", "ILivingEntityAccessor", @@ -57,7 +58,7 @@ "PlayerEntityMixin", "PlayerEntityRendererMixin", "PlayerInteractEntityC2SPacketAccessor", - "PlayerSkinMixin", + "PlayerListHudMixin", "RebuildTaskMixin", "ScreenMixin", "SelectWorldScreenMixin", @@ -68,8 +69,7 @@ "SliderWidgetMixin", "TitleScreenMixin", "WorldRendererAccessor", - "WorldRendererMixin", - "IdentifierAccessor" + "WorldRendererMixin" ], "client": [], "server": [],