diff --git a/c_callback.hpp b/c_callback.hpp new file mode 100644 index 0000000..fbf4dcd --- /dev/null +++ b/c_callback.hpp @@ -0,0 +1,14 @@ +#pragma once + +template struct CCallback_; +template +struct CCallback_ +{ + static R invoke(Ts... args, void* u) + { + return (*reinterpret_cast(u))(args...); + } +}; + +template +using CCallback = CCallback_; diff --git a/snote_thread.cpp b/snote_thread.cpp index 0f08ca9..4ed23ab 100644 --- a/snote_thread.cpp +++ b/snote_thread.cpp @@ -2,6 +2,7 @@ #include "irc_parse_thread.hpp" #include "connection.hpp" +#include "c_callback.hpp" #include #include @@ -45,24 +46,41 @@ SnotePattern const patterns[] = {SnoteTag::TemporaryKlineExpired, R"(^Temporary K-line for \[([^ ]+)\] expired$)"}, + {SnoteTag::PropagatedBanExpired, + R"(^Propagated ban for \[([^ ]+)\] expired$)"}, + {SnoteTag::DisconnectingKlined, R"(^Disconnecting K-Lined user ([^ ]+)\[([^@]+)@([^ ]+)\] \((.*)\)$)"}, + + {SnoteTag::NewPropagatedKline, + R"(^([^ ]+)!([^ ]+)@([^ ]+)\{([^ ]+)\} added global ([^ ]+) min\. K-Line for \[([^ ]+)\] \[(.*)\]$)"}, + + {SnoteTag::NewTemporaryKline, + R"(^([^ ]+)!([^ ]+)@([^ ]+)\{([^ ]+)\} added temporary ([^ ]+) min\. K-Line for \[([^ ]+)\] \[(.*)\]$)"}, + + {SnoteTag::LoginAttempts, + "^Warning: \x02([^ ]+)\x02 failed login attempts to \x02([^ ]+)\x02\\. Last attempt received from \x02(.+)\x02.*$"}, + + {SnoteTag::PossibleFlooder, + R"(^Possible Flooder ([^ ]+)\[([^ ]+)@[^ ]+\] on ([^ ]+) target: ([^ ]+)$)"}, + + {SnoteTag::Killed, + R"(^Received KILL message for ([^ ]+)!([^ ]+)@([^ ]+)\. From ([^ ]+) Path: ([^ ]+) \((.*)\)$)"}, }; auto setup_database() -> hs_database_t* { auto const n = std::size(patterns); std::vector expressions; - std::vector flags(n, 0); + std::vector flags(n, HS_FLAG_SINGLEMATCH); std::vector ids; - expressions.reserve(std::size(patterns)); - ids.reserve(std::size(patterns)); + expressions.reserve(n); + ids.reserve(n); for (std::size_t i = 0; i < n; i++) { expressions.push_back(patterns[i].expression); - flags.push_back(0); ids.push_back(i); } @@ -104,35 +122,37 @@ auto SnoteThread::start(Connection& connection) -> std::shared_ptr connection.add_listener([&connection, thread](IrcMsgEvent& event) { auto& args = event.irc.args; - if (IrcCommand::NOTICE == event.command - && "*" == args[0] - && args[1].starts_with(prefix)) + if (IrcCommand::NOTICE == event.command && "*" == args[0] && args[1].starts_with(prefix)) { event.handled_ = true; - auto message = args[1].substr(strlen(prefix)); - unsigned int match_id = -1; - auto const scan_result = hs_scan(thread->db_.get(), message.data(), message.size(), 0, thread->scratch_.get(), - [](unsigned int id, unsigned long long from, unsigned long long to, unsigned int flags, void *context) -> int - { - int* const match_id = static_cast(context); - *match_id = id; - return 1; // stop scanning - } - , &match_id); - - if (scan_result != HS_SUCCESS && scan_result != HS_SCAN_TERMINATED) + auto const message = args[1].substr(strlen(prefix)); + + unsigned match_id; + auto cb = [&match_id](unsigned id, unsigned long long, unsigned long long, unsigned) -> int { - abort(); - } + match_id = id; + return 1; // stop scanning + }; - if (match_id == -1) + auto const scan_result = + hs_scan( + thread->db_.get(), + message.data(), message.size(), + 0, // no flags + thread->scratch_.get(), + CCallback::invoke, &cb + ); + + switch (scan_result) { + case HS_SUCCESS: std::cout << "Unknown snote: " << message << std::endl; - } - else + break; + + case HS_SCAN_TERMINATED: { auto& pattern = patterns[match_id]; - std::match_results results; + std::match_results results; if (not std::regex_match(message.begin(), message.end(), results, pattern.regex)) { // something went wrong - hyperscan disagrees with std::regex @@ -145,6 +165,11 @@ auto SnoteThread::start(Connection& connection) -> std::shared_ptr parts.push_back(std::string_view{sub.first, sub.second}); } connection.make_event(pattern.tag, std::move(parts)); + break; + } + + default: + abort(); } } }); diff --git a/snote_thread.hpp b/snote_thread.hpp index 0adc77a..5aced50 100644 --- a/snote_thread.hpp +++ b/snote_thread.hpp @@ -16,7 +16,13 @@ enum class SnoteTag NickChange, CreateChannel, TemporaryKlineExpired, + PropagatedBanExpired, DisconnectingKlined, + NewPropagatedKline, + NewTemporaryKline, + LoginAttempts, + PossibleFlooder, + Killed, }; struct SnoteEvent : Event