diff options
Diffstat (limited to '')
-rw-r--r-- | catgirl.1 | 14 | ||||
-rw-r--r-- | chat.h | 3 | ||||
-rw-r--r-- | filter.c | 29 |
3 files changed, 45 insertions, 1 deletions
diff --git a/catgirl.1 b/catgirl.1 index c5ac74e..9954def 100644 --- a/catgirl.1 +++ b/catgirl.1 @@ -935,6 +935,20 @@ catgirl freenode .Re .It .Rs +.%A James Wheare +.%T Reply Client Tag +.%I IRCv3 Working Group +.%U https://ircv3.net/specs/client-tags/reply +.Re +.It +.Rs +.%A James Wheare +.%T Message IDs +.%I IRCv3 Working Group +.%U https://ircv3.net/specs/extensions/message-ids +.Re +.It +.Rs .%A K. Zeilenga, Ed. .%T The PLAIN Simple Authentication and Security Layer (SASL) Mechanism .%I IETF diff --git a/chat.h b/chat.h index eb826a8..fadbc30 100644 --- a/chat.h +++ b/chat.h @@ -171,6 +171,7 @@ extern struct Network { X("chghost", CapChghost) \ X("extended-join", CapExtendedJoin) \ X("invite-notify", CapInviteNotify) \ + X("message-tags", CapMessageTags) \ X("multi-prefix", CapMultiPrefix) \ X("sasl", CapSASL) \ X("server-time", CapServerTime) \ @@ -205,7 +206,9 @@ static inline void set(char **field, const char *value) { } #define ENUM_TAG \ + X("+draft/reply", TagReply) \ X("causal.agency/pos", TagPos) \ + X("msgid", TagMsgID) \ X("time", TagTime) enum Tag { diff --git a/filter.c b/filter.c index a648d8b..63c3369 100644 --- a/filter.c +++ b/filter.c @@ -94,12 +94,39 @@ static bool filterTest( return !fnmatch(filter.mesg, msg->params[1], FNM_CASEFOLD); } +enum { IcedCap = 8 }; +static struct { + size_t len; + char *msgIDs[IcedCap]; +} iced; + +static void icedPush(const char *msgID) { + if (!msgID) return; + size_t i = iced.len % IcedCap; + free(iced.msgIDs[i]); + iced.msgIDs[i] = strdup(msgID); + if (!iced.msgIDs[i]) err(EX_OSERR, "strdup"); + iced.len++; +} + enum Heat filterCheck(enum Heat heat, uint id, const struct Message *msg) { if (!len) return heat; + + if (msg->tags[TagReply]) { + for (size_t i = 0; i < IcedCap; ++i) { + if (!iced.msgIDs[i]) continue; + if (strcmp(msg->tags[TagReply], iced.msgIDs[i])) continue; + icedPush(msg->tags[TagMsgID]); + return Ice; + } + } + char mask[512]; snprintf(mask, sizeof(mask), "%s!%s@%s", msg->nick, msg->user, msg->host); for (size_t i = 0; i < len; ++i) { - if (filterTest(filters[i], mask, id, msg)) return filters[i].heat; + if (!filterTest(filters[i], mask, id, msg)) continue; + if (filters[i].heat == Ice) icedPush(msg->tags[TagMsgID]); + return filters[i].heat; } return heat; } |