Allow multi-line /me and split long /me messages
/me shouldn't behave differently from a regular message.master
parent
e8be141cc0
commit
64d14d3541
53
command.c
53
command.c
|
@ -64,8 +64,7 @@ static void echoMessage(char *cmd, uint id, char *params) {
|
||||||
handle(&msg);
|
handle(&msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void splitMessage(char *cmd, uint id, char *params) {
|
static int splitChunk(const char *cmd, uint id) {
|
||||||
if (!params) return;
|
|
||||||
int overhead = snprintf(
|
int overhead = snprintf(
|
||||||
NULL, 0, ":%s!%*s@%*s %s %s :\r\n",
|
NULL, 0, ":%s!%*s@%*s %s %s :\r\n",
|
||||||
self.nick,
|
self.nick,
|
||||||
|
@ -74,22 +73,32 @@ static void splitMessage(char *cmd, uint id, char *params) {
|
||||||
cmd, idNames[id]
|
cmd, idNames[id]
|
||||||
);
|
);
|
||||||
assert(overhead > 0 && overhead < 512);
|
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')) {
|
if (strlen(params) <= (size_t)chunk && !strchr(params, '\n')) {
|
||||||
echoMessage(cmd, id, params);
|
echoMessage(cmd, id, params);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (*params) {
|
while (*params) {
|
||||||
int len = 0;
|
int len = splitLen(chunk, params);
|
||||||
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;
|
|
||||||
}
|
|
||||||
char ch = params[len];
|
char ch = params[len];
|
||||||
params[len] = '\0';
|
params[len] = '\0';
|
||||||
echoMessage(cmd, id, params);
|
echoMessage(cmd, id, params);
|
||||||
|
@ -109,8 +118,20 @@ static void commandNotice(uint id, char *params) {
|
||||||
|
|
||||||
static void commandMe(uint id, char *params) {
|
static void commandMe(uint id, char *params) {
|
||||||
char buf[512];
|
char buf[512];
|
||||||
snprintf(buf, sizeof(buf), "\1ACTION %s\1", (params ?: ""));
|
if (!params) params = "";
|
||||||
echoMessage("PRIVMSG", id, buf);
|
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) {
|
static void commandMsg(uint id, char *params) {
|
||||||
|
@ -505,7 +526,7 @@ static const struct Handler {
|
||||||
{ "/join", commandJoin, Kiosk },
|
{ "/join", commandJoin, Kiosk },
|
||||||
{ "/kick", commandKick, 0 },
|
{ "/kick", commandKick, 0 },
|
||||||
{ "/list", commandList, Kiosk },
|
{ "/list", commandList, Kiosk },
|
||||||
{ "/me", commandMe, 0 },
|
{ "/me", commandMe, Multiline },
|
||||||
{ "/mode", commandMode, 0 },
|
{ "/mode", commandMode, 0 },
|
||||||
{ "/move", commandMove, 0 },
|
{ "/move", commandMove, 0 },
|
||||||
{ "/msg", commandMsg, Multiline | Kiosk },
|
{ "/msg", commandMsg, Multiline | Kiosk },
|
||||||
|
|
Loading…
Reference in New Issue