mirror of
https://github.com/smartfrigde/armcord.git
synced 2024-08-14 23:56:58 +00:00
Update arrpc to 3.0.0 (#284)
This commit is contained in:
parent
af1f2f2e1c
commit
e2fc0c6401
11 changed files with 33122 additions and 13 deletions
|
@ -71,6 +71,7 @@ Then just use apps with Discord RPC like normal and they _should_ work!
|
|||
- [ ] Erlpack
|
||||
- [ ] HTTP Server
|
||||
- [x] IPC
|
||||
- [x] Process Scanning
|
||||
|
||||
### Commands
|
||||
|
||||
|
|
|
@ -1,5 +1,16 @@
|
|||
# arRPC Changelog
|
||||
|
||||
## v3.0.0 [26-11-2022]
|
||||
|
||||
- **Added Process Scanning.** Now scans for detectable/verified games and tells Discord the app, allowing process detection whilst maintaining privacy (Discord does not see any/all processes, just the name and app ID).
|
||||
- **Fixed RPC not fully working with more apps/libraries.** Now responds with a mock/fake arRPC user and the proper config, replies with confirmation, and supports blank activites fully.
|
||||
- **Fixed a few minor Bridge bugs.** Fixed catchup not working with several apps.
|
||||
|
||||
## v2.2.1 [24-11-2022]
|
||||
|
||||
- IPC: Fix version given as string not being accepted
|
||||
- IPC: Fix socket closing
|
||||
|
||||
## v2.2.0 [20-11-2022]
|
||||
|
||||
- Server: Move all looking up/fetching to client
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"name": "arrpc",
|
||||
"version": "2.2.0",
|
||||
"version": "3.0.0",
|
||||
"description": "Open Discord RPC server for atypical setups",
|
||||
"main": "src/index.cjs",
|
||||
"main": "src/index.js",
|
||||
"scripts": {
|
||||
"start": "node src"
|
||||
},
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const rgb = (r, g, b, msg) => `\x1b[38;2;${r};${g};${b}m${msg}\x1b[0m`;
|
||||
const log = (...args) => console.log(`[${rgb(88, 101, 242, "arRPC")}]`, ...args);
|
||||
|
||||
log("arRPC v2.2.0 [ArmCord]");
|
||||
log("arRPC v3.0.0 [ArmCord]");
|
||||
|
||||
const {RPCServer} = require("./server.js");
|
||||
const {mainWindow} = require("../../../ts-out/window.js");
|
32937
src/arrpc/src/process/detectable.json
Normal file
32937
src/arrpc/src/process/detectable.json
Normal file
File diff suppressed because it is too large
Load diff
95
src/arrpc/src/process/index.js
Normal file
95
src/arrpc/src/process/index.js
Normal file
|
@ -0,0 +1,95 @@
|
|||
const rgb = (r, g, b, msg) => `\x1b[38;2;${r};${g};${b}m${msg}\x1b[0m`;
|
||||
const log = (...args) => console.log(`[${rgb(88, 101, 242, "arRPC")} > ${rgb(237, 66, 69, "process")}]`, ...args);
|
||||
|
||||
const DetectableDB = require("./detectable.json");
|
||||
|
||||
const Natives = require("./native/index.js");
|
||||
const Native = Natives[process.platform];
|
||||
|
||||
const timestamps = {},
|
||||
names = {},
|
||||
pids = {};
|
||||
class ProcessServer {
|
||||
constructor(handlers) {
|
||||
if (!Native) return log("unsupported platform:", process.platform);
|
||||
|
||||
this.handlers = handlers;
|
||||
|
||||
this.scan = this.scan.bind(this);
|
||||
|
||||
this.scan();
|
||||
setInterval(this.scan, 5000);
|
||||
|
||||
log("started");
|
||||
}
|
||||
|
||||
async scan() {
|
||||
const processes = await Native.getProcesses();
|
||||
const ids = [];
|
||||
|
||||
for (const [pid, _path] of processes) {
|
||||
const path = _path.toLowerCase().replaceAll("\\", "/");
|
||||
const toCompare = [path.split("/").pop(), path.split("/").slice(-2).join("/")];
|
||||
|
||||
for (const p of toCompare.slice()) {
|
||||
// add more possible tweaked paths for less false negatives
|
||||
toCompare.push(p.replace("64", "")); // remove 64bit identifiers-ish
|
||||
toCompare.push(p.replace(".x64", ""));
|
||||
toCompare.push(p.replace("x64", ""));
|
||||
}
|
||||
|
||||
for (const {executables, id, name} of DetectableDB) {
|
||||
if (executables?.some((x) => !x.isLauncher && toCompare.some((y) => x.name === y))) {
|
||||
names[id] = name;
|
||||
pids[id] = pid;
|
||||
|
||||
ids.push(id);
|
||||
if (!timestamps[id]) {
|
||||
log("detected game!", name);
|
||||
timestamps[id] = Date.now();
|
||||
|
||||
this.handlers.message(
|
||||
{
|
||||
socketId: id
|
||||
},
|
||||
{
|
||||
cmd: "SET_ACTIVITY",
|
||||
args: {
|
||||
activity: {
|
||||
application_id: id,
|
||||
name,
|
||||
timestamps: {
|
||||
start: timestamps[id]
|
||||
}
|
||||
},
|
||||
pid
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const id in timestamps) {
|
||||
if (!ids.includes(id)) {
|
||||
log("lost game!", names[id]);
|
||||
delete timestamps[id];
|
||||
|
||||
this.handlers.message(
|
||||
{
|
||||
socketId: id
|
||||
},
|
||||
{
|
||||
cmd: "SET_ACTIVITY",
|
||||
args: {
|
||||
activity: null,
|
||||
pid: pids[id]
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
module.exports = {ProcessServer};
|
2
src/arrpc/src/process/native/index.js
Normal file
2
src/arrpc/src/process/native/index.js
Normal file
|
@ -0,0 +1,2 @@
|
|||
const win32 = require("./win32.js");
|
||||
module.exports = {win32};
|
21
src/arrpc/src/process/native/win32.js
Normal file
21
src/arrpc/src/process/native/win32.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
const {exec} = require("child_process");
|
||||
|
||||
module.exports = {
|
||||
getProcesses: () =>
|
||||
new Promise((res) =>
|
||||
exec(`wmic process get ProcessID,ExecutablePath /format:csv`, (e, out) => {
|
||||
res(
|
||||
out
|
||||
.toString()
|
||||
.split("\r\n")
|
||||
.slice(2)
|
||||
.map((x) => {
|
||||
const parsed = x.trim().split(",").slice(1).reverse();
|
||||
parsed[0] = parseInt(parsed[0]) || parsed[0]; // pid to int
|
||||
return parsed;
|
||||
})
|
||||
.filter((x) => x[1])
|
||||
);
|
||||
})
|
||||
)
|
||||
};
|
|
@ -1,10 +1,8 @@
|
|||
const rgb = (r, g, b, msg) => `\x1b[38;2;${r};${g};${b}m${msg}\x1b[0m`;
|
||||
const log = (...args) => console.log(`[${rgb(88, 101, 242, "arRPC")} > ${rgb(87, 242, 135, "bridge")}]`, ...args);
|
||||
|
||||
const {EventEmitter} = require("events");
|
||||
|
||||
const {IPCServer} = require("./transports/ipc.js");
|
||||
const {WSServer} = require("./transports/websocket.js");
|
||||
const {ProcessServer} = require("./process/index.js");
|
||||
|
||||
let socketId = 0;
|
||||
class RPCServer extends EventEmitter {
|
||||
|
@ -23,6 +21,7 @@ class RPCServer extends EventEmitter {
|
|||
|
||||
this.ipc = await new IPCServer(handlers);
|
||||
this.ws = await new WSServer(handlers);
|
||||
this.process = await new ProcessServer(handlers);
|
||||
|
||||
return this;
|
||||
})();
|
||||
|
@ -34,7 +33,23 @@ class RPCServer extends EventEmitter {
|
|||
evt: "READY",
|
||||
|
||||
data: {
|
||||
v: 1
|
||||
v: 1,
|
||||
|
||||
// needed otherwise some stuff errors out parsing json strictly
|
||||
user: {
|
||||
// mock user data using arRPC app/bot
|
||||
id: "1045800378228281345",
|
||||
username: "arRPC",
|
||||
discriminator: "0000",
|
||||
avatar: "cfefa4d9839fb4bdf030f91c2a13e95c",
|
||||
flags: 0,
|
||||
premium_type: 0
|
||||
},
|
||||
config: {
|
||||
api_endpoint: "//discord.com/api",
|
||||
cdn_host: "cdn.discordapp.com",
|
||||
environment: "production"
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -59,6 +74,14 @@ class RPCServer extends EventEmitter {
|
|||
switch (cmd) {
|
||||
case "SET_ACTIVITY":
|
||||
const {activity, pid} = args; // translate given parameters into what discord dispatch expects
|
||||
|
||||
if (!activity)
|
||||
return this.emit("activity", {
|
||||
activity: null,
|
||||
pid,
|
||||
socketId: socket.socketId.toString()
|
||||
});
|
||||
|
||||
const {buttons, timestamps, instance} = activity;
|
||||
|
||||
socket.lastPid = pid ?? socket.lastPid;
|
||||
|
@ -91,6 +114,13 @@ class RPCServer extends EventEmitter {
|
|||
socketId: socket.socketId.toString()
|
||||
});
|
||||
|
||||
socket.send?.({
|
||||
cmd,
|
||||
data: null,
|
||||
evt: null,
|
||||
nonce
|
||||
});
|
||||
|
||||
break;
|
||||
|
||||
case "GUILD_TEMPLATE_BROWSER":
|
||||
|
@ -104,7 +134,7 @@ class RPCServer extends EventEmitter {
|
|||
nonce
|
||||
});
|
||||
|
||||
this.emit(cmd === "INVITE_BROWSER" ? "invite" : "guild_template", code);
|
||||
this.emit(cmd === "INVITE_BROWSER" ? "invite" : "guild-template", code);
|
||||
break;
|
||||
|
||||
case "DEEP_LINK":
|
||||
|
|
|
@ -4,7 +4,9 @@ const log = (...args) => console.log(`[${rgb(88, 101, 242, "arRPC")} > ${rgb(254
|
|||
const {join} = require("path");
|
||||
const {platform, env} = require("process");
|
||||
const {unlinkSync} = require("fs");
|
||||
|
||||
const {createServer, createConnection} = require("net");
|
||||
|
||||
const SOCKET_PATH =
|
||||
platform === "win32"
|
||||
? "\\\\?\\pipe\\discord-ipc"
|
||||
|
@ -210,10 +212,20 @@ class IPCServer {
|
|||
socket.once("handshake", (params) => {
|
||||
log("handshake:", params);
|
||||
|
||||
const ver = params.v ?? 1;
|
||||
const ver = parseInt(params.v ?? 1);
|
||||
const clientId = params.client_id ?? "";
|
||||
// encoding is always json for ipc
|
||||
|
||||
socket.close = (code = CloseCodes.CLOSE_NORMAL, message = "") => {
|
||||
socket.end(
|
||||
encode(Types.CLOSE, {
|
||||
code,
|
||||
message
|
||||
})
|
||||
);
|
||||
socket.destroy();
|
||||
};
|
||||
|
||||
if (ver !== 1) {
|
||||
log("unsupported version requested", ver);
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ class WSServer {
|
|||
await new Promise((res) => {
|
||||
http = createServer();
|
||||
http.on("error", (e) => {
|
||||
// log('http error', e);
|
||||
// log("http error", e);
|
||||
|
||||
if (e.code === "EADDRINUSE") {
|
||||
log(port, "in use!");
|
||||
|
@ -35,7 +35,7 @@ class WSServer {
|
|||
|
||||
wss = new WebSocketServer({server: http});
|
||||
wss.on("error", (e) => {
|
||||
// log('wss error', e);
|
||||
// log("wss error", e);
|
||||
});
|
||||
|
||||
wss.on("connection", this.onConnection);
|
||||
|
@ -92,8 +92,8 @@ class WSServer {
|
|||
return;
|
||||
}
|
||||
|
||||
/* if (clientId === '') {
|
||||
log('client id required');
|
||||
/* if (clientId === "") {
|
||||
log("client id required");
|
||||
|
||||
socket.close();
|
||||
return;
|
||||
|
|
Loading…
Reference in a new issue