diff options
Diffstat (limited to 'src/irc')
-rw-r--r-- | src/irc/iid.cpp | 5 | ||||
-rw-r--r-- | src/irc/iid.hpp | 1 | ||||
-rw-r--r-- | src/irc/irc_client.cpp | 49 | ||||
-rw-r--r-- | src/irc/irc_client.hpp | 11 | ||||
-rw-r--r-- | src/irc/irc_message.cpp | 6 | ||||
-rw-r--r-- | src/irc/irc_user.cpp | 2 | ||||
-rw-r--r-- | src/irc/irc_user.hpp | 2 |
7 files changed, 45 insertions, 31 deletions
diff --git a/src/irc/iid.cpp b/src/irc/iid.cpp index d442013..6b07793 100644 --- a/src/irc/iid.cpp +++ b/src/irc/iid.cpp @@ -34,9 +34,10 @@ Iid::Iid(const std::string& iid, const Bridge *bridge) void Iid::set_type(const std::set<char>& chantypes) { + if (this->local.empty() && this->server.empty()) + this->type = Iid::Type::None; if (this->local.empty()) return; - if (chantypes.count(this->local[0]) == 1) this->type = Iid::Type::Channel; else @@ -105,6 +106,8 @@ namespace std { { if (iid.type == Iid::Type::Server) return iid.get_server(); + else if (iid.get_local().empty() && iid.get_server().empty()) + return {}; else return iid.get_encoded_local() + iid.separator + iid.get_server(); } diff --git a/src/irc/iid.hpp b/src/irc/iid.hpp index 44861c1..81cf3ca 100644 --- a/src/irc/iid.hpp +++ b/src/irc/iid.hpp @@ -53,6 +53,7 @@ public: Channel, User, Server, + None, }; static constexpr char separator[]{"%"}; Iid(const std::string& iid, const std::set<char>& chantypes); diff --git a/src/irc/irc_client.cpp b/src/irc/irc_client.cpp index b0d3a47..48b105d 100644 --- a/src/irc/irc_client.cpp +++ b/src/irc/irc_client.cpp @@ -14,13 +14,13 @@ #include <sstream> #include <iostream> #include <stdexcept> +#include <algorithm> #include <cstring> #include <chrono> #include <string> #include "biboumi.h" -#include "louloulibs.h" using namespace std::string_literals; using namespace std::chrono_literals; @@ -66,6 +66,7 @@ static const std::unordered_map<std::string, {"433", {&IrcClient::on_nickname_conflict, {2, 0}}}, {"438", {&IrcClient::on_nickname_change_too_fast, {2, 0}}}, {"443", {&IrcClient::on_useronchannel, {3, 0}}}, + {"475", {&IrcClient::on_channel_bad_key, {3, 0}}}, {"ERR_USERONCHANNEL", {&IrcClient::on_useronchannel, {3, 0}}}, {"001", {&IrcClient::on_welcome_message, {1, 0}}}, {"PART", {&IrcClient::on_part, {1, 0}}}, @@ -113,7 +114,6 @@ static const std::unordered_map<std::string, {"472", {&IrcClient::on_generic_error, {2, 0}}}, {"473", {&IrcClient::on_generic_error, {2, 0}}}, {"474", {&IrcClient::on_generic_error, {2, 0}}}, - {"475", {&IrcClient::on_generic_error, {2, 0}}}, {"476", {&IrcClient::on_generic_error, {2, 0}}}, {"477", {&IrcClient::on_generic_error, {2, 0}}}, {"481", {&IrcClient::on_generic_error, {2, 0}}}, @@ -127,11 +127,11 @@ static const std::unordered_map<std::string, {"502", {&IrcClient::on_generic_error, {2, 0}}}, }; -IrcClient::IrcClient(std::shared_ptr<Poller> poller, const std::string& hostname, +IrcClient::IrcClient(std::shared_ptr<Poller>& poller, const std::string& hostname, const std::string& nickname, const std::string& username, const std::string& realname, const std::string& user_hostname, Bridge& bridge): - TCPSocketHandler(poller), + TCPClientSocketHandler(poller), hostname(hostname), user_hostname(user_hostname), username(username), @@ -338,7 +338,7 @@ void IrcClient::parse_in_buffer(const size_t) if (pos == std::string::npos) break ; IrcMessage message(this->in_buf.substr(0, pos)); - this->in_buf = this->in_buf.substr(pos + 2, std::string::npos); + this->consume_in_buffer(pos + 2); log_debug("IRC RECEIVING: (", this->get_hostname(), ") ", message); // Call the standard callback (if any), associated with the command @@ -450,7 +450,12 @@ void IrcClient::send_quit_command(const std::string& reason) void IrcClient::send_join_command(const std::string& chan_name, const std::string& password) { if (this->welcomed == false) - this->channels_to_join.emplace_back(chan_name, password); + { + const auto it = std::find_if(begin(this->channels_to_join), end(this->channels_to_join), + [&chan_name](const auto& pair) { return std::get<0>(pair) == chan_name; }); + if (it == end(this->channels_to_join)) + this->channels_to_join.emplace_back(chan_name, password); + } else if (password.empty()) this->send_message(IrcMessage("JOIN", {chan_name})); else @@ -496,15 +501,7 @@ void IrcClient::send_private_message(const std::string& username, const std::str void IrcClient::send_part_command(const std::string& chan_name, const std::string& status_message) { - IrcChannel* channel = this->get_channel(chan_name); - if (channel->joined == true) - { - if (chan_name.empty()) - this->leave_dummy_channel(status_message); - else - this->send_message(IrcMessage("PART", {chan_name, status_message})); - channel->parting = true; - } + this->send_message(IrcMessage("PART", {chan_name, status_message})); } void IrcClient::send_mode_command(const std::string& chan_name, const std::vector<std::string>& arguments) @@ -891,7 +888,7 @@ void IrcClient::on_part(const IrcMessage& message) // channel pointer is now invalid channel = nullptr; } - this->bridge.send_muc_leave(std::move(iid), std::move(nick), std::move(txt), self); + this->bridge.send_muc_leave(iid, std::move(nick), std::move(txt), self); } } @@ -909,7 +906,7 @@ void IrcClient::on_error(const IrcMessage& message) if (!channel->joined) continue; std::string own_nick = channel->get_self()->nick; - this->bridge.send_muc_leave(std::move(iid), std::move(own_nick), leave_message, true); + this->bridge.send_muc_leave(iid, std::move(own_nick), leave_message, true); } this->channels.clear(); this->send_gateway_message("ERROR: "s + leave_message); @@ -933,7 +930,7 @@ void IrcClient::on_quit(const IrcMessage& message) iid.set_local(chan_name); iid.set_server(this->hostname); iid.type = Iid::Type::Channel; - this->bridge.send_muc_leave(std::move(iid), std::move(nick), txt, false); + this->bridge.send_muc_leave(iid, std::move(nick), txt, false); } } } @@ -1014,6 +1011,18 @@ void IrcClient::on_mode(const IrcMessage& message) this->on_user_mode(message); } +void IrcClient::on_channel_bad_key(const IrcMessage& message) +{ + this->on_generic_error(message); + const std::string& nickname = message.arguments[0]; + const std::string& channel = message.arguments[1]; + std::string text; + if (message.arguments.size() > 2) + text = message.arguments[2]; + + this->bridge.send_presence_error({channel, this->hostname, Iid::Type::Channel}, nickname, "auth", "not-authorized", "", text); +} + void IrcClient::on_channel_mode(const IrcMessage& message) { // For now, just transmit the modes so the user can know what happens @@ -1143,14 +1152,14 @@ DummyIrcChannel& IrcClient::get_dummy_channel() return this->dummy_channel; } -void IrcClient::leave_dummy_channel(const std::string& exit_message) +void IrcClient::leave_dummy_channel(const std::string& exit_message, const std::string& resource) { if (!this->dummy_channel.joined) return; this->dummy_channel.joined = false; this->dummy_channel.joining = false; this->dummy_channel.remove_all_users(); - this->bridge.send_muc_leave(Iid("%"s + this->hostname, this->chantypes), std::string(this->current_nick), exit_message, true); + this->bridge.send_muc_leave(Iid("%"s + this->hostname, this->chantypes), std::string(this->current_nick), exit_message, true, resource); } #ifdef BOTAN_FOUND diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 1b4d892..8119201 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -5,7 +5,7 @@ #include <irc/irc_channel.hpp> #include <irc/iid.hpp> -#include <network/tcp_socket_handler.hpp> +#include <network/tcp_client_socket_handler.hpp> #include <network/resolver.hpp> #include <unordered_map> @@ -23,10 +23,10 @@ class Bridge; * Represent one IRC client, i.e. an endpoint connected to a single IRC * server, through a TCP socket, receiving and sending commands to it. */ -class IrcClient: public TCPSocketHandler +class IrcClient: public TCPClientSocketHandler { public: - explicit IrcClient(std::shared_ptr<Poller> poller, const std::string& hostname, + explicit IrcClient(std::shared_ptr<Poller>& poller, const std::string& hostname, const std::string& nickname, const std::string& username, const std::string& realname, const std::string& user_hostname, Bridge& bridge); @@ -52,7 +52,7 @@ public: /** * Close the connection, remove us from the poller */ - void on_connection_close(const std::string& error) override final; + void on_connection_close(const std::string& error_msg) override final; /** * Parse the data we have received so far and try to get one or more * complete messages from it. @@ -257,6 +257,7 @@ public: void on_nick(const IrcMessage& message); void on_kick(const IrcMessage& message); void on_mode(const IrcMessage& message); + void on_channel_bad_key(const IrcMessage& message); /** * A mode towards our own user is received (note, that is different from a * channel mode towards or own nick, see @@ -282,7 +283,7 @@ public: * Leave the dummy channel: forward a message to the user to indicate that * he left it, and mark it as not joined. */ - void leave_dummy_channel(const std::string& exit_message); + void leave_dummy_channel(const std::string& exit_message, const std::string& resource); const std::string& get_hostname() const { return this->hostname; } std::string get_nick() const { return this->current_nick; } diff --git a/src/irc/irc_message.cpp b/src/irc/irc_message.cpp index 966a47c..14fdb0e 100644 --- a/src/irc/irc_message.cpp +++ b/src/irc/irc_message.cpp @@ -8,12 +8,12 @@ IrcMessage::IrcMessage(std::string&& line) // optional prefix if (line[0] == ':') { - pos = line.find(" "); + pos = line.find(' '); this->prefix = line.substr(1, pos - 1); line = line.substr(pos + 1, std::string::npos); } // command - pos = line.find(" "); + pos = line.find(' '); this->command = line.substr(0, pos); line = line.substr(pos + 1, std::string::npos); // arguments @@ -24,7 +24,7 @@ IrcMessage::IrcMessage(std::string&& line) this->arguments.emplace_back(line.substr(1, std::string::npos)); break ; } - pos = line.find(" "); + pos = line.find(' '); this->arguments.emplace_back(line.substr(0, pos)); line = line.substr(pos + 1, std::string::npos); } while (pos != std::string::npos); diff --git a/src/irc/irc_user.cpp b/src/irc/irc_user.cpp index 9fa3612..139015e 100644 --- a/src/irc/irc_user.cpp +++ b/src/irc/irc_user.cpp @@ -21,7 +21,7 @@ IrcUser::IrcUser(const std::string& name, name_begin++; } - const std::string::size_type sep = name.find("!", name_begin); + const std::string::size_type sep = name.find('!', name_begin); if (sep == std::string::npos) this->nick = name.substr(name_begin); else diff --git a/src/irc/irc_user.hpp b/src/irc/irc_user.hpp index c84030e..a4291d4 100644 --- a/src/irc/irc_user.hpp +++ b/src/irc/irc_user.hpp @@ -23,7 +23,7 @@ public: void add_mode(const char mode); void remove_mode(const char mode); - char get_most_significant_mode(const std::vector<char>& sorted_user_modes) const; + char get_most_significant_mode(const std::vector<char>& modes) const; std::string nick; std::string host; |