From 92937e4817268a029cc2446b74319a0d29025ed2 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Mon, 5 Feb 2024 13:17:46 +0300 Subject: =?UTF-8?q?fixes=20#4141=20(ICQ:=20=D0=BF=D1=80=D0=B8=20=D1=83?= =?UTF-8?q?=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD=D0=B8=D0=B8=20=D1=81=D0=B2=D0=BE?= =?UTF-8?q?=D0=B5=D0=B3=D0=BE=20=D1=81=D0=BE=D0=BE=D0=B1=D1=89=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=BD=D1=83=D0=B6=D0=BD=D0=BE=20=D1=81=D1=80?= =?UTF-8?q?=D0=B0=D0=B7=D1=83=20=D0=B6=D0=B5=20=D0=B7=D0=B0=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D1=88=D0=B8=D0=B2=D0=B0=D1=82=D1=8C=20=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D1=8B=D0=B5=20=D1=81=D0=BE=D0=B1=D1=8B=D1=82=D0=B8=D1=8F=20?= =?UTF-8?q?=D1=83=20=D1=81=D0=B5=D1=80=D0=B2=D0=B5=D1=80=D0=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- protocols/ICQ-WIM/src/poll.cpp | 6 ++++++ protocols/ICQ-WIM/src/proto.cpp | 18 +++++++++++++++--- protocols/ICQ-WIM/src/proto.h | 4 +++- protocols/ICQ-WIM/src/server.cpp | 32 +++++++++++++++++++++++++++++--- 4 files changed, 53 insertions(+), 7 deletions(-) (limited to 'protocols') diff --git a/protocols/ICQ-WIM/src/poll.cpp b/protocols/ICQ-WIM/src/poll.cpp index 2972ce770c..c24fe39333 100644 --- a/protocols/ICQ-WIM/src/poll.cpp +++ b/protocols/ICQ-WIM/src/poll.cpp @@ -207,7 +207,13 @@ void CIcqProto::ProcessHistData(const JSONNode &ev) setId(hContact, DB_KEY_LASTMSGID, lastMsgId); } + if (pUser && pUser->m_bSkipPatch) { + pUser->m_bSkipPatch = false; + goto LBL_SkipPatch; + } + ProcessPatchVersion(hContact, _wtoi64(ev["patchVersion"].as_mstring())); +LBL_SkipPatch: __int64 srvLastId = _wtoi64(ev["lastMsgId"].as_mstring()); diff --git a/protocols/ICQ-WIM/src/proto.cpp b/protocols/ICQ-WIM/src/proto.cpp index 9978c83ed6..c9ddc82054 100644 --- a/protocols/ICQ-WIM/src/proto.cpp +++ b/protocols/ICQ-WIM/src/proto.cpp @@ -209,10 +209,19 @@ void CIcqProto::OnEventEdited(MCONTACT, MEVENT, const DBEVENTINFO &) ///////////////////////////////////////////////////////////////////////////////////////// // batch events deletion from the server -void CIcqProto::BatchDeleteMsg() +void CIcqProto::OnBatchDeleteMsg(MHttpResponse *pReply, AsyncHttpRequest *pReq) { - auto *pReq = new AsyncRapiRequest(this, "delMsgBatch"); + RobustReply root(pReply); + if (root.error() != 20000) + return; + + if (auto *pUser = FindUser(GetUserId(pReq->hContact))) + pUser->m_bSkipPatch = true; + RetrievePatches(pReq->hContact); +} +void CIcqProto::BatchDeleteMsg() +{ JSONNode ids(JSON_ARRAY); ids.set_name("msgIds"); mir_cslock lck(m_csDeleteQueue); @@ -221,6 +230,8 @@ void CIcqProto::BatchDeleteMsg() mir_free(it); } + auto *pReq = new AsyncRapiRequest(this, "delMsgBatch", &CIcqProto::OnBatchDeleteMsg); + pReq->hContact = m_hDeleteContact; pReq->params << WCHAR_PARAM("sn", GetUserId(m_hDeleteContact)) << BOOL_PARAM("silent", true) << BOOL_PARAM("shared", m_bRemoveForAll) << ids; Push(pReq); @@ -230,7 +241,8 @@ void CIcqProto::BatchDeleteMsg() void CIcqProto::OnEventDeleted(MCONTACT hContact, MEVENT hEvent, int flags) { - if (!(flags & CDF_FROM_SERVER)) + // the command arrived from the server, don't send it back then + if (flags & CDF_FROM_SERVER) return; if (m_hDeleteContact != INVALID_CONTACT_ID) diff --git a/protocols/ICQ-WIM/src/proto.h b/protocols/ICQ-WIM/src/proto.h index f4f3e8f8d7..8416e344a7 100644 --- a/protocols/ICQ-WIM/src/proto.h +++ b/protocols/ICQ-WIM/src/proto.h @@ -115,7 +115,7 @@ struct IcqUser : public MZeroedObject CMStringW m_aimid; MCONTACT m_hContact; - bool m_bInList, m_bGotCaps, m_bWasOnline; + bool m_bInList, m_bGotCaps, m_bWasOnline, m_bSkipPatch; __int64 m_iProcessedMsgId; int m_iApparentMode; time_t m_timer1, m_timer2; @@ -245,6 +245,7 @@ class CIcqProto : public PROTO void ParseMessage(MCONTACT hContact, __int64 &lastMsgId, const JSONNode &msg, bool bCreateRead, bool bLocalTime); void ParseMessagePart(MCONTACT hContact, const JSONNode &msg, IcqFileInfo *&pFileInfo); IcqFileInfo* RetrieveFileInfo(MCONTACT hContact, const CMStringW &wszUrl); + void RetrievePatches(MCONTACT hContact); int StatusFromPresence(const JSONNode &presence, MCONTACT hContact); void ProcessPatchVersion(MCONTACT hContact, __int64 currPatch); void ProcessStatus(IcqUser *pUser, int iStatus); @@ -266,6 +267,7 @@ class CIcqProto : public PROTO void OnAddBuddy(MHttpResponse *pReply, AsyncHttpRequest *pReq); void OnAddClient(MHttpResponse *pReply, AsyncHttpRequest *pReq); + void OnBatchDeleteMsg(MHttpResponse *pReply, AsyncHttpRequest *pReq); void OnCheckMraAuth(MHttpResponse *pReply, AsyncHttpRequest *pReq); void OnCheckMraAuthFinal(MHttpResponse *pReply, AsyncHttpRequest *pReq); void OnCheckMrimLogin(MHttpResponse *pReply, AsyncHttpRequest *pReq); diff --git a/protocols/ICQ-WIM/src/server.cpp b/protocols/ICQ-WIM/src/server.cpp index 945ab57ba3..abba88aa22 100644 --- a/protocols/ICQ-WIM/src/server.cpp +++ b/protocols/ICQ-WIM/src/server.cpp @@ -822,15 +822,26 @@ void CIcqProto::OnGetPatches(MHttpResponse *pReply, AsyncHttpRequest *pReq) for (auto &it : results["patch"]) { std::string type = it["type"].as_string(); __int64 msgId = _wtoi64(it["msgId"].as_mstring()); - if (type == "update") + if (type == "update" || type == "modify") events[msgId] = true; else events[msgId] = false; } for (auto &it : events) { - if (it.second) - RetrieveHistoryChunk(pReq->hContact, it.first, it.first-1, 1); + if (it.second) { + bool bFound = false; + + for (auto &msg: results["messages"]) + if (_wtoi64(msg["msgId"].as_mstring()) == it.first) { + bFound = true; + __int64 lastMsgId; + ParseMessage(pReq->hContact, lastMsgId, msg, true, false); + } + + if (!bFound) + RetrieveHistoryChunk(pReq->hContact, it.first, it.first - 1, 1); + } else { char msgId[100]; _i64toa(it.first, msgId, 10); @@ -858,6 +869,21 @@ void CIcqProto::ProcessPatchVersion(MCONTACT hContact, __int64 currPatch) Push(pReq); } +void CIcqProto::RetrievePatches(MCONTACT hContact) +{ + __int64 oldPatch(getId(hContact, DB_KEY_PATCHVER)); + if (!oldPatch) + oldPatch = 1; + + auto *pReq = new AsyncRapiRequest(this, "getHistory", &CIcqProto::OnGetPatches); + #ifndef _DEBUG + pReq->flags |= NLHRF_NODUMPSEND; + #endif + pReq->hContact = hContact; + pReq->params << WCHAR_PARAM("sn", GetUserId(hContact)) << INT_PARAM("fromMsgId", -1) << INT_PARAM("count", -1) << SINT64_PARAM("patchVersion", oldPatch); + Push(pReq); +} + ///////////////////////////////////////////////////////////////////////////////////////// void CIcqProto::OnGetUserHistory(MHttpResponse *pReply, AsyncHttpRequest *pReq) -- cgit v1.2.3