Updated AchievementManager VerifyCredentials to properly lock inputs and outputs without locking during the network call.

This commit is contained in:
LillyJadeKatrin 2023-09-26 21:24:36 -04:00
parent 3c564078cd
commit a29ec7d956

View file

@ -54,11 +54,7 @@ AchievementManager::ResponseType AchievementManager::Login(const std::string& pa
"Achievement Manager initialized."); "Achievement Manager initialized.");
return AchievementManager::ResponseType::MANAGER_NOT_INITIALIZED; return AchievementManager::ResponseType::MANAGER_NOT_INITIALIZED;
} }
AchievementManager::ResponseType r_type = AchievementManager::ResponseType::UNKNOWN_FAILURE; AchievementManager::ResponseType r_type = VerifyCredentials(password);
{
std::lock_guard lg{m_lock};
r_type = VerifyCredentials(password);
}
if (m_update_callback) if (m_update_callback)
m_update_callback(); m_update_callback();
return r_type; return r_type;
@ -74,10 +70,7 @@ void AchievementManager::LoginAsync(const std::string& password, const ResponseC
return; return;
} }
m_queue.EmplaceItem([this, password, callback] { m_queue.EmplaceItem([this, password, callback] {
{ callback(VerifyCredentials(password));
std::lock_guard lg{m_lock};
callback(VerifyCredentials(password));
}
if (m_update_callback) if (m_update_callback)
m_update_callback(); m_update_callback();
}); });
@ -488,22 +481,34 @@ void AchievementManager::Shutdown()
AchievementManager::ResponseType AchievementManager::VerifyCredentials(const std::string& password) AchievementManager::ResponseType AchievementManager::VerifyCredentials(const std::string& password)
{ {
rc_api_login_response_t login_data{}; rc_api_login_response_t login_data{};
std::string username = Config::Get(Config::RA_USERNAME); std::string username, api_token;
std::string api_token = Config::Get(Config::RA_API_TOKEN); {
std::lock_guard lg{m_lock};
username = Config::Get(Config::RA_USERNAME);
api_token = Config::Get(Config::RA_API_TOKEN);
}
rc_api_login_request_t login_request = { rc_api_login_request_t login_request = {
.username = username.c_str(), .api_token = api_token.c_str(), .password = password.c_str()}; .username = username.c_str(), .api_token = api_token.c_str(), .password = password.c_str()};
ResponseType r_type = Request<rc_api_login_request_t, rc_api_login_response_t>( ResponseType r_type = Request<rc_api_login_request_t, rc_api_login_response_t>(
login_request, &login_data, rc_api_init_login_request, rc_api_process_login_response); login_request, &login_data, rc_api_init_login_request, rc_api_process_login_response);
if (r_type == ResponseType::SUCCESS) if (r_type == ResponseType::SUCCESS)
{ {
INFO_LOG_FMT(ACHIEVEMENTS, "Successfully logged in to RetroAchievements server."); INFO_LOG_FMT(ACHIEVEMENTS, "Successfully logged in {} to RetroAchievements server.", username);
std::lock_guard lg{m_lock};
if (username != Config::Get(Config::RA_USERNAME))
{
INFO_LOG_FMT(ACHIEVEMENTS, "Attempted to login prior user {}; current user is {}.", username,
Config::Get(Config::RA_USERNAME));
Config::SetBaseOrCurrent(Config::RA_API_TOKEN, "");
return ResponseType::EXPIRED_CONTEXT;
}
Config::SetBaseOrCurrent(Config::RA_API_TOKEN, login_data.api_token); Config::SetBaseOrCurrent(Config::RA_API_TOKEN, login_data.api_token);
m_display_name = login_data.display_name; m_display_name = login_data.display_name;
m_player_score = login_data.score; m_player_score = login_data.score;
} }
else else
{ {
WARN_LOG_FMT(ACHIEVEMENTS, "Failed to login to RetroAchievements server."); WARN_LOG_FMT(ACHIEVEMENTS, "Failed to login {} to RetroAchievements server.", username);
} }
rc_api_destroy_login_response(&login_data); rc_api_destroy_login_response(&login_data);
return r_type; return r_type;