AmendHub

Download:

jcs

/

wallops

/

amendments

/

129

*: Support /monitor and its numerics, do better server reconnecting

Monitor commands are sent as-is to the server, but we now parse each
numeric response.
 
When reconnecting to a new server, don't send the initial autojoin
channels, build a list of channels based on what we're currently
joined to and then autojoin those, to reactivate each tab.

jcs made amendment 129 2 months ago
--- chatter.c Wed Sep 18 10:05:20 2024 +++ chatter.c Sun Sep 22 16:46:36 2024 @@ -1456,6 +1456,7 @@ chatter_sync_nick_list(struct chatter *chatter, struct nick = &channel->nicks[nick->next_nick]; } + tab->ignore_activity = true; chatter_printf(chatter, channel->connection, channel->name, "$B%s$0: Total of $B%ld$0 nick%s $B(%ld$0 op%s, $B%ld$0 " "voice%s$B)$0", @@ -1463,6 +1464,7 @@ chatter_sync_nick_list(struct chatter *chatter, struct channel->nnicks == 1 ? "" : "s", ops, ops == 1 ? "" : "s", voices, voices == 1 ? "" : "s"); + tab->ignore_activity = false; } LDoDraw(true, tab->nick_list); --- irc.c Sun Sep 22 14:05:47 2024 +++ irc.c Sun Sep 22 17:14:39 2024 @@ -458,6 +458,7 @@ irc_process_server(struct irc_connection *conn) struct irc_msg msg; struct irc_user *user; struct irc_channel *channel; + struct chatter_tab *tab; char *line, *word; size_t size, n, lastbreak; short curarg; @@ -903,14 +904,22 @@ irc_process_server(struct irc_connection *conn) strlcat(msg.msg, " ", sizeof(msg.msg)); strlcat(msg.msg, msg.arg[5], sizeof(msg.msg)); } - chatter_printf(conn->chatter, conn, msg.arg[1], - "$B***$0 Mode for $B%s$0:$/ %s", - msg.arg[1], msg.msg); if ((channel = irc_find_channel(conn, msg.arg[1]))) { + if (channel->chatter && channel->mode[0] == '\0') { + /* initial mode set from join is unimportant */ + tab = chatter_find_tab(conn->chatter, conn, msg.arg[1]); + if (tab) + tab->ignore_activity = true; + } strlcpy(channel->mode, msg.msg, sizeof(channel->mode)); if (channel->chatter) channel->chatter->need_tab_bar_redraw = true; } + chatter_printf(conn->chatter, conn, msg.arg[1], + "$B***$0 Mode for $B%s$0:$/ %s", + msg.arg[1], msg.msg); + if (tab) + tab->ignore_activity = false; return true; case 328: /* channel URL, we probably can't do anything with it anyway */ @@ -1020,6 +1029,12 @@ irc_process_server(struct irc_connection *conn) irc_send(conn, conn->line, len); return true; } + case 461: + /* not enough args */ + chatter_printf(conn->chatter, conn, NULL, + "$B***$0 $B%s$0$/: %s", + msg.arg[1], msg.msg); + return true; case 475: /* can't join channel */ chatter_printf(conn->chatter, conn, NULL, @@ -1051,6 +1066,35 @@ irc_process_server(struct irc_connection *conn) "$B*** |$0 Connection:$/ %s", msg.msg); return true; + case 730: + /* monitor online */ + chatter_printf(conn->chatter, conn, NULL, + "$B***$0 $B%s$0$/ %s online", + msg.msg, strstr(msg.msg, ",") ? "are" : "is"); + if (conn->chatter->focusable && !conn->chatter->focusable->visible) + notify(); + return true; + case 731: + /* monitor offline */ + chatter_printf(conn->chatter, conn, NULL, + "$B***$0 $B%s$0$/ %s offline", + msg.msg, strstr(msg.msg, ",") ? "are" : "is"); + return true; + case 732: + /* monitor list */ + chatter_printf(conn->chatter, conn, NULL, + "$B***$0 Monitor list: %s", + msg.msg); + return true; + case 733: + /* end of monitor list */ + return true; + case 734: + /* monitor error */ + chatter_printf(conn->chatter, conn, NULL, + "$B***$0 Monitor error: %s", + msg.msg); + return true; case 900: /* nickserv login */ chatter_printf(conn->chatter, conn, NULL, @@ -1108,15 +1152,40 @@ irc_process_input(struct irc_connection *conn, struct strncasecmp(str, "/server ", 8) == 0) { struct irc_connection *new; struct chatter_tab *tab; + char *autojoin = NULL; + size_t len; str++; arg0 = strsep(&str, " "); if (strcasecmp(arg0, "server") == 0 && str == NULL) goto not_enough_params; + /* build a new list of autojoin channels based on what's joined */ + len = 0; + SLIST_FOREACH(tab, &conn->chatter->tabs_list, list) { + if (tab->conn == conn && tab->channel) + len += strlen(tab->channel->name) + 1; + } + if (len) { + autojoin = xmalloc(len); + if (autojoin == NULL) { + chatter_printf(conn->chatter, conn, NULL, + "$B*!*$0 Can't allocate memory for autojoin"); + return; + } + autojoin[0] = '\0'; + SLIST_FOREACH(tab, &conn->chatter->tabs_list, list) { + if (tab->conn == conn && tab->channel) { + if (autojoin[0]) + strlcat(autojoin, ",", len); + strlcat(autojoin, tab->channel->name, len); + } + } + } + new = irc_connect(conn->chatter, str ? str : conn->hostname, conn->port, conn->password, conn->nick, conn->ident, - conn->realname, conn->hide_motd, conn->channel_autojoin); + conn->realname, conn->hide_motd, autojoin); if (new->state == IRC_STATE_UNREGISTERED) { /* the new connection succeeded, kill the old one */ @@ -1252,6 +1321,12 @@ irc_process_input(struct irc_connection *conn, struct goto not_in_channel; irc_printf(conn, "MODE %s%s%s\r\n", channel_name, (str ? " " : ""), (str ? str : "")); + return; + } + if (strcasecmp(arg0, "monitor") == 0) { + if (str == NULL) + goto not_enough_params; + irc_printf(conn, "MONITOR %s\r\n", str); return; } if (strcasecmp(arg0, "msg") == 0) { --- README Fri Sep 20 12:57:51 2024 +++ README Sun Sep 22 17:18:26 2024 @@ -35,6 +35,7 @@ See http://jcs.org/wallops for more information and ve /join - join a channel and create a new tab for it /me - send an action /mode - change mode on a channel + /monitor - send raw monitor commands to server /msg - send a private message to a user /nick - change your nick name /op - grant operator privileges to given users