From 613ea3f7b4b29cddea99ef372ac3894bed7c1c0d Mon Sep 17 00:00:00 2001 From: smartfrigde <37928912+smartfrigde@users.noreply.github.com> Date: Sun, 28 Jan 2024 15:10:45 +0100 Subject: [PATCH] fix arRPC --- src/arrpc/src/process/native/linux.js | 22 +++-- src/arrpc/src/server.js | 29 ++++-- src/content/js/rpc.js | 127 ++++++++++++++++---------- src/preload/patch.ts | 22 ----- src/preload/preload.ts | 1 - 5 files changed, 110 insertions(+), 91 deletions(-) delete mode 100644 src/preload/patch.ts diff --git a/src/arrpc/src/process/native/linux.js b/src/arrpc/src/process/native/linux.js index 6e1f854..c4ec405 100644 --- a/src/arrpc/src/process/native/linux.js +++ b/src/arrpc/src/process/native/linux.js @@ -1,16 +1,18 @@ -const {readlink, readdir} = require("fs/promises"); +const {readFile, readdir} = require("fs/promises"); -const getProcesses = async () => { - const pids = (await readdir("/proc")).filter((f) => !isNaN(+f)); - return ( +const getProcesses = async () => + ( await Promise.all( - pids.map((pid) => - readlink(`/proc/${pid}/exe`).then( - (path) => [+pid, path], - () => {} - ) + ( + await readdir("/proc") + ).map( + (pid) => + +pid > 0 && + readFile(`/proc/${pid}/cmdline`, "utf8").then( + (path) => [+pid, path.replaceAll("0", "")], + () => 0 + ) ) ) ).filter((x) => x); -}; module.exports = {getProcesses}; diff --git a/src/arrpc/src/server.js b/src/arrpc/src/server.js index 66694c5..59ad41a 100644 --- a/src/arrpc/src/server.js +++ b/src/arrpc/src/server.js @@ -23,7 +23,9 @@ class RPCServer extends EventEmitter { this.ipc = await new IPCServer(handlers); this.ws = await new WSServer(handlers); - this.process = await new ProcessServer(handlers); + + if (!process.argv.includes("--no-process-scanning") && !process.env.ARRPC_NO_PROCESS_SCANNING) + this.process = await new ProcessServer(handlers); return this; })(); @@ -33,6 +35,7 @@ class RPCServer extends EventEmitter { socket.send({ cmd: "DISPATCH", evt: "READY", + nonce: 0, data: { v: 1, @@ -137,15 +140,23 @@ class RPCServer extends EventEmitter { case "GUILD_TEMPLATE_BROWSER": case "INVITE_BROWSER": const {code} = args; - socket.send({ - cmd, - data: { - code - }, - nonce - }); - this.emit(cmd === "INVITE_BROWSER" ? "invite" : "guild-template", code); + const isInvite = cmd === "INVITE_BROWSER"; + const callback = (isValid = true) => { + socket.send({ + cmd, + data: isValid + ? {code} + : { + code: isInvite ? 4011 : 4017, + message: `Invalid ${isInvite ? "invite" : "guild template"} id: ${code}` + }, + evt: isValid ? null : "ERROR", + nonce + }); + }; + + this.emit(isInvite ? "invite" : "guild-template", code, callback); break; case "DEEP_LINK": diff --git a/src/content/js/rpc.js b/src/content/js/rpc.js index 78a1872..c447689 100644 --- a/src/content/js/rpc.js +++ b/src/content/js/rpc.js @@ -1,62 +1,91 @@ -{ - const cb = () => { - let Dispatcher, - lookupAsset, - lookupApp, - apps = {}; +(() => { + let Dispatcher, + lookupAsset, + lookupApp, + apps = {}; - ArmCordRPC.listen(async (msg) => { - console.warn(msg); - if (!Dispatcher) { - let wpRequire; - window.webpackChunkdiscord_app.push([[Symbol()], {}, (x) => (wpRequire = x)]); - window.webpackChunkdiscord_app.pop(); + ArmCordRPC.listen(async (msg) => { + if (!Dispatcher) { + let wpRequire; + window.webpackChunkdiscord_app.push([[Symbol()], {}, (x) => (wpRequire = x)]); + window.webpackChunkdiscord_app.pop(); - const modules = wpRequire.c; - lookupAsset = Object.values(modules).find((m) => m.exports?.fetchAssetIds).exports.fetchAssetIds; - lookupApp = Object.values(modules).find((m) => m.exports?.fetchApplicationsRPC).exports - .fetchApplicationsRPC; + const modules = wpRequire.c; - for (const id in modules) { - const mod = modules[id].exports; - if (!mod?.__esModule) continue; + for (const id in modules) { + const mod = modules[id].exports; + if (!mod?.__esModule) continue; - for (const prop in mod) { - if (!mod.hasOwnProperty(prop)) continue; + for (const prop in mod) { + if (!mod.hasOwnProperty(prop)) continue; - const candidate = mod[prop]; - if (candidate && candidate.register && candidate.wait) { - Dispatcher = candidate; - break; - } + const candidate = mod[prop]; + if (candidate && candidate.register && candidate.wait) { + Dispatcher = candidate; + break; } - - if (Dispatcher) break; } + + if (Dispatcher) break; } - if (msg.activity?.assets?.large_image) - msg.activity.assets.large_image = await lookupAsset( - msg.activity.application_id, - msg.activity.assets.large_image - ); - if (msg.activity?.assets?.small_image) - msg.activity.assets.small_image = await lookupAsset( - msg.activity.application_id, - msg.activity.assets.small_image - ); + const factories = wpRequire.m; + for (const id in factories) { + if (factories[id].toString().includes("getAssetImage: size must === [number, number] for Twitch")) { + const mod = wpRequire(id); - if (msg.activity) { - const appId = msg.activity.application_id; - if (!apps[appId]) apps[appId] = await lookupApp(appId); + // fetchAssetIds + const _lookupAsset = Object.values(mod).find( + (e) => typeof e === "function" && e.toString().includes("APPLICATION_ASSETS_FETCH_SUCCESS") + ); + if (_lookupAsset) + lookupAsset = async (appId, name) => (await _lookupAsset(appId, [name, undefined]))[0]; + } - const app = apps[appId]; - if (!msg.activity.name) msg.activity.name = app.name; + if (lookupAsset) break; } - Dispatcher.dispatch({type: "LOCAL_ACTIVITY_UPDATE", ...msg}); // set RPC status - }); - }; - cb(); - setInterval(cb, 30 * 1000); -} + for (const id in factories) { + if (factories[id].toString().includes("APPLICATION_RPC(")) { + const mod = wpRequire(id); + + // fetchApplicationsRPC + const _lookupApp = Object.values(mod).find((e) => { + if (typeof e !== "function") return; + const str = e.toString(); + return str.includes(",coverImage:") && str.includes("INVALID_ORIGIN"); + }); + if (_lookupApp) + lookupApp = async (appId) => { + let socket = {}; + await _lookupApp(socket, appId); + return socket.application; + }; + } + + if (lookupApp) break; + } + } + + if (msg.activity?.assets?.large_image) + msg.activity.assets.large_image = await lookupAsset( + msg.activity.application_id, + msg.activity.assets.large_image + ); + if (msg.activity?.assets?.small_image) + msg.activity.assets.small_image = await lookupAsset( + msg.activity.application_id, + msg.activity.assets.small_image + ); + + if (msg.activity) { + const appId = msg.activity.application_id; + if (!apps[appId]) apps[appId] = await lookupApp(appId); + + const app = apps[appId]; + if (!msg.activity.name) msg.activity.name = app.name; + } + + Dispatcher.dispatch({type: "LOCAL_ACTIVITY_UPDATE", ...msg}); // set RPC status + }); +})(); diff --git a/src/preload/patch.ts b/src/preload/patch.ts deleted file mode 100644 index da51a5e..0000000 --- a/src/preload/patch.ts +++ /dev/null @@ -1,22 +0,0 @@ -// What does this do? -// In case of faulty update of ArmCord we can quickly push an update to the user and possibly try to fix it -// This is completely optional and is disabled by default in settings -import {ipcRenderer} from "electron"; -import {injectJS} from "../utils"; - -const patchEndpoint = "https://patch.armcord.app"; -const version = ipcRenderer.sendSync("get-app-version", "app-version"); -if (ipcRenderer.sendSync("shouldPatch")) { - document.addEventListener("DOMContentLoaded", function () { - fetch(`${patchEndpoint}/${version}/info.json`, {cache: "no-store"}) //lmao - .then((res) => res.json()) - .then((res) => { - if (res.patch == true) { - console.log("Found a patch. Injecting..."); - injectJS(`${patchEndpoint}/${version}/patch.js`); - } else { - console.log("No patches have been found."); - } - }); - }); -} diff --git a/src/preload/preload.ts b/src/preload/preload.ts index c44e3d6..e27a747 100644 --- a/src/preload/preload.ts +++ b/src/preload/preload.ts @@ -1,5 +1,4 @@ import "./bridge"; -import "./patch"; import "./optimizer"; import "./settings"; import {ipcRenderer} from "electron";