diff options
Diffstat (limited to 'src/irc/irc_client.cpp')
-rw-r--r-- | src/irc/irc_client.cpp | 105 |
1 files changed, 102 insertions, 3 deletions
diff --git a/src/irc/irc_client.cpp b/src/irc/irc_client.cpp index 80f36ee..7875b1c 100644 --- a/src/irc/irc_client.cpp +++ b/src/irc/irc_client.cpp @@ -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); } |