From 7c671499350e22f8bfba2f72b9827aa5b200f7b0 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Sat, 9 Nov 2013 23:17:48 +0100 Subject: Implement part and join, both ways --- src/xmpp/xmpp_component.cpp | 38 ++++++++++++++++++++++++++++++++++++-- src/xmpp/xmpp_component.hpp | 4 ++++ src/xmpp/xmpp_stanza.cpp | 2 ++ 3 files changed, 42 insertions(+), 2 deletions(-) (limited to 'src/xmpp') diff --git a/src/xmpp/xmpp_component.cpp b/src/xmpp/xmpp_component.cpp index cd9cd6f..83091ba 100644 --- a/src/xmpp/xmpp_component.cpp +++ b/src/xmpp/xmpp_component.cpp @@ -149,8 +149,22 @@ void XmppComponent::handle_presence(const Stanza& stanza) Bridge* bridge = this->get_user_bridge(stanza["from"]); Jid to(stanza["to"]); Iid iid(to.local); - if (!iid.chan.empty() && !iid.server.empty()) - bridge->join_irc_channel(iid, to.resource); + std::string type; + try { + type = stanza["type"]; + } + catch (const AttributeNotFound&) {} + + if (!iid.chan.empty() && !iid.chan.empty()) + { // presence toward a MUC that corresponds to an irc channel + if (type.empty()) + bridge->join_irc_channel(iid, to.resource); + else if (type == "unavailable") + { + XmlNode* status = stanza.get_child("status"); + bridge->leave_irc_channel(std::move(iid), status ? std::move(status->get_inner()) : ""); + } + } } void XmppComponent::handle_message(const Stanza& stanza) @@ -269,3 +283,23 @@ void XmppComponent::send_muc_message(const std::string& muc_name, const std::str message.close(); this->send_stanza(message); } + +void XmppComponent::send_muc_leave(std::string&& muc_name, std::string&& nick, std::string&& message, const std::string& jid_to, const bool self) +{ + Stanza presence("presence"); + presence["to"] = jid_to; + presence["from"] = muc_name + "@" + this->served_hostname + "/" + nick; + presence["type"] = "unavailable"; + if (!message.empty() || self) + { + XmlNode status("status"); + if (!message.empty()) + status.set_inner(std::move(message)); + if (self) + status["code"] = "110"; + status.close(); + presence.add_child(std::move(status)); + } + presence.close(); + this->send_stanza(presence); +} diff --git a/src/xmpp/xmpp_component.hpp b/src/xmpp/xmpp_component.hpp index 73eadd2..a5127a9 100644 --- a/src/xmpp/xmpp_component.hpp +++ b/src/xmpp/xmpp_component.hpp @@ -75,6 +75,10 @@ public: * Send a (non-private) message to the MUC */ void send_muc_message(const std::string& muc_name, const std::string& nick, const std::string body_str, const std::string& jid_to); + /** + * Send an unavailable presence for this nick + */ + void send_muc_leave(std::string&& muc_name, std::string&& nick, std::string&& message, const std::string& jid_to, const bool self); /** * Handle the various stanza types */ diff --git a/src/xmpp/xmpp_stanza.cpp b/src/xmpp/xmpp_stanza.cpp index d856836..ab26304 100644 --- a/src/xmpp/xmpp_stanza.cpp +++ b/src/xmpp/xmpp_stanza.cpp @@ -1,5 +1,7 @@ #include +#include + #include std::string xml_escape(const std::string& data) -- cgit v1.2.3