From 048c4de10ca9ae3b57d166aa31e6249cb35e99e7 Mon Sep 17 00:00:00 2001 From: ReBlast Date: Wed, 10 Apr 2024 18:24:03 +0500 Subject: [PATCH 1/4] unix implementation --- src/ipc/client.rs | 7 +++ src/ipc/platform/mod.rs | 3 + src/ipc/platform/unix_connection.rs | 79 ++++++++++++++++++++++++++ src/ipc/platform/windows_connection.rs | 2 - 4 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 src/ipc/platform/unix_connection.rs diff --git a/src/ipc/client.rs b/src/ipc/client.rs index 95aa93e..c0e9507 100644 --- a/src/ipc/client.rs +++ b/src/ipc/client.rs @@ -7,6 +7,13 @@ pub struct RichClient { pub last_activity: Option, } +#[cfg(not(target_os = "windows"))] +pub struct RichClient { + pub client_id: u64, + pub stream: std::os::unix::net::UnixStream, + pub last_activity: Option, +} + pub trait Connection { fn connect( client_id: u64, diff --git a/src/ipc/platform/mod.rs b/src/ipc/platform/mod.rs index 3b4ca1b..3968253 100644 --- a/src/ipc/platform/mod.rs +++ b/src/ipc/platform/mod.rs @@ -1,2 +1,5 @@ #[cfg(target_os = "windows")] pub mod windows_connection; + +#[cfg(not(target_os = "windows"))] +pub mod unix_connection; \ No newline at end of file diff --git a/src/ipc/platform/unix_connection.rs b/src/ipc/platform/unix_connection.rs new file mode 100644 index 0000000..94f24bc --- /dev/null +++ b/src/ipc/platform/unix_connection.rs @@ -0,0 +1,79 @@ +use std::fs::OpenOptions; +use std::io::{self, Read, Write}; +use std::os::unix::net::UnixStream; + +use crate::ipc::client::{Connection, RichClient}; +use crate::ipc::utils; + +impl Connection for RichClient { + fn connect(client_id: u64) -> Result> { + for i in 0..10 { + match UnixStream::connect(format!("/tmp/discord-ipc-{}", i)) { + Ok(stream) => { + return Ok(RichClient { + client_id: client_id, + stream: stream, + last_activity: None, + }) + } + Err(e) => match e.kind() { + io::ErrorKind::ConnectionRefused => continue, + _ => return Err(e.into()), + }, + } + } + + Err("Socket not found".into()) + } + + fn write(&mut self, opcode: u32, data: Option<&[u8]>) -> io::Result<()> { + if let Some(packet) = data { + self.stream.write_all( + utils::encode(opcode, packet.len() as u32).as_slice(), + )?; + self.stream.write_all(packet)?; + } else { + self.stream.write_all(utils::encode(opcode, 0).as_slice())?; + } + Ok(()) + } + + fn read(&mut self) -> io::Result> { + let mut header = [0; 8]; + self.stream.read_exact(&mut header)?; + let mut buffer = vec![0u8; utils::decode(&header) as usize]; + self.stream.read_exact(&mut buffer)?; + Ok(buffer) + } + + fn close(&mut self) -> io::Result<()> { + self.stream.write_all(utils::encode(2, 0).as_slice())?; + self.stream.flush()?; + Ok(()) + } + + fn handshake(&mut self) -> io::Result<()> { + self.write( + 0, + Some( + (format!("{{\"v\": 1,\"client_id\":\"{}\"}}", self.client_id)) + .as_bytes(), + ), + ) + } + + fn update( + &mut self, + packet: &crate::rpc::packet::Packet, + ) -> io::Result<()> { + if packet.activity != self.last_activity { + self.write(1, Some(packet.to_json().unwrap().as_bytes())) + } else { + Ok(()) + } + } + + fn clear(&mut self) -> io::Result<()> { + self.write(1, None) + } +} diff --git a/src/ipc/platform/windows_connection.rs b/src/ipc/platform/windows_connection.rs index 2f1dc29..3af8bf1 100644 --- a/src/ipc/platform/windows_connection.rs +++ b/src/ipc/platform/windows_connection.rs @@ -1,5 +1,3 @@ -#![cfg(target_os = "windows")] - use std::fs::OpenOptions; use std::io::{self, Read, Write}; use std::os::windows::fs::OpenOptionsExt; From febc134887e5160ed6f8a99eb4b8e0081d3e4e7d Mon Sep 17 00:00:00 2001 From: vyfor <92883017+vyfor@users.noreply.github.com> Date: Wed, 10 Apr 2024 18:25:01 +0500 Subject: [PATCH 2/4] setup github actions --- .github/workflows/rust.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .github/workflows/rust.yml diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml new file mode 100644 index 0000000..c1d5066 --- /dev/null +++ b/.github/workflows/rust.yml @@ -0,0 +1,19 @@ +name: Rust + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Build + run: cargo build --verbose From 366e2c4e753b1b6c5bf1d3a6fa2b11bbc15a993e Mon Sep 17 00:00:00 2001 From: ReBlast Date: Wed, 10 Apr 2024 18:30:39 +0500 Subject: [PATCH 3/4] check for paths --- src/ipc/platform/unix_connection.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/ipc/platform/unix_connection.rs b/src/ipc/platform/unix_connection.rs index 94f24bc..d01fa12 100644 --- a/src/ipc/platform/unix_connection.rs +++ b/src/ipc/platform/unix_connection.rs @@ -7,8 +7,13 @@ use crate::ipc::utils; impl Connection for RichClient { fn connect(client_id: u64) -> Result> { + let path = var("XDG_RUNTIME_DIR") + .or_else(|_| var("TMPDIR")) + .or_else(|_| var("TMP")) + .or_else(|_| var("TEMP")) + .unwrap_or_else(|_| "/tmp".to_string()); for i in 0..10 { - match UnixStream::connect(format!("/tmp/discord-ipc-{}", i)) { + match UnixStream::connect(format!("{}/discord-ipc-{}", path, i)) { Ok(stream) => { return Ok(RichClient { client_id: client_id, From cd0209787974dd4bf3023199553e0da007712380 Mon Sep 17 00:00:00 2001 From: ReBlast Date: Wed, 10 Apr 2024 18:48:27 +0500 Subject: [PATCH 4/4] add import for var --- src/ipc/platform/unix_connection.rs | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/ipc/platform/unix_connection.rs b/src/ipc/platform/unix_connection.rs index d01fa12..7929820 100644 --- a/src/ipc/platform/unix_connection.rs +++ b/src/ipc/platform/unix_connection.rs @@ -1,4 +1,4 @@ -use std::fs::OpenOptions; +use std::env::var; use std::io::{self, Read, Write}; use std::os::unix::net::UnixStream; @@ -33,9 +33,8 @@ impl Connection for RichClient { fn write(&mut self, opcode: u32, data: Option<&[u8]>) -> io::Result<()> { if let Some(packet) = data { - self.stream.write_all( - utils::encode(opcode, packet.len() as u32).as_slice(), - )?; + self.stream + .write_all(utils::encode(opcode, packet.len() as u32).as_slice())?; self.stream.write_all(packet)?; } else { self.stream.write_all(utils::encode(opcode, 0).as_slice())?; @@ -60,17 +59,11 @@ impl Connection for RichClient { fn handshake(&mut self) -> io::Result<()> { self.write( 0, - Some( - (format!("{{\"v\": 1,\"client_id\":\"{}\"}}", self.client_id)) - .as_bytes(), - ), + Some((format!("{{\"v\": 1,\"client_id\":\"{}\"}}", self.client_id)).as_bytes()), ) } - fn update( - &mut self, - packet: &crate::rpc::packet::Packet, - ) -> io::Result<()> { + fn update(&mut self, packet: &crate::rpc::packet::Packet) -> io::Result<()> { if packet.activity != self.last_activity { self.write(1, Some(packet.to_json().unwrap().as_bytes())) } else {