refresh.rs
1 use tracing::{info, warn}; 2 use crate::constants::Icon_Locked; 3 use crate::data::AppData; 4 use crate::data::secure::getSteamAuth; 5 use crate::io::{FileName_GameIcon, Path_Games, saveUserData_Steam}; 6 use crate::{join, jpg, jpgAlt}; 7 use crate::net::limiter::request::{DataOperation, DataOperationResult, 8 FileLocation, DataRequest, SteamOperation}; 9 use crate::steam::SteamApi; 10 11 pub async fn handleDataOperation(mut appData: AppData, operation: SteamOperation) -> Option<DataOperationResult> 12 { 13 return match operation 14 { 15 SteamOperation::GetGameList => { 16 let result = refreshGameList(appData).await; 17 info!("[Steam API] Refreshed game list"); 18 19 Some(result) 20 } 21 22 SteamOperation::GetGlobalPercentages(id) => { 23 let appData = refreshGlobalPercentages(appData, id).await; 24 info!("[Steam API] Refreshed global percentages for app id {}", id); 25 26 Some(appData.into()) 27 } 28 29 SteamOperation::GetPlayerAchievements(id) => { 30 let appData = refreshGameAchievements(appData, id).await; 31 info!("[Steam API] Refreshed achievements for app id {}", id); 32 33 Some(appData.into()) 34 } 35 36 SteamOperation::GetPlayerSummary => { 37 let result = refreshPlayerSummary(appData).await; 38 info!("[Steam API] Refreshed player summary"); 39 40 Some(result) 41 } 42 43 SteamOperation::GetSchemaForGame(id) => { 44 let result = refreshGameSchema(appData, id).await; 45 info!("[Steam API] Refreshed schema for app id {}", id); 46 47 Some(result) 48 } 49 50 SteamOperation::SaveToFile => { 51 match saveUserData_Steam(&appData.user.steam) 52 { 53 Err(e) => warn!("[Steam] Error saving user data: {:?}", e), 54 Ok(_) => info!("[Steam] Saved user data"), 55 } 56 57 None 58 } 59 60 SteamOperation::SetGameLoaded(id, loaded) => { 61 if let Some(game) = appData.user.steam.games.iter_mut() 62 .find(|g| g.id == id) 63 { 64 game.loaded = loaded; 65 } 66 67 Some(appData.into()) 68 } 69 }; 70 } 71 72 async fn refreshPlayerSummary(mut appData: AppData) -> DataOperationResult 73 { 74 let mut requests = vec![]; 75 if getSteamAuth().is_ok_and(|a| a.validate()) 76 { 77 let api = SteamApi::default(); 78 79 if let Ok(payload) = api.getPlayerSummaries().await 80 { 81 if let Some(profile) = payload.response.players.first() 82 { 83 appData.user.steam.update( 84 &profile.steamid, 85 &profile.personaname, 86 match profile.avatarhash.is_empty() 87 { 88 false => Some(&profile.avatarhash), 89 true => None, 90 } 91 ); 92 93 // Cache user avatar images 94 for i in 0..3 95 { 96 let (avatarDestination, avatarUrl) = SteamApi::constructProfileAvatarMetadata( 97 appData.user.steam.id.clone(), 98 appData.user.steam.avatar.clone().unwrap_or_default(), 99 i 100 ); 101 102 requests.push(DataRequest 103 { 104 destination: Some(avatarDestination), 105 operation: DataOperation::CacheImage, 106 url: Some(avatarUrl), 107 }); 108 } 109 } 110 } 111 } 112 113 return DataOperationResult 114 { 115 appData, 116 requests, 117 }; 118 } 119 120 async fn refreshGameList(mut appData: AppData) -> DataOperationResult 121 { 122 let mut requests = vec![]; 123 if getSteamAuth().is_ok_and(|a| a.validate()) 124 { 125 let api = SteamApi::default(); 126 if let Ok(payload) = api.getOwnedGames().await 127 { 128 appData.user.steam.processOwnedGames(payload); 129 130 // Cache game icons 131 let platform = SteamApi::Platform.to_string(); 132 let fileName = jpg!(FileName_GameIcon); 133 134 for game in appData.user.steam.games.iter() 135 { 136 let destination = FileLocation 137 { 138 fileName: fileName.clone(), 139 group: join!(Path_Games, game.id), 140 platform: platform.clone(), 141 }; 142 143 let url = SteamApi::constructGameIconUrl(game.id, &game.iconHash); 144 145 requests.push(DataRequest 146 { 147 destination: Some(destination), 148 operation: DataOperation::CacheImage, 149 url: Some(url) 150 }); 151 } 152 } 153 } 154 155 return DataOperationResult 156 { 157 appData, 158 requests, 159 }; 160 } 161 162 /* 163 if let Ok(payload) = api.getRecentlyPlayedGames().await 164 { 165 if !payload.response.games.is_empty() 166 { 167 // Good for play time in past 2 weeks 168 // Will require update to the Game struct 169 // Should Option<> and only titles returned from this have a value 170 // when processing from here, first step is to clear all existing values 171 } 172 } 173 */ 174 175 async fn refreshGameSchema(mut appData: AppData, id: u64) -> DataOperationResult 176 { 177 let mut requests = vec![]; 178 if getSteamAuth().is_ok_and(|a| a.validate()) 179 { 180 let api = SteamApi::default(); 181 if let Ok(payload) = api.getSchemaForGame(id, &appData.app.settings.language).await 182 { 183 if let Some(game) = appData.user.steam.games.iter_mut() 184 .find(|g| g.id == id) 185 { 186 game.updateAchievementsMetadata(&payload); 187 } 188 189 // Cache achievement icons 190 if let Some(achievements) = payload.game.availableGameStats.achievements 191 { 192 let group = join!(Path_Games, id); 193 let platform = SteamApi::Platform.to_string(); 194 195 for achievement in achievements 196 { 197 //Unlocked 198 requests.push(DataRequest 199 { 200 destination: Some(FileLocation 201 { 202 fileName: jpg!(achievement.name), 203 group: group.clone(), 204 platform: platform.clone(), 205 }), 206 operation: DataOperation::CacheImage, 207 url: Some(achievement.icon), 208 }); 209 210 //Locked 211 requests.push(DataRequest 212 { 213 destination: Some(FileLocation 214 { 215 fileName: jpgAlt!(achievement.name, Icon_Locked), 216 group: group.clone(), 217 platform: platform.clone(), 218 }), 219 operation: DataOperation::CacheImage, 220 url: Some(achievement.icongray), 221 }); 222 } 223 } 224 } 225 } 226 227 return DataOperationResult 228 { 229 appData, 230 requests, 231 }; 232 } 233 234 async fn refreshGameAchievements(mut appData: AppData, id: u64) -> AppData 235 { 236 if getSteamAuth().is_ok_and(|a| a.validate()) 237 { 238 let api = SteamApi::default(); 239 if let Ok(payload) = api.getPlayerAchievements(id, &appData.app.settings.language).await 240 { 241 if let Some(game) = appData.user.steam.games.iter_mut() 242 .find(|g| g.id == id) 243 { 244 game.updateAchievementsState(&payload); 245 } 246 } 247 } 248 249 return appData; 250 } 251 252 async fn refreshGlobalPercentages(mut appData: AppData, id: u64) -> AppData 253 { 254 if getSteamAuth().is_ok_and(|a| a.validate()) 255 { 256 let api = SteamApi::default(); 257 if let Ok(payload) = api.getGlobalPercentages(id).await 258 { 259 if let Some(game) = appData.user.steam.games.iter_mut() 260 .find(|g| g.id == id) 261 { 262 game.updateGlobalPercentages(&payload); 263 } 264 } 265 } 266 267 return appData; 268 }