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…
	
	Add table
		Add a link
		
	
		Reference in a new issue