summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--protocols/SkypeWeb/src/requests/contacts.h4
-rw-r--r--protocols/SkypeWeb/src/requests/messages.h22
-rw-r--r--protocols/SkypeWeb/src/skype_contacts.cpp2
-rw-r--r--protocols/SkypeWeb/src/skype_events.cpp6
-rw-r--r--protocols/SkypeWeb/src/skype_menus.cpp1
-rw-r--r--protocols/SkypeWeb/src/skype_messages.cpp116
-rw-r--r--protocols/SkypeWeb/src/skype_poll_processing.cpp5
-rw-r--r--protocols/SkypeWeb/src/skype_polling.cpp5
-rw-r--r--protocols/SkypeWeb/src/skype_profile.cpp2
-rw-r--r--protocols/SkypeWeb/src/skype_proto.cpp10
-rw-r--r--protocols/SkypeWeb/src/skype_proto.h22
-rw-r--r--protocols/SkypeWeb/src/skype_request.cpp40
-rw-r--r--protocols/SkypeWeb/src/skype_utils.cpp1
13 files changed, 141 insertions, 95 deletions
diff --git a/protocols/SkypeWeb/src/requests/contacts.h b/protocols/SkypeWeb/src/requests/contacts.h
index 786f59e10d..8a23526bf9 100644
--- a/protocols/SkypeWeb/src/requests/contacts.h
+++ b/protocols/SkypeWeb/src/requests/contacts.h
@@ -25,10 +25,8 @@ public:
<< CHAR_VALUE("X-Skypetoken", token)
<< CHAR_VALUE("Accept", "application/json");
- for (size_t i = 0; i < skypenames.getCount(); i++)
- {
+ for (int i = 0; i < skypenames.getCount(); i++)
Body << CHAR_VALUE("contacts[]", skypenames[i]);
- }
}
};
diff --git a/protocols/SkypeWeb/src/requests/messages.h b/protocols/SkypeWeb/src/requests/messages.h
index 389d9fa7bb..d2c000d8be 100644
--- a/protocols/SkypeWeb/src/requests/messages.h
+++ b/protocols/SkypeWeb/src/requests/messages.h
@@ -8,7 +8,7 @@ public:
HttpRequest(REQUEST_POST, FORMAT, "%s/v1/users/ME/conversations/8:%s/messages", server, username)
{
Headers
- << CHAR_VALUE("Accept", "application / json, text / javascript")
+ << 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")
@@ -31,7 +31,7 @@ public:
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("Accept", "application/json, text/javascript")
<< CHAR_VALUE("Expires", "0")
<< FORMAT_VALUE("RegistrationToken", "registrationToken=%s", regToken)
<< CHAR_VALUE("Content-Type", "application/json; charset = UTF-8")
@@ -49,4 +49,22 @@ public:
}
};
+class GetHistoryRequest : public HttpRequest
+{
+public:
+ GetHistoryRequest(const char *regToken, int time, const char *server = "client-s.gateway.messenger.live.com") :
+ HttpRequest(REQUEST_GET, FORMAT, "%s/v1/users/ME/conversations?startTime=%d&pageSize=100&view=msnp24Equivalent&targetType=Passport|Skype|Lync|Thread", server, time)
+ {
+ 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");
+ }
+};
+
#endif //_SKYPE_REQUEST_MESSAGES_H_
diff --git a/protocols/SkypeWeb/src/skype_contacts.cpp b/protocols/SkypeWeb/src/skype_contacts.cpp
index a9e7db7e97..5e779d545a 100644
--- a/protocols/SkypeWeb/src/skype_contacts.cpp
+++ b/protocols/SkypeWeb/src/skype_contacts.cpp
@@ -216,7 +216,7 @@ void CSkypeProto::LoadContactList(const NETLIBHTTPREQUEST *response)
{
PushRequest(new GetContactsInfoRequest(token, skypenames), &CSkypeProto::LoadContactsInfo);
- for (size_t i = 0; i < skypenames.getCount(); i++)
+ for (int i = 0; i < skypenames.getCount(); i++)
mir_free(skypenames[i]);
skypenames.destroy();
}
diff --git a/protocols/SkypeWeb/src/skype_events.cpp b/protocols/SkypeWeb/src/skype_events.cpp
index 26c0c11ec2..db91d9f1b8 100644
--- a/protocols/SkypeWeb/src/skype_events.cpp
+++ b/protocols/SkypeWeb/src/skype_events.cpp
@@ -106,8 +106,8 @@ void CSkypeProto::OnGetRegInfo(const NETLIBHTTPREQUEST *response)
{
CMStringA szValue = response->headers[i].szValue, szCookieName, szCookieVal;
int iStart = 0;
- while (true) {
- bool bFirstToken = (iStart == 0);
+ while (true)
+ {
CMStringA szToken = szValue.Tokenize(";", iStart).Trim();
if (iStart == -1)
break;
@@ -137,6 +137,8 @@ void CSkypeProto::OnGetRegInfo(const NETLIBHTTPREQUEST *response)
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), getStringA("Server")), &CSkypeProto::OnSetStatus);
+ PushRequest(new GetHistoryRequest(ptrA(getStringA("registrationToken")), getDword("LastMsgTime", time(NULL)), ptrA(getStringA("Server"))), &CSkypeProto::OnGetServerHistory);
+
}
void CSkypeProto::OnGetEndpoint(const NETLIBHTTPREQUEST *response)
diff --git a/protocols/SkypeWeb/src/skype_menus.cpp b/protocols/SkypeWeb/src/skype_menus.cpp
index de82902909..0bb9092828 100644
--- a/protocols/SkypeWeb/src/skype_menus.cpp
+++ b/protocols/SkypeWeb/src/skype_menus.cpp
@@ -66,7 +66,6 @@ int CSkypeProto::OnInitStatusMenu()
{
char text[MAX_PATH];
mir_strcpy(text, m_szModuleName);
- char *tDest = text + strlen(text);
CLISTMENUITEM mi = { sizeof(mi) };
mi.pszService = text;
diff --git a/protocols/SkypeWeb/src/skype_messages.cpp b/protocols/SkypeWeb/src/skype_messages.cpp
index 70436ce0e7..b863fa57fd 100644
--- a/protocols/SkypeWeb/src/skype_messages.cpp
+++ b/protocols/SkypeWeb/src/skype_messages.cpp
@@ -3,89 +3,113 @@
/* MESSAGE RECEIVING */
// writing message/even into db
-int CSkypeProto::OnReceiveMessage(const char *from, const char *convLink, time_t timeStamp, char *content)
+int CSkypeProto::OnReceiveMessage(const char *from, const char *convLink, time_t timestamp, char *content)
{
+ setDword("LastMsgTime", timestamp);
PROTORECVEVENT recv = { 0 };
recv.flags = PREF_UTF;
- recv.timestamp = timeStamp;
+ recv.timestamp = timestamp;
recv.szMessage = content;
- debugLogA("Incoming message from %s", ContactUrlToName(from));
- if (IsMe(ContactUrlToName(from)))
+
+ ptrA skypename(ContactUrlToName(from));
+ debugLogA("Incoming message from %s", skypename);
+ if (IsMe(skypename))
{
recv.flags |= PREF_SENT;
MCONTACT hContact = GetContact(ContactUrlToName(convLink));
return ProtoChainRecvMsg(hContact, &recv);
}
- MCONTACT hContact = GetContact(ContactUrlToName(from));
+ MCONTACT hContact = GetContact(skypename);
return ProtoChainRecvMsg(hContact, &recv);
}
/* MESSAGE SENDING */
+struct SendMessageParam
+{
+ MCONTACT hContact;
+ HANDLE hMessage;
+};
+
// outcoming message flow
int CSkypeProto::OnSendMessage(MCONTACT hContact, int flags, const char *szMessage)
{
- UINT hMessage = InterlockedIncrement(&hMessageProcess);
+ ULONG hMessage = InterlockedIncrement(&hMessageProcess);
+
+ if (!IsOnline())
+ {
+ ProtoBroadcastAck(hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, NULL, (LPARAM)"You cannot send when you are offline.");
+ return 0;
+ }
- SendMessageParam *param = (SendMessageParam*)mir_calloc(sizeof(SendMessageParam));
+ SendMessageParam *param = new SendMessageParam();
param->hContact = hContact;
param->hMessage = (HANDLE)hMessage;
- param->msg = szMessage;
- param->flags = flags;
- ForkThread(&CSkypeProto::SendMsgThread, (void*)param);
+ ptrA message;
+ if (flags & PREF_UNICODE)
+ message = mir_utf8encodeW((wchar_t*)&szMessage[mir_strlen(szMessage) + 1]);
+ else if (flags & PREF_UTF)
+ message = mir_strdup(szMessage);
+ else
+ message = mir_utf8encode(szMessage);
+
+ ptrA server(getStringA("Server"));
+ ptrA token(getStringA("registrationToken"));
+ ptrA username(getStringA(hContact, "Skypename"));
+ PushRequest(new SendMsgRequest(token, username, message, server), &CSkypeProto::OnMessageSent, param);
return hMessage;
}
-void CSkypeProto::SendMsgThread(void *arg)
+void CSkypeProto::OnMessageSent(const NETLIBHTTPREQUEST *response, void *arg)
{
SendMessageParam *param = (SendMessageParam*)arg;
+ MCONTACT hContact = param->hContact;
+ HANDLE hMessage = param->hMessage;
+ delete param;
- if (!IsOnline())
+ if (response->resultCode != 200 || response->resultCode != 201)
{
- ProtoBroadcastAck(param->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, param->hMessage, (LPARAM)Translate("You cannot send messages when you are offline."));
- mir_free(param);
+ CMStringA error = "Unknown error";
+ if (response)
+ {
+ JSONROOT root(response->pData);
+ JSONNODE *node = json_get(root, "errorCode");
+ error = _T2A(json_as_string(node));
+ }
+ ptrT username(getTStringA(hContact, "Skypename"));
+ debugLogA(__FUNCTION__": failed to send message for %s (%s)", username, error);
+ ProtoBroadcastAck(hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, hMessage, (LPARAM)error.GetBuffer());
return;
}
- CMStringA message = (param->flags & PREF_UNICODE) ? ptrA(mir_utf8encode(param->msg)) : param->msg; // TODO: mir_utf8encode check taken from FacebookRM, is it needed? Usually we get PREF_UTF8 flag instead.
-
- ptrA token(getStringA("registrationToken"));
- ptrA username(getStringA(param->hContact, "Skypename"));
- PushRequest(
- new SendMsgRequest(token, username, message, getStringA("Server"))/*,
- &CSkypeProto::OnMessageSent*/);
+ ProtoBroadcastAck(hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, hMessage, 0);
}
-void CSkypeProto::OnMessageSent(const NETLIBHTTPREQUEST *response, void *arg)
+void CSkypeProto::OnGetServerHistory(const NETLIBHTTPREQUEST *response)
{
- SendMessageParam *param = (SendMessageParam*)arg;
-
- ptrT error(mir_tstrdup(TranslateT("Unknown error")));
- ptrT username(getTStringA(param->hContact, "Skypename"));
-
- if (response != NULL && (response->resultCode == 201 || response->resultCode == 200))
- {
- JSONROOT root(response->pData);
- JSONNODE *node = json_get(root, "errorCode");
- if (node)
- error = json_as_string(node);
- }
+ if (response == NULL)
+ return;
- int status = ACKRESULT_FAILED;
+ JSONROOT root(response->pData);
+ if (root == NULL)
+ return;
- if (error == NULL)
+ JSONNODE *conversations = json_as_array(json_get(root, "conversations"));
+ for (size_t i = 0; i < json_size(conversations); i++)
{
- status = ACKRESULT_SUCCESS;
+ JSONNODE *message = json_get(json_at(conversations, i), "lastMessage");
+
+ ptrA clientMsgId(mir_t2a(ptrT(json_as_string(json_get(message, "clientmessageid")))));
+ ptrA skypeEditedId(mir_t2a(ptrT(json_as_string(json_get(message, "skypeeditedid")))));
+ ptrA messageType(mir_t2a(ptrT(json_as_string(json_get(message, "messagetype")))));
+ ptrA from(mir_t2a(ptrT(json_as_string(json_get(message, "from")))));
+ ptrA content(mir_t2a(ptrT(json_as_string(json_get(message, "content")))));
+ ptrT composeTime(json_as_string(json_get(message, "composetime")));
+ ptrA conversationLink(mir_t2a(ptrT(json_as_string(json_get(message, "conversationLink")))));
+ time_t timestamp = IsoToUnixTime(composeTime);
+ if (conversationLink != NULL && strstr(conversationLink, "/8:"))
+ OnReceiveMessage(from, conversationLink, timestamp, content);
}
- else
- debugLog(_T("CSkypeProto::OnMessageSent: failed to send message for %s (%s)"), username, error);
-
- ProtoBroadcastAck(
- param->hContact,
- ACKTYPE_MESSAGE,
- status,
- param->hMessage,
- error);
} \ No newline at end of file
diff --git a/protocols/SkypeWeb/src/skype_poll_processing.cpp b/protocols/SkypeWeb/src/skype_poll_processing.cpp
index 24baf6f8e1..e2f0f6c0de 100644
--- a/protocols/SkypeWeb/src/skype_poll_processing.cpp
+++ b/protocols/SkypeWeb/src/skype_poll_processing.cpp
@@ -86,7 +86,7 @@ void CSkypeProto::ProcessNewMessageRes(JSONNODE *node)
char *convname;
if (strstr(conversationLink, "/19:"))
{
- const char *chatname, *topic;
+ const char *chatname;
chatname = ContactUrlToName(conversationLink);
convname = mir_strdup(chatname);
return; //chats not supported
@@ -100,7 +100,8 @@ void CSkypeProto::ProcessNewMessageRes(JSONNODE *node)
}
else if (!mir_strcmpi(messagetype, "Control/ClearTyping"))
{
- return;
+ MCONTACT hContact = GetContact(ContactUrlToName(from));
+ CallService(MS_PROTO_CONTACTISTYPING, hContact, 0);
}
else if (!mir_strcmpi(messagetype, "Text") || !mir_strcmpi(messagetype, "RichText"))
{
diff --git a/protocols/SkypeWeb/src/skype_polling.cpp b/protocols/SkypeWeb/src/skype_polling.cpp
index 668359667f..528f9e7d53 100644
--- a/protocols/SkypeWeb/src/skype_polling.cpp
+++ b/protocols/SkypeWeb/src/skype_polling.cpp
@@ -5,13 +5,12 @@
void CSkypeProto::ParsePollData(JSONNODE *data)
{
debugLogA("CSkypeProto::ParsePollData");
- JSONNODE *node, *item = NULL;
+ JSONNODE *node;
node = json_get(data, "eventMessages");
if (node != NULL)
{
- int index, length;
JSONNODE *messages = json_as_array(node);
- for (int i = 0; i < json_size(messages); i++)
+ for (size_t i = 0; i < json_size(messages); i++)
{
JSONNODE *message = json_at(messages, i);
JSONNODE *resType = json_get(message, "resourceType");
diff --git a/protocols/SkypeWeb/src/skype_profile.cpp b/protocols/SkypeWeb/src/skype_profile.cpp
index 2b5ec95218..c260380fc2 100644
--- a/protocols/SkypeWeb/src/skype_profile.cpp
+++ b/protocols/SkypeWeb/src/skype_profile.cpp
@@ -427,7 +427,7 @@ void CSkypeProto::UpdateProfileXStatusMessage(JSONNODE *root, MCONTACT hContact)
void CSkypeProto::UpdateProfileAvatar(JSONNODE *root, MCONTACT hContact)
{
- JSONNODE *node = json_get(root, "avatarUrl");
+ //JSONNODE *node = json_get(root, "avatarUrl");
// add avatar support
}
diff --git a/protocols/SkypeWeb/src/skype_proto.cpp b/protocols/SkypeWeb/src/skype_proto.cpp
index 3937a4e6c7..eb420ad998 100644
--- a/protocols/SkypeWeb/src/skype_proto.cpp
+++ b/protocols/SkypeWeb/src/skype_proto.cpp
@@ -141,7 +141,15 @@ int CSkypeProto::SetStatus(int iNewStatus)
isTerminated = true;
//if (m_pollingConnection)
// CallService(MS_NETLIB_SHUTDOWN, (WPARAM)m_pollingConnection, 0);
- PushRequest(new LogoutRequest());
+ LogoutRequest *logoutRequest = new LogoutRequest();
+ if (!cookies.empty())
+ {
+ CMStringA allCookies;
+ for (std::map<std::string, std::string>::iterator cookie = cookies.begin(); cookie != cookies.end(); ++cookie)
+ allCookies.AppendFormat("%s=%s; ", cookie->first.c_str(), cookie->second.c_str());
+ logoutRequest->Headers << CHAR_VALUE("Set-Cookie", allCookies);
+ }
+ PushRequest(logoutRequest);
requestQueue->Stop();
if (!Miranda_Terminated())
diff --git a/protocols/SkypeWeb/src/skype_proto.h b/protocols/SkypeWeb/src/skype_proto.h
index 5e598a8e99..1be152508d 100644
--- a/protocols/SkypeWeb/src/skype_proto.h
+++ b/protocols/SkypeWeb/src/skype_proto.h
@@ -1,21 +1,8 @@
#ifndef _SKYPE_PROTO_H_
#define _SKYPE_PROTO_H_
-struct SendMessageParam
-{
- MCONTACT hContact;
- HANDLE hMessage;
- const char *msg;
- int flags;
-};
-
-enum ARG_FREE_TYPE
-{
- ARG_NO_FREE,
- ARG_MIR_FREE
-};
-
typedef void(CSkypeProto::*SkypeResponseCallback)(const NETLIBHTTPREQUEST *response);
+typedef void(CSkypeProto::*SkypeResponseWithArgCallback)(const NETLIBHTTPREQUEST *response, void *arg);
struct CSkypeProto : public PROTO < CSkypeProto >
{
@@ -116,7 +103,9 @@ private:
INT_PTR __cdecl OnAccountManagerInit(WPARAM, LPARAM);
// requests
- void PushRequest(HttpRequest *request, SkypeResponseCallback response = NULL);
+ void PushRequest(HttpRequest *request);
+ void PushRequest(HttpRequest *request, SkypeResponseCallback response);
+ void PushRequest(HttpRequest *request, SkypeResponseWithArgCallback response, void *arg);
// icons
static IconInfo Icons[];
@@ -184,10 +173,11 @@ private:
int __cdecl OnContactDeleted(MCONTACT, LPARAM);
// messages
- int OnReceiveMessage(const char *from, const char *convLink, time_t timeStamp, char *content);
+ int OnReceiveMessage(const char *from, const char *convLink, time_t timestamp, char *content);
int OnSendMessage(MCONTACT hContact, int flags, const char *message);
void __cdecl CSkypeProto::SendMsgThread(void *arg);
void OnMessageSent(const NETLIBHTTPREQUEST *response, void *arg);
+ void OnGetServerHistory(const NETLIBHTTPREQUEST *response);
//polling
void __cdecl ParsePollData(JSONNODE *data);
void __cdecl PollingThread(void*);
diff --git a/protocols/SkypeWeb/src/skype_request.cpp b/protocols/SkypeWeb/src/skype_request.cpp
index 61d9754ec0..b0026de980 100644
--- a/protocols/SkypeWeb/src/skype_request.cpp
+++ b/protocols/SkypeWeb/src/skype_request.cpp
@@ -5,14 +5,24 @@ class SkypeResponseDelegate
private:
CSkypeProto *proto;
SkypeResponseCallback responseCallback;
+ SkypeResponseWithArgCallback responseWithArgCallback;
+
+ void *arg;
+ bool hasArg;
public:
SkypeResponseDelegate(CSkypeProto *proto, SkypeResponseCallback responseCallback)
- : proto(proto), responseCallback(responseCallback) { }
+ : proto(proto), responseCallback(responseCallback), arg(NULL), hasArg(false) {}
+
+ SkypeResponseDelegate(CSkypeProto *proto, SkypeResponseWithArgCallback responseCallback, void *arg)
+ : proto(proto), responseWithArgCallback(responseCallback), arg(arg), hasArg(true) { }
void Invoke(const NETLIBHTTPREQUEST *response)
{
- (proto->*(responseCallback))(response);
+ if (hasArg)
+ (proto->*(responseWithArgCallback))(response, arg);
+ else
+ (proto->*(responseCallback))(response);
}
};
@@ -21,22 +31,20 @@ static void SkypeHttpResponse(const NETLIBHTTPREQUEST *response, void *arg)
((SkypeResponseDelegate*)arg)->Invoke(response);
}
-void CSkypeProto::PushRequest(HttpRequest *request, SkypeResponseCallback response)
+void CSkypeProto::PushRequest(HttpRequest *request)
{
- if (!cookies.empty())
- {
- CMStringA allCookies;
- for (std::map<std::string, std::string>::iterator cookie = cookies.begin(); cookie != cookies.end(); ++cookie)
- allCookies.AppendFormat("%s=%s; ", cookie->first.c_str(), cookie->second.c_str());
- request->Headers << CHAR_VALUE("Set-Cookie", allCookies);
- }
-
- if (response == NULL)
- {
- requestQueue->Push(request);
- return;
- }
+ requestQueue->Push(request);
+ return;
+}
+void CSkypeProto::PushRequest(HttpRequest *request, SkypeResponseCallback response)
+{
SkypeResponseDelegate *delegate = new SkypeResponseDelegate(this, response);
requestQueue->Push(request, SkypeHttpResponse, delegate);
+}
+
+void CSkypeProto::PushRequest(HttpRequest *request, SkypeResponseWithArgCallback response, void *arg)
+{
+ SkypeResponseDelegate *delegate = new SkypeResponseDelegate(this, response, arg);
+ requestQueue->Push(request, SkypeHttpResponse, delegate);
} \ No newline at end of file
diff --git a/protocols/SkypeWeb/src/skype_utils.cpp b/protocols/SkypeWeb/src/skype_utils.cpp
index df66f1ee97..4b3723dfe3 100644
--- a/protocols/SkypeWeb/src/skype_utils.cpp
+++ b/protocols/SkypeWeb/src/skype_utils.cpp
@@ -78,7 +78,6 @@ bool CSkypeProto::IsMe(const char *skypeName)
char *CSkypeProto::MirandaToSkypeStatus(int status)
{
- char *result = "Online";
switch (status)
{
case ID_STATUS_AWAY: