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