diff --git a/src/core/achievements.cpp b/src/core/achievements.cpp index 0ec391f90..f4012d474 100644 --- a/src/core/achievements.cpp +++ b/src/core/achievements.cpp @@ -2008,29 +2008,21 @@ bool Achievements::IsLoggedInOrLoggingIn() return (IsLoggedIn() || s_state.login_request); } -bool Achievements::LoginAsync(const char* username, const char* password, Error* error, - LoginCompletionCallback callback) +void Achievements::LoginAsync(const char* username, const char* password, LoginCompletionCallback callback) { auto lock = GetLock(); // We need to use a temporary client if achievements aren't currently active. if (!s_state.client && !CreateClient(lock, true)) { - Error::SetString(error, "Failed to create client."); - return false; + callback(false, "Failed to create client."); + return; } + // Callback always runs regardless of whether an async request was created. LoginCompletionCallback* const callback_copy = new LoginCompletionCallback(std::move(callback)); - if (!rc_client_begin_login_with_password(s_state.client, username, password, - RESOLVE_CLIENT_CALLBACK(ClientLoginWithPasswordCallback), callback_copy)) - { - Error::SetString(error, "Failed to create login request."); - delete callback_copy; - return false; - } - - // Login attempt started. - return true; + rc_client_begin_login_with_password(s_state.client, username, password, + RESOLVE_CLIENT_CALLBACK(ClientLoginWithPasswordCallback), callback_copy); } void Achievements::ClientLoginWithPasswordCallback(int result, const char* error_message, rc_client_t* client, diff --git a/src/core/achievements.h b/src/core/achievements.h index 5001cf4f4..0c60ebf92 100644 --- a/src/core/achievements.h +++ b/src/core/achievements.h @@ -107,7 +107,7 @@ bool DoState(StateWrapper& sw); /// Attempts to log in to RetroAchievements using the specified credentials. /// If the login is successful, the token returned by the server will be saved. using LoginCompletionCallback = std::function; -bool LoginAsync(const char* username, const char* password, Error* error, LoginCompletionCallback callback); +void LoginAsync(const char* username, const char* password, LoginCompletionCallback callback); /// Logs out of RetroAchievements, clearing any credentials. void Logout(); diff --git a/src/core/fullscreenui_settings.cpp b/src/core/fullscreenui_settings.cpp index ea0bfbb92..d1b43bd23 100644 --- a/src/core/fullscreenui_settings.cpp +++ b/src/core/fullscreenui_settings.cpp @@ -5844,31 +5844,25 @@ void FullscreenUI::DrawAchievementsLoginWindow() { OpenBackgroundProgressDialog(LOGIN_PROGRESS_NAME, FSUI_STR("Logging in to RetroAchievements..."), 0, 0, 0); - static constexpr auto set_error = [](const std::string& description) { - s_settings_locals.achievements_login_error = std::make_unique(fmt::format( - FSUI_FSTR("Login Failed.\nError: {}\nPlease check your username and password, and try again."), description)); - }; - - if (Error error; !Achievements::LoginAsync( - s_settings_locals.achievements_login_username, s_settings_locals.achievements_login_password, &error, - [](bool result, std::string&& error_message) { - // callback runs on core thread - DebugAssert(Host::IsOnCoreThread()); - VideoThread::RunOnThread([result, error_message = std::move(error_message)]() { - CloseBackgroundProgressDialog(LOGIN_PROGRESS_NAME); - - if (result) - { - CloseFixedPopupDialog(); - return; - } + Achievements::LoginAsync( + s_settings_locals.achievements_login_username, s_settings_locals.achievements_login_password, + [](bool result, std::string&& error_message) { + // callback runs on core thread + DebugAssert(Host::IsOnCoreThread()); + VideoThread::RunOnThread([result, error_message = std::move(error_message)]() { + CloseBackgroundProgressDialog(LOGIN_PROGRESS_NAME); + + if (result) + { + CloseFixedPopupDialog(); + return; + } - set_error(error_message); - }); - })) - { - set_error(error.GetDescription()); - } + s_settings_locals.achievements_login_error = std::make_unique( + fmt::format(FSUI_FSTR("Login Failed.\nError: {}\nPlease check your username and password, and try again."), + error_message)); + }); + }); } if (HorizontalMenuButton(FSUI_ICONVSTR(ICON_FA_XMARK, "Cancel"), !is_logging_in)) diff --git a/src/duckstation-qt/achievementlogindialog.cpp b/src/duckstation-qt/achievementlogindialog.cpp index 274e92367..476a5cf7f 100644 --- a/src/duckstation-qt/achievementlogindialog.cpp +++ b/src/duckstation-qt/achievementlogindialog.cpp @@ -53,18 +53,15 @@ void AchievementLoginDialog::loginClicked() // Use QPointer<> to safely check if the dialog still exists when the login finishes, since the callback // runs on the core thread and we need to queue it back to the UI thread. - if (Error error; !Achievements::LoginAsync( - username.toUtf8().constData(), password.toUtf8().constData(), &error, - [dialog = QPointer(this)](bool result, std::string&& error_message) mutable { - DebugAssert(Host::IsOnCoreThread()); - Host::RunOnUIThread([dialog = std::move(dialog), error_message = std::move(error_message), result]() { - if (dialog) - dialog->processLoginResult(result, QString::fromStdString(error_message)); - }); - })) - { - processLoginResult(false, QString::fromStdString(error.GetDescription())); - } + Achievements::LoginAsync(username.toUtf8().constData(), password.toUtf8().constData(), + [dialog = QPointer(this)](bool result, std::string&& error_message) mutable { + DebugAssert(Host::IsOnCoreThread()); + Host::RunOnUIThread( + [dialog = std::move(dialog), error_message = std::move(error_message), result]() { + if (dialog) + dialog->processLoginResult(result, QString::fromStdString(error_message)); + }); + }); } void AchievementLoginDialog::cancelClicked()