summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorLillyJadeKatrin <lilly.kitty.1988@gmail.com>2024-03-30 18:04:00 -0400
committerLillyJadeKatrin <lilly.kitty.1988@gmail.com>2024-05-01 06:43:19 -0400
commitbc3e429dd92b130cd1476b8fce4a04cd1a08bb26 (patch)
tree45603337c9e18208e30de5a788e4e2c29171e3b9 /Source/Core
parentc88d4cf0403e36caf17008ea3c1e11b7d8d6732a (diff)
Handle Achievement Triggered Client Event
Also deletes the old runtime-based Achievement Triggered event from the old handler, and the methods used by it to publish to the server and reactivate/deactivate achievements in the runtime.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/AchievementManager.cpp153
-rw-r--r--Source/Core/Core/AchievementManager.h5
2 files changed, 26 insertions, 132 deletions
diff --git a/Source/Core/Core/AchievementManager.cpp b/Source/Core/Core/AchievementManager.cpp
index 6a34350cb2..1a8a7479d5 100644
--- a/Source/Core/Core/AchievementManager.cpp
+++ b/Source/Core/Core/AchievementManager.cpp
@@ -234,9 +234,6 @@ void AchievementManager::AchievementEventHandler(const rc_runtime_event_t* runti
{
switch (runtime_event->type)
{
- case RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED:
- HandleAchievementTriggeredEvent(runtime_event);
- break;
case RC_RUNTIME_EVENT_ACHIEVEMENT_PROGRESS_UPDATED:
HandleAchievementProgressUpdatedEvent(runtime_event);
break;
@@ -665,56 +662,6 @@ AchievementManager::ResponseType AchievementManager::FetchBoardInfo(AchievementI
return ResponseType::SUCCESS;
}
-void AchievementManager::ActivateDeactivateAchievement(AchievementId id, bool enabled,
- bool unofficial, bool encore)
-{
- auto it = m_unlock_map.find(id);
- if (it == m_unlock_map.end())
- {
- ERROR_LOG_FMT(ACHIEVEMENTS, "Attempted to unlock unknown achievement id {}.", id);
- return;
- }
- const UnlockStatus& status = it->second;
- u32 index = status.game_data_index;
- bool active = (rc_runtime_get_achievement(&m_runtime, id) != nullptr);
- bool hardcore_mode_enabled = Config::Get(Config::RA_HARDCORE_ENABLED);
-
- // Deactivate achievements if game is not loaded
- bool activate = m_is_game_loaded;
- // Activate achievements only if achievements are enabled
- if (activate && !enabled)
- activate = false;
- // Deactivate if achievement is unofficial, unless unofficial achievements are enabled
- if (activate && !unofficial &&
- m_game_data.achievements[index].category == RC_ACHIEVEMENT_CATEGORY_UNOFFICIAL)
- {
- activate = false;
- }
- // If encore mode is on, activate/deactivate regardless of current unlock status
- if (activate && !encore)
- {
- // Encore is off, achievement has been unlocked in this session, deactivate
- activate = (status.session_unlock_count == 0);
- // Encore is off, achievement has been hardcore unlocked on site, deactivate
- if (activate && status.remote_unlock_status == UnlockStatus::UnlockType::HARDCORE)
- activate = false;
- // Encore is off, hardcore is off, achievement has been softcore unlocked on site, deactivate
- if (activate && !hardcore_mode_enabled &&
- status.remote_unlock_status == UnlockStatus::UnlockType::SOFTCORE)
- {
- activate = false;
- }
- }
-
- if (!active && activate)
- {
- rc_runtime_activate_achievement(&m_runtime, id, m_game_data.achievements[index].definition,
- nullptr, 0);
- }
- if (active && !activate)
- rc_runtime_deactivate_achievement(&m_runtime, id);
-}
-
void AchievementManager::GenerateRichPresence(const Core::CPUThreadGuard& guard)
{
std::lock_guard lg{m_lock};
@@ -723,33 +670,6 @@ void AchievementManager::GenerateRichPresence(const Core::CPUThreadGuard& guard)
[](unsigned address, unsigned num_bytes, void* ud) { return 0u; }, this, nullptr);
}
-AchievementManager::ResponseType AchievementManager::AwardAchievement(AchievementId achievement_id)
-{
- std::string username = Config::Get(Config::RA_USERNAME);
- std::string api_token = Config::Get(Config::RA_API_TOKEN);
- bool hardcore_mode_enabled = Config::Get(Config::RA_HARDCORE_ENABLED);
- rc_api_award_achievement_request_t award_request = {.username = username.c_str(),
- .api_token = api_token.c_str(),
- .achievement_id = achievement_id,
- .hardcore = hardcore_mode_enabled,
- .game_hash = m_game_hash.data()};
- rc_api_award_achievement_response_t award_response = {};
- ResponseType r_type =
- Request<rc_api_award_achievement_request_t, rc_api_award_achievement_response_t>(
- award_request, &award_response, rc_api_init_award_achievement_request,
- rc_api_process_award_achievement_response);
- rc_api_destroy_award_achievement_response(&award_response);
- if (r_type == ResponseType::SUCCESS)
- {
- INFO_LOG_FMT(ACHIEVEMENTS, "Awarded achievement ID {}.", achievement_id);
- }
- else
- {
- WARN_LOG_FMT(ACHIEVEMENTS, "Failed to award achievement ID {}.", achievement_id);
- }
- return r_type;
-}
-
AchievementManager::ResponseType AchievementManager::SubmitLeaderboard(AchievementId leaderboard_id,
int value)
{
@@ -851,55 +771,6 @@ void AchievementManager::DisplayWelcomeMessage()
OSD::Duration::VERY_LONG, color);
}
-void AchievementManager::HandleAchievementTriggeredEvent(const rc_runtime_event_t* runtime_event)
-{
- bool hardcore_mode_enabled = Config::Get(Config::RA_HARDCORE_ENABLED);
- const auto event_id = runtime_event->id;
- auto it = m_unlock_map.find(event_id);
- if (it == m_unlock_map.end())
- {
- ERROR_LOG_FMT(ACHIEVEMENTS, "Invalid achievement triggered event with id {}.", event_id);
- return;
- }
- it->second.session_unlock_count++;
- AchievementId game_data_index = it->second.game_data_index;
- OSD::AddMessage(fmt::format("Unlocked: {} ({})", m_game_data.achievements[game_data_index].title,
- m_game_data.achievements[game_data_index].points),
- OSD::Duration::VERY_LONG,
- (hardcore_mode_enabled) ? OSD::Color::YELLOW : OSD::Color::CYAN,
- (Config::Get(Config::RA_BADGES_ENABLED)) ?
- DecodeBadgeToOSDIcon(it->second.unlocked_badge.badge) :
- nullptr);
- if (m_game_data.achievements[game_data_index].category == RC_ACHIEVEMENT_CATEGORY_CORE)
- {
- auto* user = rc_client_get_user_info(m_client);
- m_queue.EmplaceItem([this, event_id] { AwardAchievement(event_id); });
- PointSpread spread = TallyScore();
- if (spread.hard_points == spread.total_points &&
- it->second.remote_unlock_status != UnlockStatus::UnlockType::HARDCORE)
- {
- OSD::AddMessage(
- fmt::format("Congratulations! {} has mastered {}", user->display_name, m_game_data.title),
- OSD::Duration::VERY_LONG, OSD::Color::YELLOW,
- (Config::Get(Config::RA_BADGES_ENABLED)) ? DecodeBadgeToOSDIcon(m_game_badge.badge) :
- nullptr);
- }
- else if (spread.hard_points + spread.soft_points == spread.total_points &&
- it->second.remote_unlock_status == UnlockStatus::UnlockType::LOCKED)
- {
- OSD::AddMessage(fmt::format("Congratulations! {} has completed {}", user->display_name,
- m_game_data.title),
- OSD::Duration::VERY_LONG, OSD::Color::CYAN,
- (Config::Get(Config::RA_BADGES_ENABLED)) ?
- DecodeBadgeToOSDIcon(m_game_badge.badge) :
- nullptr);
- }
- }
- ActivateDeactivateAchievement(event_id, Config::Get(Config::RA_ACHIEVEMENTS_ENABLED),
- Config::Get(Config::RA_UNOFFICIAL_ENABLED),
- Config::Get(Config::RA_ENCORE_ENABLED));
-}
-
void AchievementManager::HandleAchievementProgressUpdatedEvent(
const rc_runtime_event_t* runtime_event)
{
@@ -1019,6 +890,21 @@ void AchievementManager::HandleLeaderboardTriggeredEvent(const rc_runtime_event_
ERROR_LOG_FMT(ACHIEVEMENTS, "Invalid leaderboard triggered event with id {}.", event_id);
}
+void AchievementManager::HandleAchievementTriggeredEvent(const rc_client_event_t* client_event)
+{
+ OSD::AddMessage(fmt::format("Unlocked: {} ({})", client_event->achievement->title,
+ client_event->achievement->points),
+ OSD::Duration::VERY_LONG,
+ (rc_client_get_hardcore_enabled(AchievementManager::GetInstance().m_client)) ?
+ OSD::Color::YELLOW :
+ OSD::Color::CYAN,
+ (Config::Get(Config::RA_BADGES_ENABLED)) ?
+ DecodeBadgeToOSDIcon(AchievementManager::GetInstance()
+ .m_unlocked_badges[client_event->achievement->id]
+ .badge) :
+ nullptr);
+}
+
// 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
@@ -1201,6 +1087,15 @@ void AchievementManager::FetchBadge(AchievementManager::BadgeStatus* badge, u32
void AchievementManager::EventHandlerV2(const rc_client_event_t* event, rc_client_t* client)
{
+ switch (event->type)
+ {
+ case RC_CLIENT_EVENT_ACHIEVEMENT_TRIGGERED:
+ HandleAchievementTriggeredEvent(event);
+ break;
+ default:
+ INFO_LOG_FMT(ACHIEVEMENTS, "Event triggered of unhandled type {}", event->type);
+ break;
+ }
}
#endif // USE_RETRO_ACHIEVEMENTS
diff --git a/Source/Core/Core/AchievementManager.h b/Source/Core/Core/AchievementManager.h
index 89ebb2bc1b..94f40eb173 100644
--- a/Source/Core/Core/AchievementManager.h
+++ b/Source/Core/Core/AchievementManager.h
@@ -174,10 +174,8 @@ private:
std::unique_ptr<DiscIO::Volume>& GetLoadingVolume() { return m_loading_volume; };
- void ActivateDeactivateAchievement(AchievementId id, bool enabled, bool unofficial, bool encore);
void GenerateRichPresence(const Core::CPUThreadGuard& guard);
- ResponseType AwardAchievement(AchievementId achievement_id);
ResponseType SubmitLeaderboard(AchievementId leaderboard_id, int value);
ResponseType PingRichPresence(const RichPresence& rich_presence);
@@ -185,7 +183,6 @@ private:
void* userdata);
void DisplayWelcomeMessage();
- void HandleAchievementTriggeredEvent(const rc_runtime_event_t* runtime_event);
void HandleAchievementProgressUpdatedEvent(const rc_runtime_event_t* runtime_event);
void HandleAchievementPrimedEvent(const rc_runtime_event_t* runtime_event);
void HandleAchievementUnprimedEvent(const rc_runtime_event_t* runtime_event);
@@ -193,6 +190,8 @@ private:
void HandleLeaderboardCanceledEvent(const rc_runtime_event_t* runtime_event);
void HandleLeaderboardTriggeredEvent(const rc_runtime_event_t* runtime_event);
+ static void HandleAchievementTriggeredEvent(const rc_client_event_t* client_event);
+
template <typename RcRequest, typename RcResponse>
ResponseType Request(RcRequest rc_request, RcResponse* rc_response,
const std::function<int(rc_api_request_t*, const RcRequest*)>& init_request,