Skip to content

Commit

Permalink
[PR 120] Add RA login status indicator/action to settings
Browse files Browse the repository at this point in the history
  • Loading branch information
garbear committed Aug 31, 2020
1 parent 7a1fb2c commit 067ad1a
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 19 deletions.
28 changes: 27 additions & 1 deletion addons/resource.language.en_gb/resources/strings.po
Original file line number Diff line number Diff line change
Expand Up @@ -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."
Expand Down
6 changes: 6 additions & 0 deletions system/settings/settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2113,6 +2113,12 @@
</constraints>
<control type="edit" format="string"/>
</setting>
<setting id="gamesachievements.loggedin" type="boolean" label="35268" help="35269">
<visible>true</visible>
<level>0</level>
<default>false</default>
<control type="toggle" />
</setting>
</group>
</category>
</section>
Expand Down
87 changes: 69 additions & 18 deletions xbmc/games/GameSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "utils/StringUtils.h"
#include "utils/Variant.h"
#include "utils/auto_buffer.h"
#include "utils/log.h"

#include <algorithm>

Expand All @@ -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()
Expand All @@ -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()
Expand Down Expand Up @@ -118,36 +121,84 @@ void CGameSettings::OnSettingChanged(std::shared_ptr<const CSetting> 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<const CSettingBool>(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<const CSettingBool>(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;
}
4 changes: 4 additions & 0 deletions xbmc/games/GameSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ class CGameSettings : public ISettingCallback, public Observable
void OnSettingChanged(std::shared_ptr<const CSetting> setting) override;

private:
std::string LoginToRA(const std::string& username,
const std::string& password,
std::string token);

// Construction parameters
std::shared_ptr<CSettings> m_settings;
};
Expand Down

0 comments on commit 067ad1a

Please sign in to comment.