diff --git a/Source/Core/Core/AchievementManager.cpp b/Source/Core/Core/AchievementManager.cpp index d9987015e1..f3e4b41ba6 100644 --- a/Source/Core/Core/AchievementManager.cpp +++ b/Source/Core/Core/AchievementManager.cpp @@ -402,6 +402,16 @@ const AchievementManager::NamedIconMap& AchievementManager::GetChallengeIcons() return m_active_challenges; } +std::vector AchievementManager::GetActiveLeaderboards() const +{ + std::vector display_values; + for (u32 ix = 0; ix < MAX_DISPLAYED_LBOARDS && ix < m_active_leaderboards.size(); ix++) + { + display_values.push_back(std::string(m_active_leaderboards[ix].display)); + } + return display_values; +} + void AchievementManager::CloseGame() { { @@ -409,6 +419,7 @@ void AchievementManager::CloseGame() if (rc_client_get_game_info(m_client)) { m_active_challenges.clear(); + m_active_leaderboards.clear(); m_game_badge.name.clear(); m_unlocked_badges.clear(); m_locked_badges.clear(); @@ -827,6 +838,33 @@ void AchievementManager::HandleLeaderboardSubmittedEvent(const rc_client_event_t OSD::Duration::VERY_LONG, OSD::Color::YELLOW); } +void AchievementManager::HandleLeaderboardTrackerUpdateEvent(const rc_client_event_t* client_event) +{ + auto& active_leaderboards = AchievementManager::GetInstance().m_active_leaderboards; + for (auto& leaderboard : active_leaderboards) + { + if (leaderboard.id == client_event->leaderboard_tracker->id) + { + strncpy(leaderboard.display, client_event->leaderboard_tracker->display, + RC_CLIENT_LEADERBOARD_DISPLAY_SIZE); + } + } +} + +void AchievementManager::HandleLeaderboardTrackerShowEvent(const rc_client_event_t* client_event) +{ + AchievementManager::GetInstance().m_active_leaderboards.push_back( + *client_event->leaderboard_tracker); +} + +void AchievementManager::HandleLeaderboardTrackerHideEvent(const rc_client_event_t* client_event) +{ + auto& active_leaderboards = AchievementManager::GetInstance().m_active_leaderboards; + std::erase_if(active_leaderboards, [client_event](const auto& leaderboard) { + return leaderboard.id == client_event->leaderboard_tracker->id; + }); +} + // Every RetroAchievements API call, with only a partial exception for fetch_image, follows // the same design pattern (here, X is the name of the call): // Create a specific rc_api_X_request_t struct and populate with the necessary values @@ -1023,6 +1061,15 @@ void AchievementManager::EventHandlerV2(const rc_client_event_t* event, rc_clien case RC_CLIENT_EVENT_LEADERBOARD_SUBMITTED: HandleLeaderboardSubmittedEvent(event); break; + case RC_CLIENT_EVENT_LEADERBOARD_TRACKER_UPDATE: + HandleLeaderboardTrackerUpdateEvent(event); + break; + case RC_CLIENT_EVENT_LEADERBOARD_TRACKER_SHOW: + HandleLeaderboardTrackerShowEvent(event); + break; + case RC_CLIENT_EVENT_LEADERBOARD_TRACKER_HIDE: + HandleLeaderboardTrackerHideEvent(event); + break; default: INFO_LOG_FMT(ACHIEVEMENTS, "Event triggered of unhandled type {}", event->type); break; diff --git a/Source/Core/Core/AchievementManager.h b/Source/Core/Core/AchievementManager.h index acc87fcdb2..a833de0be9 100644 --- a/Source/Core/Core/AchievementManager.h +++ b/Source/Core/Core/AchievementManager.h @@ -73,6 +73,7 @@ public: using RichPresence = std::array; using Badge = std::vector; using NamedIconMap = std::map, std::less<>>; + static constexpr size_t MAX_DISPLAYED_LBOARDS = 4; struct BadgeStatus { @@ -146,6 +147,7 @@ public: bool IsDisabled() const { return m_disabled; }; void SetDisabled(bool disabled); const NamedIconMap& GetChallengeIcons() const; + std::vector GetActiveLeaderboards() const; void CloseGame(); void Logout(); @@ -190,6 +192,9 @@ private: static void HandleLeaderboardStartedEvent(const rc_client_event_t* client_event); static void HandleLeaderboardFailedEvent(const rc_client_event_t* client_event); static void HandleLeaderboardSubmittedEvent(const rc_client_event_t* client_event); + static void HandleLeaderboardTrackerUpdateEvent(const rc_client_event_t* client_event); + static void HandleLeaderboardTrackerShowEvent(const rc_client_event_t* client_event); + static void HandleLeaderboardTrackerHideEvent(const rc_client_event_t* client_event); template ResponseType Request(RcRequest rc_request, RcResponse* rc_response, @@ -224,6 +229,7 @@ private: std::unordered_map m_unlock_map; std::unordered_map m_leaderboard_map; NamedIconMap m_active_challenges; + std::vector m_active_leaderboards; Common::WorkQueueThread> m_queue; Common::WorkQueueThread> m_image_queue;