Achievements: Defer login/game identify until after RAIntegration load

This commit is contained in:
Stenzek 2025-04-23 21:56:14 +10:00
parent 50e99dd1ff
commit 559f831c30
No known key found for this signature in database

View File

@ -141,7 +141,9 @@ static bool HasSavedCredentials();
static bool TryLoggingInWithToken(); static bool TryLoggingInWithToken();
static void EnableHardcodeMode(bool display_message, bool display_game_summary); static void EnableHardcodeMode(bool display_message, bool display_game_summary);
static void OnHardcoreModeChanged(bool enabled, bool display_message, bool display_game_summary); static void OnHardcoreModeChanged(bool enabled, bool display_message, bool display_game_summary);
static bool IsRAIntegrationInitializing();
static bool IsLoggedInOrLoggingIn(); static bool IsLoggedInOrLoggingIn();
static void FinishInitialize();
static void FinishLogin(const rc_client_t* client); static void FinishLogin(const rc_client_t* client);
static void ShowLoginNotification(); static void ShowLoginNotification();
static bool IdentifyGame(CDImage* image); static bool IdentifyGame(CDImage* image);
@ -299,6 +301,7 @@ struct State
#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION #ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION
rc_client_async_handle_t* load_raintegration_request = nullptr; rc_client_async_handle_t* load_raintegration_request = nullptr;
bool using_raintegration = false; bool using_raintegration = false;
bool raintegration_loading = false;
#endif #endif
}; };
@ -658,6 +661,15 @@ bool Achievements::Initialize()
rc_client_set_unofficial_enabled(s_state.client, g_settings.achievements_unofficial_test_mode); rc_client_set_unofficial_enabled(s_state.client, g_settings.achievements_unofficial_test_mode);
rc_client_set_spectator_mode_enabled(s_state.client, g_settings.achievements_spectator_mode); rc_client_set_spectator_mode_enabled(s_state.client, g_settings.achievements_spectator_mode);
// We can't do an internal client login while using RAIntegration, since the two will conflict.
if (!IsRAIntegrationInitializing())
FinishInitialize();
return true;
}
void Achievements::FinishInitialize()
{
// Start logging in. This can take a while. // Start logging in. This can take a while.
TryLoggingInWithToken(); TryLoggingInWithToken();
@ -671,8 +683,6 @@ bool Achievements::Initialize()
if (IsLoggedInOrLoggingIn() && g_settings.achievements_hardcore_mode) if (IsLoggedInOrLoggingIn() && g_settings.achievements_hardcore_mode)
DisplayHardcoreDeferredMessage(); DisplayHardcoreDeferredMessage();
} }
return true;
} }
bool Achievements::CreateClient(rc_client_t** client, std::unique_ptr<HTTPDownloader>* http) bool Achievements::CreateClient(rc_client_t** client, std::unique_ptr<HTTPDownloader>* http)
@ -1138,7 +1148,7 @@ void Achievements::OnSystemStarting(CDImage* image, bool disable_hardcore_mode)
{ {
std::unique_lock lock(s_state.mutex); std::unique_lock lock(s_state.mutex);
if (!IsActive()) if (!IsActive() || IsRAIntegrationInitializing())
return; return;
// if we're not logged in, and there's no login request, retry logging in // if we're not logged in, and there's no login request, retry logging in
@ -1179,7 +1189,7 @@ void Achievements::OnSystemDestroyed()
void Achievements::OnSystemReset() void Achievements::OnSystemReset()
{ {
const auto lock = GetLock(); const auto lock = GetLock();
if (!IsActive()) if (!IsActive()|| IsRAIntegrationInitializing())
return; return;
// Do we need to enable hardcore mode? // Do we need to enable hardcore mode?
@ -1198,7 +1208,7 @@ void Achievements::GameChanged(CDImage* image)
{ {
std::unique_lock lock(s_state.mutex); std::unique_lock lock(s_state.mutex);
if (!IsActive()) if (!IsActive()|| IsRAIntegrationInitializing())
return; return;
// disc changed? // disc changed?
@ -4616,6 +4626,7 @@ const Achievements::ProgressDatabase::Entry* Achievements::ProgressDatabase::Loo
namespace Achievements { namespace Achievements {
static void FinishLoadRAIntegration(); static void FinishLoadRAIntegration();
static void FinishLoadRAIntegrationOnCPUThread();
static void RAIntegrationBeginLoadCallback(int result, const char* error_message, rc_client_t* client, void* userdata); static void RAIntegrationBeginLoadCallback(int result, const char* error_message, rc_client_t* client, void* userdata);
static void RAIntegrationEventHandler(const rc_client_raintegration_event_t* event, rc_client_t* client); static void RAIntegrationEventHandler(const rc_client_raintegration_event_t* event, rc_client_t* client);
@ -4636,8 +4647,17 @@ bool Achievements::IsRAIntegrationAvailable()
FileSystem::FileExists(Path::Combine(EmuFolders::AppRoot, "RA_Integration.dll").c_str())); FileSystem::FileExists(Path::Combine(EmuFolders::AppRoot, "RA_Integration.dll").c_str()));
} }
bool Achievements::IsRAIntegrationInitializing()
{
return (s_state.using_raintegration && (s_state.load_raintegration_request || s_state.raintegration_loading));
}
void Achievements::BeginLoadRAIntegration() void Achievements::BeginLoadRAIntegration()
{ {
// set the flag so we don't try to log in immediately, need to wait for RAIntegration to load first
s_state.using_raintegration = true;
s_state.raintegration_loading = true;
const std::wstring wapproot = StringUtil::UTF8StringToWideString(EmuFolders::AppRoot); const std::wstring wapproot = StringUtil::UTF8StringToWideString(EmuFolders::AppRoot);
s_state.load_raintegration_request = rc_client_begin_load_raintegration_deferred( s_state.load_raintegration_request = rc_client_begin_load_raintegration_deferred(
s_state.client, wapproot.c_str(), RAIntegrationBeginLoadCallback, nullptr); s_state.client, wapproot.c_str(), RAIntegrationBeginLoadCallback, nullptr);
@ -4646,16 +4666,17 @@ void Achievements::BeginLoadRAIntegration()
void Achievements::RAIntegrationBeginLoadCallback(int result, const char* error_message, rc_client_t* client, void Achievements::RAIntegrationBeginLoadCallback(int result, const char* error_message, rc_client_t* client,
void* userdata) void* userdata)
{ {
s_state.load_raintegration_request = nullptr;
if (result != RC_OK) if (result != RC_OK)
{ {
s_state.raintegration_loading = false;
std::string message = fmt::format("Failed to load RAIntegration:\n{}", error_message ? error_message : ""); std::string message = fmt::format("Failed to load RAIntegration:\n{}", error_message ? error_message : "");
Host::ReportErrorAsync("RAIntegration Error", message); Host::ReportErrorAsync("RAIntegration Error", message);
return; return;
} }
// set this so we can unload it if the request changes
s_state.using_raintegration = true;
INFO_COLOR_LOG(StrongGreen, "RAIntegration DLL loaded, initializing."); INFO_COLOR_LOG(StrongGreen, "RAIntegration DLL loaded, initializing.");
Host::RunOnUIThread(&Achievements::FinishLoadRAIntegration); Host::RunOnUIThread(&Achievements::FinishLoadRAIntegration);
} }
@ -4679,6 +4700,7 @@ void Achievements::FinishLoadRAIntegration()
std::string message = fmt::format("Failed to initialize RAIntegration:\n{}", error_message ? error_message : ""); std::string message = fmt::format("Failed to initialize RAIntegration:\n{}", error_message ? error_message : "");
Host::ReportErrorAsync("RAIntegration Error", message); Host::ReportErrorAsync("RAIntegration Error", message);
s_state.using_raintegration = false; s_state.using_raintegration = false;
Host::RunOnCPUThread(&Achievements::FinishLoadRAIntegrationOnCPUThread);
return; return;
} }
@ -4688,6 +4710,17 @@ void Achievements::FinishLoadRAIntegration()
rc_client_raintegration_set_event_handler(s_state.client, RAIntegrationEventHandler); rc_client_raintegration_set_event_handler(s_state.client, RAIntegrationEventHandler);
Host::OnRAIntegrationMenuChanged(); Host::OnRAIntegrationMenuChanged();
Host::RunOnCPUThread(&Achievements::FinishLoadRAIntegrationOnCPUThread);
}
void Achievements::FinishLoadRAIntegrationOnCPUThread()
{
// note: this is executed even for the failure case.
// we want to finish initializing with internal client if RAIntegration didn't load.
const auto lock = GetLock();
s_state.raintegration_loading = false;
FinishInitialize();
} }
void Achievements::UnloadRAIntegration() void Achievements::UnloadRAIntegration()
@ -4695,7 +4728,14 @@ void Achievements::UnloadRAIntegration()
if (!s_state.using_raintegration) if (!s_state.using_raintegration)
return; return;
if (s_state.load_raintegration_request)
{
rc_client_abort_async(s_state.client, s_state.load_raintegration_request);
s_state.load_raintegration_request = nullptr;
}
rc_client_unload_raintegration(s_state.client); rc_client_unload_raintegration(s_state.client);
s_state.raintegration_loading = false;
s_state.using_raintegration = false; s_state.using_raintegration = false;
Host::OnRAIntegrationMenuChanged(); Host::OnRAIntegrationMenuChanged();
} }
@ -4758,4 +4798,9 @@ bool Achievements::IsRAIntegrationAvailable()
return false; return false;
} }
bool Achievements::IsRAIntegrationInitializing()
{
return false;
}
#endif #endif