summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Lantsev <aunsane@gmail.com>2015-04-04 22:00:18 +0000
committerAlexander Lantsev <aunsane@gmail.com>2015-04-04 22:00:18 +0000
commit04da76c5fae4f4ef3eda995641b0251671d6edd0 (patch)
treedd5a96c5a9524e4e2baf94ea854e4a19dfae2471
parentc89e8a054ac888b27065916ffde96af73404228c (diff)
SkypeWeb: support of actions (/me ...)
git-svn-id: http://svn.miranda-ng.org/main/trunk@12600 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
-rw-r--r--protocols/SkypeWeb/src/common.h2
-rw-r--r--protocols/SkypeWeb/src/requests/messages.h6
-rw-r--r--protocols/SkypeWeb/src/skype_accounts.cpp1
-rw-r--r--protocols/SkypeWeb/src/skype_messages.cpp71
-rw-r--r--protocols/SkypeWeb/src/skype_poll_processing.cpp19
-rw-r--r--protocols/SkypeWeb/src/skype_proto.cpp5
-rw-r--r--protocols/SkypeWeb/src/skype_proto.h10
-rw-r--r--protocols/SkypeWeb/src/version.h2
8 files changed, 94 insertions, 22 deletions
diff --git a/protocols/SkypeWeb/src/common.h b/protocols/SkypeWeb/src/common.h
index 84060c4eba..bbe6addfb1 100644
--- a/protocols/SkypeWeb/src/common.h
+++ b/protocols/SkypeWeb/src/common.h
@@ -68,4 +68,6 @@ extern HINSTANCE g_hInstance;
#define SKYPE_SETTINGS_PASSWORD "Password"
#define SKYPE_SETTINGS_GROUP "DefaultGroup"
+#define SKYPE_DB_EVENT_TYPE_ACTION 10001
+
#endif //_COMMON_H_ \ No newline at end of file
diff --git a/protocols/SkypeWeb/src/requests/messages.h b/protocols/SkypeWeb/src/requests/messages.h
index d2c000d8be..c3ac040579 100644
--- a/protocols/SkypeWeb/src/requests/messages.h
+++ b/protocols/SkypeWeb/src/requests/messages.h
@@ -4,7 +4,7 @@
class SendMsgRequest : public HttpRequest
{
public:
- SendMsgRequest(const char *regToken, const char *username, const char *message, const char *server = "client-s.gateway.messenger.live.com") :
+ SendMsgRequest(const char *regToken, const char *username, const char *clientMsgId, 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
@@ -18,7 +18,7 @@ public:
<< CHAR_VALUE("Connection", "keep-alive");
CMStringA data;
- data.AppendFormat("{\"clientmessageid\":\"\",\"content\":\"%s\",\"messagetype\":\"RichText\",\"contenttype\":\"text\"}", message);
+ data.AppendFormat("{\"clientmessageid\":\"%s\",\"content\":\"%s\",\"messagetype\":\"RichText\",\"contenttype\":\"text\"}", clientMsgId, message);
Body << VALUE(data);
}
@@ -27,7 +27,7 @@ public:
class SendTypingRequest : public HttpRequest
{
public:
- SendTypingRequest(const char *regToken, const char *username,bool bstate, const char *server = "client-s.gateway.messenger.live.com") :
+ 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
diff --git a/protocols/SkypeWeb/src/skype_accounts.cpp b/protocols/SkypeWeb/src/skype_accounts.cpp
index 6a383045f2..ea9fe30489 100644
--- a/protocols/SkypeWeb/src/skype_accounts.cpp
+++ b/protocols/SkypeWeb/src/skype_accounts.cpp
@@ -32,6 +32,7 @@ CSkypeProto* CSkypeProto::GetContactAccount(MCONTACT hContact)
int CSkypeProto::OnAccountLoaded(WPARAM, LPARAM)
{
HookProtoEvent(ME_OPT_INITIALISE, &CSkypeProto::OnOptionsInit);
+ HookProtoEvent(ME_MSG_PRECREATEEVENT, &CSkypeProto::OnPreCreateMessage);
return 0;
}
diff --git a/protocols/SkypeWeb/src/skype_messages.cpp b/protocols/SkypeWeb/src/skype_messages.cpp
index b863fa57fd..66c53fc29d 100644
--- a/protocols/SkypeWeb/src/skype_messages.cpp
+++ b/protocols/SkypeWeb/src/skype_messages.cpp
@@ -2,33 +2,57 @@
/* MESSAGE RECEIVING */
-// writing message/even into db
-int CSkypeProto::OnReceiveMessage(const char *from, const char *convLink, time_t timestamp, char *content)
+// incoming message flow
+int CSkypeProto::OnReceiveMessage(const char *messageId, const char *from, const char *to, time_t timestamp, char *content, int emoteOffset)
{
setDword("LastMsgTime", timestamp);
PROTORECVEVENT recv = { 0 };
recv.flags = PREF_UTF;
recv.timestamp = timestamp;
- recv.szMessage = content;
+ recv.szMessage = &content[emoteOffset];
+ recv.lParam = emoteOffset == 0
+ ? EVENTTYPE_MESSAGE
+ : SKYPE_DB_EVENT_TYPE_ACTION;
+ recv.pCustomData = (void*)messageId;
+ recv.cbCustomDataSize = mir_strlen(messageId);
ptrA skypename(ContactUrlToName(from));
debugLogA("Incoming message from %s", skypename);
if (IsMe(skypename))
{
recv.flags |= PREF_SENT;
- MCONTACT hContact = GetContact(ContactUrlToName(convLink));
+ MCONTACT hContact = GetContact(ptrA(ContactUrlToName(to)));
return ProtoChainRecvMsg(hContact, &recv);
}
MCONTACT hContact = GetContact(skypename);
return ProtoChainRecvMsg(hContact, &recv);
}
+// writing message/even into db
+int CSkypeProto::SaveMessageToDb(MCONTACT hContact, PROTORECVEVENT *pre)
+{
+ //return Proto_RecvMessage(hContact, pre);
+ if (pre->szMessage == NULL)
+ return NULL;
+
+ DBEVENTINFO dbei = { sizeof(dbei) };
+ dbei.szModule = GetContactProto(hContact);
+ dbei.timestamp = pre->timestamp;
+ dbei.flags = DBEF_UTF;
+ dbei.eventType = pre->lParam;
+ dbei.cbBlob = (DWORD)strlen(pre->szMessage) + 1;
+ dbei.pBlob = (PBYTE)pre->szMessage;
+
+ return (INT_PTR)db_event_add(hContact, &dbei);
+}
+
/* MESSAGE SENDING */
struct SendMessageParam
{
MCONTACT hContact;
HANDLE hMessage;
+ char *clientMsgId;
};
// outcoming message flow
@@ -42,9 +66,11 @@ int CSkypeProto::OnSendMessage(MCONTACT hContact, int flags, const char *szMessa
return 0;
}
+ CMStringA clientMsgId(FORMAT, "%d000", time(NULL));
SendMessageParam *param = new SendMessageParam();
param->hContact = hContact;
param->hMessage = (HANDLE)hMessage;
+ param->clientMsgId = mir_strdup(clientMsgId);
ptrA message;
if (flags & PREF_UNICODE)
@@ -57,7 +83,11 @@ int CSkypeProto::OnSendMessage(MCONTACT hContact, int flags, const char *szMessa
ptrA server(getStringA("Server"));
ptrA token(getStringA("registrationToken"));
ptrA username(getStringA(hContact, "Skypename"));
- PushRequest(new SendMsgRequest(token, username, message, server), &CSkypeProto::OnMessageSent, param);
+ if (strncmp(message, "/me ", 4) == 0)
+ {
+ // TODO: make /me action send when it will work in skype web
+ }
+ PushRequest(new SendMsgRequest(token, username, clientMsgId, message, server), &CSkypeProto::OnMessageSent, param);
return hMessage;
}
@@ -67,9 +97,10 @@ void CSkypeProto::OnMessageSent(const NETLIBHTTPREQUEST *response, void *arg)
SendMessageParam *param = (SendMessageParam*)arg;
MCONTACT hContact = param->hContact;
HANDLE hMessage = param->hMessage;
+ ptrA clientMsgId(param->clientMsgId);
delete param;
- if (response->resultCode != 200 || response->resultCode != 201)
+ if (response->resultCode != 200 && response->resultCode != 201)
{
CMStringA error = "Unknown error";
if (response)
@@ -87,6 +118,29 @@ void CSkypeProto::OnMessageSent(const NETLIBHTTPREQUEST *response, void *arg)
ProtoBroadcastAck(hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, hMessage, 0);
}
+// preparing message/action to writing into db
+int CSkypeProto::OnPreCreateMessage(WPARAM, LPARAM lParam)
+{
+ MessageWindowEvent *evt = (MessageWindowEvent*)lParam;
+ if (mir_strcmp(GetContactProto(evt->hContact), m_szModuleName))
+ return 0;
+
+ char *message = (char*)evt->dbei->pBlob;
+ if (strncmp(message, "/me ", 4) == 0)
+ {
+ evt->dbei->cbBlob = evt->dbei->cbBlob - 4;
+ PBYTE action = (PBYTE)mir_alloc(evt->dbei->cbBlob);
+ memcpy(action, &evt->dbei->pBlob[4], evt->dbei->cbBlob);
+ mir_free(evt->dbei->pBlob);
+ evt->dbei->pBlob = action;
+ evt->dbei->eventType = SKYPE_DB_EVENT_TYPE_ACTION;
+ }
+
+ return 1;
+}
+
+/* HISTORY SYNC */
+
void CSkypeProto::OnGetServerHistory(const NETLIBHTTPREQUEST *response)
{
if (response == NULL)
@@ -110,6 +164,9 @@ void CSkypeProto::OnGetServerHistory(const NETLIBHTTPREQUEST *response)
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);
+ {
+ int emoteOffset = json_as_int(json_get(message, "skypeemoteoffset"));
+ OnReceiveMessage(clientMsgId, from, conversationLink, timestamp, content, emoteOffset);
+ }
}
} \ 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 e2f0f6c0de..9f0cc24fa1 100644
--- a/protocols/SkypeWeb/src/skype_poll_processing.cpp
+++ b/protocols/SkypeWeb/src/skype_poll_processing.cpp
@@ -76,13 +76,13 @@ void CSkypeProto::ProcessUserPresenceRes(JSONNODE *node)
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 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")))));
- TCHAR *composeTime = json_as_string (json_get(node, "composetime"));
+ ptrT 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_t timestamp = IsoToUnixTime(composeTime);
char *convname;
if (strstr(conversationLink, "/19:"))
{
@@ -93,21 +93,22 @@ void CSkypeProto::ProcessNewMessageRes(JSONNODE *node)
}
else if (strstr(conversationLink, "/8:"))
{
- if (!mir_strcmpi(messagetype, "Control/Typing"))
+ if (!mir_strcmpi(messageType, "Control/Typing"))
{
MCONTACT hContact = GetContact(ContactUrlToName(from));
CallService(MS_PROTO_CONTACTISTYPING, hContact, 5);
}
- else if (!mir_strcmpi(messagetype, "Control/ClearTyping"))
+ else if (!mir_strcmpi(messageType, "Control/ClearTyping"))
{
MCONTACT hContact = GetContact(ContactUrlToName(from));
CallService(MS_PROTO_CONTACTISTYPING, hContact, 0);
}
- else if (!mir_strcmpi(messagetype, "Text") || !mir_strcmpi(messagetype, "RichText"))
+ else if (!mir_strcmpi(messageType, "Text") || !mir_strcmpi(messageType, "RichText"))
{
- OnReceiveMessage(from, conversationLink, timeStamp, content);
+ int emoteOffset = json_as_int(json_get(node, "skypeemoteoffset"));
+ OnReceiveMessage(clientMsgId, from, conversationLink, timestamp, content, emoteOffset);
}
- else if (!mir_strcmpi(messagetype, "Event/SkypeVideoMessage"))
+ else if (!mir_strcmpi(messageType, "Event/SkypeVideoMessage"))
{
return; //not supported
}
diff --git a/protocols/SkypeWeb/src/skype_proto.cpp b/protocols/SkypeWeb/src/skype_proto.cpp
index eb420ad998..f7ceb14f7c 100644
--- a/protocols/SkypeWeb/src/skype_proto.cpp
+++ b/protocols/SkypeWeb/src/skype_proto.cpp
@@ -104,6 +104,11 @@ HWND CSkypeProto::SearchAdvanced(HWND owner) { return 0; }
HWND CSkypeProto::CreateExtendedSearchUI(HWND owner) { return 0; }
+int CSkypeProto::RecvMsg(MCONTACT hContact, PROTORECVEVENT *pre)
+{
+ return SaveMessageToDb(hContact, pre);
+}
+
int CSkypeProto::RecvContacts(MCONTACT, PROTORECVEVENT*) { return 0; }
int CSkypeProto::RecvFile(MCONTACT hContact, PROTOFILEEVENT *pre) { return 0; }
diff --git a/protocols/SkypeWeb/src/skype_proto.h b/protocols/SkypeWeb/src/skype_proto.h
index 1be152508d..6de26e05d5 100644
--- a/protocols/SkypeWeb/src/skype_proto.h
+++ b/protocols/SkypeWeb/src/skype_proto.h
@@ -43,6 +43,7 @@ public:
virtual HWND __cdecl SearchAdvanced(HWND owner);
virtual HWND __cdecl CreateExtendedSearchUI(HWND owner);
+ virtual int __cdecl RecvMsg(MCONTACT hContact, PROTORECVEVENT *pre);
virtual int __cdecl RecvContacts(MCONTACT hContact, PROTORECVEVENT*);
virtual int __cdecl RecvFile(MCONTACT hContact, PROTOFILEEVENT*);
virtual int __cdecl RecvUrl(MCONTACT hContact, PROTORECVEVENT*);
@@ -173,17 +174,22 @@ private:
int __cdecl OnContactDeleted(MCONTACT, LPARAM);
// messages
- int OnReceiveMessage(const char *from, const char *convLink, time_t timestamp, char *content);
+ int OnReceiveMessage(const char *messageId, const char *from, const char *to, time_t timestamp, char *content, int emoteOffset = 0);
+ int SaveMessageToDb(MCONTACT hContact, PROTORECVEVENT *pre);
+
int OnSendMessage(MCONTACT hContact, int flags, const char *message);
- void __cdecl CSkypeProto::SendMsgThread(void *arg);
void OnMessageSent(const NETLIBHTTPREQUEST *response, void *arg);
+ int __cdecl OnPreCreateMessage(WPARAM, LPARAM lParam);
+
void OnGetServerHistory(const NETLIBHTTPREQUEST *response);
+
//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
bool IsOnline();
time_t __stdcall IsoToUnixTime(const TCHAR *stamp);
diff --git a/protocols/SkypeWeb/src/version.h b/protocols/SkypeWeb/src/version.h
index 6af653b5c6..e84c003545 100644
--- a/protocols/SkypeWeb/src/version.h
+++ b/protocols/SkypeWeb/src/version.h
@@ -7,7 +7,7 @@
#define __PLUGIN_NAME "Skype protocol (Web)"
#define __FILENAME "SkypeWeb.dll"
-#define __DESCRIPTION "Skype protocol support for Miranda NG. Based on new Skype for Web API."
+#define __DESCRIPTION "Skype protocol support for Miranda NG. Based on new Skype for Web."
#define __AUTHOR "Miranda NG Team"
#define __AUTHOREMAIL ""
#define __AUTHORWEB "http://miranda-ng.org/p/SkypeWeb/"