use gperf
This commit is contained in:
parent
959d51f5f4
commit
4c2f783d74
|
@ -7,7 +7,6 @@ project(xbot
|
||||||
)
|
)
|
||||||
|
|
||||||
find_package(Boost REQUIRED)
|
find_package(Boost REQUIRED)
|
||||||
|
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
|
|
||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
|
@ -24,5 +23,16 @@ FetchContent_Declare(
|
||||||
)
|
)
|
||||||
FetchContent_MakeAvailable(eventpp)
|
FetchContent_MakeAvailable(eventpp)
|
||||||
|
|
||||||
add_executable(xbot main.cpp 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_custom_command(
|
||||||
|
OUTPUT irc_commands.inc
|
||||||
|
COMMAND
|
||||||
|
gperf
|
||||||
|
-C -Z IrcCommandHash -K text -L C++ -t
|
||||||
|
--output-file irc_commands.inc
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/irc_commands.gperf
|
||||||
|
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/irc_commands.gperf
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
|
|
@ -2,10 +2,25 @@
|
||||||
|
|
||||||
#include "connection.hpp"
|
#include "connection.hpp"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
#include "irc_commands.inc"
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
auto irc_parse_thread(Connection * connection) -> void
|
auto irc_parse_thread(Connection * connection) -> void
|
||||||
{
|
{
|
||||||
connection->add_listener<LineEvent>([connection](LineEvent const& event)
|
connection->add_listener<LineEvent>([connection](LineEvent const& event)
|
||||||
{
|
{
|
||||||
connection->make_event<IrcMsgEvent>(parse_irc_message(event.line));
|
auto const msg = parse_irc_message(event.line);
|
||||||
|
auto const recognized = IrcCommandHash::in_word_set(msg.command.data(), msg.command.size());
|
||||||
|
auto const command
|
||||||
|
= recognized
|
||||||
|
&& recognized->min_args <= msg.args.size()
|
||||||
|
&& recognized->max_args >= msg.args.size()
|
||||||
|
? recognized->command : IrcCommand::UNKNOWN;
|
||||||
|
connection->make_event<IrcMsgEvent>(command, msg);
|
||||||
});
|
});
|
||||||
}
|
}
|
|
@ -2,12 +2,295 @@
|
||||||
|
|
||||||
#include "thread.hpp"
|
#include "thread.hpp"
|
||||||
|
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
class Connection;
|
class Connection;
|
||||||
|
|
||||||
|
|
||||||
|
enum class IrcCommand
|
||||||
|
{
|
||||||
|
UNKNOWN,
|
||||||
|
RPL_WELCOME,
|
||||||
|
RPL_YOURHOST,
|
||||||
|
RPL_CREATED,
|
||||||
|
RPL_MYINFO,
|
||||||
|
RPL_ISUPPORT,
|
||||||
|
RPL_SNOMASK,
|
||||||
|
RPL_REDIR,
|
||||||
|
RPL_MAP,
|
||||||
|
RPL_MAPMORE,
|
||||||
|
RPL_MAPEND,
|
||||||
|
RPL_SAVENICK,
|
||||||
|
RPL_TRACELINK,
|
||||||
|
RPL_TRACECONNECTING,
|
||||||
|
RPL_TRACEHANDSHAKE,
|
||||||
|
RPL_TRACEUNKNOWN,
|
||||||
|
RPL_TRACEOPERATOR,
|
||||||
|
RPL_TRACEUSER,
|
||||||
|
RPL_TRACESERVER,
|
||||||
|
RPL_TRACENEWTYPE,
|
||||||
|
RPL_TRACECLASS,
|
||||||
|
RPL_STATSLINKINFO,
|
||||||
|
RPL_STATSCOMMANDS,
|
||||||
|
RPL_STATSCLINE,
|
||||||
|
RPL_STATSNLINE,
|
||||||
|
RPL_STATSILINE,
|
||||||
|
RPL_STATSKLINE,
|
||||||
|
RPL_STATSQLINE,
|
||||||
|
RPL_STATSYLINE,
|
||||||
|
RPL_ENDOFSTATS,
|
||||||
|
RPL_STATSPLINE,
|
||||||
|
RPL_UMODEIS,
|
||||||
|
RPL_STATSFLINE,
|
||||||
|
RPL_STATSDLINE,
|
||||||
|
RPL_SERVLIST,
|
||||||
|
RPL_SERVLISTEND,
|
||||||
|
RPL_STATSLLINE,
|
||||||
|
RPL_STATSUPTIME,
|
||||||
|
RPL_STATSOLINE,
|
||||||
|
RPL_STATSHLINE,
|
||||||
|
RPL_STATSSLINE,
|
||||||
|
RPL_STATSXLINE,
|
||||||
|
RPL_STATSULINE,
|
||||||
|
RPL_STATSDEBUG,
|
||||||
|
RPL_STATSCONN,
|
||||||
|
RPL_LUSERCLIENT,
|
||||||
|
RPL_LUSEROP,
|
||||||
|
RPL_LUSERUNKNOWN,
|
||||||
|
RPL_LUSERCHANNELS,
|
||||||
|
RPL_LUSERME,
|
||||||
|
RPL_ADMINME,
|
||||||
|
RPL_ADMINLOC1,
|
||||||
|
RPL_ADMINLOC2,
|
||||||
|
RPL_ADMINEMAIL,
|
||||||
|
RPL_TRACELOG,
|
||||||
|
RPL_ENDOFTRACE,
|
||||||
|
RPL_LOAD2HI,
|
||||||
|
RPL_LOCALUSERS,
|
||||||
|
RPL_GLOBALUSERS,
|
||||||
|
RPL_PRIVS,
|
||||||
|
RPL_WHOISCERTFP,
|
||||||
|
RPL_ACCEPTLIST,
|
||||||
|
RPL_ENDOFACCEPT,
|
||||||
|
RPL_NONE,
|
||||||
|
RPL_AWAY,
|
||||||
|
RPL_USERHOST,
|
||||||
|
RPL_ISON,
|
||||||
|
RPL_TEXT,
|
||||||
|
RPL_UNAWAY,
|
||||||
|
RPL_NOWAWAY,
|
||||||
|
RPL_WHOISHELPOP,
|
||||||
|
RPL_WHOISUSER,
|
||||||
|
RPL_WHOISSERVER,
|
||||||
|
RPL_WHOISOPERATOR,
|
||||||
|
RPL_WHOWASUSER,
|
||||||
|
RPL_ENDOFWHOWAS,
|
||||||
|
RPL_WHOISCHANOP,
|
||||||
|
RPL_WHOISIDLE,
|
||||||
|
RPL_ENDOFWHOIS,
|
||||||
|
RPL_WHOISCHANNELS,
|
||||||
|
RPL_WHOISSPECIAL,
|
||||||
|
RPL_LISTSTART,
|
||||||
|
RPL_LIST,
|
||||||
|
RPL_LISTEND,
|
||||||
|
RPL_CHANNELMODEIS,
|
||||||
|
RPL_CHANNELMLOCK,
|
||||||
|
RPL_CHANNELURL,
|
||||||
|
RPL_CREATIONTIME,
|
||||||
|
RPL_WHOISLOGGEDIN,
|
||||||
|
RPL_NOTOPIC,
|
||||||
|
RPL_TOPIC,
|
||||||
|
RPL_TOPICWHOTIME,
|
||||||
|
RPL_WHOISTEXT,
|
||||||
|
RPL_WHOISACTUALLY,
|
||||||
|
RPL_INVITING,
|
||||||
|
RPL_SUMMONING,
|
||||||
|
RPL_INVITELIST,
|
||||||
|
RPL_ENDOFINVITELIST,
|
||||||
|
RPL_EXCEPTLIST,
|
||||||
|
RPL_ENDOFEXCEPTLIST,
|
||||||
|
RPL_VERSION,
|
||||||
|
RPL_WHOREPLY,
|
||||||
|
RPL_WHOSPCRPL,
|
||||||
|
RPL_ENDOFWHO,
|
||||||
|
RPL_NAMREPLY,
|
||||||
|
RPL_WHOWASREAL,
|
||||||
|
RPL_ENDOFNAMES,
|
||||||
|
RPL_KILLDONE,
|
||||||
|
RPL_CLOSING,
|
||||||
|
RPL_CLOSEEND,
|
||||||
|
RPL_LINKS,
|
||||||
|
RPL_ENDOFLINKS,
|
||||||
|
RPL_BANLIST,
|
||||||
|
RPL_ENDOFBANLIST,
|
||||||
|
RPL_INFO,
|
||||||
|
RPL_MOTD,
|
||||||
|
RPL_INFOSTART,
|
||||||
|
RPL_ENDOFINFO,
|
||||||
|
RPL_MOTDSTART,
|
||||||
|
RPL_ENDOFMOTD,
|
||||||
|
RPL_WHOISHOST,
|
||||||
|
RPL_YOUREOPER,
|
||||||
|
RPL_REHASHING,
|
||||||
|
RPL_MYPORTIS,
|
||||||
|
RPL_NOTOPERANYMORE,
|
||||||
|
RPL_RSACHALLENGE,
|
||||||
|
RPL_TIME,
|
||||||
|
RPL_USERSSTART,
|
||||||
|
RPL_USERS,
|
||||||
|
RPL_ENDOFUSERS,
|
||||||
|
RPL_NOUSERS,
|
||||||
|
RPL_HOSTHIDDEN,
|
||||||
|
ERR_NOSUCHNICK,
|
||||||
|
ERR_NOSUCHSERVER,
|
||||||
|
ERR_NOSUCHCHANNEL,
|
||||||
|
ERR_CANNOTSENDTOCHAN,
|
||||||
|
ERR_TOOMANYCHANNELS,
|
||||||
|
ERR_WASNOSUCHNICK,
|
||||||
|
ERR_TOOMANYTARGETS,
|
||||||
|
ERR_NOORIGIN,
|
||||||
|
ERR_INVALIDCAPCMD,
|
||||||
|
ERR_NORECIPIENT,
|
||||||
|
ERR_NOTEXTTOSEND,
|
||||||
|
ERR_NOTOPLEVEL,
|
||||||
|
ERR_WILDTOPLEVEL,
|
||||||
|
ERR_MSGNEEDREGGEDNICK,
|
||||||
|
ERR_TOOMANYMATCHES,
|
||||||
|
ERR_UNKNOWNCOMMAND,
|
||||||
|
ERR_NOMOTD,
|
||||||
|
ERR_NOADMININFO,
|
||||||
|
ERR_FILEERROR,
|
||||||
|
ERR_NONICKNAMEGIVEN,
|
||||||
|
ERR_ERRONEUSNICKNAME,
|
||||||
|
ERR_NICKNAMEINUSE,
|
||||||
|
ERR_BANNICKCHANGE,
|
||||||
|
ERR_NICKCOLLISION,
|
||||||
|
ERR_UNAVAILRESOURCE,
|
||||||
|
ERR_NICKTOOFAST,
|
||||||
|
ERR_SERVICESDOWN,
|
||||||
|
ERR_USERNOTINCHANNEL,
|
||||||
|
ERR_NOTONCHANNEL,
|
||||||
|
ERR_USERONCHANNEL,
|
||||||
|
ERR_NOLOGIN,
|
||||||
|
ERR_SUMMONDISABLED,
|
||||||
|
ERR_USERSDISABLED,
|
||||||
|
ERR_NOTREGISTERED,
|
||||||
|
ERR_ACCEPTFULL,
|
||||||
|
ERR_ACCEPTEXIST,
|
||||||
|
ERR_ACCEPTNOT,
|
||||||
|
ERR_NEEDMOREPARAMS,
|
||||||
|
ERR_ALREADYREGISTRED,
|
||||||
|
ERR_NOPERMFORHOST,
|
||||||
|
ERR_PASSWDMISMATCH,
|
||||||
|
ERR_YOUREBANNEDCREEP,
|
||||||
|
ERR_YOUWILLBEBANNED,
|
||||||
|
ERR_KEYSET,
|
||||||
|
ERR_LINKCHANNEL,
|
||||||
|
ERR_CHANNELISFULL,
|
||||||
|
ERR_UNKNOWNMODE,
|
||||||
|
ERR_INVITEONLYCHAN,
|
||||||
|
ERR_BANNEDFROMCHAN,
|
||||||
|
ERR_BADCHANNELKEY,
|
||||||
|
ERR_BADCHANMASK,
|
||||||
|
ERR_NEEDREGGEDNICK,
|
||||||
|
ERR_BANLISTFULL,
|
||||||
|
ERR_BADCHANNAME,
|
||||||
|
ERR_THROTTLE,
|
||||||
|
ERR_NOPRIVILEGES,
|
||||||
|
ERR_CHANOPRIVSNEEDED,
|
||||||
|
ERR_CANTKILLSERVER,
|
||||||
|
ERR_ISCHANSERVICE,
|
||||||
|
ERR_BANNEDNICK,
|
||||||
|
ERR_NONONREG,
|
||||||
|
ERR_VOICENEEDED,
|
||||||
|
ERR_NOOPERHOST,
|
||||||
|
ERR_CANNOTSENDTOUSER,
|
||||||
|
ERR_OWNMODE,
|
||||||
|
ERR_UMODEUNKNOWNFLAG,
|
||||||
|
ERR_USERSDONTMATCH,
|
||||||
|
ERR_GHOSTEDCLIENT,
|
||||||
|
ERR_USERNOTONSERV,
|
||||||
|
ERR_WRONGPONG,
|
||||||
|
ERR_DISABLED,
|
||||||
|
ERR_HELPNOTFOUND,
|
||||||
|
RPL_STARTTLS,
|
||||||
|
RPL_WHOISSECURE,
|
||||||
|
ERR_STARTTLS,
|
||||||
|
RPL_MODLIST,
|
||||||
|
RPL_ENDOFMODLIST,
|
||||||
|
RPL_HELPSTART,
|
||||||
|
RPL_HELPTXT,
|
||||||
|
RPL_ENDOFHELP,
|
||||||
|
ERR_TARGCHANGE,
|
||||||
|
RPL_ETRACEFULL,
|
||||||
|
RPL_ETRACE,
|
||||||
|
RPL_KNOCK,
|
||||||
|
RPL_KNOCKDLVR,
|
||||||
|
ERR_TOOMANYKNOCK,
|
||||||
|
ERR_CHANOPEN,
|
||||||
|
ERR_KNOCKONCHAN,
|
||||||
|
ERR_KNOCKDISABLED,
|
||||||
|
ERR_TARGUMODEG,
|
||||||
|
RPL_TARGNOTIFY,
|
||||||
|
RPL_UMODEGMSG,
|
||||||
|
RPL_OMOTDSTART,
|
||||||
|
RPL_OMOTD,
|
||||||
|
RPL_ENDOFOMOTD,
|
||||||
|
ERR_NOPRIVS,
|
||||||
|
RPL_TESTMASK,
|
||||||
|
RPL_TESTLINE,
|
||||||
|
RPL_NOTESTLINE,
|
||||||
|
RPL_TESTMASKGECO,
|
||||||
|
RPL_QUIETLIST,
|
||||||
|
RPL_ENDOFQUIETLIS,
|
||||||
|
RPL_MONONLINE,
|
||||||
|
RPL_MONOFFLINE,
|
||||||
|
RPL_MONLIST,
|
||||||
|
RPL_ENDOFMONLIS,
|
||||||
|
ERR_MONLISTFULL,
|
||||||
|
RPL_RSACHALLENGE2,
|
||||||
|
RPL_ENDOFRSACHALLENGE2,
|
||||||
|
ERR_MLOCKRESTRICTE,
|
||||||
|
ERR_INVALIDBAN,
|
||||||
|
ERR_TOPICLOCK,
|
||||||
|
RPL_SCANMATCHED,
|
||||||
|
RPL_SCANUMODES,
|
||||||
|
RPL_LOGGEDIN,
|
||||||
|
RPL_LOGGEDOUT,
|
||||||
|
ERR_NICKLOCKED,
|
||||||
|
RPL_SASLSUCCESS,
|
||||||
|
ERR_SASLFAIL,
|
||||||
|
ERR_SASLTOOLONG,
|
||||||
|
ERR_SASLABORTED,
|
||||||
|
ERR_SASLALREADY,
|
||||||
|
RPL_SASLMECHS,
|
||||||
|
ACCOUNT,
|
||||||
|
AUTHENTICATE,
|
||||||
|
AWAY,
|
||||||
|
BATCH,
|
||||||
|
BOUNCER,
|
||||||
|
CAP,
|
||||||
|
CHGHOST,
|
||||||
|
ERROR,
|
||||||
|
JOIN,
|
||||||
|
KICK,
|
||||||
|
MODE,
|
||||||
|
NICK,
|
||||||
|
NOTICE,
|
||||||
|
PART,
|
||||||
|
PING,
|
||||||
|
PRIVMSG,
|
||||||
|
QUIT,
|
||||||
|
SETNAME,
|
||||||
|
TOPIC,
|
||||||
|
};
|
||||||
|
|
||||||
struct IrcMsgEvent : Event
|
struct IrcMsgEvent : Event
|
||||||
{
|
{
|
||||||
IrcMsgEvent(IrcMsg irc) : irc{irc} {}
|
IrcMsgEvent(IrcCommand command, IrcMsg const& irc)
|
||||||
IrcMsg irc;
|
: command{command}, irc{irc} {}
|
||||||
|
IrcCommand command;
|
||||||
|
IrcMsg const& irc;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto irc_parse_thread(Connection * connection) -> void;
|
auto irc_parse_thread(Connection * connection) -> void;
|
||||||
|
|
4
main.cpp
4
main.cpp
|
@ -36,10 +36,10 @@ auto unhandled_message_thread(Connection * connection) -> void
|
||||||
{
|
{
|
||||||
connection->add_listener<IrcMsgEvent>([](IrcMsgEvent const& event)
|
connection->add_listener<IrcMsgEvent>([](IrcMsgEvent const& event)
|
||||||
{
|
{
|
||||||
if (not event.handled_)
|
if (IrcCommand::UNKNOWN == event.command)
|
||||||
{
|
{
|
||||||
auto& irc = event.irc;
|
auto& irc = event.irc;
|
||||||
std::cout << "Unhandled message " << irc.command;
|
std::cout << "Unknown message " << irc.command;
|
||||||
for (auto const arg : irc.args)
|
for (auto const arg : irc.args)
|
||||||
{
|
{
|
||||||
std::cout << " " << arg;
|
std::cout << " " << arg;
|
||||||
|
|
|
@ -8,7 +8,7 @@ auto ping_thread(Connection * connection) -> void
|
||||||
connection->add_listener<IrcMsgEvent>([connection](IrcMsgEvent& event)
|
connection->add_listener<IrcMsgEvent>([connection](IrcMsgEvent& event)
|
||||||
{
|
{
|
||||||
auto& irc = event.irc;
|
auto& irc = event.irc;
|
||||||
if ("PING" == irc.command && 1 == irc.args.size())
|
if (IrcCommand::PING == event.command)
|
||||||
{
|
{
|
||||||
write_irc(*connection, "PONG", irc.args[0]);
|
write_irc(*connection, "PONG", irc.args[0]);
|
||||||
event.handled_ = true;
|
event.handled_ = true;
|
||||||
|
|
|
@ -116,7 +116,7 @@ auto RegistrationThread::send_req() -> void
|
||||||
auto RegistrationThread::capack(IrcMsg const& msg) -> void
|
auto RegistrationThread::capack(IrcMsg const& msg) -> void
|
||||||
{
|
{
|
||||||
auto const n = msg.args.size();
|
auto const n = msg.args.size();
|
||||||
if ("CAP" == msg.command && n >= 2 && "*" == msg.args[0] && "ACK" == msg.args[1])
|
if (n >= 2 && "*" == msg.args[0] && "ACK" == msg.args[1])
|
||||||
{
|
{
|
||||||
auto in = std::istringstream{std::string{msg.args[2]}};
|
auto in = std::istringstream{std::string{msg.args[2]}};
|
||||||
std::for_each(
|
std::for_each(
|
||||||
|
@ -137,7 +137,7 @@ auto RegistrationThread::capack(IrcMsg const& msg) -> void
|
||||||
auto RegistrationThread::capls(IrcMsg const& msg) -> void
|
auto RegistrationThread::capls(IrcMsg const& msg) -> void
|
||||||
{
|
{
|
||||||
auto const n = msg.args.size();
|
auto const n = msg.args.size();
|
||||||
if ("CAP" == msg.command && n >= 2 && "*" == msg.args[0] && "LS" == msg.args[1])
|
if (n >= 2 && "*" == msg.args[0] && "LS" == msg.args[1])
|
||||||
{
|
{
|
||||||
std::string_view const* kvs;
|
std::string_view const* kvs;
|
||||||
bool last;
|
bool last;
|
||||||
|
@ -201,10 +201,13 @@ auto registration_thread(
|
||||||
std::string nickname
|
std::string nickname
|
||||||
) -> void
|
) -> void
|
||||||
{
|
{
|
||||||
auto thread = std::make_shared<RegistrationThread>(connection, password, username, realname, nickname);
|
auto const thread = std::make_shared<RegistrationThread>(connection, password, username, realname, nickname);
|
||||||
thread->message_handle_ = connection->add_listener<IrcMsgEvent>([thread](IrcMsgEvent const& event)
|
thread->message_handle_ = connection->add_listener<IrcMsgEvent>([thread](IrcMsgEvent const& event)
|
||||||
{
|
{
|
||||||
thread->on_msg(event.irc);
|
if (IrcCommand::CAP == event.command)
|
||||||
|
{
|
||||||
|
thread->on_msg(event.irc);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
thread->connect_handle_ = connection->add_listener<ConnectEvent>([thread](ConnectEvent const&)
|
thread->connect_handle_ = connection->add_listener<ConnectEvent>([thread](ConnectEvent const&)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user