From ac42d6d50636db69e56623b4b8093a5993c829d1 Mon Sep 17 00:00:00 2001 From: Vladimir Date: Mon, 29 Jan 2018 17:56:07 +0300 Subject: Carbons support attempt --- protocols/JabberG/src/jabber_caps.cpp | 1 + protocols/JabberG/src/jabber_caps.h | 4 +++ protocols/JabberG/src/jabber_iqid.cpp | 3 ++ protocols/JabberG/src/jabber_proto.h | 2 ++ protocols/JabberG/src/jabber_thread.cpp | 53 +++++++++++++++++++++++++++++++++ 5 files changed, 63 insertions(+) (limited to 'protocols/JabberG') diff --git a/protocols/JabberG/src/jabber_caps.cpp b/protocols/JabberG/src/jabber_caps.cpp index 4b99b77219..83a13dcd39 100755 --- a/protocols/JabberG/src/jabber_caps.cpp +++ b/protocols/JabberG/src/jabber_caps.cpp @@ -76,6 +76,7 @@ const JabberFeatCapPair g_JabberFeatCapPairs[] = { { JABBER_FEAT_ROSTER_EXCHANGE, JABBER_CAPS_ROSTER_EXCHANGE, LPGENW("Supports Roster Exchange") }, { JABBER_FEAT_DIRECT_MUC_INVITE, JABBER_CAPS_DIRECT_MUC_INVITE, LPGENW("Supports direct chat invitations (XEP-0249)") }, { JABBER_FEAT_OMEMO_DEVICELIST_NOTIFY, JABBER_CAPS_OMEMO_DEVICELIST_NOTIFY, LPGENW("Receives information about OMEMO devices") }, + { JABBER_FEAT_CARBONS, JABBER_CAPS_CARBONS, LPGENW("Supports message carbons (XEP-0280)")}, { nullptr } }; diff --git a/protocols/JabberG/src/jabber_caps.h b/protocols/JabberG/src/jabber_caps.h index 66f033119d..fe69024b21 100755 --- a/protocols/JabberG/src/jabber_caps.h +++ b/protocols/JabberG/src/jabber_caps.h @@ -154,6 +154,9 @@ typedef unsigned __int64 JabberCapsBits; #define JABBER_FEAT_PUBSUB_EVENT L"http://jabber.org/protocol/pubsub#event" #define JABBER_FEAT_PUBSUB_NODE_CONFIG L"http://jabber.org/protocol/pubsub#node_config" +#define JABBER_FEAT_CARBONS L"urn:xmpp:carbons:2" +#define JABBER_CAPS_CARBONS ((JabberCapsBits)1<<43) + #define JABBER_CAPS_MESSAGE_EVENTS_NO_DELIVERY ((JabberCapsBits)1<<63) #define JABBER_CAPS_OTHER_SPECIAL (JABBER_CAPS_MESSAGE_EVENTS_NO_DELIVERY|JABBER_RESOURCE_CAPS_ERROR) // must contain all the caps not listed in g_JabberFeatCapPairs, to prevent using these bits for features registered through IJabberNetInterface::RegisterFeature() @@ -168,6 +171,7 @@ typedef unsigned __int64 JabberCapsBits; 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 L"urn:xmpp:forward:0" #define JABBER_EXT_SECUREIM L"secureim" #define JABBER_EXT_MIROTR L"mirotr" diff --git a/protocols/JabberG/src/jabber_iqid.cpp b/protocols/JabberG/src/jabber_iqid.cpp index da7c1260f6..4ecac9d48e 100755 --- a/protocols/JabberG/src/jabber_iqid.cpp +++ b/protocols/JabberG/src/jabber_iqid.cpp @@ -135,6 +135,9 @@ void CJabberProto::OnProcessLoginRq(ThreadData *info, DWORD rq) if (info->jabberServerCaps & JABBER_CAPS_ARCHIVE_AUTO) EnableArchive(m_options.EnableMsgArchive != 0); + if (info->jabberServerCaps & JABBER_CAPS_CARBONS) + EnableCarbons(true); + if (m_options.AutoJoinBookmarks) { LIST ll(10); LISTFOREACH(i, this, LIST_BOOKMARK) diff --git a/protocols/JabberG/src/jabber_proto.h b/protocols/JabberG/src/jabber_proto.h index b04f639967..350b5e438c 100755 --- a/protocols/JabberG/src/jabber_proto.h +++ b/protocols/JabberG/src/jabber_proto.h @@ -737,6 +737,8 @@ struct CJabberProto : public PROTO, public IJabberInterface bool ProcessCaptcha(HXML node, HXML parentNode, ThreadData *info); + void EnableCarbons(bool bEnable); + //---- jabber_util.c ----------------------------------------------------------------- pResourceStatus ResourceInfoFromJID(const wchar_t *jid); diff --git a/protocols/JabberG/src/jabber_thread.cpp b/protocols/JabberG/src/jabber_thread.cpp index 60cf077661..1177020ab0 100755 --- a/protocols/JabberG/src/jabber_thread.cpp +++ b/protocols/JabberG/src/jabber_thread.cpp @@ -1051,6 +1051,43 @@ void CJabberProto::OnProcessMessage(HXML node, ThreadData *info) if (m_messageManager.HandleMessagePermanent(node, info)) return; + //Handle carbons. The message MUST be coming from our bare JID. + HXML carbon = nullptr; + bool carbonSent = false; //2 cases: received or sent. + if (this->IsMyOwnJID(from)) { + carbon = XmlGetChildByTag(node, "received", "xmlns", JABBER_FEAT_CARBONS); + if (!carbon) { + carbon = XmlGetChildByTag(node, "sent", "xmlns", JABBER_FEAT_CARBONS); + if (carbon) + carbonSent = true; + } + if (carbon) { + HXML forwarded = NULL; + HXML message = NULL; + //Carbons MUST have forwarded/message content + if (!(forwarded = XmlGetChildByTag(carbon, "forwarded", "xmlns", JABBER_XMLNS_FORWARD)) + || !(message = XmlGetChild(forwarded, "message"))) + return; + + //Unwrap the carbon in any case + node = message; + type = XmlGetAttrValue(node, L"type"); + + if (!carbonSent) { + //Received should just be treated like incoming messages, except maybe not flash the flasher. Simply unwrap. + from = XmlGetAttrValue(node, L"from"); + if (from == nullptr) + return; + } + else { + //Sent should set SENT flag and invert from/to. + from = XmlGetAttrValue(node, L"to"); + if (from == nullptr) + return; + } + } + } + MCONTACT hContact = HContactFromJID(from); JABBER_LIST_ITEM *chatItem = ListGetItemPtr(LIST_CHATROOM, from); if (chatItem) { @@ -1416,6 +1453,11 @@ void CJabberProto::OnProcessMessage(HXML node, ThreadData *info) msgTime = now; PROTORECVEVENT recv = { 0 }; + if (carbon) { + recv.flags |= PREF_CREATEREAD; + if (carbonSent) + recv.flags |= PREF_SENT; + } recv.timestamp = (DWORD)msgTime; recv.szMessage = buf; recv.lParam = (LPARAM)((pFromResource != nullptr && m_options.EnableRemoteControl) ? pFromResource->m_tszResourceName : 0); @@ -1941,6 +1983,17 @@ void CJabberProto::OnProcessRegIq(HXML node, ThreadData *info) } } + +///////////////////////////////////////////////////////////////////////////////////////// +// Carbons -- this might need to go into its own module + +void CJabberProto::EnableCarbons(bool bEnable) +{ + m_ThreadInfo->send(XmlNodeIq(L"set", SerialNext()) + << XCHILDNS((bEnable) ? L"enable" : L"disable", JABBER_FEAT_CARBONS)); +} + + ///////////////////////////////////////////////////////////////////////////////////////// // ThreadData constructor & destructor -- cgit v1.2.3