From b4c481c84032871bae26e47ca5f8dc2747a196cb Mon Sep 17 00:00:00 2001 From: George Hazan Date: Thu, 30 Nov 2023 19:45:53 +0300 Subject: =?UTF-8?q?fixes=20#3982=20(ICQ:=20=D0=BE=D1=82=D0=BE=D0=B1=D1=80?= =?UTF-8?q?=D0=B0=D0=B6=D0=B0=D1=82=D1=8C=20=D0=BE=D0=BF=D0=B8=D1=81=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B3=D1=80=D1=83=D0=BF=D1=87=D0=B0=D1=82?= =?UTF-8?q?=D0=B0=20=D0=BA=D0=B0=D0=BA=20=D1=82=D0=BE=D0=BF=D0=B8=D0=BA)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- protocols/ICQ-WIM/src/groupchats.cpp | 109 +++++++++++++++++------------------ protocols/ICQ-WIM/src/poll.cpp | 12 ++-- protocols/ICQ-WIM/src/proto.cpp | 4 +- protocols/ICQ-WIM/src/proto.h | 4 +- 4 files changed, 63 insertions(+), 66 deletions(-) (limited to 'protocols/ICQ-WIM/src') diff --git a/protocols/ICQ-WIM/src/groupchats.cpp b/protocols/ICQ-WIM/src/groupchats.cpp index 42aea886a8..abeaa9a503 100644 --- a/protocols/ICQ-WIM/src/groupchats.cpp +++ b/protocols/ICQ-WIM/src/groupchats.cpp @@ -23,14 +23,27 @@ SESSION_INFO* CIcqProto::CreateGroupChat(const wchar_t *pwszId, const wchar_t *pwszNick) { auto *si = Chat_NewSession(GCW_CHATROOM, m_szModuleName, pwszId, pwszNick); - if (si != nullptr) { + if (si == nullptr) + return nullptr; + + if (si->pStatuses == 0) { Chat_AddGroup(si, TranslateT("admin")); Chat_AddGroup(si, TranslateT("member")); - Chat_Control(si, m_bHideGroupchats ? WINDOW_HIDDEN : SESSION_INITDONE); - Chat_Control(si, SESSION_ONLINE); + } + + Chat_Control(si, m_bHideGroupchats ? WINDOW_HIDDEN : SESSION_INITDONE); + Chat_Control(si, SESSION_ONLINE); + + // #3420 ICQ server will place our group chat into its own group + Clist_SetGroup(si->hContact, nullptr); + + if (si->ptszTopic) { + GCEVENT gce = { si, GC_EVENT_TOPIC }; + gce.time = ::time(0); + gce.pszText.w = si->ptszTopic; si->ptszTopic = 0; + Chat_Event(&gce); - // #3420 ICQ server will place our group chat into its own group - Clist_SetGroup(si->hContact, nullptr); + mir_free((void*)gce.pszText.w); } return si; @@ -47,73 +60,59 @@ INT_PTR CIcqProto::SvcLeaveChat(WPARAM hContact, LPARAM) ///////////////////////////////////////////////////////////////////////////////////////// -void CIcqProto::LoadChatInfo(SESSION_INFO *si) -{ - int memberCount = getDword(si->hContact, "MemberCount"); - for (int i = 0; i < memberCount; i++) { - char buf[100]; - mir_snprintf(buf, "m%d", i); - ptrW szSetting(getWStringA(si->hContact, buf)); - JSONNode *node = json_parse(T2Utf(szSetting)); - if (node == nullptr) - continue; - - CMStringW nick((*node)["nick"].as_mstring()); - CMStringW role((*node)["role"].as_mstring()); - CMStringW sn((*node)["sn"].as_mstring()); - - GCEVENT gce = { si, GC_EVENT_JOIN }; - gce.dwFlags = GCEF_SILENT; - gce.pszNick.w = nick; - gce.pszUID.w = sn; - gce.time = ::time(0); - gce.bIsMe = sn == m_szOwnId; - gce.pszStatus.w = TranslateW(role); - Chat_Event(&gce); - - json_delete(node); - } -} - -///////////////////////////////////////////////////////////////////////////////////////// - -void CIcqProto::RetrieveChatInfo(SESSION_INFO *si) -{ - auto *pReq = new AsyncRapiRequest(this, "getChatInfo", &CIcqProto::OnGetChatInfo); - pReq->params << WCHAR_PARAM("sn", si->ptszID) << INT_PARAM("memberLimit", 100) << CHAR_PARAM("aimSid", m_aimsid); - pReq->pUserInfo = si; - Push(pReq); -} - void CIcqProto::OnGetChatInfo(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq) { - SESSION_INFO *si = (SESSION_INFO*)pReq->pUserInfo; - RobustReply root(pReply); if (root.error() != 20000) return; - int n = 0; - char buf[100]; + SESSION_INFO *si = (SESSION_INFO *)pReq->pUserInfo; + const JSONNode &results = root.results(); for (auto &it : results["members"]) { - mir_snprintf(buf, "m%d", n++); - CMStringW friendly = it["friendly"].as_mstring(); CMStringW role = it["role"].as_mstring(); CMStringW sn = it["sn"].as_mstring(); - JSONNode member; - member << WCHAR_PARAM("nick", friendly) << WCHAR_PARAM("role", role) << WCHAR_PARAM("sn", sn); - ptrW text(json_write(&member)); - setWString(si->hContact, buf, text); + GCEVENT gce = { si, GC_EVENT_JOIN }; + gce.dwFlags = GCEF_SILENT; + gce.pszNick.w = friendly; + gce.pszUID.w = sn; + gce.time = ::time(0); + gce.bIsMe = sn == m_szOwnId; + gce.pszStatus.w = TranslateW(role); + Chat_Event(&gce); + } + + CMStringW wszAbout = results["about"].as_mstring(), wszTopic; + CMStringW wszRules = results["rules"].as_mstring(); + if (!wszAbout.IsEmpty()) + wszTopic.AppendFormat(L"%s: %s", TranslateT("About"), wszAbout.c_str()); + if (!wszRules.IsEmpty()) { + if (!wszTopic.IsEmpty()) + wszTopic.Append(L"\r\n"); + wszTopic.AppendFormat(L"%s: %s", TranslateT("Rules"), wszRules.c_str()); + } + if (!wszTopic.IsEmpty()) { + GCEVENT gce = { si, GC_EVENT_TOPIC }; + gce.time = ::time(0); + gce.pszText.w = wszTopic; + Chat_Event(&gce); } - setDword(si->hContact, "MemberCount", n); setId(si->hContact, "InfoVersion", _wtoi64(results["infoVersion"].as_mstring())); setId(si->hContact, "MembersVersion", _wtoi64(results["membersVersion"].as_mstring())); +} - LoadChatInfo(si); +void CIcqProto::RetrieveChatInfo(MCONTACT hContact) +{ + CMStringW wszChatID(GetUserId(hContact)); + if (auto *si = Chat_Find(wszChatID, m_szModuleName)) { + auto *pReq = new AsyncRapiRequest(this, "getChatInfo", &CIcqProto::OnGetChatInfo); + pReq->params << WCHAR_PARAM("sn", wszChatID) << INT_PARAM("memberLimit", 100) << CHAR_PARAM("aimSid", m_aimsid); + pReq->pUserInfo = si; + Push(pReq); + } } ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/protocols/ICQ-WIM/src/poll.cpp b/protocols/ICQ-WIM/src/poll.cpp index fbcfd178c0..aee14bd00d 100644 --- a/protocols/ICQ-WIM/src/poll.cpp +++ b/protocols/ICQ-WIM/src/poll.cpp @@ -183,14 +183,10 @@ void CIcqProto::ProcessHistData(const JSONNode &ev) hContact = si->hContact; - if (si->arUsers.getCount() == 0) { - __int64 srvInfoVer = _wtoi64(ev["mchatState"]["infoVersion"].as_mstring()); - __int64 srvMembersVer = _wtoi64(ev["mchatState"]["membersVersion"].as_mstring()); - if (srvInfoVer != getId(hContact, "InfoVersion") || srvMembersVer != getId(hContact, "MembersVersion")) - RetrieveChatInfo(si); - else - LoadChatInfo(si); - } + __int64 srvInfoVer = _wtoi64(ev["mchatState"]["infoVersion"].as_mstring()); + __int64 srvMembersVer = _wtoi64(ev["mchatState"]["membersVersion"].as_mstring()); + if (srvInfoVer != getId(hContact, "InfoVersion") || srvMembersVer != getId(hContact, "MembersVersion") || si->arUsers.getCount() == 0) + RetrieveChatInfo(hContact); } else { hContact = CreateContact(wszId, true); diff --git a/protocols/ICQ-WIM/src/proto.cpp b/protocols/ICQ-WIM/src/proto.cpp index ccda5e0c98..0e07956cd5 100644 --- a/protocols/ICQ-WIM/src/proto.cpp +++ b/protocols/ICQ-WIM/src/proto.cpp @@ -85,7 +85,7 @@ CIcqProto::CIcqProto(const char *aProtoName, const wchar_t *aUserName) : // group chats GCREGISTER gcr = {}; - gcr.dwFlags = GC_TYPNOTIF | GC_CHANMGR | GC_DATABASE; + gcr.dwFlags = GC_TYPNOTIF | GC_CHANMGR | GC_DATABASE | GC_PERSISTENT; gcr.ptszDispName = m_tszUserName; gcr.pszModule = m_szModuleName; Chat_Register(&gcr); @@ -521,6 +521,8 @@ INT_PTR CIcqProto::GetCaps(int type, MCONTACT) int CIcqProto::GetInfo(MCONTACT hContact, int) { RetrieveUserInfo(hContact); + if (Contact::IsGroupChat(hContact)) + RetrieveChatInfo(hContact); return 0; } diff --git a/protocols/ICQ-WIM/src/proto.h b/protocols/ICQ-WIM/src/proto.h index 37e1b48357..bdd47635c3 100644 --- a/protocols/ICQ-WIM/src/proto.h +++ b/protocols/ICQ-WIM/src/proto.h @@ -329,10 +329,10 @@ class CIcqProto : public PROTO SESSION_INFO* CreateGroupChat(const wchar_t *pwszId, const wchar_t *pwszNick); - void RetrieveChatInfo(SESSION_INFO *si); + void RetrieveChatInfo(MCONTACT hContact); + void InviteUserToChat(SESSION_INFO *si); void LeaveDestroyChat(SESSION_INFO *si); - void LoadChatInfo(SESSION_INFO *si); //////////////////////////////////////////////////////////////////////////////////////// // http queue -- cgit v1.2.3