diff --git a/src-tauri/src/downloader.rs b/src-tauri/src/downloader.rs index 6b2a9fb..1883170 100644 --- a/src-tauri/src/downloader.rs +++ b/src-tauri/src/downloader.rs @@ -8,7 +8,7 @@ use std::io::Write; use futures_util::StreamExt; // This will create a downloads list that will be used to check if we should continue downloading the file -lazy_static!{ +lazy_static! { static ref DOWNLOADS: Mutex> = { let m = Vec::new(); Mutex::new(m) @@ -19,121 +19,121 @@ lazy_static!{ // and docs ofc #[tauri::command] pub async fn download_file(window: tauri::Window, url: &str, path: &str) -> Result<(), String> { - // Reqwest setup - let res = match reqwest::get(url) - .await { - Ok(r) => r, - Err(_e) => { - emit_download_err(window, format!("Failed to request {}", url), path); - return Err(format!("Failed to request {}", url)); - }, - }; - let total_size = res - .content_length() - .unwrap_or(0); + // Reqwest setup + let res = match reqwest::get(url) + .await { + Ok(r) => r, + Err(_e) => { + emit_download_err(window, format!("Failed to request {}", url), path); + return Err(format!("Failed to request {}", url)); + } + }; + let total_size = res + .content_length() + .unwrap_or(0); - // Create file path - let mut file = match File::create(path) { - Ok(f) => f, - Err(_e) => { - emit_download_err(window, format!("Failed to create file '{}'", path), path); - return Err(format!("Failed to create file '{}'", path)); - }, - }; - let mut downloaded: u64 = 0; + // Create file path + let mut file = match File::create(path) { + Ok(f) => f, + Err(_e) => { + emit_download_err(window, format!("Failed to create file '{}'", path), path); + return Err(format!("Failed to create file '{}'", path)); + } + }; + let mut downloaded: u64 = 0; - // File stream - let mut stream = res.bytes_stream(); + // File stream + let mut stream = res.bytes_stream(); - // Assuming all goes well, add to the downloads list - DOWNLOADS.lock().unwrap().push(path.to_string()); + // Assuming all goes well, add to the downloads list + DOWNLOADS.lock().unwrap().push(path.to_string()); - // Await chunks - while let Some(item) = stream.next().await { - // Stop the loop if the download is removed from the list - if !DOWNLOADS.lock().unwrap().contains(&path.to_string()) { - break; - } - - let chunk = match item { - Ok(itm) => itm, - Err(e) => { - emit_download_err(window, format!("Error while downloading file"), path); - return Err(format!("Error while downloading file: {}", e)); - }, - }; - let vect = &chunk.to_vec()[..]; - - // Write bytes - match file.write_all(&vect) { - Ok(x) => x, - Err(e) => { - emit_download_err(window, format!("Error while writing file"), path); - return Err(format!("Error while writing file: {}", e)); - }, - } - - // New progress - let new = min(downloaded + (chunk.len() as u64), total_size); - downloaded = new; - - let mut res_hash = std::collections::HashMap::new(); - - res_hash.insert( - "downloaded".to_string(), - downloaded.to_string() - ); - - res_hash.insert( - "total".to_string(), - total_size.to_string() - ); - - res_hash.insert( - "path".to_string(), - path.to_string() - ); - - // Create event to send to frontend - window.emit("download_progress", &res_hash).unwrap(); + // Await chunks + while let Some(item) = stream.next().await { + // Stop the loop if the download is removed from the list + if !DOWNLOADS.lock().unwrap().contains(&path.to_string()) { + break; } - // One more "finish" event - window.emit("download_finished", &path).unwrap(); + let chunk = match item { + Ok(itm) => itm, + Err(e) => { + emit_download_err(window, format!("Error while downloading file"), path); + return Err(format!("Error while downloading file: {}", e)); + } + }; + let vect = &chunk.to_vec()[..]; - // We are done - return Ok(()); -} + // Write bytes + match file.write_all(&vect) { + Ok(x) => x, + Err(e) => { + emit_download_err(window, format!("Error while writing file"), path); + return Err(format!("Error while writing file: {}", e)); + } + } + + // New progress + let new = min(downloaded + (chunk.len() as u64), total_size); + downloaded = new; -pub fn emit_download_err(window: tauri::Window, msg: std::string::String, path: &str) { let mut res_hash = std::collections::HashMap::new(); res_hash.insert( - "error".to_string(), - msg.to_string() + "downloaded".to_string(), + downloaded.to_string(), ); res_hash.insert( - "path".to_string(), - path.to_string() + "total".to_string(), + total_size.to_string(), ); - window.emit("download_error", &res_hash).unwrap(); + res_hash.insert( + "path".to_string(), + path.to_string(), + ); + + // Create event to send to frontend + window.emit("download_progress", &res_hash).unwrap(); + } + + // One more "finish" event + window.emit("download_finished", &path).unwrap(); + + // We are done + return Ok(()); +} + +pub fn emit_download_err(window: tauri::Window, msg: std::string::String, path: &str) { + let mut res_hash = std::collections::HashMap::new(); + + res_hash.insert( + "error".to_string(), + msg.to_string(), + ); + + res_hash.insert( + "path".to_string(), + path.to_string(), + ); + + window.emit("download_error", &res_hash).unwrap(); } #[tauri::command] pub fn stop_download(path: String) { - // Check if the path is in the downloads list - let mut downloads = DOWNLOADS.lock().unwrap(); - let index = downloads.iter().position(|x| x == &path); + // Check if the path is in the downloads list + let mut downloads = DOWNLOADS.lock().unwrap(); + let index = downloads.iter().position(|x| x == &path); - // Remove from list - if let Some(i) = index { - downloads.remove(i); - } + // Remove from list + if let Some(i) = index { + downloads.remove(i); + } - // Delete the file from disk - if let Err(_e) = std::fs::remove_file(&path) { - // Do nothing - } + // Delete the file from disk + if let Err(_e) = std::fs::remove_file(&path) { + // Do nothing + } } \ No newline at end of file diff --git a/src-tauri/src/lang.rs b/src-tauri/src/lang.rs index 80baaff..23c518e 100644 --- a/src-tauri/src/lang.rs +++ b/src-tauri/src/lang.rs @@ -44,8 +44,8 @@ pub fn emit_lang_err(window: tauri::Window, msg: std::string::String) { let mut res_hash = std::collections::HashMap::new(); res_hash.insert( - "error".to_string(), - msg.to_string() + "error".to_string(), + msg.to_string(), ); window.emit("lang_error", &res_hash).unwrap(); diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 7602898..ce34fee 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -19,7 +19,7 @@ mod lang; mod proxy; mod web; -lazy_static!{ +lazy_static! { static ref WATCH_GAME_PROCESS: Mutex = { let m = "".to_string(); Mutex::new(m) @@ -48,7 +48,7 @@ fn main() { lang::get_lang, lang::get_languages ]) - .run(tauri::generate_context!()) + .run(tauri::generate_context!()) .expect("error while running tauri application"); } @@ -60,14 +60,14 @@ fn process_watcher() { // Start in thread so as to not block the main thread. thread::spawn(|| { let mut s = System::new_all(); - + loop { // Refresh system info s.refresh_all(); - + // Grab the game process name let proc = WATCH_GAME_PROCESS.lock().unwrap().to_string(); - + if !&proc.is_empty() { let proc_with_name = s.processes_by_exact_name(&proc); let mut exists = false; @@ -133,7 +133,7 @@ async fn get_bg_file(bg_path: String) -> String { return "".to_string(); } }; - + let file_name = response_data.backgroundFile.to_string() + ".png"; // First we see if the file already exists in our local bg folder @@ -141,7 +141,7 @@ async fn get_bg_file(bg_path: String) -> String { let cwd = std::env::current_dir().unwrap(); return format!("{}\\{}", cwd.display(), response_data.backgroundFile.as_str()); } - + // Now we check if the bg folder, which is one directory above the game_path, exists. let bg_img_path = format!("{}\\{}", bg_path.clone().to_string(), file_name.as_str()); @@ -164,7 +164,7 @@ async fn get_bg_file(bg_path: String) -> String { // Copy was successful, lets return true let cwd = std::env::current_dir().unwrap(); return format!("{}\\{}", cwd.display(), response_data.backgroundFile.as_str()); - }, + } Err(e) => { // Copy failed, lets return false println!("Failed to copy background image: {}", e); diff --git a/src-tauri/src/proxy.rs b/src-tauri/src/proxy.rs index 3836228..43b7caf 100644 --- a/src-tauri/src/proxy.rs +++ b/src-tauri/src/proxy.rs @@ -7,10 +7,10 @@ use lazy_static::lazy_static; use std::sync::Mutex; use hudsucker::{ - async_trait::async_trait, - certificate_authority::RcgenAuthority, - hyper::{Body, Request, Response}, - * + async_trait::async_trait, + certificate_authority::RcgenAuthority, + hyper::{Body, Request, Response}, + *, }; use std::net::SocketAddr; @@ -20,12 +20,12 @@ use rustls_pemfile as pemfile; use tauri::http::Uri; async unsafe fn shutdown_signal() { - tokio::signal::ctrl_c().await - .expect("Failed to install CTRL+C signal handler"); + tokio::signal::ctrl_c().await + .expect("Failed to install CTRL+C signal handler"); } // Global ver for getting server address -lazy_static!{ +lazy_static! { static ref SERVER: Mutex = { let m = "localhost:443".to_string(); Mutex::new(m) @@ -36,110 +36,106 @@ lazy_static!{ struct ProxyHandler; #[tauri::command] -pub fn set_proxy_addr(addr: String){ - *SERVER.lock().unwrap() = addr; +pub fn set_proxy_addr(addr: String) { + *SERVER.lock().unwrap() = addr; } #[async_trait] impl HttpHandler for ProxyHandler { - async fn handle_request(&mut self, - _context: &HttpContext, - mut request: Request - ) -> RequestOrResponse { - println!("Request: {}", &request.uri()); + async fn handle_request(&mut self, + _context: &HttpContext, + mut request: Request, + ) -> RequestOrResponse { + // Get request URI. + let uri = request.uri().to_string(); + let uri_path = request.uri().path(); - // Get request URI - let uri = request.uri().to_string(); - let uri_path = request.uri().path(); - - // Only switch up if request is to the game servers - if uri.contains("hoyoverse.com") || uri.contains("mihoyo.com") || uri.contains("yuanshen.com") { - // Copy the request and just change the URI - let uri = format!("https://{}{}", SERVER.lock().unwrap(), uri_path).parse::().unwrap(); - - *request.uri_mut() = uri; - } - - println!("New request: {}", &request.uri()); - - RequestOrResponse::Request(request) + // Only switch up if request is to the game servers. + if uri.contains("hoyoverse.com") || uri.contains("mihoyo.com") || uri.contains("yuanshen.com") { + // Create new URI. + let uri = format!("https://{}{}", SERVER.lock().unwrap(), uri_path).parse::().unwrap(); + // Set request URI to the new one. + *request.uri_mut() = uri; } - - async fn handle_response(&mut self, - _context: &HttpContext, - response: Response - ) -> Response { response } + + RequestOrResponse::Request(request) + } + + async fn handle_response(&mut self, + _context: &HttpContext, + response: Response, + ) -> Response { response } } /** * Starts an HTTP(S) proxy server. */ pub(crate) async fn create_proxy(proxy_port: u16) { - // Get the certificate and private key. - let mut private_key_bytes: &[u8] = include_bytes!("../resources/private-key.pem"); - let mut ca_cert_bytes: &[u8] = include_bytes!("../resources/ca-certificate.pem"); - - // Parse the private key and certificate. - let private_key = rustls::PrivateKey( - pemfile::pkcs8_private_keys(&mut private_key_bytes) - .expect("Failed to parse private key") - .remove(0), - ); + // Get the certificate and private key. + let mut private_key_bytes: &[u8] = include_bytes!("../resources/private-key.pem"); + let mut ca_cert_bytes: &[u8] = include_bytes!("../resources/ca-certificate.pem"); - let ca_cert = rustls::Certificate( - pemfile::certs(&mut ca_cert_bytes) - .expect("Failed to parse CA certificate") - .remove(0), - ); - - // Create the certificate authority. - let authority = RcgenAuthority::new(private_key, ca_cert, 1_000) - .expect("Failed to create Certificate Authority"); - - // Create an instance of the proxy. - let proxy = ProxyBuilder::new() - .with_addr(SocketAddr::from(([0, 0, 0, 0], proxy_port))) - .with_rustls_client() - .with_ca(authority) - .with_http_handler(ProxyHandler) - .build(); + // Parse the private key and certificate. + let private_key = rustls::PrivateKey( + pemfile::pkcs8_private_keys(&mut private_key_bytes) + .expect("Failed to parse private key") + .remove(0), + ); - // Start the proxy. - unsafe { - tokio::spawn(proxy.start(shutdown_signal())); - } + let ca_cert = rustls::Certificate( + pemfile::certs(&mut ca_cert_bytes) + .expect("Failed to parse CA certificate") + .remove(0), + ); + + // Create the certificate authority. + let authority = RcgenAuthority::new(private_key, ca_cert, 1_000) + .expect("Failed to create Certificate Authority"); + + // Create an instance of the proxy. + let proxy = ProxyBuilder::new() + .with_addr(SocketAddr::from(([0, 0, 0, 0], proxy_port))) + .with_rustls_client() + .with_ca(authority) + .with_http_handler(ProxyHandler) + .build(); + + // Start the proxy. + unsafe { + tokio::spawn(proxy.start(shutdown_signal())); + } } /** * Connects to the local HTTP(S) proxy server. */ pub(crate) fn connect_to_proxy(proxy_port: u16) { - if cfg!(target_os = "windows") { - // Create 'ProxyServer' string. - let server_string: String = format!("http=127.0.0.1:{};https=127.0.0.1:{};ftp=127.0.0.1:{}", proxy_port, proxy_port, proxy_port); + if cfg!(target_os = "windows") { + // Create 'ProxyServer' string. + let server_string: String = format!("http=127.0.0.1:{};https=127.0.0.1:{};ftp=127.0.0.1:{}", proxy_port, proxy_port, proxy_port); - // Fetch the 'Internet Settings' registry key. - let settings = Hive::CurrentUser.open(r"Software\Microsoft\Windows\CurrentVersion\Internet Settings", Security::Write).unwrap(); - - // Set registry values. - settings.set_value("ProxyServer", &Data::String(server_string.parse().unwrap())).unwrap(); - settings.set_value("ProxyEnable", &Data::U32(1)).unwrap(); - } + // Fetch the 'Internet Settings' registry key. + let settings = Hive::CurrentUser.open(r"Software\Microsoft\Windows\CurrentVersion\Internet Settings", Security::Write).unwrap(); - println!("Connected to the proxy."); + // Set registry values. + settings.set_value("ProxyServer", &Data::String(server_string.parse().unwrap())).unwrap(); + settings.set_value("ProxyEnable", &Data::U32(1)).unwrap(); + } + + println!("Connected to the proxy."); } /** * Disconnects from the local HTTP(S) proxy server. */ pub(crate) fn disconnect_from_proxy() { - if cfg!(target_os = "windows") { - // Fetch the 'Internet Settings' registry key. - let settings = Hive::CurrentUser.open(r"Software\Microsoft\Windows\CurrentVersion\Internet Settings", Security::Write).unwrap(); + if cfg!(target_os = "windows") { + // Fetch the 'Internet Settings' registry key. + let settings = Hive::CurrentUser.open(r"Software\Microsoft\Windows\CurrentVersion\Internet Settings", Security::Write).unwrap(); - // Set registry values. - settings.set_value("ProxyEnable", &Data::U32(0)).unwrap(); - } + // Set registry values. + settings.set_value("ProxyEnable", &Data::U32(0)).unwrap(); + } - println!("Disconnected from proxy."); + println!("Disconnected from proxy."); } \ No newline at end of file diff --git a/src-tauri/src/structs.rs b/src-tauri/src/structs.rs index faac02d..dca3538 100644 --- a/src-tauri/src/structs.rs +++ b/src-tauri/src/structs.rs @@ -4,5 +4,5 @@ use serde::Deserialize; #[derive(Deserialize)] pub(crate) struct APIQuery { - pub backgroundFile: String, + pub backgroundFile: String, } \ No newline at end of file diff --git a/src-tauri/src/unzip.rs b/src-tauri/src/unzip.rs index 33619d6..16735d9 100644 --- a/src-tauri/src/unzip.rs +++ b/src-tauri/src/unzip.rs @@ -26,21 +26,21 @@ pub fn unzip(window: tauri::Window, zipfile: String, destpath: String) { match zip_extract::extract(&f, &full_path, true) { Ok(_) => { println!("Extracted zip file to: {}", full_path.to_str().unwrap_or("Error")); - }, + } Err(e) => { println!("Failed to extract zip file: {}", e); let mut res_hash = std::collections::HashMap::new(); res_hash.insert( - "error".to_string(), - e.to_string() + "error".to_string(), + e.to_string(), ); - + res_hash.insert( - "path".to_string(), - zipfile.to_string() + "path".to_string(), + zipfile.to_string(), ); - + window.emit("download_error", &res_hash).unwrap(); } }; @@ -59,7 +59,7 @@ pub fn unzip(window: tauri::Window, zipfile: String, destpath: String) { match std::fs::remove_file(&zipfile) { Ok(_) => { println!("Deleted zip file: {}", zipfile); - }, + } Err(e) => { println!("Failed to delete zip file: {}", e); } diff --git a/src-tauri/src/web.rs b/src-tauri/src/web.rs index 7dcd631..420a05b 100644 --- a/src-tauri/src/web.rs +++ b/src-tauri/src/web.rs @@ -1,8 +1,8 @@ use reqwest::header::USER_AGENT; pub(crate) async fn query(site: &str) -> String { - let client = reqwest::Client::new(); + let client = reqwest::Client::new(); - let response = client.get(site).header(USER_AGENT, "cultivation").send().await.unwrap(); - return response.text().await.unwrap(); + let response = client.get(site).header(USER_AGENT, "cultivation").send().await.unwrap(); + return response.text().await.unwrap(); } \ No newline at end of file