From 067ad1a7640e9e540bad1038da873044c98ab984 Mon Sep 17 00:00:00 2001 From: Garrett Brown Date: Sat, 29 Aug 2020 18:37:32 -0700 Subject: [PATCH] [PR 120] Add RA login status indicator/action to settings --- .../resources/strings.po | 28 +++++- system/settings/settings.xml | 6 ++ xbmc/games/GameSettings.cpp | 87 +++++++++++++++---- xbmc/games/GameSettings.h | 4 + 4 files changed, 106 insertions(+), 19 deletions(-) diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index 19a969069c7eb..d68246567c46b 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -17919,7 +17919,33 @@ msgctxt "#35265" msgid "Incorrect User/Password!" msgstr "" -#empty strings from id 35266 to 35401 +#. TODO +#: xbmc/games/GameSettings.cpp +msgctxt "#35266" +msgid "Failed to contact server" +msgstr "" + +#. TODO +#: xbmc/games/GameSettings.cpp +msgctxt "#35267" +msgid "Invalid response from server" +msgstr "" + +#. Setting to show if the user is logged in to RetroAchievements +#. Settings -> Games -> Achievements -> Logged in +#: system/settings/settings.xml +msgctxt "#35268" +msgid "Logged in" +msgstr "" + +#. Help text for the setting that shows if the user is logged in to RetroAchievements +#. Settings -> Games -> Achievements -> Logged in +#: system/settings/settings.xml +msgctxt "#35269" +msgid "Toggle this setting to log in or out of RetroAchievemts." +msgstr "" + +#empty strings from id 35270 to 35401 msgctxt "#35402" msgid "Replicates the 2.6-inch dot matrix screen of the Game Boy. Features the ghosting problems of the original handheld." diff --git a/system/settings/settings.xml b/system/settings/settings.xml index 913bebf1cfcf9..87a59142a34b1 100755 --- a/system/settings/settings.xml +++ b/system/settings/settings.xml @@ -2113,6 +2113,12 @@ + + true + 0 + false + + diff --git a/xbmc/games/GameSettings.cpp b/xbmc/games/GameSettings.cpp index ab6651424f889..78a48651f7b38 100644 --- a/xbmc/games/GameSettings.cpp +++ b/xbmc/games/GameSettings.cpp @@ -20,6 +20,7 @@ #include "utils/StringUtils.h" #include "utils/Variant.h" #include "utils/auto_buffer.h" +#include "utils/log.h" #include @@ -36,6 +37,7 @@ const std::string SETTING_GAMES_REWINDTIME = "gamesgeneral.rewindtime"; const std::string SETTING_GAMES_ACHIEVEMENTS_USERNAME = "gamesachievements.username"; const std::string SETTING_GAMES_ACHIEVEMENTS_PASSWORD = "gamesachievements.password"; const std::string SETTING_GAMES_ACHIEVEMENTS_TOKEN = "gamesachievements.token"; +const std::string SETTING_GAMES_ACHIEVEMENTS_LOGGED_IN = "gamesachievements.loggedin"; } // namespace CGameSettings::CGameSettings() @@ -44,7 +46,8 @@ CGameSettings::CGameSettings() m_settings->RegisterCallback(this, {SETTING_GAMES_ENABLEREWIND, SETTING_GAMES_REWINDTIME, SETTING_GAMES_ACHIEVEMENTS_USERNAME, - SETTING_GAMES_ACHIEVEMENTS_PASSWORD}); + SETTING_GAMES_ACHIEVEMENTS_PASSWORD, + SETTING_GAMES_ACHIEVEMENTS_LOGGED_IN}); } CGameSettings::~CGameSettings() @@ -118,36 +121,84 @@ void CGameSettings::OnSettingChanged(std::shared_ptr setting) NotifyObservers(ObservableMessageSettingsChanged); } else if (settingId == SETTING_GAMES_ACHIEVEMENTS_USERNAME || - settingId == SETTING_GAMES_ACHIEVEMENTS_PASSWORD) + settingId == SETTING_GAMES_ACHIEVEMENTS_PASSWORD || + (settingId == SETTING_GAMES_ACHIEVEMENTS_LOGGED_IN && + std::dynamic_pointer_cast(setting)->GetValue())) { const std::string username = m_settings->GetString(SETTING_GAMES_ACHIEVEMENTS_USERNAME); const std::string password = m_settings->GetString(SETTING_GAMES_ACHIEVEMENTS_PASSWORD); + std::string token = m_settings->GetString(SETTING_GAMES_ACHIEVEMENTS_TOKEN); - if (!username.empty() && !password.empty()) + // TODO: Async login, this freezes the GUI + token = LoginToRA(username, password, std::move(token)); + + m_settings->SetString(SETTING_GAMES_ACHIEVEMENTS_TOKEN, token); + + if (!token.empty()) { - XFILE::CFile request; - const CURL loginUrl(StringUtils::Format( - "http://retroachievements.org/dorequest.php?r=login&u=%s&p=%s", username, password)); - XUTILS::auto_buffer response; - CVariant data(CVariant::VariantTypeObject); + m_settings->SetBool(SETTING_GAMES_ACHIEVEMENTS_LOGGED_IN, true); + } + else + { + if (settingId == SETTING_GAMES_ACHIEVEMENTS_PASSWORD) + m_settings->SetString(SETTING_GAMES_ACHIEVEMENTS_PASSWORD, ""); + m_settings->SetBool(SETTING_GAMES_ACHIEVEMENTS_LOGGED_IN, false); + } + + m_settings->Save(); + } + else if (settingId == SETTING_GAMES_ACHIEVEMENTS_LOGGED_IN && + !std::dynamic_pointer_cast(setting)->GetValue()) + { + m_settings->SetString(SETTING_GAMES_ACHIEVEMENTS_TOKEN, ""); + m_settings->Save(); + } +} - request.LoadFile(loginUrl, response); - CJSONVariantParser::Parse(response.get(), data); +std::string CGameSettings::LoginToRA(const std::string& username, + const std::string& password, + std::string token) +{ + if (!username.empty() && !password.empty()) + { + XFILE::CFile request; + const CURL loginUrl(StringUtils::Format( + "http://retroachievements.org/dorequest.php?r=login&u={}&p={}", username, password)); - if (data["Success"].asBoolean()) + XUTILS::auto_buffer response; + if (request.LoadFile(loginUrl, response) > 0) + { + std::string strResponse(response.get(), response.size()); + CVariant data(CVariant::VariantTypeObject); + if (CJSONVariantParser::Parse(strResponse, data)) { - const std::string token = data["Token"].asString(); - m_settings->SetString(SETTING_GAMES_ACHIEVEMENTS_TOKEN, token); + if (data["Success"].asBoolean()) + token = data["Token"].asString(); + else + { + token.clear(); + + // "RetroAchievements", "Incorrect User/Password!" + CServiceBroker::GetEventLog().AddWithNotification( + EventPtr(new CNotificationEvent(35264, 35265, EventLevel::Error))); + } } else { - m_settings->SetString(SETTING_GAMES_ACHIEVEMENTS_PASSWORD, ""); - m_settings->SetString(SETTING_GAMES_ACHIEVEMENTS_TOKEN, ""); - - // "RetroAchievements", "Incorrect User/Password!" + // "RetroAchievements", "Invalid response from server" CServiceBroker::GetEventLog().AddWithNotification( - EventPtr(new CNotificationEvent(35264, 35265, EventLevel::Error))); + EventPtr(new CNotificationEvent(35264, 35267, EventLevel::Error))); + + CLog::Log(LOGERROR, "Invalid server response: {}", strResponse); } } + else + { + // "RetroAchievements", "Failed to contact server" + CServiceBroker::GetEventLog().AddWithNotification( + EventPtr(new CNotificationEvent(35264, 35266, EventLevel::Error))); + } } + + return token; } diff --git a/xbmc/games/GameSettings.h b/xbmc/games/GameSettings.h index dd4fa01ba280d..2472f8c6b290a 100644 --- a/xbmc/games/GameSettings.h +++ b/xbmc/games/GameSettings.h @@ -42,6 +42,10 @@ class CGameSettings : public ISettingCallback, public Observable void OnSettingChanged(std::shared_ptr setting) override; private: + std::string LoginToRA(const std::string& username, + const std::string& password, + std::string token); + // Construction parameters std::shared_ptr m_settings; };