wip
This commit is contained in:
@@ -1197,6 +1197,18 @@ async fn calculate_directory_size(dir: &Path) -> eyre::Result<u64> {
|
|||||||
Ok(total_size)
|
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 {
|
struct Ctx {
|
||||||
game_dir: Arc<RwLock<Option<String>>>,
|
game_dir: Arc<RwLock<Option<String>>>,
|
||||||
local_game_db: Arc<RwLock<Option<GameDB>>>,
|
local_game_db: Arc<RwLock<Option<GameDB>>>,
|
||||||
@@ -1395,7 +1407,43 @@ async fn handle_list_games_command(ctx: &Ctx, tx_notify_ui: &UnboundedSender<Pee
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn try_serve_local_game(
|
||||||
|
ctx: &Ctx,
|
||||||
|
tx_notify_ui: &UnboundedSender<PeerEvent>,
|
||||||
|
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<PeerEvent>, id: String) {
|
async fn handle_get_game_command(ctx: &Ctx, tx_notify_ui: &UnboundedSender<PeerEvent>, id: String) {
|
||||||
|
if try_serve_local_game(ctx, tx_notify_ui, &id).await {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
log::info!("Requesting game from peers: {id}");
|
log::info!("Requesting game from peers: {id}");
|
||||||
let peers = { ctx.peer_game_db.read().await.peers_with_game(&id) };
|
let peers = { ctx.peer_game_db.read().await.peers_with_game(&id) };
|
||||||
if peers.is_empty() {
|
if peers.is_empty() {
|
||||||
@@ -1496,7 +1544,20 @@ async fn handle_download_game_files_command(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if peer_whitelist.is_empty() {
|
if peer_whitelist.is_empty() {
|
||||||
|
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}");
|
log::error!("No trusted peers available after majority validation for game {id}");
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user