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