From 02b2ee6b8eae541c323f76be967a3b5132f44c32 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Mon, 25 Sep 2017 17:56:44 +0300 Subject: fixes #934 (Jabber: missing software information about conference members) --- protocols/JabberG/src/jabber_chat.cpp | 4 +- protocols/JabberG/src/jabber_groupchat.cpp | 3 + protocols/JabberG/src/jabber_list.cpp | 2 +- protocols/JabberG/src/jabber_proto.h | 2 +- protocols/JabberG/src/jabber_thread.cpp | 108 +++++++++++++++-------------- 5 files changed, 63 insertions(+), 56 deletions(-) (limited to 'protocols/JabberG') diff --git a/protocols/JabberG/src/jabber_chat.cpp b/protocols/JabberG/src/jabber_chat.cpp index dc92fabb9b..6a887eadf0 100644 --- a/protocols/JabberG/src/jabber_chat.cpp +++ b/protocols/JabberG/src/jabber_chat.cpp @@ -1016,9 +1016,11 @@ static void sttNickListHook(CJabberProto *ppro, JABBER_LIST_ITEM *item, GCHOOK* MCONTACT hContact = ppro->AddToListByJID(jid, PALF_TEMPORARY); ppro->setWString(hContact, "Nick", him->m_tszResourceName); - ppro->ListAdd(LIST_VCARD_TEMP, jid, hContact); + JABBER_LIST_ITEM *pTmp = ppro->ListAdd(LIST_VCARD_TEMP, jid, hContact); ppro->ListAddResource(LIST_VCARD_TEMP, jid, him->m_iStatus, him->m_tszStatusMessage, him->m_iPriority); + pTmp->findResource(him->m_tszResourceName)->m_pCaps = ppro->ListGetItemPtr(LIST_CHATROOM, item->jid)->findResource(him->m_tszResourceName)->m_pCaps; + CallService(MS_USERINFO_SHOWDIALOG, hContact, 0); } break; diff --git a/protocols/JabberG/src/jabber_groupchat.cpp b/protocols/JabberG/src/jabber_groupchat.cpp index 879b9bca10..1ec5ec20c4 100644 --- a/protocols/JabberG/src/jabber_groupchat.cpp +++ b/protocols/JabberG/src/jabber_groupchat.cpp @@ -908,6 +908,9 @@ void CJabberProto::GroupchatProcessPresence(HXML node) if (str = XmlGetAttrValue(itemNode, L"jid")) r->m_tszRealJid = mir_wstrdup(str); + + // XEP-0115: Entity Capabilities + OnProcessPresenceCapabilites(node, r); } } diff --git a/protocols/JabberG/src/jabber_list.cpp b/protocols/JabberG/src/jabber_list.cpp index badc48eb15..5559b39901 100644 --- a/protocols/JabberG/src/jabber_list.cpp +++ b/protocols/JabberG/src/jabber_list.cpp @@ -278,7 +278,7 @@ bool CJabberProto::ListAddResource(JABBER_LIST list, const wchar_t *jid, int sta if (q) { const wchar_t *resource = q + 1; if (*resource == 0) - return 0; + return false; JABBER_RESOURCE_STATUS *r = LI->findResource(resource); if (r != nullptr) { // Already exists, update status and statusMessage diff --git a/protocols/JabberG/src/jabber_proto.h b/protocols/JabberG/src/jabber_proto.h index 875afd5c27..b6df7fb40e 100755 --- a/protocols/JabberG/src/jabber_proto.h +++ b/protocols/JabberG/src/jabber_proto.h @@ -720,7 +720,7 @@ struct CJabberProto : public PROTO, public IJabberInterface void OnProcessCompressed(HXML node, ThreadData *info); void OnProcessMessage(HXML node, ThreadData *info); void OnProcessPresence(HXML node, ThreadData *info); - void OnProcessPresenceCapabilites(HXML node); + void OnProcessPresenceCapabilites(HXML node, pResourceStatus &resource); void OnProcessPubsubEvent(HXML node); void OnProcessStreamOpening(HXML node, ThreadData *info); diff --git a/protocols/JabberG/src/jabber_thread.cpp b/protocols/JabberG/src/jabber_thread.cpp index c373e4e521..f2518a4e20 100755 --- a/protocols/JabberG/src/jabber_thread.cpp +++ b/protocols/JabberG/src/jabber_thread.cpp @@ -1423,70 +1423,70 @@ void CJabberProto::OnProcessMessage(HXML node, ThreadData *info) } // XEP-0115: Entity Capabilities -void CJabberProto::OnProcessPresenceCapabilites(HXML node) +void CJabberProto::OnProcessPresenceCapabilites(HXML node, pResourceStatus &r) { + if (r == nullptr) + return; + + // already filled up? ok + if (r->m_pCaps != nullptr) + return; + const wchar_t *from = XmlGetAttrValue(node, L"from"); if (from == nullptr) return; - debugLogW(L"presence: for jid %s", from); - - pResourceStatus r(ResourceInfoFromJID(from)); - if (r == nullptr) + HXML n = XmlGetChildByTag(node, "c", "xmlns", JABBER_FEAT_ENTITY_CAPS); + if (n == nullptr) return; - // XEP-0115 support - if (r->m_pCaps == nullptr) { - HXML n = XmlGetChildByTag(node, "c", "xmlns", JABBER_FEAT_ENTITY_CAPS); - if (n != nullptr) { - const wchar_t *szNode = XmlGetAttrValue(n, L"node"); - const wchar_t *szVer = XmlGetAttrValue(n, L"ver"); - const wchar_t *szExt = XmlGetAttrValue(n, L"ext"); - if (szNode && szVer) { - const wchar_t *szHash = XmlGetAttrValue(n, L"hash"); - if (szHash == nullptr) { // old version - ptrA szVerUtf(mir_utf8encodeW(szVer)); - BYTE hashOut[MIR_SHA1_HASH_SIZE]; - mir_sha1_hash((BYTE*)szVerUtf.get(), mir_strlen(szVerUtf), hashOut); - wchar_t szHashOut[MIR_SHA1_HASH_SIZE * 2 + 1]; - bin2hexW(hashOut, _countof(hashOut), szHashOut); - r->m_pCaps = m_clientCapsManager.GetPartialCaps(szNode, szHashOut); - if (r->m_pCaps == nullptr) - r->m_pCaps = m_clientCapsManager.SetClientCaps(szNode, szHashOut, szVer, JABBER_RESOURCE_CAPS_NONE); - - MCONTACT hContact = HContactFromJID(from); - if (hContact) - UpdateMirVer(hContact, r); - } - else { - r->m_pCaps = m_clientCapsManager.GetPartialCaps(szNode, szVer); - if (r->m_pCaps == nullptr) { - CMStringA szName(FORMAT, "%S#%S", szNode, szVer); - ptrA szValue(db_get_sa(0, "JabberCaps", szName)); - if (szValue != 0) { - JSONNode root = JSONNode::parse(szValue); - if (root) { - CMStringW wszCaps = root["c"].as_mstring(); - r->m_pCaps = m_clientCapsManager.SetClientCaps(szNode, szVer, nullptr, _wtoi64(wszCaps)); - r->m_pCaps->m_szOs = mir_wstrdup(root["o"].as_mstring()); - r->m_pCaps->m_szOsVer = mir_wstrdup(root["ov"].as_mstring()); - r->m_pCaps->m_szSoft = mir_wstrdup(root["s"].as_mstring()); - r->m_pCaps->m_szSoftVer = mir_wstrdup(root["sv"].as_mstring()); - r->m_pCaps->m_szSoftMir = mir_wstrdup(root["sm"].as_mstring()); - } - } - } + const wchar_t *szNode = XmlGetAttrValue(n, L"node"); + const wchar_t *szVer = XmlGetAttrValue(n, L"ver"); + const wchar_t *szExt = XmlGetAttrValue(n, L"ext"); + if (szNode == nullptr || szVer == nullptr) + return; - if (r->m_pCaps == nullptr) { - r->m_pCaps = m_clientCapsManager.SetClientCaps(szNode, szVer, L"", JABBER_RESOURCE_CAPS_UNINIT); - GetResourceCapabilites(from, false); - } + const wchar_t *szHash = XmlGetAttrValue(n, L"hash"); + if (szHash == nullptr) { // old version + ptrA szVerUtf(mir_utf8encodeW(szVer)); + BYTE hashOut[MIR_SHA1_HASH_SIZE]; + mir_sha1_hash((BYTE*)szVerUtf.get(), mir_strlen(szVerUtf), hashOut); + wchar_t szHashOut[MIR_SHA1_HASH_SIZE * 2 + 1]; + bin2hexW(hashOut, _countof(hashOut), szHashOut); + r->m_pCaps = m_clientCapsManager.GetPartialCaps(szNode, szHashOut); + if (r->m_pCaps == nullptr) + r->m_pCaps = m_clientCapsManager.SetClientCaps(szNode, szHashOut, szVer, JABBER_RESOURCE_CAPS_NONE); + + MCONTACT hContact = HContactFromJID(from); + if (hContact) + UpdateMirVer(hContact, r); + } + else { + r->m_pCaps = m_clientCapsManager.GetPartialCaps(szNode, szVer); + if (r->m_pCaps == nullptr) { + CMStringA szName(FORMAT, "%S#%S", szNode, szVer); + ptrA szValue(db_get_sa(0, "JabberCaps", szName)); + if (szValue != 0) { + JSONNode root = JSONNode::parse(szValue); + if (root) { + CMStringW wszCaps = root["c"].as_mstring(); + r->m_pCaps = m_clientCapsManager.SetClientCaps(szNode, szVer, nullptr, _wtoi64(wszCaps)); + r->m_pCaps->m_szOs = mir_wstrdup(root["o"].as_mstring()); + r->m_pCaps->m_szOsVer = mir_wstrdup(root["ov"].as_mstring()); + r->m_pCaps->m_szSoft = mir_wstrdup(root["s"].as_mstring()); + r->m_pCaps->m_szSoftVer = mir_wstrdup(root["sv"].as_mstring()); + r->m_pCaps->m_szSoftMir = mir_wstrdup(root["sm"].as_mstring()); } - - r->m_tszCapsExt = mir_wstrdup(szExt); } } + + if (r->m_pCaps == nullptr) { + r->m_pCaps = m_clientCapsManager.SetClientCaps(szNode, szVer, L"", JABBER_RESOURCE_CAPS_UNINIT); + GetResourceCapabilites(from, false); + } } + + r->m_tszCapsExt = mir_wstrdup(szExt); } void CJabberProto::UpdateJidDbSettings(const wchar_t *jid) @@ -1613,7 +1613,9 @@ void CJabberProto::OnProcessPresence(HXML node, ThreadData *info) ListAddResource(LIST_ROSTER, from, status, XmlGetText(XmlGetChild(node, "status")), priority); // XEP-0115: Entity Capabilities - OnProcessPresenceCapabilites(node); + pResourceStatus r(ResourceInfoFromJID(from)); + if (r != nullptr) + OnProcessPresenceCapabilites(node, r); UpdateJidDbSettings(from); -- cgit v1.2.3