diff options
author | George Hazan <ghazan@miranda.im> | 2020-08-28 20:16:04 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2020-08-28 20:16:04 +0300 |
commit | 7650b1b0aa057df686e7d44bae58eaeba03b9b93 (patch) | |
tree | d233c6393d8831002729beaa0432ff9e4099dac1 | |
parent | 8fa3e54ad4fd6d3f3055273a2f400a3360ab82ea (diff) |
Jabber: MAM adaptation for OpenFire
-rw-r--r-- | protocols/JabberG/src/jabber_mam.cpp | 30 | ||||
-rwxr-xr-x | protocols/JabberG/src/jabber_proto.h | 1 | ||||
-rwxr-xr-x | protocols/JabberG/src/jabber_thread.cpp | 61 |
3 files changed, 59 insertions, 33 deletions
diff --git a/protocols/JabberG/src/jabber_mam.cpp b/protocols/JabberG/src/jabber_mam.cpp index f369dcb0c4..4fb0359e93 100644 --- a/protocols/JabberG/src/jabber_mam.cpp +++ b/protocols/JabberG/src/jabber_mam.cpp @@ -69,13 +69,26 @@ void CJabberProto::MamSetMode(int iNewMode) void CJabberProto::MamRetrieveMissingMessages() { CMStringA szLastId = getMStringA("LastMamId"); - if (szLastId.IsEmpty()) - return; XmlNodeIq iq("set", SerialNext()); - auto *set = iq << XCHILDNS("query", JABBER_FEAT_MAM) << XCHILDNS("set", "http://jabber.org/protocol/rsm"); - set << XCHILD("max", "100"); - set << XCHILD("after", szLastId); + auto *query = iq << XCHILDNS("query", JABBER_FEAT_MAM); + + if (szLastId.IsEmpty()) { + m_bMamDisableMessages = true; // our goal is to save message id, not to store messages + + char buf[100]; + time2str(time(0), buf, _countof(buf)); + + auto *form = query << XCHILDNS("x", JABBER_FEAT_DATA_FORMS) << XATTR("type", "submit"); + form << XCHILD("field") << XATTR("var", "FORM_TYPE") << XATTR("type", "hidden") << XCHILD("value", JABBER_FEAT_MAM); + form << XCHILD("field") << XATTR("var", "end") << XCHILD("value", buf); + } + else { + auto *set = query << XCHILDNS("set", "http://jabber.org/protocol/rsm"); + set << XCHILD("max", "1000"); + set << XCHILD("after", szLastId); + } + m_ThreadInfo->send(iq); } @@ -84,6 +97,9 @@ void CJabberProto::MamRetrieveMissingMessages() void CJabberProto::OnIqResultRsm(const TiXmlElement *iqNode, CJabberIqInfo *pInfo) { + // even if that flag was enabled, unset it + m_bMamDisableMessages = false; + if (auto *fin = XmlGetChildByTag(iqNode, "fin", "xmlns", JABBER_FEAT_MAM)) { // if dataset is complete, there's nothing more to do if (!mir_strcmp(XmlGetAttr(fin, "complete"), "true")) @@ -98,7 +114,7 @@ void CJabberProto::OnIqResultRsm(const TiXmlElement *iqNode, CJabberIqInfo *pInf XmlNodeIq iq(pReq); auto *query = iq << XCHILDNS("query", JABBER_FEAT_MAM); - auto *x = query << XCHILDNS("x", "jabber:x:data") << XATTR("type", "submit"); + auto *x = query << XCHILDNS("x", JABBER_FEAT_DATA_FORMS) << XATTR("type", "submit"); x << XCHILD("var", "FORM_TYPE") << XATTR("type", "hidden") << XCHILD("value", JABBER_FEAT_MAM); x << XCHILD("var", "with") << XCHILD("value", jid); auto *rsm = query << XCHILDNS("set", "http://jabber.org/protocol/rsm"); @@ -128,7 +144,7 @@ INT_PTR __cdecl CJabberProto::OnMenuLoadHistory(WPARAM hContact, LPARAM) XmlNodeIq iq(pReq); auto *query = iq << XCHILDNS("query", JABBER_FEAT_MAM); - auto *x = query << XCHILDNS("x", "jabber:x:data") << XATTR("type", "submit"); + auto *x = query << XCHILDNS("x", JABBER_FEAT_DATA_FORMS) << XATTR("type", "submit"); x << XCHILD("var", "FORM_TYPE") << XATTR("type", "hidden") << XCHILD("value", JABBER_FEAT_MAM); x << XCHILD("var", "with") << XCHILD("value", jid); query << XCHILDNS("set", "http://jabber.org/protocol/rsm") << XCHILD("max", "100"); diff --git a/protocols/JabberG/src/jabber_proto.h b/protocols/JabberG/src/jabber_proto.h index c09b07ce34..64e17bb539 100755 --- a/protocols/JabberG/src/jabber_proto.h +++ b/protocols/JabberG/src/jabber_proto.h @@ -251,6 +251,7 @@ struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface bool m_bPepSupported;
bool m_bStreamSent;
bool m_bMamPrefsAvailable;
+ bool m_bMamDisableMessages;
HWND m_hwndJabberChangePassword;
HWND m_hwndPrivacyRule;
diff --git a/protocols/JabberG/src/jabber_thread.cpp b/protocols/JabberG/src/jabber_thread.cpp index f295adbfc7..a9b3a6c78d 100755 --- a/protocols/JabberG/src/jabber_thread.cpp +++ b/protocols/JabberG/src/jabber_thread.cpp @@ -1005,18 +1005,49 @@ void CJabberProto::OnProcessMessage(const TiXmlElement *node, ThreadData *info) if (!node->Name() || mir_strcmp(node->Name(), "message"))
return;
- const char *from, *type = XmlGetAttr(node, "type");
- if ((from = XmlGetAttr(node, "from")) == nullptr) {
+ bool bEnableDelivery = true;
+ time_t msgTime = 0;
+ auto *from = XmlGetAttr(node, "from"), *type = XmlGetAttr(node, "type"), *idStr = XmlGetAttr(node, "id");
+ const char *szMsgId = nullptr; // MAM support
+
+ // check for MAM response
+ if (auto *mamResult = XmlGetChildByTag(node, "result", "xmlns", JABBER_FEAT_MAM)) {
+ szMsgId = XmlGetAttr(mamResult, "id");
+ if (szMsgId)
+ setString("LastMamId", szMsgId);
+
+ // we only collect ids, no need to store messages
+ if (m_bMamDisableMessages)
+ return;
+
+ auto *xmlForwarded = XmlGetChildByTag(mamResult, "forwarded", "xmlns", JABBER_XMLNS_FORWARD);
+ if (auto *xmlMessage = XmlFirstChild(xmlForwarded, "message")) {
+ node = xmlMessage;
+ type = XmlGetAttr(node, "type");
+ from = XmlGetAttr(node, "from");
+ if (!mir_strcmpi(from, info->fullJID)) {
+ debugLogA("MAM: outgoing message from this machine (%s), ignored", from);
+ return;
+ }
+ }
+
+ if (auto *xmlDelay = XmlGetChildByTag(xmlForwarded, "delay", "xmlns", JABBER_FEAT_DELAY))
+ if (auto *ptszTimeStamp = XmlGetAttr(xmlDelay, "stamp"))
+ msgTime = JabberIsoToUnixTime(ptszTimeStamp);
+
+ bEnableDelivery = false;
+ }
+
+ if (from == nullptr) {
debugLogA("no 'from' attribute, returning");
return;
}
- const char *idStr = XmlGetAttr(node, "id");
pResourceStatus pFromResource(ResourceInfoFromJID(from));
// Message receipts delivery request. Reply here, before a call to HandleMessagePermanent() to make sure message receipts are handled for external plugins too.
bool bSendMark = false;
- if ((!type || mir_strcmpi(type, "error"))) {
+ if (bEnableDelivery && (!type || mir_strcmpi(type, "error"))) {
bool bSendReceipt = XmlGetChildByTag(node, "request", "xmlns", JABBER_FEAT_MESSAGE_RECEIPTS) != 0;
bSendMark = XmlGetChildByTag(node, "markable", "xmlns", JABBER_FEAT_CHAT_MARKERS) != 0;
if (bSendReceipt || bSendMark) {
@@ -1040,8 +1071,6 @@ void CJabberProto::OnProcessMessage(const TiXmlElement *node, ThreadData *info) return;
}
- time_t msgTime = 0;
-
// Handle carbons. The message MUST be coming from our bare JID.
const TiXmlElement *carbon = nullptr;
bool carbonSent = false; //2 cases: received or sent.
@@ -1087,24 +1116,6 @@ void CJabberProto::OnProcessMessage(const TiXmlElement *node, ThreadData *info) }
}
}
- else { // check for MAM response
- if (auto *mamResult = XmlGetChildByTag(node, "result", "xmlns", JABBER_FEAT_MAM)) {
- auto *xmlForwarded = XmlGetChildByTag(mamResult, "forwarded", "xmlns", JABBER_XMLNS_FORWARD);
- if (auto *xmlMessage = XmlFirstChild(xmlForwarded, "message")) {
- node = xmlMessage;
- type = XmlGetAttr(node, "type");
- from = XmlGetAttr(node, "from");
- if (!mir_strcmpi(from, info->fullJID)) {
- debugLogA("MAM: outgoing message from this machine (%s), ignored", from);
- return;
- }
- }
- if (auto *xmlDelay = XmlGetChildByTag(xmlForwarded, "delay", "xmlns", JABBER_FEAT_DELAY)) {
- if (auto *ptszTimeStamp = XmlGetAttr(xmlDelay, "stamp"))
- msgTime = JabberIsoToUnixTime(ptszTimeStamp);
- }
- }
- }
}
MCONTACT hContact = HContactFromJID(from);
@@ -1146,8 +1157,6 @@ void CJabberProto::OnProcessMessage(const TiXmlElement *node, ThreadData *info) if (bodyNode != nullptr)
szMessage.Append(bodyNode->GetText());
- // check MAM support
- const char *szMsgId = nullptr;
if (auto *n = XmlGetChildByTag(node, "stanza-id", "xmlns", JABBER_FEAT_SID))
if (szMsgId = n->Attribute("id"))
setString("LastMamId", szMsgId);
|