diff options
author | Alexander Lantsev <aunsane@gmail.com> | 2015-03-15 11:20:05 +0000 |
---|---|---|
committer | Alexander Lantsev <aunsane@gmail.com> | 2015-03-15 11:20:05 +0000 |
commit | 641c67a9d552b07664308c2ae3384cc95a75a2d0 (patch) | |
tree | b9e29c5bf201211065b912bb2048143152c82201 /protocols/Steam/src | |
parent | 108bb117b2a796e8a99d7add61f304730b9ecadb (diff) |
Steam:
- added support for templated url
- fixed broken login
- version bump
git-svn-id: http://svn.miranda-ng.org/main/trunk@12408 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols/Steam/src')
-rw-r--r-- | protocols/Steam/src/Steam/authorization.h | 54 | ||||
-rw-r--r-- | protocols/Steam/src/Steam/captcha.h | 4 | ||||
-rw-r--r-- | protocols/Steam/src/Steam/friend_list.h | 6 | ||||
-rw-r--r-- | protocols/Steam/src/Steam/pending.h | 18 | ||||
-rw-r--r-- | protocols/Steam/src/Steam/rsa_key.h | 2 | ||||
-rw-r--r-- | protocols/Steam/src/Steam/session.h | 50 | ||||
-rw-r--r-- | protocols/Steam/src/Steam/steam.h | 130 | ||||
-rw-r--r-- | protocols/Steam/src/steam_account.cpp | 527 | ||||
-rw-r--r-- | protocols/Steam/src/steam_pooling.cpp | 6 | ||||
-rw-r--r-- | protocols/Steam/src/steam_proto.h | 681 | ||||
-rw-r--r-- | protocols/Steam/src/steam_queue.cpp | 11 | ||||
-rw-r--r-- | protocols/Steam/src/version.h | 2 |
12 files changed, 750 insertions, 741 deletions
diff --git a/protocols/Steam/src/Steam/authorization.h b/protocols/Steam/src/Steam/authorization.h index 194a5dee36..e72eef1a11 100644 --- a/protocols/Steam/src/Steam/authorization.h +++ b/protocols/Steam/src/Steam/authorization.h @@ -5,49 +5,55 @@ namespace SteamWebApi {
class AuthorizationRequest : public HttpsPostRequest
{
- void InitData(const char *username, const char *password, const char *timestamp, const char *guardId = "-1", const char *guardCode = "", const char *captchaId = "-1", const char *captchaText = "")
+ public:
+ AuthorizationRequest(const char *username, const char *password, const char *timestamp) :
+ HttpsPostRequest(STEAM_WEB_URL "/mobilelogin/dologin")
{
+ flags = NLHRF_HTTP11 | NLHRF_SSL | NLHRF_NODUMP;
+
char data[1024];
mir_snprintf(data, SIZEOF(data),
- "username=%s&password=%s&emailsteamid=%s&emailauth=%s&captchagid=%s&captcha_text=%s&rsatimestamp=%s&donotcache=%ld&remember_login=true&oauth_client_id=DE45CD61&oauth_scope=read_profile write_profile read_client write_client",
- username,
+ "username=%s&password=%s&oauth_client_id=3638BFB1&oauth_scope=read_profile write_profile read_client write_client&captchagid=-1&rsatimestamp=%s",
+ ptrA(mir_urlEncode(username)),
ptrA(mir_urlEncode(password)),
- guardId,
- guardCode,
- captchaId,
- ptrA(mir_urlEncode(captchaText)),
- timestamp,
- time(NULL));
+ timestamp);
SetData(data, strlen(data));
}
- public:
- AuthorizationRequest(const char *username, const char *password, const char *timestamp) :
- HttpsPostRequest(STEAM_COM_URL "/mobilelogin/dologin")
+ AuthorizationRequest(const char *username, const char *password, const char *timestamp, const char *guardCode) :
+ HttpsPostRequest(STEAM_WEB_URL "/mobilelogin/dologin")
{
flags = NLHRF_HTTP11 | NLHRF_SSL | NLHRF_NODUMP;
- InitData(username, password, timestamp);
- }
-
- AuthorizationRequest(const char *username, const char *password, const char *timestamp, const char *guardId, const char *guardCode) :
- HttpsPostRequest(STEAM_COM_URL "/mobilelogin/dologin")
- {
- flags = NLHRF_HTTP11 | NLHRF_SSL | NLHRF_NODUMP;
+ char data[1024];
+ mir_snprintf(data, SIZEOF(data),
+ "username=%s&password=%s&emailauth=%s&loginfriendlyname=MirandaNG&oauth_client_id=3638BFB1&oauth_scope=read_profile write_profile read_client write_client&captchagid=-1&rsatimestamp=%s",
+ ptrA(mir_urlEncode(username)),
+ ptrA(mir_urlEncode(password)),
+ guardCode,
+ timestamp);
- InitData(username, password, timestamp, guardId, guardCode);
+ SetData(data, strlen(data));
}
- AuthorizationRequest(const char *username, const char *password, const char *timestamp, const char *guardId, const char *guardCode, const char *captchaId, const char *captchaText) :
- HttpsPostRequest(STEAM_COM_URL "/mobilelogin/dologin")
+ AuthorizationRequest(const char *username, const char *password, const char *timestamp, const char *captchaId, const char *captchaText) :
+ HttpsPostRequest(STEAM_WEB_URL "/mobilelogin/dologin")
{
flags = NLHRF_HTTP11 | NLHRF_SSL | NLHRF_NODUMP;
- InitData(username, password, timestamp, guardId, guardCode, captchaId, captchaText);
+ char data[1024];
+ mir_snprintf(data, SIZEOF(data),
+ "username=%s&password=%s&captchagid=%s&captcha_text=%s&oauth_client_id=3638BFB1&oauth_scope=read_profile write_profile read_client write_client&rsatimestamp=%s",
+ ptrA(mir_urlEncode(username)),
+ ptrA(mir_urlEncode(password)),
+ captchaId,
+ ptrA(mir_urlEncode(captchaText)),
+ timestamp);
+
+ SetData(data, strlen(data));
}
};
}
-
#endif //_STEAM_AUTHORIZATION_H_
\ No newline at end of file diff --git a/protocols/Steam/src/Steam/captcha.h b/protocols/Steam/src/Steam/captcha.h index cb02fdda49..6ad01048ca 100644 --- a/protocols/Steam/src/Steam/captcha.h +++ b/protocols/Steam/src/Steam/captcha.h @@ -6,8 +6,8 @@ namespace SteamWebApi class GetCaptchaRequest : public HttpGetRequest
{
public:
- GetCaptchaRequest(const char *url) :
- HttpGetRequest(url)
+ GetCaptchaRequest(const char *captchaId) :
+ HttpGetRequest(STEAM_WEB_URL "/public/captcha.php?gid=%s", captchaId)
{
flags = NLHRF_HTTP11 | NLHRF_NODUMP;
}
diff --git a/protocols/Steam/src/Steam/friend_list.h b/protocols/Steam/src/Steam/friend_list.h index feed63f706..eccc3d1224 100644 --- a/protocols/Steam/src/Steam/friend_list.h +++ b/protocols/Steam/src/Steam/friend_list.h @@ -19,7 +19,7 @@ namespace SteamWebApi {
public:
AddFriendRequest(const char *token, const char *sessionId, const char *steamId, const char *who) :
- HttpsPostRequest(STEAM_COM_URL "/actions/AddFriendAjax")
+ HttpsPostRequest(STEAM_WEB_URL "/actions/AddFriendAjax")
{
char login[MAX_PATH];
mir_snprintf(login, SIZEOF(login), "%s||oauth:%s", steamId, token);
@@ -42,7 +42,7 @@ namespace SteamWebApi {
public:
BlockFriendRequest(const char *token, const char *sessionId, const char *steamId, const char *who) :
- HttpsPostRequest(STEAM_COM_URL "/actions/BlockUserAjax")
+ HttpsPostRequest(STEAM_WEB_URL "/actions/BlockUserAjax")
{
char login[MAX_PATH];
mir_snprintf(login, SIZEOF(login), "%s||oauth:%s", steamId, token);
@@ -65,7 +65,7 @@ namespace SteamWebApi {
public:
RemoveFriendRequest(const char *token, const char *sessionId, const char *steamId, const char *who) :
- HttpsPostRequest(STEAM_COM_URL "/actions/RemoveFriendAjax")
+ HttpsPostRequest(STEAM_WEB_URL "/actions/RemoveFriendAjax")
{
char login[MAX_PATH];
mir_snprintf(login, SIZEOF(login), "%s||oauth:%s", steamId, token);
diff --git a/protocols/Steam/src/Steam/pending.h b/protocols/Steam/src/Steam/pending.h index 5cdd85b885..68b86ad689 100644 --- a/protocols/Steam/src/Steam/pending.h +++ b/protocols/Steam/src/Steam/pending.h @@ -7,7 +7,7 @@ namespace SteamWebApi {
public:
ApprovePendingRequest(const char *token, const char *sessionId, const char *steamId, const char *who) :
- HttpsPostRequest(STEAM_COM_URL "/profiles/%s/home_process")
+ HttpsPostRequest(STEAM_WEB_URL "/profiles/%s/home_process", steamId)
{
char login[MAX_PATH];
mir_snprintf(login, SIZEOF(login), "%s||oauth:%s", steamId, token);
@@ -15,10 +15,6 @@ namespace SteamWebApi char cookie[MAX_PATH];
mir_snprintf(cookie, SIZEOF(cookie), "steamLogin=%s;sessionid=%s;forceMobile=1", login, sessionId);
- char url[MAX_PATH];
- mir_snprintf(url, SIZEOF(url), STEAM_COM_URL "/profiles/%s/home_process", steamId);
- this->url = url;
-
char data[MAX_PATH];
mir_snprintf(data, SIZEOF(data), "sessionID=%s&id=%s&perform=accept&action=approvePending&itype=friend&json=1&xml=0", sessionId, who);
@@ -31,7 +27,7 @@ namespace SteamWebApi {
public:
IgnorePendingRequest(const char *token, const char *sessionId, const char *steamId, const char *who) :
- HttpsPostRequest(STEAM_COM_URL "/profiles/%s/home_process")
+ HttpsPostRequest(STEAM_WEB_URL "/profiles/%s/home_process", steamId)
{
char login[MAX_PATH];
mir_snprintf(login, SIZEOF(login), "%s||oauth:%s", steamId, token);
@@ -39,10 +35,6 @@ namespace SteamWebApi char cookie[MAX_PATH];
mir_snprintf(cookie, SIZEOF(cookie), "steamLogin=%s;sessionid=%s;forceMobile=1", login, sessionId);
- char url[MAX_PATH];
- mir_snprintf(url, SIZEOF(url), STEAM_COM_URL "/profiles/%s/home_process", steamId);
- this->url = url;
-
char data[MAX_PATH];
mir_snprintf(data, SIZEOF(data), "sessionID=%s&id=%s&perform=ignore&action=approvePending&itype=friend&json=1&xml=0", sessionId, who);
@@ -55,7 +47,7 @@ namespace SteamWebApi {
public:
BlockPendingRequest(const char *token, const char *sessionId, const char *steamId, const char *who) :
- HttpsPostRequest(STEAM_COM_URL "/profiles/%s/home_process")
+ HttpsPostRequest(STEAM_WEB_URL "/profiles/%s/home_process", steamId)
{
char login[MAX_PATH];
mir_snprintf(login, SIZEOF(login), "%s||oauth:%s", steamId, token);
@@ -63,10 +55,6 @@ namespace SteamWebApi char cookie[MAX_PATH];
mir_snprintf(cookie, SIZEOF(cookie), "steamLogin=%s;sessionid=%s;forceMobile=1", login, sessionId);
- char url[MAX_PATH];
- mir_snprintf(url, SIZEOF(url), STEAM_COM_URL "/profiles/%s/home_process", steamId);
- this->url = url;
-
char data[MAX_PATH];
mir_snprintf(data, SIZEOF(data), "sessionID=%s&id=%s&perform=block&action=approvePending&itype=friend&json=1&xml=0", sessionId, who);
diff --git a/protocols/Steam/src/Steam/rsa_key.h b/protocols/Steam/src/Steam/rsa_key.h index c4f9efc72d..be7d7ac79c 100644 --- a/protocols/Steam/src/Steam/rsa_key.h +++ b/protocols/Steam/src/Steam/rsa_key.h @@ -7,7 +7,7 @@ namespace SteamWebApi {
public:
RsaKeyRequest(const char *username) :
- HttpsGetRequest(STEAM_COM_URL "/mobilelogin/getrsakey")
+ HttpsGetRequest(STEAM_WEB_URL "/mobilelogin/getrsakey")
{
flags = NLHRF_HTTP11 | NLHRF_SSL | NLHRF_NODUMP;
diff --git a/protocols/Steam/src/Steam/session.h b/protocols/Steam/src/Steam/session.h index a5fd950e1d..ea42cc77c4 100644 --- a/protocols/Steam/src/Steam/session.h +++ b/protocols/Steam/src/Steam/session.h @@ -3,59 +3,11 @@ namespace SteamWebApi
{
- //class SessionApi : public BaseApi
- //{
- //public:
- // class SessionId : public Result
- // {
- // friend SessionApi;
-
- // private:
- // std::string sessionid;
-
- // public:
-
- // const char *GetSessionId() { return sessionid.c_str(); }
- // };
-
- // static void GetSessionId(HANDLE hConnection, const char *token, const char *steamId, SessionId *sessionId)
- // {
- // sessionId->success = false;
-
- // char login[MAX_PATH];
- // mir_snprintf(login, SIZEOF(login), "%s||oauth:%s", steamId, token);
-
- // char cookie[MAX_PATH];
- // mir_snprintf(cookie, SIZEOF(cookie), "steamLogin=%s", ptrA(mir_urlEncode(login)));
-
- // SecureHttpGetRequest request(hConnection, STEAM_COM_URL "/mobilesettings/GetManifest/v0001");
- // request.AddHeader("Cookie", cookie);
-
- // mir_ptr<NETLIBHTTPREQUEST> response(request.Send());
- // if (!response)
- // return;
-
- // for (int i = 0; i < response->headersCount; i++)
- // {
- // if (lstrcmpiA(response->headers[i].szName, "Set-Cookie"))
- // continue;
-
- // std::string cookies = response->headers[i].szValue;
- // size_t start = cookies.find("sessionid=") + 10;
- // size_t end = cookies.substr(start).find(';');
- // sessionId->sessionid = cookies.substr(start, end - start + 10);
- // break;
- // }
-
- // sessionId->success = true;
- // }
- //};
-
class GetSessionRequest : public HttpsPostRequest
{
public:
GetSessionRequest(const char *token, const char *steamId, const char *cookie) :
- HttpsPostRequest(STEAM_COM_URL "/mobileloginsucceeded")
+ HttpsPostRequest(STEAM_WEB_URL "/mobileloginsucceeded")
{
flags = NLHRF_HTTP11 | NLHRF_SSL | NLHRF_NODUMP;
diff --git a/protocols/Steam/src/Steam/steam.h b/protocols/Steam/src/Steam/steam.h index c32da7e92a..a2a373a3d3 100644 --- a/protocols/Steam/src/Steam/steam.h +++ b/protocols/Steam/src/Steam/steam.h @@ -4,33 +4,31 @@ namespace SteamWebApi
{
#define STEAM_API_URL "https://api.steampowered.com"
- #define STEAM_COM_URL "https://steamcommunity.com"
+ #define STEAM_WEB_URL "https://steamcommunity.com"
class HttpRequest : public NETLIBHTTPREQUEST, public MZeroedObject
{
- public:
- std::string url;
-
- HttpRequest(int type, LPCSTR url)
+ private:
+ CMStringA url;
+
+ protected:
+ HttpRequest()
{
cbSize = sizeof(NETLIBHTTPREQUEST);
- requestType = type;
- this->url = url;
- szUrl = (char*)this->url.c_str();
- timeout = 0;
- flags = NLHRF_HTTP11 | NLHRF_NODUMPSEND | NLHRF_DUMPASTEXT;
+ AddHeader("user-agent", "Steam 1.2.0 / iPhone");
}
- ~HttpRequest()
+ HttpRequest(int type, LPCSTR urlFormat, va_list args)
{
- for (int i = 0; i < headersCount; i++)
- {
- mir_free(headers[i].szName);
- mir_free(headers[i].szValue);
- }
- mir_free(headers);
- mir_free(pData);
+ this->HttpRequest::HttpRequest();
+
+ requestType = type;
+ //timeout = 0;
+ flags = NLHRF_HTTP11 | NLHRF_NODUMPSEND | NLHRF_DUMPASTEXT;
+
+ url.AppendFormatV(urlFormat, args);
+ szUrl = url.GetBuffer();
}
void AddHeader(LPCSTR szName, LPCSTR szValue)
@@ -41,20 +39,23 @@ namespace SteamWebApi headersCount++;
}
- void AddParameter(LPCSTR szName, LPCSTR szValue)
+ void AddParameter(const char *fmt, ...)
{
- if (url.find('?') == -1)
- url.append("?").append(szName).append("=").append(szValue);
+ va_list args;
+ va_start(args, fmt);
+ if (url.Find('?') == -1)
+ url += '?';
else
- url.append("&").append(szName).append("=").append(szValue);
+ url += '&';
+ url.AppendFormatV(fmt, args);
+ va_end(args);
+
+ szUrl = url.GetBuffer();
}
- void AddParameter(LPCSTR szValue)
+ void AddParameter(LPCSTR name, LPCSTR value)
{
- if (url.find('?') == -1)
- url.append("?").append(szValue);
- else
- url.append("&").append(szValue);
+ AddParameter("%s=%s", name, value);
}
void SetData(const char *data, size_t size)
@@ -67,28 +68,76 @@ namespace SteamWebApi memcpy(pData, data, size);
pData[size] = 0;
}
+
+ public:
+ HttpRequest(int type, LPCSTR urlFormat, ...)
+ {
+ va_list args;
+ va_start(args, urlFormat);
+ this->HttpRequest::HttpRequest(type, urlFormat, args);
+ va_end(args);
+ }
+
+ ~HttpRequest()
+ {
+ for (int i = 0; i < headersCount; i++)
+ {
+ mir_free(headers[i].szName);
+ mir_free(headers[i].szValue);
+ }
+ mir_free(headers);
+ mir_free(pData);
+ }
+
+ NETLIBHTTPREQUEST * Send(HANDLE hConnection)
+ {
+ char message[1024];
+ mir_snprintf(message, SIZEOF(message), "Send request to %s", szUrl);
+ CallService(MS_NETLIB_LOG, (WPARAM)hConnection, (LPARAM)&message);
+
+ return (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)hConnection, (LPARAM)this);
+ }
};
class HttpGetRequest : public HttpRequest
{
public:
- HttpGetRequest(LPCSTR url) : HttpRequest(REQUEST_GET, url) { }
+ HttpGetRequest(LPCSTR urlFormat, ...) : HttpRequest()
+ {
+ va_list args;
+ va_start(args, urlFormat);
+ this->HttpRequest::HttpRequest(REQUEST_GET, urlFormat, args);
+ va_end(args);
+ }
};
- /*class HttpPostRequest : public HttpRequest
+ class HttpPostRequest : public HttpRequest
{
public:
- HttpPostRequest(LPCSTR url) : HttpRequest(REQUEST_POST, url)
+ HttpPostRequest(LPCSTR urlFormat, ...) : HttpRequest()
{
+ va_list args;
+ va_start(args, urlFormat);
+ this->HttpRequest::HttpRequest(REQUEST_POST, urlFormat, args);
+ va_end(args);
+
AddHeader("Content-Type", "application/x-www-form-urlencoded");
}
- };*/
+ };
class HttpsRequest : public HttpRequest
{
+ protected:
+ HttpsRequest() : HttpRequest() { }
+
public:
- HttpsRequest(int type, LPCSTR url) : HttpRequest(type, url)
+ HttpsRequest(int type, LPCSTR urlFormat, ...) : HttpRequest()
{
+ va_list args;
+ va_start(args, urlFormat);
+ this->HttpRequest::HttpRequest(type, urlFormat, args);
+ va_end(args);
+
flags = NLHRF_HTTP11 | NLHRF_SSL | NLHRF_NODUMPSEND | NLHRF_DUMPASTEXT;
}
};
@@ -96,15 +145,26 @@ namespace SteamWebApi class HttpsGetRequest : public HttpsRequest
{
public:
- HttpsGetRequest(LPCSTR url) : HttpsRequest(REQUEST_GET, url) { }
+ HttpsGetRequest(LPCSTR urlFormat, ...) : HttpsRequest()
+ {
+ va_list args;
+ va_start(args, urlFormat);
+ this->HttpRequest::HttpRequest(REQUEST_GET, urlFormat, args);
+ va_end(args);
+ }
};
class HttpsPostRequest : public HttpsRequest
{
public:
- HttpsPostRequest(LPCSTR url) : HttpsRequest(REQUEST_POST, url)
+ HttpsPostRequest(LPCSTR urlFormat, ...) : HttpsRequest()
{
- AddHeader("Content-Type", "application/x-www-form-urlencoded");
+ va_list args;
+ va_start(args, urlFormat);
+ this->HttpRequest::HttpRequest(REQUEST_POST, urlFormat, args);
+ va_end(args);
+
+ AddHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
}
};
}
diff --git a/protocols/Steam/src/steam_account.cpp b/protocols/Steam/src/steam_account.cpp index 7e16e5b850..94b26e384d 100644 --- a/protocols/Steam/src/steam_account.cpp +++ b/protocols/Steam/src/steam_account.cpp @@ -1,263 +1,266 @@ -#include "common.h" - -bool CSteamProto::IsOnline() -{ - return m_iStatus > ID_STATUS_OFFLINE && m_hPollingThread; -} - -bool CSteamProto::IsMe(const char *steamId) -{ - ptrA mySteamId(getStringA("SteamID")); - if (!lstrcmpA(steamId, mySteamId)) - return true; - - return false; -} - -void CSteamProto::OnGotRsaKey(const NETLIBHTTPREQUEST *response, void *arg) -{ - if (response == NULL) - return; - - // load rsa key parts - JSONROOT root(response->pData); - if (!root) - return; - - JSONNODE *node = json_get(root, "success"); - if (!json_as_bool(node)) { - return; - } - - node = json_get(root, "publickey_mod"); - ptrA modulus(mir_u2a(ptrT(json_as_string(node)))); - - // exponent "010001" is used as constant in CSteamProto::RsaEncrypt - /*node = json_get(root, "publickey_exp"); - ptrA exponent(mir_u2a(ptrT(json_as_string(node))));*/ - - node = json_get(root, "timestamp"); - ptrA timestamp(mir_u2a(ptrT(json_as_string(node)))); - setString("Timestamp", timestamp); - - // encrcrypt password - ptrA base64RsaEncryptedPassword; - ptrA password(getStringA("Password")); - - DWORD error = 0; - DWORD encryptedSize = 0; - DWORD passwordSize = (DWORD)strlen(password); - if ((error = RsaEncrypt(modulus, password, NULL, encryptedSize)) != 0) - { - debugLogA("CSteamProto::OnGotRsaKey: encryption error (%lu)", error); - return; - } - - BYTE *encryptedPassword = (BYTE*)mir_calloc(encryptedSize); - if ((error = RsaEncrypt(modulus, password, encryptedPassword, encryptedSize)) != 0) - { - debugLogA("CSteamProto::OnGotRsaKey: encryption error (%lu)", error); - return; - } - - base64RsaEncryptedPassword = mir_base64_encode(encryptedPassword, encryptedSize); - mir_free(encryptedPassword); - - setString("EncryptedPassword", base64RsaEncryptedPassword); - - // run authorization request - ptrA username(mir_urlEncode(ptrA(mir_utf8encodeW(getWStringA("Username"))))); - - PushRequest( - new SteamWebApi::AuthorizationRequest(username, base64RsaEncryptedPassword, timestamp), - &CSteamProto::OnAuthorization); -} - -void CSteamProto::OnAuthorization(const NETLIBHTTPREQUEST *response, void *arg) -{ - if (response == NULL) { - SetStatus(ID_STATUS_OFFLINE); - return; - } - - JSONROOT root(response->pData); - - JSONNODE *node = json_get(root, "success"); - if (json_as_bool(node) == 0) - { - node = json_get(root, "message"); - ptrT message(json_as_string(node)); - if (!lstrcmpi(message, L"Incorrect login")) - { - ShowNotification(TranslateTS(message)); - SetStatus(ID_STATUS_OFFLINE); - return; - } - - node = json_get(root, "emailauth_needed"); - if (json_as_bool(node) > 0) - { - node = json_get(root, "emailsteamid"); - ptrA guardId(mir_u2a(ptrT(json_as_string(node)))); - - node = json_get(root, "emaildomain"); - ptrA emailDomain(mir_utf8encodeW(ptrT(json_as_string(node)))); - - GuardParam guard; - mir_strncpy(guard.domain, emailDomain, SIZEOF(guard.domain)); - - if (DialogBoxParam(g_hInstance, MAKEINTRESOURCE(IDD_GUARD), NULL, CSteamProto::GuardProc, (LPARAM)&guard) != 1) { - return; - } - - ptrA username(mir_urlEncode(ptrA(mir_utf8encodeW(getWStringA("Username"))))); - ptrA base64RsaEncryptedPassword(getStringA("EncryptedPassword")); - ptrA timestamp(getStringA("Timestamp")); - - PushRequest( - new SteamWebApi::AuthorizationRequest(username, base64RsaEncryptedPassword, timestamp, guardId, guard.code), - &CSteamProto::OnAuthorization); - } - - node = json_get(root, "captcha_needed"); - if (json_as_bool(node) > 0) - { - node = json_get(root, "captcha_gid"); - ptrA captchaId(mir_u2a(ptrT(json_as_string(node)))); - - char url[MAX_PATH]; - mir_snprintf(url, SIZEOF(url), STEAM_COM_URL "/public/captcha.php?gid=%s", captchaId); - - SteamWebApi::GetCaptchaRequest *request = new SteamWebApi::GetCaptchaRequest(url); - request->szUrl = (char*)request->url.c_str(); - NETLIBHTTPREQUEST *response = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)m_hNetlibUser, (LPARAM)request); - delete request; - - CaptchaParam captcha = { 0 }; - captcha.size = response->dataLength; - captcha.data = (BYTE*)mir_alloc(captcha.size); - memcpy(captcha.data, response->pData, captcha.size); - - CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)response); - - int res = DialogBoxParam( - g_hInstance, - MAKEINTRESOURCE(IDD_CAPTCHA), - NULL, - CSteamProto::CaptchaProc, - (LPARAM)&captcha); - - mir_free(captcha.data); - - if (res != 1) - { - SetStatus(ID_STATUS_OFFLINE); - return; - } - - ptrA username(mir_urlEncode(ptrA(mir_utf8encodeW(getWStringA("Username"))))); - ptrA base64RsaEncryptedPassword(getStringA("EncryptedPassword")); - ptrA timestamp(getStringA("Timestamp")); - - PushRequest( - new SteamWebApi::AuthorizationRequest(username, base64RsaEncryptedPassword, timestamp, "-1", "", captchaId, captcha.text), - &CSteamProto::OnAuthorization); - } - - return; - } - - node = json_get(root, "login_complete"); - if (!json_as_bool(node)) - { - SetStatus(ID_STATUS_OFFLINE); - return; - } - - node = json_get(root, "oauth"); - JSONROOT nroot(_T2A(ptrT(json_as_string(node)))); - - node = json_get(nroot, "steamid"); - ptrA steamId(mir_u2a(ptrT(json_as_string(node)))); - setString("SteamID", steamId); - - node = json_get(nroot, "oauth_token"); - ptrA token(mir_u2a(ptrT(json_as_string(node)))); - setString("TokenSecret", token); - - node = json_get(nroot, "webcookie"); - ptrA cookie(mir_u2a(ptrT(json_as_string(node)))); - - delSetting("Timestamp"); - delSetting("EncryptedPassword"); - - PushRequest( - new SteamWebApi::GetSessionRequest(token, steamId, cookie), - &CSteamProto::OnGotSession); - - PushRequest( - new SteamWebApi::LogonRequest(token), - &CSteamProto::OnLoggedOn); -} - -void CSteamProto::OnGotSession(const NETLIBHTTPREQUEST *response, void *arg) -{ - if (response == NULL) - return; - - for (int i = 0; i < response->headersCount; i++) - { - if (lstrcmpiA(response->headers[i].szName, "Set-Cookie")) - continue; - - 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); - setString("SessionID", sessionId.c_str()); - break; - } -} - -void CSteamProto::OnLoggedOn(const NETLIBHTTPREQUEST *response, void *arg) -{ - if (response == NULL) - { - SetStatus(ID_STATUS_OFFLINE); - return; - } - - JSONROOT root(response->pData); - - JSONNODE *node = json_get(root, "error"); - ptrW error(json_as_string(node)); - if (lstrcmpi(error, L"OK")/* || response->resultCode == HTTP_STATUS_UNAUTHORIZED*/) - { - //delSetting("TokenSecret"); - //delSetting("Cookie"); - - // set status to offline - SetStatus(ID_STATUS_OFFLINE); - return; - } - - node = json_get(root, "umqid"); - setString("UMQID", ptrA(mir_u2a(ptrT(json_as_string(node))))); - - node = json_get(root, "message"); - setDword("MessageID", json_as_int(node)); - - // load contact list - ptrA token(getStringA("TokenSecret")); - ptrA steamId(getStringA("SteamID")); - - PushRequest( - new SteamWebApi::GetFriendListRequest(token, steamId), - &CSteamProto::OnGotFriendList); - - // start polling thread - m_hPollingThread = ForkThreadEx(&CSteamProto::PollingThread, 0, NULL); - - // go to online now - ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)ID_STATUS_CONNECTING, m_iStatus = m_iDesiredStatus); +#include "common.h"
+
+bool CSteamProto::IsOnline()
+{
+ return m_iStatus > ID_STATUS_OFFLINE && m_hPollingThread;
+}
+
+bool CSteamProto::IsMe(const char *steamId)
+{
+ ptrA mySteamId(getStringA("SteamID"));
+ if (!lstrcmpA(steamId, mySteamId))
+ return true;
+
+ return false;
+}
+
+void CSteamProto::OnGotRsaKey(const NETLIBHTTPREQUEST *response, void *arg)
+{
+ if (response == NULL)
+ return;
+
+ // load rsa key parts
+ JSONROOT root(response->pData);
+ if (!root)
+ return;
+
+ JSONNODE *node = json_get(root, "success");
+ if (!json_as_bool(node)) {
+ return;
+ }
+
+ node = json_get(root, "publickey_mod");
+ ptrA modulus(mir_u2a(ptrT(json_as_string(node))));
+
+ // exponent "010001" is used as constant in CSteamProto::RsaEncrypt
+ /*node = json_get(root, "publickey_exp");
+ ptrA exponent(mir_u2a(ptrT(json_as_string(node))));*/
+
+ node = json_get(root, "timestamp");
+ ptrA timestamp(mir_u2a(ptrT(json_as_string(node))));
+ setString("Timestamp", timestamp);
+
+ // encrcrypt password
+ ptrA base64RsaEncryptedPassword;
+ ptrA password(getStringA("Password"));
+
+ DWORD error = 0;
+ DWORD encryptedSize = 0;
+ DWORD passwordSize = (DWORD)strlen(password);
+ if ((error = RsaEncrypt(modulus, password, NULL, encryptedSize)) != 0)
+ {
+ debugLogA("CSteamProto::OnGotRsaKey: encryption error (%lu)", error);
+ return;
+ }
+
+ BYTE *encryptedPassword = (BYTE*)mir_calloc(encryptedSize);
+ if ((error = RsaEncrypt(modulus, password, encryptedPassword, encryptedSize)) != 0)
+ {
+ debugLogA("CSteamProto::OnGotRsaKey: encryption error (%lu)", error);
+ return;
+ }
+
+ base64RsaEncryptedPassword = mir_base64_encode(encryptedPassword, encryptedSize);
+ mir_free(encryptedPassword);
+
+ //setString("EncryptedPassword", base64RsaEncryptedPassword);
+ PasswordParam *param = (PasswordParam*)mir_alloc(sizeof(PasswordParam));
+ strcpy(param->password, base64RsaEncryptedPassword);
+ strcpy(param->timestamp, timestamp);
+
+ // run authorization request
+ ptrA username(mir_utf8encodeW(getWStringA("Username")));
+
+ PushRequest(
+ new SteamWebApi::AuthorizationRequest(username, base64RsaEncryptedPassword, timestamp),
+ &CSteamProto::OnAuthorization, param, ARG_NO_FREE);
+}
+
+void CSteamProto::OnAuthorization(const NETLIBHTTPREQUEST *response, void *arg)
+{
+ if (response == NULL) {
+ SetStatus(ID_STATUS_OFFLINE);
+ return;
+ }
+
+ JSONROOT root(response->pData);
+
+ JSONNODE *node = json_get(root, "success");
+ if (json_as_bool(node) == 0)
+ {
+ node = json_get(root, "message");
+ ptrT message(json_as_string(node));
+ if (!lstrcmpi(message, L"Incorrect login"))
+ {
+ ShowNotification(TranslateTS(message));
+ SetStatus(ID_STATUS_OFFLINE);
+ mir_free(arg);
+ return;
+ }
+
+ node = json_get(root, "emailauth_needed");
+ if (json_as_bool(node) > 0)
+ {
+ node = json_get(root, "emailsteamid");
+ ptrA guardId(mir_u2a(ptrT(json_as_string(node))));
+
+ node = json_get(root, "emaildomain");
+ ptrA emailDomain(mir_utf8encodeW(ptrT(json_as_string(node))));
+
+ GuardParam guard;
+ mir_strncpy(guard.domain, emailDomain, SIZEOF(guard.domain));
+
+ if (DialogBoxParam(g_hInstance, MAKEINTRESOURCE(IDD_GUARD), NULL, CSteamProto::GuardProc, (LPARAM)&guard) != IDOK)
+ return;
+
+ ptrA username(mir_utf8encodeW(getWStringA("Username")));
+ PasswordParam *param = (PasswordParam*)arg;
+
+ PushRequest(
+ new SteamWebApi::AuthorizationRequest(username, param->password, param->timestamp, guard.code),
+ &CSteamProto::OnAuthorization);
+ return;
+ }
+
+ node = json_get(root, "captcha_needed");
+ if (json_as_bool(node) > 0)
+ {
+ node = json_get(root, "captcha_gid");
+ ptrA captchaId(mir_u2a(ptrT(json_as_string(node))));
+
+ SteamWebApi::GetCaptchaRequest *request = new SteamWebApi::GetCaptchaRequest(captchaId);
+ NETLIBHTTPREQUEST *response = request->Send(m_hNetlibUser);
+ delete request;
+
+ CaptchaParam captcha = { 0 };
+ captcha.size = response->dataLength;
+ captcha.data = (BYTE*)mir_alloc(captcha.size);
+ memcpy(captcha.data, response->pData, captcha.size);
+
+ CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)response);
+
+ int res = DialogBoxParam(
+ g_hInstance,
+ MAKEINTRESOURCE(IDD_CAPTCHA),
+ NULL,
+ CSteamProto::CaptchaProc,
+ (LPARAM)&captcha);
+
+ mir_free(captcha.data);
+
+ if (res != 1)
+ {
+ SetStatus(ID_STATUS_OFFLINE);
+ return;
+ }
+
+ ptrA username(mir_utf8encodeW(getWStringA("Username")));
+ PasswordParam *param = (PasswordParam*)arg;
+
+ PushRequest(
+ new SteamWebApi::AuthorizationRequest(username, param->password, param->timestamp, captchaId, captcha.text),
+ &CSteamProto::OnAuthorization);
+ return;
+ }
+
+ SetStatus(ID_STATUS_OFFLINE);
+ mir_free(arg);
+ return;
+ }
+
+ mir_free(arg);
+
+ node = json_get(root, "login_complete");
+ if (!json_as_bool(node))
+ {
+ SetStatus(ID_STATUS_OFFLINE);
+ return;
+ }
+
+ node = json_get(root, "oauth");
+ JSONROOT nroot(_T2A(ptrT(json_as_string(node))));
+
+ node = json_get(nroot, "steamid");
+ ptrA steamId(mir_u2a(ptrT(json_as_string(node))));
+ setString("SteamID", steamId);
+
+ node = json_get(nroot, "oauth_token");
+ ptrA token(mir_u2a(ptrT(json_as_string(node))));
+ setString("TokenSecret", token);
+
+ node = json_get(nroot, "webcookie");
+ ptrA cookie(mir_u2a(ptrT(json_as_string(node))));
+
+ delSetting("Timestamp");
+ delSetting("EncryptedPassword");
+
+ PushRequest(
+ new SteamWebApi::GetSessionRequest(token, steamId, cookie),
+ &CSteamProto::OnGotSession);
+
+ PushRequest(
+ new SteamWebApi::LogonRequest(token),
+ &CSteamProto::OnLoggedOn);
+}
+
+void CSteamProto::OnGotSession(const NETLIBHTTPREQUEST *response, void *arg)
+{
+ if(response == NULL)
+ return;
+
+ for (int i = 0; i < response->headersCount; i++)
+ {
+ if (lstrcmpiA(response->headers[i].szName, "Set-Cookie"))
+ continue;
+
+ 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);
+ setString("SessionID", sessionId.c_str());
+ break;
+ }
+}
+
+void CSteamProto::OnLoggedOn(const NETLIBHTTPREQUEST *response, void *arg)
+{
+ if (response == NULL)
+ {
+ SetStatus(ID_STATUS_OFFLINE);
+ return;
+ }
+
+ JSONROOT root(response->pData);
+
+ JSONNODE *node = json_get(root, "error");
+ ptrW error(json_as_string(node));
+ if (lstrcmpi(error, L"OK")/* || response->resultCode == HTTP_STATUS_UNAUTHORIZED*/)
+ {
+ //delSetting("TokenSecret");
+ //delSetting("Cookie");
+
+ // set status to offline
+ SetStatus(ID_STATUS_OFFLINE);
+ return;
+ }
+
+ node = json_get(root, "umqid");
+ setString("UMQID", ptrA(mir_u2a(ptrT(json_as_string(node)))));
+
+ node = json_get(root, "message");
+ setDword("MessageID", json_as_int(node));
+
+ // load contact list
+ ptrA token(getStringA("TokenSecret"));
+ ptrA steamId(getStringA("SteamID"));
+
+ PushRequest(
+ new SteamWebApi::GetFriendListRequest(token, steamId),
+ &CSteamProto::OnGotFriendList);
+
+ // start polling thread
+ m_hPollingThread = ForkThreadEx(&CSteamProto::PollingThread, 0, NULL);
+
+ // go to online now
+ ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)ID_STATUS_CONNECTING, m_iStatus = m_iDesiredStatus);
}
\ No newline at end of file diff --git a/protocols/Steam/src/steam_pooling.cpp b/protocols/Steam/src/steam_pooling.cpp index 7097cc0dff..1bf9f8314e 100644 --- a/protocols/Steam/src/steam_pooling.cpp +++ b/protocols/Steam/src/steam_pooling.cpp @@ -178,10 +178,8 @@ void CSteamProto::PollingThread(void*) while (!isTerminated && !breaked && errors < POLLING_ERRORS_LIMIT) { SteamWebApi::PollRequest *request = new SteamWebApi::PollRequest(token, umqId, messageId, IdleSeconds()); - debugLogA("CSteamProto::PollingThread: %s", request->szUrl); - request->szUrl = (char*)request->url.c_str(); - request->nlc = m_pollingConnection; - NETLIBHTTPREQUEST *response = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)m_hNetlibUser, (LPARAM)request); + //request->nlc = m_pollingConnection; + NETLIBHTTPREQUEST *response = request->Send(m_hNetlibUser); delete request; if (response == NULL || response->resultCode != HTTP_STATUS_OK) diff --git a/protocols/Steam/src/steam_proto.h b/protocols/Steam/src/steam_proto.h index 6ee5b79a8a..514410caea 100644 --- a/protocols/Steam/src/steam_proto.h +++ b/protocols/Steam/src/steam_proto.h @@ -1,338 +1,345 @@ -#ifndef _STEAM_PROTO_H_ -#define _STEAM_PROTO_H_ - -#define STEAM_SEARCH_BYID 1001 -#define STEAM_SEARCH_BYNAME 1002 -#define STEAM_TYPING_TIME 10 - -struct GuardParam -{ - char code[10]; - char domain[32]; -}; - -struct CaptchaParam -{ - BYTE *data; - size_t size; - char text[10]; -}; - -struct SendAuthParam -{ - MCONTACT hContact; - HANDLE hAuth; -}; - -struct SendMessageParam -{ - MCONTACT hContact; - HANDLE hMessage; - const char *msg; - int flags; -}; - -struct STEAM_SEARCH_RESULT -{ - PROTOSEARCHRESULT hdr; - JSONNODE *data; -}; - -enum -{ - CMI_AUTH_REQUEST, - //CMI_AUTH_GRANT, - //CMI_AUTH_REVOKE, - CMI_BLOCK, - CMI_JOIN_GAME, - SMI_BLOCKED_LIST, - CMI_MAX // this item shall be the last one -}; - -enum HTTP_STATUS -{ - HTTP_STATUS_NONE = 0, - HTTP_STATUS_OK = 200, - HTTP_STATUS_FOUND = 302, - HTTP_STATUS_BAD_REQUEST = 400, - HTTP_STATUS_UNAUTHORIZED = 401, - HTTP_STATUS_FORBIDDEN = 403, - HTTP_STATUS_NOT_FOUND = 404, - HTTP_STATUS_METHOD_NOT_ALLOWED = 405, - HTTP_STATUS_TOO_MANY_REQUESTS = 429, - HTTP_STATUS_SERVICE_UNAVAILABLE = 503, - HTTP_STATUS_INSUFICIENTE_STORAGE = 507 -}; - -enum ARG_FREE_TYPE -{ - ARG_NO_FREE, - ARG_MIR_FREE -}; - -typedef void (CSteamProto::*RESPONSE)(const NETLIBHTTPREQUEST *response, void *arg); - -struct QueueItem -{ - SteamWebApi::HttpRequest *request; - void *arg; - ARG_FREE_TYPE arg_free_type; - RESPONSE responseCallback; - //RESPONSE responseFailedCallback; - - QueueItem(SteamWebApi::HttpRequest *request) : - request(request), arg(NULL), responseCallback(NULL)/*, responseFailedCallback(NULL)*/ { } - - QueueItem(SteamWebApi::HttpRequest *request, RESPONSE response) : - request(request), arg(NULL), responseCallback(response)/*, responseFailedCallback(NULL)*/ { } - - //QueueItem(SteamWebApi::HttpRequest *request, RESPONSE response, RESPONSE responseFailedCallback) : - // request(request), arg(NULL), responseCallback(response), responseFailedCallback(responseFailedCallback) { } - - ~QueueItem() { - // Free request - delete request; - - // Free argument - switch (arg_free_type) - { - case ARG_NO_FREE: - break; - case ARG_MIR_FREE: - mir_free(arg); - default: - break; - } - - responseCallback = NULL; - //responseFailedCallback = NULL; - } -}; - -class CSteamProto : public PROTO<CSteamProto> -{ -public: - // PROTO_INTERFACE - CSteamProto(const char *protoName, const wchar_t *userName); - ~CSteamProto(); - - // PROTO_INTERFACE - virtual MCONTACT __cdecl AddToList(int flags, PROTOSEARCHRESULT *psr); - virtual MCONTACT __cdecl AddToListByEvent(int flags, int iContact, MEVENT hDbEvent); - - virtual int __cdecl Authorize(MEVENT hDbEvent); - virtual int __cdecl AuthDeny(MEVENT hDbEvent, const TCHAR *szReason); - virtual int __cdecl AuthRecv(MCONTACT hContact, PROTORECVEVENT *); - virtual int __cdecl AuthRequest(MCONTACT hContact, const TCHAR * szMessage); - - virtual HANDLE __cdecl FileAllow(MCONTACT hContact, HANDLE hTransfer, const TCHAR* szPath); - virtual int __cdecl FileCancel(MCONTACT hContact, HANDLE hTransfer); - virtual int __cdecl FileDeny(MCONTACT hContact, HANDLE hTransfer, const TCHAR* szReason); - virtual int __cdecl FileResume(HANDLE hTransfer, int *action, const TCHAR** szFilename); - - virtual DWORD_PTR __cdecl GetCaps(int type, MCONTACT hContact = NULL); - virtual int __cdecl GetInfo(MCONTACT hContact, int infoType); - - virtual HANDLE __cdecl SearchBasic(const TCHAR *id); - virtual HANDLE __cdecl SearchByEmail(const TCHAR *email); - virtual HANDLE __cdecl SearchByName(const TCHAR *nick, const TCHAR *firstName, const TCHAR *lastName); - virtual HWND __cdecl SearchAdvanced(HWND owner); - virtual HWND __cdecl CreateExtendedSearchUI(HWND owner); - - virtual int __cdecl RecvContacts(MCONTACT hContact, PROTORECVEVENT*); - virtual int __cdecl RecvFile(MCONTACT hContact, PROTORECVFILET*); - virtual int __cdecl RecvMsg(MCONTACT hContact, PROTORECVEVENT*); - virtual int __cdecl RecvUrl(MCONTACT hContact, PROTORECVEVENT*); - - virtual int __cdecl SendContacts(MCONTACT hContact, int flags, int nContacts, MCONTACT *hContactsList); - virtual HANDLE __cdecl SendFile(MCONTACT hContact, const TCHAR* szDescription, TCHAR** ppszFiles); - virtual int __cdecl SendMsg(MCONTACT hContact, int flags, const char* msg); - virtual int __cdecl SendUrl(MCONTACT hContact, int flags, const char* url); - - virtual int __cdecl SetApparentMode(MCONTACT hContact, int mode); - virtual int __cdecl SetStatus(int iNewStatus); - - virtual HANDLE __cdecl GetAwayMsg(MCONTACT hContact); - virtual int __cdecl RecvAwayMsg(MCONTACT hContact, int mode, PROTORECVEVENT* evt); - virtual int __cdecl SetAwayMsg(int m_iStatus, const TCHAR* msg); - - virtual int __cdecl UserIsTyping(MCONTACT hContact, int type); - - virtual int __cdecl OnEvent(PROTOEVENTTYPE eventType, WPARAM wParam, LPARAM lParam); - - // instances - static CSteamProto* InitProtoInstance(const char* protoName, const wchar_t* userName); - static int UninitProtoInstance(CSteamProto* ppro); - - static CSteamProto* GetContactProtoInstance(MCONTACT hContact); - static void UninitProtoInstances(); - - // menus - static void InitMenus(); - static void UninitMenus(); - -protected: - bool isTerminated; - time_t m_idleTS; - HANDLE m_evRequestsQueue, m_hQueueThread; - HANDLE m_pollingConnection, m_hPollingThread; - ULONG hAuthProcess; - ULONG hMessageProcess; - CRITICAL_SECTION contact_search_lock; - CRITICAL_SECTION requests_queue_lock; - CRITICAL_SECTION set_status_lock; - LIST<QueueItem> requestsQueue; - - // instances - static LIST<CSteamProto> InstanceList; - static int CompareProtos(const CSteamProto *p1, const CSteamProto *p2); - - // queue - void InitQueue(); - void UninitQueue(); - - void StartQueue(); - void StopQueue(); - - void PushRequest(SteamWebApi::HttpRequest *request); - void PushRequest(SteamWebApi::HttpRequest *request, RESPONSE response); - void PushRequest(SteamWebApi::HttpRequest *request, RESPONSE response, void *arg, ARG_FREE_TYPE arg_free_type); - - void ExecuteRequest(QueueItem *requestItem); - - void __cdecl SendMsgThread(void*); - void __cdecl QueueThread(void*); - - // pooling thread - void ParsePollData(JSONNODE *data); - void __cdecl PollingThread(void*); - - // account - bool IsOnline(); - bool IsMe(const char *steamId); - - void OnGotRsaKey(const NETLIBHTTPREQUEST *response, void *arg); - - void OnAuthorization(const NETLIBHTTPREQUEST *response, void *arg); - void OnGotSession(const NETLIBHTTPREQUEST *response, void *arg); - - void OnLoggedOn(const NETLIBHTTPREQUEST *response, void *arg); - - // contacts - void SetContactStatus(MCONTACT hContact, WORD status); - void SetAllContactsStatus(WORD status); - - MCONTACT GetContactFromAuthEvent(MEVENT hEvent); - - void UpdateContact(MCONTACT hContact, JSONNODE *data); - void ProcessContact(std::map<std::string, JSONNODE*>::iterator *it, MCONTACT hContact); - - void ContactIsRemoved(MCONTACT hContact); - void ContactIsFriend(MCONTACT hContact); - void ContactIsIgnored(MCONTACT hContact); - - MCONTACT FindContact(const char *steamId); - MCONTACT AddContact(const char *steamId, bool isTemporary = false); - - void OnGotFriendList(const NETLIBHTTPREQUEST *response, void *arg); - void OnGotBlockList(const NETLIBHTTPREQUEST *response, void *arg); - void OnGotUserSummaries(const NETLIBHTTPREQUEST *response, void *arg); - void OnGotAvatar(const NETLIBHTTPREQUEST *response, void *arg); - - void OnFriendAdded(const NETLIBHTTPREQUEST *response, void *arg); - void OnFriendBlocked(const NETLIBHTTPREQUEST *response, void *arg); - void OnFriendRemoved(const NETLIBHTTPREQUEST *response, void *arg); - - void OnAuthRequested(const NETLIBHTTPREQUEST *response, void *arg); - - void OnPendingApproved(const NETLIBHTTPREQUEST *response, void *arg); - void OnPendingIgnoreded(const NETLIBHTTPREQUEST *response, void *arg); - - void OnSearchByIdEnded(const NETLIBHTTPREQUEST *response, void *arg); - - void OnSearchByNameStarted(const NETLIBHTTPREQUEST *response, void *arg); - void OnSearchByNameFinished(const NETLIBHTTPREQUEST *response, void *arg); - - // messages - void OnMessageSent(const NETLIBHTTPREQUEST *response, void *arg); - - // menus - HGENMENU m_hMenuRoot; - static HANDLE hChooserMenu; - static HGENMENU contactMenuItems[CMI_MAX]; - - int __cdecl AuthRequestCommand(WPARAM, LPARAM); - int __cdecl BlockCommand(WPARAM, LPARAM); - int __cdecl JoinToGameCommand(WPARAM, LPARAM); - - INT_PTR __cdecl OpenBlockListCommand(WPARAM, LPARAM); - - static INT_PTR MenuChooseService(WPARAM wParam, LPARAM lParam); - - static int PrebuildContactMenu(WPARAM wParam, LPARAM lParam); - int OnPrebuildContactMenu(WPARAM wParam, LPARAM); - - void OnInitStatusMenu(); - - // avatars - TCHAR* GetAvatarFilePath(MCONTACT hContact); - bool GetDbAvatarInfo(PROTO_AVATAR_INFORMATIONT &pai); - void CheckAvatarChange(MCONTACT hContact, std::string avatarUrl); - - INT_PTR __cdecl GetAvatarInfo(WPARAM, LPARAM); - INT_PTR __cdecl GetAvatarCaps(WPARAM, LPARAM); - INT_PTR __cdecl GetMyAvatar(WPARAM, LPARAM); - - // xstatuses - INT_PTR __cdecl OnGetXStatusEx(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl OnGetXStatusIcon(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl OnRequestAdvStatusIconIdx(WPARAM wParam, LPARAM lParam); - HICON GetXStatusIcon(int status, UINT flags); - int GetContactXStatus(MCONTACT hContact); - - // events - int OnModulesLoaded(WPARAM, LPARAM); - int OnPreShutdown(WPARAM, LPARAM); - int __cdecl OnIdleChanged(WPARAM, LPARAM); - INT_PTR __cdecl OnAccountManagerInit(WPARAM wParam, LPARAM lParam); - static int __cdecl OnOptionsInit(void *obj, WPARAM wParam, LPARAM lParam); - - // utils - static WORD SteamToMirandaStatus(int state); - static int MirandaToSteamState(int status); - - static int RsaEncrypt(const char *pszModulus, const char *data, BYTE *encrypted, DWORD &encryptedSize); - - MEVENT AddDBEvent(MCONTACT hContact, WORD type, DWORD timestamp, DWORD flags, DWORD cbBlob, PBYTE pBlob); - - static void CSteamProto::ShowNotification(const wchar_t *message, int flags = 0, MCONTACT hContact = NULL); - static void CSteamProto::ShowNotification(const wchar_t *caption, const wchar_t *message, int flags = 0, MCONTACT hContact = NULL); - - // dialog procs - static INT_PTR CALLBACK GuardProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); - static INT_PTR CALLBACK CaptchaProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); - static INT_PTR CALLBACK MainOptionsProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); - static LRESULT CALLBACK BlockListOptionsSubProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); - static INT_PTR CALLBACK BlockListOptionsProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - - // helpers - inline int IdleSeconds() { - // Based on idle time we report Steam server will mark us as online/away/snooze - switch (this->m_iStatus) { - case ID_STATUS_AWAY: - return STEAM_API_IDLEOUT_AWAY; - case ID_STATUS_NA: - return STEAM_API_IDLEOUT_SNOOZE; - default: - return 0; - } - - // ... or we can report real idle info - // return m_idleTS ? time(0) - m_idleTS : 0; - } -}; - -int OnReloadIcons(WPARAM wParam, LPARAM lParam); -void SetContactExtraIcon(MCONTACT hContact, int status); - +#ifndef _STEAM_PROTO_H_
+#define _STEAM_PROTO_H_
+
+#define STEAM_SEARCH_BYID 1001
+#define STEAM_SEARCH_BYNAME 1002
+#define STEAM_TYPING_TIME 10
+
+struct PasswordParam
+{
+ char password[513];
+ char timestamp[16];
+};
+
+
+struct GuardParam
+{
+ char code[10];
+ char domain[32];
+};
+
+struct CaptchaParam
+{
+ BYTE *data;
+ size_t size;
+ char text[10];
+};
+
+struct SendAuthParam
+{
+ MCONTACT hContact;
+ HANDLE hAuth;
+};
+
+struct SendMessageParam
+{
+ MCONTACT hContact;
+ HANDLE hMessage;
+ const char *msg;
+ int flags;
+};
+
+struct STEAM_SEARCH_RESULT
+{
+ PROTOSEARCHRESULT hdr;
+ JSONNODE *data;
+};
+
+enum
+{
+ CMI_AUTH_REQUEST,
+ //CMI_AUTH_GRANT,
+ //CMI_AUTH_REVOKE,
+ CMI_BLOCK,
+ CMI_JOIN_GAME,
+ SMI_BLOCKED_LIST,
+ CMI_MAX // this item shall be the last one
+};
+
+enum HTTP_STATUS
+{
+ HTTP_STATUS_NONE = 0,
+ HTTP_STATUS_OK = 200,
+ HTTP_STATUS_FOUND = 302,
+ HTTP_STATUS_BAD_REQUEST = 400,
+ HTTP_STATUS_UNAUTHORIZED = 401,
+ HTTP_STATUS_FORBIDDEN = 403,
+ HTTP_STATUS_NOT_FOUND = 404,
+ HTTP_STATUS_METHOD_NOT_ALLOWED = 405,
+ HTTP_STATUS_TOO_MANY_REQUESTS = 429,
+ HTTP_STATUS_SERVICE_UNAVAILABLE = 503,
+ HTTP_STATUS_INSUFICIENTE_STORAGE = 507
+};
+
+enum ARG_FREE_TYPE
+{
+ ARG_NO_FREE,
+ ARG_MIR_FREE
+};
+
+typedef void (CSteamProto::*RESPONSE)(const NETLIBHTTPREQUEST *response, void *arg);
+
+struct QueueItem
+{
+ SteamWebApi::HttpRequest *request;
+ void *arg;
+ ARG_FREE_TYPE arg_free_type;
+ RESPONSE responseCallback;
+ //RESPONSE responseFailedCallback;
+
+ QueueItem(SteamWebApi::HttpRequest *request) :
+ request(request), arg(NULL), responseCallback(NULL)/*, responseFailedCallback(NULL)*/ { }
+
+ QueueItem(SteamWebApi::HttpRequest *request, RESPONSE response) :
+ request(request), arg(NULL), responseCallback(response)/*, responseFailedCallback(NULL)*/ { }
+
+ //QueueItem(SteamWebApi::HttpRequest *request, RESPONSE response, RESPONSE responseFailedCallback) :
+ // request(request), arg(NULL), responseCallback(response), responseFailedCallback(responseFailedCallback) { }
+
+ ~QueueItem() {
+ // Free request
+ delete request;
+
+ // Free argument
+ switch (arg_free_type)
+ {
+ case ARG_NO_FREE:
+ break;
+ case ARG_MIR_FREE:
+ mir_free(arg);
+ default:
+ break;
+ }
+
+ responseCallback = NULL;
+ //responseFailedCallback = NULL;
+ }
+};
+
+class CSteamProto : public PROTO<CSteamProto>
+{
+public:
+ // PROTO_INTERFACE
+ CSteamProto(const char *protoName, const wchar_t *userName);
+ ~CSteamProto();
+
+ // PROTO_INTERFACE
+ virtual MCONTACT __cdecl AddToList(int flags, PROTOSEARCHRESULT *psr);
+ virtual MCONTACT __cdecl AddToListByEvent(int flags, int iContact, MEVENT hDbEvent);
+
+ virtual int __cdecl Authorize(MEVENT hDbEvent);
+ virtual int __cdecl AuthDeny(MEVENT hDbEvent, const TCHAR *szReason);
+ virtual int __cdecl AuthRecv(MCONTACT hContact, PROTORECVEVENT *);
+ virtual int __cdecl AuthRequest(MCONTACT hContact, const TCHAR * szMessage);
+
+ virtual HANDLE __cdecl FileAllow(MCONTACT hContact, HANDLE hTransfer, const TCHAR* szPath);
+ virtual int __cdecl FileCancel(MCONTACT hContact, HANDLE hTransfer);
+ virtual int __cdecl FileDeny(MCONTACT hContact, HANDLE hTransfer, const TCHAR* szReason);
+ virtual int __cdecl FileResume(HANDLE hTransfer, int *action, const TCHAR** szFilename);
+
+ virtual DWORD_PTR __cdecl GetCaps(int type, MCONTACT hContact = NULL);
+ virtual int __cdecl GetInfo(MCONTACT hContact, int infoType);
+
+ virtual HANDLE __cdecl SearchBasic(const TCHAR *id);
+ virtual HANDLE __cdecl SearchByEmail(const TCHAR *email);
+ virtual HANDLE __cdecl SearchByName(const TCHAR *nick, const TCHAR *firstName, const TCHAR *lastName);
+ virtual HWND __cdecl SearchAdvanced(HWND owner);
+ virtual HWND __cdecl CreateExtendedSearchUI(HWND owner);
+
+ virtual int __cdecl RecvContacts(MCONTACT hContact, PROTORECVEVENT*);
+ virtual int __cdecl RecvFile(MCONTACT hContact, PROTORECVFILET*);
+ virtual int __cdecl RecvMsg(MCONTACT hContact, PROTORECVEVENT*);
+ virtual int __cdecl RecvUrl(MCONTACT hContact, PROTORECVEVENT*);
+
+ virtual int __cdecl SendContacts(MCONTACT hContact, int flags, int nContacts, MCONTACT *hContactsList);
+ virtual HANDLE __cdecl SendFile(MCONTACT hContact, const TCHAR* szDescription, TCHAR** ppszFiles);
+ virtual int __cdecl SendMsg(MCONTACT hContact, int flags, const char* msg);
+ virtual int __cdecl SendUrl(MCONTACT hContact, int flags, const char* url);
+
+ virtual int __cdecl SetApparentMode(MCONTACT hContact, int mode);
+ virtual int __cdecl SetStatus(int iNewStatus);
+
+ virtual HANDLE __cdecl GetAwayMsg(MCONTACT hContact);
+ virtual int __cdecl RecvAwayMsg(MCONTACT hContact, int mode, PROTORECVEVENT* evt);
+ virtual int __cdecl SetAwayMsg(int m_iStatus, const TCHAR* msg);
+
+ virtual int __cdecl UserIsTyping(MCONTACT hContact, int type);
+
+ virtual int __cdecl OnEvent(PROTOEVENTTYPE eventType, WPARAM wParam, LPARAM lParam);
+
+ // instances
+ static CSteamProto* InitProtoInstance(const char* protoName, const wchar_t* userName);
+ static int UninitProtoInstance(CSteamProto* ppro);
+
+ static CSteamProto* GetContactProtoInstance(MCONTACT hContact);
+ static void UninitProtoInstances();
+
+ // menus
+ static void InitMenus();
+ static void UninitMenus();
+
+protected:
+ bool isTerminated;
+ time_t m_idleTS;
+ HANDLE m_evRequestsQueue, m_hQueueThread;
+ HANDLE m_pollingConnection, m_hPollingThread;
+ ULONG hAuthProcess;
+ ULONG hMessageProcess;
+ CRITICAL_SECTION contact_search_lock;
+ CRITICAL_SECTION requests_queue_lock;
+ CRITICAL_SECTION set_status_lock;
+ LIST<QueueItem> requestsQueue;
+
+ // instances
+ static LIST<CSteamProto> InstanceList;
+ static int CompareProtos(const CSteamProto *p1, const CSteamProto *p2);
+
+ // queue
+ void InitQueue();
+ void UninitQueue();
+
+ void StartQueue();
+ void StopQueue();
+
+ void PushRequest(SteamWebApi::HttpRequest *request);
+ void PushRequest(SteamWebApi::HttpRequest *request, RESPONSE response);
+ void PushRequest(SteamWebApi::HttpRequest *request, RESPONSE response, void *arg, ARG_FREE_TYPE arg_free_type);
+
+ void ExecuteRequest(QueueItem *requestItem);
+
+ void __cdecl SendMsgThread(void*);
+ void __cdecl QueueThread(void*);
+
+ // pooling thread
+ void ParsePollData(JSONNODE *data);
+ void __cdecl PollingThread(void*);
+
+ // account
+ bool IsOnline();
+ bool IsMe(const char *steamId);
+
+ void OnGotRsaKey(const NETLIBHTTPREQUEST *response, void *arg);
+
+ void OnAuthorization(const NETLIBHTTPREQUEST *response, void *arg);
+ void OnGotSession(const NETLIBHTTPREQUEST *response, void *arg);
+
+ void OnLoggedOn(const NETLIBHTTPREQUEST *response, void *arg);
+
+ // contacts
+ void SetContactStatus(MCONTACT hContact, WORD status);
+ void SetAllContactsStatus(WORD status);
+
+ MCONTACT GetContactFromAuthEvent(MEVENT hEvent);
+
+ void UpdateContact(MCONTACT hContact, JSONNODE *data);
+ void ProcessContact(std::map<std::string, JSONNODE*>::iterator *it, MCONTACT hContact);
+
+ void ContactIsRemoved(MCONTACT hContact);
+ void ContactIsFriend(MCONTACT hContact);
+ void ContactIsIgnored(MCONTACT hContact);
+
+ MCONTACT FindContact(const char *steamId);
+ MCONTACT AddContact(const char *steamId, bool isTemporary = false);
+
+ void OnGotFriendList(const NETLIBHTTPREQUEST *response, void *arg);
+ void OnGotBlockList(const NETLIBHTTPREQUEST *response, void *arg);
+ void OnGotUserSummaries(const NETLIBHTTPREQUEST *response, void *arg);
+ void OnGotAvatar(const NETLIBHTTPREQUEST *response, void *arg);
+
+ void OnFriendAdded(const NETLIBHTTPREQUEST *response, void *arg);
+ void OnFriendBlocked(const NETLIBHTTPREQUEST *response, void *arg);
+ void OnFriendRemoved(const NETLIBHTTPREQUEST *response, void *arg);
+
+ void OnAuthRequested(const NETLIBHTTPREQUEST *response, void *arg);
+
+ void OnPendingApproved(const NETLIBHTTPREQUEST *response, void *arg);
+ void OnPendingIgnoreded(const NETLIBHTTPREQUEST *response, void *arg);
+
+ void OnSearchByIdEnded(const NETLIBHTTPREQUEST *response, void *arg);
+
+ void OnSearchByNameStarted(const NETLIBHTTPREQUEST *response, void *arg);
+ void OnSearchByNameFinished(const NETLIBHTTPREQUEST *response, void *arg);
+
+ // messages
+ void OnMessageSent(const NETLIBHTTPREQUEST *response, void *arg);
+
+ // menus
+ HGENMENU m_hMenuRoot;
+ static HANDLE hChooserMenu;
+ static HGENMENU contactMenuItems[CMI_MAX];
+
+ int __cdecl AuthRequestCommand(WPARAM, LPARAM);
+ int __cdecl BlockCommand(WPARAM, LPARAM);
+ int __cdecl JoinToGameCommand(WPARAM, LPARAM);
+
+ INT_PTR __cdecl OpenBlockListCommand(WPARAM, LPARAM);
+
+ static INT_PTR MenuChooseService(WPARAM wParam, LPARAM lParam);
+
+ static int PrebuildContactMenu(WPARAM wParam, LPARAM lParam);
+ int OnPrebuildContactMenu(WPARAM wParam, LPARAM);
+
+ void OnInitStatusMenu();
+
+ // avatars
+ TCHAR* GetAvatarFilePath(MCONTACT hContact);
+ bool GetDbAvatarInfo(PROTO_AVATAR_INFORMATIONT &pai);
+ void CheckAvatarChange(MCONTACT hContact, std::string avatarUrl);
+
+ INT_PTR __cdecl GetAvatarInfo(WPARAM, LPARAM);
+ INT_PTR __cdecl GetAvatarCaps(WPARAM, LPARAM);
+ INT_PTR __cdecl GetMyAvatar(WPARAM, LPARAM);
+
+ // xstatuses
+ INT_PTR __cdecl OnGetXStatusEx(WPARAM wParam, LPARAM lParam);
+ INT_PTR __cdecl OnGetXStatusIcon(WPARAM wParam, LPARAM lParam);
+ INT_PTR __cdecl OnRequestAdvStatusIconIdx(WPARAM wParam, LPARAM lParam);
+ HICON GetXStatusIcon(int status, UINT flags);
+ int GetContactXStatus(MCONTACT hContact);
+
+ // events
+ int OnModulesLoaded(WPARAM, LPARAM);
+ int OnPreShutdown(WPARAM, LPARAM);
+ int __cdecl OnIdleChanged(WPARAM, LPARAM);
+ INT_PTR __cdecl OnAccountManagerInit(WPARAM wParam, LPARAM lParam);
+ static int __cdecl OnOptionsInit(void *obj, WPARAM wParam, LPARAM lParam);
+
+ // utils
+ static WORD SteamToMirandaStatus(int state);
+ static int MirandaToSteamState(int status);
+
+ static int RsaEncrypt(const char *pszModulus, const char *data, BYTE *encrypted, DWORD &encryptedSize);
+
+ MEVENT AddDBEvent(MCONTACT hContact, WORD type, DWORD timestamp, DWORD flags, DWORD cbBlob, PBYTE pBlob);
+
+ static void CSteamProto::ShowNotification(const wchar_t *message, int flags = 0, MCONTACT hContact = NULL);
+ static void CSteamProto::ShowNotification(const wchar_t *caption, const wchar_t *message, int flags = 0, MCONTACT hContact = NULL);
+
+ // dialog procs
+ static INT_PTR CALLBACK GuardProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
+ static INT_PTR CALLBACK CaptchaProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
+ static INT_PTR CALLBACK MainOptionsProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
+ static LRESULT CALLBACK BlockListOptionsSubProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+ static INT_PTR CALLBACK BlockListOptionsProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+ // helpers
+ inline int IdleSeconds() {
+ // Based on idle time we report Steam server will mark us as online/away/snooze
+ switch (this->m_iStatus) {
+ case ID_STATUS_AWAY:
+ return STEAM_API_IDLEOUT_AWAY;
+ case ID_STATUS_NA:
+ return STEAM_API_IDLEOUT_SNOOZE;
+ default:
+ return 0;
+ }
+
+ // ... or we can report real idle info
+ // return m_idleTS ? time(0) - m_idleTS : 0;
+ }
+};
+
+int OnReloadIcons(WPARAM wParam, LPARAM lParam);
+void SetContactExtraIcon(MCONTACT hContact, int status);
+
#endif //_STEAM_PROTO_H_
\ No newline at end of file diff --git a/protocols/Steam/src/steam_queue.cpp b/protocols/Steam/src/steam_queue.cpp index ff61da24a7..6ef1aee6f7 100644 --- a/protocols/Steam/src/steam_queue.cpp +++ b/protocols/Steam/src/steam_queue.cpp @@ -63,9 +63,7 @@ void CSteamProto::StopQueue() ptrA umqid(getStringA("UMQID"));
SteamWebApi::HttpRequest *request = new SteamWebApi::LogoffRequest(token, umqid);
- debugLogA("CSteamProto::StopQueue: %s", request->szUrl);
- request->szUrl = (char*)request->url.c_str();
- NETLIBHTTPREQUEST *response = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)m_hNetlibUser, (LPARAM)request);
+ NETLIBHTTPREQUEST *response = request->Send(m_hNetlibUser);
CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)response);
delete request;
@@ -113,10 +111,7 @@ void CSteamProto::ExecuteRequest(QueueItem *item) return;
}
- debugLogA("CSteamProto::ExecuteRequest: %s", item->request->szUrl);
-
- item->request->szUrl = (char*)item->request->url.c_str();
- NETLIBHTTPREQUEST *response = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)m_hNetlibUser, (LPARAM)item->request);
+ NETLIBHTTPREQUEST *response = item->request->Send(m_hNetlibUser);
if (item->responseCallback != NULL)
(this->*(item->responseCallback))(response, item->arg);
@@ -128,7 +123,7 @@ void CSteamProto::ExecuteRequest(QueueItem *item) }
/*else if (requestItem->responseFailedCallback != NULL)
{
- (this->*(requestItem->responseFailedCallback))(response);
+ (this->*(requestItem->responseFailedCallback))(response);
}*/
delete item;
diff --git a/protocols/Steam/src/version.h b/protocols/Steam/src/version.h index e33f795d5b..007f994986 100644 --- a/protocols/Steam/src/version.h +++ b/protocols/Steam/src/version.h @@ -1,7 +1,7 @@ #define __MAJOR_VERSION 0
#define __MINOR_VERSION 11
#define __RELEASE_NUM 3
-#define __BUILD_NUM 0
+#define __BUILD_NUM 1
#include <stdver.h>
|