Files
achievement-watcher/src/lib.rs

150 lines
5.3 KiB
Rust

use reqwest::Client;
use steam::App;
pub mod steam;
#[cfg(test)]
mod test;
pub mod util;
#[derive(Debug)]
pub struct Game {
pub app_id: u32,
pub name: String,
pub achievements: Vec<Achievement>,
}
#[derive(Debug)]
pub struct Achievement {
pub name: String,
pub description: Option<String>,
pub achieved: bool,
pub hidden: bool,
pub icon: String,
pub icongray: String,
pub current_progress: u32,
pub max_progress: u32,
pub unlock_time: u32,
}
pub struct Context {
pub api_key: String,
pub game_name_cache_path: String,
pub json_cache_path: String,
pub icon_cache_path: String,
pub game_name_list: Vec<App>,
pub dirs: Vec<String>,
}
pub async fn get_achievement_data(client: &Client, app_id: u32, context: &Context) -> Option<Game> {
let mut game = Game {
name: steam::get_game_name(
client,
&context.game_name_cache_path,
&context.game_name_list,
app_id,
)
.await
.unwrap(),
app_id,
achievements: Vec::new(),
};
let game_data = steam::get_steam_data(client, &context.api_key, app_id, "en", &context.json_cache_path).await;
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 {
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)
}
pub async fn get_achievement_data_all(client: &Client, context: &Context) -> Vec<Game> {
let mut games: Vec<Game> = Vec::new();
let ini_games = steam::get_achievement_data_all_ini(&context.dirs);
for ini_game in ini_games {
let mut game = Game {
app_id: ini_game.id,
achievements: Vec::new(),
name: steam::get_game_name(
client,
&context.game_name_cache_path,
&context.game_name_list,
ini_game.id,
)
.await
.unwrap(),
};
let game_data = steam::get_steam_data(client, &context.api_key, ini_game.id, "en", &context.json_cache_path).await;
for json_achievement in &game_data.game.available_game_stats.achievements {
let mut found_in_ini = false;
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,
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(),
unlock_time: ini_achievement.unlock_time,
});
found_in_ini = true;
}
}
if !found_in_ini {
game.achievements.push(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(),
});
}
}
games.push(game);
}
games
}