summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2025-01-10 15:28:20 +0300
committerGeorge Hazan <george.hazan@gmail.com>2025-01-10 15:28:20 +0300
commitb58bd0a705dba9a32e4db1420e2d615c6ee6bd41 (patch)
tree5924c1355288a80575a7caf64849b1846ebec194
parent9d98fd2380b5e8bc66ab599e896cee5ad2ec7d58 (diff)
fixes #4830 (SkypeWeb: редактированное своё сообщение приходит как новое)
-rw-r--r--protocols/SkypeWeb/src/requests/messages.h2
-rw-r--r--protocols/SkypeWeb/src/skype_chatrooms.cpp4
-rw-r--r--protocols/SkypeWeb/src/skype_files.cpp9
-rw-r--r--protocols/SkypeWeb/src/skype_history_sync.cpp5
-rw-r--r--protocols/SkypeWeb/src/skype_messages.cpp38
-rw-r--r--protocols/SkypeWeb/src/skype_proto.h16
-rw-r--r--protocols/SkypeWeb/src/skype_utils.cpp17
-rw-r--r--protocols/SkypeWeb/src/skype_utils.h3
8 files changed, 61 insertions, 33 deletions
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 <http://www.gnu.org/licenses/>.
#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<std::wstring, std::wstring> languages;
LIST<void> m_PopupClasses;
- LIST<void> m_OutMessages;
+ OBJLIST<COwnMessage> 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;