From 24268b56fb96b64edd129cd1c2539fb70cd4cf58 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Wed, 31 Jul 2024 21:37:29 +0300 Subject: SkypeWeb: simple file transfers are packed into offline file events --- protocols/SkypeWeb/src/skype_db.cpp | 2 - protocols/SkypeWeb/src/skype_db.h | 2 - protocols/SkypeWeb/src/skype_events.cpp | 6 -- protocols/SkypeWeb/src/skype_history_sync.cpp | 33 ++++----- protocols/SkypeWeb/src/skype_messages.cpp | 99 +++++++++++++++++++++------ protocols/SkypeWeb/src/skype_proto.h | 10 ++- 6 files changed, 103 insertions(+), 49 deletions(-) (limited to 'protocols/SkypeWeb/src') diff --git a/protocols/SkypeWeb/src/skype_db.cpp b/protocols/SkypeWeb/src/skype_db.cpp index e83563c735..967aa1e5a4 100644 --- a/protocols/SkypeWeb/src/skype_db.cpp +++ b/protocols/SkypeWeb/src/skype_db.cpp @@ -28,9 +28,7 @@ static g_SkypeDBTypes[] = { SKYPE_DB_EVENT_TYPE_ACTION, LPGEN("Action"), 0 }, { SKYPE_DB_EVENT_TYPE_CALL_INFO, LPGEN("Call information"), 0 }, { SKYPE_DB_EVENT_TYPE_FILETRANSFER_INFO, LPGEN("File transfer information"), 0 }, - { SKYPE_DB_EVENT_TYPE_URIOBJ, LPGEN("URI object"), 0 }, { SKYPE_DB_EVENT_TYPE_MOJI, LPGEN("Moji"), 0 }, - { SKYPE_DB_EVENT_TYPE_FILE, LPGEN("File"), 0 }, { SKYPE_DB_EVENT_TYPE_UNKNOWN, LPGEN("Unknown event"), 0 }, }; diff --git a/protocols/SkypeWeb/src/skype_db.h b/protocols/SkypeWeb/src/skype_db.h index b498b6266d..47bca1bcc4 100644 --- a/protocols/SkypeWeb/src/skype_db.h +++ b/protocols/SkypeWeb/src/skype_db.h @@ -24,9 +24,7 @@ enum SKYPE_DB_EVENT_TYPE SKYPE_DB_EVENT_TYPE_INCOMING_CALL, SKYPE_DB_EVENT_TYPE_CALL_INFO, SKYPE_DB_EVENT_TYPE_FILETRANSFER_INFO, - SKYPE_DB_EVENT_TYPE_URIOBJ, SKYPE_DB_EVENT_TYPE_MOJI, - SKYPE_DB_EVENT_TYPE_FILE, SKYPE_DB_EVENT_TYPE_UNKNOWN }; diff --git a/protocols/SkypeWeb/src/skype_events.cpp b/protocols/SkypeWeb/src/skype_events.cpp index af088bbe88..44d662f4e5 100644 --- a/protocols/SkypeWeb/src/skype_events.cpp +++ b/protocols/SkypeWeb/src/skype_events.cpp @@ -72,9 +72,7 @@ INT_PTR CSkypeProto::GetEventText(WPARAM pEvent, LPARAM datatype) } break; - case SKYPE_DB_EVENT_TYPE_FILE: case SKYPE_DB_EVENT_TYPE_MOJI: - case SKYPE_DB_EVENT_TYPE_URIOBJ: { TiXmlDocument doc; if (0 != doc.Parse((char*)dbei->pBlob)) @@ -132,10 +130,6 @@ INT_PTR CSkypeProto::EventGetIcon(WPARAM flags, LPARAM pEvent) icon = Skin_LoadIcon(SKINICON_EVENT_FILE); break; - case SKYPE_DB_EVENT_TYPE_URIOBJ: - icon = Skin_LoadIcon(SKINICON_EVENT_URL); - break; - case SKYPE_DB_EVENT_TYPE_UNKNOWN: icon = Skin_LoadIcon(SKINICON_WARNING); break; diff --git a/protocols/SkypeWeb/src/skype_history_sync.cpp b/protocols/SkypeWeb/src/skype_history_sync.cpp index 3984845d7c..5d141174e3 100644 --- a/protocols/SkypeWeb/src/skype_history_sync.cpp +++ b/protocols/SkypeWeb/src/skype_history_sync.cpp @@ -53,12 +53,12 @@ void CSkypeProto::OnGetServerHistory(MHttpResponse *response, AsyncHttpRequest * if (timestamp > getDword(hContact, "LastMsgTime", 0)) setDword(hContact, "LastMsgTime", timestamp); - CMStringW wszContent = message["content"].as_mstring(); - T2Utf szMsg(wszContent); - if (messageType == "RichText/Contacts") { - ProcessContactRecv(hContact, timestamp, szMsg, szMessageId); - return; - } + DB::EventInfo dbei(db_event_getById(m_szModuleName, szMessageId)); + dbei.szModule = m_szModuleName; + dbei.timestamp = timestamp; + dbei.szId = szMessageId; + if (iUserType == 19) + dbei.szUserId = szFrom; uint32_t id = message["id"].as_int(); if (id > lastMsgTime) @@ -67,14 +67,23 @@ void CSkypeProto::OnGetServerHistory(MHttpResponse *response, AsyncHttpRequest * if (bUseLocalTime) timestamp = iLocalTime; - DB::EventInfo dbei(db_event_getById(m_szModuleName, szMessageId)); - dbei.flags = DBEF_UTF; if (!markAllAsUnread) dbei.flags |= DBEF_READ; if (IsMe(szFrom)) dbei.flags |= DBEF_SENT; + CMStringW wszContent = message["content"].as_mstring(); + T2Utf szMsg(wszContent); + if (messageType == "RichText/UriObject") { + ProcessFileRecv(hContact, szMsg, dbei); + return; + } + if (messageType == "RichText/Contacts") { + ProcessContactRecv(hContact, szMsg, dbei); + return; + } + if (messageType == "Text" || messageType == "RichText") { CMStringW szMessage(messageType == "RichText" ? RemoveHtml(wszContent) : wszContent); dbei.eventType = (emoteOffset == 0) ? EVENTTYPE_MESSAGE : SKYPE_DB_EVENT_TYPE_ACTION; @@ -85,9 +94,6 @@ void CSkypeProto::OnGetServerHistory(MHttpResponse *response, AsyncHttpRequest * else if (messageType == "RichText/Files") { dbei.eventType = SKYPE_DB_EVENT_TYPE_FILETRANSFER_INFO; } - else if (messageType == "RichText/UriObject") { - dbei.eventType = SKYPE_DB_EVENT_TYPE_URIOBJ; - } else if (messageType == "RichText/Media_Album") { // do nothing } @@ -95,13 +101,8 @@ void CSkypeProto::OnGetServerHistory(MHttpResponse *response, AsyncHttpRequest * dbei.eventType = SKYPE_DB_EVENT_TYPE_UNKNOWN; } - dbei.szModule = m_szModuleName; - dbei.timestamp = timestamp; dbei.cbBlob = (uint32_t)mir_strlen(szMsg); dbei.pBlob = szMsg; - dbei.szId = szMessageId; - if (iUserType == 19) - dbei.szUserId = szFrom; if (dbei) { db_event_edit(dbei.getEvent(), &dbei, true); diff --git a/protocols/SkypeWeb/src/skype_messages.cpp b/protocols/SkypeWeb/src/skype_messages.cpp index 4c57fa2322..feef52da75 100644 --- a/protocols/SkypeWeb/src/skype_messages.cpp +++ b/protocols/SkypeWeb/src/skype_messages.cpp @@ -96,12 +96,6 @@ void CSkypeProto::ProcessNewMessage(const JSONNode &node) CMStringA szConversationName(UrlToSkypeId(node["conversationLink"].as_string().c_str())); CMStringA szFromSkypename(UrlToSkypeId(node["from"].as_mstring())); - CMStringW wszContent = node["content"].as_mstring(); - - std::string strMessageType = node["messagetype"].as_string(); - if (strMessageType == "RichText") - wszContent = RemoveHtml(wszContent); - time_t timestamp = time(0); // fuck the server time, we need to place events in the order of our local time int nEmoteOffset = node["skypeemoteoffset"].as_int(); @@ -115,6 +109,7 @@ void CSkypeProto::ProcessNewMessage(const JSONNode &node) if (IsMe(szFromSkypename)) dwFlags |= DBEF_SENT; + std::string strMessageType = node["messagetype"].as_string(); if (strMessageType == "Control/Typing") { CallService(MS_PROTO_CONTACTISTYPING, hContact, PROTOTYPE_CONTACTTYPING_INFINITE); return; @@ -124,16 +119,24 @@ void CSkypeProto::ProcessNewMessage(const JSONNode &node) return; } + CMStringW wszContent = node["content"].as_mstring(); T2Utf szMsg(wszContent); DB::EventInfo dbei(db_event_getById(m_szModuleName, szMessageId)); dbei.timestamp = timestamp; - dbei.pBlob = szMsg; - dbei.cbBlob = (uint32_t)mir_strlen(szMsg); dbei.szId = szMessageId; if (iUserType == 19) dbei.szUserId = szFromSkypename; + if (strMessageType == "RichText/Media_GenericFile") { + ProcessFileRecv(hContact, szMsg, dbei); + return; + } + if (strMessageType == "RichText/Contacts") { + ProcessContactRecv(hContact, T2Utf(wszContent), dbei); + return; + } + if (strMessageType == "Text" || strMessageType == "RichText") { if (IsMe(szFromSkypename)) { HANDLE hMessage = (HANDLE)atoi(szMessageId); @@ -147,6 +150,9 @@ void CSkypeProto::ProcessNewMessage(const JSONNode &node) } else CallService(MS_PROTO_CONTACTISTYPING, hContact, PROTOTYPE_CONTACTTYPING_OFF); + if (strMessageType == "RichText") + wszContent = RemoveHtml(wszContent); + dbei.eventType = nEmoteOffset == 0 ? EVENTTYPE_MESSAGE : SKYPE_DB_EVENT_TYPE_ACTION; } else if (strMessageType == "Event/Call") { @@ -155,19 +161,9 @@ void CSkypeProto::ProcessNewMessage(const JSONNode &node) else if (strMessageType == "RichText/Files") { dbei.eventType = SKYPE_DB_EVENT_TYPE_FILETRANSFER_INFO; } - else if (strMessageType == "RichText/UriObject") { - dbei.eventType = SKYPE_DB_EVENT_TYPE_URIOBJ; - } - else if (strMessageType == "RichText/Contacts") { - ProcessContactRecv(hContact, timestamp, T2Utf(wszContent), szMessageId); - return; - } else if (strMessageType == "RichText/Media_FlikMsg") { dbei.eventType = SKYPE_DB_EVENT_TYPE_MOJI; } - else if (strMessageType == "RichText/Media_GenericFile") { - dbei.eventType = SKYPE_DB_EVENT_TYPE_FILE; - } else if (strMessageType == "RichText/Media_Album") { // do nothing } @@ -179,6 +175,9 @@ void CSkypeProto::ProcessNewMessage(const JSONNode &node) dbei.eventType = SKYPE_DB_EVENT_TYPE_UNKNOWN; } + dbei.pBlob = szMsg; + dbei.cbBlob = (uint32_t)mir_strlen(szMsg); + if (dbei) { db_event_edit(dbei.getEvent(), &dbei, true); dbei.pBlob = nullptr; @@ -204,7 +203,66 @@ void CSkypeProto::MarkMessagesRead(MCONTACT hContact, MEVENT hDbEvent) PushRequest(new MarkMessageReadRequest(getId(hContact), timestamp, timestamp)); } -void CSkypeProto::ProcessContactRecv(MCONTACT hContact, time_t timestamp, const char *szContent, const char *szMessageId) +void CSkypeProto::OnReceiveOfflineFile(DB::FILE_BLOB &blob) +{ + if (auto *ft = (CSkypeTransfer *)blob.getUserInfo()) { + blob.setUrl(ft->url); + blob.setSize(ft->iFileSize); + delete ft; + } +} + +void CSkypeProto::ProcessFileRecv(MCONTACT hContact, const char *szContent, DB::EventInfo &dbei) +{ + TiXmlDocument doc; + if (0 != doc.Parse(szContent)) + return; + + auto *xmlRoot = doc.FirstChildElement("URIObject"); + if (xmlRoot == nullptr) + return; + + const char *pszFileType = 0; + CSkypeTransfer *ft = new CSkypeTransfer; + if (auto *str = xmlRoot->Attribute("doc_id")) + ft->docId = str; + if (auto *str = xmlRoot->Attribute("uri")) + ft->url = str; + if (auto *str = xmlRoot->Attribute("type")) + pszFileType = str; + if (auto *xml = xmlRoot->FirstChildElement("FileSize")) + if (auto *str = xml->Attribute("v")) + ft->iFileSize = atoi(str); + if (auto *xml = xmlRoot->FirstChildElement("OriginalName")) + if (auto *str = xml->Attribute("v")) + ft->fileName = str; + + if (ft->url.IsEmpty() || ft->fileName.IsEmpty() || ft->iFileSize == 0) { + debugLogA("Missing file info: url=<%s> name=<%s> %d", ft->url.c_str(), ft->fileName.c_str(), ft->iFileSize); + delete ft; + return; + } + + // ordinary file + if (!mir_strcmp(pszFileType, "File.1")) { + } + else { + debugLogA("Invalid or unsupported file type <%s> ignored", pszFileType); + return; + } + + dbei.flags |= DBEF_TEMPORARY; + if (dbei) { + DB::FILE_BLOB blob(dbei); + OnReceiveOfflineFile(blob); + blob.write(dbei); + db_event_edit(dbei.getEvent(), &dbei, true); + delete ft; + } + else ProtoChainRecvFile(hContact, DB::FILE_BLOB(ft, ft->fileName), dbei); +} + +void CSkypeProto::ProcessContactRecv(MCONTACT hContact, const char *szContent, DB::EventInfo &dbei) { TiXmlDocument doc; if (0 != doc.Parse(szContent)) @@ -231,11 +289,8 @@ void CSkypeProto::ProcessContactRecv(MCONTACT hContact, time_t timestamp, const } if (nCount) { - DB::EventInfo dbei; - dbei.timestamp = (uint32_t)timestamp; dbei.pBlob = (char*)psr; dbei.cbBlob = nCount; - dbei.szId = szMessageId; ProtoChainRecv(hContact, PSR_CONTACTS, 0, (LPARAM)&dbei); for (int i = 0; i < nCount; i++) { diff --git a/protocols/SkypeWeb/src/skype_proto.h b/protocols/SkypeWeb/src/skype_proto.h index 488e7db19d..bd71a99658 100644 --- a/protocols/SkypeWeb/src/skype_proto.h +++ b/protocols/SkypeWeb/src/skype_proto.h @@ -18,6 +18,12 @@ along with this program. If not, see . #ifndef _SKYPE_PROTO_H_ #define _SKYPE_PROTO_H_ +struct CSkypeTransfer +{ + CMStringA docId, fileName, url; + int iFileSize = 0; +}; + struct CSkypeProto : public PROTO { friend class CSkypeOptionsMain; @@ -72,6 +78,7 @@ public: MWindow OnCreateAccMgrUI(MWindow) override; void OnMarkRead(MCONTACT, MEVENT) override; void OnModulesLoaded() override; + void OnReceiveOfflineFile(DB::FILE_BLOB &blob) override; void OnShutdown() override; // icons @@ -251,7 +258,8 @@ private: void MarkMessagesRead(MCONTACT hContact, MEVENT hDbEvent); - void ProcessContactRecv(MCONTACT hContact, time_t timestamp, const char *szContent, const char *szMessageId); + void ProcessContactRecv(MCONTACT hContact, const char *szContent, DB::EventInfo &dbei); + void ProcessFileRecv(MCONTACT hContact, const char *szContent, DB::EventInfo &dbei); // chats void InitGroupChatModule(); -- cgit v1.2.3