From 15da86e11646f0465febbc6cd1eb29864abacfe6 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Mon, 13 Mar 2023 20:00:04 +0300 Subject: =?UTF-8?q?fixes=20#3426=20(ICQ:=20=D0=BD=D0=B5=20=D0=BE=D0=B1?= =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=B0=D1=82=D1=8B=D0=B2=D0=B0=D0=B5=D1=82?= =?UTF-8?q?=D1=81=D1=8F=20=D1=81=D0=BE=D0=B1=D1=8B=D1=82=D0=B8=D0=B5=20?= =?UTF-8?q?=D0=B8=D1=81=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=B8=D1=8F=20?= =?UTF-8?q?=D0=B8=D0=B7=20=D1=87=D0=B0=D1=82=D0=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- protocols/ICQ-WIM/src/groupchats.cpp | 12 +++---- protocols/ICQ-WIM/src/ignore.cpp | 6 ++-- protocols/ICQ-WIM/src/poll.cpp | 44 +++++++++++++------------- protocols/ICQ-WIM/src/proto.cpp | 18 +++++------ protocols/ICQ-WIM/src/proto.h | 10 +++--- protocols/ICQ-WIM/src/server.cpp | 61 +++++++++++++++++++++++++----------- protocols/ICQ-WIM/src/utils.cpp | 20 ++++++------ 7 files changed, 98 insertions(+), 73 deletions(-) diff --git a/protocols/ICQ-WIM/src/groupchats.cpp b/protocols/ICQ-WIM/src/groupchats.cpp index 42c1b21c64..0e4bbb1a53 100644 --- a/protocols/ICQ-WIM/src/groupchats.cpp +++ b/protocols/ICQ-WIM/src/groupchats.cpp @@ -246,14 +246,14 @@ void CIcqProto::Chat_ProcessLogMenu(SESSION_INFO *si, int iChoice) void CIcqProto::Chat_SendPrivateMessage(GCHOOK *gch) { MCONTACT hContact; - auto *pCache = FindContactByUIN(gch->ptszUID); - if (pCache == nullptr) { + auto *pUser = FindUser(gch->ptszUID); + if (pUser == nullptr) { hContact = CreateContact(gch->ptszUID, true); setWString(hContact, "Nick", gch->ptszNick); Contact::Hide(hContact); db_set_dw(hContact, "Ignore", "Mask1", 0); } - else hContact = pCache->m_hContact; + else hContact = pUser->m_hContact; CallService(MS_MSG_SENDMESSAGE, hContact, 0); } @@ -276,11 +276,11 @@ void CIcqProto::ProcessGroupChat(const JSONNode &ev) if (member.IsEmpty()) break; - auto *pCache = FindContactByUIN(member); - if (pCache == nullptr) + auto *pUser = FindUser(member); + if (pUser == nullptr) continue; - gce.pszNick.w = Clist_GetContactDisplayName(pCache->m_hContact); + gce.pszNick.w = Clist_GetContactDisplayName(pUser->m_hContact); gce.pszUID.w = member; gce.time = ::time(0); gce.bIsMe = member == m_szOwnId; diff --git a/protocols/ICQ-WIM/src/ignore.cpp b/protocols/ICQ-WIM/src/ignore.cpp index a2ce8c098f..7d64edceba 100644 --- a/protocols/ICQ-WIM/src/ignore.cpp +++ b/protocols/ICQ-WIM/src/ignore.cpp @@ -41,7 +41,7 @@ void CIcqProto::ProcessPermissions(const JSONNode &ev) } for (auto &it : ev["allows"]) { - auto *p = FindContactByUIN(it.as_mstring()); + auto *p = FindUser(it.as_mstring()); if (p) p->m_iApparentMode = ID_STATUS_ONLINE; } @@ -49,10 +49,10 @@ void CIcqProto::ProcessPermissions(const JSONNode &ev) m_bIgnoreListEmpty = true; for (auto &it : ev["ignores"]) { CMStringW wszId(it.as_mstring()); - auto *p = FindContactByUIN(wszId); + auto *p = FindUser(wszId); if (p == nullptr) { CreateContact(wszId, false); - p = FindContactByUIN(wszId); + p = FindUser(wszId); } p->m_iApparentMode = ID_STATUS_OFFLINE; Contact::Hide(p->m_hContact); diff --git a/protocols/ICQ-WIM/src/poll.cpp b/protocols/ICQ-WIM/src/poll.cpp index c6c7d0b2e0..b7cd908ea2 100644 --- a/protocols/ICQ-WIM/src/poll.cpp +++ b/protocols/ICQ-WIM/src/poll.cpp @@ -164,7 +164,7 @@ void CIcqProto::ProcessHistData(const JSONNode &ev) bool bVeryBeginning = m_bFirstBos; CMStringW wszId(ev["sn"].as_mstring()); - auto *pCache = FindContactByUIN(wszId); // might be NULL for groupchats + auto *pUser = FindUser(wszId); // might be NULL for groupchats if (IsChat(wszId)) { SESSION_INFO *si = Chat_Find(wszId, m_szModuleName); @@ -189,9 +189,9 @@ void CIcqProto::ProcessHistData(const JSONNode &ev) hContact = CreateContact(wszId, true); // for temporary contacts that just gonna be created - if (pCache == nullptr) { + if (pUser == nullptr) { bVeryBeginning = true; - pCache = FindContactByUIN(wszId); + pUser = FindUser(wszId); } } @@ -209,9 +209,9 @@ void CIcqProto::ProcessHistData(const JSONNode &ev) // we load history in the very beginning or if the previous message if (bVeryBeginning) { - if (pCache) { + if (pUser) { debugLogA("Setting cache = %lld for %d", srvLastId, hContact); - pCache->m_iProcessedMsgId = srvLastId; + pUser->m_iProcessedMsgId = srvLastId; } if (srvLastId > lastMsgId) { @@ -220,9 +220,9 @@ void CIcqProto::ProcessHistData(const JSONNode &ev) } } else { - if (!(pCache && pCache->m_iProcessedMsgId >= srvLastId)) { - if (pCache) - debugLogA("Proceeding with cache for %d: %lld < %lld", hContact, pCache->m_iProcessedMsgId, srvLastId); + if (!(pUser && pUser->m_iProcessedMsgId >= srvLastId)) { + if (pUser) + debugLogA("Proceeding with cache for %d: %lld < %lld", hContact, pUser->m_iProcessedMsgId, srvLastId); else debugLogA("Proceeding with empty cache for %d", hContact); @@ -230,8 +230,8 @@ void CIcqProto::ProcessHistData(const JSONNode &ev) ParseMessage(hContact, lastMsgId, it, false, true); setId(hContact, DB_KEY_LASTMSGID, lastMsgId); - if (pCache) { - pCache->m_iProcessedMsgId = lastMsgId; + if (pUser) { + pUser->m_iProcessedMsgId = lastMsgId; debugLogA("Setting second cache = %lld for %d", srvLastId, hContact); } } @@ -317,11 +317,11 @@ void CIcqProto::ProcessPresence(const JSONNode &ev) { CMStringW aimId = ev["aimId"].as_mstring(); - IcqCacheItem *pCache = FindContactByUIN(aimId); - if (pCache == nullptr) + auto *pUser = FindUser(aimId); + if (pUser == nullptr) return; - int iNewStatus = StatusFromPresence(ev, pCache->m_hContact); + int iNewStatus = StatusFromPresence(ev, pUser->m_hContact); if (iNewStatus == -1) iNewStatus = ID_STATUS_OFFLINE; @@ -331,16 +331,16 @@ void CIcqProto::ProcessPresence(const JSONNode &ev) if (iNewStatus == ID_STATUS_OFFLINE) { if (m_iTimeDiff1) { iNewStatus = m_iStatus1; - pCache->m_timer1 = time(0); + pUser->m_timer1 = time(0); } } // if a client returns back online, we clear timers not to play with statuses anymore - else pCache->m_timer1 = pCache->m_timer2 = 0; + else pUser->m_timer1 = pUser->m_timer2 = 0; - setWord(pCache->m_hContact, "Status", iNewStatus); + setWord(pUser->m_hContact, "Status", iNewStatus); - Json2string(pCache->m_hContact, ev, "friendly", "Nick", true); - CheckAvatarChange(pCache->m_hContact, ev); + Json2string(pUser->m_hContact, ev, "friendly", "Nick", true); + CheckAvatarChange(pUser->m_hContact, ev); } void CIcqProto::ProcessSessionEnd(const JSONNode &/*ev*/) @@ -357,12 +357,12 @@ void CIcqProto::ProcessTyping(const JSONNode &ev) CMStringW aimId = ev["aimId"].as_mstring(); CMStringW wszStatus = ev["typingStatus"].as_mstring(); - IcqCacheItem *pCache = FindContactByUIN(aimId); - if (pCache) { + auto *pUser = FindUser(aimId); + if (pUser) { if (wszStatus == "typing") - CallService(MS_PROTO_CONTACTISTYPING, pCache->m_hContact, 60); + CallService(MS_PROTO_CONTACTISTYPING, pUser->m_hContact, 60); else - CallService(MS_PROTO_CONTACTISTYPING, pCache->m_hContact, PROTOTYPE_CONTACTTYPING_OFF); + CallService(MS_PROTO_CONTACTISTYPING, pUser->m_hContact, PROTOTYPE_CONTACTTYPING_OFF); } } diff --git a/protocols/ICQ-WIM/src/proto.cpp b/protocols/ICQ-WIM/src/proto.cpp index 41cd2119fb..1e6ffb5ada 100644 --- a/protocols/ICQ-WIM/src/proto.cpp +++ b/protocols/ICQ-WIM/src/proto.cpp @@ -33,7 +33,7 @@ #pragma warning(disable:4355) -static int CompareCache(const IcqCacheItem *p1, const IcqCacheItem *p2) +static int CompareCache(const IcqUser *p1, const IcqUser *p2) { return mir_wstrcmp(p1->m_aimid, p2->m_aimid); } @@ -145,9 +145,9 @@ void CIcqProto::OnShutdown() void CIcqProto::OnContactAdded(MCONTACT hContact) { CMStringW wszId(getMStringW(hContact, DB_KEY_ID)); - if (!wszId.IsEmpty() && !FindContactByUIN(wszId)) { + if (!wszId.IsEmpty() && !FindUser(wszId)) { mir_cslock l(m_csCache); - m_arCache.insert(new IcqCacheItem(wszId, hContact)); + m_arCache.insert(new IcqUser(wszId, hContact)); } } @@ -155,7 +155,7 @@ void CIcqProto::OnContactDeleted(MCONTACT hContact) { CMStringW szId(GetUserId(hContact)); if (!isChatRoom(hContact)) - m_arCache.remove(FindContactByUIN(szId)); + m_arCache.remove(FindUser(szId)); Push(new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, ICQ_API_SERVER "/buddylist/removeBuddy") << AIMSID(this) << WCHAR_PARAM("buddy", szId) << INT_PARAM("allGroups", 1)); @@ -239,7 +239,7 @@ void CIcqProto::SendMarkRead() { mir_cslock lck(m_csMarkReadQueue); while (m_arMarkReadQueue.getCount()) { - IcqCacheItem *pUser = m_arMarkReadQueue[0]; + auto *pUser = m_arMarkReadQueue[0]; auto *pReq = new AsyncRapiRequest(this, "setDlgStateWim"); pReq->params << WCHAR_PARAM("sn", GetUserId(pUser->m_hContact)) << INT64_PARAM("lastRead", getId(pUser->m_hContact, DB_KEY_LASTMSGID)); @@ -256,11 +256,11 @@ void CIcqProto::OnMarkRead(MCONTACT hContact, MEVENT) m_impl.m_markRead.Start(200); - auto *pCache = FindContactByUIN(GetUserId(hContact)); - if (pCache) { + auto *pUser = FindUser(GetUserId(hContact)); + if (pUser) { mir_cslock lck(m_csMarkReadQueue); - if (m_arMarkReadQueue.indexOf(pCache) == -1) - m_arMarkReadQueue.insert(pCache); + if (m_arMarkReadQueue.indexOf(pUser) == -1) + m_arMarkReadQueue.insert(pUser); } } diff --git a/protocols/ICQ-WIM/src/proto.h b/protocols/ICQ-WIM/src/proto.h index f36f6911ab..75e33ef5c2 100644 --- a/protocols/ICQ-WIM/src/proto.h +++ b/protocols/ICQ-WIM/src/proto.h @@ -107,9 +107,9 @@ struct IcqGroup } }; -struct IcqCacheItem : public MZeroedObject +struct IcqUser : public MZeroedObject { - IcqCacheItem(const CMStringW &wszId, MCONTACT _contact) : + IcqUser(const CMStringW &wszId, MCONTACT _contact) : m_aimid(wszId), m_hContact(_contact) {} @@ -282,7 +282,7 @@ class CIcqProto : public PROTO void OnLoggedOut(void); mir_cs m_csMarkReadQueue; - LIST m_arMarkReadQueue; + LIST m_arMarkReadQueue; void SendMarkRead(); __int64 getId(MCONTACT hContact, const char *szSetting); @@ -383,10 +383,10 @@ class CIcqProto : public PROTO // cache mir_cs m_csCache; - OBJLIST m_arCache; + OBJLIST m_arCache; void InitContactCache(void); - IcqCacheItem* FindContactByUIN(const CMStringW &pwszId); + IcqUser* FindUser(const CMStringW &pwszId); MCONTACT CreateContact(const CMStringW &pwszId, bool bTemporary); void GetAvatarFileName(MCONTACT hContact, wchar_t *pszDest, size_t cbLen); diff --git a/protocols/ICQ-WIM/src/server.cpp b/protocols/ICQ-WIM/src/server.cpp index 918ee2d119..818807d3ea 100644 --- a/protocols/ICQ-WIM/src/server.cpp +++ b/protocols/ICQ-WIM/src/server.cpp @@ -277,8 +277,8 @@ MCONTACT CIcqProto::ParseBuddyInfo(const JSONNode &buddy, MCONTACT hContact, boo CMStringW wszChatId(buddy["aimId"].as_mstring()); CMStringW wszChatName(buddy["friendly"].as_mstring()); - auto *pContact = FindContactByUIN(wszId); - if (pContact && pContact->m_iApparentMode == ID_STATUS_OFFLINE) + auto *pUser = FindUser(wszId); + if (pUser && pUser->m_iApparentMode == ID_STATUS_OFFLINE) return INVALID_CONTACT_ID; auto *si = Chat_NewSession(GCW_CHATROOM, m_szModuleName, wszChatId, wszChatName); @@ -298,7 +298,7 @@ MCONTACT CIcqProto::ParseBuddyInfo(const JSONNode &buddy, MCONTACT hContact, boo return INVALID_CONTACT_ID; hContact = CreateContact(wszId, false); - FindContactByUIN(wszId)->m_bInList = true; + FindUser(wszId)->m_bInList = true; } else if (bIgnored) { db_delete_contact(hContact, true); @@ -424,6 +424,8 @@ void CIcqProto::ParseMessage(MCONTACT hContact, __int64 &lastMsgId, const JSONNo if (msgId > lastMsgId) lastMsgId = msgId; + int iMsgTime = (bLocalTime) ? time(0) : it["time"].as_int(); + CMStringW wszText; const JSONNode &sticker = it["sticker"]; if (sticker) { @@ -439,25 +441,48 @@ void CIcqProto::ParseMessage(MCONTACT hContact, __int64 &lastMsgId, const JSONNo wszText = it["text"].as_mstring(); wszText.TrimRight(); - // user added you - if (it["class"].as_mstring() == L"event" && it["eventTypeId"].as_mstring() == L"27:33000") { - if (bLocalTime) { - CMStringA id = getMStringA(hContact, DB_KEY_ID); - int pos = id.Find('@'); - CMStringA nick = (pos == -1) ? id : id.Left(pos); - DB::AUTH_BLOB blob(hContact, nick, nullptr, nullptr, id, nullptr); - - PROTORECVEVENT pre = {}; - pre.timestamp = (uint32_t)time(0); - pre.lParam = blob.size(); - pre.szMessage = blob; - ProtoChainRecv(hContact, PSR_AUTH, 0, (LPARAM)&pre); + if (it["class"].as_mstring() == L"event") { + // user added you + if (it["eventTypeId"].as_mstring() == L"27:33000") { + if (bLocalTime) { + CMStringA id = getMStringA(hContact, DB_KEY_ID); + int pos = id.Find('@'); + CMStringA nick = (pos == -1) ? id : id.Left(pos); + DB::AUTH_BLOB blob(hContact, nick, nullptr, nullptr, id, nullptr); + + PROTORECVEVENT pre = {}; + pre.timestamp = (uint32_t)time(0); + pre.lParam = blob.size(); + pre.szMessage = blob; + ProtoChainRecv(hContact, PSR_AUTH, 0, (LPARAM)&pre); + } + return; + } + + if (auto &pChat = it["chat"]) { + auto *si = Chat_Find(pChat["sender"].as_mstring(), m_szModuleName); + if (si == nullptr) + return; + + if (pChat["type"].as_string() == "group") { + if (pChat["memberEvent"]["type"].as_string() == "kicked") { + GCEVENT gce = {}; + gce.si = si; + gce.time = iMsgTime; + gce.iType = GC_EVENT_KICK; + + for (auto &jt : pChat["memberEvent"]["members"]) { + auto userId = jt.as_mstring(); + gce.pszUID.w = userId; + Chat_Event(&gce); + } + } + } + return; } - return; } } - int iMsgTime = (bLocalTime) ? time(0) : it["time"].as_int(); bool bIsOutgoing = it["outgoing"].as_bool(), bIsFileTransfer = false; IcqFileInfo *pFileInfo = nullptr; diff --git a/protocols/ICQ-WIM/src/utils.cpp b/protocols/ICQ-WIM/src/utils.cpp index 6bfc868e96..bdaac877bf 100644 --- a/protocols/ICQ-WIM/src/utils.cpp +++ b/protocols/ICQ-WIM/src/utils.cpp @@ -43,18 +43,18 @@ void CIcqProto::InitContactCache() } CMStringW wszId = GetUserId(it); - auto *pCache = FindContactByUIN(wszId); - if (pCache == nullptr) { - pCache = new IcqCacheItem(wszId, it); - m_arCache.insert(pCache); + auto *pUser = FindUser(wszId); + if (pUser == nullptr) { + pUser = new IcqUser(wszId, it); + m_arCache.insert(pUser); } - pCache->m_iProcessedMsgId = getId(it, DB_KEY_LASTMSGID); + pUser->m_iProcessedMsgId = getId(it, DB_KEY_LASTMSGID); } } -IcqCacheItem* CIcqProto::FindContactByUIN(const CMStringW &wszId) +IcqUser* CIcqProto::FindUser(const CMStringW &wszId) { - IcqCacheItem tmp(wszId, -1); + IcqUser tmp(wszId, -1); mir_cslock l(m_csCache); return m_arCache.find(&tmp); @@ -90,9 +90,9 @@ wchar_t* CIcqProto::GetUIN(MCONTACT hContact) MCONTACT CIcqProto::CreateContact(const CMStringW &wszId, bool bTemporary) { - auto *pCache = FindContactByUIN(wszId); - if (pCache != nullptr) - return pCache->m_hContact; + auto *pUser = FindUser(wszId); + if (pUser != nullptr) + return pUser->m_hContact; MCONTACT hContact = db_add_contact(); setWString(hContact, DB_KEY_ID, wszId); -- cgit v1.2.3