From 02919456e615e75ca6718cfc11cd933d0f80e8e6 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Wed, 20 Jul 2022 19:59:47 +0300 Subject: Jabber: attempt to unify caps processing --- protocols/JabberG/src/jabber_caps.cpp | 145 +++++++++++----------------------- protocols/JabberG/src/jabber_proto.h | 3 + 2 files changed, 51 insertions(+), 97 deletions(-) (limited to 'protocols/JabberG/src') diff --git a/protocols/JabberG/src/jabber_caps.cpp b/protocols/JabberG/src/jabber_caps.cpp index e2d663fd7c..af7ea89ba8 100644 --- a/protocols/JabberG/src/jabber_caps.cpp +++ b/protocols/JabberG/src/jabber_caps.cpp @@ -106,15 +106,7 @@ const int g_cJabberFeatCapPairsExt = _countof(g_JabberFeatCapPairsExt); void CJabberProto::AddDefaultCaps() { - JabberCapsBits myCaps = JABBER_CAPS_MIRANDA_ALL; - if (m_bUseOMEMO) - myCaps |= JABBER_CAPS_OMEMO_DEVICELIST_NOTIFY; - if (!m_bAllowTimeReplies) - myCaps &= ~JABBER_CAPS_ENTITY_TIME; - if (!m_bAllowVersionRequests) - myCaps &= ~JABBER_CAPS_VERSION; - if (!m_bMsgAck) - myCaps &= ~(JABBER_CAPS_CHAT_MARKERS | JABBER_CAPS_MESSAGE_RECEIPTS); + JabberCapsBits myCaps = GetOwnCaps(false); for (auto &it : g_JabberFeatCapPairsExt) if (it.Valid()) @@ -322,66 +314,13 @@ JabberCapsBits CJabberProto::GetResourceCapabilities(const char *jid, pResourceS bool CJabberProto::HandleCapsInfoRequest(const TiXmlElement *, CJabberIqInfo *pInfo, const char *szNode) { - JabberCapsBits jcb = 0; - - if (szNode) { - char szExtCap[512], szExtCapWHash[560]; - mir_snprintf(szExtCap, "%s#%s", JABBER_CAPS_MIRANDA_NODE, m_szFeaturesCrc.c_str()); - if (!mir_strcmp(szExtCap, szNode)) { - szNode = nullptr; - goto LBL_All; - } - - for (auto &it : g_JabberFeatCapPairsExt) { - if (!it.Valid()) - continue; - - // TODO: something better here - mir_snprintf(szExtCap, "%s#%s", JABBER_CAPS_MIRANDA_NODE, it.szFeature); - mir_snprintf(szExtCapWHash, "%s %s", szExtCap, m_szFeaturesCrc.c_str()); - if (!mir_strcmp(szNode, szExtCap) || !mir_strcmp(szNode, szExtCapWHash)) { - jcb = it.jcbCap; - break; - } - } - - // check features registered through IJabberNetInterface::RegisterFeature() and IJabberNetInterface::AddFeatures() - for (auto &it : m_lstJabberFeatCapPairsDynamic) { - // TODO: something better here - mir_snprintf(szExtCap, "%s#%s", JABBER_CAPS_MIRANDA_NODE, it->szExt); - mir_snprintf(szExtCapWHash, "%s %s", szExtCap, m_szFeaturesCrc.c_str()); - if (!mir_strcmp(szNode, szExtCap) || !mir_strcmp(szNode, szExtCapWHash)) { - jcb = it->jcbCap; - break; - } - } - - // unknown node, not XEP-0115 request - if (!jcb) - return false; - } - else { - LBL_All: - jcb = JABBER_CAPS_MIRANDA_ALL; - for (auto &it : m_lstJabberFeatCapPairsDynamic) - jcb |= it->jcbCap; - } - - if (m_bUseOMEMO) - jcb |= JABBER_CAPS_OMEMO_DEVICELIST_NOTIFY; - - if (!m_bAllowTimeReplies) - jcb &= ~JABBER_CAPS_ENTITY_TIME; - if (!m_bAllowVersionRequests) - jcb &= ~JABBER_CAPS_VERSION; - if (!m_bMsgAck) - jcb &= ~(JABBER_CAPS_CHAT_MARKERS | JABBER_CAPS_MESSAGE_RECEIPTS); - XmlNodeIq iq("result", pInfo); TiXmlElement *query = iq << XQUERY(JABBER_FEAT_DISCO_INFO); - if (szNode) - query << XATTR("node", szNode); + if (szNode){ + CMStringA szExtCap(FORMAT, "%s#%s", JABBER_CAPS_MIRANDA_NODE, m_szFeaturesCrc.c_str()); + query << XATTR("node", szExtCap); + } CMStringA szName(getMStringA("Identity")); // hidden setting to be entered from dbeditor++ if (szName.IsEmpty()) { @@ -391,13 +330,9 @@ bool CJabberProto::HandleCapsInfoRequest(const TiXmlElement *, CJabberIqInfo *pI } query << XCHILD("identity") << XATTR("category", "client") << XATTR("type", "pc") << XATTR("name", szName); - for (auto &it : g_JabberFeatCapPairs) - if (jcb & it.jcbCap) - query << XCHILD("feature") << XATTR("var", it.szFeature); - - for (auto &it : m_lstJabberFeatCapPairsDynamic) - if (jcb & it->jcbCap) - query << XCHILD("feature") << XATTR("var", it->szFeature); + for (auto &it : GetSortedFeatStrings(GetOwnCaps())) { + query << XCHILD("feature") << XATTR("var", it); + } if (m_bAllowVersionRequests && !szNode) { TiXmlElement *form = query << XCHILDNS("x", JABBER_FEAT_DATA_FORMS) << XATTR("type", "result"); @@ -420,45 +355,61 @@ bool CJabberProto::HandleCapsInfoRequest(const TiXmlElement *, CJabberIqInfo *pI return true; } -void CJabberProto::RequestOldCapsInfo(pResourceStatus &r, const char *fullJid) +JabberCapsBits CJabberProto::GetOwnCaps(bool IncludeDynamic) { - CJabberIqInfo *pInfo = AddIQ(&CJabberProto::OnIqResultCapsDiscoInfo, JABBER_IQ_TYPE_GET, fullJid); - pInfo->SetParamsToParse(JABBER_IQ_PARSE_FROM | JABBER_IQ_PARSE_CHILD_TAG_NODE); - pInfo->SetTimeout(JABBER_RESOURCE_CAPS_QUERY_TIMEOUT); - r->m_dwDiscoInfoRequestTime = pInfo->GetRequestTime(); - - m_ThreadInfo->send(XmlNodeIq(pInfo) << XQUERY(JABBER_FEAT_DISCO_INFO)); -} + JabberCapsBits jcb = JABBER_CAPS_MIRANDA_ALL; -void CJabberProto::UpdateFeatHash() -{ - m_szFeaturesCrc.Empty(); + if (IncludeDynamic) + for (auto &it : m_lstJabberFeatCapPairsDynamic) + jcb |= it->jcbCap; - JabberCapsBits jcb = JABBER_CAPS_MIRANDA_ALL; - for (auto &it : m_lstJabberFeatCapPairsDynamic) - jcb |= it->jcbCap; if (!m_bAllowTimeReplies) jcb &= ~JABBER_CAPS_ENTITY_TIME; if (!m_bAllowVersionRequests) jcb &= ~JABBER_CAPS_VERSION; - if (m_bUseOMEMO) jcb |= JABBER_CAPS_OMEMO_DEVICELIST_NOTIFY; if (!m_bMsgAck) jcb &= ~(JABBER_CAPS_CHAT_MARKERS | JABBER_CAPS_MESSAGE_RECEIPTS); - CMStringA feat_buf(FORMAT, "client/pc//Miranda %d.%d.%d.%d<", __MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM); + return jcb; +} + +LIST CJabberProto::GetSortedFeatStrings(JabberCapsBits jcb) +{ + LIST feats(10, strcmp); for (auto &it : g_JabberFeatCapPairs) - if (jcb & it.jcbCap) { - feat_buf.Append(it.szFeature); - feat_buf.AppendChar('<'); - } + if (jcb & it.jcbCap) + feats.insert((char*)it.szFeature); for (auto &it : m_lstJabberFeatCapPairsDynamic) - if (jcb & it->jcbCap) { - feat_buf.Append(it->szFeature); - feat_buf.AppendChar('<'); - } + if (jcb & it->jcbCap) + feats.insert(it->szFeature); + + return feats; +} + +void CJabberProto::RequestOldCapsInfo(pResourceStatus &r, const char *fullJid) +{ + CJabberIqInfo *pInfo = AddIQ(&CJabberProto::OnIqResultCapsDiscoInfo, JABBER_IQ_TYPE_GET, fullJid); + pInfo->SetParamsToParse(JABBER_IQ_PARSE_FROM | JABBER_IQ_PARSE_CHILD_TAG_NODE); + pInfo->SetTimeout(JABBER_RESOURCE_CAPS_QUERY_TIMEOUT); + r->m_dwDiscoInfoRequestTime = pInfo->GetRequestTime(); + + m_ThreadInfo->send(XmlNodeIq(pInfo) << XQUERY(JABBER_FEAT_DISCO_INFO)); +} + +void CJabberProto::UpdateFeatHash() +{ + m_szFeaturesCrc.Empty(); + + ptrA szName(getStringA("Identity", "Miranda")); // hidden setting to be entered from dbeditor++ + CMStringA feat_buf(FORMAT, "client/pc//%s<", szName.get()); + + for (auto &it : GetSortedFeatStrings(GetOwnCaps())) { + feat_buf.Append(it); + feat_buf.AppendChar('<'); + } feat_buf.Append("software_version"); feat_buf.AppendChar('<'); feat_buf.Append(__VERSION_STRING_DOTS); feat_buf.AppendChar('<'); diff --git a/protocols/JabberG/src/jabber_proto.h b/protocols/JabberG/src/jabber_proto.h index 72e29ceb74..749060052e 100644 --- a/protocols/JabberG/src/jabber_proto.h +++ b/protocols/JabberG/src/jabber_proto.h @@ -431,6 +431,9 @@ struct CJabberProto : public PROTO, public IJabberInterface JabberCapsBits GetResourceCapabilities(const char *jid); JabberCapsBits GetResourceCapabilities(const char *jid, pResourceStatus &r); + LIST GetSortedFeatStrings(JabberCapsBits jcb); + JabberCapsBits GetOwnCaps(bool IncludeDynamic = true); + //---- jabber_captcha.cpp ------------------------------------------------------------ void sendCaptchaResult(char* buf, ThreadData *info, const char *from, const char *challenge, const char *fromjid, const char *sid); -- cgit v1.2.3