From 8416fc702df5a6530fb3724063d8dc0a214be505 Mon Sep 17 00:00:00 2001 From: TheKodeToad <57493648+TheKodeToad@users.noreply.github.com> Date: Tue, 28 Jun 2022 17:05:48 +0100 Subject: [PATCH 01/77] Fix hotbar keys on Linux --- .../io/github/solclient/client/Client.java | 9 +-- .../io/github/solclient/client/MiscInit.java | 28 +++++++ .../mixin/lwjgl/MixinLinuxKeyboard.java | 73 +++++++++++++++++++ .../mixin/lwjgl/MixinLinuxKeycodes.java | 14 ++++ .../tweak/transformer/ClassTransformer.java | 4 +- .../impl/TransformerGuiScreen.java | 5 +- .../impl/TransformerLinuxKeycodes.java | 21 ++++++ .../github/solclient/client/util/Utils.java | 35 +++------ .../client/util/font/SlickFontRenderer.java | 30 +------- game/src/main/resources/mixins.solclient.json | 4 +- 10 files changed, 160 insertions(+), 63 deletions(-) create mode 100644 game/src/main/java/io/github/solclient/client/MiscInit.java create mode 100644 game/src/main/java/io/github/solclient/client/mixin/lwjgl/MixinLinuxKeyboard.java create mode 100644 game/src/main/java/io/github/solclient/client/mixin/lwjgl/MixinLinuxKeycodes.java create mode 100644 game/src/main/java/io/github/solclient/client/tweak/transformer/impl/TransformerLinuxKeycodes.java diff --git a/game/src/main/java/io/github/solclient/client/Client.java b/game/src/main/java/io/github/solclient/client/Client.java index d1b1509a..14c0b38e 100755 --- a/game/src/main/java/io/github/solclient/client/Client.java +++ b/game/src/main/java/io/github/solclient/client/Client.java @@ -9,7 +9,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.function.Supplier; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.ArrayUtils; @@ -76,13 +75,11 @@ import io.github.solclient.client.ui.ChatButton; import io.github.solclient.client.ui.screen.mods.ModsScreen; import io.github.solclient.client.ui.screen.mods.MoveHudsScreen; -import io.github.solclient.client.util.Utils; import io.github.solclient.client.util.access.AccessMinecraft; import lombok.Getter; import lombok.Setter; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiMainMenu; -import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.multiplayer.ServerData; import net.minecraft.client.multiplayer.WorldClient; import net.minecraft.client.resources.IResource; @@ -138,11 +135,7 @@ public class Client { private GuiMainMenu mainMenu; public void init() { - Utils.resetLineWidth(); - new File(mc.mcDataDir, "server-resource-packs").mkdirs(); // Fix crash - - System.setProperty("http.agent", "Sol Client/" + VERSION); - + MiscInit.init(); LOGGER.info("Initialising..."); bus.register(this); diff --git a/game/src/main/java/io/github/solclient/client/MiscInit.java b/game/src/main/java/io/github/solclient/client/MiscInit.java new file mode 100644 index 00000000..764840b5 --- /dev/null +++ b/game/src/main/java/io/github/solclient/client/MiscInit.java @@ -0,0 +1,28 @@ +package io.github.solclient.client; + +import java.io.File; + +import io.github.solclient.client.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.util.Util; +import net.minecraft.util.Util.EnumOS; + +public class MiscInit { + + public static void init() { + if(Util.getOSType() == EnumOS.LINUX) { + try { + Class.forName("org.lwjgl.opengl.LinuxKeycodes"); + } + catch(ClassNotFoundException error) { + error.printStackTrace(); + } + } + + Utils.resetLineWidth(); + new File(Minecraft.getMinecraft().mcDataDir, "server-resource-packs").mkdirs(); // Fix crash + + System.setProperty("http.agent", "Sol Client/" + Client.VERSION); + } + +} diff --git a/game/src/main/java/io/github/solclient/client/mixin/lwjgl/MixinLinuxKeyboard.java b/game/src/main/java/io/github/solclient/client/mixin/lwjgl/MixinLinuxKeyboard.java new file mode 100644 index 00000000..624d5e96 --- /dev/null +++ b/game/src/main/java/io/github/solclient/client/mixin/lwjgl/MixinLinuxKeyboard.java @@ -0,0 +1,73 @@ +package io.github.solclient.client.mixin.lwjgl; + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(targets = "org.lwjgl.opengl.LinuxKeyboard") +public class MixinLinuxKeyboard { + + @Shadow + private @Final int numlock_mask, modeswitch_mask, caps_lock_mask, shift_lock_mask; + + @Overwrite + private int getKeycode(long eventp, int eventState) { + /* + * Copyright (c) 2002-2008 LWJGL Project All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + boolean shift = (eventState & (1 | shift_lock_mask)) != 0; + int group = (eventState & modeswitch_mask) != 0 ? 1 : 0; + long keysym; + if((eventState & numlock_mask) != 0 && isKeypadKeysym(keysym = getKeySym(eventp, group, 1))) { + if(shift) + keysym = getKeySym(eventp, group, 0); + } + else { + keysym = getKeySym(eventp, group, 0); + if(shift ^ ((eventState & caps_lock_mask) != 0)) + keysym = toUpper(keysym); + } + return MixinLinuxKeycodes.mapKeySymToLWJGLKeyCode(keysym); + } + + @Shadow + private static boolean isKeypadKeysym(long keysym) { + throw new UnsupportedOperationException(); + } + + @Shadow + private static long getKeySym(long eventp, int group, int index) { + throw new UnsupportedOperationException(); + } + + @Shadow + private static native long toUpper(long keysym); + +} diff --git a/game/src/main/java/io/github/solclient/client/mixin/lwjgl/MixinLinuxKeycodes.java b/game/src/main/java/io/github/solclient/client/mixin/lwjgl/MixinLinuxKeycodes.java new file mode 100644 index 00000000..145d52e5 --- /dev/null +++ b/game/src/main/java/io/github/solclient/client/mixin/lwjgl/MixinLinuxKeycodes.java @@ -0,0 +1,14 @@ +package io.github.solclient.client.mixin.lwjgl; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(targets = "org.lwjgl.opengl.LinuxKeycodes") +public interface MixinLinuxKeycodes { + + @Invoker("mapKeySymToLWJGLKeyCode") + static int mapKeySymToLWJGLKeyCode(long keysym) { + throw new UnsupportedOperationException(); + } + +} diff --git a/game/src/main/java/io/github/solclient/client/tweak/transformer/ClassTransformer.java b/game/src/main/java/io/github/solclient/client/tweak/transformer/ClassTransformer.java index b4a7f45c..2714a370 100644 --- a/game/src/main/java/io/github/solclient/client/tweak/transformer/ClassTransformer.java +++ b/game/src/main/java/io/github/solclient/client/tweak/transformer/ClassTransformer.java @@ -1,18 +1,17 @@ package io.github.solclient.client.tweak.transformer; -import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; -import org.apache.commons.io.FileUtils; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.tree.ClassNode; import io.github.solclient.client.tweak.transformer.impl.TransformerGuiButton; import io.github.solclient.client.tweak.transformer.impl.TransformerGuiScreen; +import io.github.solclient.client.tweak.transformer.impl.TransformerLinuxKeycodes; import io.github.solclient.client.tweak.transformer.impl.TransformerMinecraft; import io.github.solclient.client.tweak.transformer.impl.TransformerWorldClient; import net.minecraft.launchwrapper.IClassTransformer; @@ -26,6 +25,7 @@ public ClassTransformer() { register(new TransformerGuiScreen()); register(new TransformerWorldClient()); register(new TransformerMinecraft()); + register(new TransformerLinuxKeycodes()); } @Override diff --git a/game/src/main/java/io/github/solclient/client/tweak/transformer/impl/TransformerGuiScreen.java b/game/src/main/java/io/github/solclient/client/tweak/transformer/impl/TransformerGuiScreen.java index a4050517..c57e056c 100644 --- a/game/src/main/java/io/github/solclient/client/tweak/transformer/impl/TransformerGuiScreen.java +++ b/game/src/main/java/io/github/solclient/client/tweak/transformer/impl/TransformerGuiScreen.java @@ -1,13 +1,12 @@ package io.github.solclient.client.tweak.transformer.impl; +import java.lang.reflect.Modifier; + import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.FieldNode; -import org.objectweb.asm.tree.MethodNode; import io.github.solclient.client.tweak.transformer.ClassNodeTransformer; -import java.lang.reflect.Modifier; - public class TransformerGuiScreen implements ClassNodeTransformer { @Override diff --git a/game/src/main/java/io/github/solclient/client/tweak/transformer/impl/TransformerLinuxKeycodes.java b/game/src/main/java/io/github/solclient/client/tweak/transformer/impl/TransformerLinuxKeycodes.java new file mode 100644 index 00000000..b69d1d8b --- /dev/null +++ b/game/src/main/java/io/github/solclient/client/tweak/transformer/impl/TransformerLinuxKeycodes.java @@ -0,0 +1,21 @@ +package io.github.solclient.client.tweak.transformer.impl; + +import java.lang.reflect.Modifier; + +import org.objectweb.asm.tree.ClassNode; + +import io.github.solclient.client.tweak.transformer.ClassNodeTransformer; + +public class TransformerLinuxKeycodes implements ClassNodeTransformer { + + @Override + public boolean test(String name) { + return name.equals("org/lwjgl/opengl/LinuxKeycodes"); + } + + @Override + public void apply(ClassNode clazz) { + clazz.access |= Modifier.PUBLIC; + } + +} diff --git a/game/src/main/java/io/github/solclient/client/util/Utils.java b/game/src/main/java/io/github/solclient/client/util/Utils.java index 69258283..5a33a28e 100755 --- a/game/src/main/java/io/github/solclient/client/util/Utils.java +++ b/game/src/main/java/io/github/solclient/client/util/Utils.java @@ -1,38 +1,27 @@ package io.github.solclient.client.util; -import java.awt.Desktop; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.io.OutputStream; import java.io.PrintStream; -import java.io.PrintWriter; import java.io.UnsupportedEncodingException; -import java.net.HttpURLConnection; import java.net.InetAddress; -import java.net.URI; import java.net.URL; import java.net.URLConnection; import java.net.UnknownHostException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Paths; import java.util.Comparator; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadLocalRandom; import java.util.function.IntConsumer; -import org.apache.commons.io.IOUtils; import org.lwjgl.opengl.GL11; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; import com.replaymod.replay.ReplayModReplay; import com.replaymod.replay.camera.CameraEntity; -import io.github.solclient.client.lib.penner.easing.Linear; import io.github.solclient.client.mod.impl.SolClientMod; import io.github.solclient.client.util.data.Colour; import io.github.solclient.client.util.data.Rectangle; @@ -131,10 +120,10 @@ public void drawRectangle(double x, double y, double right, double bottom, int c bottom = swap; } - float r = (float) (colour >> 24 & 255) / 255.0F; - float g = (float) (colour >> 16 & 255) / 255.0F; - float b = (float) (colour >> 8 & 255) / 255.0F; - float a = (float) (colour & 255) / 255.0F; + float r = (colour >> 24 & 255) / 255.0F; + float g = (colour >> 16 & 255) / 255.0F; + float b = (colour >> 8 & 255) / 255.0F; + float a = (colour & 255) / 255.0F; Tessellator tessellator = Tessellator.getInstance(); WorldRenderer worldrenderer = tessellator.getWorldRenderer(); @@ -433,10 +422,10 @@ public void drawFloatRectangle(float left, float top, float right, float bottom, bottom = swap; } - float f3 = (float) (colour >> 24 & 255) / 255.0F; - float f = (float) (colour >> 16 & 255) / 255.0F; - float f1 = (float) (colour >> 8 & 255) / 255.0F; - float f2 = (float) (colour & 255) / 255.0F; + float f3 = (colour >> 24 & 255) / 255.0F; + float f = (colour >> 16 & 255) / 255.0F; + float f1 = (colour >> 8 & 255) / 255.0F; + float f2 = (colour & 255) / 255.0F; Tessellator tessellator = Tessellator.getInstance(); WorldRenderer worldrenderer = tessellator.getWorldRenderer(); GlStateManager.enableBlend(); @@ -444,10 +433,10 @@ public void drawFloatRectangle(float left, float top, float right, float bottom, GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); GlStateManager.color(f, f1, f2, f3); worldrenderer.begin(7, DefaultVertexFormats.POSITION); - worldrenderer.pos((double) left, (double) bottom, 0.0D).endVertex(); - worldrenderer.pos((double) right, (double) bottom, 0.0D).endVertex(); - worldrenderer.pos((double) right, (double) top, 0.0D).endVertex(); - worldrenderer.pos((double) left, (double) top, 0.0D).endVertex(); + worldrenderer.pos(left, bottom, 0.0D).endVertex(); + worldrenderer.pos(right, bottom, 0.0D).endVertex(); + worldrenderer.pos(right, top, 0.0D).endVertex(); + worldrenderer.pos(left, top, 0.0D).endVertex(); tessellator.draw(); GlStateManager.enableTexture2D(); GlStateManager.disableBlend(); diff --git a/game/src/main/java/io/github/solclient/client/util/font/SlickFontRenderer.java b/game/src/main/java/io/github/solclient/client/util/font/SlickFontRenderer.java index 29cc80ff..0c7c498b 100644 --- a/game/src/main/java/io/github/solclient/client/util/font/SlickFontRenderer.java +++ b/game/src/main/java/io/github/solclient/client/util/font/SlickFontRenderer.java @@ -45,24 +45,8 @@ public class SlickFontRenderer implements Font { private static final Pattern COLOR_CODE_PATTERN = Pattern.compile("§[0123456789abcdefklmnor]"); - private final int[] colorCodes = { - 0x000000, - 0x0000AA, - 0x00AA00, - 0x00AAAA, - 0xAA0000, - 0xAA00AA, - 0xFFAA00, - 0xAAAAAA, - 0x555555, - 0x5555FF, - 0x55FF55, - 0x55FFFF, - 0xFF5555, - 0xFF55FF, - 0xFFFF55, - 0xFFFFFF - }; + private final int[] colorCodes = { 0x000000, 0x0000AA, 0x00AA00, 0x00AAAA, 0xAA0000, 0xAA00AA, 0xFFAA00, 0xAAAAAA, + 0x555555, 0x5555FF, 0x55FF55, 0x55FFFF, 0xFF5555, 0xFF55FF, 0xFFFF55, 0xFFFFFF }; private float scaleFactor; private UnicodeFont slickFont; private int prevScaleFactor; @@ -135,8 +119,7 @@ public int renderString(String text, float x, float y, int colour) { char colorCode = characters[index]; if(colorCode == '§') { char colorChar = characters[index + 1]; - int codeIndex = ("0123456789" + - "abcdef").indexOf(colorChar); + int codeIndex = ("0123456789" + "abcdef").indexOf(colorChar); if(codeIndex < 0) { if(colorChar == 'r') { currentColour = colour; @@ -214,12 +197,7 @@ public UnicodeFont getFont() { } public void drawSplitString(ArrayList lines, int x, int y, int color) { - renderString( - String.join("\n\r", lines), - x, - y, - color - ); + renderString(String.join("\n\r", lines), x, y, color); } public List splitString(String text, int wrapWidth) { diff --git a/game/src/main/resources/mixins.solclient.json b/game/src/main/resources/mixins.solclient.json index 44f36a6e..9cb6947c 100644 --- a/game/src/main/resources/mixins.solclient.json +++ b/game/src/main/resources/mixins.solclient.json @@ -85,7 +85,9 @@ "mod.MixinV1_7VisualsMod$MixinItemRenderer", "mod.MixinV1_7VisualsMod$MixinLayerArmorBase", "mod.MixinTNTTimerMod$MixinRenderTNTPrimed", - "lwjgl.MixinWindowsDisplay" + "lwjgl.MixinWindowsDisplay", + "lwjgl.MixinLinuxKeyboard", + "lwjgl.MixinLinuxKeycodes" ], "injectors": { "defaultRequire": 1 From 00ab258047aa728b079950fdbc9d21964893ab03 Mon Sep 17 00:00:00 2001 From: TheKodeToad <57493648+TheKodeToad@users.noreply.github.com> Date: Tue, 28 Jun 2022 17:07:32 +0100 Subject: [PATCH 02/77] Improve force-load --- .../java/io/github/solclient/client/Client.java | 2 +- .../java/io/github/solclient/client/MiscInit.java | 13 ++++--------- .../java/io/github/solclient/client/util/Utils.java | 10 ++++++++++ 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/game/src/main/java/io/github/solclient/client/Client.java b/game/src/main/java/io/github/solclient/client/Client.java index 14c0b38e..c18f5de1 100755 --- a/game/src/main/java/io/github/solclient/client/Client.java +++ b/game/src/main/java/io/github/solclient/client/Client.java @@ -105,7 +105,7 @@ public class Client { private Map modsById = new HashMap<>(); @Getter private List huds = new ArrayList(); - private static final Logger LOGGER = LogManager.getLogger(); + public static final Logger LOGGER = LogManager.getLogger(); private final File DATA_FILE = new File(Minecraft.getMinecraft().mcDataDir, "sol_client_mods.json"); private final File LEGACY_DATA_FILE = new File(Minecraft.getMinecraft().mcDataDir, "parrot_client_mods.json" /* This was the old name. */ ); diff --git a/game/src/main/java/io/github/solclient/client/MiscInit.java b/game/src/main/java/io/github/solclient/client/MiscInit.java index 764840b5..4800df18 100644 --- a/game/src/main/java/io/github/solclient/client/MiscInit.java +++ b/game/src/main/java/io/github/solclient/client/MiscInit.java @@ -2,21 +2,16 @@ import java.io.File; +import org.lwjgl.LWJGLUtil; + import io.github.solclient.client.util.Utils; import net.minecraft.client.Minecraft; -import net.minecraft.util.Util; -import net.minecraft.util.Util.EnumOS; public class MiscInit { public static void init() { - if(Util.getOSType() == EnumOS.LINUX) { - try { - Class.forName("org.lwjgl.opengl.LinuxKeycodes"); - } - catch(ClassNotFoundException error) { - error.printStackTrace(); - } + if(LWJGLUtil.getPlatform() == LWJGLUtil.PLATFORM_LINUX) { + Utils.earlyLoad("org.lwjgl.opengl.LinuxKeycodes"); } Utils.resetLineWidth(); diff --git a/game/src/main/java/io/github/solclient/client/util/Utils.java b/game/src/main/java/io/github/solclient/client/util/Utils.java index 5a33a28e..be5f8605 100755 --- a/game/src/main/java/io/github/solclient/client/util/Utils.java +++ b/game/src/main/java/io/github/solclient/client/util/Utils.java @@ -22,6 +22,7 @@ import com.replaymod.replay.ReplayModReplay; import com.replaymod.replay.camera.CameraEntity; +import io.github.solclient.client.Client; import io.github.solclient.client.mod.impl.SolClientMod; import io.github.solclient.client.util.data.Colour; import io.github.solclient.client.util.data.Rectangle; @@ -535,4 +536,13 @@ public void fillBox(AxisAlignedBB box) { GlStateManager.enableCull(); } + public static void earlyLoad(String name) { + try { + Class.forName(name); + } + catch(Exception error) { + Client.LOGGER.error("Could not early load " + name + ". This may cause further issues."); + } + } + } From 2bfdb95e8a524fd537e9c51737833605e181e95c Mon Sep 17 00:00:00 2001 From: TheKodeToad <57493648+TheKodeToad@users.noreply.github.com> Date: Tue, 28 Jun 2022 17:20:27 +0100 Subject: [PATCH 03/77] Cleaner config --- config.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/config.js b/config.js index d79489d2..002abe20 100644 --- a/config.js +++ b/config.js @@ -3,12 +3,14 @@ const Utils = require("./utils"); class Config { - static data = { + static DEFAULT = { maxMemory: 2048, optifine: Utils.getOsName() != "osx", minecraftFolder: "", autoUpdate: true }; + + static data = Config.DEFAULT; static file; static init(base) { @@ -17,13 +19,7 @@ class Config { static load() { if(fs.existsSync(Config.file)) { - Config.data = JSON.parse(fs.readFileSync(Config.file, "UTF-8")); - if(!Config.data.minecraftFolder) { - Config.data.minecraftFolder = ""; - } - if(Config.data.autoUpdate == undefined) { - Config.data.autoUpdate = true; - } + Config.data = {...Config.DEFAULT, ...JSON.parse(fs.readFileSync(Config.file, "UTF-8"))}; } } From 9d9114cdf1a05e5864a765d060d841107800950b Mon Sep 17 00:00:00 2001 From: TheKodeToad <57493648+TheKodeToad@users.noreply.github.com> Date: Tue, 28 Jun 2022 21:16:18 +0100 Subject: [PATCH 04/77] Secure access token storage, proudly written in Atom :atom: --- app.js | 10 +- auth.js | 96 +++++++++++--- config.js | 2 +- launcher.js | 8 +- main.js | 4 + package-lock.json | 331 ++++++++++++++++++++++++++++++++++++++++++++-- package.json | 1 + 7 files changed, 413 insertions(+), 39 deletions(-) diff --git a/app.js b/app.js index 011f731e..79e6434f 100644 --- a/app.js +++ b/app.js @@ -31,7 +31,7 @@ ipcRenderer.on("quitGame", (event) => { ipcRenderer.send("quit", true); }); -window.addEventListener("DOMContentLoaded", () => { +window.addEventListener("DOMContentLoaded", async() => { if(Utils.getOsName() == "osx") { document.querySelector(".drag-region").style.display = "block"; } @@ -112,6 +112,10 @@ window.addEventListener("DOMContentLoaded", () => { } }); + for(var account of launcher.accountManager.accounts) { + await launcher.accountManager.encrypt(account); + } + function updateAccount() { document.querySelector(".account-button").innerHTML = ` ${launcher.accountManager.activeAccount.username} `; } @@ -212,7 +216,7 @@ window.addEventListener("DOMContentLoaded", () => { } }; - ipcRenderer.on("msa", (event, result) => { + ipcRenderer.on("msa", async(event, result) => { loggingIn = false; microsoftLoginButton.innerText = "Microsoft Account"; result = JSON.parse(result); @@ -223,7 +227,7 @@ window.addEventListener("DOMContentLoaded", () => { alert("Could not log in: " + result.type); return; } - var account = microsoftAuthService.authenticate(result.profile); + var account = await microsoftAuthService.authenticate(result.profile); launcher.accountManager.addAccount(account); login.style.display = "none"; main.style.display = "block"; diff --git a/auth.js b/auth.js index ac15de82..3ba2c7e4 100644 --- a/auth.js +++ b/auth.js @@ -1,7 +1,12 @@ const axios = require("axios"); const msmc = require("msmc"); const fs = require("fs"); +const keytar = require("keytar"); +const crypto = require("crypto"); const Utils = require("./utils"); +const KEYCHAIN_PREFIX = "keychain:"; +const SERVICE = "sol_client"; +var manager; class AccountManager { @@ -18,14 +23,62 @@ class AccountManager { } else { this.accounts = []; - this.save(); } + this.save(); this.dataCallback = dataCallback; this.refreshTask = {}; + manager = this; } save() { - fs.writeFileSync(this.file, JSON.stringify({ accounts: this.accounts, activeAccount: this.accounts.indexOf(this.activeAccount) })); + fs.writeFileSync(this.file, JSON.stringify({ + accounts: this.accounts, + activeAccount: this.accounts.indexOf(this.activeAccount) + })); + } + + isEncrypted(prop) { + return prop.startsWith(KEYCHAIN_PREFIX); + } + + async encrypt(account) { + account.accessToken = await this.encryptProp(account.accessToken); + if(account._msmc) { + account._msmc.refresh = await this.encryptProp(account._msmc.refresh); + } + } + + async encryptProp(prop, oldValue) { + if(this.isEncrypted(prop)) { + return prop; + } + var key = crypto.randomBytes(32).toString("hex"); + await keytar.setPassword(SERVICE, key, prop); + var test = await keytar.getPassword(SERVICE, key); + if(test != prop) { + return prop; + } + return KEYCHAIN_PREFIX + key; + } + + async decryptProp(prop) { + if(!this.isEncrypted(prop)) { + return prop; + } + var key = prop.substring(KEYCHAIN_PREFIX.length); + return keytar.getPassword(SERVICE, key); + } + + async realToken(account) { + return this.decryptProp(account.accessToken); + } + + async realRefresh(account) { + if(!account._msmc) { + return null; + } + + return this.decryptProp(account._msmc.refresh); } refreshAccount(account) { @@ -173,34 +226,39 @@ class MicrosoftAuthService extends AuthService { static instance = new MicrosoftAuthService(); - authenticate(msmc) { - return new Account("msa", msmc.name, msmc.id, msmc._msmc.mcToken, null, msmc._msmc.demo, msmc._msmc); + async authenticate(msmc) { + var account = new Account("msa", msmc.name, msmc.id, msmc._msmc.mcToken, null, msmc._msmc.demo, msmc._msmc); + msmc._msmc.mcToken = undefined; + await manager.encrypt(account); + return account; } - toMsmc(account) { + async toMsmc(account) { return { name: account.username, id: account.uuid, - _msmc: account._msmc + _msmc: { ...account._msmc, ...{ refresh: await manager.realRefresh(account), mcToken: await manager.realToken(account) } } } } validate(account) { - return new Promise((resolve) => { - resolve(msmc.validate(this.toMsmc(account))); + return new Promise(async(resolve) => { + resolve(msmc.validate(await this.toMsmc(account))); }); } refresh(account) { return new Promise(async(resolve) => { - var result = await msmc.refresh(this.toMsmc(account), () => {}, {client_id: "00000000402b5328"}); + var startingToken = account.accessToken; + var startingRefresh = account._msmc.refresh; + var result = await msmc.refresh(await this.toMsmc(account), () => {}, {client_id: "00000000402b5328"}); if(result.type != "Success") { resolve(null); return; } - resolve(this.authenticate(result.profile)); + resolve(await this.authenticate(result.profile)); }); } @@ -238,24 +296,24 @@ class YggdrasilAuthService extends AuthService { return; } var data = response.data; - resolve( - new Account( + var account = new Account( "mojang", data.selectedProfile.name, data.selectedProfile.id, data.accessToken, data.clientToken - ) ); + manager.encrypt(account); + resolve(account); }); }); } - validate(account) { - return new Promise((resolve) => { + validate(accessToken) { + return new Promise(async(resolve) => { const url = YggdrasilAuthService.api; axios.post(url + "/validate", { - accessToken: account.accessToken, + accessToken: await manager.realToken(account), clientToken: account.clientToken }) .catch((error) => { @@ -269,9 +327,9 @@ class YggdrasilAuthService extends AuthService { refresh(account) { const url = YggdrasilAuthService.api; - return new Promise((resolve) => { + return new Promise(async(resolve) => { axios.post(url + "/refresh", { - accessToken: account.accessToken, + accessToken: await manager.realToken(account), clientToken: account.clientToken, selectedProfile: { name: account.username, @@ -282,7 +340,7 @@ class YggdrasilAuthService extends AuthService { resolve(false); }) .then((response) => { - account.accessToken = response.data.accessToken; + account.accessToken = manager.encryptProp(response.data.accessToken); resolve(true); }); }); diff --git a/config.js b/config.js index 002abe20..96988615 100644 --- a/config.js +++ b/config.js @@ -19,7 +19,7 @@ class Config { static load() { if(fs.existsSync(Config.file)) { - Config.data = {...Config.DEFAULT, ...JSON.parse(fs.readFileSync(Config.file, "UTF-8"))}; + Config.data = { ...Config.DEFAULT, ...JSON.parse(fs.readFileSync(Config.file, "UTF-8")) }; } } diff --git a/launcher.js b/launcher.js index 170c402a..8f7217dd 100644 --- a/launcher.js +++ b/launcher.js @@ -12,7 +12,7 @@ const Patcher = require("./patcher"); const { ipcRenderer, shell } = require("electron"); const crypto = require("crypto"); const url = require("url"); -const { AccountManager } = require("./auth"); +const { AccountManager } = require("./auth").AccountManager; class Launcher { @@ -191,7 +191,7 @@ class Launcher { fs.mkdirSync(path.dirname(destination), { recursive: true }); } - await entry.pipe(fs.createWriteStream(nativesFolder + "/" + fileName)); + await entry.pipe(fs.createWriteStream(nativesFolder + "/" + fileName)); } } } @@ -371,7 +371,7 @@ class Launcher { await entry.autodrain(); } else { - await entry.pipe(fs.createWriteStream(discordNativeLibrary)); + await entry.pipe(fs.createWriteStream(discordNativeLibrary)); } } progress("Starting..."); @@ -437,7 +437,7 @@ class Launcher { } args.push("--accessToken"); - args.push(activeAccount.accessToken); + args.push(await this.accountManager.realToken(activeAccount)); args.push("--versionType"); args.push("release"); diff --git a/main.js b/main.js index 0540e595..5a43f15c 100644 --- a/main.js +++ b/main.js @@ -51,6 +51,10 @@ async function run() { window.loadFile("app.html"); window.setMenu(null); + if(process.env.DEVTOOLS) { + window.webContents.openDevTools(); + } + window.on("close", (event) => { if(!canQuit) { event.preventDefault(); diff --git a/package-lock.json b/package-lock.json index 60dae114..42fd4046 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "electron-is-dev": "^2.0.0", "electron-squirrel-startup": "^1.0.0", "hastebin": "^0.2.1", + "keytar": "^7.9.0", "msmc": "^3.1.1", "nbt": "^0.8.1", "tar": "^6.1.11", @@ -2896,6 +2897,14 @@ "node": ">=4" } }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/defaults": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", @@ -4351,6 +4360,14 @@ "node": ">=0.8" } }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "engines": { + "node": ">=6" + } + }, "node_modules/expand-tilde": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", @@ -4874,6 +4891,11 @@ "assert-plus": "^1.0.0" } }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" + }, "node_modules/glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", @@ -5353,8 +5375,7 @@ "node_modules/ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "node_modules/inquirer": { "version": "8.1.5", @@ -5724,6 +5745,21 @@ "node": ">=8" } }, + "node_modules/keytar": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz", + "integrity": "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==", + "hasInstallScript": true, + "dependencies": { + "node-addon-api": "^4.3.0", + "prebuild-install": "^7.0.1" + } + }, + "node_modules/keytar/node_modules/node-addon-api": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" + }, "node_modules/keyv": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", @@ -5887,7 +5923,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -6195,6 +6230,11 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -6243,6 +6283,11 @@ "dev": true, "optional": true }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" + }, "node_modules/nbt": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/nbt/-/nbt-0.8.1.tgz", @@ -6267,7 +6312,6 @@ "version": "3.8.0", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.8.0.tgz", "integrity": "sha512-tzua9qWWi7iW4I42vUPKM+SfaF0vQSLAm4yO5J83mSwB7GeoWrDKC/K+8YCnYNwqP5duwazbw2X9l4m8SC2cUw==", - "dev": true, "dependencies": { "semver": "^7.3.5" }, @@ -6279,7 +6323,6 @@ "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -6996,6 +7039,39 @@ "node": ">=4.0" } }, + "node_modules/prebuild-install": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", + "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prebuild-install/node_modules/detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "engines": { + "node": ">=8" + } + }, "node_modules/prepend-http": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", @@ -7166,6 +7242,20 @@ "murmur-32": "^0.1.0 || ^0.2.0" } }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, "node_modules/rcedit": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/rcedit/-/rcedit-3.0.1.tgz", @@ -7647,6 +7737,74 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/simple-get/node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/simple-get/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/single-line-log": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/single-line-log/-/single-line-log-1.1.2.tgz", @@ -7910,6 +8068,14 @@ "node": ">=0.10.0" } }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/strip-outer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", @@ -7977,6 +8143,22 @@ "node": ">= 10" } }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-fs/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, "node_modules/tar-stream": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", @@ -8305,7 +8487,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, "dependencies": { "safe-buffer": "^5.0.1" }, @@ -10977,6 +11158,11 @@ "mimic-response": "^1.0.0" } }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, "defaults": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", @@ -12104,6 +12290,11 @@ "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==" }, + "expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==" + }, "expand-tilde": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", @@ -12537,6 +12728,11 @@ "assert-plus": "^1.0.0" } }, + "github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" + }, "glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", @@ -12901,8 +13097,7 @@ "ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "inquirer": { "version": "8.1.5", @@ -13190,6 +13385,22 @@ "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==", "dev": true }, + "keytar": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz", + "integrity": "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==", + "requires": { + "node-addon-api": "^4.3.0", + "prebuild-install": "^7.0.1" + }, + "dependencies": { + "node-addon-api": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" + } + } + }, "keyv": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", @@ -13331,7 +13542,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "requires": { "yallist": "^4.0.0" } @@ -13559,6 +13769,11 @@ "minimist": "^1.2.5" } }, + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -13598,6 +13813,11 @@ "dev": true, "optional": true }, + "napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" + }, "nbt": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/nbt/-/nbt-0.8.1.tgz", @@ -13619,7 +13839,6 @@ "version": "3.8.0", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.8.0.tgz", "integrity": "sha512-tzua9qWWi7iW4I42vUPKM+SfaF0vQSLAm4yO5J83mSwB7GeoWrDKC/K+8YCnYNwqP5duwazbw2X9l4m8SC2cUw==", - "dev": true, "requires": { "semver": "^7.3.5" }, @@ -13628,7 +13847,6 @@ "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, "requires": { "lru-cache": "^6.0.0" } @@ -14154,6 +14372,32 @@ } } }, + "prebuild-install": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", + "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "requires": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "dependencies": { + "detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==" + } + } + }, "prepend-http": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", @@ -14274,6 +14518,17 @@ "murmur-32": "^0.1.0 || ^0.2.0" } }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, "rcedit": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/rcedit/-/rcedit-3.0.1.tgz", @@ -14655,6 +14910,36 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" + }, + "simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "requires": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + }, + "dependencies": { + "decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "requires": { + "mimic-response": "^3.1.0" + } + }, + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" + } + } + }, "single-line-log": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/single-line-log/-/single-line-log-1.1.2.tgz", @@ -14868,6 +15153,11 @@ "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==" + }, "strip-outer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", @@ -14929,6 +15219,24 @@ } } }, + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + }, + "dependencies": { + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + } + } + }, "tar-stream": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", @@ -15202,7 +15510,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, "requires": { "safe-buffer": "^5.0.1" } diff --git a/package.json b/package.json index 7546d922..b65ce08d 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "electron-is-dev": "^2.0.0", "electron-squirrel-startup": "^1.0.0", "hastebin": "^0.2.1", + "keytar": "^7.9.0", "msmc": "^3.1.1", "nbt": "^0.8.1", "tar": "^6.1.11", From 504c315910b2d83868e54a0ca662880451ef580a Mon Sep 17 00:00:00 2001 From: TheKodeToad <57493648+TheKodeToad@users.noreply.github.com> Date: Tue, 28 Jun 2022 21:23:01 +0100 Subject: [PATCH 05/77] Refactor keychain methods --- auth.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/auth.js b/auth.js index 3ba2c7e4..8467284f 100644 --- a/auth.js +++ b/auth.js @@ -41,14 +41,14 @@ class AccountManager { return prop.startsWith(KEYCHAIN_PREFIX); } - async encrypt(account) { - account.accessToken = await this.encryptProp(account.accessToken); + async storeInKeychain(account) { + account.accessToken = await this.storeProp(account.accessToken); if(account._msmc) { - account._msmc.refresh = await this.encryptProp(account._msmc.refresh); + account._msmc.refresh = await this.storeProp(account._msmc.refresh); } } - async encryptProp(prop, oldValue) { + async storeProp(prop, oldValue) { if(this.isEncrypted(prop)) { return prop; } @@ -61,7 +61,7 @@ class AccountManager { return KEYCHAIN_PREFIX + key; } - async decryptProp(prop) { + async retrieveProp(prop) { if(!this.isEncrypted(prop)) { return prop; } @@ -70,7 +70,7 @@ class AccountManager { } async realToken(account) { - return this.decryptProp(account.accessToken); + return this.retrieveProp(account.accessToken); } async realRefresh(account) { @@ -78,7 +78,7 @@ class AccountManager { return null; } - return this.decryptProp(account._msmc.refresh); + return this.retrieveProp(account._msmc.refresh); } refreshAccount(account) { @@ -229,7 +229,7 @@ class MicrosoftAuthService extends AuthService { async authenticate(msmc) { var account = new Account("msa", msmc.name, msmc.id, msmc._msmc.mcToken, null, msmc._msmc.demo, msmc._msmc); msmc._msmc.mcToken = undefined; - await manager.encrypt(account); + await manager.storeInKeychain(account); return account; } @@ -303,7 +303,7 @@ class YggdrasilAuthService extends AuthService { data.accessToken, data.clientToken ); - manager.encrypt(account); + manager.storeInKeychain(account); resolve(account); }); }); @@ -340,7 +340,7 @@ class YggdrasilAuthService extends AuthService { resolve(false); }) .then((response) => { - account.accessToken = manager.encryptProp(response.data.accessToken); + account.accessToken = manager.storeProp(response.data.accessToken); resolve(true); }); }); From 94fce0e9bb9796eb1189ded4d73170748f17b53e Mon Sep 17 00:00:00 2001 From: TheKodeToad <57493648+TheKodeToad@users.noreply.github.com> Date: Tue, 28 Jun 2022 21:24:45 +0100 Subject: [PATCH 06/77] DIY Refactoring --- app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.js b/app.js index 79e6434f..d09c0211 100644 --- a/app.js +++ b/app.js @@ -113,7 +113,7 @@ window.addEventListener("DOMContentLoaded", async() => { }); for(var account of launcher.accountManager.accounts) { - await launcher.accountManager.encrypt(account); + await launcher.accountManager.storeInKeychain(account); } function updateAccount() { From 425a0c3dd48310ff46aeb5cf816a59269f137c6c Mon Sep 17 00:00:00 2001 From: TheKodeToad <57493648+TheKodeToad@users.noreply.github.com> Date: Tue, 28 Jun 2022 21:50:23 +0100 Subject: [PATCH 07/77] Fix compile error --- .../github/solclient/client/mixin/lwjgl/MixinLinuxKeyboard.java | 2 +- .../github/solclient/client/mixin/lwjgl/MixinLinuxKeycodes.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/game/src/main/java/io/github/solclient/client/mixin/lwjgl/MixinLinuxKeyboard.java b/game/src/main/java/io/github/solclient/client/mixin/lwjgl/MixinLinuxKeyboard.java index 624d5e96..9c7fdc80 100644 --- a/game/src/main/java/io/github/solclient/client/mixin/lwjgl/MixinLinuxKeyboard.java +++ b/game/src/main/java/io/github/solclient/client/mixin/lwjgl/MixinLinuxKeyboard.java @@ -11,7 +11,7 @@ public class MixinLinuxKeyboard { @Shadow private @Final int numlock_mask, modeswitch_mask, caps_lock_mask, shift_lock_mask; - @Overwrite + @Overwrite(remap = false) private int getKeycode(long eventp, int eventState) { /* * Copyright (c) 2002-2008 LWJGL Project All rights reserved. diff --git a/game/src/main/java/io/github/solclient/client/mixin/lwjgl/MixinLinuxKeycodes.java b/game/src/main/java/io/github/solclient/client/mixin/lwjgl/MixinLinuxKeycodes.java index 145d52e5..eaa1afd2 100644 --- a/game/src/main/java/io/github/solclient/client/mixin/lwjgl/MixinLinuxKeycodes.java +++ b/game/src/main/java/io/github/solclient/client/mixin/lwjgl/MixinLinuxKeycodes.java @@ -6,7 +6,7 @@ @Mixin(targets = "org.lwjgl.opengl.LinuxKeycodes") public interface MixinLinuxKeycodes { - @Invoker("mapKeySymToLWJGLKeyCode") + @Invoker(value = "mapKeySymToLWJGLKeyCode", remap = false) static int mapKeySymToLWJGLKeyCode(long keysym) { throw new UnsupportedOperationException(); } From b93508c44fe97731a0365ac9d68b6dd029ba7f9e Mon Sep 17 00:00:00 2001 From: TheKodeToad <57493648+TheKodeToad@users.noreply.github.com> Date: Tue, 28 Jun 2022 22:00:39 +0100 Subject: [PATCH 08/77] Fix force loading crash --- .../io/github/solclient/client/Client.java | 6 ++++- .../io/github/solclient/client/MiscInit.java | 23 ------------------- .../io/github/solclient/client/PreMain.java | 17 ++++++++++++++ .../solclient/client/tweak/Tweaker.java | 2 +- .../github/solclient/client/util/Utils.java | 3 ++- 5 files changed, 25 insertions(+), 26 deletions(-) delete mode 100644 game/src/main/java/io/github/solclient/client/MiscInit.java create mode 100644 game/src/main/java/io/github/solclient/client/PreMain.java diff --git a/game/src/main/java/io/github/solclient/client/Client.java b/game/src/main/java/io/github/solclient/client/Client.java index c18f5de1..4fb60f2b 100755 --- a/game/src/main/java/io/github/solclient/client/Client.java +++ b/game/src/main/java/io/github/solclient/client/Client.java @@ -75,6 +75,7 @@ import io.github.solclient.client.ui.ChatButton; import io.github.solclient.client.ui.screen.mods.ModsScreen; import io.github.solclient.client.ui.screen.mods.MoveHudsScreen; +import io.github.solclient.client.util.Utils; import io.github.solclient.client.util.access.AccessMinecraft; import lombok.Getter; import lombok.Setter; @@ -135,7 +136,10 @@ public class Client { private GuiMainMenu mainMenu; public void init() { - MiscInit.init(); + Utils.resetLineWidth(); + new File(Minecraft.getMinecraft().mcDataDir, "server-resource-packs").mkdirs(); // Fix crash + System.setProperty("http.agent", "Sol Client/" + Client.VERSION); + LOGGER.info("Initialising..."); bus.register(this); diff --git a/game/src/main/java/io/github/solclient/client/MiscInit.java b/game/src/main/java/io/github/solclient/client/MiscInit.java deleted file mode 100644 index 4800df18..00000000 --- a/game/src/main/java/io/github/solclient/client/MiscInit.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.github.solclient.client; - -import java.io.File; - -import org.lwjgl.LWJGLUtil; - -import io.github.solclient.client.util.Utils; -import net.minecraft.client.Minecraft; - -public class MiscInit { - - public static void init() { - if(LWJGLUtil.getPlatform() == LWJGLUtil.PLATFORM_LINUX) { - Utils.earlyLoad("org.lwjgl.opengl.LinuxKeycodes"); - } - - Utils.resetLineWidth(); - new File(Minecraft.getMinecraft().mcDataDir, "server-resource-packs").mkdirs(); // Fix crash - - System.setProperty("http.agent", "Sol Client/" + Client.VERSION); - } - -} diff --git a/game/src/main/java/io/github/solclient/client/PreMain.java b/game/src/main/java/io/github/solclient/client/PreMain.java new file mode 100644 index 00000000..afe1361d --- /dev/null +++ b/game/src/main/java/io/github/solclient/client/PreMain.java @@ -0,0 +1,17 @@ +package io.github.solclient.client; + +import org.lwjgl.LWJGLUtil; + +import io.github.solclient.client.util.Utils; +import net.minecraft.client.main.Main; + +public class PreMain { + + public static void main(String[] args) { + if(LWJGLUtil.getPlatform() == LWJGLUtil.PLATFORM_LINUX) { + Utils.earlyLoad("org.lwjgl.opengl.LinuxKeycodes"); + } + Main.main(args); + } + +} diff --git a/game/src/main/java/io/github/solclient/client/tweak/Tweaker.java b/game/src/main/java/io/github/solclient/client/tweak/Tweaker.java index fe7df2fb..0a9a1372 100755 --- a/game/src/main/java/io/github/solclient/client/tweak/Tweaker.java +++ b/game/src/main/java/io/github/solclient/client/tweak/Tweaker.java @@ -94,7 +94,7 @@ private void getExceptions() { @Override public String getLaunchTarget() { - return "net.minecraft.client.main.Main"; + return "io.github.solclient.client.PreMain"; } @Override diff --git a/game/src/main/java/io/github/solclient/client/util/Utils.java b/game/src/main/java/io/github/solclient/client/util/Utils.java index be5f8605..2062afa5 100755 --- a/game/src/main/java/io/github/solclient/client/util/Utils.java +++ b/game/src/main/java/io/github/solclient/client/util/Utils.java @@ -38,6 +38,7 @@ import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.WorldRenderer; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.launchwrapper.Launch; import net.minecraft.network.EnumConnectionState; import net.minecraft.network.NetworkManager; import net.minecraft.network.handshake.client.C00Handshake; @@ -538,7 +539,7 @@ public void fillBox(AxisAlignedBB box) { public static void earlyLoad(String name) { try { - Class.forName(name); + Class.forName(name, true, Launch.classLoader); } catch(Exception error) { Client.LOGGER.error("Could not early load " + name + ". This may cause further issues."); From 17248056a2a2494e1093b01990c4bc865e0c0601 Mon Sep 17 00:00:00 2001 From: TheKodeToad <57493648+TheKodeToad@users.noreply.github.com> Date: Tue, 28 Jun 2022 22:01:45 +0100 Subject: [PATCH 09/77] Less error and leak prone token storage --- app.js | 8 +++++--- auth.js | 20 ++++++++++++-------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/app.js b/app.js index d09c0211..c7bf16d5 100644 --- a/app.js +++ b/app.js @@ -117,7 +117,9 @@ window.addEventListener("DOMContentLoaded", async() => { } function updateAccount() { - document.querySelector(".account-button").innerHTML = ` ${launcher.accountManager.activeAccount.username} `; + if(launcher.accountManager.activeAccount) { + document.querySelector(".account-button").innerHTML = ` ${launcher.accountManager.activeAccount.username} `; + } } function updateMinecraftFolder() { @@ -164,10 +166,10 @@ window.addEventListener("DOMContentLoaded", async() => { var accountElement = document.createElement("div"); accountElement.classList.add("account"); accountElement.innerHTML = ` ${account.username} `; - accountElement.onclick = (event) => { + accountElement.onclick = async(event) => { if(event.target.classList.contains("remove-account") || event.target.parentElement.classList.contains("remove-account")) { - if(!launcher.accountManager.removeAccount(account)) { + if(!(await launcher.accountManager.removeAccount(account))) { main.style.display = null; login.style.display = "block"; backToMain.style.display = null; diff --git a/auth.js b/auth.js index 8467284f..40bbf1a8 100644 --- a/auth.js +++ b/auth.js @@ -19,7 +19,9 @@ class AccountManager { this.accounts.push(Account.from(account)); } this.activeAccount = this.accounts[data.activeAccount]; - this.fetchSkin(this.activeAccount); + if(this.activeAccount) { + this.fetchSkin(this.activeAccount); + } } else { this.accounts = []; @@ -42,17 +44,16 @@ class AccountManager { } async storeInKeychain(account) { - account.accessToken = await this.storeProp(account.accessToken); + account.accessToken = await this.storeProp(account.accessToken, account.uuid + "_access_token"); if(account._msmc) { - account._msmc.refresh = await this.storeProp(account._msmc.refresh); + account._msmc.refresh = await this.storeProp(account._msmc.refresh, account.uuid + "_refresh"); } } - async storeProp(prop, oldValue) { + async storeProp(prop, key) { if(this.isEncrypted(prop)) { return prop; } - var key = crypto.randomBytes(32).toString("hex"); await keytar.setPassword(SERVICE, key, prop); var test = await keytar.getPassword(SERVICE, key); if(test != prop) { @@ -184,10 +185,13 @@ class AccountManager { this.switchAccount(account); } - removeAccount(account) { + async removeAccount(account) { var index = this.accounts.indexOf(this.activeAccount); this.accounts = this.accounts.filter((item) => item != account); + keytar.deletePassword(SERVICE, KEYCHAIN_PREFIX + account.uuid + "_access_token"); + keytar.deletePassword(SERVICE, KEYCHAIN_PREFIX + account.uuid + "_refresh"); + if(account == this.activeAccount) { this.activeAccount = this.accounts[index]; @@ -339,8 +343,8 @@ class YggdrasilAuthService extends AuthService { .catch((error) => { resolve(false); }) - .then((response) => { - account.accessToken = manager.storeProp(response.data.accessToken); + .then(async(response) => { + account.accessToken = await manager.storeProp(response.data.accessToken, account.uuid + "_access_token"); resolve(true); }); }); From df320776fbe4d5cf08a0ae093a01ad29e725328b Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Fri, 1 Jul 2022 14:54:01 +0100 Subject: [PATCH 10/77] Clean up some old code Duplicated code taken from a Forge mod (only concern is the identical local names; the code is pretty generic). --- .../client/mod/impl/hud/SpeedometerMod.java | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/game/src/main/java/io/github/solclient/client/mod/impl/hud/SpeedometerMod.java b/game/src/main/java/io/github/solclient/client/mod/impl/hud/SpeedometerMod.java index c21847e2..5f4557c9 100755 --- a/game/src/main/java/io/github/solclient/client/mod/impl/hud/SpeedometerMod.java +++ b/game/src/main/java/io/github/solclient/client/mod/impl/hud/SpeedometerMod.java @@ -100,10 +100,9 @@ public void render(Position position, boolean editMode) { } private double getSpeed() { - double distTraveledLastTickX = mc.thePlayer.posX - mc.thePlayer.prevPosX; - double distTraveledLastTickZ = mc.thePlayer.posZ - mc.thePlayer.prevPosZ; - return MathHelper.sqrt_double(distTraveledLastTickX * distTraveledLastTickX - + distTraveledLastTickZ * distTraveledLastTickZ); + double xTraveled = mc.thePlayer.posX - mc.thePlayer.prevPosX; + double zTraveled = mc.thePlayer.posZ - mc.thePlayer.prevPosZ; + return MathHelper.sqrt_double(xTraveled * xTraveled + zTraveled * zTraveled); } @Override @@ -116,11 +115,7 @@ public String getText(boolean editMode) { return "0.00 m/s"; } else { - double distTraveledLastTickX = mc.thePlayer.posX - mc.thePlayer.prevPosX; - double distTraveledLastTickZ = mc.thePlayer.posZ - mc.thePlayer.prevPosZ; - double currentSpeed = MathHelper.sqrt_double(distTraveledLastTickX * distTraveledLastTickX - + distTraveledLastTickZ * distTraveledLastTickZ); - return FORMAT.format(currentSpeed / 0.05F) + " m/s"; + return FORMAT.format(getSpeed() / 0.05F) + " m/s"; } } From 2de4b6c85f8099c9fc0fbd527437f726f55a766e Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 5 Jul 2022 10:29:35 +0100 Subject: [PATCH 11/77] Add Discord contact info --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4870a568..74278a08 100644 --- a/README.md +++ b/README.md @@ -82,9 +82,9 @@ The code for this client is available, meaning that you can see what it does. This client has been tested by multiple people on Hypixel, and it disables disallowed mods automatically. There may be some unknown servers, but just disable the correct mods and you should be fine, as all Sol Client mods are designed to not change the behaviour of the player. ## Credits -[TheKodeToad](https://github.com/TheKodeToad) / [mcblueparrot](https://mine.ly/mcblueparrot.1): Programmer (turning tea into code). +[TheKodeToad](https://github.com/TheKodeToad) ([Discord User](https://discord.com/users/706152404072267788)): Programmer (turning tea into code). -[Holso](https://github.com/Holso) / [Dolfinc](https://mine.ly/Dolfinc.1): Helped create Discord, came up with the name (and changed his own one many times) and tested the client. +[i9Dolphin](https://github.com/i9Dolphin): Helped create Discord, came up with the name (and changed his own one many times) and tested the client. [sp614x](https://github.com/sp614x): OptiFine mod. From c1897e8ab7b6a172e28686bf3c5dd5ec6da77685 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 5 Jul 2022 10:54:54 +0100 Subject: [PATCH 12/77] Add JVM flags --- app.html | 4 ++++ app.js | 7 +++++++ config.js | 32 +++++++++++++++++++++++++++++++- launcher.js | 6 +++++- style.css | 8 +++++++- 5 files changed, 54 insertions(+), 3 deletions(-) diff --git a/app.html b/app.html index 4b689f5c..2bd464dc 100644 --- a/app.html +++ b/app.html @@ -90,6 +90,10 @@

Play Server



+

Advanced

+

JVM Arguments

+ +

diff --git a/app.js b/app.js index c7bf16d5..2f954489 100644 --- a/app.js +++ b/app.js @@ -365,6 +365,13 @@ window.addEventListener("DOMContentLoaded", async() => { Config.save(); }; + var jvmArguments = document.querySelector(".jvm-arguments"); + jvmArguments.value = Config.data.jvmArgs; + jvmArguments.onchange = () => { + Config.data.jvmArgs = jvmArguments.value; + Config.save(); + }; + function updateMemoryLabel() { memoryLabel.innerText = (memory.value / 1024).toFixed(1) + " GB"; Config.data.maxMemory = memory.value; diff --git a/config.js b/config.js index 96988615..9fc3324e 100644 --- a/config.js +++ b/config.js @@ -7,7 +7,8 @@ class Config { maxMemory: 2048, optifine: Utils.getOsName() != "osx", minecraftFolder: "", - autoUpdate: true + autoUpdate: true, + jvmArgs: "" }; static data = Config.DEFAULT; @@ -35,6 +36,35 @@ class Config { return defaultDirectory; } + static getJvmArgs() { + var args = Config.data.jvmArgs; + var result = []; + + var prevC; + var arg = ""; + + for(var c of args) { + if(prevC == "\\") { + arg = arg.substring(0, arg.length - 1); + arg += c; + prevC = 0; + continue; + } + else if(c == " ") { + result.push(arg); + arg = ""; + } + else { + arg += c; + } + prevC = c; + } + + result.push(arg); + + return result; + } + } module.exports = Config; diff --git a/launcher.js b/launcher.js index 8f7217dd..4498f153 100644 --- a/launcher.js +++ b/launcher.js @@ -248,7 +248,7 @@ class Launcher { if(!fs.existsSync(dest)) { - fs.mkdirSync(dest, {recursive: true}); + fs.mkdirSync(dest, { recursive: true }); } if(name.endsWith(".tar.gz")) { @@ -401,6 +401,10 @@ class Launcher { // Fix Log4j encoding. args.push("-Dfile.encoding=UTF-8"); + console.log(Config.getJvmArgs()); + + args.push(...Config.getJvmArgs()); + var classpathSeparator = Utils.getOsName() == "windows" ? ";" : ":"; var classpath = ""; diff --git a/style.css b/style.css index 069307c3..d70976e3 100644 --- a/style.css +++ b/style.css @@ -260,6 +260,12 @@ height: 30px; margin-bottom: 30px; padding: 5px; + background: black; +} + +.settings .input { + padding: 5px; + background: rgb(30, 30, 30); } .label { @@ -643,7 +649,7 @@ input[type="range"]:hover::-webkit-slider-thumb { top: 50px; } -.news * { +.news * { max-width: 600px; } From abc9935220b79b215649c9fcb1416ea7eca81094 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 5 Jul 2022 10:56:43 +0100 Subject: [PATCH 13/77] Remove debugging args log --- launcher.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/launcher.js b/launcher.js index 4498f153..85e30a2f 100644 --- a/launcher.js +++ b/launcher.js @@ -341,6 +341,7 @@ class Launcher { url: "https://dl-game-sdk.discordapp.net/2.5.6/discord_game_sdk.zip", size: 22808634, path: discordPath + break; }); var sdkZip = fs.createReadStream(discordFile) @@ -357,7 +358,6 @@ class Launcher { break; case "osx": suffix = ".dylib"; - break; } var discordLibraryName = "discord_game_sdk" + suffix; @@ -371,6 +371,7 @@ class Launcher { await entry.autodrain(); } else { + } await entry.pipe(fs.createWriteStream(discordNativeLibrary)); } } @@ -389,7 +390,6 @@ class Launcher { if(Utils.getOsName() == "windows") { args.push("-XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump"); - } args.push("-Dio.github.solclient.client.discord_lib=" + discordNativeLibrary); @@ -401,8 +401,7 @@ class Launcher { // Fix Log4j encoding. args.push("-Dfile.encoding=UTF-8"); - console.log(Config.getJvmArgs()); - + // Add custom args. args.push(...Config.getJvmArgs()); var classpathSeparator = Utils.getOsName() == "windows" ? ";" : ":"; From b8dd6bc40788adeb2f81367b14f49506f380f99a Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 5 Jul 2022 14:13:15 +0100 Subject: [PATCH 14/77] What just happened? --- app.html | 6 ++++-- launcher.js | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app.html b/app.html index 2bd464dc..903d820a 100644 --- a/app.html +++ b/app.html @@ -82,8 +82,7 @@

Play Server



- Minecraft Folder -
+

Minecraft Folder


@@ -94,6 +93,9 @@

Advanced

JVM Arguments


+

JRE Location

+ +

diff --git a/launcher.js b/launcher.js index 85e30a2f..0b649f17 100644 --- a/launcher.js +++ b/launcher.js @@ -341,7 +341,6 @@ class Launcher { url: "https://dl-game-sdk.discordapp.net/2.5.6/discord_game_sdk.zip", size: 22808634, path: discordPath - break; }); var sdkZip = fs.createReadStream(discordFile) @@ -358,6 +357,7 @@ class Launcher { break; case "osx": suffix = ".dylib"; + break; } var discordLibraryName = "discord_game_sdk" + suffix; @@ -371,7 +371,6 @@ class Launcher { await entry.autodrain(); } else { - } await entry.pipe(fs.createWriteStream(discordNativeLibrary)); } } @@ -390,6 +389,7 @@ class Launcher { if(Utils.getOsName() == "windows") { args.push("-XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump"); + } args.push("-Dio.github.solclient.client.discord_lib=" + discordNativeLibrary); From bfe56bd79ea2d46cd89c9021cfb520f19f76f643 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 5 Jul 2022 17:18:44 +0100 Subject: [PATCH 15/77] Add JRE folder selection --- app.html | 19 ++++--- app.js | 41 ++++++++++++--- auth.js | 7 +-- config.js | 15 ++++-- launcher.js | 140 +++++++++++++++++++++++++++------------------------- main.js | 27 ++++++---- utils.js | 24 +++++---- 7 files changed, 163 insertions(+), 110 deletions(-) diff --git a/app.html b/app.html index 903d820a..80d4c026 100644 --- a/app.html +++ b/app.html @@ -64,12 +64,12 @@

Play Server