diff options
author | George Hazan <ghazan@miranda.im> | 2020-06-11 22:20:11 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2020-06-11 22:20:18 +0300 |
commit | 5fb805622a3a3368ffb3de0c649074376e70256a (patch) | |
tree | 64f0149c8e5d692cf19e5fcebb60b0fba59e3d93 /protocols/JabberG | |
parent | e6bf9c2a41622424c2cd4006326455e08c80812a (diff) |
fixes #1149 (XMPP/Jabber: Implement XEP-0313 ( mam / Message Archive Management )
Diffstat (limited to 'protocols/JabberG')
-rwxr-xr-x | protocols/JabberG/jabber.vcxproj | 1 | ||||
-rwxr-xr-x | protocols/JabberG/jabber.vcxproj.filters | 3 | ||||
-rw-r--r-- | protocols/JabberG/res/jabber.rc | 21 | ||||
-rwxr-xr-x | protocols/JabberG/src/jabber_caps.cpp | 1 | ||||
-rwxr-xr-x | protocols/JabberG/src/jabber_caps.h | 7 | ||||
-rwxr-xr-x | protocols/JabberG/src/jabber_iqid.cpp | 10 | ||||
-rw-r--r-- | protocols/JabberG/src/jabber_mam.cpp | 78 | ||||
-rwxr-xr-x | protocols/JabberG/src/jabber_opt.cpp | 14 | ||||
-rwxr-xr-x | protocols/JabberG/src/jabber_proto.cpp | 1 | ||||
-rwxr-xr-x | protocols/JabberG/src/jabber_proto.h | 44 | ||||
-rwxr-xr-x | protocols/JabberG/src/jabber_thread.cpp | 27 | ||||
-rw-r--r-- | protocols/JabberG/src/resource.h | 3 |
12 files changed, 175 insertions, 35 deletions
diff --git a/protocols/JabberG/jabber.vcxproj b/protocols/JabberG/jabber.vcxproj index 9495f2516f..7eb80b6e17 100755 --- a/protocols/JabberG/jabber.vcxproj +++ b/protocols/JabberG/jabber.vcxproj @@ -51,6 +51,7 @@ <ClCompile Include="src\jabber_iq_handlers.cpp" />
<ClCompile Include="src\jabber_libstr.cpp" />
<ClCompile Include="src\jabber_list.cpp" />
+ <ClCompile Include="src\jabber_mam.cpp" />
<ClCompile Include="src\jabber_menu.cpp" />
<ClCompile Include="src\jabber_message_handlers.cpp" />
<ClCompile Include="src\jabber_message_manager.cpp" />
diff --git a/protocols/JabberG/jabber.vcxproj.filters b/protocols/JabberG/jabber.vcxproj.filters index 72b6943026..3a72f63b4b 100755 --- a/protocols/JabberG/jabber.vcxproj.filters +++ b/protocols/JabberG/jabber.vcxproj.filters @@ -164,6 +164,9 @@ <ClCompile Include="src\stdafx.cxx">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="src\jabber_mam.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\jabber_byte.h">
diff --git a/protocols/JabberG/res/jabber.rc b/protocols/JabberG/res/jabber.rc index 6280d2c403..5e6bb8a04e 100644 --- a/protocols/JabberG/res/jabber.rc +++ b/protocols/JabberG/res/jabber.rc @@ -91,7 +91,7 @@ BEGIN PUSHBUTTON "Export to file",IDC_EXPORT,272,268,71,15
END
-IDD_OPT_JABBER DIALOGEX 0, 0, 304, 208
+IDD_OPT_JABBER DIALOGEX 0, 0, 304, 222
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
EXSTYLE WS_EX_CONTROLPARENT
FONT 8, "MS Shell Dlg", 0, 0, 0x1
@@ -103,6 +103,7 @@ BEGIN EDITTEXT IDC_EDIT_PASSWORD,66,30,86,12,ES_PASSWORD | ES_AUTOHSCROLL
PUSHBUTTON "Change password",IDC_BUTTON_CHANGE_PASSWORD,156,30,78,13
CONTROL "Save password",IDC_SAVEPASSWORD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,66,45,89,10
+ CONTROL "Use Domain Login",IDC_USEDOMAINLOGIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,157,45,137,9
LTEXT "Priority:",IDC_PRIORITY_LABEL,12,59,41,8
EDITTEXT IDC_PRIORITY,66,57,85,12,ES_AUTOHSCROLL
CONTROL "Spin1",IDC_PRIORITY_SPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,151,57,12,12
@@ -120,18 +121,19 @@ BEGIN CONTROL "Use TLS",IDC_USE_TLS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,189,100,97,10
PUSHBUTTON "Register new user",IDC_BUTTON_REGISTER,156,16,78,13
PUSHBUTTON "Unregister",IDC_UNREGISTER,235,16,56,13
- GROUPBOX "Expert",IDC_STATIC,4,120,295,85
+ GROUPBOX "Expert",IDC_STATIC,4,120,295,99
CONTROL "Manually specify connection host",IDC_MANUAL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,134,223,10
RTEXT "Host:",IDC_STATIC,26,147,30,8
EDITTEXT IDC_HOST,57,145,90,12,ES_AUTOHSCROLL | WS_DISABLED
RTEXT "Port:",IDC_STATIC,156,147,27,8
EDITTEXT IDC_HOSTPORT,186,145,31,12,ES_AUTOHSCROLL | ES_NUMBER | WS_DISABLED
- CONTROL "Keep connection alive",IDC_KEEPALIVE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,158,221,10
+ CONTROL "Keep connection alive",IDC_KEEPALIVE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,159,283,10
CONTROL "Automatically delete contacts not in my roster",IDC_ROSTER_SYNC,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,172,221,10
- LTEXT "Language for human-readable resources:",IDC_MSGLANG_LABEL,11,188,170,8
- COMBOBOX IDC_MSGLANG,188,186,103,69,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
- CONTROL "Use Domain Login",IDC_USEDOMAINLOGIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,157,45,137,9
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,172,283,10
+ LTEXT "History recording mode",IDC_STATIC,12,187,170,8
+ COMBOBOX IDC_MAM_MODE,188,185,103,69,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "Language for human-readable resources:",IDC_MSGLANG_LABEL,11,202,170,8
+ COMBOBOX IDC_MSGLANG,188,200,103,69,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
END
IDD_OPT_JABBER2 DIALOGEX 0, 0, 304, 228
@@ -712,6 +714,11 @@ BEGIN BEGIN
END
+ IDD_OPT_JABBER, DIALOG
+ BEGIN
+ BOTTOMMARGIN, 208
+ END
+
IDD_OPT_REGISTER, DIALOG
BEGIN
RIGHTMARGIN, 165
diff --git a/protocols/JabberG/src/jabber_caps.cpp b/protocols/JabberG/src/jabber_caps.cpp index d1e8b987f9..bce11fb61f 100755 --- a/protocols/JabberG/src/jabber_caps.cpp +++ b/protocols/JabberG/src/jabber_caps.cpp @@ -68,6 +68,7 @@ const JabberFeatCapPair g_JabberFeatCapPairs[] = { JABBER_FEAT_USER_TUNE_NOTIFY, JABBER_CAPS_USER_TUNE_NOTIFY, LPGEN("Receives information about the music to which a user is listening") },
{ JABBER_FEAT_PRIVATE_STORAGE, JABBER_CAPS_PRIVATE_STORAGE, LPGEN("Supports private XML Storage (for bookmarks and other)") },
{ JABBER_FEAT_ATTENTION, JABBER_CAPS_ATTENTION, LPGEN("Supports attention requests ('nudge')") },
+ { JABBER_FEAT_MAM, JABBER_CAPS_MAM, LPGEN("Support Message Archive Management (XEP-0313)") },
{ JABBER_FEAT_USER_ACTIVITY, JABBER_CAPS_USER_ACTIVITY, LPGEN("Can report information about user activity") },
{ JABBER_FEAT_USER_ACTIVITY_NOTIFY, JABBER_CAPS_USER_ACTIVITY_NOTIFY, LPGEN("Receives information about user activity") },
{ JABBER_FEAT_MIRANDA_NOTES, JABBER_CAPS_MIRANDA_NOTES, LPGEN("Supports Miranda NG notes extension") },
diff --git a/protocols/JabberG/src/jabber_caps.h b/protocols/JabberG/src/jabber_caps.h index 052ee09cf5..980ff36777 100755 --- a/protocols/JabberG/src/jabber_caps.h +++ b/protocols/JabberG/src/jabber_caps.h @@ -144,6 +144,9 @@ typedef unsigned __int64 JabberCapsBits; #define JABBER_FEAT_PRIVATE_STORAGE "jabber:iq:private"
#define JABBER_CAPS_PRIVATE_STORAGE ((JabberCapsBits)1<<33)
+#define JABBER_FEAT_MAM "urn:xmpp:mam:2"
+#define JABBER_CAPS_MAM ((JabberCapsBits)1<<34)
+
#define JABBER_FEAT_ATTENTION "urn:xmpp:attention:0"
#define JABBER_CAPS_ATTENTION ((JabberCapsBits)1<<36)
@@ -211,8 +214,8 @@ typedef unsigned __int64 JabberCapsBits; JABBER_CAPS_ROSTER_EXCHANGE | JABBER_CAPS_DIRECT_MUC_INVITE | JABBER_CAPS_CHAT_MARKERS | JABBER_CAPS_BITS | JABBER_CAPS_XHTML)
#define JABBER_CAPS_MIRANDA_ALL (JABBER_CAPS_MIRANDA_PARTIAL | JABBER_CAPS_COMMANDS | \
- JABBER_CAPS_USER_MOOD_NOTIFY | JABBER_CAPS_USER_TUNE_NOTIFY | JABBER_CAPS_USER_ACTIVITY_NOTIFY \
- | JABBER_CAPS_PLATFORMX86 | JABBER_CAPS_PLATFORMX64)
+ JABBER_CAPS_USER_MOOD_NOTIFY | JABBER_CAPS_USER_TUNE_NOTIFY | JABBER_CAPS_USER_ACTIVITY_NOTIFY | \
+ JABBER_CAPS_PLATFORMX86 | JABBER_CAPS_PLATFORMX64)
#define JABBER_XMLNS_FORWARD "urn:xmpp:forward:0"
diff --git a/protocols/JabberG/src/jabber_iqid.cpp b/protocols/JabberG/src/jabber_iqid.cpp index e342f39410..bdaa73dc5d 100755 --- a/protocols/JabberG/src/jabber_iqid.cpp +++ b/protocols/JabberG/src/jabber_iqid.cpp @@ -123,10 +123,14 @@ void CJabberProto::OnProcessLoginRq(ThreadData *info, DWORD rq) DWORD dwMask = JABBER_LOGIN_ROSTER | JABBER_LOGIN_BOOKMARKS | JABBER_LOGIN_SERVERINFO;
if ((info->dwLoginRqs & dwMask) == dwMask && !(info->dwLoginRqs & JABBER_LOGIN_BOOKMARKS_AJ)) {
- if (info->jabberServerCaps & JABBER_CAPS_CARBONS) {
- // Server seems to support carbon copies, let's enable/disable them
+
+ // Server seems to support carbon copies, let's enable/disable them
+ if (info->jabberServerCaps & JABBER_CAPS_CARBONS)
m_ThreadInfo->send(XmlNodeIq("set", SerialNext()) << XCHILDNS((m_bEnableCarbons) ? "enable" : "disable", JABBER_FEAT_CARBONS));
- }
+
+ // Server seems to support MAM, let's retrieve MAM settings
+ if (info->jabberServerCaps & JABBER_CAPS_MAM)
+ m_ThreadInfo->send(XmlNodeIq(AddIQ(&CJabberProto::OnIqResultMamInfo, JABBER_IQ_TYPE_GET, 0, this)) << XCHILDNS("prefs", JABBER_FEAT_MAM));
if (m_bAutoJoinBookmarks) {
LIST<JABBER_LIST_ITEM> ll(10);
diff --git a/protocols/JabberG/src/jabber_mam.cpp b/protocols/JabberG/src/jabber_mam.cpp new file mode 100644 index 0000000000..41a3482119 --- /dev/null +++ b/protocols/JabberG/src/jabber_mam.cpp @@ -0,0 +1,78 @@ +/* + +Jabber Protocol Plugin for Miranda NG + +Copyright (c) 2002-04 Santithorn Bunchua +Copyright (c) 2005-12 George Hazan +Copyright (c) 2007 Maxim Mluhov +Copyright (C) 2012-20 Miranda NG team + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "stdafx.h" +#include "jabber_iq.h" +#include "jabber_caps.h" + +void CJabberProto::OnIqResultMamInfo(const TiXmlElement *iqNode, CJabberIqInfo *pInfo) +{ + if (pInfo->GetIqType() != JABBER_IQ_TYPE_RESULT) + return; + + if (auto *n = XmlFirstChild(iqNode, "prefs")) { + if (auto *type = n->Attribute("default")) { + if (!strcmp(type, "never")) + m_iMamMode = 0; + else if (!strcmp(type, "roster")) + m_iMamMode = 1; + else + m_iMamMode = 2; + } + } + + // shall we retrieve missing messages? + if (pInfo->GetUserData()) + MamRetrieveMissingMessages(); +} + +void CJabberProto::MamSetMode(int iNewMode) +{ + const char *szMode; + switch (iNewMode) { + case 0: szMode = "never"; break; + case 1: szMode = "roster"; break; + default: szMode = "always"; break; + } + + XmlNodeIq iq(AddIQ(&CJabberProto::OnIqResultMamInfo, JABBER_IQ_TYPE_SET)); + auto *node = iq << XCHILDNS("prefs", JABBER_FEAT_MAM) << XATTR("default", szMode); + node << XCHILD("always"); node << XCHILD("never"); + m_ThreadInfo->send(iq); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CJabberProto::MamRetrieveMissingMessages() +{ + CMStringA szLastId = getMStringA("LastMamId"); + + XmlNodeIq iq("set", SerialNext()); + auto *set = iq << XCHILDNS("query", JABBER_FEAT_MAM) << XCHILDNS("set", "http://jabber.org/protocol/rsm"); + set << XCHILD("max", "100"); + if (!szLastId.IsEmpty()) + set << XCHILD("after", szLastId); + m_ThreadInfo->send(iq); +} diff --git a/protocols/JabberG/src/jabber_opt.cpp b/protocols/JabberG/src/jabber_opt.cpp index 7ee006d64b..65d95086e9 100755 --- a/protocols/JabberG/src/jabber_opt.cpp +++ b/protocols/JabberG/src/jabber_opt.cpp @@ -348,7 +348,7 @@ class CDlgOptAccount : public CJabberDlgBase CCtrlEdit m_txtManualPort;
CCtrlCheck m_chkKeepAlive;
CCtrlCheck m_chkAutoDeleteContacts;
- CCtrlCombo m_cbLocale;
+ CCtrlCombo m_cbLocale, m_cbMam;
CCtrlButton m_btnRegister;
CCtrlButton m_btnUnregister;
CCtrlButton m_btnChangePassword;
@@ -364,6 +364,7 @@ public: m_cbResource(this, IDC_COMBO_RESOURCE),
m_chkUseHostnameAsResource(this, IDC_HOSTNAME_AS_RESOURCE),
m_chkUseDomainLogin(this, IDC_USEDOMAINLOGIN),
+ m_cbMam(this, IDC_MAM_MODE),
m_cbServer(this, IDC_EDIT_LOGIN_SERVER),
m_txtPort(this, IDC_PORT),
m_chkUseSsl(this, IDC_USE_SSL),
@@ -429,6 +430,14 @@ protected: for (auto &it : szResources)
m_cbResource.AddString(it);
+
+ // fill MAM modes
+ wchar_t *szMamModes[] = { LPGENW("Never"), LPGENW("Roster"), LPGENW("Always") };
+ for (auto &it : szMamModes)
+ m_cbMam.AddString(it, int(&it - szMamModes));
+ m_cbMam.SetCurSel(m_proto->m_iMamMode);
+ m_cbMam.Enable(m_proto->m_ThreadInfo && (m_proto->m_ThreadInfo->jabberServerCaps & JABBER_CAPS_MAM));
+
// append computer name to the resource list
wchar_t szCompName[MAX_COMPUTERNAME_LENGTH + 1];
DWORD dwCompNameLength = MAX_COMPUTERNAME_LENGTH;
@@ -488,6 +497,9 @@ protected: }
}
+ if (m_cbMam.Enabled() && m_cbMam.GetCurSel() != m_proto->m_iMamMode)
+ m_proto->MamSetMode(m_cbMam.GetCurSel());
+
sttStoreJidFromUI(m_proto, m_txtUsername, m_cbServer);
if (m_proto->m_bJabberOnline) {
diff --git a/protocols/JabberG/src/jabber_proto.cpp b/protocols/JabberG/src/jabber_proto.cpp index 349d68646b..5c496b1e6f 100755 --- a/protocols/JabberG/src/jabber_proto.cpp +++ b/protocols/JabberG/src/jabber_proto.cpp @@ -129,6 +129,7 @@ CJabberProto::CJabberProto(const char *aProtoName, const wchar_t *aUserName) : m_bUseSSL(this, "UseSSL", false),
m_bUseTLS(this, "UseTLS", true),
+ m_iMamMode(this, "MamMode", 0),
m_iConnectionKeepAliveInterval(this, "ConnectionKeepAliveInterval", 60000),
m_iConnectionKeepAliveTimeout(this, "ConnectionKeepAliveTimeout", 50000)
{
diff --git a/protocols/JabberG/src/jabber_proto.h b/protocols/JabberG/src/jabber_proto.h index 32fcd80d64..f6a292029e 100755 --- a/protocols/JabberG/src/jabber_proto.h +++ b/protocols/JabberG/src/jabber_proto.h @@ -224,6 +224,7 @@ struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface CMOption<bool> m_bUseSSL;
CMOption<bool> m_bUseTLS;
+ CMOption<int> m_iMamMode;
CMOption<DWORD> m_iConnectionKeepAliveInterval;
CMOption<DWORD> m_iConnectionKeepAliveTimeout;
@@ -419,24 +420,6 @@ struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface void AddMucListItem(JABBER_MUC_JIDLIST_INFO* jidListInfo, const char *str, const char *reason);
void DeleteMucListItem(JABBER_MUC_JIDLIST_INFO* jidListInfo, const char* jid);
- //---- jabber_omemo.cpp --------------------------------------------------------------
-
- bool OmemoHandleMessage(const TiXmlElement *node, const char *jid, time_t msgTime);
- void OmemoPutMessageToOutgoingQueue(MCONTACT hContact, int, const char* pszSrc);
- void OmemoPutMessageToIncommingQueue(const TiXmlElement *node, const char *jid, time_t msgTime);
- void OmemoHandleMessageQueue();
- void OmemoHandleDeviceList(const TiXmlElement *node);
- void OmemoInitDevice();
- void OmemoAnnounceDevice();
- void OmemoSendBundle();
- void OmemoPublishNodes();
- bool OmemoCheckSession(MCONTACT hContact);
- int OmemoEncryptMessage(XmlNode &msg, const char *msg_text, MCONTACT hContact);
- bool OmemoIsEnabled(MCONTACT hContact);
- void OmemoOnIqResultGetBundle(const TiXmlElement *iqNode, CJabberIqInfo *pInfo);
-
- omemo::omemo_impl m_omemo;
-
//---- jabber_console.cpp ------------------------------------------------------------
INT_PTR __cdecl OnMenuHandleConsole(WPARAM wParam, LPARAM lParam);
@@ -639,6 +622,13 @@ struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface void SetBookmarkRequest(XmlNodeIq &iqId);
void UpdateItem(JABBER_LIST_ITEM *pItem, const char *name);
+ //---- jabber_mam.cpp ----------------------------------------------------------------
+
+ void OnIqResultMamInfo(const TiXmlElement *iqNode, CJabberIqInfo *pInfo);
+
+ void MamRetrieveMissingMessages(void);
+ void MamSetMode(int iNewMode);
+
//---- jabber_menu.cpp ---------------------------------------------------------------
INT_PTR __cdecl OnMenuHandleRequestAuth(WPARAM wParam, LPARAM lParam);
@@ -686,6 +676,24 @@ struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface CMStringA ExtractImage(const TiXmlElement *node);
const char* GetSoftName(const char *wszName);
+ //---- jabber_omemo.cpp --------------------------------------------------------------
+
+ bool OmemoHandleMessage(const TiXmlElement *node, const char *jid, time_t msgTime);
+ void OmemoPutMessageToOutgoingQueue(MCONTACT hContact, int, const char *pszSrc);
+ void OmemoPutMessageToIncommingQueue(const TiXmlElement *node, const char *jid, time_t msgTime);
+ void OmemoHandleMessageQueue();
+ void OmemoHandleDeviceList(const TiXmlElement *node);
+ void OmemoInitDevice();
+ void OmemoAnnounceDevice();
+ void OmemoSendBundle();
+ void OmemoPublishNodes();
+ bool OmemoCheckSession(MCONTACT hContact);
+ int OmemoEncryptMessage(XmlNode &msg, const char *msg_text, MCONTACT hContact);
+ bool OmemoIsEnabled(MCONTACT hContact);
+ void OmemoOnIqResultGetBundle(const TiXmlElement *iqNode, CJabberIqInfo *pInfo);
+
+ omemo::omemo_impl m_omemo;
+
//---- jabber_password.cpp --------------------------------------------------------------
INT_PTR __cdecl OnMenuHandleChangePassword(WPARAM wParam, LPARAM lParam);
diff --git a/protocols/JabberG/src/jabber_thread.cpp b/protocols/JabberG/src/jabber_thread.cpp index 30a2128c29..57b3727c90 100755 --- a/protocols/JabberG/src/jabber_thread.cpp +++ b/protocols/JabberG/src/jabber_thread.cpp @@ -1078,6 +1078,8 @@ 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.
@@ -1124,6 +1126,20 @@ 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 (auto *xmlDelay = XmlGetChildByTag(xmlForwarded, "delay", "xmlns", JABBER_FEAT_DELAY)) {
+ if (auto *ptszTimeStamp = XmlGetAttr(xmlDelay, "stamp"))
+ msgTime = JabberIsoToUnixTime(ptszTimeStamp);
+ }
+ }
+ }
}
MCONTACT hContact = HContactFromJID(from);
@@ -1168,15 +1184,14 @@ void CJabberProto::OnProcessMessage(const TiXmlElement *node, ThreadData *info) // check MAM support
const char *szMsgId = nullptr;
if (auto *n = XmlGetChildByTag(node, "stanza-id", "xmlns", JABBER_FEAT_SID))
- szMsgId = n->GetText();
+ if (szMsgId = n->Attribute("id"))
+ setString("LastMamId", szMsgId);
// If message is from a stranger (not in roster), item is nullptr
JABBER_LIST_ITEM *item = ListGetItemPtr(LIST_ROSTER, from);
if (item == nullptr)
item = ListGetItemPtr(LIST_VCARD_TEMP, from);
- time_t msgTime = 0;
-
// check chatstates availability
if (pFromResource && XmlGetChildByTag(node, "active", "xmlns", JABBER_FEAT_CHATSTATES))
pFromResource->m_jcbManualDiscoveredCaps |= JABBER_CAPS_CHATSTATES;
@@ -1370,6 +1385,12 @@ void CJabberProto::OnProcessMessage(const TiXmlElement *node, ThreadData *info) return;
}
+ // we ignore messages without server id either if MAM is enabled
+ if ((info->jabberServerCaps & JABBER_CAPS_MAM) && m_iMamMode != 0 && szMsgId == nullptr) {
+ debugLogA("MAM is enabled, but there's no stanza-id: ignoting a message");
+ return;
+ }
+
szMessage.Replace("\n", "\r\n");
if (item != nullptr) {
diff --git a/protocols/JabberG/src/resource.h b/protocols/JabberG/src/resource.h index a3e3f5987f..ae97f821f8 100644 --- a/protocols/JabberG/src/resource.h +++ b/protocols/JabberG/src/resource.h @@ -114,9 +114,10 @@ #define IDC_MSGLANG 1049
#define IDC_PASSWORD 1050
#define IDC_JID 1051
-#define IDC_NEWPASSWD2 1052
#define IDC_ROSTER_SYNC 1052
#define IDC_OLDPASSWD 1053
+#define IDC_MAM_MODE 1054
+#define IDC_NEWPASSWD2 1055
#define IDC_ADDRESS1 1056
#define IDC_ADDRESS2 1057
#define IDC_CITY 1058
|