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:
+102
-3
@@ -1,10 +1,18 @@
|
||||
#include <irc/irc_client.hpp>
|
||||
#include <irc/irc_message.hpp>
|
||||
#include <irc/irc_client.hpp>
|
||||
#include <bridge/bridge.hpp>
|
||||
#include <irc/irc_user.hpp>
|
||||
|
||||
#include <utils/make_unique.hpp>
|
||||
#include <utils/split.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
IrcClient::IrcClient()
|
||||
IrcClient::IrcClient(const std::string& hostname, const std::string& username, Bridge* bridge):
|
||||
hostname(hostname),
|
||||
username(username),
|
||||
bridge(bridge)
|
||||
{
|
||||
std::cout << "IrcClient()" << std::endl;
|
||||
}
|
||||
@@ -14,8 +22,15 @@ IrcClient::~IrcClient()
|
||||
std::cout << "~IrcClient()" << std::endl;
|
||||
}
|
||||
|
||||
void IrcClient::start()
|
||||
{
|
||||
this->connect(this->hostname, "6667");
|
||||
}
|
||||
|
||||
void IrcClient::on_connected()
|
||||
{
|
||||
this->send_nick_command(this->username);
|
||||
this->send_user_command(this->username, this->username);
|
||||
}
|
||||
|
||||
void IrcClient::on_connection_close()
|
||||
@@ -23,6 +38,19 @@ void IrcClient::on_connection_close()
|
||||
std::cout << "Connection closed by remote server." << std::endl;
|
||||
}
|
||||
|
||||
IrcChannel* IrcClient::get_channel(const std::string& name)
|
||||
{
|
||||
try
|
||||
{
|
||||
return this->channels.at(name).get();
|
||||
}
|
||||
catch (const std::out_of_range& exception)
|
||||
{
|
||||
this->channels.emplace(name, std::make_unique<IrcChannel>());
|
||||
return this->channels.at(name).get();
|
||||
}
|
||||
}
|
||||
|
||||
void IrcClient::parse_in_buffer()
|
||||
{
|
||||
while (true)
|
||||
@@ -33,6 +61,21 @@ void IrcClient::parse_in_buffer()
|
||||
IrcMessage message(this->in_buf.substr(0, pos));
|
||||
this->in_buf = this->in_buf.substr(pos + 2, std::string::npos);
|
||||
std::cout << message << std::endl;
|
||||
// TODO map function and command name properly
|
||||
if (message.command == "PING")
|
||||
this->send_pong_command();
|
||||
else if (message.command == "NOTICE" ||
|
||||
message.command == "375" ||
|
||||
message.command == "372")
|
||||
this->forward_server_message(message);
|
||||
else if (message.command == "JOIN")
|
||||
this->on_self_channel_join(message);
|
||||
else if (message.command == "353")
|
||||
this->set_and_forward_user_list(message);
|
||||
else if (message.command == "332")
|
||||
this->on_topic_received(message);
|
||||
else if (message.command == "366")
|
||||
this->on_channel_completely_joined(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +95,8 @@ void IrcClient::send_message(IrcMessage&& message)
|
||||
res += " " + arg;
|
||||
}
|
||||
res += "\r\n";
|
||||
std::cout << "=== IRC SENDING ===" << std::endl;
|
||||
std::cout << res << std::endl;
|
||||
this->send_data(std::move(res));
|
||||
}
|
||||
|
||||
@@ -67,5 +112,59 @@ void IrcClient::send_nick_command(const std::string& nick)
|
||||
|
||||
void IrcClient::send_join_command(const std::string& chan_name)
|
||||
{
|
||||
this->send_message(IrcMessage("JOIN", {chan_name}));
|
||||
IrcChannel* channel = this->get_channel(chan_name);
|
||||
if (channel->joined == false)
|
||||
this->send_message(IrcMessage("JOIN", {chan_name}));
|
||||
}
|
||||
|
||||
void IrcClient::send_pong_command()
|
||||
{
|
||||
this->send_message(IrcMessage("PONG", {}));
|
||||
}
|
||||
|
||||
void IrcClient::forward_server_message(const IrcMessage& message)
|
||||
{
|
||||
const std::string from = message.prefix;
|
||||
const std::string body = message.arguments[1];
|
||||
|
||||
this->bridge->send_xmpp_message(this->hostname, from, body);
|
||||
}
|
||||
|
||||
void IrcClient::set_and_forward_user_list(const IrcMessage& message)
|
||||
{
|
||||
const std::string chan_name = message.arguments[2];
|
||||
IrcChannel* channel = this->get_channel(chan_name);
|
||||
std::vector<std::string> nicks = utils::split(message.arguments[3], ' ');
|
||||
for (const std::string& nick: nicks)
|
||||
{
|
||||
IrcUser* user = channel->add_user(nick);
|
||||
if (user->nick != channel->get_self()->nick)
|
||||
{
|
||||
std::cout << "Adding user [" << nick << "] to chan " << chan_name << std::endl;
|
||||
this->bridge->send_user_join(this->hostname, chan_name, user->nick);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IrcClient::on_self_channel_join(const IrcMessage& message)
|
||||
{
|
||||
const std::string chan_name = message.arguments[0];
|
||||
IrcChannel* channel = this->get_channel(chan_name);
|
||||
channel->joined = true;
|
||||
channel->set_self(message.prefix);
|
||||
}
|
||||
|
||||
void IrcClient::on_topic_received(const IrcMessage& message)
|
||||
{
|
||||
const std::string chan_name = message.arguments[1];
|
||||
IrcChannel* channel = this->get_channel(chan_name);
|
||||
channel->topic = message.arguments[2];
|
||||
}
|
||||
|
||||
void IrcClient::on_channel_completely_joined(const IrcMessage& message)
|
||||
{
|
||||
const std::string chan_name = message.arguments[1];
|
||||
IrcChannel* channel = this->get_channel(chan_name);
|
||||
this->bridge->send_self_join(this->hostname, chan_name, channel->get_self()->nick);
|
||||
this->bridge->send_topic(this->hostname, chan_name, channel->topic);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user