From 64d14d354156332b8fd71f8e40761a69721737b2 Mon Sep 17 00:00:00 2001 From: C. McEnroe Date: Sun, 14 Mar 2021 17:36:16 -0400 Subject: Allow multi-line /me and split long /me messages /me shouldn't behave differently from a regular message. --- command.c | 53 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 16 deletions(-) (limited to 'command.c') diff --git a/command.c b/command.c index 1154942..5af3e25 100644 --- a/command.c +++ b/command.c @@ -64,8 +64,7 @@ static void echoMessage(char *cmd, uint id, char *params) { handle(&msg); } -static void splitMessage(char *cmd, uint id, char *params) { - if (!params) return; +static int splitChunk(const char *cmd, uint id) { int overhead = snprintf( NULL, 0, ":%s!%*s@%*s %s %s :\r\n", self.nick, @@ -74,22 +73,32 @@ static void splitMessage(char *cmd, uint id, char *params) { cmd, idNames[id] ); assert(overhead > 0 && overhead < 512); - int chunk = 512 - overhead; + return 512 - overhead; +} + +static int splitLen(int chunk, const char *params) { + int len = 0; + size_t cap = 1 + strlen(params); + for (int n = 0; params[len] != '\n' && len + n <= chunk; len += n) { + n = mblen(¶ms[len], cap - len); + if (n < 0) { + n = 1; + mblen(NULL, 0); + } + if (!n) break; + } + return len; +} + +static void splitMessage(char *cmd, uint id, char *params) { + if (!params) return; + int chunk = splitChunk(cmd, id); if (strlen(params) <= (size_t)chunk && !strchr(params, '\n')) { echoMessage(cmd, id, params); return; } - while (*params) { - int len = 0; - for (int n = 0; params[len] != '\n' && len + n <= chunk; len += n) { - n = mblen(¶ms[len], 1 + strlen(¶ms[len])); - if (n < 0) { - n = 1; - mblen(NULL, 0); - } - if (!n) break; - } + int len = splitLen(chunk, params); char ch = params[len]; params[len] = '\0'; echoMessage(cmd, id, params); @@ -109,8 +118,20 @@ static void commandNotice(uint id, char *params) { static void commandMe(uint id, char *params) { char buf[512]; - snprintf(buf, sizeof(buf), "\1ACTION %s\1", (params ?: "")); - echoMessage("PRIVMSG", id, buf); + if (!params) params = ""; + int chunk = splitChunk("PRIVMSG \1ACTION\1", id); + if (strlen(params) <= (size_t)chunk && !strchr(params, '\n')) { + snprintf(buf, sizeof(buf), "\1ACTION %s\1", params); + echoMessage("PRIVMSG", id, buf); + return; + } + while (*params) { + int len = splitLen(chunk, params); + snprintf(buf, sizeof(buf), "\1ACTION %.*s\1", len, params); + echoMessage("PRIVMSG", id, buf); + params += len; + if (*params == '\n') params++; + } } static void commandMsg(uint id, char *params) { @@ -505,7 +526,7 @@ static const struct Handler { { "/join", commandJoin, Kiosk }, { "/kick", commandKick, 0 }, { "/list", commandList, Kiosk }, - { "/me", commandMe, 0 }, + { "/me", commandMe, Multiline }, { "/mode", commandMode, 0 }, { "/move", commandMove, 0 }, { "/msg", commandMsg, Multiline | Kiosk }, -- cgit 1.4.1-2-gfad0