From 17f7b201aa6236d074792d6e270302765b1d8fff Mon Sep 17 00:00:00 2001 From: "C. McEnroe" Date: Tue, 25 Feb 2020 19:09:33 -0500 Subject: Support message-tags --- bounce.h | 3 ++- client.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++----- pounce.1 | 1 + server.c | 2 +- 4 files changed, 53 insertions(+), 7 deletions(-) diff --git a/bounce.h b/bounce.h index da52592..7f7c247 100644 --- a/bounce.h +++ b/bounce.h @@ -71,6 +71,7 @@ static inline struct Message parse(char *line) { 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) \ @@ -81,7 +82,7 @@ enum Cap { #define X(name, id) BIT(id), ENUM_CAP #undef X - TagCaps = CapServerTime, + TagCaps = CapMessageTags | CapServerTime, }; static const char *CapNames[] = { diff --git a/client.c b/client.c index 8a4e86f..b81732d 100644 --- a/client.c +++ b/client.c @@ -227,17 +227,45 @@ static void handleQuit(struct Client *client, struct Message *msg) { static void handlePrivmsg(struct Client *client, struct Message *msg) { if (!msg->params[0] || !msg->params[1]) return; - char line[1024]; + char line[MessageCap]; + if (msg->tags) { + snprintf( + line, sizeof(line), "@%s :%s %s %s :%s", + msg->tags, stateEcho(), msg->cmd, msg->params[0], msg->params[1] + ); + } else { + snprintf( + line, sizeof(line), ":%s %s %s :%s", + stateEcho(), msg->cmd, msg->params[0], msg->params[1] + ); + } + size_t diff = ringDiff(client->consumer); + ringProduce(line); + if (!diff) ringConsume(NULL, client->consumer); + if (!strcmp(msg->params[0], stateNick())) return; + + if (msg->tags) { + serverFormat( + "@%s %s %s :%s\r\n", + msg->tags, msg->cmd, msg->params[0], msg->params[1] + ); + } else { + serverFormat("%s %s :%s\r\n", msg->cmd, msg->params[0], msg->params[1]); + } +} + +static void handleTagmsg(struct Client *client, struct Message *msg) { + if (!msg->tags || !msg->params[0]) return; + char line[MessageCap]; snprintf( - line, sizeof(line), ":%s %s %s :%s", - stateEcho(), msg->cmd, msg->params[0], msg->params[1] + line, sizeof(line), "@%s :%s TAGMSG %s", + msg->tags, stateEcho(), msg->params[0] ); size_t diff = ringDiff(client->consumer); ringProduce(line); if (!diff) ringConsume(NULL, client->consumer); if (!strcmp(msg->params[0], stateNick())) return; - - serverFormat("%s %s :%s\r\n", msg->cmd, msg->params[0], msg->params[1]); + serverFormat("@%s TAGMSG %s\r\n", msg->tags, msg->params[0]); } static const struct { @@ -252,6 +280,7 @@ static const struct { { "PASS", handlePass, false }, { "PRIVMSG", handlePrivmsg, true }, { "QUIT", handleQuit, true }, + { "TAGMSG", handleTagmsg, true }, { "USER", handleUser, false }, }; @@ -268,10 +297,20 @@ static void clientParse(struct Client *client, char *line) { } static bool intercept(const char *line, size_t len) { + if (line[0] == '@') { + const char *sp = memchr(line, ' ', len); + len -= sp - line; + line = sp; + if (len) { + len--; + line++; + } + } if (len >= 4 && !memcmp(line, "CAP ", 4)) return true; if (len == 4 && !memcmp(line, "QUIT", 4)) return true; if (len >= 5 && !memcmp(line, "QUIT ", 5)) return true; if (len >= 7 && !memcmp(line, "NOTICE ", 7)) return true; + if (len >= 7 && !memcmp(line, "TAGMSG ", 7)) return true; if (len >= 8 && !memcmp(line, "PRIVMSG ", 8)) return true; return false; } @@ -396,6 +435,10 @@ static const char *filterInviteNotify(const char *line) { return (wordcmp(line, 2, stateNick()) ? NULL : line); } +static const char *filterMessageTags(const char *line) { + return (wordcmp(line, 1, "TAGMSG") ? line : NULL); +} + static const char *filterMultiPrefix(const char *line) { static char buf[MessageCap + 1]; if (!wordcmp(line, 1, "352")) { @@ -437,6 +480,7 @@ static Filter *Filters[] = { [CapChghostBit] = filterChghost, [CapExtendedJoinBit] = filterExtendedJoin, [CapInviteNotifyBit] = filterInviteNotify, + [CapMessageTagsBit] = filterMessageTags, [CapMultiPrefixBit] = filterMultiPrefix, [CapUserhostInNamesBit] = filterUserhostInNames, }; diff --git a/pounce.1 b/pounce.1 index 7ed431f..a205857 100644 --- a/pounce.1 +++ b/pounce.1 @@ -342,6 +342,7 @@ is supported: .Sy chghost , .Sy extended-join , .Sy invite-notify , +.Sy message-tags , .Sy multi-prefix , .Sy server-time , .Sy userhost-in-names . diff --git a/server.c b/server.c index e8c8880..abc7d40 100644 --- a/server.c +++ b/server.c @@ -139,7 +139,7 @@ void serverSend(const char *ptr, size_t len) { } void serverFormat(const char *format, ...) { - char buf[1024]; + char buf[MessageCap]; va_list ap; va_start(ap, format); int len = vsnprintf(buf, sizeof(buf), format, ap); -- cgit 1.4.1