Skip to content

Commit

Permalink
Working prototype, still needs some cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
adamaq01 committed Jul 31, 2020
1 parent 43ae943 commit f33d13d
Show file tree
Hide file tree
Showing 15 changed files with 1,627 additions and 35 deletions.
1,032 changes: 1,029 additions & 3 deletions Cargo.lock

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

members = [
"commons",
"client",
"server",
]
"host",
"guest",
]
9 changes: 0 additions & 9 deletions client/Cargo.toml

This file was deleted.

3 changes: 0 additions & 3 deletions client/src/main.rs

This file was deleted.

7 changes: 7 additions & 0 deletions commons/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@ name = "commons"
version = "0.1.0"
authors = ["Adamaq01 <[email protected]>"]
edition = "2018"
build = "build.rs"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
serde = { version = "1.0.114", features = ["derive"] }
bincode = "1.3.1"
uuid = { version = "0.8.1", features = ["serde"] }

[build-dependencies]
vergen = "3.1.0"
12 changes: 12 additions & 0 deletions commons/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
extern crate vergen;

use vergen::{generate_cargo_keys, ConstantsFlags};

fn main() {
// Setup the flags, toggling off the 'SEMVER' flag
let mut flags = ConstantsFlags::all();
flags.toggle(ConstantsFlags::SEMVER);

// Generate the 'cargo:' key output
generate_cargo_keys(flags).expect("Unable to generate the cargo keys!");
}
37 changes: 32 additions & 5 deletions commons/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,34 @@
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
use std::env;
use std::fmt::Error;

pub mod packet;

pub const VERSION: &str = concat!("v", env!("VERGEN_SEMVER"), "-", env!("VERGEN_SHA_SHORT"));
pub const DEFAULT_PORT: u16 = 8765;
pub const DEFAULT_PORT_STR: &str = "8765";
pub const BUFFER_SIZE: usize = 2048;

pub fn get_path(num: usize) -> Result<String, Error> {
if num > 9 {
Err(Error::default())
} else {
Ok(format!(
"{}discord-ipc-{}",
if cfg!(windows) {
"\\\\.\\pipe\\".to_string()
} else {
get_temp_path()? + "/"
},
num
))
}
}

pub fn get_temp_path() -> Result<String, Error> {
env::var("XDG_RUNTIME_DIR")
.or_else(|_| env::var("TMPDIR"))
.or_else(|_| env::var("TMP"))
.or_else(|_| env::var("TEMP"))
.or_else(|_| env::temp_dir().into_os_string().into_string())
.or_else(|_| Ok("/tmp".to_string()))
}
20 changes: 20 additions & 0 deletions commons/src/packet.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use bincode::Result;
use serde::{Deserialize, Serialize};
use uuid::Uuid;

#[derive(Serialize, Deserialize)]
pub enum Packet {
Connect(Uuid),
Disconnect(Uuid),
Data(Uuid, Vec<u8>),
}

impl Packet {
pub fn deserialize(data: Vec<u8>) -> Result<Packet> {
bincode::deserialize(data.as_slice())
}

pub fn serialize(&self) -> Result<Vec<u8>> {
bincode::serialize(&self)
}
}
18 changes: 18 additions & 0 deletions guest/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "guest"
version = "0.1.0"
authors = ["Adamaq01 <[email protected]>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
commons = { path = "../commons" }
parity-tokio-ipc = { git = "https://github.com/open-trade/parity-tokio-ipc" }
# pretty-hex = "0.1.1"
tokio = { version = "0.2.22", features = ["io-driver", "io-util", "uds", "stream", "rt-core", "macros", "time", "net", "tcp", "sync"] }
bytes = "0.5.6"
async-trait = "0.1.36"
clap = "3.0.0-beta.1"
futures = "0.3"
uuid = { version = "0.8.1", features = ["v4"] }
139 changes: 139 additions & 0 deletions guest/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
use std::collections::HashMap;
use std::error::Error;
use std::sync::Arc;

use clap::Clap;
use futures::stream::StreamExt;
use parity_tokio_ipc::{Connection, Endpoint, SecurityAttributes};
use tokio::io::{AsyncWriteExt, WriteHalf};
use tokio::net::tcp::OwnedWriteHalf;
use tokio::net::TcpStream;
use tokio::sync::Mutex;
use tokio::{self, prelude::*};
use uuid::Uuid;

use commons::packet::Packet;
use commons::packet::Packet::Data;

#[allow(irrefutable_let_patterns)]
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let opts: Opts = Opts::parse();
let addr = opts.address + ":" + opts.port.to_string().as_str();

println!("Connecting to {}", addr);
let (mut rx, tx) = TcpStream::connect(&addr).await?.into_split();
println!("Successfully connected to {}", addr);

let state = Arc::new(Mutex::new(Shared::new(tx)));

// TCP Connection
let tcp_state = Arc::clone(&state);
tokio::spawn(async move {
loop {
let mut buf = [0u8; commons::BUFFER_SIZE];
let length = rx
.read(&mut buf[..])
.await
.expect("Couldn't receive data from Host");
if length == 0 {
continue;
}
if let Ok(packet) = Packet::deserialize(buf[..length].to_vec()) {
if let Data(uuid, data) = packet {
if let Some(peer) = tcp_state.lock().await.peers.get_mut(&uuid) {
let _ = peer.write_all(data.as_slice()).await;
}
}
}
// tcp_state.lock().await.broadcast(&buf[..length]).await;
// println!("{:?}", data.hex_dump());
}
});

// Discord
let mut endpoint = Endpoint::new(commons::get_path(0)?);
endpoint.set_security_attributes(SecurityAttributes::allow_everyone_create()?);

let mut incoming = endpoint.incoming()?;
println!("Listening for Discord IPC Calls");

loop {
let stream: Connection = incoming
.next()
.await
.expect("Couldn't receive connection")?;

let state = Arc::clone(&state);

let (mut rx, tx) = tokio::io::split(stream);

let uuid = Uuid::new_v4();
state.lock().await.peers.insert(uuid, tx);
let _ = state.lock().await.send_packet(Packet::Connect(uuid)).await;

tokio::spawn(async move {
println!("Accepted connection {}", uuid);

let mut buf = [0u8; commons::BUFFER_SIZE];
while let Ok(length) = rx.read(&mut buf[..]).await {
if length == 0 {
break;
}
// println!("{}", &buf[..length].to_vec().hex_dump());
let _ = state
.lock()
.await
.send_packet(Packet::Data(uuid, buf[..length].to_vec()))
.await;
}

{
state
.lock()
.await
.send_packet(Packet::Disconnect(uuid))
.await;
state.lock().await.peers.remove(&uuid);
println!("Removed connection {}", uuid)
}
});
}
}

struct Shared {
tx: OwnedWriteHalf,
peers: HashMap<Uuid, WriteHalf<Connection>>,
}

impl Shared {
fn new(tx: OwnedWriteHalf) -> Self {
Shared {
tx,
peers: HashMap::new(),
}
}

async fn send_packet(&mut self, packet: Packet) {
let _ = self
.tx
.write_all(packet.serialize().unwrap().as_slice())
.await;
}
}

/// Enables Discord Rich Presence on Linux Host for games running in a Windows Guest VM
#[derive(Clap)]
#[clap(
name = "VFIO Discord IPC Bridge Guest",
version = commons::VERSION,
author = "Adamaq01 <[email protected]>"
)]
struct Opts {
/// The address to connect to
#[clap(short = "i", long)]
address: String,
/// The port to connect to
#[clap(short, long, default_value = commons::DEFAULT_PORT_STR)]
port: u16,
}
19 changes: 19 additions & 0 deletions host/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[package]
name = "host"
version = "0.1.0"
authors = ["Adamaq01 <[email protected]>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
commons = { path = "../commons" }
parity-tokio-ipc = "0.7.0"
# pretty-hex = "0.1.1"
tokio = { version = "0.2.22", features = ["io-driver", "io-util", "uds", "stream", "rt-core", "macros", "time", "net", "tcp", "sync"] }
bytes = "0.5.6"
interfaces = "0.0.4"
async-trait = "0.1.36"
clap = "3.0.0-beta.1"
futures = "0.3.5"
uuid = { version = "0.8.1", features = ["v4"] }
Loading

0 comments on commit f33d13d

Please sign in to comment.