From 5c46a4ff3d889e7ef4b2c4a8e6c353f84207a7ab Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Mon, 30 Mar 2015 19:23:00 +0000 Subject: SkypeWeb: massive improvements (patch from MikalaiR) git-svn-id: http://svn.miranda-ng.org/main/trunk@12556 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/SkypeWeb/src/http_request.h | 2 +- protocols/SkypeWeb/src/requests/contacts.h | 4 +- protocols/SkypeWeb/src/requests/endpoint.h | 5 ++- protocols/SkypeWeb/src/requests/logout.h | 10 ++++- protocols/SkypeWeb/src/requests/status.h | 39 +++++++++++++---- protocols/SkypeWeb/src/skype_events.cpp | 68 ++++++++++++++--------------- protocols/SkypeWeb/src/skype_proto.cpp | 70 +----------------------------- protocols/SkypeWeb/src/skype_proto.h | 2 +- protocols/SkypeWeb/src/skype_status.cpp | 62 ++++++++++++++++++++++++++ 9 files changed, 144 insertions(+), 118 deletions(-) create mode 100644 protocols/SkypeWeb/src/skype_status.cpp (limited to 'protocols/SkypeWeb/src') diff --git a/protocols/SkypeWeb/src/http_request.h b/protocols/SkypeWeb/src/http_request.h index db6c2caeec..a7d9eb8937 100644 --- a/protocols/SkypeWeb/src/http_request.h +++ b/protocols/SkypeWeb/src/http_request.h @@ -288,7 +288,7 @@ public: { va_list args; va_start(args, urlFormat); - this->HttpsRequest::HttpsRequest(REQUEST_POST, urlFormat, args); + this->HttpRequest::HttpRequest(REQUEST_POST, urlFormat, args); va_end(args); //Headers << CHAR_VALUE("Content-Type", "application/x-www-form-urlencoded; charset=utf-8"); diff --git a/protocols/SkypeWeb/src/requests/contacts.h b/protocols/SkypeWeb/src/requests/contacts.h index 21bf1d56a5..55d35334ae 100644 --- a/protocols/SkypeWeb/src/requests/contacts.h +++ b/protocols/SkypeWeb/src/requests/contacts.h @@ -18,8 +18,8 @@ public: class GetContactsInfoRequest : public HttpsPostRequest { public: - GetContactsInfoRequest(const char *token, const LIST &skypenames/*, const char *skypename = "self"*/) : - HttpsPostRequest("api.skype.com/users/self/contacts/profiles"/*, skypename*/) + GetContactsInfoRequest(const char *token, const LIST &skypenames, const char *skypename = "self") : + HttpsPostRequest("api.skype.com/users/%s/contacts/profiles", skypename) { Headers << CHAR_VALUE("X-Skypetoken", token) diff --git a/protocols/SkypeWeb/src/requests/endpoint.h b/protocols/SkypeWeb/src/requests/endpoint.h index 3bd6827ac4..d6e0fdda7c 100644 --- a/protocols/SkypeWeb/src/requests/endpoint.h +++ b/protocols/SkypeWeb/src/requests/endpoint.h @@ -4,8 +4,8 @@ class GetEndpointRequest : public HttpsRequest { public: - GetEndpointRequest(const char *regToken, const char *endpointURL) : - HttpsRequest(REQUEST_PUT, endpointURL) + GetEndpointRequest(const char *regToken, const char *endpointID) : + HttpsRequest(REQUEST_PUT, "client-s.gateway.messenger.live.com/v1/users/ME/endpoints/%s/presenceDocs/messagingService", mir_urlEncode(endpointID)) { flags |= NLHRF_SSL; CMStringA auth = "registrationToken="; @@ -15,6 +15,7 @@ public: << CHAR_VALUE("Expires", "0") << CHAR_VALUE("RegistrationToken", auth) << CHAR_VALUE("Content-Type", "application/json; charset=UTF-8") + << CHAR_VALUE("BehaviorOverride", "redirectAs404") << CHAR_VALUE("Referer", "https://web.skype.com/main") << CHAR_VALUE("Origin", "https://web.skype.com") << CHAR_VALUE("Connection", "keep-alive"); diff --git a/protocols/SkypeWeb/src/requests/logout.h b/protocols/SkypeWeb/src/requests/logout.h index b1585c9e91..2083973e7c 100644 --- a/protocols/SkypeWeb/src/requests/logout.h +++ b/protocols/SkypeWeb/src/requests/logout.h @@ -4,7 +4,15 @@ class LogoutRequest : public HttpsPostRequest { public: - LogoutRequest() : HttpsPostRequest("login.skype.com/logout") { } + LogoutRequest() : HttpsPostRequest("login.skype.com/logout") + { + //flags = NLHRF_SSL | NLHRF_NODUMPSEND | NLHRF_DUMPASTEXT; + Url + << INT_VALUE("client_id", 578134) + << CHAR_VALUE("redirect_uri", "https%3A%2F%2Fweb.skype.com&intsrc=client-_-webapp-_-production-_-go-signin"); + Headers + << CHAR_VALUE("Referer", "https://web.skype.com/"); + } }; #endif //_SKYPE_REQUEST_LOGOUT_H_ diff --git a/protocols/SkypeWeb/src/requests/status.h b/protocols/SkypeWeb/src/requests/status.h index f37c936ec4..2f0f9f4f42 100644 --- a/protocols/SkypeWeb/src/requests/status.h +++ b/protocols/SkypeWeb/src/requests/status.h @@ -14,19 +14,42 @@ public: << CHAR_VALUE("Expires", "0") << CHAR_VALUE("RegistrationToken", auth) << CHAR_VALUE("Content-Type", "application/json; charset = UTF-8") + << CHAR_VALUE("BehaviorOverride", "redirectAs404") << CHAR_VALUE("Referer", "https://web.skype.com/main") << CHAR_VALUE("Origin", "https://web.skype.com") << CHAR_VALUE("Connection", "keep-alive"); const char *data; - if (status == ID_STATUS_ONLINE) - data = "{\"status\":\"Online\"}"; - else if (status == ID_STATUS_INVISIBLE) - data = "{\"status\":\"Hidden\"}"; - else if (status == ID_STATUS_AWAY) - data = "{\"status\":\"Away\"}"; - else - data = "{\"status\":\"Online\"}"; + switch (status) + { + case ID_STATUS_ONLINE: + { + data = "{\"status\":\"Online\"}"; + break; + } + case ID_STATUS_AWAY: + { + data = "{\"status\":\"Away\"}"; + break; + } + case ID_STATUS_DND: + { + data = "{\"status\":\"Busy\"}"; + break; + } + case ID_STATUS_IDLE: + { + data = "{\"status\":\"Idle\"}"; + break; + } + case ID_STATUS_INVISIBLE: + { + data = "{\"status\":\"Hidden\"}"; + break; + } + default: + data = "{\"status\":\"Online\"}"; + } Body << VALUE(data); } }; diff --git a/protocols/SkypeWeb/src/skype_events.cpp b/protocols/SkypeWeb/src/skype_events.cpp index b64618e6cb..2414a799ed 100644 --- a/protocols/SkypeWeb/src/skype_events.cpp +++ b/protocols/SkypeWeb/src/skype_events.cpp @@ -104,33 +104,25 @@ void CSkypeProto::OnGetRegInfo(const NETLIBHTTPREQUEST *response) std::regex regex; std::smatch match; std::string content = response->pData; - for (int i = 0; i < response->headersCount; i++) - { - if (mir_strcmpi(response->headers[i].szName, "Set-RegistrationToken") == 0) - { - regex = "^(.+?)=(.+?);"; - content = response->headers[i].szValue; - if (std::regex_search(content, match, regex)) - RegInfo[match[1]] = match[2]; - } - else if (mir_strcmpi(response->headers[i].szName, "Location") == 0) - { - content = response->headers[i].szValue; - RegInfo["Location"] = content; - } - else + for (int i = 0; i < response->headersCount; i++) { + if (_stricmp(response->headers[i].szName, "Set-RegistrationToken")) continue; + + CMStringA szValue = response->headers[i].szValue, szCookieName, szCookieVal; + int iStart = 0; + while (true) { + bool bFirstToken = (iStart == 0); + CMStringA szToken = szValue.Tokenize(";", iStart).Trim(); + if (iStart == -1) + break; + int iStart2 = 0; + szCookieName = szToken.Tokenize("=", iStart2); + szCookieVal = szToken.Mid(iStart2); + setString(szCookieName, szCookieVal); + } } - setString("RegistrationToken", RegInfo["registrationToken"].c_str()); - setString("Endpoint", urlDecode(RegInfo["Location"].c_str()).c_str()); - - debugLogA(getStringA("RegistrationToken")); - debugLogA(getStringA("Endpoint")); - CMStringA endpointURL = getStringA("Endpoint"); - endpointURL += "/presenceDocs/messagingService"; - PushRequest(new GetEndpointRequest(ptrA(getStringA("RegistrationToken")), endpointURL)); - PushRequest(new SetStatusRequest(ptrA(getStringA("RegistrationToken")), ID_STATUS_ONLINE), &CSkypeProto::OnSetStatus); - //SetStatus(ID_STATUS_ONLINE); + PushRequest(new GetEndpointRequest(getStringA("registrationToken"), getStringA("endpointId"))); + PushRequest(new SetStatusRequest(getStringA("registrationToken"), ID_STATUS_ONLINE), &CSkypeProto::OnSetStatus); } void CSkypeProto::OnSetStatus(const NETLIBHTTPREQUEST *response) @@ -139,24 +131,30 @@ void CSkypeProto::OnSetStatus(const NETLIBHTTPREQUEST *response) return; JSONROOT root(response->pData); + if (root == NULL) return; - JSONNODE *status_json = json_get(root, "status"); - debugLog(json_as_string(status_json)); - - const char* status = (const char *)json_as_string(status_json); - debugLogA(status); + JSONNODE *status_json = json_get(root, "status"); + TCHAR *status = json_as_string(status_json); int old_status = m_iStatus; int iNewStatus; - if (mir_strcmp(status, "O")==0) + if (!mir_tstrcmpi(status, _T("Online"))) iNewStatus = ID_STATUS_ONLINE; - else if (mir_strcmp(status, "H") == 0) + else if (!mir_tstrcmpi(status, _T("Hidden"))) iNewStatus = ID_STATUS_INVISIBLE; - else if (mir_strcmp(status, "A") == 0) + else if (!mir_tstrcmpi(status, _T("Away"))) iNewStatus = ID_STATUS_AWAY; + else if (!mir_tstrcmpi(status, _T("Idle"))) + iNewStatus = ID_STATUS_IDLE; + else if (!mir_tstrcmpi(status, _T("Busy"))) + iNewStatus = ID_STATUS_DND; else - iNewStatus = ID_STATUS_ONLINE; + iNewStatus = ID_STATUS_OFFLINE; m_iStatus = iNewStatus; - ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus); + + if (iNewStatus == ID_STATUS_OFFLINE) + SetStatus(ID_STATUS_OFFLINE); + else + ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus); } \ No newline at end of file diff --git a/protocols/SkypeWeb/src/skype_proto.cpp b/protocols/SkypeWeb/src/skype_proto.cpp index 14e520c239..e5ef4991d6 100644 --- a/protocols/SkypeWeb/src/skype_proto.cpp +++ b/protocols/SkypeWeb/src/skype_proto.cpp @@ -33,9 +33,9 @@ DWORD_PTR CSkypeProto::GetCaps(int type, MCONTACT) case PFLAGNUM_1: return PF1_AUTHREQ; case PFLAGNUM_2: - return PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY; + return PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_HEAVYDND; case PFLAGNUM_3: - return PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY; + return PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_HEAVYDND; case PFLAGNUM_4: return PF4_FORCEADDED | PF4_NOAUTHDENYREASON; case PFLAG_UNIQUEIDTEXT: @@ -122,73 +122,7 @@ int CSkypeProto::SendUrl(MCONTACT, int, const char*) { return 0; } int CSkypeProto::SetApparentMode(MCONTACT, int) { return 0; } -int CSkypeProto::SetStatus(int iNewStatus) -{ - if (iNewStatus == m_iDesiredStatus) - { - return 0; - } - - debugLogA(__FUNCTION__ ": changing status from %i to %i", m_iStatus, iNewStatus); - - int old_status = m_iStatus; - m_iDesiredStatus = iNewStatus; - CMStringA endpointURL = getStringA("Endpoint"); - endpointURL += "/presenceDocs/messagingService"; - - if (iNewStatus == ID_STATUS_OFFLINE) - { - // logout - PushRequest(new LogoutRequest()); - requestQueue->Stop(); - - if (!Miranda_Terminated()) - { - SetAllContactsStatus(ID_STATUS_OFFLINE); - } - - m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE; - } - else if (iNewStatus == ID_STATUS_INVISIBLE) - { - PushRequest(new GetEndpointRequest(ptrA(getStringA("RegistrationToken")), endpointURL)); - PushRequest(new SetStatusRequest(ptrA(getStringA("RegistrationToken")), ID_STATUS_INVISIBLE), &CSkypeProto::OnSetStatus); - } - else if (iNewStatus == ID_STATUS_AWAY) - { - PushRequest(new GetEndpointRequest(ptrA(getStringA("RegistrationToken")), endpointURL)); - PushRequest(new SetStatusRequest(ptrA(getStringA("RegistrationToken")), ID_STATUS_AWAY), &CSkypeProto::OnSetStatus); - } - else - { - if (old_status == ID_STATUS_CONNECTING) - { - return 0; - } - - if (m_iStatus == ID_STATUS_INVISIBLE || m_iStatus == ID_STATUS_AWAY) - { - PushRequest(new GetEndpointRequest(ptrA(getStringA("RegistrationToken")), endpointURL)); - PushRequest(new SetStatusRequest(ptrA(getStringA("RegistrationToken")), ID_STATUS_ONLINE), &CSkypeProto::OnSetStatus); - } - else if (old_status == ID_STATUS_OFFLINE && m_iStatus == ID_STATUS_OFFLINE) - { - // login - m_iStatus = ID_STATUS_CONNECTING; - - requestQueue->Start(); - PushRequest(new LoginRequest(), &CSkypeProto::OnLoginFirst); - } - else - { - // set status - m_iStatus = iNewStatus; - } - } - ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus); - return 0; -} HANDLE CSkypeProto::GetAwayMsg(MCONTACT) { return 0; } diff --git a/protocols/SkypeWeb/src/skype_proto.h b/protocols/SkypeWeb/src/skype_proto.h index 32bcd1f411..bab1b29248 100644 --- a/protocols/SkypeWeb/src/skype_proto.h +++ b/protocols/SkypeWeb/src/skype_proto.h @@ -174,7 +174,7 @@ private: // utils static void ShowNotification(const TCHAR *message, int flags = 0, MCONTACT hContact = NULL); static void ShowNotification(const TCHAR *caption, const TCHAR *message, int flags = 0, MCONTACT hContact = NULL); - + void CSkypeProto::SetServerStatus(int iNewStatus); static bool IsFileExists(std::tstring path); std::string urlDecode(std::string SRC); diff --git a/protocols/SkypeWeb/src/skype_status.cpp b/protocols/SkypeWeb/src/skype_status.cpp new file mode 100644 index 0000000000..b40aa44198 --- /dev/null +++ b/protocols/SkypeWeb/src/skype_status.cpp @@ -0,0 +1,62 @@ +#include "common.h" +int CSkypeProto::SetStatus(int iNewStatus) +{ + if (iNewStatus == m_iDesiredStatus) + { + return 0; + } + + debugLogA(__FUNCTION__ ": changing status from %i to %i", m_iStatus, iNewStatus); + + int old_status = m_iStatus; + m_iDesiredStatus = iNewStatus; + switch (iNewStatus) + { + case ID_STATUS_OFFLINE: + PushRequest(new LogoutRequest()); + requestQueue->Stop(); + if (!Miranda_Terminated()) + { + SetAllContactsStatus(ID_STATUS_OFFLINE); + } + + m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE; + break; + + case ID_STATUS_INVISIBLE: + case ID_STATUS_AWAY: + case ID_STATUS_DND: + case ID_STATUS_IDLE: + PushRequest(new GetEndpointRequest(ptrA(getStringA("registrationToken")), getStringA("endpointId"))); + PushRequest(new SetStatusRequest(ptrA(getStringA("registrationToken")), iNewStatus), &CSkypeProto::OnSetStatus); + break; + default: + if (old_status == ID_STATUS_CONNECTING) + return 0; + + if (m_iStatus == ID_STATUS_INVISIBLE || m_iStatus == ID_STATUS_AWAY || m_iStatus == ID_STATUS_DND || m_iStatus == ID_STATUS_IDLE) + { + PushRequest(new GetEndpointRequest(ptrA(getStringA("registrationToken")), getStringA("endpointId"))); + PushRequest(new SetStatusRequest(ptrA(getStringA("registrationToken")), ID_STATUS_ONLINE), &CSkypeProto::OnSetStatus); + } + else if (old_status == ID_STATUS_OFFLINE && m_iStatus == ID_STATUS_OFFLINE) + { + // login + m_iStatus = ID_STATUS_CONNECTING; + + requestQueue->Start(); + PushRequest(new LoginRequest(), &CSkypeProto::OnLoginFirst); + } + else + { + // set status + m_iStatus = iNewStatus; + } + break; + + } + ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus); + return 0; +} + +void CSkypeProto::SetServerStatus(int iNewStatus){ return; } \ No newline at end of file -- cgit v1.2.3