diff options
Diffstat (limited to 'src/irc')
-rw-r--r-- | src/irc/iid.cpp | 4 | ||||
-rw-r--r-- | src/irc/iid.hpp | 1 | ||||
-rw-r--r-- | src/irc/irc_client.cpp | 59 | ||||
-rw-r--r-- | src/irc/irc_client.hpp | 32 |
4 files changed, 89 insertions, 7 deletions
diff --git a/src/irc/iid.cpp b/src/irc/iid.cpp index ffc8d88..4694c0c 100644 --- a/src/irc/iid.cpp +++ b/src/irc/iid.cpp @@ -15,3 +15,7 @@ Iid::Iid(const std::string& iid) } this->server = iid.substr(sep); } + +Iid::Iid() +{ +} diff --git a/src/irc/iid.hpp b/src/irc/iid.hpp index aacc9e6..a62ac71 100644 --- a/src/irc/iid.hpp +++ b/src/irc/iid.hpp @@ -20,6 +20,7 @@ class Iid { public: explicit Iid(const std::string& iid); + explicit Iid(); std::string chan; std::string server; diff --git a/src/irc/irc_client.cpp b/src/irc/irc_client.cpp index 7875b1c..cf57bd7 100644 --- a/src/irc/irc_client.cpp +++ b/src/irc/irc_client.cpp @@ -12,7 +12,9 @@ IrcClient::IrcClient(const std::string& hostname, const std::string& username, Bridge* bridge): hostname(hostname), username(username), - bridge(bridge) + current_nick(username), + bridge(bridge), + welcomed(false) { std::cout << "IrcClient()" << std::endl; } @@ -51,6 +53,11 @@ IrcChannel* IrcClient::get_channel(const std::string& name) } } +std::string IrcClient::get_own_nick() const +{ + return this->current_nick; +} + void IrcClient::parse_in_buffer() { while (true) @@ -63,19 +70,23 @@ void IrcClient::parse_in_buffer() std::cout << message << std::endl; // TODO map function and command name properly if (message.command == "PING") - this->send_pong_command(); + this->send_pong_command(message); 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 == "PRIVMSG") + this->on_channel_message(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); + else if (message.command == "001") + this->on_welcome_message(message); } } @@ -102,7 +113,7 @@ void IrcClient::send_message(IrcMessage&& message) void IrcClient::send_user_command(const std::string& username, const std::string& realname) { - this->send_message(IrcMessage("USER", {username, "NONE", "NONE", realname})); + this->send_message(IrcMessage("USER", {username, "ignored", "ignored", realname})); } void IrcClient::send_nick_command(const std::string& nick) @@ -112,14 +123,32 @@ void IrcClient::send_nick_command(const std::string& nick) void IrcClient::send_join_command(const std::string& chan_name) { + if (this->welcomed == false) + { + this->channels_to_join.push_back(chan_name); + return ; + } IrcChannel* channel = this->get_channel(chan_name); if (channel->joined == false) this->send_message(IrcMessage("JOIN", {chan_name})); } -void IrcClient::send_pong_command() +bool IrcClient::send_channel_message(const std::string& chan_name, const std::string& body) { - this->send_message(IrcMessage("PONG", {})); + IrcChannel* channel = this->get_channel(chan_name); + if (channel->joined == false) + { + std::cout << "Cannot send message to channel " << chan_name << ", it is not joined" << std::endl; + return false; + } + this->send_message(IrcMessage("PRIVMSG", {chan_name, body})); + return true; +} + +void IrcClient::send_pong_command(const IrcMessage& message) +{ + const std::string id = message.arguments[0]; + this->send_message(IrcMessage("PONG", {id})); } void IrcClient::forward_server_message(const IrcMessage& message) @@ -154,6 +183,17 @@ void IrcClient::on_self_channel_join(const IrcMessage& message) channel->set_self(message.prefix); } +void IrcClient::on_channel_message(const IrcMessage& message) +{ + const IrcUser user(message.prefix); + const std::string nick = user.nick; + Iid iid; + iid.chan = message.arguments[0]; + iid.server = this->hostname; + const std::string body = message.arguments[1]; + this->bridge->send_muc_message(iid, nick, body); +} + void IrcClient::on_topic_received(const IrcMessage& message) { const std::string chan_name = message.arguments[1]; @@ -168,3 +208,12 @@ void IrcClient::on_channel_completely_joined(const IrcMessage& message) this->bridge->send_self_join(this->hostname, chan_name, channel->get_self()->nick); this->bridge->send_topic(this->hostname, chan_name, channel->topic); } + +void IrcClient::on_welcome_message(const IrcMessage& message) +{ + this->current_nick = message.arguments[0]; + this->welcomed = true; + for (const std::string& chan_name: this->channels_to_join) + this->send_join_command(chan_name); + this->channels_to_join.clear(); +} diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index db1b83b..50f3781 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -45,6 +45,10 @@ public: */ IrcChannel* get_channel(const std::string& name); /** + * Return our own nick + */ + std::string get_own_nick() const; + /** * Serialize the given message into a line, and send that into the socket * (actually, into our out_buf and signal the poller that we want to wach * for send events to be ready) @@ -53,7 +57,7 @@ public: /** * Send the PONG irc command */ - void send_pong_command(); + void send_pong_command(const IrcMessage& message); /** * Send the USER irc command */ @@ -67,6 +71,11 @@ public: */ void send_join_command(const std::string& chan_name); /** + * Send a PRIVMSG command for a channel + * Return true if the message was actually sent + */ + bool send_channel_message(const std::string& chan_name, const std::string& body); + /** * Forward the server message received from IRC to the XMPP component */ void forward_server_message(const IrcMessage& message); @@ -81,6 +90,10 @@ public: */ void on_self_channel_join(const IrcMessage& message); /** + * When a channel message is received + */ + void on_channel_message(const IrcMessage& message); + /** * Save the topic in the IrcChannel */ void on_topic_received(const IrcMessage& message); @@ -89,6 +102,10 @@ public: * received etc), send the self presence and topic to the XMPP user. */ void on_channel_completely_joined(const IrcMessage& message); + /** + * When a message 001 is received, join the rooms we wanted to join, and set our actual nickname + */ + void on_welcome_message(const IrcMessage& message); private: /** @@ -100,14 +117,25 @@ private: */ const std::string username; /** + * Our current nickname on the server + */ + std::string current_nick; + /** * Raw pointer because the bridge owns us. */ Bridge* bridge; - /** * The list of joined channels, indexed by name */ std::unordered_map<std::string, std::unique_ptr<IrcChannel>> channels; + /** + * A list of chan we want to join, but we need a response 001 from + * the server before sending the actual JOIN commands. So we just keep the + * channel names in a list, and send the JOIN commands for each of them + * whenever the WELCOME message is received. + */ + std::vector<std::string> channels_to_join; + bool welcomed; IrcClient(const IrcClient&) = delete; IrcClient(IrcClient&&) = delete; |