diff options
Diffstat (limited to 'src/irc')
-rw-r--r-- | src/irc/irc_channel.cpp | 17 | ||||
-rw-r--r-- | src/irc/irc_channel.hpp | 33 | ||||
-rw-r--r-- | src/irc/irc_client.cpp | 89 | ||||
-rw-r--r-- | src/irc/irc_client.hpp | 14 |
4 files changed, 27 insertions, 126 deletions
diff --git a/src/irc/irc_channel.cpp b/src/irc/irc_channel.cpp index 53043c7..2dd20fe 100644 --- a/src/irc/irc_channel.cpp +++ b/src/irc/irc_channel.cpp @@ -33,8 +33,9 @@ IrcUser* IrcChannel::find_user(const std::string& name) const return nullptr; } -void IrcChannel::remove_user(const IrcUser* user) +std::unique_ptr<IrcUser> IrcChannel::remove_user(const IrcUser* user) { + std::unique_ptr<IrcUser> result{}; const auto nick = user->nick; const bool is_self = (user == this->self); const auto it = std::find_if(this->users.begin(), this->users.end(), @@ -44,6 +45,7 @@ void IrcChannel::remove_user(const IrcUser* user) }); if (it != this->users.end()) { + result = std::move(*it); this->users.erase(it); if (is_self) { @@ -51,16 +53,5 @@ void IrcChannel::remove_user(const IrcUser* user) this->joined = false; } } -} - -void IrcChannel::remove_all_users() -{ - this->users.clear(); - this->self = nullptr; -} - -DummyIrcChannel::DummyIrcChannel(): - IrcChannel(), - joining(false) -{ + return result; } diff --git a/src/irc/irc_channel.hpp b/src/irc/irc_channel.hpp index 8f85edb..7000ada 100644 --- a/src/irc/irc_channel.hpp +++ b/src/irc/irc_channel.hpp @@ -32,8 +32,7 @@ public: IrcUser* add_user(const std::string& name, const std::map<char, char>& prefix_to_mode); IrcUser* find_user(const std::string& name) const; - void remove_user(const IrcUser* user); - void remove_all_users(); + std::unique_ptr<IrcUser> remove_user(const IrcUser* user); const std::vector<std::unique_ptr<IrcUser>>& get_users() const { return this->users; } @@ -42,33 +41,3 @@ protected: IrcUser* self{nullptr}; std::vector<std::unique_ptr<IrcUser>> users{}; }; - -/** - * A special channel that is not actually linked to any real irc - * channel. This is just a channel representing a connection to the - * server. If an user wants to maintain the connection to the server without - * having to be on any irc channel of that server, he can just join this - * dummy channel. - * It’s not actually dummy because it’s useful and it does things, but well. - */ -class DummyIrcChannel: public IrcChannel -{ -public: - explicit DummyIrcChannel(); - DummyIrcChannel(const DummyIrcChannel&) = delete; - DummyIrcChannel(DummyIrcChannel&&) = delete; - DummyIrcChannel& operator=(const DummyIrcChannel&) = delete; - DummyIrcChannel& operator=(DummyIrcChannel&&) = delete; - - /** - * This flag is at true whenever the user wants to join this channel, but - * he is not yet connected to the server. When the connection is made, we - * check that flag and if it’s true, we inform the user that he has just - * joined that channel. - * If the user is already connected to the server when he tries to join - * the channel, we don’t use that flag, we just join it immediately. - */ - bool joining; -}; - - diff --git a/src/irc/irc_client.cpp b/src/irc/irc_client.cpp index 40078d9..8f77e0d 100644 --- a/src/irc/irc_client.cpp +++ b/src/irc/irc_client.cpp @@ -145,14 +145,6 @@ IrcClient::IrcClient(std::shared_ptr<Poller>& poller, std::string hostname, chanmodes({"", "", "", ""}), chantypes({'#', '&'}) { - this->dummy_channel.topic = "This is a virtual channel provided for " - "convenience by biboumi, it is not connected " - "to any actual IRC channel of the server '" + this->hostname + - "', and sending messages in it has no effect. " - "Its main goal is to keep the connection to the IRC server " - "alive without having to join a real channel of that server. " - "To disconnect from the IRC server, leave this room and all " - "other IRC channels of that server."; #ifdef USE_DATABASE auto options = Database::get_irc_server_options(this->bridge.get_bare_jid(), this->get_hostname()); @@ -194,20 +186,22 @@ void IrcClient::start() bool tls; std::tie(port, tls) = this->ports_to_try.top(); this->ports_to_try.pop(); - this->bridge.send_xmpp_message(this->hostname, "", "Connecting to " + - this->hostname + ":" + port + " (" + - (tls ? "encrypted" : "not encrypted") + ")"); - this->bind_addr = Config::get("outgoing_bind", ""); + std::string address = this->hostname; -#ifdef BOTAN_FOUND -# ifdef USE_DATABASE +#ifdef USE_DATABASE auto options = Database::get_irc_server_options(this->bridge.get_bare_jid(), this->get_hostname()); +# ifdef BOTAN_FOUND this->credential_manager.set_trusted_fingerprint(options.col<Database::TrustedFingerprint>()); # endif + if (!options.col<Database::Address>().empty()) + address = options.col<Database::Address>(); #endif - this->connect(this->hostname, port, tls); + this->bridge.send_xmpp_message(this->hostname, "", "Connecting to " + + address + ":" + port + " (" + + (tls ? "encrypted" : "not encrypted") + ")"); + this->connect(address, port, tls); } void IrcClient::on_connection_failed(const std::string& reason) @@ -315,8 +309,6 @@ void IrcClient::on_connection_close(const std::string& error_msg) IrcChannel* IrcClient::get_channel(const std::string& n) { - if (n.empty()) - return &this->dummy_channel; const std::string name = utils::tolower(n); try { @@ -670,10 +662,7 @@ void IrcClient::on_channel_join(const IrcMessage& message) { const std::string chan_name = utils::tolower(message.arguments[0]); IrcChannel* channel; - if (chan_name.empty()) - channel = &this->dummy_channel; - else - channel = this->get_channel(chan_name); + channel = this->get_channel(chan_name); const std::string nick = message.prefix; IrcUser* user = channel->add_user(nick, this->prefix_to_mode); if (channel->joined == false) @@ -900,8 +889,9 @@ void IrcClient::on_welcome_message(const IrcMessage& message) #ifdef USE_DATABASE auto options = Database::get_irc_server_options(this->bridge.get_bare_jid(), this->get_hostname()); - if (!options.col<Database::AfterConnectionCommand>().empty()) - this->send_raw(options.col<Database::AfterConnectionCommand>()); + const auto commands = Database::get_after_connection_commands(options); + for (const auto& command: commands) + this->send_raw(command.col<Database::AfterConnectionCommand>()); #endif // Install a repeated events to regularly send a PING TimedEventsManager::instance().add_event(TimedEvent(240s, std::bind(&IrcClient::send_ping_command, this), @@ -948,18 +938,6 @@ void IrcClient::on_welcome_message(const IrcMessage& message) if (!channels_with_key.empty()) this->send_join_command(channels_with_key, keys); this->channels_to_join.clear(); - // Indicate that the dummy channel is joined as well, if needed - if (this->dummy_channel.joining) - { - // Simulate a message coming from the IRC server saying that we joined - // the channel - const IrcMessage join_message(this->get_nick(), "JOIN", {""}); - this->on_channel_join(join_message); - const IrcMessage end_join_message(std::string(this->hostname), "366", - {this->get_nick(), - "", "End of NAMES list"}); - this->on_channel_completely_joined(end_join_message); - } } void IrcClient::on_part(const IrcMessage& message) @@ -976,18 +954,18 @@ void IrcClient::on_part(const IrcMessage& message) { std::string nick = user->nick; bool self = channel->get_self() && channel->get_self()->nick == nick; - channel->remove_user(user); - Iid iid; - iid.set_local(chan_name); - iid.set_server(this->hostname); - iid.type = Iid::Type::Channel; + auto user_ptr = channel->remove_user(user); if (self) { this->channels.erase(utils::tolower(chan_name)); // channel pointer is now invalid channel = nullptr; } - this->bridge.send_muc_leave(iid, std::move(nick), txt, self, true); + Iid iid; + iid.set_local(chan_name); + iid.set_server(this->hostname); + iid.type = Iid::Type::Channel; + this->bridge.send_muc_leave(iid, *user_ptr, txt, self, true, {}, this); } } @@ -1004,8 +982,7 @@ void IrcClient::on_error(const IrcMessage& message) IrcChannel* channel = pair.second.get(); if (!channel->joined) continue; - std::string own_nick = channel->get_self()->nick; - this->bridge.send_muc_leave(iid, std::move(own_nick), leave_message, true, false); + this->bridge.send_muc_leave(iid, *channel->get_self(), leave_message, true, false, {}, this); } this->channels.clear(); this->send_gateway_message("ERROR: " + leave_message); @@ -1030,7 +1007,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(iid, user->nick, txt, self, false); + this->bridge.send_muc_leave(iid, *user, txt, self, false, {}, this); channel->remove_user(user); } } @@ -1062,10 +1039,6 @@ void IrcClient::on_nick(const IrcMessage& message) } }; - if (this->get_dummy_channel().joined) - { - change_nick_func("", &this->get_dummy_channel()); - } for (const auto& pair: this->channels) { change_nick_func(pair.first, pair.second.get()); @@ -1248,25 +1221,7 @@ void IrcClient::on_unknown_message(const IrcMessage& message) size_t IrcClient::number_of_joined_channels() const { - if (this->dummy_channel.joined) - return this->channels.size() + 1; - else - return this->channels.size(); -} - -DummyIrcChannel& IrcClient::get_dummy_channel() -{ - return this->dummy_channel; -} - -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("%" + this->hostname, this->chantypes), std::string(this->current_nick), exit_message, true, true, resource); + return this->channels.size(); } #ifdef BOTAN_FOUND diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index de5c520..fd97fe6 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -279,15 +279,6 @@ public: * Return the number of joined channels */ size_t number_of_joined_channels() const; - /** - * Get a reference to the unique dummy channel - */ - DummyIrcChannel& get_dummy_channel(); - /** - * 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, const std::string& resource); const std::string& get_hostname() const { return this->hostname; } std::string get_nick() const { return this->current_nick; } @@ -340,11 +331,6 @@ private: */ std::unordered_map<std::string, std::unique_ptr<IrcChannel>> channels; /** - * A single channel with a iid of the form "hostname" (normal channel have - * an iid of the form "chan%hostname". - */ - DummyIrcChannel dummy_channel; - /** * A list of chan we want to join (tuples with the channel name and the * password, if any), but we need a response 001 from the server before * sending the actual JOIN commands. So we just keep the channel names in |