From b05028da1f97ed55a21ac1f87077d003fa568efb Mon Sep 17 00:00:00 2001 From: LillyJadeKatrin Date: Tue, 2 Apr 2024 15:38:59 -0400 Subject: [PATCH] Added Change Media client functionality to AchievementMananger The client can handle media changes natively so disabling can take place internally. This code uses the same external calls to load data, but will call either BeginLoad or BeginChangeMedia based on whether any media is already loaded. Due to the client's handling of media changes (it simply disables hardcore if an unknown media is detected) the existing functionality for "disabling" the achievements is no longer necessary and can be deleted. --- Source/Core/Core/AchievementManager.cpp | 65 ++++++++----------- Source/Core/Core/AchievementManager.h | 5 +- Source/Core/Core/BootManager.cpp | 2 +- Source/Core/Core/ConfigManager.cpp | 2 +- Source/Core/Core/Core.cpp | 1 - Source/Core/Core/IOS/ES/ES.cpp | 2 +- .../Achievements/AchievementHeaderWidget.cpp | 8 --- .../Achievements/AchievementHeaderWidget.h | 1 - 8 files changed, 33 insertions(+), 53 deletions(-) diff --git a/Source/Core/Core/AchievementManager.cpp b/Source/Core/Core/AchievementManager.cpp index ab6482f13c..350a591389 100644 --- a/Source/Core/Core/AchievementManager.cpp +++ b/Source/Core/Core/AchievementManager.cpp @@ -110,13 +110,6 @@ void AchievementManager::LoadGame(const std::string& file_path, const DiscIO::Vo "Attempted to load game achievements without achievement client initialized."); return; } - if (m_disabled) - { - INFO_LOG_FMT(ACHIEVEMENTS, "Achievement Manager is disabled until core is rebooted."); - OSD::AddMessage("Achievements are disabled until you restart emulation.", - OSD::Duration::VERY_LONG, OSD::Color::RED); - return; - } if (volume) { std::lock_guard lg{m_lock}; @@ -135,8 +128,15 @@ void AchievementManager::LoadGame(const std::string& file_path, const DiscIO::Vo .close = &AchievementManager::FilereaderClose, }; rc_hash_init_custom_filereader(&volume_reader); - rc_client_begin_identify_and_load_game(m_client, RC_CONSOLE_GAMECUBE, file_path.c_str(), NULL, 0, - LoadGameCallback, NULL); + if (rc_client_get_game_info(m_client)) + { + rc_client_begin_change_media(m_client, file_path.c_str(), NULL, 0, ChangeMediaCallback, NULL); + } + else + { + rc_client_begin_identify_and_load_game(m_client, RC_CONSOLE_GAMECUBE, file_path.c_str(), NULL, + 0, LoadGameCallback, NULL); + } } bool AchievementManager::IsGameLoaded() const @@ -324,32 +324,6 @@ AchievementManager::RichPresence AchievementManager::GetRichPresence() const return m_rich_presence; } -void AchievementManager::SetDisabled(bool disable) -{ - bool previously_disabled; - { - std::lock_guard lg{m_lock}; - previously_disabled = m_disabled; - m_disabled = disable; - if (disable && m_is_game_loaded) - CloseGame(); - } - - if (!previously_disabled && disable && Config::Get(Config::RA_ENABLED)) - { - INFO_LOG_FMT(ACHIEVEMENTS, "Achievement Manager has been disabled."); - OSD::AddMessage("Please close all games to re-enable achievements.", OSD::Duration::VERY_LONG, - OSD::Color::RED); - m_update_callback(UpdatedItems{.all = true}); - } - - if (previously_disabled && !disable) - { - INFO_LOG_FMT(ACHIEVEMENTS, "Achievement Manager has been re-enabled."); - m_update_callback(UpdatedItems{.all = true}); - } -}; - const AchievementManager::NamedIconMap& AchievementManager::GetChallengeIcons() const { return m_active_challenges; @@ -435,7 +409,6 @@ void AchievementManager::Logout() { std::lock_guard lg{m_lock}; CloseGame(); - SetDisabled(false); m_player_badge.name.clear(); Config::SetBaseOrCurrent(Config::RA_API_TOKEN, ""); } @@ -449,7 +422,6 @@ void AchievementManager::Shutdown() if (m_client) { CloseGame(); - SetDisabled(false); m_queue.Shutdown(); // DON'T log out - keep those credentials for next run. rc_client_destroy(m_client); @@ -628,6 +600,25 @@ void AchievementManager::LoadGameCallback(int result, const char* error_message, std::chrono::steady_clock::now() - std::chrono::minutes{2}; } +void AchievementManager::ChangeMediaCallback(int result, const char* error_message, + rc_client_t* client, void* userdata) +{ + if (result == RC_OK) + return; + + if (result == RC_HARDCORE_DISABLED) + { + WARN_LOG_FMT(ACHIEVEMENTS, "Hardcore disabled. Unrecognized media inserted."); + } + else + { + if (!error_message) + error_message = rc_error_str(result); + + ERROR_LOG_FMT(ACHIEVEMENTS, "RetroAchievements media change failed: {}", error_message); + } +} + void AchievementManager::DisplayWelcomeMessage() { std::lock_guard lg{m_lock}; diff --git a/Source/Core/Core/AchievementManager.h b/Source/Core/Core/AchievementManager.h index e814f1a32b..289cb4158f 100644 --- a/Source/Core/Core/AchievementManager.h +++ b/Source/Core/Core/AchievementManager.h @@ -114,8 +114,6 @@ public: const BadgeStatus& GetAchievementBadge(AchievementId id, bool locked) const; const LeaderboardStatus* GetLeaderboardInfo(AchievementId leaderboard_id); RichPresence GetRichPresence() const; - bool IsDisabled() const { return m_disabled; }; - void SetDisabled(bool disabled); const NamedIconMap& GetChallengeIcons() const; std::vector GetActiveLeaderboards() const; @@ -152,6 +150,8 @@ private: static void LoadGameCallback(int result, const char* error_message, rc_client_t* client, void* userdata); + static void ChangeMediaCallback(int result, const char* error_message, rc_client_t* client, + void* userdata); void DisplayWelcomeMessage(); static void LeaderboardEntriesCallback(int result, const char* error_message, @@ -183,7 +183,6 @@ private: bool m_is_runtime_initialized = false; UpdateCallback m_update_callback = [](const UpdatedItems&) {}; std::unique_ptr m_loading_volume; - bool m_disabled = false; BadgeStatus m_player_badge; Hash m_game_hash{}; u32 m_game_id = 0; diff --git a/Source/Core/Core/BootManager.cpp b/Source/Core/Core/BootManager.cpp index 9e9fb3b58c..6f7681fd30 100644 --- a/Source/Core/Core/BootManager.cpp +++ b/Source/Core/Core/BootManager.cpp @@ -167,7 +167,7 @@ bool BootCore(Core::System& system, std::unique_ptr boot, } #ifdef USE_RETRO_ACHIEVEMENTS - AchievementManager::GetInstance().SetDisabled(false); + AchievementManager::GetInstance().CloseGame(); #endif // USE_RETRO_ACHIEVEMENTS const bool load_ipl = !system.IsWii() && !Config::Get(Config::MAIN_SKIP_IPL) && diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp index 4adb0a240b..c8f86ef70c 100644 --- a/Source/Core/Core/ConfigManager.cpp +++ b/Source/Core/Core/ConfigManager.cpp @@ -171,7 +171,7 @@ void SConfig::SetRunningGameMetadata(const std::string& game_id, const std::stri #ifdef USE_RETRO_ACHIEVEMENTS if (game_id != "00000000") - AchievementManager::GetInstance().SetDisabled(true); + AchievementManager::GetInstance().CloseGame(); #endif // USE_RETRO_ACHIEVEMENTS if (game_id == "00000000") diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index 0dc3db14ce..0498d1ba36 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -290,7 +290,6 @@ void Stop(Core::System& system) // - Hammertime! #ifdef USE_RETRO_ACHIEVEMENTS AchievementManager::GetInstance().CloseGame(); - AchievementManager::GetInstance().SetDisabled(false); #endif // USE_RETRO_ACHIEVEMENTS s_is_stopping = true; diff --git a/Source/Core/Core/IOS/ES/ES.cpp b/Source/Core/Core/IOS/ES/ES.cpp index 216821cfbd..8eb35f3db9 100644 --- a/Source/Core/Core/IOS/ES/ES.cpp +++ b/Source/Core/Core/IOS/ES/ES.cpp @@ -481,7 +481,7 @@ bool ESDevice::LaunchPPCTitle(u64 title_id) #ifdef USE_RETRO_ACHIEVEMENTS INFO_LOG_FMT(ACHIEVEMENTS, "WAD and NAND formats not currently supported by Achievement Manager."); - AchievementManager::GetInstance().SetDisabled(true); + AchievementManager::GetInstance().CloseGame(); #endif // USE_RETRO_ACHIEVEMENTS core_timing.RemoveEvent(s_bootstrap_ppc_for_launch_event); diff --git a/Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp b/Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp index a1a0a1d7c0..6da62b478b 100644 --- a/Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp +++ b/Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp @@ -28,11 +28,6 @@ AchievementHeaderWidget::AchievementHeaderWidget(QWidget* parent) : QWidget(pare m_points = new QLabel(); m_game_progress = new QProgressBar(); m_rich_presence = new QLabel(); - m_locked_warning = new QLabel(); - - m_locked_warning->setText(tr("Achievements have been disabled.
Please close all running " - "games to re-enable achievements.")); - m_locked_warning->setStyleSheet(QStringLiteral("QLabel { color : red; }")); QSizePolicy sp_retain = m_game_progress->sizePolicy(); sp_retain.setRetainSizeWhenHidden(true); @@ -46,7 +41,6 @@ AchievementHeaderWidget::AchievementHeaderWidget(QWidget* parent) : QWidget(pare text_col->addWidget(m_points); text_col->addWidget(m_game_progress); text_col->addWidget(m_rich_presence); - text_col->addWidget(m_locked_warning); QHBoxLayout* header_layout = new QHBoxLayout(); header_layout->addLayout(icon_col); header_layout->addLayout(text_col); @@ -135,7 +129,6 @@ void AchievementHeaderWidget::UpdateData() m_rich_presence->setText(QString::fromUtf8(instance.GetRichPresence().data())); if (!m_rich_presence->isVisible()) m_rich_presence->setVisible(Config::Get(Config::RA_RICH_PRESENCE_ENABLED)); - m_locked_warning->setVisible(false); } else { @@ -144,7 +137,6 @@ void AchievementHeaderWidget::UpdateData() m_game_progress->setVisible(false); m_rich_presence->setVisible(false); - m_locked_warning->setVisible(instance.IsDisabled()); } } diff --git a/Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.h b/Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.h index b246e9dbad..0964ef488f 100644 --- a/Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.h +++ b/Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.h @@ -26,7 +26,6 @@ private: QLabel* m_points; QProgressBar* m_game_progress; QLabel* m_rich_presence; - QLabel* m_locked_warning; QGroupBox* m_header_box; };