diff options
author | George Hazan <ghazan@miranda.im> | 2022-11-03 14:37:59 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2022-11-03 14:38:09 +0300 |
commit | 3b2edeff1b7d1bff60174467d3d1cabefa5aa000 (patch) | |
tree | bbfddcc033ab58b6d3aceaddc425abfbf467ade0 /protocols/WhatsApp/src | |
parent | 6d54b6628f29f9d600c1afb9f520899890b41fbd (diff) |
WhatsApp: initial commit of group chats - non-cached, nothing but reading groupchat metadata
Diffstat (limited to 'protocols/WhatsApp/src')
-rw-r--r-- | protocols/WhatsApp/src/appsync.cpp | 6 | ||||
-rw-r--r-- | protocols/WhatsApp/src/chats.cpp | 139 | ||||
-rw-r--r-- | protocols/WhatsApp/src/message.cpp | 13 | ||||
-rw-r--r-- | protocols/WhatsApp/src/proto.h | 6 | ||||
-rw-r--r-- | protocols/WhatsApp/src/server.cpp | 4 | ||||
-rw-r--r-- | protocols/WhatsApp/src/utils.cpp | 12 |
6 files changed, 106 insertions, 74 deletions
diff --git a/protocols/WhatsApp/src/appsync.cpp b/protocols/WhatsApp/src/appsync.cpp index 2032a928ec..36531a5179 100644 --- a/protocols/WhatsApp/src/appsync.cpp +++ b/protocols/WhatsApp/src/appsync.cpp @@ -141,9 +141,6 @@ void WhatsAppProto::OnIqServerSync(const WANode &node) } } - CMStringA szSetting(FORMAT, "Collection_%s", pszName); - // setDword(szSetting, dwVersion); - JSONNode jsonRoot, jsonMap; for (auto &it : pCollection->indexValueMap) jsonMap << CHAR_PARAM(ptrA(mir_base64_encode(it.first.c_str(), it.first.size())), ptrA(mir_base64_encode(it.second.c_str(), it.second.size()))); @@ -221,8 +218,7 @@ void WhatsAppProto::ApplyPatch(const JSONNode &index, const Wa__SyncActionValue auto title = index.at((json_index_t)0).as_string(); if (title == "contact" && data->contactaction) { - WAJid jid(index.at(1).as_string().c_str()); - auto *pUser = AddUser(jid.toString(), false, jid.isGroup()); + auto *pUser = AddUser(index.at(1).as_string().c_str(), false); auto *pAction = data->contactaction; auto &fullName = pAction->fullname; diff --git a/protocols/WhatsApp/src/chats.cpp b/protocols/WhatsApp/src/chats.cpp index 6ebb94073f..8861693fca 100644 --- a/protocols/WhatsApp/src/chats.cpp +++ b/protocols/WhatsApp/src/chats.cpp @@ -7,77 +7,112 @@ Copyright © 2019-22 George Hazan #include "stdafx.h" -void WhatsAppProto::InitChat(WAUser *pUser) +void WhatsAppProto::GC_Init(WAUser *pUser) { - CMStringA jid = ""; - CMStringW wszId(Utf2T(jid.c_str())), wszNick(Utf2T("")); + CMStringW wszId(Utf2T(pUser->szId)); - setWString(pUser->hContact, "Nick", wszNick); - - pUser->si = Chat_NewSession(GCW_CHATROOM, m_szModuleName, wszId, wszNick); + pUser->si = Chat_NewSession(GCW_CHATROOM, m_szModuleName, wszId, getMStringW(pUser->hContact, "Nick")); Chat_AddGroup(pUser->si, TranslateT("Owner")); Chat_AddGroup(pUser->si, TranslateT("SuperAdmin")); Chat_AddGroup(pUser->si, TranslateT("Admin")); Chat_AddGroup(pUser->si, TranslateT("Participant")); - Chat_Control(m_szModuleName, wszId, m_bHideGroupchats ? WINDOW_HIDDEN : SESSION_INITDONE); - Chat_Control(m_szModuleName, wszId, SESSION_ONLINE); - - if (!pUser->bInited) { - // CMStringA query(FORMAT, "[\"query\",\"GroupMetadata\",\"%s\"]", jid.c_str()); - // WSSend(query, &WhatsAppProto::OnGetChatInfo, pUser); + if (pUser->bInited) { + Chat_Control(m_szModuleName, wszId, m_bHideGroupchats ? WINDOW_HIDDEN : SESSION_INITDONE); + Chat_Control(m_szModuleName, wszId, SESSION_ONLINE); } + else GC_GetMetadata(pUser->szId); } -void WhatsAppProto::OnGetChatInfo(const JSONNode &root, void *param) +void WhatsAppProto::GC_GetMetadata(const char *szId) { - auto *pChatUser = (WAUser *)param; - pChatUser->bInited = true; - - CMStringW wszOwner(root["owner"].as_mstring()), wszNick; - - for (auto &it : root["participants"]) { - CMStringW jid(it["id"].as_mstring()); - CMStringA szJid(jid); - - GCEVENT gce = { m_szModuleName, 0, GC_EVENT_JOIN }; - gce.pszID.w = pChatUser->si->ptszID; - gce.pszUID.w = jid; - gce.bIsMe = (szJid == m_szJid); + WANodeIq iq(IQ::GET, "w:g2", szId); + iq.addChild("query")->addAttr("request", "interactive"); + WSSendNode(iq, &WhatsAppProto::OnIqGcMetadata); +} - if (jid == wszOwner) - gce.pszStatus.w = L"Owner"; - else if (it["isSuperAdmin"].as_bool()) - gce.pszStatus.w = L"SuperAdmin"; - else if (it["isAdmin"].as_bool()) - gce.pszStatus.w = L"Admin"; - else - gce.pszStatus.w = L"Participant"; - - if (gce.bIsMe) - wszNick = getMStringW(DBKEY_NICK); - else if (auto *pUser = FindUser(szJid)) - wszNick = Clist_GetContactDisplayName(pUser->hContact); - else { - int iPos = jid.Find('@'); - wszNick = (iPos != -1) ? jid.Left(iPos - 1) : jid; +void WhatsAppProto::OnIqGcMetadata(const WANode &node) +{ + auto *pGroup = node.getChild("group"); + auto *pChatUser = FindUser(node.getAttr("from")); + if (pChatUser == nullptr || pGroup == nullptr) + return; + + CMStringA szOwner(pGroup->getAttr("creator")), szNick, szRole; + + for (auto &it : pGroup->getChildren()) { + if (it->title == "description") { + CMStringA szDescr = it->getBody(); + if (!szDescr.IsEmpty()) { + GCEVENT gce = {m_szModuleName, 0, GC_EVENT_INFORMATION}; + gce.dwFlags = GCEF_UTF8; + gce.pszID.a = pChatUser->szId; + gce.pszText.a = szDescr.c_str(); + Chat_Event(&gce); + } + } + else if (it->title == "member_add_mode") { + szRole = it->getBody(); + } + else if (it->title == "participant") { + auto *jid = it->getAttr("jid"); + + // if role isn't specified, use the default one + auto *role = it->getAttr("type"); + if (role == nullptr) + role = szRole; + + GCEVENT gce = {m_szModuleName, 0, GC_EVENT_JOIN}; + gce.dwFlags = GCEF_UTF8; + gce.pszID.a = pChatUser->szId; + gce.pszUID.a = jid; + gce.bIsMe = (jid == m_szJid); + + if (jid == szOwner) + gce.pszStatus.a = "Owner"; + else if (!mir_strcmp(role, "superadmin")) + gce.pszStatus.a = "SuperAdmin"; + else if (!mir_strcmp(role, "adminadd")) + gce.pszStatus.a = "Admin"; + else + gce.pszStatus.a = "Participant"; + + if (gce.bIsMe) + szNick = ptrA(getUStringA(DBKEY_NICK)); + else if (auto *pUser = FindUser(jid)) + szNick = T2Utf(Clist_GetContactDisplayName(pUser->hContact)).get(); + else + szNick = WAJid(jid).user; + + gce.pszNick.a = szNick; + Chat_Event(&gce); } - - gce.pszNick.w = wszNick; - Chat_Event(&gce); } - CMStringW wszSubject(root["subject"].as_mstring()); - if (!wszSubject.IsEmpty()) { - time_t iSubjectTime(root["subjectTime"].as_int()); - CMStringW wszSubjectSet(root["subjectOwner"].as_mstring()); + if (auto *pszSubject = pGroup->getAttr("subject")) { + time_t iSubjectTime = pGroup->getAttrInt("s_t"); + auto *pszUser = pGroup->getAttr("s_o"); + if (m_szJid == pszUser) + szNick = ptrA(getUStringA(DBKEY_NICK)); + else if (auto *pUser = FindUser(pszUser)) + szNick = T2Utf(Clist_GetContactDisplayName(pUser->hContact)).get(); + else + szNick = WAJid(pszUser).user; GCEVENT gce = { m_szModuleName, 0, GC_EVENT_TOPIC }; - gce.pszID.w = pChatUser->si->ptszID; - gce.pszUID.w = wszSubjectSet; - gce.pszText.w = wszSubject; + gce.dwFlags = GCEF_UTF8; + gce.pszID.a = pChatUser->szId; + gce.pszUID.a = pszUser; + gce.pszText.a = pszSubject; gce.time = iSubjectTime; Chat_Event(&gce); + + setUString(pChatUser->hContact, "Nick", pszSubject); } + + pChatUser->bInited = true; + CMStringW wszId(Utf2T(pChatUser->szId)); + Chat_Control(m_szModuleName, wszId, m_bHideGroupchats ? WINDOW_HIDDEN : SESSION_INITDONE); + Chat_Control(m_szModuleName, wszId, SESSION_ONLINE); } diff --git a/protocols/WhatsApp/src/message.cpp b/protocols/WhatsApp/src/message.cpp index b653b18688..4b002a3c64 100644 --- a/protocols/WhatsApp/src/message.cpp +++ b/protocols/WhatsApp/src/message.cpp @@ -188,7 +188,6 @@ void WhatsAppProto::ProcessMessage(WAMSG type, const Wa__WebMessageInfo &msg) { auto *key = msg.key; auto *body = getBody(msg.message); - bool bFromMe = key->fromme; debugLogA("Got a message: %s", protobuf_c_text_to_string(&msg).c_str()); @@ -197,15 +196,9 @@ void WhatsAppProto::ProcessMessage(WAMSG type, const Wa__WebMessageInfo &msg) auto *chatId = key->remotejid; auto *msgId = key->id; - WAUser *pUser = FindUser(chatId); - if (pUser == nullptr) { - if (type.bPrivateChat) - pUser = AddUser(chatId, false, false); - else if (type.bGroupChat) - pUser = AddUser(chatId, false, true); - } + WAUser *pUser = AddUser(chatId, false); - if (!bFromMe && msg.pushname && pUser && !pUser->bIsGroupChat) + if (!key->fromme && msg.pushname && pUser && !pUser->bIsGroupChat) setUString(pUser->hContact, "Nick", msg.pushname); // try to extract some text @@ -218,7 +211,7 @@ void WhatsAppProto::ProcessMessage(WAMSG type, const Wa__WebMessageInfo &msg) pre.szMsgId = msgId; if (type.bOffline) pre.flags |= PREF_CREATEREAD; - if (bFromMe) + if (key->fromme) pre.flags |= PREF_SENT; ProtoChainRecvMsg(pUser->hContact, &pre); } diff --git a/protocols/WhatsApp/src/proto.h b/protocols/WhatsApp/src/proto.h index 8a8e3461a4..4f2fee4609 100644 --- a/protocols/WhatsApp/src/proto.h +++ b/protocols/WhatsApp/src/proto.h @@ -284,11 +284,12 @@ class WhatsAppProto : public PROTO<WhatsAppProto> OBJLIST<WADevice> m_arDevices; WAUser* FindUser(const char *szId); - WAUser* AddUser(const char *szId, bool bTemporary, bool isChat = false); + WAUser* AddUser(const char *szId, bool bTemporary); // Group chats ///////////////////////////////////////////////////////////////////////// - void InitChat(WAUser *pUser); + void GC_Init(WAUser *pUser); + void GC_GetMetadata(const char *szJid); // UI ////////////////////////////////////////////////////////////////////////////////// @@ -353,6 +354,7 @@ class WhatsAppProto : public PROTO<WhatsAppProto> void OnIqBlockList(const WANode &node); void OnIqCountPrekeys(const WANode &node); void OnIqDoNothing(const WANode &node); + void OnIqGcMetadata(const WANode &node); void OnIqGetAvatar(const WANode &node); void OnIqGetUsync(const WANode &node); void OnIqPairDevice(const WANode &node); diff --git a/protocols/WhatsApp/src/server.cpp b/protocols/WhatsApp/src/server.cpp index 26a8015445..5dfbd34270 100644 --- a/protocols/WhatsApp/src/server.cpp +++ b/protocols/WhatsApp/src/server.cpp @@ -310,6 +310,10 @@ void WhatsAppProto::OnLoggedIn() WSSendNode( WANodeIq(IQ::GET, "privacy") << XCHILD("privacy"), &WhatsAppProto::OnIqDoNothing); + + for (auto &it : m_arUsers) + if (it->bIsGroupChat) + GC_Init(it); } void WhatsAppProto::OnLoggedOut(void) diff --git a/protocols/WhatsApp/src/utils.cpp b/protocols/WhatsApp/src/utils.cpp index 880b0e9469..a28deda31d 100644 --- a/protocols/WhatsApp/src/utils.cpp +++ b/protocols/WhatsApp/src/utils.cpp @@ -105,7 +105,7 @@ WAUser* WhatsAppProto::FindUser(const char *szId) return m_arUsers.find(tmp); } -WAUser* WhatsAppProto::AddUser(const char *szId, bool bTemporary, bool isChat) +WAUser* WhatsAppProto::AddUser(const char *szId, bool bTemporary) { auto *pUser = FindUser(szId); if (pUser != nullptr) @@ -114,9 +114,14 @@ WAUser* WhatsAppProto::AddUser(const char *szId, bool bTemporary, bool isChat) MCONTACT hContact = db_add_contact(); Proto_AddToContact(hContact, m_szModuleName); - if (isChat) { + pUser = new WAUser(hContact, mir_strdup(szId)); + pUser->bIsGroupChat = WAJid(szId).isGroup(); + + if (pUser->bIsGroupChat) { setByte(hContact, "ChatRoom", 1); setString(hContact, "ChatRoomID", szId); + + GC_Init(pUser); } else { setString(hContact, DBKEY_ID, szId); @@ -127,9 +132,6 @@ WAUser* WhatsAppProto::AddUser(const char *szId, bool bTemporary, bool isChat) if (bTemporary) Contact::RemoveFromList(hContact); - pUser = new WAUser(hContact, mir_strdup(szId)); - pUser->bIsGroupChat = isChat; - mir_cslock lck(m_csUsers); m_arUsers.insert(pUser); return pUser; |