diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 699392e5..fdf9554a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,91 +1,105 @@ name: Build DevBuild on: - push: - branches: - - main - paths: - - .github/workflows/build.yml - - src/** - - browser/** - - scripts/build/** - - package.json - - pnpm-lock.yaml + push: + branches: + - main + paths: + - .github/workflows/build.yml + - src/** + - browser/** + - scripts/build/** + - package.json + - pnpm-lock.yaml env: - FORCE_COLOR: true - GITHUB_TOKEN: ${{ secrets.ETOKEN }} + FORCE_COLOR: true + GITHUB_TOKEN: ${{ secrets.ETOKEN }} jobs: - DetermineRunner: - name: Determine Runner - runs-on: ubuntu-latest - outputs: - runner: ${{ steps.set-runner.outputs.runner }} - steps: - - name: Determine which runner to use - id: set-runner - uses: benjaminmichaelis/get-soonest-available-runner@v1.1.0 - with: - primary-runner: "self-hosted" - fallback-runner: "ubuntu-latest" - min-available-runners: 1 - github-token: ${{ env.GITHUB_TOKEN }} + DetermineRunner: + name: Determine Runner + runs-on: ubuntu-latest + outputs: + runner: ${{ steps.set-runner.outputs.runner }} + steps: + - name: Determine which runner to use + id: set-runner + uses: benjaminmichaelis/get-soonest-available-runner@v1.1.0 + with: + primary-runner: "self-hosted" + fallback-runner: "ubuntu-latest" + min-available-runners: 1 + github-token: ${{ env.GITHUB_TOKEN }} - Build: - name: Build Equicord - needs: DetermineRunner - runs-on: ${{ needs.DetermineRunner.outputs.runner}} + Build: + name: Build Equicord + needs: DetermineRunner + runs-on: ${{ needs.DetermineRunner.outputs.runner}} - steps: - - uses: actions/checkout@v4 + steps: + - uses: actions/checkout@v4 - - uses: pnpm/action-setup@v3 + - uses: pnpm/action-setup@v3 # Install pnpm using packageManager key in package.json - - name: Use Node.js 20 - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: "pnpm" + - name: Use Node.js 20 + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: "pnpm" - - name: Install dependencies - run: pnpm install --frozen-lockfile + - name: Install dependencies + run: pnpm install --frozen-lockfile - - name: Build web - run: pnpm buildWebStandalone + - name: Build web + run: pnpm buildWebStandalone - - name: Build - run: pnpm build --standalone + - name: Build + run: pnpm build --standalone - - name: Generate plugin list - run: pnpm generatePluginJson dist/plugins.json dist/plugin-readmes.json + - name: Generate plugin list + run: pnpm generatePluginJson dist/plugins.json dist/plugin-readmes.json - - name: Generate Equicord plugin list - run: pnpm generateEquicordPluginJson dist/equicordplugins.json + - name: Generate Equicord plugin list + run: pnpm generateEquicordPluginJson dist/equicordplugins.json - - name: Clean up obsolete files - run: | - rm -rf dist/*-unpacked dist/monaco Vencord.user.css vencordDesktopRenderer.css vencordDesktopRenderer.css.map + - name: Collect files to be released + run: | + cd dist + mkdir release - - name: Upload Equicord - if: github.repository == 'Equicord/Equicord' - run: | - gh release upload latest --clobber dist/* + cp browser/browser.* release + cp Vencord.user.{js,js.LEGAL.txt} release - - name: Upload Plugins JSON to Ignore repo - if: github.repository == 'Equicord/Equicord' - run: | - git config --global user.name "$USERNAME" - git config --global user.email "78185467+thororen1234@users.noreply.github.com" + # copy the plugin data jsons, the extension zips and the desktop/vesktop asars + cp *.{json,zip,asar} release - git clone https://$USERNAME:$API_TOKEN@github.com/$GH_REPO.git upload - cd upload + # legacy un-asared files + # FIXME: remove at some point + cp desktop/* release + for file in vesktop/*; do + filename=$(basename "$file") + cp "$file" "release/vencordDesktop${filename^}" + done - rm plugins.json - cp -r ../dist/equicordplugins.json plugins.json + rm release/package.json - git add -A - git commit -m "Plugins for https://github.com/$GITHUB_REPOSITORY/commit/$GITHUB_SHA" - git push --force https://$USERNAME:$API_TOKEN@github.com/$GH_REPO.git - env: - API_TOKEN: ${{ secrets.ETOKEN }} - GH_REPO: Equicord/Equibored - USERNAME: thororen1234 + - name: Upload Equicord + if: github.repository == 'Equicord/Equicord' + run: | + gh release upload latest --clobber dist/* + + - name: Upload Plugins JSON to Ignore repo + if: github.repository == 'Equicord/Equicord' + run: | + git config --global user.name "$USERNAME" + git config --global user.email "78185467+thororen1234@users.noreply.github.com" + git clone https://$USERNAME:$API_TOKEN@github.com/$GH_REPO.git upload + cd upload + rm plugins.json + cp -r ../dist/equicordplugins.json plugins.json + git add -A + git commit -m "Plugins for https://github.com/$GITHUB_REPOSITORY/commit/$GITHUB_SHA" + git push --force https://$USERNAME:$API_TOKEN@github.com/$GH_REPO.git + env: + API_TOKEN: ${{ secrets.ETOKEN }} + GH_REPO: Equicord/Equibored + USERNAME: thororen1234 diff --git a/README.md b/README.md index 70682f39..0012d6fd 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ An enhanced version of [Vencord](https://github.com/Vendicated/Vencord) by [Vend - Request for plugins from Discord.
-Extra included plugins (113 additional plugins) +Extra included plugins (110 additional plugins) - AllCallTimers by MaxHerbold and D3SOX - AltKrispSwitch by newwares @@ -85,7 +85,6 @@ An enhanced version of [Vencord](https://github.com/Vendicated/Vencord) by [Vend - MessageLoggerEnhanced by Aria - MessageTranslate by Samwich - ModalFade by Kyuuhachi -- ModViewBypass by Sqaaakoi - NewPluginsManager by Sqaaakoi - noAppsAllowed by kvba - NoBulletPoints by Samwich @@ -123,10 +122,8 @@ An enhanced version of [Vencord](https://github.com/Vendicated/Vencord) by [Vend - Title by Kyuuhachi - TosuRPC by AutumnVN - Translate+ by Prince527 (Using Translate by Ven) -- TriggerWarning by Joona - UnlimitedAccounts by Balaclava and thororen - UserPFP by nexpid and thororen -- UtilityDock by Samwich - UwUifier by echo - VCSupport by thororen - VencordRPC by AutumnVN diff --git a/package.json b/package.json index 85f9f6d0..95bf722f 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ }, "devDependencies": { "@react-spring/web": "^9.7.3", + "@electron/asar": "^3.2.10", "@types/chrome": "^0.0.246", "@types/diff": "^5.0.3", "@types/lodash": "^4.14.194", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index aff7da90..036abaab 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -59,6 +59,9 @@ importers: specifier: ^1.0.1 version: 1.0.1 devDependencies: + '@electron/asar': + specifier: ^3.2.10 + version: 3.2.10 '@react-spring/web': specifier: ^9.7.3 version: 9.7.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -234,6 +237,11 @@ packages: peerDependencies: postcss-selector-parser: ^6.0.10 + '@electron/asar@3.2.10': + resolution: {integrity: sha512-mvBSwIBUeiRscrCeJE1LwctAriBj65eUDm0Pc11iE5gRwzkmsdbS7FnZ1XUWjpSeQWL1L5g12Fc/SchPM9DUOw==} + engines: {node: '>=10.12.0'} + hasBin: true + '@esbuild-kit/cjs-loader@2.4.2': resolution: {integrity: sha512-BDXFbYOJzT/NBEtp71cvsrGPwGAMGRB/349rwKuoxNSiKjPraNNnlK6MIIabViCjqZugu6j+xeMDlEkWdHHJSg==} @@ -819,6 +827,10 @@ packages: commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + commander@5.1.0: + resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==} + engines: {node: '>= 6'} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -2434,6 +2446,12 @@ snapshots: dependencies: postcss-selector-parser: 6.0.12 + '@electron/asar@3.2.10': + dependencies: + commander: 5.1.0 + glob: 7.2.3 + minimatch: 3.1.2 + '@esbuild-kit/cjs-loader@2.4.2': dependencies: '@esbuild-kit/core-utils': 3.1.0 @@ -3030,6 +3048,8 @@ snapshots: commander@2.20.3: {} + commander@5.1.0: {} + concat-map@0.0.1: {} cosmiconfig@8.1.3: diff --git a/scripts/build/build.mjs b/scripts/build/build.mjs index 0660f155..6f95225c 100755 --- a/scripts/build/build.mjs +++ b/scripts/build/build.mjs @@ -17,8 +17,10 @@ * along with this program. If not, see . */ +import { createPackage } from "@electron/asar"; import esbuild from "esbuild"; -import { readdir } from "fs/promises"; +import { existsSync, readdirSync } from "fs"; +import { readdir, rm, writeFile } from "fs/promises"; import { join } from "path"; import { BUILD_TIMESTAMP, commonOpts, exists, globPlugins, IS_DEV, IS_REPORTER, IS_STANDALONE, IS_UPDATER_DISABLED, resolvePluginName, VERSION, watch } from "./common.mjs"; @@ -107,7 +109,7 @@ await Promise.all([ esbuild.build({ ...nodeCommonOpts, entryPoints: ["src/main/index.ts"], - outfile: "dist/patcher.js", + outfile: "dist/desktop/patcher.js", footer: { js: "//# sourceURL=VencordPatcher\n" + sourceMapFooter("patcher") }, sourcemap, define: { @@ -124,7 +126,7 @@ await Promise.all([ esbuild.build({ ...commonOpts, entryPoints: ["src/Vencord.ts"], - outfile: "dist/renderer.js", + outfile: "dist/desktop/renderer.js", format: "iife", target: ["esnext"], footer: { js: "//# sourceURL=VencordRenderer\n" + sourceMapFooter("renderer") }, @@ -144,7 +146,7 @@ await Promise.all([ esbuild.build({ ...nodeCommonOpts, entryPoints: ["src/preload.ts"], - outfile: "dist/preload.js", + outfile: "dist/desktop/preload.js", footer: { js: "//# sourceURL=VencordPreload\n" + sourceMapFooter("preload") }, sourcemap, define: { @@ -159,8 +161,8 @@ await Promise.all([ esbuild.build({ ...nodeCommonOpts, entryPoints: ["src/main/index.ts"], - outfile: "dist/vencordDesktopMain.js", - footer: { js: "//# sourceURL=VencordDesktopMain\n" + sourceMapFooter("vencordDesktopMain") }, + outfile: "dist/vesktop/main.js", + footer: { js: "//# sourceURL=VencordMain\n" + sourceMapFooter("main") }, sourcemap, define: { ...defines, @@ -176,10 +178,10 @@ await Promise.all([ esbuild.build({ ...commonOpts, entryPoints: ["src/Vencord.ts"], - outfile: "dist/vencordDesktopRenderer.js", + outfile: "dist/vesktop/renderer.js", format: "iife", target: ["esnext"], - footer: { js: "//# sourceURL=VencordDesktopRenderer\n" + sourceMapFooter("vencordDesktopRenderer") }, + footer: { js: "//# sourceURL=VencordRenderer\n" + sourceMapFooter("renderer") }, globalName: "Vencord", sourcemap, plugins: [ @@ -196,8 +198,8 @@ await Promise.all([ esbuild.build({ ...nodeCommonOpts, entryPoints: ["src/preload.ts"], - outfile: "dist/vencordDesktopPreload.js", - footer: { js: "//# sourceURL=VencordPreload\n" + sourceMapFooter("vencordDesktopPreload") }, + outfile: "dist/vesktop/preload.js", + footer: { js: "//# sourceURL=VencordPreload\n" + sourceMapFooter("preload") }, sourcemap, define: { ...defines, @@ -213,3 +215,38 @@ await Promise.all([ if (!commonOpts.watch) process.exitCode = 1; }); + +await Promise.all([ + writeFile("dist/desktop/package.json", JSON.stringify({ + name: "vencord", + main: "patcher.js" + })), + writeFile("dist/vesktop/package.json", JSON.stringify({ + name: "vencord", + main: "main.js" + })) +]); + +await Promise.all([ + createPackage("dist/desktop", "dist/desktop.asar"), + createPackage("dist/vesktop", "dist/vesktop.asar") +]); + +if (existsSync("dist/renderer.js")) { + console.warn("Legacy dist folder. Cleaning up and adding shims."); + + await Promise.all( + readdirSync("dist") + .filter(f => + f.endsWith(".map") || + f.endsWith(".LEGAL.txt") || + ["patcher", "preload", "renderer"].some(name => f.startsWith(name)) + ) + .map(file => rm(join("dist", file))) + ); + + await Promise.all([ + writeFile("dist/patcher.js", 'require("./desktop.asar")'), + writeFile("dist/vencordDesktopMain.js", 'require("./vesktop.asar")') + ]); +} diff --git a/scripts/build/buildWeb.mjs b/scripts/build/buildWeb.mjs index a7f17af6..ec943f8b 100644 --- a/scripts/build/buildWeb.mjs +++ b/scripts/build/buildWeb.mjs @@ -74,26 +74,26 @@ await Promise.all( minify: true, format: "iife", outbase: "node_modules/monaco-editor/esm/", - outdir: "dist/monaco" + outdir: "dist/browser/monaco" }), esbuild.build({ entryPoints: ["browser/monaco.ts"], bundle: true, minify: true, format: "iife", - outfile: "dist/monaco/index.js", + outfile: "dist/browser/monaco/index.js", loader: { ".ttf": "file" } }), esbuild.build({ ...commonOptions, - outfile: "dist/browser.js", + outfile: "dist/browser/browser.js", footer: { js: "//# sourceURL=VencordWeb" } }), esbuild.build({ ...commonOptions, - outfile: "dist/extension.js", + outfile: "dist/browser/extension.js", define: { ...commonOptions?.define, IS_EXTENSION: true, @@ -149,9 +149,9 @@ async function loadDir(dir, basePath = "") { */ async function buildExtension(target, files) { const entries = { - "dist/Vencord.js": await readFile("dist/extension.js"), - "dist/Vencord.css": await readFile("dist/extension.css"), - ...await loadDir("dist/monaco"), + "dist/Vencord.js": await readFile("dist/browser/extension.js"), + "dist/Vencord.css": await readFile("dist/browser/extension.css"), + ...await loadDir("dist/browser/monaco"), ...Object.fromEntries(await Promise.all(RnNoiseFiles.map(async file => [`third-party/rnnoise/${file.replace(/^dist\//, "")}`, await readFile(`node_modules/@sapphi-red/web-noise-suppressor/${file}`)] ))), @@ -172,13 +172,13 @@ async function buildExtension(target, files) { await rm(target, { recursive: true, force: true }); await Promise.all(Object.entries(entries).map(async ([file, content]) => { - const dest = join("dist", target, file); + const dest = join("dist/browser", target, file); const parentDirectory = join(dest, ".."); await mkdir(parentDirectory, { recursive: true }); await writeFile(dest, content); })); - console.info("Unpacked Extension written to dist/" + target); + console.info("Unpacked Extension written to dist/browser/" + target); } const appendCssRuntime = readFile("dist/Vencord.user.css", "utf-8").then(content => { @@ -201,12 +201,14 @@ if (!process.argv.includes("--skip-extension")) { buildExtension("firefox-unpacked", ["background.js", "content.js", "manifestv2.json", "icon.png"]), ]); - Zip.sync.zip("dist/chromium-unpacked").compress().save("dist/extension-chrome.zip"); - console.info("Packed Chromium Extension written to dist/extension-chrome.zip"); - - Zip.sync.zip("dist/firefox-unpacked").compress().save("dist/extension-firefox.zip"); - console.info("Packed Firefox Extension written to dist/extension-firefox.zip"); - + Zip.zip("dist/browser/chromium-unpacked", (_err, zip) => { + zip.compress().save("dist/extension-chrome.zip"); + console.info("Packed Chromium Extension written to dist/extension-chrome.zip"); + }); + Zip.zip("dist/browser/firefox-unpacked", (_err, zip) => { + zip.compress().save("dist/extension-firefox.zip"); + console.info("Packed Firefox Extension written to dist/extension-firefox.zip"); + }); } else { await appendCssRuntime; } diff --git a/scripts/runInstaller.mjs b/scripts/runInstaller.mjs index 5b91c13c..b1771e99 100644 --- a/scripts/runInstaller.mjs +++ b/scripts/runInstaller.mjs @@ -25,8 +25,8 @@ import { Readable } from "stream"; import { finished } from "stream/promises"; import { fileURLToPath } from "url"; -const BASE_URL = "https://github.com/Equicord/Installer/releases/latest/download/"; -const INSTALLER_PATH_DARWIN = "EquicordInstaller.app/Contents/MacOS/EquicordInstaller"; +const BASE_URL = "https://github.com/Equicord/Equilotl/releases/latest/download/"; +const INSTALLER_PATH_DARWIN = "Equilotl.app/Contents/MacOS/Equilotl"; const BASE_DIR = join(dirname(fileURLToPath(import.meta.url)), ".."); const FILE_DIR = join(BASE_DIR, "dist", "Installer"); @@ -35,11 +35,11 @@ const ETAG_FILE = join(FILE_DIR, "etag.txt"); function getFilename() { switch (process.platform) { case "win32": - return "EquicordInstallerCli.exe"; + return "EquilotlCli.exe"; case "darwin": - return "EquicordInstaller.MacOS.zip"; + return "Equilotl.MacOS.zip"; case "linux": - return "EquicordInstallerCli-linux"; + return "EquilotlCli-linux"; default: throw new Error("Unsupported platform: " + process.platform); } @@ -53,7 +53,7 @@ async function ensureBinary() { const downloadName = join(FILE_DIR, filename); const outputFile = process.platform === "darwin" - ? join(FILE_DIR, "EquicordInstaller") + ? join(FILE_DIR, "Equilotl") : downloadName; const etag = existsSync(outputFile) && existsSync(ETAG_FILE) @@ -96,7 +96,7 @@ async function ensureBinary() { execSync(cmd); } catch { } }; - logAndRun(`sudo spctl --add '${outputFile}' --label "Equicord Installer"`); + logAndRun(`sudo spctl --add '${outputFile}' --label "Equilotl"`); logAndRun(`sudo xattr -d com.apple.quarantine '${outputFile}'`); } else { // WHY DOES NODE FETCH RETURN A WEB STREAM OH MY GOD diff --git a/src/equicordplugins/modViewBypass/index.ts b/src/equicordplugins/modViewBypass/index.ts deleted file mode 100644 index d6330508..00000000 --- a/src/equicordplugins/modViewBypass/index.ts +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2024 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { Devs } from "@utils/constants"; -import definePlugin from "@utils/types"; - -export default definePlugin({ - name: "ModViewBypass", - description: "Open the mod view sidebar in guilds you don't have moderator permissions in, or where the experiment is disabled.", - authors: [Devs.Sqaaakoi], - patches: [ - { - find: "canAccessGuildMemberModViewWithExperiment:", - replacement: { - match: /canAccessGuildMemberModViewWithExperiment:function\(\){return\s\i/, - replace: "canAccessGuildMemberModViewWithExperiment:function(){return ()=>true;", - }, - }, - { - find: "useCanAccessGuildMemberModView:", - replacement: { - match: /\i.default.hasAny\(/, - replace: "true; (", - }, - }, - { - find: "isInGuildMemberModViewExperiment:", - replacement: { - match: /isInGuildMemberModViewExperiment:function\(\){return\s\i/, - replace: "isInGuildMemberModViewExperiment:function(){return ()=>true;", - }, - }, - { - find: "useGuildMemberModViewExperiment:", - replacement: { - match: /useGuildMemberModViewExperiment:function\(\){return\s\i/, - replace: "useGuildMemberModViewExperiment:function(){return ()=>true;", - }, - }, - ], -}); diff --git a/src/equicordplugins/noAppsAllowed/index.tsx b/src/equicordplugins/noAppsAllowed/index.tsx index ef4437e4..dbedeab8 100644 --- a/src/equicordplugins/noAppsAllowed/index.tsx +++ b/src/equicordplugins/noAppsAllowed/index.tsx @@ -13,13 +13,6 @@ export default definePlugin({ authors: [EquicordDevs.kvba], patches: [ - { - find: "\"APP_TAG\"", - replacement: { - match: /"APP_TAG":".*?"/, - replace: "\"APP_TAG\":\"BOT\"" - } - }, { find: ",APP_TAG:\"", replacement: { diff --git a/src/equicordplugins/philsPluginLibrary/index.tsx b/src/equicordplugins/philsPluginLibrary/index.tsx index eda80c28..673d2884 100644 --- a/src/equicordplugins/philsPluginLibrary/index.tsx +++ b/src/equicordplugins/philsPluginLibrary/index.tsx @@ -29,7 +29,7 @@ export default definePlugin({ patches: [ { - find: "Messages.ACCOUNT_A11Y_LABEL", + find: "isFullscreenInContext());", replacement: { match: /(?<=function)( \i\i\(\i\)(?={).)(.{0,1000}\i\.\i\.isFullscreenInContext\(\).+?\)]}\))\}/, replace: "$1 return $self.replacedUserPanelComponent(function(){$2}, this, arguments)}" diff --git a/src/equicordplugins/textToSpeech/index.tsx b/src/equicordplugins/textToSpeech/index.tsx index dcba1e1f..26e29c0d 100644 --- a/src/equicordplugins/textToSpeech/index.tsx +++ b/src/equicordplugins/textToSpeech/index.tsx @@ -62,13 +62,12 @@ export default definePlugin({ name: "TextToSpeech", description: "Reads out chat messages with openai tts", authors: [Devs.Samwich], - flux: - { + flux: { async MESSAGE_CREATE({ optimistic, type, message, channelId }) { if (optimistic || type !== "MESSAGE_CREATE") return; if (message.state === "SENDING") return; if (!message.content) return; - if (message.channel_id !== getCurrentChannel().id) return; + if (message.channel_id !== getCurrentChannel()?.id ?? 0) return; readOutText(message.content); } diff --git a/src/equicordplugins/triggerWarning/index.ts b/src/equicordplugins/triggerWarning/index.ts deleted file mode 100644 index 626f7e8c..00000000 --- a/src/equicordplugins/triggerWarning/index.ts +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2024 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { definePluginSettings } from "@api/Settings"; -import { EquicordDevs } from "@utils/constants"; -import definePlugin, { OptionType } from "@utils/types"; - -const settings = definePluginSettings({ - spoilerFilenames: { - description: "Strings in filenames that should be spoilered. Comma separated.", - type: OptionType.STRING, - default: "", - }, - spoilerLinks: { - description: "Strings in link attachments that should be spoilered. Comma separated.", - type: OptionType.STRING, - default: "" - }, - gifSpoilersOnly: { - description: "Should the links only be gifs?", - type: OptionType.BOOLEAN, - default: true - - }, -}); - -export default definePlugin({ - name: "TriggerWarning", - authors: [EquicordDevs.Joona], - description: "Spoiler attachments based on filenames and links.", - patches: [ - { - find: "SimpleMessageAccessories:", - replacement: [ - { - match: /function \i\((\i),\i\){return/, - replace: "$& $self.shouldSpoiler($1.originalItem.filename) || " - }, - { - match: /(\i)=\(0,\i\.getOb.{27,35}\);(?=if\((\i).type)/, - replace: "$&$1=$self.spoilerLink($1,$2.url,$2.type);" - } - ] - } - ], - settings, - shouldSpoiler(filename: string): string | null { - const { spoilerFilenames } = settings.store; - if (!filename || !spoilerFilenames) return null; - const strings = spoilerFilenames.split(",").map(s => s.trim()); - return strings.some(s => filename.includes(s)) ? "spoiler" : null; - }, - spoilerLink(alreadySpoilered: string, link: string, type: string): string | null { - if (alreadySpoilered) return alreadySpoilered; - const { spoilerLinks, gifSpoilersOnly } = settings.store; - if (!link || !spoilerLinks) return null; - - const strings = spoilerLinks.split(",").map(s => s.trim()); - const isLinkSpoiler = strings.some(s => link.includes(s)); - - if (gifSpoilersOnly) { - return type === "gifv" && isLinkSpoiler ? "spoiler" : null; - } else { - return isLinkSpoiler ? "spoiler" : null; - } - } -}); diff --git a/src/equicordplugins/utilityDock/index.tsx b/src/equicordplugins/utilityDock/index.tsx deleted file mode 100644 index a7a3f689..00000000 --- a/src/equicordplugins/utilityDock/index.tsx +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Vencord, a modification for Discord's desktop app - * Copyright (c) 2023 Vendicated and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -import { Settings } from "@api/Settings"; -import ErrorBoundary from "@components/ErrorBoundary"; -import { Devs } from "@utils/constants"; -import definePlugin from "@utils/types"; -import { findExportedComponentLazy } from "@webpack"; -import { Menu, Popout, useState } from "@webpack/common"; -import type { ReactNode } from "react"; - -function toggle(name: string, onClose: () => void) { - Settings.plugins.TextModifiers[name] = !Settings.plugins.TextModifiers[name]; - onClose(); -} -function isEnabled(name: string) { - return Settings.plugins.TextModifiers[name]; -} - - -const HeaderBarIcon = findExportedComponentLazy("Icon", "Divider"); - - -function utilityDockPopout(onClose: () => void) { - - - return ( - - { - Settings.useQuickCss = !Settings.useQuickCss; - onClose(); - }} - /> - VencordNative.quickCss.openEditor()} - /> - - - ); -} - -function utilityDockIcon(isShown: boolean) { - return ( - - - - ); -} - -function VencordPopoutButton() { - const [show, setShow] = useState(false); - - return ( - setShow(false)} - renderPopout={() => utilityDockPopout(() => setShow(false))} - > - {(_, { isShown }) => ( - setShow(v => !v)} - tooltip={isShown ? null : "Utility Dock"} - icon={() => utilityDockIcon(isShown)} - selected={isShown} - /> - )} - - ); -} - -function utilityDock({ children }: { children: ReactNode[]; }) { - children.splice( - children.length - 1, 0, - - - - ); - - return <>{children}; -} - -export default definePlugin({ - name: "UtilityDock", - description: "Adds a button on your titlebar with multiple useful features", - authors: [Devs.Samwich], - - patches: [ - { - find: "toolbar:function", - replacement: { - match: /(?<=toolbar:function.{0,100}\()\i.Fragment,/, - replace: "$self.utilityDock," - } - } - ], - - utilityDock: ErrorBoundary.wrap(utilityDock, { - fallback: () =>

Failed to render :(

- }) -}); - -export function TextPlugin({ pluginName, onClose }) { - return ( - { - Settings.plugins[pluginName].isEnabled = !Settings.plugins[pluginName].isEnabled; - onClose(); - }} - /> - ); -} - diff --git a/src/main/index.ts b/src/main/index.ts index 53907783..cc2eb14e 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -43,11 +43,9 @@ if (IS_VESKTOP || !IS_VANILLA) { } switch (url) { case "renderer.js.map": - case "vencordDesktopRenderer.js.map": case "preload.js.map": - case "vencordDesktopPreload.js.map": case "patcher.js.map": - case "vencordDesktopMain.js.map": + case "main.js.map": cb(join(__dirname, url)); break; default: diff --git a/src/main/ipcMain.ts b/src/main/ipcMain.ts index b7e5f3d2..43fd2099 100644 --- a/src/main/ipcMain.ts +++ b/src/main/ipcMain.ts @@ -119,7 +119,7 @@ ipcMain.handle(IpcEvents.OPEN_MONACO_EDITOR, async () => { autoHideMenuBar: true, darkTheme: true, webPreferences: { - preload: join(__dirname, IS_DISCORD_DESKTOP ? "preload.js" : "vencordDesktopPreload.js"), + preload: join(__dirname, "preload.js"), contextIsolation: true, nodeIntegration: false, sandbox: false diff --git a/src/main/patcher.ts b/src/main/patcher.ts index aeee1ac3..aa346c5c 100644 --- a/src/main/patcher.ts +++ b/src/main/patcher.ts @@ -26,14 +26,18 @@ import { IS_VANILLA } from "./utils/constants"; console.log("[Equicord] Starting up..."); +// FIXME: remove at some point +const isLegacyNonAsarVencord = IS_STANDALONE && !__dirname.endsWith(".asar"); +if (isLegacyNonAsarVencord) { + console.warn("This is a legacy non asar install! Migrating to asar and restarting..."); + require("./updater/http").migrateLegacyToAsar(); +} + // Our injector file at app/index.js const injectorPath = require.main!.filename; -// special discord_arch_electron injection method -const asarName = require.main!.path.endsWith("app.asar") ? "_app.asar" : "app.asar"; - // The original app.asar -const asarPath = join(dirname(injectorPath), "..", asarName); +const asarPath = join(dirname(injectorPath), "..", "_app.asar"); const discordPkg = require(join(asarPath, "package.json")); require.main!.filename = join(asarPath, discordPkg.main); @@ -41,7 +45,7 @@ require.main!.filename = join(asarPath, discordPkg.main); // @ts-ignore Untyped method? Dies from cringe app.setAppPath(asarPath); -if (!IS_VANILLA) { +if (!IS_VANILLA && !isLegacyNonAsarVencord) { const settings = RendererSettings.store; // Repatch after host updates on Windows if (process.platform === "win32") { @@ -71,7 +75,7 @@ if (!IS_VANILLA) { constructor(options: BrowserWindowConstructorOptions) { if (options?.webPreferences?.preload && options.title) { const original = options.webPreferences.preload; - options.webPreferences.preload = join(__dirname, IS_DISCORD_DESKTOP ? "preload.js" : "vencordDesktopPreload.js"); + options.webPreferences.preload = join(__dirname, "preload.js"); options.webPreferences.sandbox = false; // work around discord unloading when in background options.webPreferences.backgroundThrottling = false; @@ -157,5 +161,7 @@ if (!IS_VANILLA) { console.log("[Equicord] Running in vanilla mode. Not loading Equicord"); } -console.log("[Equicord] Loading original Discord app.asar"); -require(require.main!.filename); +if (!isLegacyNonAsarVencord) { + console.log("[Equicord] Loading original Discord app.asar"); + require(require.main!.filename); +} diff --git a/src/main/updater/common.ts b/src/main/updater/common.ts index 41b9837c..5cf9abc1 100644 --- a/src/main/updater/common.ts +++ b/src/main/updater/common.ts @@ -16,12 +16,9 @@ * along with this program. If not, see . */ -export const VENCORD_FILES = [ - IS_DISCORD_DESKTOP ? "patcher.js" : "vencordDesktopMain.js", - IS_DISCORD_DESKTOP ? "preload.js" : "vencordDesktopPreload.js", - IS_DISCORD_DESKTOP ? "renderer.js" : "vencordDesktopRenderer.js", - IS_DISCORD_DESKTOP ? "renderer.css" : "vencordDesktopRenderer.css", -]; +export const ASAR_FILE = IS_VESKTOP + ? "vesktop.asar" + : "desktop.asar"; export function serializeErrors(func: (...args: any[]) => any) { return async function () { diff --git a/src/main/updater/http.ts b/src/main/updater/http.ts index 5fcb4702..bd70b51d 100644 --- a/src/main/updater/http.ts +++ b/src/main/updater/http.ts @@ -18,25 +18,21 @@ import { IpcEvents } from "@shared/IpcEvents"; import { VENCORD_USER_AGENT } from "@shared/vencordUserAgent"; -import axios from "axios"; -import { ipcMain } from "electron"; -import { writeFile } from "fs/promises"; +import { app, dialog, ipcMain } from "electron"; +import { writeFileSync as originalWriteFileSync } from "original-fs"; import { join } from "path"; import gitHash from "~git-hash"; import gitRemote from "~git-remote"; -import { serializeErrors, VENCORD_FILES } from "./common"; - +import { get } from "../utils/simpleGet"; +import { ASAR_FILE, serializeErrors } from "./common"; const API_BASE = `https://api.github.com/repos/${gitRemote}`; -let PendingUpdates = [] as [string, string][]; +let PendingUpdate: string | null = null; async function githubGet(endpoint: string) { - return axios({ - method: "get", - responseType: "json", - url: API_BASE + endpoint, + return get(API_BASE + endpoint, { headers: { Accept: "application/vnd.github+json", // "All API requests MUST include a valid User-Agent header. @@ -52,7 +48,8 @@ async function calculateGitChanges() { const res = await githubGet(`/compare/${gitHash}...HEAD`); - return res.data.commits.map((c: any) => ({ + const data = JSON.parse(res.toString("utf-8")); + return data.commits.map((c: any) => ({ // github api only sends the long sha hash: c.sha.slice(0, 7), author: c.author.login, @@ -63,32 +60,26 @@ async function calculateGitChanges() { async function fetchUpdates() { const release = await githubGet("/releases/latest"); - const hash = release.data.name.slice(release.data.name.lastIndexOf(" ") + 1); + const data = JSON.parse(release.toString()); + const hash = data.name.slice(data.name.lastIndexOf(" ") + 1); if (hash === gitHash) return false; - release.data.assets.forEach(({ name, browser_download_url }) => { - if (VENCORD_FILES.some(s => name.startsWith(s))) { - PendingUpdates.push([name, browser_download_url]); - } - }); + + const asset = data.assets.find(a => a.name === ASAR_FILE); + PendingUpdate = asset.browser_download_url; + return true; } async function applyUpdates() { - await Promise.all(PendingUpdates.map( - async ([name, data]) => { - writeFile( - join(__dirname, name), - (await axios({ - method: "get", - responseType: "arraybuffer", - url: data, - })).data - ); - } - )); - PendingUpdates = []; + if (!PendingUpdate) return true; + + const data = await get(PendingUpdate); + originalWriteFileSync(__dirname, data); + + PendingUpdate = null; + return true; } @@ -96,3 +87,28 @@ ipcMain.handle(IpcEvents.GET_REPO, serializeErrors(() => `https://github.com/${g ipcMain.handle(IpcEvents.GET_UPDATES, serializeErrors(calculateGitChanges)); ipcMain.handle(IpcEvents.UPDATE, serializeErrors(fetchUpdates)); ipcMain.handle(IpcEvents.BUILD, serializeErrors(applyUpdates)); + +export async function migrateLegacyToAsar() { + try { + const isFlatpak = process.platform === "linux" && !!process.env.FLATPAK_ID; + if (isFlatpak) throw "Flatpak Discord can't automatically be migrated."; + + const data = await get(`https://github.com/${gitRemote}/releases/latest/download/desktop.asar`); + + originalWriteFileSync(join(__dirname, "../vencord.asar"), data); + originalWriteFileSync(__filename, '// Legacy shim for new asar\n\nrequire("../vencord.asar");'); + + app.relaunch(); + app.exit(); + } catch (e) { + console.error("Failed to migrate to asar", e); + + app.whenReady().then(() => { + dialog.showErrorBox( + "Legacy Install", + "The way Vencord loaded was changed and the updater failed to migrate. Please reinstall using the Vencord Installer!" + ); + app.exit(1); + }); + } +} diff --git a/src/main/utils/extensions.ts b/src/main/utils/extensions.ts index f1e49f1f..4a354657 100644 --- a/src/main/utils/extensions.ts +++ b/src/main/utils/extensions.ts @@ -16,7 +16,6 @@ * along with this program. If not, see . */ -import axios from "axios"; import { session } from "electron"; import { unzip } from "fflate"; import { constants as fsConstants } from "fs"; @@ -25,6 +24,7 @@ import { join } from "path"; import { DATA_DIR } from "./constants"; import { crxToZip } from "./crxToZip"; +import { get } from "./simpleGet"; const extensionCacheDir = join(DATA_DIR, "ExtensionCache"); @@ -73,15 +73,12 @@ export async function installExt(id: string) { // Unfortunately, Google does not serve old versions, so this is the only way ? "https://raw.githubusercontent.com/Vendicated/random-files/f6f550e4c58ac5f2012095a130406c2ab25b984d/fmkadmapgofadopljbjfkapdkoienihi.zip" : `https://clients2.google.com/service/update2/crx?response=redirect&acceptformat=crx2,crx3&x=id%3D${id}%26uc&prodversion=32`; - const response = await axios({ - method: "get", - responseType: "blob", - url: url, + const buf = await get(url, { headers: { - "User-Agent": "Vencord (https://github.com/Vendicated/Vencord)" + "User-Agent": "Equicord (https://github.com/Equicord/Equicord)" } }); - await extract(crxToZip(Buffer.from(response.data, "binary")), extDir).catch(console.error); + await extract(crxToZip(buf), extDir).catch(console.error); } session.defaultSession.loadExtension(extDir); diff --git a/src/preload.ts b/src/preload.ts index 69f3dc30..7c61a181 100644 --- a/src/preload.ts +++ b/src/preload.ts @@ -28,13 +28,7 @@ contextBridge.exposeInMainWorld("VencordNative", VencordNative); // Discord if (location.protocol !== "data:") { // #region cssInsert - let rendererPath; - if (IS_VESKTOP || IS_EQUIBOP) { - rendererPath = "vencordDesktopRenderer.css"; - } else { - rendererPath = "renderer.css"; - } - const rendererCss = join(__dirname, rendererPath); + const rendererCss = join(__dirname, "renderer.css"); const style = document.createElement("style"); style.id = "vencord-css-core";