From 32d54e6bb298b51159797bead575d0997b9ebfe4 Mon Sep 17 00:00:00 2001 From: Lilly Jade Katrin Date: Sat, 7 Mar 2026 12:31:30 -0500 Subject: [PATCH] RetroAchievements - Abort load when spammed If a second load is called while a load is in progress, suggesting a disc change, abort the load and cancel. This primarily is used to block a load from the default disc on the Wii menu. --- Source/Core/Core/AchievementManager.cpp | 21 ++++++++++++++++----- Source/Core/Core/AchievementManager.h | 1 + 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/Source/Core/Core/AchievementManager.cpp b/Source/Core/Core/AchievementManager.cpp index cacad3f3d1..cfc1394bde 100644 --- a/Source/Core/Core/AchievementManager.cpp +++ b/Source/Core/Core/AchievementManager.cpp @@ -162,6 +162,13 @@ void AchievementManager::LoadGame(const DiscIO::Volume* volume) "Attempted to load game achievements without achievement client initialized."); return; } + if (m_load_async_handle) + { + WARN_LOG_FMT(ACHIEVEMENTS, "Attempted to load while load is in progress; aborting all loads."); + rc_client_abort_async(m_client, m_load_async_handle); + CloseGame(); + return; + } if (volume == nullptr) { WARN_LOG_FMT(ACHIEVEMENTS, "Software format unsupported by AchievementManager."); @@ -171,7 +178,7 @@ void AchievementManager::LoadGame(const DiscIO::Volume* volume) } else { - rc_client_begin_load_game(m_client, "", LoadGameCallback, NULL); + m_load_async_handle = rc_client_begin_load_game(m_client, "", LoadGameCallback, NULL); } return; } @@ -205,13 +212,14 @@ void AchievementManager::LoadGame(const DiscIO::Volume* volume) rc_hash_init_custom_filereader(&volume_reader); if (rc_client_get_game_info(m_client)) { - rc_client_begin_identify_and_change_media(m_client, "", NULL, 0, ChangeMediaCallback, NULL); + m_load_async_handle = + rc_client_begin_identify_and_change_media(m_client, "", NULL, 0, ChangeMediaCallback, NULL); } else { u32 console_id = FindConsoleID(volume->GetVolumeType()); - rc_client_begin_identify_and_load_game(m_client, console_id, "", NULL, 0, LoadGameCallback, - NULL); + m_load_async_handle = rc_client_begin_identify_and_load_game(m_client, console_id, "", NULL, 0, + LoadGameCallback, NULL); } } @@ -987,6 +995,7 @@ void AchievementManager::LoadGameCallback(int result, const char* error_message, { auto& instance = AchievementManager::GetInstance(); instance.m_loading_volume.reset(nullptr); + instance.m_load_async_handle = nullptr; if (result == RC_API_FAILURE) { WARN_LOG_FMT(ACHIEVEMENTS, "Load data request rejected for old Dolphin version."); @@ -1060,7 +1069,9 @@ void AchievementManager::LoadGameCallback(int result, const char* error_message, void AchievementManager::ChangeMediaCallback(int result, const char* error_message, rc_client_t* client, void* userdata) { - AchievementManager::GetInstance().m_loading_volume.reset(nullptr); + auto& instance = AchievementManager::GetInstance(); + instance.m_loading_volume.reset(nullptr); + instance.m_load_async_handle = nullptr; if (result == RC_OK) { return; diff --git a/Source/Core/Core/AchievementManager.h b/Source/Core/Core/AchievementManager.h index 2ab23a4368..2413787734 100644 --- a/Source/Core/Core/AchievementManager.h +++ b/Source/Core/Core/AchievementManager.h @@ -262,6 +262,7 @@ private: rc_client_t* m_client{}; std::atomic m_system{}; std::unique_ptr m_loading_volume; + rc_client_async_handle_t* m_load_async_handle = nullptr; Config::ConfigChangedCallbackID m_config_changed_callback_id; Badge m_default_player_badge; Badge m_default_game_badge;