Implement the Bridge class to translate between the two protocols
Add all useful classes as well: Jid, Iid, IrcChannel, IrcUser etc to properly keep the informations about what we receive from the IRC server. Only handle the MUC join stanza, and send the list of users in the IRC channel to the XMPP user, and the IRC channel’s topic, for now.
This commit is contained in:
+107
-3
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user