-
-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(ipc): continuously read data from Discord pipe to detect sudden …
…disconnects
- Loading branch information
Showing
15 changed files
with
624 additions
and
187 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
#![allow(clippy::upper_case_acronyms)] | ||
|
||
#[cfg(target_os = "windows")] | ||
mod windows { | ||
pub type HANDLE = *mut std::ffi::c_void; | ||
pub type DWORD = u32; | ||
pub type BOOL = i32; | ||
pub type LPCWSTR = *const u16; | ||
pub type LPVOID = *mut std::ffi::c_void; | ||
|
||
pub const GENERIC_READ: DWORD = 0x80000000; | ||
pub const GENERIC_WRITE: DWORD = 0x40000000; | ||
pub const OPEN_EXISTING: DWORD = 3; | ||
pub const INVALID_HANDLE_VALUE: HANDLE = -1isize as HANDLE; | ||
pub const ERROR_PIPE_CONNECTED: DWORD = 535; | ||
pub const ERROR_IO_PENDING: DWORD = 997; | ||
pub const PIPE_ACCESS_DUPLEX: DWORD = 0x00000003; | ||
pub const FILE_FLAG_OVERLAPPED: DWORD = 0x40000000; | ||
pub const PIPE_TYPE_MESSAGE: DWORD = 0x00000004; | ||
pub const PIPE_READMODE_MESSAGE: DWORD = 0x00000002; | ||
pub const PIPE_WAIT: DWORD = 0x00000000; | ||
pub const PIPE_UNLIMITED_INSTANCES: DWORD = 255; | ||
|
||
#[repr(C)] | ||
pub struct Overlapped { | ||
pub internal: usize, | ||
pub internal_high: usize, | ||
pub offset: DWORD, | ||
pub offset_high: DWORD, | ||
pub h_event: HANDLE, | ||
} | ||
|
||
impl Default for Overlapped { | ||
fn default() -> Self { | ||
Self { | ||
internal: 0, | ||
internal_high: 0, | ||
offset: 0, | ||
offset_high: 0, | ||
h_event: unsafe { | ||
CreateEventW( | ||
std::ptr::null_mut(), | ||
1, | ||
0, | ||
std::ptr::null_mut(), | ||
) | ||
}, | ||
} | ||
} | ||
} | ||
|
||
extern "system" { | ||
pub fn CreateFileW( | ||
lfFileName: LPCWSTR, | ||
dwDesiredAccess: DWORD, | ||
dwShareMode: DWORD, | ||
lpSecurityAttributes: LPVOID, | ||
dwCreationDisposition: DWORD, | ||
dwFlagsAndAttributes: DWORD, | ||
hTemplateFile: HANDLE, | ||
) -> HANDLE; | ||
|
||
pub fn CreateNamedPipeW( | ||
lpName: LPCWSTR, | ||
dwOpenMode: DWORD, | ||
dwPipeMode: DWORD, | ||
nMaxInstances: DWORD, | ||
nOutBufferSize: DWORD, | ||
nInBufferSize: DWORD, | ||
nDefaultTimeOut: DWORD, | ||
lpSecurityAttributes: LPVOID, | ||
) -> HANDLE; | ||
|
||
pub fn ConnectNamedPipe( | ||
hNamedPipe: HANDLE, | ||
lpOverlapped: *mut Overlapped, | ||
) -> BOOL; | ||
|
||
pub fn GetLastError() -> DWORD; | ||
|
||
pub fn CloseHandle(hObject: HANDLE) -> BOOL; | ||
|
||
pub fn CreateEventW( | ||
lpEventAttributes: LPVOID, | ||
bManualReset: BOOL, | ||
bInitialState: BOOL, | ||
lpName: LPCWSTR, | ||
) -> HANDLE; | ||
|
||
pub fn WriteFile( | ||
hFile: HANDLE, | ||
lpBuffer: *const u8, | ||
nNumberOfBytesToWrite: DWORD, | ||
lpNumberOfBytesWritten: *mut DWORD, | ||
lpOverlapped: *mut Overlapped, | ||
) -> BOOL; | ||
|
||
pub fn ReadFile( | ||
hFile: HANDLE, | ||
lpBuffer: *mut u8, | ||
nNumberOfBytesToRead: DWORD, | ||
lpNumberOfBytesRead: *mut DWORD, | ||
lpOverlapped: *mut Overlapped, | ||
) -> BOOL; | ||
|
||
pub fn GetOverlappedResult( | ||
hFile: HANDLE, | ||
lpOverlapped: *mut Overlapped, | ||
lpNumberOfBytesTransferred: *mut DWORD, | ||
bWait: BOOL, | ||
) -> BOOL; | ||
} | ||
} | ||
|
||
#[cfg(target_os = "windows")] | ||
pub use windows::*; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
use std::{fmt, io}; | ||
|
||
#[derive(Debug)] | ||
pub enum DiscordError { | ||
Io(io::Error), | ||
InvalidClientId(String), | ||
ConnectionClosed, | ||
PipeNotFound, | ||
Custom(String), | ||
} | ||
|
||
impl fmt::Display for DiscordError { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
match self { | ||
DiscordError::Io(err) => write!(f, "IO error: {}", err), | ||
DiscordError::InvalidClientId(id) => { | ||
write!(f, "'{}' is not a valid client ID", id) | ||
} | ||
DiscordError::ConnectionClosed => { | ||
write!(f, "The connection was forcibly closed") | ||
} | ||
DiscordError::PipeNotFound => { | ||
write!(f, "Discord IPC pipe not found") | ||
} | ||
DiscordError::Custom(msg) => write!(f, "{}", msg), | ||
} | ||
} | ||
} | ||
|
||
impl std::error::Error for DiscordError {} | ||
|
||
impl From<io::Error> for DiscordError { | ||
fn from(err: io::Error) -> Self { | ||
DiscordError::Io(err) | ||
} | ||
} | ||
|
||
impl From<&str> for DiscordError { | ||
fn from(err: &str) -> Self { | ||
DiscordError::Custom(err.to_string()) | ||
} | ||
} | ||
|
||
impl From<String> for DiscordError { | ||
fn from(err: String) -> Self { | ||
DiscordError::Custom(err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
pub mod client; | ||
pub mod error; | ||
pub mod opcodes; | ||
pub mod platform; | ||
mod utils; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/// Discord IPC opcodes | ||
#[derive(Debug, Clone, Copy, PartialEq)] | ||
pub enum Opcode { | ||
Handshake = 0, | ||
Frame = 1, | ||
Close = 2, | ||
Ping = 3, | ||
Pong = 4, | ||
} | ||
|
||
impl From<u32> for Opcode { | ||
fn from(code: u32) -> Self { | ||
match code { | ||
0 => Opcode::Handshake, | ||
1 => Opcode::Frame, | ||
2 => Opcode::Close, | ||
3 => Opcode::Ping, | ||
4 => Opcode::Pong, | ||
_ => Opcode::Frame, | ||
} | ||
} | ||
} | ||
|
||
impl From<Opcode> for u32 { | ||
fn from(op: Opcode) -> Self { | ||
op as u32 | ||
} | ||
} |
Oops, something went wrong.