From 8570a62235e5e9b6a6d719fd8b92cedc91a1d511 Mon Sep 17 00:00:00 2001 From: "C. McEnroe" Date: Sat, 29 Feb 2020 01:03:46 -0500 Subject: [PATCH] Implement the causal.agency/consumer capability --- catgirl.1 | 14 +++++++++++++- chat.h | 3 +++ handle.c | 11 ++++++++--- ui.c | 10 ++++++++-- 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/catgirl.1 b/catgirl.1 index b1b72de..a69d282 100644 --- a/catgirl.1 +++ b/catgirl.1 @@ -1,4 +1,4 @@ -.Dd February 23, 2020 +.Dd February 29, 2020 .Dt CATGIRL 1 .Os . @@ -658,6 +658,18 @@ join = #ascii.town .Re .El . +.Ss Extensions +The +.Nm +client can take advantage of the +.Sy causal.agency/consumer +vendor-specific IRCv3 capability +implemented by +.Xr pounce 1 . +The consumer position is stored in the +.Cm save +file. +. .Sh AUTHORS .An June Bug Aq Mt june@causal.agency . diff --git a/chat.h b/chat.h index 5b4e14c..91d175f 100644 --- a/chat.h +++ b/chat.h @@ -96,6 +96,7 @@ extern struct Network { } network; #define ENUM_CAP \ + X("causal.agency/consumer", CapConsumer) \ X("extended-join", CapExtendedJoin) \ X("invite-notify", CapInviteNotify) \ X("multi-prefix", CapMultiPrefix) \ @@ -112,6 +113,7 @@ enum Cap { extern struct Self { bool debug; bool restricted; + size_t pos; enum Cap caps; char *plain; char *join; @@ -128,6 +130,7 @@ static inline void set(char **field, const char *value) { } #define ENUM_TAG \ + X("causal.agency/pos", TagPos) \ X("time", TagTime) enum Tag { diff --git a/handle.c b/handle.c index 58fdce2..0a1dedb 100644 --- a/handle.c +++ b/handle.c @@ -126,6 +126,10 @@ static void handleCap(struct Message *msg) { enum Cap caps = capParse(msg->params[2]); if (!strcmp(msg->params[1], "LS")) { caps &= ~CapSASL; + if (caps & CapConsumer && self.pos) { + ircFormat("CAP REQ %s=%zu\r\n", CapNames[CapConsumerBit], self.pos); + caps &= ~CapConsumer; + } if (caps) { ircFormat("CAP REQ :%s\r\n", capList(caps)); } else { @@ -1019,9 +1023,10 @@ void handle(struct Message msg) { ); if (handler) { handler->fn(&msg); - return; - } - if (strcmp(msg.cmd, "400") >= 0 && strcmp(msg.cmd, "599") <= 0) { + } else if (strcmp(msg.cmd, "400") >= 0 && strcmp(msg.cmd, "599") <= 0) { handleErrorGeneric(&msg); } + if (msg.tags[TagPos]) { + self.pos = strtoull(msg.tags[TagPos], NULL, 10); + } } diff --git a/ui.c b/ui.c index d6f79c2..b3f3b09 100644 --- a/ui.c +++ b/ui.c @@ -960,7 +960,8 @@ void uiRead(void) { static const time_t Signatures[] = { 0x6C72696774616301, // no heat, unread, unreadWarm - 0x6C72696774616302, + 0x6C72696774616302, // no self.pos + 0x6C72696774616303, }; static size_t signatureVersion(time_t signature) { @@ -981,7 +982,8 @@ int uiSave(const char *name) { FILE *file = dataOpen(name, "w"); if (!file) return -1; - if (writeTime(file, Signatures[1])) return -1; + if (writeTime(file, Signatures[2])) return -1; + if (writeTime(file, self.pos)) return -1; for (uint num = 0; num < windows.len; ++num) { const struct Window *window = windows.ptrs[num]; if (writeString(file, idNames[window->id])) return -1; @@ -1032,6 +1034,10 @@ void uiLoad(const char *name) { } size_t version = signatureVersion(signature); + if (version > 1) { + self.pos = readTime(file); + } + char *buf = NULL; size_t cap = 0; while (0 < readString(file, &buf, &cap)) {