summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2024-07-31 21:37:29 +0300
committerGeorge Hazan <george.hazan@gmail.com>2024-07-31 21:37:33 +0300
commit24268b56fb96b64edd129cd1c2539fb70cd4cf58 (patch)
tree49bd3d3c002b7a0d885c39a419599c7f65490201
parent9884d399ace9dc7320b8d53255c560661323b1e0 (diff)
SkypeWeb: simple file transfers are packed into offline file events
-rw-r--r--protocols/SkypeWeb/src/skype_db.cpp2
-rw-r--r--protocols/SkypeWeb/src/skype_db.h2
-rw-r--r--protocols/SkypeWeb/src/skype_events.cpp6
-rw-r--r--protocols/SkypeWeb/src/skype_history_sync.cpp33
-rw-r--r--protocols/SkypeWeb/src/skype_messages.cpp99
-rw-r--r--protocols/SkypeWeb/src/skype_proto.h10
6 files changed, 103 insertions, 49 deletions
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 <http://www.gnu.org/licenses/>.
#ifndef _SKYPE_PROTO_H_
#define _SKYPE_PROTO_H_
+struct CSkypeTransfer
+{
+ CMStringA docId, fileName, url;
+ int iFileSize = 0;
+};
+
struct CSkypeProto : public PROTO <CSkypeProto>
{
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();