From db44e10057893deb614fc67cd8c87515bae7d53f Mon Sep 17 00:00:00 2001 From: LillyJadeKatrin Date: Wed, 12 Apr 2023 21:43:07 -0400 Subject: [PATCH] Added FetchUnlockData to AchievementManager FetchUnlockData is an API call to RetroAchievements that downloads a list of achievement IDs for a game that the user has already unlocked and published to the site. It accepts a parameter for whether or not hardcore or softcore achievements are being requested, so that must be provided as well. Once it has the requested list on hand, it updates each achievement's status in the unlock map and will activate or deactivate achievements as necessary. --- Source/Core/Core/AchievementManager.cpp | 33 +++++++++++++++++++++++++ Source/Core/Core/AchievementManager.h | 2 ++ 2 files changed, 35 insertions(+) diff --git a/Source/Core/Core/AchievementManager.cpp b/Source/Core/Core/AchievementManager.cpp index 84329b1f10..e6b5df8bd9 100644 --- a/Source/Core/Core/AchievementManager.cpp +++ b/Source/Core/Core/AchievementManager.cpp @@ -215,6 +215,39 @@ AchievementManager::ResponseType AchievementManager::FetchGameData() rc_api_process_fetch_game_data_response); } +AchievementManager::ResponseType AchievementManager::FetchUnlockData(bool hardcore) +{ + rc_api_fetch_user_unlocks_response_t unlock_data{}; + std::string username = Config::Get(Config::RA_USERNAME); + std::string api_token = Config::Get(Config::RA_API_TOKEN); + rc_api_fetch_user_unlocks_request_t fetch_unlocks_request = {.username = username.c_str(), + .api_token = api_token.c_str(), + .game_id = m_game_id, + .hardcore = hardcore}; + ResponseType r_type = + Request( + fetch_unlocks_request, &unlock_data, rc_api_init_fetch_user_unlocks_request, + rc_api_process_fetch_user_unlocks_response); + if (r_type == ResponseType::SUCCESS) + { + std::lock_guard lg{m_lock}; + bool enabled = Config::Get(Config::RA_ACHIEVEMENTS_ENABLED); + bool unofficial = Config::Get(Config::RA_UNOFFICIAL_ENABLED); + bool encore = Config::Get(Config::RA_ENCORE_ENABLED); + for (AchievementId ix = 0; ix < unlock_data.num_achievement_ids; ix++) + { + auto it = m_unlock_map.find(unlock_data.achievement_ids[ix]); + if (it == m_unlock_map.end()) + continue; + it->second.remote_unlock_status = + hardcore ? UnlockStatus::UnlockType::HARDCORE : UnlockStatus::UnlockType::SOFTCORE; + ActivateDeactivateAchievement(unlock_data.achievement_ids[ix], enabled, unofficial, encore); + } + } + rc_api_destroy_fetch_user_unlocks_response(&unlock_data); + return r_type; +} + void AchievementManager::ActivateDeactivateAchievement(AchievementId id, bool enabled, bool unofficial, bool encore) { diff --git a/Source/Core/Core/AchievementManager.h b/Source/Core/Core/AchievementManager.h index 511a573d23..0e0c2668d9 100644 --- a/Source/Core/Core/AchievementManager.h +++ b/Source/Core/Core/AchievementManager.h @@ -52,6 +52,7 @@ private: ResponseType ResolveHash(std::array game_hash); ResponseType StartRASession(); ResponseType FetchGameData(); + ResponseType FetchUnlockData(bool hardcore); void ActivateDeactivateAchievement(AchievementId id, bool enabled, bool unofficial, bool encore); @@ -80,6 +81,7 @@ private: std::unordered_map m_unlock_map; Common::WorkQueueThread> m_queue; + std::recursive_mutex m_lock; }; // class AchievementManager #endif // USE_RETRO_ACHIEVEMENTS