diff --git a/src/lib.rs b/src/lib.rs index 717a5e2..4f28207 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -51,27 +51,32 @@ pub async fn get_achievement_data(client: &Client, app_id: u32, context: &Contex let ini_data = steam::get_achievement_data_all_ini(&context.dirs); let ini_game = ini_data.iter().find(|m| m.id == app_id)?; for json_achievement in &game_data.game.available_game_stats.achievements { + let mut achievement = Achievement { + achieved: false, + max_progress: 0, + current_progress: 0, + unlock_time: 0, + description: json_achievement.description.clone(), + name: json_achievement.display_name.clone(), + hidden: if json_achievement.hidden == 1 { + true + } else if json_achievement.hidden == 0 { + false + } else { + panic!("Unexpected hidden value") + }, + icon: json_achievement.icon.clone(), + icongray: json_achievement.icongray.clone(), + }; for ini_achievement in &ini_game.achievements { if json_achievement.name == ini_achievement.name { - game.achievements.push(Achievement { - achieved: ini_achievement.achieved, - max_progress: ini_achievement.max_progress, - current_progress: ini_achievement.current_progress, - unlock_time: ini_achievement.unlock_time, - description: json_achievement.description.clone(), - name: json_achievement.display_name.clone(), - hidden: if json_achievement.hidden == 1 { - true - } else if json_achievement.hidden == 0 { - false - } else { - panic!("Unexpected hidden value") - }, - icon: json_achievement.icon.clone(), - icongray: json_achievement.icongray.clone(), - }); - } + achievement.achieved = ini_achievement.achieved; + achievement.max_progress = ini_achievement.max_progress; + achievement.current_progress = ini_achievement.current_progress; + achievement.unlock_time = ini_achievement.unlock_time; + } } + game.achievements.push(achievement); } Some(game) } diff --git a/src/main.rs b/src/main.rs index 18f2e05..f1ca072 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,9 +13,9 @@ async fn main() { let args: Vec = std::env::args().skip(1).collect(); if args.is_empty() { ui::ui(games).unwrap(); - } else if args.len() == 3 { + } else if args.len() == 1 { match args[0].as_str() { - "-w" => watch::watch_file(&args[1], args[2].parse().unwrap(), &context, &mut games) + "-w" => watch::watch_file(&context, &mut games) .await .unwrap(), _ => panic!("wrong arg"), diff --git a/src/util.rs b/src/util.rs index 67e8a41..0a27e76 100644 --- a/src/util.rs +++ b/src/util.rs @@ -14,10 +14,23 @@ pub fn get_game_name_file_cache(path: &str) -> Vec { .collect() } -pub fn send_notification(game_name: &str, achievement_name: &str, achievement_description: Option<&str>, icon_path: Option<&str>) { +pub fn send_notification( + game_name: &str, + achievement_name: &str, + achievement_description: Option<&str>, + icon_path: Option<&str>, +) { std::process::Command::new("notify-send") - .args(["-a", game_name, "-i", icon_path.unwrap_or(""), achievement_name, achievement_description.unwrap_or("")]) + .args([ + "-a", + game_name, + "-i", + icon_path.unwrap_or(""), + achievement_name, + achievement_description.unwrap_or(""), + ]) .spawn() + .unwrap() + .wait() .unwrap(); } - diff --git a/src/watch.rs b/src/watch.rs index f0a8c87..95c5c55 100644 --- a/src/watch.rs +++ b/src/watch.rs @@ -4,26 +4,39 @@ use reqwest::Client; use std::path::Path; use std::sync::mpsc; -pub async fn watch_file( - path: &str, - app_id: u32, - context: &Context, - games: &mut Vec, -) -> Result<()> { +pub async fn watch_file(context: &Context, games: &mut Vec) -> Result<()> { let (tx, rx) = mpsc::channel::>(); - let mut watcher = notify::recommended_watcher(tx)?; - - watcher.watch(Path::new(path), RecursiveMode::NonRecursive)?; let client = Client::new(); - for res in rx { + + for dir in &context.dirs { + watcher.watch(Path::new(dir), RecursiveMode::Recursive)?; + } + for res in &rx { match res { Ok(event) => { - println!("event: {:#?}", event); + // println!("event: {:#?}", event); if let EventKind::Access(AccessKind::Close(notify::event::AccessMode::Write)) = event.kind { - check_for_new_achievement(&client, games, app_id, context).await; + assert_eq!(event.paths.len(), 1); + let path = &event.paths[0]; + if path.file_name().unwrap() == "achievements.ini" { + println!("WATCHER: found achievement file change"); + let app_id: u32 = path + .parent() + .unwrap() + .file_name() + .unwrap() + .to_str() + .unwrap() + .parse() + .unwrap(); + println!("WATCHER: app id for change: {app_id}"); + check_for_new_achievement(&client, games, app_id, context).await; + } else { + println!("\n\n####\nSome other file changed\n####\n\n"); + } } } Err(e) => panic!("watch error: {:?}", e), @@ -44,7 +57,11 @@ async fn check_for_new_achievement( .unwrap(); let old = games.iter().find(|m| m.app_id == app_id); if let Some(old) = old { + assert_eq!(new.achievements.len(), old.achievements.len()); let indexes = compare_achievements(&new.achievements, &old.achievements); + if indexes.is_empty() { + println!("WATCHER: found no new achievements"); + } for i in indexes { let new_achievement = &new.achievements[i]; println!("new achievement: {:#?}", new_achievement); @@ -68,23 +85,18 @@ async fn check_for_new_achievement( ); } } else { - println!("\n\nWATCHER: did not find the game"); + println!("WATCHER: did not find the game"); } let u_old = games.iter_mut().find(|m| m.app_id == app_id).unwrap(); *u_old = new; } fn compare_achievements(new: &Vec, old: &Vec) -> Vec { - let mut indexes = Vec::new(); - for (i, new_a) in new.iter().enumerate() { - if old - .iter() - .find(|m| m.name == new_a.name && !m.achieved && new_a.achieved) - .is_some() - { - println!("\n\nWATCHER: found new achievement {}", new_a.name); - indexes.push(i); - } - } - indexes + new.iter() + .map(|n| { + old.iter() + .position(|o| !o.achieved && n.achieved && o.name == n.name) + }) + .flatten() + .collect() }