From 32e909448f1faff8a718f23f4ddcdc509422b9c4 Mon Sep 17 00:00:00 2001 From: ddidderr Date: Thu, 13 Nov 2025 23:58:04 +0100 Subject: [PATCH] wip --- crates/lanspread-peer/src/lib.rs | 63 +++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/crates/lanspread-peer/src/lib.rs b/crates/lanspread-peer/src/lib.rs index 5113819..3570e47 100644 --- a/crates/lanspread-peer/src/lib.rs +++ b/crates/lanspread-peer/src/lib.rs @@ -1197,6 +1197,18 @@ async fn calculate_directory_size(dir: &Path) -> eyre::Result { Ok(total_size) } +async fn local_download_available(game_dir: &str, game_id: &str) -> bool { + let game_path = PathBuf::from(game_dir).join(game_id); + let eti_path = game_path.join(format!("{game_id}.eti")); + + if tokio::fs::metadata(&eti_path).await.is_err() { + return false; + } + + // Only treat as pending install if the local installation directory is empty/missing + !local_dir_has_content(game_path.as_path()).await +} + struct Ctx { game_dir: Arc>>, local_game_db: Arc>>, @@ -1395,7 +1407,43 @@ async fn handle_list_games_command(ctx: &Ctx, tx_notify_ui: &UnboundedSender, + id: &str, +) -> bool { + let game_dir = { ctx.game_dir.read().await.clone() }; + let Some(game_dir) = game_dir else { + return false; + }; + + if !local_download_available(&game_dir, id).await { + return false; + } + + match get_game_file_descriptions(id, &game_dir).await { + Ok(file_descriptions) => { + log::info!("Serving game {id} from local files"); + if let Err(e) = tx_notify_ui.send(PeerEvent::GotGameFiles { + id: id.to_string(), + file_descriptions, + }) { + log::error!("Failed to send GotGameFiles event: {e}"); + } + true + } + Err(e) => { + log::error!("Failed to enumerate local file descriptions for {id}: {e}"); + false + } + } +} + async fn handle_get_game_command(ctx: &Ctx, tx_notify_ui: &UnboundedSender, id: String) { + if try_serve_local_game(ctx, tx_notify_ui, &id).await { + return; + } + log::info!("Requesting game from peers: {id}"); let peers = { ctx.peer_game_db.read().await.peers_with_game(&id) }; if peers.is_empty() { @@ -1496,7 +1544,20 @@ async fn handle_download_game_files_command( } if peer_whitelist.is_empty() { - log::error!("No trusted peers available after majority validation for game {id}"); + if local_download_available(&games_folder, &id).await { + log::info!("Using locally downloaded files for game {id}; skipping peer transfer"); + if let Err(e) = tx_notify_ui.send(PeerEvent::DownloadGameFilesBegin { id: id.clone() }) + { + log::error!("Failed to send DownloadGameFilesBegin event: {e}"); + } + if let Err(e) = + tx_notify_ui.send(PeerEvent::DownloadGameFilesFinished { id: id.clone() }) + { + log::error!("Failed to send DownloadGameFilesFinished event: {e}"); + } + } else { + log::error!("No trusted peers available after majority validation for game {id}"); + } return; }