summaryrefslogtreecommitdiff
path: root/protocols/Steam/src/steam_login.cpp
diff options
context:
space:
mode:
authoraunsane <aunsane@gmail.com>2017-12-28 21:21:10 +0300
committeraunsane <aunsane@gmail.com>2017-12-28 21:21:28 +0300
commit0156ed41dceeef48f070adf67f14d4ba4c4f6d61 (patch)
treed0e1dca4c2c9c3c056ae9cb69dde10ea59316481 /protocols/Steam/src/steam_login.cpp
parentf0075f2b956969f29acd3bc9289c8a5f78faddad (diff)
Steam: refactoring
- reworking http requests - added ability to get game name by appid - another attempt to fix #633 - minor refactoring
Diffstat (limited to 'protocols/Steam/src/steam_login.cpp')
-rw-r--r--protocols/Steam/src/steam_login.cpp250
1 files changed, 148 insertions, 102 deletions
diff --git a/protocols/Steam/src/steam_login.cpp b/protocols/Steam/src/steam_login.cpp
index d91acaba6d..3375a128d5 100644
--- a/protocols/Steam/src/steam_login.cpp
+++ b/protocols/Steam/src/steam_login.cpp
@@ -14,6 +14,31 @@ bool CSteamProto::IsMe(const char *steamId)
return false;
}
+void CSteamProto::Login()
+{
+ ptrA token(getStringA("TokenSecret"));
+ ptrA sessionId(getStringA("SessionID"));
+ if (mir_strlen(token) > 0 && mir_strlen(sessionId) > 0)
+ {
+ PushRequest(
+ new LogonRequest(token),
+ &CSteamProto::OnLoggedOn);
+ }
+ else
+ {
+ T2Utf username(getWStringA("Username"));
+ if (username == NULL)
+ {
+ SetStatus(ID_STATUS_OFFLINE);
+ return;
+ }
+
+ PushRequest(
+ new GetRsaKeyRequest(username),
+ &CSteamProto::OnGotRsaKey);
+ }
+}
+
bool CSteamProto::Relogin()
{
ptrA token(getStringA("TokenSecret"));
@@ -21,53 +46,66 @@ bool CSteamProto::Relogin()
return false;
HttpRequest *request = new LogonRequest(token);
- HttpResponse *response = request->Send(m_hNetlibUser);
+ HttpResponse *response = SendRequest(request);
bool success = false;
- if (CheckResponse(response))
+ if (response)
{
- JSONROOT root(response->pData);
- if (root != nullptr) {
- JSONNode *node = json_get(root, "error");
-
- ptrW error(json_as_string(node));
- if (!mir_wstrcmpi(error, L"OK"))
+ JSONNode root = JSONNode::parse(response->Content);
+ if (root.isnull()) {
+ json_string error = root["error"].as_string();
+ if (!mir_strcmpi(error.c_str(), "OK"))
{
- node = json_get(root, "umqid");
- setString("UMQID", ptrA(mir_u2a(ptrW(json_as_string(node)))));
+ json_string umqId = root["umqid"].as_string();
+ setString("UMQID", umqId.c_str());
- node = json_get(root, "message");
- setDword("MessageID", json_as_int(node));
+ long messageId = root["message"].as_int();
+ setDword("MessageID", messageId);
success = true;
}
}
}
- delete request;
delete response;
return success;
}
-void CSteamProto::OnGotRsaKey(const HttpResponse *response)
+void CSteamProto::LogOut()
{
- if (!CheckResponse(response))
- return;
+ isTerminated = true;
+ if (hRequestQueueThread)
+ SetEvent(hRequestsQueueEvent);
- // load rsa key parts
- JSONNode root = JSONNode::parse(response->pData);
- if (!root)
+ ptrA token(getStringA("TokenSecret"));
+ if (mir_strlen(token) > 0)
+ {
+ ptrA umqid(getStringA("UMQID"));
+ SendRequest(new LogoffRequest(token, umqid));
+ }
+}
+
+void CSteamProto::OnGotRsaKey(const JSONNode &root, void*)
+{
+ if (root.isnull())
+ {
+ SetStatus(ID_STATUS_OFFLINE);
return;
+ }
if (!root["success"].as_bool())
+ {
+ SetStatus(ID_STATUS_OFFLINE);
return;
+ }
- std::string modulus = root["publickey_mod"].as_string();
- std::string exp = root["publickey_exp"].as_string();
+ // load rsa key parts
+ json_string modulus = root["publickey_mod"].as_string();
+ json_string exp = root["publickey_exp"].as_string();
DWORD exponent = strtoul(exp.c_str(), nullptr, 16); // default "010001" = 0x10001
- std::string timestamp = root["timestamp"].as_string();
+ json_string timestamp = root["timestamp"].as_string();
// encrcrypt password
ptrA base64RsaEncryptedPassword;
@@ -77,14 +115,16 @@ void CSteamProto::OnGotRsaKey(const HttpResponse *response)
DWORD encryptedSize = 0;
if ((error = RsaEncrypt(modulus.c_str(), exponent, szPassword, nullptr, encryptedSize)) != 0)
{
- debugLogA("CSteamProto::OnGotRsaKey: encryption error (%lu)", error);
+ debugLogA(__FUNCTION__ ": encryption error (%lu)", error);
+ SetStatus(ID_STATUS_OFFLINE);
return;
}
BYTE *encryptedPassword = (BYTE*)mir_calloc(encryptedSize);
if ((error = RsaEncrypt(modulus.c_str(), exponent, szPassword, encryptedPassword, encryptedSize)) != 0)
{
- debugLogA("CSteamProto::OnGotRsaKey: encryption error (%lu)", error);
+ debugLogA(__FUNCTION__ ": encryption error (%lu)", error);
+ SetStatus(ID_STATUS_OFFLINE);
return;
}
@@ -112,16 +152,43 @@ void CSteamProto::OnGotRsaKey(const HttpResponse *response)
&CSteamProto::OnAuthorization);
}
-void CSteamProto::OnAuthorization(const HttpResponse *response)
+void CSteamProto::OnGotCaptcha(const HttpResponse &response, void *arg)
+{
+ ptrA captchaId((char*)arg);
+
+ if (!response.IsSuccess())
+ {
+ debugLogA(__FUNCTION__ ": failed to get captcha");
+ return;
+ }
+
+ CSteamCaptchaDialog captchaDialog(this, (BYTE*)response.Content.GetData(), response.Content.GetSize());
+ if (captchaDialog.DoModal() != DIALOG_RESULT_OK)
+ {
+ DeleteAuthSettings();
+ SetStatus(ID_STATUS_OFFLINE);
+ return;
+ }
+
+ setString("CaptchaId", captchaId);
+ setString("CaptchaText", captchaDialog.GetCaptchaText());
+
+ T2Utf username(getWStringA("Username"));
+ PushRequest(
+ new GetRsaKeyRequest(username),
+ &CSteamProto::OnGotRsaKey);
+}
+
+void CSteamProto::OnAuthorization(const HttpResponse &response, void*)
{
- if (!CheckResponse(response))
+ if (!response)
{
SetStatus(ID_STATUS_OFFLINE);
return;
}
- JSONNode root = JSONNode::parse(response->pData);
- if (!root)
+ JSONNode root = JSONNode::parse(response.Content);
+ if (root.isnull())
{
SetStatus(ID_STATUS_OFFLINE);
return;
@@ -145,13 +212,11 @@ void CSteamProto::DeleteAuthSettings()
delSetting("CaptchaText");
}
-void CSteamProto::OnAuthorizationError(const JSONNode &node)
+void CSteamProto::OnAuthorizationError(const JSONNode &root)
{
- std::string message = node["message"].as_string();
- ptrW messageT(mir_utf8decodeW(message.c_str()));
- debugLogA("CSteamProto::OnAuthorizationError: %s", message.c_str());
-
- if (!mir_wstrcmpi(messageT, L"Incorrect login."))
+ CMStringW message = root["message"].as_mstring();
+ debugLogA(__FUNCTION__ ": %s", _T2A(message.GetBuffer()));
+ if (!mir_wstrcmpi(message, L"Incorrect login."))
{
// We can't continue with incorrect login/password
DeleteAuthSettings();
@@ -161,9 +226,9 @@ void CSteamProto::OnAuthorizationError(const JSONNode &node)
T2Utf username(getWStringA("Username"));
- if (node["requires_twofactor"].as_bool())
+ if (root["requires_twofactor"].as_bool())
{
- debugLogA("CSteamProto::OnAuthorizationError: requires twofactor");
+ debugLogA(__FUNCTION__ ": requires twofactor");
CSteamTwoFactorDialog twoFactorDialog(this);
if (twoFactorDialog.DoModal() != DIALOG_RESULT_OK)
@@ -181,21 +246,20 @@ void CSteamProto::OnAuthorizationError(const JSONNode &node)
return;
}
- if (node["clear_password_field"].as_bool())
+ if (root["clear_password_field"].as_bool())
{
- debugLogA("CSteamProto::OnAuthorizationError: clear password field");
-
- // Probably wrong password entered?
+ debugLogA(__FUNCTION__ ": clear password field");
+ // describes if the password field was cleared. This can also be true if the twofactor code was wrong
DeleteAuthSettings();
SetStatus(ID_STATUS_OFFLINE);
return;
}
- if (node["emailauth_needed"].as_bool())
+ if (root["emailauth_needed"].as_bool())
{
- debugLogA("CSteamProto::OnAuthorizationError: emailauth needed");
+ debugLogA(__FUNCTION__ ": emailauth needed");
- std::string guardId = node["emailsteamid"].as_string();
+ std::string guardId = root["emailsteamid"].as_string();
ptrA oldGuardId(getStringA("GuardId"));
if (mir_strcmp(guardId.c_str(), oldGuardId) == 0)
{
@@ -207,7 +271,7 @@ void CSteamProto::OnAuthorizationError(const JSONNode &node)
return;
}
- std::string domain = node["emaildomain"].as_string();
+ std::string domain = root["emaildomain"].as_string();
// Make absolute link
if (domain.find("://") == std::string::npos)
@@ -230,70 +294,54 @@ void CSteamProto::OnAuthorizationError(const JSONNode &node)
return;
}
- if (node["captcha_needed"].as_bool())
+ if (root["captcha_needed"].as_bool())
{
- debugLogA("CSteamProto::OnAuthorizationError: captcha needed");
-
- std::string captchaId = node["captcha_gid"].as_string();
-
- GetCaptchaRequest *request = new GetCaptchaRequest(captchaId.c_str());
- HttpResponse *response = request->Send(m_hNetlibUser);
- delete request;
-
- CSteamCaptchaDialog captchaDialog(this, (BYTE*)response->pData, response->dataLength);
- delete response;
- if (captchaDialog.DoModal() != DIALOG_RESULT_OK)
- {
- DeleteAuthSettings();
- SetStatus(ID_STATUS_OFFLINE);
- return;
- }
-
- setString("CaptchaId", captchaId.c_str());
- setString("CaptchaText", captchaDialog.GetCaptchaText());
-
+ debugLogA(__FUNCTION__ ": captcha needed");
+ std::string captchaId = root["captcha_gid"].as_string();
PushRequest(
- new GetRsaKeyRequest(username),
- &CSteamProto::OnGotRsaKey);
+ new GetCaptchaRequest(captchaId.c_str()),
+ &CSteamProto::OnGotCaptcha,
+ mir_strdup(captchaId.c_str()));
return;
}
DeleteAuthSettings();
SetStatus(ID_STATUS_OFFLINE);
+ ShowNotification(L"Steam", message);
}
-void CSteamProto::OnAuthorizationSuccess(const JSONNode &node)
+void CSteamProto::OnAuthorizationSuccess(const JSONNode &root)
{
DeleteAuthSettings();
- if (!node["login_complete"].as_bool())
+ if (!root["login_complete"].as_bool())
{
SetStatus(ID_STATUS_OFFLINE);
return;
}
- std::string oauth = node["oauth"].as_string();
- JSONNode root = JSONNode::parse(oauth.c_str());
- if (!root)
+ std::string oauth = root["oauth"].as_string();
+ JSONNode node = JSONNode::parse(oauth.c_str());
+ if (node.isnull())
{
SetStatus(ID_STATUS_OFFLINE);
return;
}
- std::string steamId = root["steamid"].as_string();
+ std::string steamId = node["steamid"].as_string();
setString("SteamID", steamId.c_str());
- std::string token = root["oauth_token"].as_string();
+ std::string token = node["oauth_token"].as_string();
setString("TokenSecret", token.c_str());
- std::string cookie = root["webcookie"].as_string();
+ std::string cookie = node["webcookie"].as_string();
- PushRequest(
+ SendRequest(
new GetSessionRequest(token.c_str(), steamId.c_str(), cookie.c_str()),
&CSteamProto::OnGotSession);
// We need to load homepage to get sessionid cookie
- PushRequest(
+ SendRequest(
new GetSessionRequest2(),
&CSteamProto::OnGotSession);
@@ -302,17 +350,17 @@ void CSteamProto::OnAuthorizationSuccess(const JSONNode &node)
&CSteamProto::OnLoggedOn);
}
-void CSteamProto::OnGotSession(const HttpResponse *response)
+void CSteamProto::OnGotSession(const HttpResponse &response, void*)
{
if (!response)
return;
- for (int i = 0; i < response->headersCount; i++)
+ for (size_t i = 0; i < response.Headers.GetSize(); i++)
{
- if (lstrcmpiA(response->headers[i].szName, "Set-Cookie"))
+ if (lstrcmpiA(response.Headers[i]->szName, "Set-Cookie"))
continue;
- std::string cookies = response->headers[i].szValue;
+ std::string cookies = response.Headers[i]->szValue;
size_t start = cookies.find("sessionid=") + 10;
size_t end = cookies.substr(start).find(';');
std::string sessionId = cookies.substr(start, end - start + 10);
@@ -329,8 +377,8 @@ void CSteamProto::HandleTokenExpired()
// Try to relogin automatically (but only once)
if (isLoginAgain) {
// Notify error to user
+ debugLogA(__FUNCTION__ ": cannot obtain connection token");
ShowNotification(L"Steam", TranslateT("Cannot obtain connection token."));
-
// Just go offline; it also resets the isLoginAgain to false
SetStatus(ID_STATUS_OFFLINE);
}
@@ -350,28 +398,26 @@ void CSteamProto::HandleTokenExpired()
}
}
-void CSteamProto::OnLoggedOn(const HttpResponse *response)
+void CSteamProto::OnLoggedOn(const HttpResponse &response, void*)
{
- if (!CheckResponse(response))
+ if (!response.IsSuccess())
{
- if (response && response->resultCode == HTTP_CODE_UNAUTHORIZED)
- {
- // Probably expired TokenSecret
- HandleTokenExpired();
- return;
- }
-
// Probably timeout or no connection, we can do nothing here
+ debugLogA(__FUNCTION__ ": unknown login error");
ShowNotification(L"Steam", TranslateT("Unknown login error."));
-
SetStatus(ID_STATUS_OFFLINE);
return;
}
- JSONROOT root(response->pData);
+ if (response.GetStatusCode() == HTTP_CODE_UNAUTHORIZED)
+ {
+ // Probably expired TokenSecret
+ HandleTokenExpired();
+ return;
+ }
- JSONNode *node = json_get(root, "error");
- ptrW error(json_as_string(node));
+ JSONNode root = JSONNode::parse(response.Content);
+ CMStringW error = root["error"].as_mstring();
if (mir_wstrcmpi(error, L"OK"))
{
// Probably expired TokenSecret
@@ -379,15 +425,15 @@ void CSteamProto::OnLoggedOn(const HttpResponse *response)
return;
}
- node = json_get(root, "umqid");
- setString("UMQID", ptrA(mir_u2a(ptrW(json_as_string(node)))));
+ json_string umqId = root["umqid"].as_string();
+ setString("UMQID", umqId.c_str());
- node = json_get(root, "message");
- setDword("MessageID", json_as_int(node));
+ long messageId = root["umqid"].as_int();
+ setDword("MessageID", messageId);
- if (m_lastMessageTS <= 0) {
- node = json_get(root, "utc_timestamp");
- time_t timestamp = _wtoi64(ptrW(json_as_string(node)));
+ if (m_lastMessageTS <= 0)
+ {
+ time_t timestamp = _wtoi64(root["utc_timestamp"].as_mstring());
setDword("LastMessageTS", timestamp);
}