diff --git a/.editorconfig b/.editorconfig index 2acebee..813f40d 100644 --- a/.editorconfig +++ b/.editorconfig @@ -13,6 +13,8 @@ trim_trailing_whitespace = false [*.rs] max_line_length = 100 indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true [{*.ats,*.cts,*.mts,*.ts}] indent_size = 2 diff --git a/src-tauri/rustfmt.toml b/src-tauri/rustfmt.toml new file mode 100644 index 0000000..2f9c1b2 --- /dev/null +++ b/src-tauri/rustfmt.toml @@ -0,0 +1,3 @@ +tab_spaces = 2 +use_field_init_shorthand = true +use_try_shorthand = true diff --git a/src-tauri/src/downloader.rs b/src-tauri/src/downloader.rs index 1b567ce..ebf6301 100644 --- a/src-tauri/src/downloader.rs +++ b/src-tauri/src/downloader.rs @@ -1,9 +1,9 @@ use once_cell::sync::Lazy; -use std::sync::Mutex; use std::cmp::min; use std::fs::File; use std::io::Write; +use std::sync::Mutex; use futures_util::StreamExt; @@ -15,17 +15,14 @@ static DOWNLOADS: Lazy>> = Lazy::new(|| Mutex::new(Vec::new()) #[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 { + 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); + let total_size = res.content_length().unwrap_or(0); // Create file path let mut file = match File::create(path) { @@ -77,25 +74,10 @@ pub async fn download_file(window: tauri::Window, url: &str, path: &str) -> Resu 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(), - ); - - res_hash.insert( - "total_downloaded".to_string(), - total_downloaded.to_string(), - ); + 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()); + res_hash.insert("total_downloaded".to_string(), total_downloaded.to_string()); // Create event to send to frontend window.emit("download_progress", &res_hash).unwrap(); @@ -111,15 +93,8 @@ pub async fn download_file(window: tauri::Window, url: &str, path: &str) -> Resu pub fn emit_download_err(window: tauri::Window, msg: String, path: &str) { let mut res_hash = std::collections::HashMap::new(); - res_hash.insert( - "error".to_string(), - msg, - ); - - res_hash.insert( - "path".to_string(), - path.to_string(), - ); + res_hash.insert("error".to_string(), msg); + res_hash.insert("path".to_string(), path.to_string()); window.emit("download_error", &res_hash).unwrap(); } @@ -139,4 +114,4 @@ pub fn stop_download(path: String) { 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 e797996..2ec452f 100644 --- a/src-tauri/src/lang.rs +++ b/src-tauri/src/lang.rs @@ -1,12 +1,14 @@ -use std::path::{Path, PathBuf}; use crate::system_helpers::*; +use std::path::{Path, PathBuf}; #[tauri::command] pub async fn get_lang(window: tauri::Window, lang: String) -> String { let lang = lang.to_lowercase(); // Send contents of language file back - let lang_path: PathBuf = [&install_location(), "lang", &format!("{}.json", lang)].iter().collect(); + let lang_path: PathBuf = [&install_location(), "lang", &format!("{}.json", lang)] + .iter() + .collect(); match std::fs::read_to_string(&lang_path) { Ok(x) => x, Err(e) => { @@ -45,10 +47,7 @@ pub async fn get_languages() -> std::collections::HashMap { pub fn emit_lang_err(window: tauri::Window, msg: String) { let mut res_hash = std::collections::HashMap::new(); - res_hash.insert( - "error".to_string(), - msg, - ); + res_hash.insert("error".to_string(), msg); window.emit("lang_error", &res_hash).unwrap(); -} \ No newline at end of file +} diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 3bbf69a..525558d 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -1,22 +1,22 @@ #![cfg_attr( -all(not(debug_assertions), target_os = "windows"), -windows_subsystem = "windows" + all(not(debug_assertions), target_os = "windows"), + windows_subsystem = "windows" )] use once_cell::sync::Lazy; -use std::{sync::Mutex, collections::HashMap}; +use std::{collections::HashMap, sync::Mutex}; use std::thread; +use structs::APIQuery; use sysinfo::{System, SystemExt}; -use structs::{APIQuery}; -mod structs; -mod system_helpers; -mod file_helpers; -mod unzip; mod downloader; +mod file_helpers; mod lang; mod proxy; +mod structs; +mod system_helpers; +mod unzip; mod web; static WATCH_GAME_PROCESS: Lazy> = Lazy::new(|| Mutex::new(String::new())); @@ -155,7 +155,7 @@ async fn get_theme_list(data_dir: String) -> Vec> { map.insert("json".to_string(), theme_json); map.insert("path".to_string(), path.to_str().unwrap().to_string()); - + // Push key-value pair containing "json" and "path" themes.push(map); } diff --git a/src-tauri/src/proxy.rs b/src-tauri/src/proxy.rs index 415bc43..ec29d69 100644 --- a/src-tauri/src/proxy.rs +++ b/src-tauri/src/proxy.rs @@ -4,15 +4,15 @@ */ use once_cell::sync::Lazy; -use std::{sync::Mutex, str::FromStr}; +use std::{str::FromStr, sync::Mutex}; -use rcgen::*; use hudsucker::{ async_trait::async_trait, certificate_authority::RcgenAuthority, hyper::{Body, Request, Response}, *, }; +use rcgen::*; use std::fs; use std::net::SocketAddr; @@ -22,10 +22,11 @@ use rustls_pemfile as pemfile; use tauri::http::Uri; #[cfg(windows)] -use registry::{Hive, Data, Security}; +use registry::{Data, Hive, Security}; async fn shutdown_signal() { - tokio::signal::ctrl_c().await + tokio::signal::ctrl_c() + .await .expect("Failed to install CTRL+C signal handler"); } @@ -42,16 +43,18 @@ pub fn set_proxy_addr(addr: String) { #[async_trait] impl HttpHandler for ProxyHandler { - async fn handle_request(&mut self, - _context: &HttpContext, - mut request: Request, + async fn handle_request( + &mut self, + _context: &HttpContext, + mut request: Request, ) -> RequestOrResponse { let uri = request.uri().to_string(); let uri_path = request.uri().path(); - + if uri.contains("hoyoverse.com") || uri.contains("mihoyo.com") || uri.contains("yuanshen.com") { // Create new URI. - let new_uri = Uri::from_str(format!("{}{}", SERVER.lock().unwrap(), uri_path).as_str()).unwrap(); + let new_uri = + Uri::from_str(format!("{}{}", SERVER.lock().unwrap(), uri_path).as_str()).unwrap(); // Set request URI to the new one. *request.uri_mut() = new_uri; } @@ -59,10 +62,13 @@ impl HttpHandler for ProxyHandler { RequestOrResponse::Request(request) } - async fn handle_response(&mut self, - _context: &HttpContext, - response: Response, - ) -> Response { response } + async fn handle_response( + &mut self, + _context: &HttpContext, + response: Response, + ) -> Response { + response + } } /** @@ -70,20 +76,22 @@ impl HttpHandler for ProxyHandler { */ pub async fn create_proxy(proxy_port: u16, certificate_path: String) { // Get the certificate and private key. - let mut private_key_bytes: &[u8] = &fs::read(format!("{}\\private.key", certificate_path)).expect("Could not read private key"); - let mut ca_cert_bytes: &[u8] = &fs::read(format!("{}\\cert.crt", certificate_path)).expect("Could not read certificate"); + let mut private_key_bytes: &[u8] = + &fs::read(format!("{}\\private.key", certificate_path)).expect("Could not read private key"); + let mut ca_cert_bytes: &[u8] = + &fs::read(format!("{}\\cert.crt", certificate_path)).expect("Could not read certificate"); // 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) + .remove(0), ); let ca_cert = rustls::Certificate( pemfile::certs(&mut ca_cert_bytes) .expect("Failed to parse CA certificate") - .remove(0) + .remove(0), ); // Create the certificate authority. @@ -108,13 +116,23 @@ pub async fn create_proxy(proxy_port: u16, certificate_path: String) { #[cfg(windows)] pub fn connect_to_proxy(proxy_port: u16) { // Create 'ProxyServer' string. - let server_string: String = format!("http=127.0.0.1:{};https=127.0.0.1:{}", proxy_port, proxy_port); + let server_string: String = format!( + "http=127.0.0.1:{};https=127.0.0.1:{}", + 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(); + 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("ProxyServer", &Data::String(server_string.parse().unwrap())) + .unwrap(); settings.set_value("ProxyEnable", &Data::U32(1)).unwrap(); println!("Connected to the proxy."); @@ -131,7 +149,12 @@ pub fn connect_to_proxy(_proxy_port: u16) { #[cfg(windows)] pub fn disconnect_from_proxy() { // Fetch the 'Internet Settings' registry key. - let settings = Hive::CurrentUser.open(r"Software\Microsoft\Windows\CurrentVersion\Internet Settings", Security::Write).unwrap(); + 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(); @@ -157,7 +180,7 @@ pub fn generate_ca_files(path: &Path) { details.push(DnType::OrganizationName, "Grasscutters"); details.push(DnType::CountryName, "CN"); details.push(DnType::LocalityName, "CN"); - + // Set details in the parameter. params.distinguished_name = details; // Set other properties. @@ -165,9 +188,9 @@ pub fn generate_ca_files(path: &Path) { params.key_usages = vec![ KeyUsagePurpose::DigitalSignature, KeyUsagePurpose::KeyCertSign, - KeyUsagePurpose::CrlSign + KeyUsagePurpose::CrlSign, ]; - + // Create certificate. let cert = Certificate::from_params(params).unwrap(); let cert_crt = cert.serialize_pem().unwrap(); @@ -176,26 +199,37 @@ pub fn generate_ca_files(path: &Path) { // Make certificate directory. let cert_dir = path.join("ca"); match fs::create_dir(&cert_dir) { - Ok(_) => {}, + Ok(_) => {} Err(e) => { println!("{}", e); } }; - + // Write the certificate to a file. let cert_path = cert_dir.join("cert.crt"); match fs::write(&cert_path, cert_crt) { Ok(_) => println!("Wrote certificate to {}", cert_path.to_str().unwrap()), - Err(e) => println!("Error writing certificate to {}: {}", cert_path.to_str().unwrap(), e), + Err(e) => println!( + "Error writing certificate to {}: {}", + cert_path.to_str().unwrap(), + e + ), } // Write the private key to a file. let private_key_path = cert_dir.join("private.key"); match fs::write(&private_key_path, private_key) { - Ok(_) => println!("Wrote private key to {}", private_key_path.to_str().unwrap()), - Err(e) => println!("Error writing private key to {}: {}", private_key_path.to_str().unwrap(), e), + Ok(_) => println!( + "Wrote private key to {}", + private_key_path.to_str().unwrap() + ), + Err(e) => println!( + "Error writing private key to {}: {}", + private_key_path.to_str().unwrap(), + e + ), } - + // Install certificate into the system's Root CA store. install_ca_files(&cert_path); } @@ -205,13 +239,27 @@ pub fn generate_ca_files(path: &Path) { */ #[cfg(windows)] pub fn install_ca_files(cert_path: &Path) { - crate::system_helpers::run_command("certutil", vec!["-user", "-addstore", "Root", cert_path.to_str().unwrap()]); + crate::system_helpers::run_command( + "certutil", + vec!["-user", "-addstore", "Root", cert_path.to_str().unwrap()], + ); println!("Installed certificate."); } #[cfg(target_os = "macos")] pub fn install_ca_files(cert_path: &Path) { - crate::system_helpers::run_command("security", vec!["add-trusted-cert", "-d", "-r", "trustRoot", "-k", "/Library/Keychains/System.keychain", cert_path.to_str().unwrap()]); + crate::system_helpers::run_command( + "security", + vec![ + "add-trusted-cert", + "-d", + "-r", + "trustRoot", + "-k", + "/Library/Keychains/System.keychain", + cert_path.to_str().unwrap(), + ], + ); println!("Installed certificate."); } diff --git a/src-tauri/src/structs.rs b/src-tauri/src/structs.rs index e2d0710..406083e 100644 --- a/src-tauri/src/structs.rs +++ b/src-tauri/src/structs.rs @@ -5,4 +5,4 @@ use serde::Deserialize; #[derive(Deserialize)] pub(crate) struct APIQuery { pub bg_file: String, -} \ No newline at end of file +} diff --git a/src-tauri/src/system_helpers.rs b/src-tauri/src/system_helpers.rs index 2eb3f39..2cb49bc 100644 --- a/src-tauri/src/system_helpers.rs +++ b/src-tauri/src/system_helpers.rs @@ -10,8 +10,7 @@ pub fn run_program(path: String) { #[tauri::command] pub fn run_command(program: &str, args: Vec<&str>) { - cmd(program, args).run() - .expect("Failed to run command"); + cmd(program, args).run().expect("Failed to run command"); } #[tauri::command] @@ -23,7 +22,10 @@ pub fn run_jar(path: String, execute_in: String, java_path: String) { }; // Open the program from the specified path. - match open::with(format!("/k cd /D \"{}\" & {}", &execute_in, &command), "C:\\Windows\\System32\\cmd.exe") { + match open::with( + format!("/k cd /D \"{}\" & {}", &execute_in, &command), + "C:\\Windows\\System32\\cmd.exe", + ) { Ok(_) => (), Err(e) => println!("Failed to open jar ({} from {}): {}", &path, &execute_in, e), }; @@ -38,7 +40,6 @@ pub fn open_in_browser(url: String) { }; } - #[tauri::command] pub fn install_location() -> String { let mut exe_path = std::env::current_exe().unwrap(); diff --git a/src-tauri/src/unzip.rs b/src-tauri/src/unzip.rs index dcfe084..310b7c4 100644 --- a/src-tauri/src/unzip.rs +++ b/src-tauri/src/unzip.rs @@ -23,21 +23,18 @@ 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")); + 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(), - ); + res_hash.insert("error".to_string(), e.to_string()); - res_hash.insert( - "path".to_string(), - zipfile.to_string(), - ); + res_hash.insert("path".to_string(), zipfile.to_string()); window.emit("download_error", &res_hash).unwrap(); } @@ -50,7 +47,9 @@ pub fn unzip(window: tauri::Window, zipfile: String, destpath: String) { // If the contents is a jar file, emit that we have extracted a new jar file if name.ends_with(".jar") { - window.emit("jar_extracted", destpath.to_string() + name).unwrap(); + window + .emit("jar_extracted", destpath.to_string() + name) + .unwrap(); } // Delete zip file @@ -65,4 +64,4 @@ pub fn unzip(window: tauri::Window, zipfile: String, destpath: String) { window.emit("extract_end", &zipfile).unwrap(); }); -} \ No newline at end of file +} diff --git a/src-tauri/src/web.rs b/src-tauri/src/web.rs index af5864d..9650124 100644 --- a/src-tauri/src/web.rs +++ b/src-tauri/src/web.rs @@ -3,7 +3,12 @@ use reqwest::header::USER_AGENT; pub(crate) async fn query(site: &str) -> String { let client = reqwest::Client::new(); - let response = client.get(site).header(USER_AGENT, "cultivation").send().await.unwrap(); + let response = client + .get(site) + .header(USER_AGENT, "cultivation") + .send() + .await + .unwrap(); response.text().await.unwrap() } @@ -12,7 +17,12 @@ pub(crate) async fn valid_url(url: String) -> bool { // Check if we get a 200 response let client = reqwest::Client::new(); - let response = client.get(url).header(USER_AGENT, "cultivation").send().await.unwrap(); + let response = client + .get(url) + .header(USER_AGENT, "cultivation") + .send() + .await + .unwrap(); response.status().as_str() == "200" -} \ No newline at end of file +}