diff --git a/scripts/patcher/common.js b/scripts/patcher/common.js index 5ccd0e81..05523e5a 100644 --- a/scripts/patcher/common.js +++ b/scripts/patcher/common.js @@ -21,6 +21,20 @@ const readline = require("readline"); const fs = require("fs"); const menu = require("console-menu"); +function pathToBranch(dir) { + dir = dir.toLowerCase(); + if (dir.endsWith("development")) { + return "development"; + } + if (dir.endsWith("canary")) { + return "canary"; + } + if (dir.endsWith("ptb")) { + return "ptb"; + } + return "stable"; +} + const BRANCH_NAMES = [ "Discord", "DiscordPTB", @@ -329,6 +343,7 @@ function getLinuxDirs() { } module.exports = { + pathToBranch, BRANCH_NAMES, MACOS_DISCORD_DIRS, LINUX_DISCORD_DIRS, diff --git a/scripts/patcher/install.js b/scripts/patcher/install.js index 852f3a20..3d744a67 100755 --- a/scripts/patcher/install.js +++ b/scripts/patcher/install.js @@ -39,7 +39,8 @@ const { getDarwinDirs, getLinuxDirs, ENTRYPOINT, - question + question, + pathToBranch } = require("./common"); switch (process.platform) { @@ -104,19 +105,84 @@ async function install(installations) { } } + const useNewMethod = pathToBranch(selected.branch) !== "stable"; + for (const version of selected.versions) { - const dir = version.path; + + const dir = useNewMethod ? path.join(version.path, "..") : version.path; + // Check if we have write perms to the install directory... try { fs.accessSync(selected.location, fs.constants.W_OK); } catch (e) { console.error("No write access to", selected.location); console.error( - "Try running this script as an administrator:", + "Make sure Discord isn't running. If that doesn't work,", + "try running this script as an administrator:", "sudo pnpm inject" ); process.exit(1); } + if (useNewMethod) { + const appAsar = path.join(dir, "app.asar"); + const _appAsar = path.join(dir, "_app.asar"); + + if (fs.existsSync(_appAsar) && fs.existsSync(appAsar)) { + console.log("This copy of Discord already seems to be patched..."); + console.log("Try running `pnpm uninject` first."); + process.exit(1); + } + + try { + fs.renameSync(appAsar, _appAsar); + } catch (err) { + if (err.code === "EBUSY") { + console.error(selected.branch, "is still running. Make sure you fully close it before running this script."); + process.exit(1); + } + console.error("Failed to rename app.asar to _app.asar"); + throw err; + } + + try { + fs.mkdirSync(appAsar); + } catch (err) { + if (err.code === "EBUSY") { + console.error(selected.branch, "is still running. Make sure you fully close it before running this script."); + process.exit(1); + } + console.error("Failed to create app.asar folder"); + throw err; + } + + fs.writeFileSync( + path.join(appAsar, "index.js"), + `require("${ENTRYPOINT}");` + ); + fs.writeFileSync( + path.join(appAsar, "package.json"), + JSON.stringify({ + name: "discord", + main: "index.js", + }) + ); + + const requiredFiles = ["index.js", "package.json"]; + + if (requiredFiles.every(f => fs.existsSync(path.join(appAsar, f)))) { + console.log( + "Successfully patched", + version.name + ? `${selected.branch} ${version.name}` + : selected.branch + ); + } else { + console.log("Failed to patch", dir); + console.log("Files in directory:", fs.readdirSync(appAsar)); + } + + return; + } if (fs.existsSync(dir) && fs.lstatSync(dir).isDirectory()) { fs.rmSync(dir, { recursive: true }); } diff --git a/scripts/patcher/uninstall.js b/scripts/patcher/uninstall.js index e9764a75..ded6cf9c 100755 --- a/scripts/patcher/uninstall.js +++ b/scripts/patcher/uninstall.js @@ -32,6 +32,7 @@ const { getWindowsDirs, getDarwinDirs, getLinuxDirs, + pathToBranch, } = require("./common"); switch (process.platform) { @@ -52,19 +53,56 @@ switch (process.platform) { async function uninstall(installations) { const selected = await getMenuItem(installations); + const useNewMethod = pathToBranch(selected.branch) !== "stable"; + for (const version of selected.versions) { - const dir = version.path; + const dir = useNewMethod ? path.join(version.path, "..") : version.path; + // Check if we have write perms to the install directory... try { fs.accessSync(selected.location, fs.constants.W_OK); } catch (e) { console.error("No write access to", selected.location); console.error( - "Try running this script as an administrator:", + "Make sure Discord isn't running. If that doesn't work,", + "try running this script as an administrator:", "sudo pnpm uninject" ); process.exit(1); } + if (useNewMethod) { + if (!fs.existsSync(path.join(dir, "_app.asar"))) { + console.error( + "Original app.asar (_app.asar) doesn't exist.", + "Is your Discord installation corrupt? Try reinstalling Discord." + ); + process.exit(1); + } + if (fs.existsSync(path.join(dir, "app.asar"))) { + try { + fs.rmSync(path.join(dir, "app.asar"), { force: true, recursive: true }); + } catch (err) { + console.error("Failed to delete app.asar folder"); + throw err; + } + } + try { + fs.renameSync( + path.join(dir, "_app.asar"), + path.join(dir, "app.asar") + ); + } catch (err) { + console.error("Failed to rename _app.asar to app.asar"); + throw err; + } + console.log( + "Successfully unpatched", + version.name + ? `${selected.branch} ${version.name}` + : selected.branch + ); + return; + } if (fs.existsSync(dir)) { fs.rmSync(dir, { recursive: true }); }