explicitly tear down slots
This commit is contained in:
parent
135f5aa47d
commit
a49389d508
@ -46,9 +46,9 @@ add_executable(xbot
|
|||||||
connection.cpp
|
connection.cpp
|
||||||
irc_coroutine.cpp
|
irc_coroutine.cpp
|
||||||
ircmsg.cpp
|
ircmsg.cpp
|
||||||
registration_thread.cpp
|
registration.cpp
|
||||||
sasl_mechanism.cpp
|
sasl_mechanism.cpp
|
||||||
self_thread.cpp
|
client.cpp
|
||||||
settings.cpp
|
settings.cpp
|
||||||
snote.cpp
|
snote.cpp
|
||||||
)
|
)
|
||||||
|
37
bot.cpp
37
bot.cpp
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <boost/log/trivial.hpp>
|
#include <boost/log/trivial.hpp>
|
||||||
|
|
||||||
auto Bot::start(std::shared_ptr<SelfThread> self) -> std::shared_ptr<Bot>
|
auto Bot::start(std::shared_ptr<Client> self) -> std::shared_ptr<Bot>
|
||||||
{
|
{
|
||||||
const auto thread = std::make_shared<Bot>(std::move(self));
|
const auto thread = std::make_shared<Bot>(std::move(self));
|
||||||
|
|
||||||
@ -22,18 +22,38 @@ auto Bot::process_command(std::string_view message, const IrcMsg &msg) -> void
|
|||||||
message = message.substr(cmdstart);
|
message = message.substr(cmdstart);
|
||||||
|
|
||||||
if (not message.starts_with(command_prefix_)) return;
|
if (not message.starts_with(command_prefix_)) return;
|
||||||
|
message = message.substr(1); // discard the prefix
|
||||||
|
|
||||||
auto cmdend = message.find_first_of(' ', 1);
|
auto cmdend = message.find(' ');
|
||||||
|
|
||||||
std::string_view command =
|
std::string_view command =
|
||||||
cmdend == message.npos ? message : message.substr(0, cmdend);
|
cmdend == message.npos ? message : message.substr(0, cmdend);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::string_view arguments =
|
std::string_view arguments =
|
||||||
cmdend == message.npos ? std::string_view{} : message.substr(cmdend + 1);
|
cmdend == message.npos ? std::string_view{} : message.substr(cmdend + 1);
|
||||||
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << "COMMAND: " << command << " -- [" << arguments << "]";
|
std::string_view oper;
|
||||||
|
std::string_view account;
|
||||||
|
for (auto [key, value] : msg.tags)
|
||||||
|
{
|
||||||
|
if (key == "account")
|
||||||
|
{
|
||||||
|
account = value;
|
||||||
|
}
|
||||||
|
else if (key == "operator")
|
||||||
|
{
|
||||||
|
oper = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sig_command({
|
||||||
|
.source = msg.args[0],
|
||||||
|
.target = msg.args[1],
|
||||||
|
.oper = oper,
|
||||||
|
.account = account,
|
||||||
|
.command = command,
|
||||||
|
.arguments = arguments
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Bot::on_ircmsg(IrcCommand cmd, const IrcMsg &msg) -> void
|
auto Bot::on_ircmsg(IrcCommand cmd, const IrcMsg &msg) -> void
|
||||||
@ -52,4 +72,9 @@ auto Bot::on_ircmsg(IrcCommand cmd, const IrcMsg &msg) -> void
|
|||||||
process_command(message.substr(colon+1), msg);
|
process_command(message.substr(colon+1), msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto Bot::shutdown() -> void
|
||||||
|
{
|
||||||
|
sig_command.disconnect_all_slots();
|
||||||
|
}
|
||||||
|
12
bot.hpp
12
bot.hpp
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "self_thread.hpp"
|
#include "client.hpp"
|
||||||
|
|
||||||
#include <boost/signals2.hpp>
|
#include <boost/signals2.hpp>
|
||||||
|
|
||||||
@ -18,15 +18,19 @@ struct Command
|
|||||||
|
|
||||||
struct Bot : std::enable_shared_from_this<Bot>
|
struct Bot : std::enable_shared_from_this<Bot>
|
||||||
{
|
{
|
||||||
std::shared_ptr<SelfThread> self_;
|
std::shared_ptr<Client> self_;
|
||||||
char command_prefix_;
|
char command_prefix_;
|
||||||
|
|
||||||
Bot(std::shared_ptr<SelfThread> self)
|
boost::signals2::signal<void(const Command &)> sig_command;
|
||||||
|
|
||||||
|
Bot(std::shared_ptr<Client> self)
|
||||||
: self_{std::move(self)}
|
: self_{std::move(self)}
|
||||||
, command_prefix_{'!'}
|
, command_prefix_{'!'}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
auto on_ircmsg(IrcCommand, const IrcMsg &) -> void;
|
auto on_ircmsg(IrcCommand, const IrcMsg &) -> void;
|
||||||
auto process_command(std::string_view message, const IrcMsg &msg) -> void;
|
auto process_command(std::string_view message, const IrcMsg &msg) -> void;
|
||||||
static auto start(std::shared_ptr<SelfThread>) -> std::shared_ptr<Bot>;
|
static auto start(std::shared_ptr<Client>) -> std::shared_ptr<Bot>;
|
||||||
|
|
||||||
|
auto shutdown() -> void;
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "self_thread.hpp"
|
#include "client.hpp"
|
||||||
|
|
||||||
#include "connection.hpp"
|
#include "connection.hpp"
|
||||||
|
|
||||||
@ -9,17 +9,17 @@
|
|||||||
|
|
||||||
using namespace std::literals;
|
using namespace std::literals;
|
||||||
|
|
||||||
auto SelfThread::on_welcome(const IrcMsg &irc) -> void
|
auto Client::on_welcome(const IrcMsg &irc) -> void
|
||||||
{
|
{
|
||||||
nickname_ = irc.args[0];
|
nickname_ = irc.args[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SelfThread::on_registered() -> void
|
auto Client::on_registered() -> void
|
||||||
{
|
{
|
||||||
connection_.send_join("#lobby");
|
sig_registered();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SelfThread::on_nick(const IrcMsg &irc) -> void
|
auto Client::on_nick(const IrcMsg &irc) -> void
|
||||||
{
|
{
|
||||||
if (is_my_mask(irc.source))
|
if (is_my_mask(irc.source))
|
||||||
{
|
{
|
||||||
@ -27,12 +27,12 @@ auto SelfThread::on_nick(const IrcMsg &irc) -> void
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SelfThread::on_umodeis(const IrcMsg &irc) -> void
|
auto Client::on_umodeis(const IrcMsg &irc) -> void
|
||||||
{
|
{
|
||||||
mode_ = irc.args[1];
|
mode_ = irc.args[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SelfThread::on_join(const IrcMsg &irc) -> void
|
auto Client::on_join(const IrcMsg &irc) -> void
|
||||||
{
|
{
|
||||||
if (is_my_mask(irc.source))
|
if (is_my_mask(irc.source))
|
||||||
{
|
{
|
||||||
@ -40,7 +40,7 @@ auto SelfThread::on_join(const IrcMsg &irc) -> void
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SelfThread::on_kick(const IrcMsg &irc) -> void
|
auto Client::on_kick(const IrcMsg &irc) -> void
|
||||||
{
|
{
|
||||||
if (is_my_nick(irc.args[1]))
|
if (is_my_nick(irc.args[1]))
|
||||||
{
|
{
|
||||||
@ -48,7 +48,7 @@ auto SelfThread::on_kick(const IrcMsg &irc) -> void
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SelfThread::on_part(const IrcMsg &irc) -> void
|
auto Client::on_part(const IrcMsg &irc) -> void
|
||||||
{
|
{
|
||||||
if (is_my_mask(irc.source))
|
if (is_my_mask(irc.source))
|
||||||
{
|
{
|
||||||
@ -56,7 +56,7 @@ auto SelfThread::on_part(const IrcMsg &irc) -> void
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SelfThread::on_mode(const IrcMsg &irc) -> void
|
auto Client::on_mode(const IrcMsg &irc) -> void
|
||||||
{
|
{
|
||||||
if (is_my_nick(irc.args[0]))
|
if (is_my_nick(irc.args[0]))
|
||||||
{
|
{
|
||||||
@ -90,7 +90,7 @@ auto SelfThread::on_mode(const IrcMsg &irc) -> void
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SelfThread::on_isupport(const IrcMsg &msg) -> void
|
auto Client::on_isupport(const IrcMsg &msg) -> void
|
||||||
{
|
{
|
||||||
const auto hi = msg.args.size() - 1;
|
const auto hi = msg.args.size() - 1;
|
||||||
for (int i = 1; i < hi; ++i)
|
for (int i = 1; i < hi; ++i)
|
||||||
@ -117,9 +117,9 @@ auto SelfThread::on_isupport(const IrcMsg &msg) -> void
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SelfThread::start(Connection &connection) -> std::shared_ptr<SelfThread>
|
auto Client::start(Connection &connection) -> std::shared_ptr<Client>
|
||||||
{
|
{
|
||||||
auto thread = std::make_shared<SelfThread>(connection);
|
auto thread = std::make_shared<Client>(connection);
|
||||||
|
|
||||||
connection.sig_ircmsg.connect([thread](auto cmd, auto &msg) {
|
connection.sig_ircmsg.connect([thread](auto cmd, auto &msg) {
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
@ -163,38 +163,38 @@ auto SelfThread::start(Connection &connection) -> std::shared_ptr<SelfThread>
|
|||||||
return thread;
|
return thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SelfThread::get_my_nickname() const -> const std::string &
|
auto Client::get_my_nickname() const -> const std::string &
|
||||||
{
|
{
|
||||||
return nickname_;
|
return nickname_;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SelfThread::get_my_mode() const -> const std::string &
|
auto Client::get_my_mode() const -> const std::string &
|
||||||
{
|
{
|
||||||
return mode_;
|
return mode_;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SelfThread::get_my_channels() const -> const std::unordered_set<std::string> &
|
auto Client::get_my_channels() const -> const std::unordered_set<std::string> &
|
||||||
{
|
{
|
||||||
return channels_;
|
return channels_;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SelfThread::is_my_nick(std::string_view nick) const -> bool
|
auto Client::is_my_nick(std::string_view nick) const -> bool
|
||||||
{
|
{
|
||||||
return casemap_compare(nick, nickname_) == 0;
|
return casemap_compare(nick, nickname_) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SelfThread::is_my_mask(std::string_view mask) const -> bool
|
auto Client::is_my_mask(std::string_view mask) const -> bool
|
||||||
{
|
{
|
||||||
const auto bang = mask.find('!');
|
const auto bang = mask.find('!');
|
||||||
return bang != std::string_view::npos && nickname_ == mask.substr(0, bang);
|
return bang != std::string_view::npos && nickname_ == mask.substr(0, bang);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SelfThread::is_channel(std::string_view name) const -> bool
|
auto Client::is_channel(std::string_view name) const -> bool
|
||||||
{
|
{
|
||||||
return not name.empty() && channel_prefix_.find(name[0]) != channel_prefix_.npos;
|
return not name.empty() && channel_prefix_.find(name[0]) != channel_prefix_.npos;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SelfThread::on_authenticate(const std::string_view body) -> void
|
auto Client::on_authenticate(const std::string_view body) -> void
|
||||||
{
|
{
|
||||||
if (not sasl_mechanism_)
|
if (not sasl_mechanism_)
|
||||||
{
|
{
|
||||||
@ -216,7 +216,7 @@ auto SelfThread::on_authenticate(const std::string_view body) -> void
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SelfThread::start_sasl(std::unique_ptr<SaslMechanism> mechanism) -> void
|
auto Client::start_sasl(std::unique_ptr<SaslMechanism> mechanism) -> void
|
||||||
{
|
{
|
||||||
if (sasl_mechanism_)
|
if (sasl_mechanism_)
|
||||||
{
|
{
|
||||||
@ -248,7 +248,7 @@ static auto casemap_impl(std::string_view str) -> std::string
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SelfThread::casemap(std::string_view str) const -> std::string
|
auto Client::casemap(std::string_view str) const -> std::string
|
||||||
{
|
{
|
||||||
switch (casemap_) {
|
switch (casemap_) {
|
||||||
case Casemap::Ascii: return casemap_impl<tolower>(str);
|
case Casemap::Ascii: return casemap_impl<tolower>(str);
|
||||||
@ -272,11 +272,16 @@ static auto casemap_compare_impl(std::string_view lhs, std::string_view rhs) ->
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SelfThread::casemap_compare(std::string_view lhs, std::string_view rhs) const -> int
|
auto Client::casemap_compare(std::string_view lhs, std::string_view rhs) const -> int
|
||||||
{
|
{
|
||||||
switch (casemap_) {
|
switch (casemap_) {
|
||||||
case Casemap::Ascii: return casemap_compare_impl<tolower>(lhs, rhs);
|
case Casemap::Ascii: return casemap_compare_impl<tolower>(lhs, rhs);
|
||||||
case Casemap::Rfc1459: return casemap_compare_impl<tolower_rfc1459>(lhs, rhs);
|
case Casemap::Rfc1459: return casemap_compare_impl<tolower_rfc1459>(lhs, rhs);
|
||||||
case Casemap::Rfc1459_Strict: return casemap_compare_impl<tolower_rfc1459_strict>(lhs, rhs);
|
case Casemap::Rfc1459_Strict: return casemap_compare_impl<tolower_rfc1459_strict>(lhs, rhs);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Client::shutdown() -> void
|
||||||
|
{
|
||||||
|
sig_registered.disconnect_all_slots();
|
||||||
}
|
}
|
@ -20,7 +20,7 @@ enum class Casemap
|
|||||||
* @brief Thread to track this connection's identity, and IRC state.
|
* @brief Thread to track this connection's identity, and IRC state.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class SelfThread
|
class Client
|
||||||
{
|
{
|
||||||
Connection &connection_;
|
Connection &connection_;
|
||||||
|
|
||||||
@ -47,13 +47,16 @@ class SelfThread
|
|||||||
auto on_registered() -> void;
|
auto on_registered() -> void;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SelfThread(Connection &connection)
|
boost::signals2::signal<void()> sig_registered;
|
||||||
|
|
||||||
|
Client(Connection &connection)
|
||||||
: connection_{connection}
|
: connection_{connection}
|
||||||
, casemap_{Casemap::Rfc1459}
|
, casemap_{Casemap::Rfc1459}
|
||||||
, channel_prefix_{"#&"}
|
, channel_prefix_{"#&"}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
static auto start(Connection &) -> std::shared_ptr<SelfThread>;
|
|
||||||
|
static auto start(Connection &) -> std::shared_ptr<Client>;
|
||||||
|
|
||||||
auto start_sasl(std::unique_ptr<SaslMechanism> mechanism) -> void;
|
auto start_sasl(std::unique_ptr<SaslMechanism> mechanism) -> void;
|
||||||
|
|
||||||
@ -72,4 +75,6 @@ public:
|
|||||||
|
|
||||||
auto casemap(std::string_view) const -> std::string;
|
auto casemap(std::string_view) const -> std::string;
|
||||||
auto casemap_compare(std::string_view, std::string_view) const -> int;
|
auto casemap_compare(std::string_view, std::string_view) const -> int;
|
||||||
|
|
||||||
|
auto shutdown() -> void;
|
||||||
};
|
};
|
@ -477,5 +477,12 @@ auto Connection::start(ConnectSettings settings) -> void
|
|||||||
}
|
}
|
||||||
|
|
||||||
self->sig_disconnect();
|
self->sig_disconnect();
|
||||||
|
|
||||||
|
// Disconnect all slots to avoid circular references
|
||||||
|
self->sig_connect.disconnect_all_slots();
|
||||||
|
self->sig_ircmsg.disconnect_all_slots();
|
||||||
|
self->sig_disconnect.disconnect_all_slots();
|
||||||
|
self->sig_snote.disconnect_all_slots();
|
||||||
|
self->sig_authenticate.disconnect_all_slots();
|
||||||
});
|
});
|
||||||
}
|
}
|
31
main.cpp
31
main.cpp
@ -10,18 +10,18 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "bot.hpp"
|
#include "bot.hpp"
|
||||||
#include "registration_thread.hpp"
|
#include "client.hpp"
|
||||||
#include "self_thread.hpp"
|
#include "registration.hpp"
|
||||||
|
|
||||||
using namespace std::chrono_literals;
|
using namespace std::literals;
|
||||||
|
|
||||||
auto start(boost::asio::io_context &io, const Settings &settings) -> void
|
auto start(boost::asio::io_context &io, const Settings &settings) -> void
|
||||||
{
|
{
|
||||||
const auto connection = std::make_shared<Connection>(io);
|
const auto connection = std::make_shared<Connection>(io);
|
||||||
|
const auto client = Client::start(*connection);
|
||||||
|
Registration::start(*connection, settings, client);
|
||||||
|
|
||||||
const auto selfThread = SelfThread::start(*connection);
|
const auto bot = Bot::start(client);
|
||||||
RegistrationThread::start(*connection, settings, selfThread);
|
|
||||||
Bot::start(selfThread);
|
|
||||||
|
|
||||||
connection->sig_snote.connect([](auto &match) {
|
connection->sig_snote.connect([](auto &match) {
|
||||||
std::cout << "SNOTE " << static_cast<int>(match.get_tag()) << std::endl;
|
std::cout << "SNOTE " << static_cast<int>(match.get_tag()) << std::endl;
|
||||||
@ -31,16 +31,27 @@ auto start(boost::asio::io_context &io, const Settings &settings) -> void
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
connection->sig_disconnect.connect_extended(
|
client->sig_registered.connect_extended([connection](auto &slot) {
|
||||||
[&io, &settings](auto &slot) {
|
slot.disconnect();
|
||||||
slot.disconnect();
|
connection->send_join("##glguy"sv);
|
||||||
|
});
|
||||||
|
|
||||||
|
connection->sig_disconnect.connect(
|
||||||
|
[&io, &settings, client, bot]() {
|
||||||
|
client->shutdown();
|
||||||
|
bot->shutdown();
|
||||||
|
|
||||||
auto timer = std::make_shared<boost::asio::steady_timer>(io);
|
auto timer = std::make_shared<boost::asio::steady_timer>(io);
|
||||||
timer->expires_after(5s);
|
timer->expires_after(5s);
|
||||||
timer->async_wait([&io, &settings, timer](auto) { start(io, settings); });
|
timer->async_wait([&io, &settings, timer](auto) { start(io, settings); });
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
connection->start(ConnectSettings{
|
bot->sig_command.connect([connection](const Command &cmd) {
|
||||||
|
std::cout << "COMMAND " << cmd.command << " from " << cmd.account << std::endl;
|
||||||
|
});
|
||||||
|
|
||||||
|
connection->start({
|
||||||
.tls = settings.use_tls,
|
.tls = settings.use_tls,
|
||||||
.host = settings.host,
|
.host = settings.host,
|
||||||
.port = settings.service,
|
.port = settings.service,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "registration_thread.hpp"
|
#include "registration.hpp"
|
||||||
|
|
||||||
#include "connection.hpp"
|
#include "connection.hpp"
|
||||||
#include "ircmsg.hpp"
|
#include "ircmsg.hpp"
|
||||||
@ -8,10 +8,10 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
RegistrationThread::RegistrationThread(
|
Registration::Registration(
|
||||||
Connection &connection,
|
Connection &connection,
|
||||||
const Settings &settings,
|
const Settings &settings,
|
||||||
std::shared_ptr<SelfThread> self
|
std::shared_ptr<Client> self
|
||||||
)
|
)
|
||||||
: connection_{connection}
|
: connection_{connection}
|
||||||
, settings_{settings}
|
, settings_{settings}
|
||||||
@ -19,9 +19,11 @@ RegistrationThread::RegistrationThread(
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
auto RegistrationThread::on_connect() -> void
|
auto Registration::on_connect() -> void
|
||||||
{
|
{
|
||||||
connection_.send_cap_ls();
|
connection_.send_cap_ls();
|
||||||
|
listen_for_cap_ls();
|
||||||
|
|
||||||
if (not settings_.password.empty())
|
if (not settings_.password.empty())
|
||||||
{
|
{
|
||||||
connection_.send_pass(settings_.password);
|
connection_.send_pass(settings_.password);
|
||||||
@ -30,7 +32,7 @@ auto RegistrationThread::on_connect() -> void
|
|||||||
connection_.send_nick(settings_.nickname);
|
connection_.send_nick(settings_.nickname);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto RegistrationThread::send_req() -> void
|
auto Registration::send_req() -> void
|
||||||
{
|
{
|
||||||
std::string request;
|
std::string request;
|
||||||
std::vector<const char *> want{
|
std::vector<const char *> want{
|
||||||
@ -77,7 +79,7 @@ auto RegistrationThread::send_req() -> void
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto RegistrationThread::on_msg_cap_ack(const IrcMsg &msg) -> void
|
auto Registration::on_msg_cap_ack(const IrcMsg &msg) -> void
|
||||||
{
|
{
|
||||||
auto in = std::istringstream{std::string{msg.args[2]}};
|
auto in = std::istringstream{std::string{msg.args[2]}};
|
||||||
std::for_each(
|
std::for_each(
|
||||||
@ -89,16 +91,16 @@ auto RegistrationThread::on_msg_cap_ack(const IrcMsg &msg) -> void
|
|||||||
);
|
);
|
||||||
if (outstanding.empty())
|
if (outstanding.empty())
|
||||||
{
|
{
|
||||||
message_handle_.disconnect();
|
|
||||||
|
|
||||||
if (settings_.sasl_mechanism.empty())
|
if (settings_.sasl_mechanism.empty())
|
||||||
{
|
{
|
||||||
|
slot_.disconnect();
|
||||||
connection_.send_cap_end();
|
connection_.send_cap_end();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
self_->start_sasl(std::make_unique<SaslPlain>(settings_.sasl_authcid, settings_.sasl_authzid, settings_.sasl_password));
|
self_->start_sasl(std::make_unique<SaslPlain>(settings_.sasl_authcid, settings_.sasl_authzid, settings_.sasl_password));
|
||||||
connection_.sig_ircmsg.connect_extended([thread = shared_from_this()](auto &slot, auto cmd, auto &msg) {
|
slot_ = connection_.sig_ircmsg.connect([thread = shared_from_this()](auto cmd, auto &msg) {
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
@ -106,14 +108,14 @@ auto RegistrationThread::on_msg_cap_ack(const IrcMsg &msg) -> void
|
|||||||
case IrcCommand::RPL_SASLSUCCESS:
|
case IrcCommand::RPL_SASLSUCCESS:
|
||||||
case IrcCommand::ERR_SASLFAIL:
|
case IrcCommand::ERR_SASLFAIL:
|
||||||
thread->connection_.send_cap_end();
|
thread->connection_.send_cap_end();
|
||||||
slot.disconnect();
|
thread->slot_.disconnect();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto RegistrationThread::on_msg_cap_ls(const IrcMsg &msg) -> void
|
auto Registration::on_msg_cap_ls(const IrcMsg &msg) -> void
|
||||||
{
|
{
|
||||||
const std::string_view *kvs;
|
const std::string_view *kvs;
|
||||||
bool last;
|
bool last;
|
||||||
@ -153,32 +155,30 @@ auto RegistrationThread::on_msg_cap_ls(const IrcMsg &msg) -> void
|
|||||||
|
|
||||||
if (last)
|
if (last)
|
||||||
{
|
{
|
||||||
message_handle_.disconnect();
|
slot_.disconnect();
|
||||||
send_req();
|
send_req();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto RegistrationThread::start(
|
auto Registration::start(
|
||||||
Connection &connection,
|
Connection &connection,
|
||||||
const Settings &settings,
|
const Settings &settings,
|
||||||
std::shared_ptr<SelfThread> self
|
std::shared_ptr<Client> self
|
||||||
) -> std::shared_ptr<RegistrationThread>
|
) -> std::shared_ptr<Registration>
|
||||||
{
|
{
|
||||||
const auto thread = std::make_shared<RegistrationThread>(connection, std::move(settings), std::move(self));
|
const auto thread = std::make_shared<Registration>(connection, std::move(settings), std::move(self));
|
||||||
|
|
||||||
thread->listen_for_cap_ls();
|
thread->slot_ = connection.sig_connect.connect([thread]() {
|
||||||
|
thread->slot_.disconnect();
|
||||||
thread->connect_handle_ = connection.sig_connect.connect([thread]() {
|
|
||||||
thread->connect_handle_.disconnect();
|
|
||||||
thread->on_connect();
|
thread->on_connect();
|
||||||
});
|
});
|
||||||
|
|
||||||
return thread;
|
return thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto RegistrationThread::listen_for_cap_ack() -> void
|
auto Registration::listen_for_cap_ack() -> void
|
||||||
{
|
{
|
||||||
message_handle_ = connection_.sig_ircmsg.connect([thread = shared_from_this()](IrcCommand cmd, const IrcMsg &msg) {
|
slot_ = connection_.sig_ircmsg.connect([thread = shared_from_this()](IrcCommand cmd, const IrcMsg &msg) {
|
||||||
if (IrcCommand::CAP == cmd && msg.args.size() >= 2 && "ACK" == msg.args[1])
|
if (IrcCommand::CAP == cmd && msg.args.size() >= 2 && "ACK" == msg.args[1])
|
||||||
{
|
{
|
||||||
thread->on_msg_cap_ack(msg);
|
thread->on_msg_cap_ack(msg);
|
||||||
@ -186,9 +186,9 @@ auto RegistrationThread::listen_for_cap_ack() -> void
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
auto RegistrationThread::listen_for_cap_ls() -> void
|
auto Registration::listen_for_cap_ls() -> void
|
||||||
{
|
{
|
||||||
message_handle_ = connection_.sig_ircmsg.connect([thread = shared_from_this()](IrcCommand cmd, const IrcMsg &msg) {
|
slot_ = connection_.sig_ircmsg.connect([thread = shared_from_this()](IrcCommand cmd, const IrcMsg &msg) {
|
||||||
if (IrcCommand::CAP == cmd && msg.args.size() >= 2 && "LS" == msg.args[1])
|
if (IrcCommand::CAP == cmd && msg.args.size() >= 2 && "LS" == msg.args[1])
|
||||||
{
|
{
|
||||||
thread->on_msg_cap_ls(msg);
|
thread->on_msg_cap_ls(msg);
|
||||||
@ -196,7 +196,7 @@ auto RegistrationThread::listen_for_cap_ls() -> void
|
|||||||
else if (IrcCommand::RPL_WELCOME == cmd)
|
else if (IrcCommand::RPL_WELCOME == cmd)
|
||||||
{
|
{
|
||||||
// Server doesn't support CAP negotiation
|
// Server doesn't support CAP negotiation
|
||||||
thread->message_handle_.disconnect();
|
thread->slot_.disconnect();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "connection.hpp"
|
#include "connection.hpp"
|
||||||
#include "self_thread.hpp"
|
#include "client.hpp"
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -9,17 +9,16 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
class RegistrationThread : public std::enable_shared_from_this<RegistrationThread>
|
class Registration : public std::enable_shared_from_this<Registration>
|
||||||
{
|
{
|
||||||
Connection &connection_;
|
Connection &connection_;
|
||||||
const Settings &settings_;
|
const Settings &settings_;
|
||||||
std::shared_ptr<SelfThread> self_;
|
std::shared_ptr<Client> self_;
|
||||||
|
|
||||||
std::unordered_map<std::string, std::string> caps;
|
std::unordered_map<std::string, std::string> caps;
|
||||||
std::unordered_set<std::string> outstanding;
|
std::unordered_set<std::string> outstanding;
|
||||||
|
|
||||||
boost::signals2::scoped_connection connect_handle_;
|
boost::signals2::scoped_connection slot_;
|
||||||
boost::signals2::scoped_connection message_handle_;
|
|
||||||
|
|
||||||
auto on_connect() -> void;
|
auto on_connect() -> void;
|
||||||
auto send_req() -> void;
|
auto send_req() -> void;
|
||||||
@ -30,15 +29,15 @@ class RegistrationThread : public std::enable_shared_from_this<RegistrationThrea
|
|||||||
auto listen_for_cap_ls() -> void;
|
auto listen_for_cap_ls() -> void;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RegistrationThread(
|
Registration(
|
||||||
Connection &connection_,
|
Connection &connection_,
|
||||||
const Settings &,
|
const Settings &,
|
||||||
std::shared_ptr<SelfThread> self
|
std::shared_ptr<Client> self
|
||||||
);
|
);
|
||||||
|
|
||||||
static auto start(
|
static auto start(
|
||||||
Connection &connection,
|
Connection &connection,
|
||||||
const Settings &,
|
const Settings &,
|
||||||
std::shared_ptr<SelfThread> self
|
std::shared_ptr<Client> self
|
||||||
) -> std::shared_ptr<RegistrationThread>;
|
) -> std::shared_ptr<Registration>;
|
||||||
};
|
};
|
Loading…
x
Reference in New Issue
Block a user