add thread for tracking own status

This commit is contained in:
Eric Mertens 2023-11-26 16:48:21 -08:00
parent 964d5fa96c
commit e2a5c8c66b
5 changed files with 135 additions and 9 deletions

View File

@ -33,6 +33,10 @@ add_custom_command(
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/irc_commands.gperf DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/irc_commands.gperf
VERBATIM) VERBATIM)
add_executable(xbot main.cpp irc_commands.inc ircmsg.cpp settings.cpp connection.cpp thread.cpp snote_thread.cpp watchdog_thread.cpp write_irc.cpp ping_thread.cpp irc_parse_thread.cpp registration_thread.cpp) add_executable(xbot
main.cpp irc_commands.inc ircmsg.cpp settings.cpp connection.cpp
thread.cpp snote_thread.cpp watchdog_thread.cpp write_irc.cpp
ping_thread.cpp irc_parse_thread.cpp registration_thread.cpp
self_thread.cpp)
target_include_directories(xbot PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) target_include_directories(xbot PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(xbot PRIVATE Boost::headers tomlplusplus_tomlplusplus eventpp) target_link_libraries(xbot PRIVATE Boost::headers tomlplusplus_tomlplusplus eventpp)

View File

@ -87,10 +87,10 @@ struct RecognizedCommand {
321, IrcCommand::RPL_LISTSTART, 3, 3 321, IrcCommand::RPL_LISTSTART, 3, 3
322, IrcCommand::RPL_LIST, 4, 4 322, IrcCommand::RPL_LIST, 4, 4
323, IrcCommand::RPL_LISTEND, 2, 2 323, IrcCommand::RPL_LISTEND, 2, 2
324, IrcCommand::RPL_CHANNELMODEIS 324, IrcCommand::RPL_CHANNELMODEIS, 3, 3
325, IrcCommand::RPL_CHANNELMLOCK 325, IrcCommand::RPL_CHANNELMLOCK
328, IrcCommand::RPL_CHANNELURL 328, IrcCommand::RPL_CHANNELURL
329, IrcCommand::RPL_CREATIONTIME 329, IrcCommand::RPL_CREATIONTIME, 3, 3
330, IrcCommand::RPL_WHOISLOGGEDIN, 4, 4 330, IrcCommand::RPL_WHOISLOGGEDIN, 4, 4
331, IrcCommand::RPL_NOTOPIC, 3, 3 331, IrcCommand::RPL_NOTOPIC, 3, 3
332, IrcCommand::RPL_TOPIC, 3, 3 332, IrcCommand::RPL_TOPIC, 3, 3
@ -123,7 +123,7 @@ struct RecognizedCommand {
375, IrcCommand::RPL_MOTDSTART, 2, 2 375, IrcCommand::RPL_MOTDSTART, 2, 2
376, IrcCommand::RPL_ENDOFMOTD, 2, 2 376, IrcCommand::RPL_ENDOFMOTD, 2, 2
378, IrcCommand::RPL_WHOISHOST 378, IrcCommand::RPL_WHOISHOST
381, IrcCommand::RPL_YOUREOPER 381, IrcCommand::RPL_YOUREOPER, 2, 2
382, IrcCommand::RPL_REHASHING 382, IrcCommand::RPL_REHASHING
384, IrcCommand::RPL_MYPORTIS 384, IrcCommand::RPL_MYPORTIS
385, IrcCommand::RPL_NOTOPERANYMORE 385, IrcCommand::RPL_NOTOPERANYMORE
@ -155,7 +155,7 @@ struct RecognizedCommand {
424, IrcCommand::ERR_FILEERROR 424, IrcCommand::ERR_FILEERROR
431, IrcCommand::ERR_NONICKNAMEGIVEN 431, IrcCommand::ERR_NONICKNAMEGIVEN
432, IrcCommand::ERR_ERRONEUSNICKNAME 432, IrcCommand::ERR_ERRONEUSNICKNAME
433, IrcCommand::ERR_NICKNAMEINUSE 433, IrcCommand::ERR_NICKNAMEINUSE, 3, 3
435, IrcCommand::ERR_BANNICKCHANGE 435, IrcCommand::ERR_BANNICKCHANGE
436, IrcCommand::ERR_NICKCOLLISION 436, IrcCommand::ERR_NICKCOLLISION
437, IrcCommand::ERR_UNAVAILRESOURCE 437, IrcCommand::ERR_UNAVAILRESOURCE
@ -200,7 +200,7 @@ struct RecognizedCommand {
492, IrcCommand::ERR_CANNOTSENDTOUSER 492, IrcCommand::ERR_CANNOTSENDTOUSER
494, IrcCommand::ERR_OWNMODE 494, IrcCommand::ERR_OWNMODE
501, IrcCommand::ERR_UMODEUNKNOWNFLAG 501, IrcCommand::ERR_UMODEUNKNOWNFLAG
502, IrcCommand::ERR_USERSDONTMATCH 502, IrcCommand::ERR_USERSDONTMATCH, 2, 2
503, IrcCommand::ERR_GHOSTEDCLIENT 503, IrcCommand::ERR_GHOSTEDCLIENT
504, IrcCommand::ERR_USERNOTONSERV 504, IrcCommand::ERR_USERNOTONSERV
513, IrcCommand::ERR_WRONGPONG 513, IrcCommand::ERR_WRONGPONG
@ -241,8 +241,8 @@ struct RecognizedCommand {
732, IrcCommand::RPL_MONLIST 732, IrcCommand::RPL_MONLIST
733, IrcCommand::RPL_ENDOFMONLIS, 2, 2 733, IrcCommand::RPL_ENDOFMONLIS, 2, 2
734, IrcCommand::ERR_MONLISTFULL 734, IrcCommand::ERR_MONLISTFULL
740, IrcCommand::RPL_RSACHALLENGE2 740, IrcCommand::RPL_RSACHALLENGE2, 2, 2
741, IrcCommand::RPL_ENDOFRSACHALLENGE2 741, IrcCommand::RPL_ENDOFRSACHALLENGE2, 2, 2
742, IrcCommand::ERR_MLOCKRESTRICTE 742, IrcCommand::ERR_MLOCKRESTRICTE
743, IrcCommand::ERR_INVALIDBAN 743, IrcCommand::ERR_INVALIDBAN
744, IrcCommand::ERR_TOPICLOCK 744, IrcCommand::ERR_TOPICLOCK
@ -270,7 +270,7 @@ KICK, IrcCommand::KICK, 3, 3
MODE, IrcCommand::MODE, 2, 15 MODE, IrcCommand::MODE, 2, 15
NICK, IrcCommand::NICK, 1, 1 NICK, IrcCommand::NICK, 1, 1
NOTICE, IrcCommand::NOTICE, 2, 2 NOTICE, IrcCommand::NOTICE, 2, 2
PART, IrcCommand::PART, 2, 2 PART, IrcCommand::PART, 1, 2
PING, IrcCommand::PING, 1, 1 PING, IrcCommand::PING, 1, 1
PRIVMSG, IrcCommand::PRIVMSG, 2, 2 PRIVMSG, IrcCommand::PRIVMSG, 2, 2
QUIT, IrcCommand::QUIT, 1, 1 QUIT, IrcCommand::QUIT, 1, 1

View File

@ -12,6 +12,7 @@
#include "ping_thread.hpp" #include "ping_thread.hpp"
#include "watchdog_thread.hpp" #include "watchdog_thread.hpp"
#include "snote_thread.hpp" #include "snote_thread.hpp"
#include "self_thread.hpp"
#include <algorithm> #include <algorithm>
#include <chrono> #include <chrono>
@ -49,6 +50,31 @@ auto unhandled_message_thread(Connection& connection) -> void
}); });
} }
auto echo_thread(Connection& connection) -> void
{
connection.add_listener<IrcMsgEvent>([&connection](IrcMsgEvent& event)
{
if (IrcCommand::PRIVMSG == event.command)
{
auto const msg = event.irc.args[1];
if (msg.starts_with("!raw "))
{
for (auto const& tag : event.irc.tags)
{
if ("account" == tag.key && "glguy" == tag.val)
{
auto txt = std::string{event.irc.args[1].substr(5)};
txt += "\r\n";
connection.write_raw(std::move(txt));
event.handled_ = true;
return;
}
}
}
}
});
}
auto start(boost::asio::io_context & io, Settings const& settings) -> void auto start(boost::asio::io_context & io, Settings const& settings) -> void
{ {
auto connection = std::make_shared<Connection>(io); auto connection = std::make_shared<Connection>(io);
@ -56,8 +82,10 @@ auto start(boost::asio::io_context & io, Settings const& settings) -> void
watchdog_thread(*connection); watchdog_thread(*connection);
irc_parse_thread(*connection); irc_parse_thread(*connection);
ping_thread(*connection); ping_thread(*connection);
auto const self_thread = SelfThread::start(*connection);
registration_thread(*connection, settings.password, settings.username, settings.realname, settings.nickname); registration_thread(*connection, settings.password, settings.username, settings.realname, settings.nickname);
snote_thread(*connection); snote_thread(*connection);
echo_thread(*connection);
unhandled_message_thread(*connection); unhandled_message_thread(*connection);
boost::asio::co_spawn( boost::asio::co_spawn(

76
self_thread.cpp Normal file
View File

@ -0,0 +1,76 @@
#include "self_thread.hpp"
#include "connection.hpp"
#include "irc_parse_thread.hpp"
auto SelfThread::start(Connection& connection) -> std::shared_ptr<SelfThread>
{
auto thread = std::make_shared<SelfThread>(connection);
connection.add_listener<IrcMsgEvent>([thread](IrcMsgEvent& event)
{
switch (event.command)
{
// Learn nickname from 001
case IrcCommand::RPL_WELCOME:
thread->nickname_ = event.irc.args[0];
break;
// Track changes to our nickname
case IrcCommand::NICK:
{
auto const bang = event.irc.source.find('!');
if (bang != std::string::npos
&& thread->nickname_ == event.irc.source.substr(0, bang)
)
{
thread->nickname_ = event.irc.args[0];
}
break;
}
// Re-establish user modes
case IrcCommand::RPL_UMODEIS:
thread->mode_ = event.irc.args[1];
break;
// Interpret self mode changes
case IrcCommand::MODE:
if (2 == event.irc.args.size()
&& thread->nickname_ == event.irc.args[0]
)
{
auto polarity = true;
for (char const c : event.irc.args[1])
{
switch (c)
{
case '+':
polarity = true;
break;
case '-':
polarity = false;
break;
default:
if (polarity)
{
thread->mode_ += c;
}
else
{
auto const ix = thread->mode_.find(c);
if (ix != std::string::npos)
{
thread->mode_.erase(ix, 1);
}
}
break;
}
}
}
default: break;
}
});
return thread;
}

18
self_thread.hpp Normal file
View File

@ -0,0 +1,18 @@
#pragma once
#include <string>
#include <memory>
struct Connection;
class SelfThread
{
Connection& connection_;
std::string nickname_;
std::string mode_;
public:
SelfThread(Connection& connection) : connection_{connection} {}
static auto start(Connection&) -> std::shared_ptr<SelfThread>;
};