Skip to content

Commit

Permalink
add better logging, add support for valorant
Browse files Browse the repository at this point in the history
  • Loading branch information
Leastrio committed Nov 28, 2023
1 parent 1536e26 commit 96aab78
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 40 deletions.
29 changes: 15 additions & 14 deletions src-tauri/src/http_proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,19 @@ pub struct RiotChat {
pub async fn listen_http() -> DolosResult<()> {
let listener = TcpListener::bind("127.0.0.1:0").await?;
HTTP_PORT.set(listener.local_addr()?.port().into())?;
println!("Listening HTTP on {}", listener.local_addr()?);
println!("[Dolos] [HTTP] Listening on {}", listener.local_addr()?);

tokio::spawn(async move {
loop {
let (stream, _) = listener.accept().await.expect("Could not accept connection");
let (stream, _) = listener.accept().await.expect("[Dolos] [HTTP] Could not accept connection");
let io = TokioIo::new(stream);

tokio::spawn(async move {
if let Err(err) = http1::Builder::new()
.serve_connection(io, service_fn(process))
.await
{
println!("Error serving connection: {:?}", err);
println!("[Dolos] [HTTP] Error serving connection: {:?}", err);
}
});
}
Expand All @@ -49,29 +49,30 @@ pub async fn listen_http() -> DolosResult<()> {
async fn process(req: Request<Incoming>) -> Result<Response<Full<Bytes>>, Infallible> {
let client = reqwest::Client::new();
let url = CONFIG_URL.to_owned() + &req.uri().to_string();
println!("[Dolos] [HTTP] Sending Request to {}", url);
let mut headers = HeaderMap::new();

if let Some(user_agent) = req.headers().get("user-agent") {
headers.append("user-agent", user_agent.to_str().expect("Header value is not a valid string").to_string().parse().expect("Could not parse header value"));
headers.append("user-agent", user_agent.to_str().expect("[Dolos] [HTTP] Header value is not a valid string").to_string().parse().expect("[Dolos] [HTTP] Could not parse header value"));
}
if let Some(jwt) = req.headers().get("x-riot-entitlements-jwt") {
headers.append("x-riot-entitlements-jwt", jwt.to_str().expect("Header value is not a valid string").to_string().parse().expect("Could not parse header value"));
headers.append("x-riot-entitlements-jwt", jwt.to_str().expect("[Dolos] [HTTP] Header value is not a valid string").to_string().parse().expect("[Dolos] [HTTP] Could not parse header value"));
}
if let Some(auth) = req.headers().get("authorization") {
headers.append("authorization", auth.to_str().expect("Header value is not a valid string").to_string().parse().expect("Could not parse header value"));
headers.append("authorization", auth.to_str().expect("[Dolos] [HTTP] Header value is not a valid string").to_string().parse().expect("[Dolos] [HTTP] Could not parse header value"));
}

let resp = client.get(url)
.headers(headers.clone())
.send()
.await
.expect("Could not make request");
.expect("[Dolos] [HTTP] Could not make request");

let reply = if resp.status() == 200 {
let data: Value = serde_json::from_slice(&resp.bytes().await.expect("Could not get bytes")).expect("Invalid JSON");
let data: Value = serde_json::from_slice(&resp.bytes().await.expect("[Dolos] [HTTP] Could not get bytes")).expect("[Dolos] [HTTP] Invalid JSON");
rewrite_resp(data, headers).await
} else {
resp.bytes().await.expect("Could not get bytes")
resp.bytes().await.expect("[Dolos] [HTTP] Could not get bytes")
};

Ok(Response::new(Full::new(reply)))
Expand Down Expand Up @@ -99,15 +100,15 @@ async fn rewrite_resp(mut resp: Value, headers: HeaderMap) -> Bytes {
.headers(headers)
.send()
.await
.expect("Could not fetch pas token")
.expect("[Dolos] [HTTP] Could not fetch pas token")
.text()
.await
.expect("could not fetch body from pas req");
.expect("[Dolos] [HTTP] could not fetch body from pas req");

let mut validation = Validation::new(Algorithm::HS256);
validation.insecure_disable_signature_validation();

let jwt = decode::<Value>(&pas, &DecodingKey::from_secret(&[]), &validation).expect("Could not decode jwt");
let jwt = decode::<Value>(&pas, &DecodingKey::from_secret(&[]), &validation).expect("[Dolos] [HTTP] Could not decode jwt");
riot_chat_host = resp["chat.affinities"][jwt.claims["affinity"].as_str().unwrap()].to_string();
}
}
Expand All @@ -121,8 +122,8 @@ async fn rewrite_resp(mut resp: Value, headers: HeaderMap) -> Bytes {
}

if riot_chat_port != 0 && !riot_chat_host.is_empty() && !RIOT_CHAT.initialized() {
RIOT_CHAT.set(RiotChat { host: riot_chat_host.trim_start_matches("\"").trim_end_matches("\"").to_string(), port: riot_chat_port }).expect("RIOT_CHAT OnceCell written to twice");
RIOT_CHAT.set(RiotChat { host: riot_chat_host.trim_start_matches("\"").trim_end_matches("\"").to_string(), port: riot_chat_port }).expect("[Dolos] [HTTP] RIOT_CHAT OnceCell written to twice");
INIT_NOTIFY.notify_one();
}
Bytes::from(serde_json::to_vec(&resp).expect("Could not serialize to vec"))
Bytes::from(serde_json::to_vec(&resp).expect("[Dolos] [HTTP] Could not serialize to vec"))
}
14 changes: 8 additions & 6 deletions src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ pub static RIOT_CLIENT_PATH: OnceCell<String> = OnceCell::const_new();
type DolosResult<T> = Result<T, Box<dyn Error + Send + Sync>>;

fn main() {
utils::is_running();
// TODO: Check if riot client is running at boot, close if so
// TODO: Close riot client if dolos closes
// utils::is_running();
let file_path = format!(
"{}\\Riot Games\\RiotClientInstalls.json",
env::var("ProgramData").expect("Could not find program data folder")
env::var("ProgramData").expect("[Dolos] [Main] Could not find program data folder")
);
let data = serde_json::from_str(&String::from_utf8_lossy(&fs::read(file_path).expect("Could not read riot installs config"))).expect("Could not parse riot installs config");
RIOT_CLIENT_PATH.set(utils::choose_channel(data).unwrap()).expect("Could not set RIOT_CLIENT_PATH");
let data = serde_json::from_str(&String::from_utf8_lossy(&fs::read(file_path).expect("[Dolos] [Main] Could not read riot installs config"))).expect("[Dolos] [Main] Could not parse riot installs config");
RIOT_CLIENT_PATH.set(utils::choose_channel(data).unwrap()).expect("[Dolos] [Main] Could not set RIOT_CLIENT_PATH");

tauri::Builder::default()
.invoke_handler(tauri::generate_handler![launch_game])
Expand All @@ -31,7 +33,7 @@ fn main() {
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
.expect("[Dolos] [Main] error while running tauri application");
}

#[tauri::command]
Expand All @@ -41,5 +43,5 @@ fn launch_game(game: &str) -> () {
.arg(format!("--launch-product={}", game))
.arg("--launch-patchline=live")
.spawn()
.expect("Could not launch riot client!");
.expect("[Dolos] [Main] Could not launch riot client!");
}
48 changes: 28 additions & 20 deletions src-tauri/src/tcp_proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ impl OutputActor {
// Receiving from Client + sending to Riot Games
Some(data) = self.output_reciever.recv() => {
let data_str = String::from_utf8_lossy(&data);
let msg = if data_str.starts_with("<presence") {
let msg = if data_str.contains("<presence") {
rewrite_presence(&data_str).await
} else {
data
Expand All @@ -71,7 +71,7 @@ impl OutputActor {
pub async fn proxy_tcp_chat() -> DolosResult<()> {
let listener = TcpListener::bind("127.0.0.1:0").await?;
CHAT_PORT.set(listener.local_addr()?.port().into())?;
println!("Listening TCP on {}", listener.local_addr()?);
println!("[Dolos] [TCP] Listening on {}", listener.local_addr()?);

let cert = include_bytes!("../../certs/server.cert");
let key = include_bytes!("../../certs/server.key");
Expand All @@ -81,16 +81,16 @@ pub async fn proxy_tcp_chat() -> DolosResult<()> {


INIT_NOTIFY.notified().await;
println!("Continuing...");
println!("[Dolos] [TCP] Continuing...");

loop {
let (stream, _) = listener.accept().await.expect("Could not accept connection");
let input_stream = (acceptor.clone()).accept(stream).await.expect("Could not accept connection via tls");
let (stream, _) = listener.accept().await.expect("[Dolos] [TCP] Could not accept connection");
let input_stream = (acceptor.clone()).accept(stream).await.expect("[Dolos] [TCP] Could not accept connection via tls");

let riot_chat = RIOT_CHAT.get().unwrap();
let output_stream = TcpStream::connect(format!("{}:{}", riot_chat.host, riot_chat.port)).await.expect("Could not connect to riot chat server");
let connector = tokio_native_tls::TlsConnector::from(native_tls::TlsConnector::new().expect("Could not create tls connector"));
let output_stream = connector.connect(&riot_chat.host, output_stream).await.expect("Could not connect tls to riot chat server");
let output_stream = TcpStream::connect(format!("{}:{}", riot_chat.host, riot_chat.port)).await.expect("[Dolos] [TCP] Could not connect to riot chat server");
let connector = tokio_native_tls::TlsConnector::from(native_tls::TlsConnector::new().expect("[Dolos] [TCP] Could not create tls connector"));
let output_stream = connector.connect(&riot_chat.host, output_stream).await.expect("[Dolos] [TCP] Could not connect tls to riot chat server");

let (input_sender, input_reciever) = mpsc::channel::<Vec<u8>>(100);
let (output_sender, output_reciever) = mpsc::channel::<Vec<u8>>(100);
Expand All @@ -112,51 +112,59 @@ pub async fn proxy_tcp_chat() -> DolosResult<()> {
}

async fn rewrite_presence(data: &str) -> Vec<u8> {
println!("[Dolos] [TCP] Rewriting Presence Update");
let mut reader = Reader::from_str(data);
let mut writer = Writer::new(Cursor::new(Vec::new()));

let mut inside_show = false;
let mut inside_league = false;
let mut inside_league_st = false;
let mut inside_game = false;
let mut inside_game_st = false;

loop {
match reader.read_event() {
// Tag Starts
Ok(Event::Start(e)) if e.name().as_ref() == b"show" => {
inside_show = true;
writer.write_event_async(Event::Start(e.clone())).await.unwrap();
},
Ok(Event::Start(e)) if e.name().as_ref() == b"league_of_legends" => {
inside_league = true;
Ok(Event::Start(e)) if e.name().as_ref() == b"league_of_legends" || e.name().as_ref() == b"valorant" => {
inside_game = true;
writer.write_event_async(Event::Start(e.clone())).await.unwrap();
},
Ok(Event::Start(e)) if inside_league && e.name().as_ref() == b"st" => {
inside_league_st = true;
Ok(Event::Start(e)) if inside_game && e.name().as_ref() == b"st" => {
inside_game_st = true;
writer.write_event_async(Event::Start(e.clone())).await.unwrap();
},
Ok(Event::Start(e)) if e.name().as_ref() == b"status" => {},

// Tag insides
Ok(Event::Text(_)) if inside_show => {
writer.write_event_async(Event::Text(BytesText::new("offline"))).await.unwrap();
},
Ok(Event::Text(_)) if inside_league && inside_league_st => {
Ok(Event::Text(_)) if inside_game && inside_game_st => {
writer.write_event_async(Event::Text(BytesText::new("offline"))).await.unwrap();
},

// Tag ends
Ok(Event::End(e)) if inside_show => {
inside_show = false;
writer.write_event_async(Event::End(e)).await.unwrap();
},
Ok(Event::End(e)) if e.name().as_ref() == b"league_of_legends" => {
inside_league = false;
Ok(Event::End(e)) if e.name().as_ref() == b"league_of_legends" || e.name().as_ref() == b"valorant" => {
inside_game = false;
writer.write_event_async(Event::End(e)).await.unwrap();
},
Ok(Event::End(e)) if inside_league && e.name().as_ref() == b"st" => {
inside_league_st = false;
Ok(Event::End(e)) if inside_game_st && e.name().as_ref() == b"st" => {
inside_game_st = false;
writer.write_event_async(Event::End(e)).await.unwrap();
},
Ok(Event::End(e)) if e.name().as_ref() == b"status" => {},

// Other
Ok(Event::Eof) => break,
Ok(e) => writer.write_event_async(e).await.unwrap(),
Err(e) => {
eprintln!("Error while parsing xml: {}", e)
eprintln!("[Dolos] [TCP] Error while parsing xml: {}", e)
}
}
}
Expand Down

0 comments on commit 96aab78

Please sign in to comment.