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 | 26 | ||||
-rw-r--r-- | src/irc/irc_client.hpp | 5 |
4 files changed, 30 insertions, 7 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..6813bba 100644 --- a/src/irc/irc_client.cpp +++ b/src/irc/irc_client.cpp @@ -14,6 +14,7 @@ #include <sstream> #include <iostream> #include <stdexcept> +#include <algorithm> #include <cstring> #include <chrono> @@ -66,6 +67,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 +115,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}}}, @@ -131,7 +132,7 @@ 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 +339,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 +451,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 @@ -1014,6 +1020,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 diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 1b4d892..4b942ad 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,7 +23,7 @@ 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, @@ -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 |