summaryrefslogtreecommitdiff
path: root/protocols/SkypeWeb
diff options
context:
space:
mode:
authorKirill Volinsky <mataes2007@gmail.com>2015-04-03 05:33:18 +0000
committerKirill Volinsky <mataes2007@gmail.com>2015-04-03 05:33:18 +0000
commita50ae784ce7394b2621cf42a28cab7edd31e6c6a (patch)
treed32d2925947e77442d364c1849adfd54bb896276 /protocols/SkypeWeb
parent2e511ab1b1ff3d78c695874e3b28ff4ce7680cc8 (diff)
login fix and some other fixes (patch by MikalaiR)
git-svn-id: http://svn.miranda-ng.org/main/trunk@12581 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols/SkypeWeb')
-rw-r--r--protocols/SkypeWeb/src/common.h1
-rw-r--r--protocols/SkypeWeb/src/requests/endpoint.h9
-rw-r--r--protocols/SkypeWeb/src/requests/messages.h29
-rw-r--r--protocols/SkypeWeb/src/requests/poll.h4
-rw-r--r--protocols/SkypeWeb/src/requests/reg_info.h4
-rw-r--r--protocols/SkypeWeb/src/requests/status.h8
-rw-r--r--protocols/SkypeWeb/src/requests/subscriptions.h4
-rw-r--r--protocols/SkypeWeb/src/skype_contacts.cpp2
-rw-r--r--protocols/SkypeWeb/src/skype_events.cpp81
-rw-r--r--protocols/SkypeWeb/src/skype_poll_processing.cpp84
-rw-r--r--protocols/SkypeWeb/src/skype_polling.cpp21
-rw-r--r--protocols/SkypeWeb/src/skype_proto.cpp29
-rw-r--r--protocols/SkypeWeb/src/skype_proto.h11
-rw-r--r--protocols/SkypeWeb/src/skype_utils.cpp120
14 files changed, 340 insertions, 67 deletions
diff --git a/protocols/SkypeWeb/src/common.h b/protocols/SkypeWeb/src/common.h
index 97e8356f09..e2f4ef2f95 100644
--- a/protocols/SkypeWeb/src/common.h
+++ b/protocols/SkypeWeb/src/common.h
@@ -35,6 +35,7 @@
#include <m_string.h>
#include <m_json.h>
#include <m_timezones.h>
+#include <m_version.h>
struct CSkypeProto;
diff --git a/protocols/SkypeWeb/src/requests/endpoint.h b/protocols/SkypeWeb/src/requests/endpoint.h
index f6dd9c604c..a5d05b7ec7 100644
--- a/protocols/SkypeWeb/src/requests/endpoint.h
+++ b/protocols/SkypeWeb/src/requests/endpoint.h
@@ -4,8 +4,8 @@
class GetEndpointRequest : public HttpRequest
{
public:
- GetEndpointRequest(const char *regToken, const char *endpointID) :
- HttpRequest(REQUEST_PUT, FORMAT, "client-s.gateway.messenger.live.com/v1/users/ME/endpoints/%s/presenceDocs/messagingService", ptrA(mir_urlEncode(endpointID)))
+ GetEndpointRequest(const char *regToken, const char *endpointID, const char *server = "client-s.gateway.messenger.live.com") :
+ HttpRequest(REQUEST_PUT, FORMAT, "%s/v1/users/ME/endpoints/%s/presenceDocs/messagingService", server, ptrA(mir_urlEncode(endpointID)))
{
Headers
<< CHAR_VALUE("Accept", "application/json, text/javascript")
@@ -16,9 +16,10 @@ public:
<< CHAR_VALUE("Referer", "https://web.skype.com/main")
<< CHAR_VALUE("Origin", "https://web.skype.com")
<< CHAR_VALUE("Connection", "keep-alive");
-
+ CMStringA data;
+ data.AppendFormat ("{\"id\":\"messagingService\",\"type\":\"EndpointPresenceDoc\",\"selfLink\":\"uri\",\"privateInfo\":{\"epname\":\"Miranda\"},\"publicInfo\":{\"capabilities\":\"\",\"typ\":125,\"skypeNameVersion\":\"0/%s//\",\"nodeInfo\":\"xx\",\"version\":\"0/%s\"}}", MIRANDA_VERSION_STRING, MIRANDA_VERSION_STRING);
Body <<
- VALUE("{\"id\":\"messagingService\",\"type\":\"EndpointPresenceDoc\",\"selfLink\":\"uri\",\"privateInfo\":{\"epname\":\"Miranda\"},\"publicInfo\":{\"capabilities\":\"\",\"type\":1,\"skypeNameVersion\":\"0/0.95.4//\",\"nodeInfo\":\"xx\",\"version\":\"0/0.95.4\"}}");
+ VALUE(data);
}
};
#endif //_SKYPE_REQUEST_ENDPOINT_H_ \ No newline at end of file
diff --git a/protocols/SkypeWeb/src/requests/messages.h b/protocols/SkypeWeb/src/requests/messages.h
index e86f54fce9..ecd939bbd0 100644
--- a/protocols/SkypeWeb/src/requests/messages.h
+++ b/protocols/SkypeWeb/src/requests/messages.h
@@ -4,8 +4,8 @@
class SendMsgRequest : public HttpRequest
{
public:
- SendMsgRequest(const char *regToken, const char *username, const char *message) :
- HttpRequest(REQUEST_POST, FORMAT, "client-s.gateway.messenger.live.com/v1/users/ME/conversations/8:%s/messages", username)
+ SendMsgRequest(const char *regToken, const char *username, const char *message, const char *server = "client-s.gateway.messenger.live.com") :
+ HttpRequest(REQUEST_POST, FORMAT, "%s/v1/users/ME/conversations/8:%s/messages", server, username)
{
Headers
<< CHAR_VALUE("Accept", "application / json, text / javascript")
@@ -21,4 +21,29 @@ public:
}
};
+class SendTypingRequest : public HttpRequest
+{
+public:
+ SendTypingRequest(const char *regToken, const char *username,bool bstate, const char *server = "client-s.gateway.messenger.live.com") :
+ HttpRequest(REQUEST_POST, FORMAT, "%s/v1/users/ME/conversations/8:%s/messages", server, mir_urlEncode(username))
+ {
+ Headers
+ << CHAR_VALUE("Accept", "application / json, text / javascript")
+ << CHAR_VALUE("Expires", "0")
+ << FORMAT_VALUE("RegistrationToken", "registrationToken=%s", regToken)
+ << 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");
+ CMStringA state;
+ if (bstate) state = "Control/Typing";
+ else state = "Control/ClearTyping";
+ CMStringA data;
+ data.AppendFormat("{\"clienmessageid\":%d, \"content\":\"\", \"messagetype\":\"%s\", \"contenttype\":\"text\"}", time(NULL), state);
+
+ Body << VALUE(data);
+ }
+};
+
#endif //_SKYPE_REQUEST_MESSAGES_H_
diff --git a/protocols/SkypeWeb/src/requests/poll.h b/protocols/SkypeWeb/src/requests/poll.h
index 48108ccdbc..538e482eac 100644
--- a/protocols/SkypeWeb/src/requests/poll.h
+++ b/protocols/SkypeWeb/src/requests/poll.h
@@ -4,8 +4,8 @@
class PollRequest : public HttpRequest
{
public:
- PollRequest(const char *regToken) :
- HttpRequest(REQUEST_POST, "client-s.gateway.messenger.live.com/v1/users/ME/endpoints/SELF/subscriptions/0/poll")
+ PollRequest(const char *regToken, const char *server = "client-s.gateway.messenger.live.com") :
+ HttpRequest(REQUEST_POST, FORMAT, "%s/v1/users/ME/endpoints/SELF/subscriptions/0/poll", server)
{
//timeout = 30 * 1000;
//flags |= NLHRF_PERSISTENT;
diff --git a/protocols/SkypeWeb/src/requests/reg_info.h b/protocols/SkypeWeb/src/requests/reg_info.h
index 47f649ec61..d1f5191fc9 100644
--- a/protocols/SkypeWeb/src/requests/reg_info.h
+++ b/protocols/SkypeWeb/src/requests/reg_info.h
@@ -4,8 +4,8 @@
class GetRegInfoRequest : public HttpRequest
{
public:
- GetRegInfoRequest(const char *token) :
- HttpRequest(REQUEST_POST, "client-s.gateway.messenger.live.com/v1/users/ME/endpoints")
+ GetRegInfoRequest(const char *token, const char *server = "client-s.gateway.messenger.live.com") :
+ HttpRequest(REQUEST_POST, FORMAT, "%s/v1/users/ME/endpoints", server)
{
Headers
<< CHAR_VALUE("Accept", "application/json, text/javascript")
diff --git a/protocols/SkypeWeb/src/requests/status.h b/protocols/SkypeWeb/src/requests/status.h
index 1fc30bac81..a8bbdc82f0 100644
--- a/protocols/SkypeWeb/src/requests/status.h
+++ b/protocols/SkypeWeb/src/requests/status.h
@@ -4,10 +4,12 @@
class SetStatusRequest : public HttpRequest
{
public:
- SetStatusRequest(const char *regToken, const char *status) :
- HttpRequest(REQUEST_PUT, "client-s.gateway.messenger.live.com/v1/users/ME/presenceDocs/messagingService")
+ SetStatusRequest(const char *regToken, const char *status, const char *server = "client-s.gateway.messenger.live.com") :
+ HttpRequest(REQUEST_PUT, FORMAT, "%s/v1/users/ME/presenceDocs/messagingService", server)
{
CMStringA auth = "registrationToken=";
+ CMStringA statuss;
+ statuss.AppendFormat("{\"status\":\"%s\"}", status);
auth += regToken;
Headers
<< CHAR_VALUE("Accept", "application/json, text/javascript")
@@ -19,7 +21,7 @@ public:
<< CHAR_VALUE("Origin", "https://web.skype.com")
<< CHAR_VALUE("Connection", "keep-alive");
- Body << FORMAT_VALUE("{\"status\":\"%s\"}", status);
+ Body << VALUE(statuss);
}
};
diff --git a/protocols/SkypeWeb/src/requests/subscriptions.h b/protocols/SkypeWeb/src/requests/subscriptions.h
index 624c7685a4..cd29aa8da4 100644
--- a/protocols/SkypeWeb/src/requests/subscriptions.h
+++ b/protocols/SkypeWeb/src/requests/subscriptions.h
@@ -4,8 +4,8 @@
class SubscriptionsRequest : public HttpRequest
{
public:
- SubscriptionsRequest(const char *regToken) :
- HttpRequest(REQUEST_POST, "client-s.gateway.messenger.live.com/v1/users/ME/endpoints/SELF/subscriptions")
+ SubscriptionsRequest(const char *regToken, const char *server = "client-s.gateway.messenger.live.com") :
+ HttpRequest(REQUEST_POST, FORMAT, "%s/v1/users/ME/endpoints/SELF/subscriptions", server)
{
Headers
<< CHAR_VALUE("Accept", "application/json, text/javascript")
diff --git a/protocols/SkypeWeb/src/skype_contacts.cpp b/protocols/SkypeWeb/src/skype_contacts.cpp
index c8a889d316..98563bcda5 100644
--- a/protocols/SkypeWeb/src/skype_contacts.cpp
+++ b/protocols/SkypeWeb/src/skype_contacts.cpp
@@ -11,6 +11,8 @@ void CSkypeProto::SetContactStatus(MCONTACT hContact, WORD status)
if (oldStatus != status)
{
setWord(hContact, "Status", status);
+ if (status == ID_STATUS_OFFLINE)
+ db_unset(hContact, m_szModuleName, "MirVer");
}
}
diff --git a/protocols/SkypeWeb/src/skype_events.cpp b/protocols/SkypeWeb/src/skype_events.cpp
index 35f3746713..945770255a 100644
--- a/protocols/SkypeWeb/src/skype_events.cpp
+++ b/protocols/SkypeWeb/src/skype_events.cpp
@@ -89,7 +89,7 @@ void CSkypeProto::OnLoginSecond(const NETLIBHTTPREQUEST *response)
cookies[match[1]] = match[2];
}
- PushRequest(new GetRegInfoRequest(token.c_str()), &CSkypeProto::OnGetRegInfo);
+ PushRequest(new GetRegInfoRequest(token.c_str(), getStringA("Server")), &CSkypeProto::OnGetRegInfo);
PushRequest(new GetProfileRequest(token.c_str()), &CSkypeProto::LoadProfile);
PushRequest(new GetContactListRequest(token.c_str()), &CSkypeProto::LoadContactList);
}
@@ -103,33 +103,56 @@ void CSkypeProto::OnGetRegInfo(const NETLIBHTTPREQUEST *response)
std::smatch match;
std::string content = response->pData;
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);
+ if (!mir_strcmpi(response->headers[i].szName, "Set-RegistrationToken"))
+ {
+ 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);
+ }
+ }
+ else if (!mir_strcmpi(response->headers[i].szName, "Location"))
+ {
+ CMStringA szValue = response->headers[i].szValue, szCookieName, szCookieVal;
+ setString("Server", GetServerFromUrl(szValue));
}
- }
- PushRequest(new GetEndpointRequest(getStringA("registrationToken"), getStringA("endpointId")));
- SubscriptionsRequest *request = new SubscriptionsRequest(getStringA("registrationToken"));
- request->Send(m_hNetlibUser);
- delete request;
+ }
+ if (response->resultCode != 201)
+ {
+ PushRequest(new GetRegInfoRequest(getStringA("Token"), getStringA("Server")), &CSkypeProto::OnGetRegInfo);
+ return;
+ }
+ PushRequest(new GetEndpointRequest(getStringA("registrationToken"), getStringA("endpointId"), getStringA("Server")), &CSkypeProto::OnGetEndpoint);
+ isTerminated = false;
m_hPollingThread = ForkThreadEx(&CSkypeProto::PollingThread, 0, NULL);
m_iStatus = m_iDesiredStatus;
ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)ID_STATUS_CONNECTING, m_iStatus);
- PushRequest(new SetStatusRequest(ptrA(getStringA("registrationToken")), MirandaToSkypeStatus(m_iStatus)), &CSkypeProto::OnSetStatus);
+ PushRequest(new SetStatusRequest(ptrA(getStringA("registrationToken")), MirandaToSkypeStatus(m_iStatus), getStringA("Server")), &CSkypeProto::OnSetStatus);
+}
+
+void CSkypeProto::OnGetEndpoint(const NETLIBHTTPREQUEST *response)
+{
+ if (response == NULL)
+ return;
+
+ JSONROOT root(response->pData);
+
+ if (root == NULL)
+ return;
+
+ ptrA selfLink(mir_t2a(ptrT(json_as_string(json_get(root, "selfLink")))));
+
+ setString("SelfEndpointName", SelfUrlToName(selfLink));
}
void CSkypeProto::OnSetStatus(const NETLIBHTTPREQUEST *response)
@@ -143,21 +166,9 @@ void CSkypeProto::OnSetStatus(const NETLIBHTTPREQUEST *response)
return;
JSONNODE *status_json = json_get(root, "status");
- TCHAR *status = json_as_string(status_json);
+ ptrA status(mir_t2a(ptrT(json_as_string(status_json))));
int old_status = m_iStatus;
- int iNewStatus;
- if (!mir_tstrcmpi(status, _T("Online")))
- iNewStatus = ID_STATUS_ONLINE;
- else if (!mir_tstrcmpi(status, _T("Hidden")))
- iNewStatus = ID_STATUS_INVISIBLE;
- 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_OFFLINE;
+ int iNewStatus = SkypeToMirandaStatus(status);
m_iStatus = iNewStatus;
if (iNewStatus == ID_STATUS_OFFLINE)
diff --git a/protocols/SkypeWeb/src/skype_poll_processing.cpp b/protocols/SkypeWeb/src/skype_poll_processing.cpp
index 4bf8b3e689..d357c5b5ee 100644
--- a/protocols/SkypeWeb/src/skype_poll_processing.cpp
+++ b/protocols/SkypeWeb/src/skype_poll_processing.cpp
@@ -1,12 +1,92 @@
#include "common.h"
+void CSkypeProto::ProcessEndpointPresenceRes(JSONNODE *node)
+{
+ debugLogA("CSkypeProto::ProcessEndpointPresenceRes");
+ ptrA selfLink(mir_t2a(ptrT(json_as_string(json_get(node, "selfLink")))));
+ char *skypename = ContactUrlToName(selfLink);
+ if (skypename == NULL)
+ return;
+ MCONTACT hContact = GetContact(skypename);
+
+ //"publicInfo":{"capabilities":"","typ":"11","skypeNameVersion":"0/7.1.0.105//","nodeInfo":"","version":"24"}
+ JSONNODE *publicInfo = json_get(node, "publicInfo");
+ if (publicInfo != NULL)
+ {
+ ptrA version(mir_t2a(ptrT(json_as_string(json_get(publicInfo, "skypeNameVersion")))));
+ ptrA typ(mir_t2a(ptrT(json_as_string(json_get(publicInfo, "typ")))));
+ if (typ != NULL)
+ {
+ if (!mir_strcmpi(typ, "17")) //Android
+ db_set_s(hContact, m_szModuleName, "MirVer", "Skype (Android)");
+ else if (!mir_strcmpi(typ, "16")) //iOS
+ db_set_s(hContact, m_szModuleName, "MirVer", "Skype (iOS)");
+ else if (!mir_strcmpi(typ, "12")) //WinRT/Metro
+ db_set_s(hContact, m_szModuleName, "MirVer", "Skype (WinRT)");
+ else if (!mir_strcmpi(typ, "15")) //Winphone
+ db_set_s(hContact, m_szModuleName, "MirVer", "Skype (WP)");
+ else if (!mir_strcmpi(typ, "13")) //OSX
+ db_set_s(hContact, m_szModuleName, "MirVer", "Skype (OSX)");
+ else if (!mir_strcmpi(typ, "11")) //Windows
+ db_set_s(hContact, m_szModuleName, "MirVer", "Skype (Windows)");
+ else if (!mir_strcmpi(typ, "14")) //Linux
+ db_set_s(hContact, m_szModuleName, "MirVer", "Skype (Linux)");
+ else if (!mir_strcmpi(typ, "10"))//XBox ? skypeNameVersion 11/1.8.0.1006
+ db_set_s(hContact, m_szModuleName, "MirVer", "Skype (XBOX)");
+ else if (!mir_strcmpi(typ, "1")) //SkypeWeb
+ db_set_s(hContact, m_szModuleName, "MirVer", "Skype (Web)");
+ else if (!mir_strcmpi(typ, "125")) //Miranda
+ db_set_s(hContact, m_szModuleName, "MirVer", "Miranda NG");
+
+ }
+
+ }
+}
+
void CSkypeProto::ProcessUserPresenceRes(JSONNODE *node)
{
debugLogA("CSkypeProto::ProcessUserPresenceRes");
+
ptrA selfLink(mir_t2a(ptrT(json_as_string(json_get(node, "selfLink")))));
ptrA status(mir_t2a(ptrT(json_as_string(json_get(node, "status")))));
-
char *skypename = ContactUrlToName(selfLink);
+ if (skypename == NULL)
+ {
+ if (IsMe(SelfUrlToName(selfLink)))
+ {
+ int iNewStatus = SkypeToMirandaStatus(status);
+ int old_status = m_iStatus;
+ m_iDesiredStatus = iNewStatus;
+ m_iStatus = iNewStatus;
+ if (old_status != iNewStatus)
+ ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, iNewStatus);
+ return;
+ }
+ return;
+ }
MCONTACT hContact = GetContact(skypename);
- SetContactStatus(hContact, ID_STATUS_ONLINE);
+ SetContactStatus(hContact, SkypeToMirandaStatus(status));
+}
+
+void CSkypeProto::ProcessNewMessageRes(JSONNODE *node)
+{
+ ptrA clientMsgId(mir_t2a(ptrT(json_as_string(json_get(node, "clientmessageid")))));
+ ptrA skypeeditedid(mir_t2a(ptrT(json_as_string(json_get(node, "skypeeditedid")))));
+ ptrA messagetype(mir_t2a(ptrT(json_as_string(json_get(node, "messagetype")))));
+ ptrA from(mir_t2a(ptrT(json_as_string(json_get(node, "from")))));
+ ptrA content(mir_t2a(ptrT(json_as_string(json_get(node, "content")))));
+ //ptrA composeTime(mir_t2a(ptrT(json_as_string(json_get(node, "composetime")))));
+ TCHAR *composeTime = json_as_string (json_get(node, "composetime"));
+ ptrA conversationLink(mir_t2a(ptrT(json_as_string(json_get(node, "conversationLink")))));
+ time_t timeStamp = IsoToUnixTime(composeTime);//time(NULL); // it should be rewritten
+
+ PROTORECVEVENT recv = { 0 };
+ recv.flags = PREF_UTF;
+ recv.timestamp = timeStamp;
+ recv.szMessage = content;
+ debugLogA("Incoming message from %s", ContactUrlToName(from));
+ if(IsMe(ContactUrlToName(from)))
+ return; //it should be rewritten
+ MCONTACT hContact = GetContact(ContactUrlToName(from));
+ OnReceiveMessage(hContact, &recv);
} \ No newline at end of file
diff --git a/protocols/SkypeWeb/src/skype_polling.cpp b/protocols/SkypeWeb/src/skype_polling.cpp
index 8dc73280a7..aed47be086 100644
--- a/protocols/SkypeWeb/src/skype_polling.cpp
+++ b/protocols/SkypeWeb/src/skype_polling.cpp
@@ -20,7 +20,7 @@ void CSkypeProto::ParsePollData(JSONNODE *data)
if (!mir_tstrcmpi(resourceType, L"NewMessage"))
{
- continue;
+ ProcessNewMessageRes(resource);
}
else if (!mir_tstrcmpi(resourceType, L"UserPresence"))
{
@@ -28,7 +28,7 @@ void CSkypeProto::ParsePollData(JSONNODE *data)
}
else if (!mir_tstrcmpi(resourceType, L"EndpointPresence"))
{
- continue;
+ ProcessEndpointPresenceRes(resource);
}
else if (!mir_tstrcmpi(resourceType, L"ConversationUpdate"))
{
@@ -40,8 +40,7 @@ void CSkypeProto::ParsePollData(JSONNODE *data)
}
}
- }
-
+ }
}
void CSkypeProto::PollingThread(void*)
@@ -49,18 +48,29 @@ void CSkypeProto::PollingThread(void*)
debugLog(_T("CSkypeProto::PollingThread: entering"));
ptrA regToken(getStringA("registrationToken"));
+ const char *server = getStringA("Server");
+
+ SubscriptionsRequest *request = new SubscriptionsRequest(regToken, server);
+ request->Send(m_hNetlibUser);
+ delete request;
int errors = 0;
bool breaked = false;
while (!isTerminated && !breaked && errors < POLLING_ERRORS_LIMIT)
{
- PollRequest *request = new PollRequest(regToken);
+ PollRequest *request = new PollRequest(regToken, server);
NETLIBHTTPREQUEST *response = request->Send(m_hNetlibUser);
delete request;
if (response != NULL)
{
+ m_pollingConnection = response->nlc;
JSONROOT root(response->pData);
+ if (json_get(root, "errorCode") != NULL)
+ {
+ errors++;
+ continue;
+ }
ParsePollData (root);
}
/*if (response->resultCode != 200)
@@ -72,6 +82,7 @@ void CSkypeProto::PollingThread(void*)
errors = 0;*/
}
m_hPollingThread = NULL;
+ m_pollingConnection = NULL;
debugLog(_T("CSkypeProto::PollingThread: leaving"));
if (!isTerminated)
diff --git a/protocols/SkypeWeb/src/skype_proto.cpp b/protocols/SkypeWeb/src/skype_proto.cpp
index 6f0905c785..88a9241d0f 100644
--- a/protocols/SkypeWeb/src/skype_proto.cpp
+++ b/protocols/SkypeWeb/src/skype_proto.cpp
@@ -31,13 +31,13 @@ DWORD_PTR CSkypeProto::GetCaps(int type, MCONTACT)
switch (type)
{
case PFLAGNUM_1:
- return PF1_AUTHREQ;
+ return PF1_IM | PF1_AUTHREQ;
case PFLAGNUM_2:
return PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_HEAVYDND;
case PFLAGNUM_3:
return PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_HEAVYDND;
case PFLAGNUM_4:
- return PF4_FORCEADDED | PF4_NOAUTHDENYREASON;
+ return PF4_FORCEADDED | PF4_NOAUTHDENYREASON | PF4_SUPPORTTYPING;
case PFLAG_UNIQUEIDTEXT:
return (INT_PTR)"Skypename";
case PFLAG_UNIQUEIDSETTING:
@@ -137,6 +137,9 @@ int CSkypeProto::SetStatus(int iNewStatus)
if (iNewStatus == ID_STATUS_OFFLINE)
{
// logout
+ isTerminated = true;
+ //if (m_pollingConnection)
+ // CallService(MS_NETLIB_SHUTDOWN, (WPARAM)m_pollingConnection, 0);
PushRequest(new LogoutRequest());
requestQueue->Stop();
@@ -156,6 +159,8 @@ int CSkypeProto::SetStatus(int iNewStatus)
else if (old_status == ID_STATUS_OFFLINE && m_iStatus == ID_STATUS_OFFLINE)
{
// login
+ if (getStringA("Server") == NULL)
+ setString("Server", "client-s.gateway.messenger.live.com");
m_iStatus = ID_STATUS_CONNECTING;
requestQueue->Start();
@@ -165,11 +170,8 @@ int CSkypeProto::SetStatus(int iNewStatus)
{
// set status
m_iStatus = iNewStatus;
- // it should be rewritten
- //GetEndpointRequest *request = new GetEndpointRequest(getStringA("registrationToken"), getStringA("endpointId"));
- //request->Send(m_hNetlibUser);
- //delete request;
- PushRequest(new SetStatusRequest(ptrA(getStringA("registrationToken")), MirandaToSkypeStatus(m_iStatus)), &CSkypeProto::OnSetStatus);
+ PushRequest(new SetStatusRequest(ptrA(getStringA("registrationToken")), MirandaToSkypeStatus(m_iStatus), getStringA("Server")), &CSkypeProto::OnSetStatus);
+ PushRequest(new GetEndpointRequest(getStringA("registrationToken"), getStringA("endpointId"), getStringA("Server")));
}
}
@@ -183,7 +185,18 @@ int CSkypeProto::RecvAwayMsg(MCONTACT, int, PROTORECVEVENT*) { return 0; }
int CSkypeProto::SetAwayMsg(int, const PROTOCHAR *msg) { return 0; }
-int CSkypeProto::UserIsTyping(MCONTACT hContact, int type) { return 0; }
+int CSkypeProto::UserIsTyping(MCONTACT hContact, int type)
+{
+ switch (type) {
+ case PROTOTYPE_SELFTYPING_OFF:
+ PushRequest(new SendTypingRequest(getStringA("registrationToken"), db_get_sa(hContact, m_szModuleName, "Skypename"), false, getStringA("Server")));
+ break;
+ case PROTOTYPE_SELFTYPING_ON:
+ PushRequest(new SendTypingRequest(getStringA("registrationToken"), db_get_sa(hContact, m_szModuleName, "Skypename"), true, getStringA("Server")));
+ break;
+ }
+ return 0;
+}
int CSkypeProto::OnEvent(PROTOEVENTTYPE iEventType, WPARAM wParam, LPARAM lParam)
{
diff --git a/protocols/SkypeWeb/src/skype_proto.h b/protocols/SkypeWeb/src/skype_proto.h
index f312fc38e5..5d86f4ce92 100644
--- a/protocols/SkypeWeb/src/skype_proto.h
+++ b/protocols/SkypeWeb/src/skype_proto.h
@@ -125,7 +125,7 @@ private:
void OnLoginSecond(const NETLIBHTTPREQUEST *response);
void OnGetRegInfo(const NETLIBHTTPREQUEST *response);
void OnSetStatus(const NETLIBHTTPREQUEST *response);
-
+ void OnGetEndpoint(const NETLIBHTTPREQUEST *response);
// profile
void UpdateProfileFirstName(JSONNODE *root, MCONTACT hContact = NULL);
void UpdateProfileLastName(JSONNODE *root, MCONTACT hContact = NULL);
@@ -174,15 +174,22 @@ private:
//polling
void __cdecl ParsePollData(JSONNODE *data);
void __cdecl PollingThread(void*);
+ void CSkypeProto::ProcessEndpointPresenceRes(JSONNODE *node);
void CSkypeProto::ProcessUserPresenceRes(JSONNODE *node);
+ void CSkypeProto::ProcessNewMessageRes(JSONNODE *node);
// utils
+ time_t __stdcall IsoToUnixTime(const TCHAR *stamp);
+ char *GetStringChunk(const char *haystack, size_t len, const char *start, const char *end);
+ bool IsMe(const char *skypeName);
+ int SkypeToMirandaStatus(const char *status);
char *MirandaToSkypeStatus(int status);
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 SetServerStatus(int iNewStatus);
static bool IsFileExists(std::tstring path);
char *ContactUrlToName(const char *url);
-
+ char *SelfUrlToName(const char *url);
+ char *GetServerFromUrl(const char *url);
template<INT_PTR(__cdecl CSkypeProto::*Service)(WPARAM, LPARAM)>
static INT_PTR __cdecl GlobalService(WPARAM wParam, LPARAM lParam)
{
diff --git a/protocols/SkypeWeb/src/skype_utils.cpp b/protocols/SkypeWeb/src/skype_utils.cpp
index 0e32b56723..a85f9c9eec 100644
--- a/protocols/SkypeWeb/src/skype_utils.cpp
+++ b/protocols/SkypeWeb/src/skype_utils.cpp
@@ -1,5 +1,67 @@
#include "common.h"
+time_t __stdcall CSkypeProto::IsoToUnixTime(const TCHAR *stamp)
+{
+ TCHAR date[9];
+ int i, y;
+
+ if (stamp == NULL)
+ return 0;
+
+ const TCHAR *p = stamp;
+
+ // Get the date part
+ for (i = 0; *p != '\0' && i < 8 && isdigit(*p); p++, i++)
+ date[i] = *p;
+
+ // Parse year
+ if (i == 6) {
+ // 2-digit year (1970-2069)
+ y = (date[0] - '0') * 10 + (date[1] - '0');
+ if (y < 70) y += 100;
+ }
+ else if (i == 8) {
+ // 4-digit year
+ y = (date[0] - '0') * 1000 + (date[1] - '0') * 100 + (date[2] - '0') * 10 + date[3] - '0';
+ y -= 1900;
+ }
+ else return 0;
+
+ struct tm timestamp;
+ timestamp.tm_year = y;
+
+ // Parse month
+ timestamp.tm_mon = (date[i - 4] - '0') * 10 + date[i - 3] - '0' - 1;
+
+ // Parse date
+ timestamp.tm_mday = (date[i - 2] - '0') * 10 + date[i - 1] - '0';
+
+ // Skip any date/time delimiter
+ for (; *p != '\0' && !isdigit(*p); p++);
+
+ // Parse time
+ if (_stscanf(p, _T("%d:%d:%d"), &timestamp.tm_hour, &timestamp.tm_min, &timestamp.tm_sec) != 3)
+ return (time_t)0;
+
+ timestamp.tm_isdst = 0; // DST is already present in _timezone below
+ time_t t = mktime(&timestamp);
+
+ _tzset();
+ t -= _timezone;
+ return (t >= 0) ? t : 0;
+}
+
+
+bool CSkypeProto::IsMe(const char *skypeName)
+{
+ ptrA mySkypeName(getStringA("Skypename"));
+ ptrA SelfEndpointName(getStringA("SelfEndpointName"));
+ if (!lstrcmpA(skypeName, mySkypeName) || !lstrcmpA(skypeName, SelfEndpointName))
+ return true;
+
+ return false;
+}
+
char *CSkypeProto::MirandaToSkypeStatus(int status)
{
char *result = "Online";
@@ -20,6 +82,22 @@ char *CSkypeProto::MirandaToSkypeStatus(int status)
return "Online";
}
+int CSkypeProto::SkypeToMirandaStatus(const char *status)
+{
+ if (!mir_strcmpi(status, "Online"))
+ return ID_STATUS_ONLINE;
+ else if (!mir_strcmpi(status, "Hidden"))
+ return ID_STATUS_INVISIBLE;
+ else if (!mir_strcmpi(status, "Away"))
+ return ID_STATUS_AWAY;
+ else if (!mir_strcmpi(status, "Idle"))
+ return /*ID_STATUS_IDLE*/ID_STATUS_AWAY;
+ else if (!mir_strcmpi(status, "Busy"))
+ return ID_STATUS_DND;
+ else
+ return ID_STATUS_OFFLINE;
+}
+
void CSkypeProto::ShowNotification(const TCHAR *caption, const TCHAR *message, int flags, MCONTACT hContact)
{
if (Miranda_Terminated())
@@ -79,3 +157,45 @@ char *CSkypeProto::ContactUrlToName(const char *url)
return tempname;
}
+
+char *CSkypeProto::SelfUrlToName(const char *url)
+{
+ char *tempname = NULL;
+ const char *start, *end;
+ start = strstr(url, "/1:");
+
+ if (!start)
+ return NULL;
+ start = start + 3;
+ if ((end = strchr(start, '/')))
+ {
+ mir_free(tempname);
+ tempname = mir_strndup(start, end - start);
+ return tempname;
+ }
+ mir_free(tempname);
+ tempname = mir_strdup(start);
+
+ return tempname;
+}
+
+char *CSkypeProto::GetServerFromUrl(const char *url)
+{
+ char *tempname = NULL;
+ const char *start, *end;
+ start = strstr(url, "://");
+
+ if (!start)
+ return NULL;
+ start = start + 3;
+ if ((end = strchr(start, '/')))
+ {
+ mir_free(tempname);
+ tempname = mir_strndup(start, end - start);
+ return tempname;
+ }
+ mir_free(tempname);
+ tempname = mir_strdup(start);
+
+ return tempname;
+} \ No newline at end of file