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
|
- [ ] Erlpack
|
||||||
- [ ] HTTP Server
|
- [ ] HTTP Server
|
||||||
- [x] IPC
|
- [x] IPC
|
||||||
|
- [x] Process Scanning
|
||||||
|
|
||||||
### Commands
|
### Commands
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,16 @@
|
||||||
# arRPC Changelog
|
# 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]
|
## v2.2.0 [20-11-2022]
|
||||||
|
|
||||||
- Server: Move all looking up/fetching to client
|
- Server: Move all looking up/fetching to client
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
{
|
{
|
||||||
"name": "arrpc",
|
"name": "arrpc",
|
||||||
"version": "2.2.0",
|
"version": "3.0.0",
|
||||||
"description": "Open Discord RPC server for atypical setups",
|
"description": "Open Discord RPC server for atypical setups",
|
||||||
"main": "src/index.cjs",
|
"main": "src/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node src"
|
"start": "node src"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const rgb = (r, g, b, msg) => `\x1b[38;2;${r};${g};${b}m${msg}\x1b[0m`;
|
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);
|
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 {RPCServer} = require("./server.js");
|
||||||
const {mainWindow} = require("../../../ts-out/window.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 {EventEmitter} = require("events");
|
||||||
|
|
||||||
const {IPCServer} = require("./transports/ipc.js");
|
const {IPCServer} = require("./transports/ipc.js");
|
||||||
const {WSServer} = require("./transports/websocket.js");
|
const {WSServer} = require("./transports/websocket.js");
|
||||||
|
const {ProcessServer} = require("./process/index.js");
|
||||||
|
|
||||||
let socketId = 0;
|
let socketId = 0;
|
||||||
class RPCServer extends EventEmitter {
|
class RPCServer extends EventEmitter {
|
||||||
|
@ -23,6 +21,7 @@ class RPCServer extends EventEmitter {
|
||||||
|
|
||||||
this.ipc = await new IPCServer(handlers);
|
this.ipc = await new IPCServer(handlers);
|
||||||
this.ws = await new WSServer(handlers);
|
this.ws = await new WSServer(handlers);
|
||||||
|
this.process = await new ProcessServer(handlers);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
})();
|
})();
|
||||||
|
@ -34,7 +33,23 @@ class RPCServer extends EventEmitter {
|
||||||
evt: "READY",
|
evt: "READY",
|
||||||
|
|
||||||
data: {
|
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) {
|
switch (cmd) {
|
||||||
case "SET_ACTIVITY":
|
case "SET_ACTIVITY":
|
||||||
const {activity, pid} = args; // translate given parameters into what discord dispatch expects
|
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;
|
const {buttons, timestamps, instance} = activity;
|
||||||
|
|
||||||
socket.lastPid = pid ?? socket.lastPid;
|
socket.lastPid = pid ?? socket.lastPid;
|
||||||
|
@ -91,6 +114,13 @@ class RPCServer extends EventEmitter {
|
||||||
socketId: socket.socketId.toString()
|
socketId: socket.socketId.toString()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
socket.send?.({
|
||||||
|
cmd,
|
||||||
|
data: null,
|
||||||
|
evt: null,
|
||||||
|
nonce
|
||||||
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "GUILD_TEMPLATE_BROWSER":
|
case "GUILD_TEMPLATE_BROWSER":
|
||||||
|
@ -104,7 +134,7 @@ class RPCServer extends EventEmitter {
|
||||||
nonce
|
nonce
|
||||||
});
|
});
|
||||||
|
|
||||||
this.emit(cmd === "INVITE_BROWSER" ? "invite" : "guild_template", code);
|
this.emit(cmd === "INVITE_BROWSER" ? "invite" : "guild-template", code);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "DEEP_LINK":
|
case "DEEP_LINK":
|
||||||
|
|
|
@ -4,7 +4,9 @@ const log = (...args) => console.log(`[${rgb(88, 101, 242, "arRPC")} > ${rgb(254
|
||||||
const {join} = require("path");
|
const {join} = require("path");
|
||||||
const {platform, env} = require("process");
|
const {platform, env} = require("process");
|
||||||
const {unlinkSync} = require("fs");
|
const {unlinkSync} = require("fs");
|
||||||
|
|
||||||
const {createServer, createConnection} = require("net");
|
const {createServer, createConnection} = require("net");
|
||||||
|
|
||||||
const SOCKET_PATH =
|
const SOCKET_PATH =
|
||||||
platform === "win32"
|
platform === "win32"
|
||||||
? "\\\\?\\pipe\\discord-ipc"
|
? "\\\\?\\pipe\\discord-ipc"
|
||||||
|
@ -210,10 +212,20 @@ class IPCServer {
|
||||||
socket.once("handshake", (params) => {
|
socket.once("handshake", (params) => {
|
||||||
log("handshake:", params);
|
log("handshake:", params);
|
||||||
|
|
||||||
const ver = params.v ?? 1;
|
const ver = parseInt(params.v ?? 1);
|
||||||
const clientId = params.client_id ?? "";
|
const clientId = params.client_id ?? "";
|
||||||
// encoding is always json for ipc
|
// 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) {
|
if (ver !== 1) {
|
||||||
log("unsupported version requested", ver);
|
log("unsupported version requested", ver);
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ class WSServer {
|
||||||
await new Promise((res) => {
|
await new Promise((res) => {
|
||||||
http = createServer();
|
http = createServer();
|
||||||
http.on("error", (e) => {
|
http.on("error", (e) => {
|
||||||
// log('http error', e);
|
// log("http error", e);
|
||||||
|
|
||||||
if (e.code === "EADDRINUSE") {
|
if (e.code === "EADDRINUSE") {
|
||||||
log(port, "in use!");
|
log(port, "in use!");
|
||||||
|
@ -35,7 +35,7 @@ class WSServer {
|
||||||
|
|
||||||
wss = new WebSocketServer({server: http});
|
wss = new WebSocketServer({server: http});
|
||||||
wss.on("error", (e) => {
|
wss.on("error", (e) => {
|
||||||
// log('wss error', e);
|
// log("wss error", e);
|
||||||
});
|
});
|
||||||
|
|
||||||
wss.on("connection", this.onConnection);
|
wss.on("connection", this.onConnection);
|
||||||
|
@ -92,8 +92,8 @@ class WSServer {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if (clientId === '') {
|
/* if (clientId === "") {
|
||||||
log('client id required');
|
log("client id required");
|
||||||
|
|
||||||
socket.close();
|
socket.close();
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in a new issue