diff options
Diffstat (limited to 'src-tauri/src/core')
| -rw-r--r-- | src-tauri/src/core/account_storage.rs | 18 | ||||
| -rw-r--r-- | src-tauri/src/core/auth.rs | 30 | ||||
| -rw-r--r-- | src-tauri/src/core/downloader.rs | 40 | ||||
| -rw-r--r-- | src-tauri/src/core/java.rs | 24 |
4 files changed, 76 insertions, 36 deletions
diff --git a/src-tauri/src/core/account_storage.rs b/src-tauri/src/core/account_storage.rs index b8e15e1..9512213 100644 --- a/src-tauri/src/core/account_storage.rs +++ b/src-tauri/src/core/account_storage.rs @@ -131,13 +131,17 @@ impl AccountStorage { pub fn get_active_account(&self) -> Option<(StoredAccount, Option<String>)> { let store = self.load(); if let Some(active_id) = &store.active_account_id { - store.accounts.iter().find(|a| &a.id() == active_id).map(|a| { - let ms_token = match a { - StoredAccount::Microsoft(m) => m.ms_refresh_token.clone(), - _ => None, - }; - (a.clone(), ms_token) - }) + store + .accounts + .iter() + .find(|a| &a.id() == active_id) + .map(|a| { + let ms_token = match a { + StoredAccount::Microsoft(m) => m.ms_refresh_token.clone(), + _ => None, + }; + (a.clone(), ms_token) + }) } else { None } diff --git a/src-tauri/src/core/auth.rs b/src-tauri/src/core/auth.rs index 624f1de..e53c00e 100644 --- a/src-tauri/src/core/auth.rs +++ b/src-tauri/src/core/auth.rs @@ -2,7 +2,6 @@ use serde::{Deserialize, Serialize}; use std::sync::Mutex; use uuid::Uuid; - // Helper to create a client with a custom User-Agent // This is critical because Microsoft's WAF often blocks requests without a valid UA fn get_client() -> reqwest::Client { @@ -142,30 +141,32 @@ pub fn is_token_expired(expires_at: i64) -> bool { .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_secs() as i64; - + // Consider expired if less than 5 minutes remaining expires_at - now < 300 } /// Full refresh flow: refresh MS token -> Xbox -> XSTS -> Minecraft -pub async fn refresh_full_auth(ms_refresh_token: &str) -> Result<(MicrosoftAccount, String), String> { +pub async fn refresh_full_auth( + ms_refresh_token: &str, +) -> Result<(MicrosoftAccount, String), String> { println!("[Auth] Starting full token refresh..."); - + // 1. Refresh Microsoft token let token_resp = refresh_microsoft_token(ms_refresh_token).await?; - + // 2. Xbox Live Auth let (xbl_token, uhs) = method_xbox_live(&token_resp.access_token).await?; - + // 3. XSTS Auth let xsts_token = method_xsts(&xbl_token).await?; - + // 4. Minecraft Auth let mc_token = login_minecraft(&xsts_token, &uhs).await?; - + // 5. Get Profile let profile = fetch_profile(&mc_token).await?; - + // 6. Create Account let account = MicrosoftAccount { username: profile.name, @@ -175,12 +176,15 @@ pub async fn refresh_full_auth(ms_refresh_token: &str) -> Result<(MicrosoftAccou expires_at: (std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap() - .as_secs() + token_resp.expires_in) as i64, + .as_secs() + + token_resp.expires_in) as i64, }; - + // Return new MS refresh token for storage - let new_ms_refresh = token_resp.refresh_token.unwrap_or_else(|| ms_refresh_token.to_string()); - + let new_ms_refresh = token_resp + .refresh_token + .unwrap_or_else(|| ms_refresh_token.to_string()); + Ok((account, new_ms_refresh)) } diff --git a/src-tauri/src/core/downloader.rs b/src-tauri/src/core/downloader.rs index 7ff81ad..3add9b7 100644 --- a/src-tauri/src/core/downloader.rs +++ b/src-tauri/src/core/downloader.rs @@ -69,7 +69,10 @@ impl GlobalProgress { /// Add downloaded bytes and return updated snapshot fn add_bytes(&self, delta: u64) -> ProgressSnapshot { - let total_bytes = self.total_downloaded_bytes.fetch_add(delta, Ordering::Relaxed) + delta; + let total_bytes = self + .total_downloaded_bytes + .fetch_add(delta, Ordering::Relaxed) + + delta; ProgressSnapshot { completed_files: self.completed_files.load(Ordering::Relaxed), total_files: self.total_files, @@ -101,10 +104,14 @@ fn emit_progress( ); } -pub async fn download_files(window: Window, tasks: Vec<DownloadTask>, max_concurrent: usize) -> Result<(), String> { +pub async fn download_files( + window: Window, + tasks: Vec<DownloadTask>, + max_concurrent: usize, +) -> Result<(), String> { // Clamp max_concurrent to a valid range (1-128) to prevent edge cases let max_concurrent = max_concurrent.clamp(1, 128); - + let client = reqwest::Client::new(); let semaphore = Arc::new(Semaphore::new(max_concurrent)); let progress = Arc::new(GlobalProgress::new(tasks.len())); @@ -141,7 +148,14 @@ pub async fn download_files(window: Window, tasks: Vec<DownloadTask>, max_concur if skipped_size > 0 { let _ = progress.add_bytes(skipped_size); } - emit_progress(&window, &file_name, "Skipped", 0, 0, &progress.inc_completed()); + emit_progress( + &window, + &file_name, + "Skipped", + 0, + 0, + &progress.inc_completed(), + ); return Ok(()); } } @@ -170,7 +184,14 @@ pub async fn download_files(window: Window, tasks: Vec<DownloadTask>, max_concur } downloaded += chunk.len() as u64; let snapshot = progress.add_bytes(chunk.len() as u64); - emit_progress(&window, &file_name, "Downloading", downloaded, total_size, &snapshot); + emit_progress( + &window, + &file_name, + "Downloading", + downloaded, + total_size, + &snapshot, + ); } Ok(None) => break, Err(e) => return Err(format!("Download error: {}", e)), @@ -180,7 +201,14 @@ pub async fn download_files(window: Window, tasks: Vec<DownloadTask>, max_concur Err(e) => return Err(format!("Request error: {}", e)), } - emit_progress(&window, &file_name, "Finished", 0, 0, &progress.inc_completed()); + emit_progress( + &window, + &file_name, + "Finished", + 0, + 0, + &progress.inc_completed(), + ); Ok(()) } }); diff --git a/src-tauri/src/core/java.rs b/src-tauri/src/core/java.rs index e0962fa..9cf3053 100644 --- a/src-tauri/src/core/java.rs +++ b/src-tauri/src/core/java.rs @@ -17,7 +17,10 @@ pub fn detect_java_installations() -> Vec<JavaInstallation> { for candidate in candidates { if let Some(java) = check_java_installation(&candidate) { // Avoid duplicates - if !installations.iter().any(|j: &JavaInstallation| j.path == java.path) { + if !installations + .iter() + .any(|j: &JavaInstallation| j.path == java.path) + { installations.push(java); } } @@ -121,7 +124,9 @@ fn get_java_candidates() -> Vec<PathBuf> { if homebrew_arm.exists() { if let Ok(entries) = std::fs::read_dir(&homebrew_arm) { for entry in entries.flatten() { - let java_path = entry.path().join("libexec/openjdk.jdk/Contents/Home/bin/java"); + let java_path = entry + .path() + .join("libexec/openjdk.jdk/Contents/Home/bin/java"); if java_path.exists() { candidates.push(java_path); } @@ -133,8 +138,10 @@ fn get_java_candidates() -> Vec<PathBuf> { #[cfg(target_os = "windows")] { // Windows Java paths - let program_files = std::env::var("ProgramFiles").unwrap_or_else(|_| "C:\\Program Files".to_string()); - let program_files_x86 = std::env::var("ProgramFiles(x86)").unwrap_or_else(|_| "C:\\Program Files (x86)".to_string()); + let program_files = + std::env::var("ProgramFiles").unwrap_or_else(|_| "C:\\Program Files".to_string()); + let program_files_x86 = std::env::var("ProgramFiles(x86)") + .unwrap_or_else(|_| "C:\\Program Files (x86)".to_string()); let local_app_data = std::env::var("LOCALAPPDATA").unwrap_or_default(); let win_paths = [ @@ -186,14 +193,11 @@ fn get_java_candidates() -> Vec<PathBuf> { /// Check a specific Java installation and get its version info fn check_java_installation(path: &PathBuf) -> Option<JavaInstallation> { - let output = Command::new(path) - .arg("-version") - .output() - .ok()?; + let output = Command::new(path).arg("-version").output().ok()?; // Java outputs version info to stderr let version_output = String::from_utf8_lossy(&output.stderr); - + // Parse version string (e.g., "openjdk version \"17.0.1\"" or "java version \"1.8.0_301\"") let version = parse_version_string(&version_output)?; let is_64bit = version_output.contains("64-Bit"); @@ -240,7 +244,7 @@ fn parse_java_version(version: &str) -> u32 { /// Get the best Java for a specific Minecraft version pub fn get_recommended_java(required_major_version: Option<u64>) -> Option<JavaInstallation> { let installations = detect_java_installations(); - + if let Some(required) = required_major_version { // Find exact match or higher installations.into_iter().find(|java| { |