From b58bd0a705dba9a32e4db1420e2d615c6ee6bd41 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Fri, 10 Jan 2025 15:28:20 +0300 Subject: =?UTF-8?q?fixes=20#4830=20(SkypeWeb:=20=D1=80=D0=B5=D0=B4=D0=B0?= =?UTF-8?q?=D0=BA=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD=D0=BE?= =?UTF-8?q?=D0=B5=20=D1=81=D0=B2=D0=BE=D1=91=20=D1=81=D0=BE=D0=BE=D0=B1?= =?UTF-8?q?=D1=89=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF=D1=80=D0=B8=D1=85=D0=BE?= =?UTF-8?q?=D0=B4=D0=B8=D1=82=20=D0=BA=D0=B0=D0=BA=20=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D0=BE=D0=B5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- protocols/SkypeWeb/src/requests/messages.h | 2 +- protocols/SkypeWeb/src/skype_chatrooms.cpp | 4 +-- protocols/SkypeWeb/src/skype_files.cpp | 9 ++----- protocols/SkypeWeb/src/skype_history_sync.cpp | 5 ++-- protocols/SkypeWeb/src/skype_messages.cpp | 38 +++++++++++++-------------- protocols/SkypeWeb/src/skype_proto.h | 16 +++++++++-- protocols/SkypeWeb/src/skype_utils.cpp | 17 ++++++++++++ protocols/SkypeWeb/src/skype_utils.h | 3 +++ 8 files changed, 61 insertions(+), 33 deletions(-) (limited to 'protocols/SkypeWeb/src') diff --git a/protocols/SkypeWeb/src/requests/messages.h b/protocols/SkypeWeb/src/requests/messages.h index 18702eea84..4c7a3cecae 100644 --- a/protocols/SkypeWeb/src/requests/messages.h +++ b/protocols/SkypeWeb/src/requests/messages.h @@ -26,7 +26,7 @@ struct SendTypingRequest : public AsyncHttpRequest const char *state = (iState == PROTOTYPE_SELFTYPING_ON) ? "Control/Typing" : "Control/ClearTyping"; JSONNode node; - node << INT_PARAM("clientmessageid", (long)time(NULL)) << CHAR_PARAM("messagetype", state) + node << INT64_PARAM("clientmessageid", getRandomId()) << CHAR_PARAM("messagetype", state) << CHAR_PARAM("contenttype", "text") << CHAR_PARAM("content", ""); m_szParam = node.write().c_str(); } diff --git a/protocols/SkypeWeb/src/skype_chatrooms.cpp b/protocols/SkypeWeb/src/skype_chatrooms.cpp index df3ed5cbc9..5c80b67f3b 100644 --- a/protocols/SkypeWeb/src/skype_chatrooms.cpp +++ b/protocols/SkypeWeb/src/skype_chatrooms.cpp @@ -340,8 +340,8 @@ void CSkypeProto::SendChatMessage(SESSION_INFO *si, const wchar_t *tszMessage) AsyncHttpRequest *pReq = new AsyncHttpRequest(REQUEST_POST, HOST_DEFAULT, szUrl, &CSkypeProto::OnMessageSent); JSONNode node; - node << CHAR_PARAM("clientmessageid", CMStringA(::FORMAT, "%llu000", (ULONGLONG)time(0))) - << CHAR_PARAM("messagetype", bRich ? "RichText" : "Text") << CHAR_PARAM("contenttype", "text") << CHAR_PARAM("content", szMessage); + node << INT64_PARAM("clientmessageid", getRandomId()) << CHAR_PARAM("messagetype", bRich ? "RichText" : "Text") + << CHAR_PARAM("contenttype", "text") << CHAR_PARAM("content", szMessage); if (strncmp(szMessage, "/me ", 4) == 0) node << INT_PARAM("skypeemoteoffset", 4); pReq->m_szParam = node.write().c_str(); diff --git a/protocols/SkypeWeb/src/skype_files.cpp b/protocols/SkypeWeb/src/skype_files.cpp index 6d3f6646db..41608e3c8b 100644 --- a/protocols/SkypeWeb/src/skype_files.cpp +++ b/protocols/SkypeWeb/src/skype_files.cpp @@ -256,15 +256,10 @@ void CSkypeProto::OnASMObjectUploaded(MHttpResponse *response, AsyncHttpRequest tinyxml2::XMLPrinter printer(0, true); doc.Print(&printer); - uint32_t hMessage; - Utils_GetRandom(&hMessage, sizeof(hMessage)); - hMessage &= ~0x80000000; - // create a new file transfer event using previously filled slot - auto *pReq = new AsyncHttpRequest(REQUEST_POST, HOST_DEFAULT, 0, &CSkypeProto::OnMessageSent); + auto *pReq = new AsyncHttpRequest(REQUEST_POST, HOST_DEFAULT); pReq->m_szUrl.AppendFormat("/users/ME/conversations/%s/messages", mir_urlEncode(getId(fup->hContact)).c_str()); pReq->hContact = fup->hContact; - pReq->pUserInfo = (HANDLE)hMessage; JSONNode ref(JSON_ARRAY); ref.set_name("amsreferences"); ref << CHAR_PARAM("", fup->uid); @@ -274,7 +269,7 @@ void CSkypeProto::OnASMObjectUploaded(MHttpResponse *response, AsyncHttpRequest else node << CHAR_PARAM("messagetype", "RichText/Media_GenericFile"); - node << INT64_PARAM("clientmessageid", time(0)) << CHAR_PARAM("contenttype", "text") << CHAR_PARAM("content", printer.CStr()) << ref; + node << INT64_PARAM("clientmessageid", getRandomId()) << CHAR_PARAM("contenttype", "text") << CHAR_PARAM("content", printer.CStr()) << ref; pReq->m_szParam = node.write().c_str(); PushRequest(pReq); diff --git a/protocols/SkypeWeb/src/skype_history_sync.cpp b/protocols/SkypeWeb/src/skype_history_sync.cpp index 48a6a56128..4861c621c3 100644 --- a/protocols/SkypeWeb/src/skype_history_sync.cpp +++ b/protocols/SkypeWeb/src/skype_history_sync.cpp @@ -42,14 +42,15 @@ void CSkypeProto::OnGetServerHistory(MHttpResponse *response, AsyncHttpRequest * auto &conv = root["messages"]; for (auto it = conv.rbegin(); it != conv.rend(); ++it) { auto &message = *it; - CMStringA szMessageId = message["id"].as_mstring(); - int64_t id = _atoi64(szMessageId); + CMStringA szId = message["id"].as_mstring(); + int64_t id = _atoi64(szId); if (id > lastMsgTime) { bSetLastTime = true; lastMsgTime = id; } int iUserType; + CMStringA szMessageId(getMessageId(message)); CMStringA szChatId = UrlToSkypeId(message["conversationLink"].as_mstring(), &iUserType); CMStringA szFrom = UrlToSkypeId(message["from"].as_mstring()); diff --git a/protocols/SkypeWeb/src/skype_messages.cpp b/protocols/SkypeWeb/src/skype_messages.cpp index d9621c839a..d944390d5e 100644 --- a/protocols/SkypeWeb/src/skype_messages.cpp +++ b/protocols/SkypeWeb/src/skype_messages.cpp @@ -43,25 +43,24 @@ void CSkypeProto::OnMessageSent(MHttpResponse *response, AsyncHttpRequest *pRequ } // outcoming message flow + int CSkypeProto::SendMsg(MCONTACT hContact, MEVENT, const char *szMessage) { if (!IsOnline()) return -1; - uint32_t hMessage; - Utils_GetRandom(&hMessage, sizeof(hMessage)); - hMessage &= ~0x80000000; - CMStringA str(szMessage); bool bRich = AddBbcodes(str); + int64_t iRandomId = getRandomId(); + m_iMessageId++; CMStringA szUrl = "/users/ME/conversations/" + mir_urlEncode(getId(hContact)) + "/messages"; AsyncHttpRequest *pReq = new AsyncHttpRequest(REQUEST_POST, HOST_DEFAULT, szUrl, &CSkypeProto::OnMessageSent); pReq->hContact = hContact; - pReq->pUserInfo = (HANDLE)hMessage; + pReq->pUserInfo = (HANDLE)m_iMessageId; JSONNode node; - node << INT64_PARAM("clientmessageid", hMessage) << CHAR_PARAM("messagetype", bRich ? "RichText" : "Text") << CHAR_PARAM("contenttype", "text"); + node << INT64_PARAM("clientmessageid", iRandomId) << CHAR_PARAM("messagetype", bRich ? "RichText" : "Text") << CHAR_PARAM("contenttype", "text"); if (strncmp(str, "/me ", 4) == 0) node << CHAR_PARAM("content", m_szSkypename + " " + str); else @@ -71,8 +70,8 @@ int CSkypeProto::SendMsg(MCONTACT hContact, MEVENT, const char *szMessage) PushRequest(pReq); mir_cslock lck(m_lckOutMessagesList); - m_OutMessages.insert((void*)hMessage); - return hMessage; + m_OutMessages.insert(new COwnMessage(m_iMessageId, iRandomId)); + return m_iMessageId; } // preparing message/action to be written into db @@ -120,15 +119,15 @@ LBL_Deleted: } if (strMessageType == "Text" || strMessageType == "RichText") { - std::string szOwnMessageId = node["clientmessageid"].as_string(); - if ((dbei.flags & DBEF_SENT) && !szOwnMessageId.empty()) { - HANDLE hMessage = (HANDLE)atoi(szOwnMessageId.c_str()); - if (m_OutMessages.getIndex(hMessage) != -1) { - ProtoBroadcastAck(dbei.hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, hMessage, (LPARAM)dbei.szId); - - mir_cslock lck(m_lckOutMessagesList); - m_OutMessages.remove(hMessage); - return false; + if ((dbei.flags & DBEF_SENT) && dbei.szId) { + for (auto &it: m_OutMessages) { + if (it->hClientMessageId == _atoi64(dbei.szId)) { + ProtoBroadcastAck(dbei.hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)it->hMessage, (LPARAM)dbei.szId); + + mir_cslock lck(m_lckOutMessagesList); + m_OutMessages.removeItem(&it); + return false; + } } } @@ -163,7 +162,8 @@ void CSkypeProto::ProcessNewMessage(const JSONNode &node) int iUserType; UrlToSkypeId(node["conversationLink"].as_string().c_str(), &iUserType); - CMStringA szMessageId = node["id"].as_mstring(); + CMStringA szId = node["id"].as_mstring(); + CMStringA szMessageId(getMessageId(node)); CMStringA szConversationName(UrlToSkypeId(node["conversationLink"].as_string().c_str())); CMStringA szFromSkypename(UrlToSkypeId(node["from"].as_mstring())); @@ -174,7 +174,7 @@ void CSkypeProto::ProcessNewMessage(const JSONNode &node) MCONTACT hContact = AddContact(szConversationName, nullptr, true); if (m_bHistorySynced) { - int64_t lastMsgId = _atoi64(szMessageId); + int64_t lastMsgId = _atoi64(szId); if (lastMsgId > getLastTime(hContact)) setLastTime(hContact, lastMsgId); } diff --git a/protocols/SkypeWeb/src/skype_proto.h b/protocols/SkypeWeb/src/skype_proto.h index b1feccf602..0653e771fa 100644 --- a/protocols/SkypeWeb/src/skype_proto.h +++ b/protocols/SkypeWeb/src/skype_proto.h @@ -18,6 +18,17 @@ along with this program. If not, see . #ifndef _SKYPE_PROTO_H_ #define _SKYPE_PROTO_H_ +struct COwnMessage +{ + COwnMessage(int _1, int64_t _2) : + hMessage(_1), + hClientMessageId(_2) + {} + + int hMessage; + int64_t hClientMessageId; +}; + struct CSkypeTransfer { CMStringA docId, fileName, fileType, url; @@ -75,6 +86,7 @@ public: void OnBuildProtoMenu(void) override; bool OnContactDeleted(MCONTACT, uint32_t flags) override; MWindow OnCreateAccMgrUI(MWindow) override; + // void OnEventEdited(MCONTACT hContact, MEVENT hDbEvent, const DBEVENTINFO &dbei) override; void OnEventDeleted(MCONTACT hContact, MEVENT hDbEvent, int flags) override; void OnMarkRead(MCONTACT, MEVENT) override; void OnModulesLoaded() override; @@ -118,7 +130,7 @@ public: ////////////////////////////////////////////////////////////////////////////////////// // other data - int m_iPollingId; + int m_iPollingId, m_iMessageId = 1; ptrA m_szApiToken, m_szToken, m_szId, m_szOwnSkypeId; CMStringA m_szSkypename, m_szMyname; MCONTACT m_hMyContact; @@ -177,7 +189,7 @@ private: static std::map languages; LIST m_PopupClasses; - LIST m_OutMessages; + OBJLIST m_OutMessages; // locks mir_cs m_lckOutMessagesList; diff --git a/protocols/SkypeWeb/src/skype_utils.cpp b/protocols/SkypeWeb/src/skype_utils.cpp index 41593b0a97..26cf39e7bb 100644 --- a/protocols/SkypeWeb/src/skype_utils.cpp +++ b/protocols/SkypeWeb/src/skype_utils.cpp @@ -661,6 +661,23 @@ bool CSkypeProto::IsFileExists(std::wstring path) return _waccess(path.c_str(), 0) == 0; } +int64_t getRandomId() +{ + int64_t ret; + Utils_GetRandom(&ret, sizeof(ret)); + if (ret < 0) + ret = -ret; + return ret; +} + +CMStringA getMessageId(const JSONNode &node) +{ + CMStringA ret(node["skypeeditedid"].as_mstring()); + if (ret.IsEmpty()) + ret = node["clientmessageid"].as_mstring(); + return ret; +} + const char* GetSkypeNick(const char *szSkypeId) { if (auto *p = strchr(szSkypeId, ':')) diff --git a/protocols/SkypeWeb/src/skype_utils.h b/protocols/SkypeWeb/src/skype_utils.h index feef9b8883..ee80c82c8c 100644 --- a/protocols/SkypeWeb/src/skype_utils.h +++ b/protocols/SkypeWeb/src/skype_utils.h @@ -35,6 +35,9 @@ CMStringW UrlToSkypeId(const wchar_t *url, int *pUserType = nullptr); int getMoodIndex(const char *pszMood); +int64_t getRandomId(); +CMStringA getMessageId(const JSONNode &node); + class EventHandle { HANDLE _hEvent; -- cgit v1.2.3