diff options
Diffstat (limited to 'src/xmpp/xmpp_component.cpp')
-rw-r--r-- | src/xmpp/xmpp_component.cpp | 110 |
1 files changed, 107 insertions, 3 deletions
diff --git a/src/xmpp/xmpp_component.cpp b/src/xmpp/xmpp_component.cpp index 0563aa7..3a288c7 100644 --- a/src/xmpp/xmpp_component.cpp +++ b/src/xmpp/xmpp_component.cpp @@ -1,4 +1,7 @@ +#include <utils/make_unique.hpp> + #include <xmpp/xmpp_component.hpp> +#include <xmpp/jid.hpp> #include <iostream> @@ -20,6 +23,8 @@ XmppComponent::XmppComponent(const std::string& hostname, const std::string& sec std::placeholders::_1)); this->stanza_handlers.emplace("handshake", std::bind(&XmppComponent::handle_handshake, this,std::placeholders::_1)); + this->stanza_handlers.emplace("presence", + std::bind(&XmppComponent::handle_presence, this,std::placeholders::_1)); } XmppComponent::~XmppComponent() @@ -46,7 +51,6 @@ void XmppComponent::on_connected() node["xmlns:stream"] = "http://etherx.jabber.org/streams"; node["to"] = "irc.abricot"; this->send_stanza(node); - } void XmppComponent::on_connection_close() @@ -99,16 +103,17 @@ void XmppComponent::on_stanza(const Stanza& stanza) { std::cout << "=========== STANZA ============" << std::endl; std::cout << stanza.to_string() << std::endl; + std::function<void(const Stanza&)> handler; try { - const auto& handler = this->stanza_handlers.at(stanza.get_name()); - handler(stanza); + handler = this->stanza_handlers.at(stanza.get_name()); } catch (const std::out_of_range& exception) { std::cout << "No handler for stanza of type " << stanza.get_name() << std::endl; return; } + handler(stanza); } void XmppComponent::send_stream_error(const std::string& name, const std::string& explanation) @@ -133,5 +138,104 @@ void XmppComponent::close_document() void XmppComponent::handle_handshake(const Stanza& stanza) { + (void)stanza; this->authenticated = true; } + +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); +} + +Bridge* XmppComponent::get_user_bridge(const std::string& user_jid) +{ + try + { + return this->bridges.at(user_jid).get(); + } + catch (const std::out_of_range& exception) + { + this->bridges.emplace(user_jid, std::make_unique<Bridge>(user_jid, this, this->poller)); + return this->bridges.at(user_jid).get(); + } +} + +void XmppComponent::send_message(const std::string& from, const std::string& body, const std::string& to) +{ + XmlNode node("message"); + node["to"] = to; + node["from"] = from + "@" + this->served_hostname; + XmlNode body_node("body"); + body_node.set_inner(body); + body_node.close(); + node.add_child(std::move(body_node)); + node.close(); + this->send_stanza(node); +} + +void XmppComponent::send_user_join(const std::string& from, const std::string& nick, const std::string& to) +{ + XmlNode node("presence"); + node["to"] = to; + node["from"] = from + "@" + this->served_hostname + "/" + nick; + + XmlNode x("x"); + x["xmlns"] = "http://jabber.org/protocol/muc#user"; + + // TODO: put real values here + XmlNode item("item"); + item["affiliation"] = "member"; + item["role"] = "participant"; + item.close(); + x.add_child(std::move(item)); + x.close(); + node.add_child(std::move(x)); + node.close(); + this->send_stanza(node); +} + +void XmppComponent::send_self_join(const std::string& from, const std::string& nick, const std::string& to) +{ + XmlNode node("presence"); + node["to"] = to; + node["from"] = from + "@" + this->served_hostname + "/" + nick; + + XmlNode x("x"); + x["xmlns"] = "http://jabber.org/protocol/muc#user"; + + // TODO: put real values here + XmlNode item("item"); + item["affiliation"] = "member"; + item["role"] = "participant"; + item.close(); + x.add_child(std::move(item)); + + XmlNode status("status"); + status["code"] = "110"; + status.close(); + x.add_child(std::move(status)); + + x.close(); + + node.add_child(std::move(x)); + node.close(); + this->send_stanza(node); +} + +void XmppComponent::send_topic(const std::string& from, const std::string& topic, const std::string& to) +{ + XmlNode message("message"); + message["to"] = to; + message["from"] = from + "@" + this->served_hostname; + message["type"] = "groupchat"; + XmlNode subject("subject"); + subject.set_inner(topic); + subject.close(); + message.add_child(std::move(subject)); + message.close(); + this->send_stanza(message); +} |