xC: don't autoactivate buffers on forced JOINs

This commit is contained in:
Přemysl Eric Janouch 2022-09-07 19:04:23 +02:00
parent 2075c38fd1
commit a2d5995cf5
Signed by: p
GPG Key ID: A0420B94F92B9493
2 changed files with 44 additions and 7 deletions

2
NEWS
View File

@ -12,6 +12,8 @@ Unreleased
* xC: improved pager integration capabilities
* xC: unsolicited JOINs will no longer automatically activate the buffer
* xC: normalized editline's history behaviour, making it a viable frontend
* xC: various bugfixes

49
xC.c
View File

@ -1801,6 +1801,8 @@ struct server
char *irc_user_host; ///< Our current user@host
bool autoaway_active; ///< Autoaway is currently active
struct strv outstanding_joins; ///< JOINs we expect a response to
struct strv cap_ls_buf; ///< Buffer for IRCv3.2 CAP LS
bool cap_echo_message; ///< Whether the server echoes messages
bool cap_away_notify; ///< Whether we get AWAY notifications
@ -1934,6 +1936,7 @@ server_new (struct poller *poller)
self->irc_user_mode = str_make ();
self->outstanding_joins = strv_make ();
self->cap_ls_buf = strv_make ();
server_init_specifics (self);
return self;
@ -1981,6 +1984,7 @@ server_destroy (struct server *self)
str_free (&self->irc_user_mode);
free (self->irc_user_host);
strv_free (&self->outstanding_joins);
strv_free (&self->cap_ls_buf);
server_free_specifics (self);
free (self);
@ -5670,6 +5674,7 @@ irc_destroy_state (struct server *s)
str_reset (&s->irc_user_mode);
cstr_set (&s->irc_user_host, NULL);
strv_reset (&s->outstanding_joins);
strv_reset (&s->cap_ls_buf);
s->cap_away_notify = false;
s->cap_echo_message = false;
@ -7103,6 +7108,16 @@ irc_handle_sent_cap (struct server *s, const struct irc_message *msg)
"#s: #S", "Capabilities requested", args);
}
static void
irc_handle_sent_join (struct server *s, const struct irc_message *msg)
{
if (msg->params.len < 1)
return;
if (strcmp (msg->params.vector[0], "0"))
cstr_split (msg->params.vector[0], ",", true, &s->outstanding_joins);
}
static void
irc_handle_sent_notice_text (struct server *s,
const struct irc_message *msg, struct str *text)
@ -7186,6 +7201,7 @@ g_irc_sent_handlers[] =
{
// This list needs to stay sorted
{ "CAP", irc_handle_sent_cap },
{ "JOIN", irc_handle_sent_join },
{ "NOTICE", irc_handle_sent_notice },
{ "PRIVMSG", irc_handle_sent_privmsg },
};
@ -7435,12 +7451,27 @@ irc_handle_invite (struct server *s, const struct irc_message *msg)
"#n has invited #n to #S", msg->prefix, target, channel_name);
}
static bool
irc_satisfy_join (struct server *s, const char *target)
{
// This queue could use some garbage collection,
// but it's unlikely to pose problems.
for (size_t i = 0; i < s->outstanding_joins.len; i++)
if (!irc_server_strcmp (s, target, s->outstanding_joins.vector[i]))
{
strv_remove (&s->outstanding_joins, i);
return true;
}
return false;
}
static void
irc_handle_join (struct server *s, const struct irc_message *msg)
{
if (!msg->prefix || msg->params.len < 1)
return;
// TODO: RFC 2812 doesn't guarantee that the argument isn't a target list.
const char *channel_name = msg->params.vector[0];
if (!irc_is_channel (s, channel_name))
return;
@ -7466,7 +7497,7 @@ irc_handle_join (struct server *s, const struct irc_message *msg)
buffer_add (s->ctx, buffer);
char *input = CALL_ (s->ctx->input, get_line, NULL);
if (!*input)
if (irc_satisfy_join (s, channel_name) && !*input)
buffer_activate (s->ctx, buffer);
else
buffer->highlighted = true;
@ -8841,12 +8872,16 @@ irc_process_numeric (struct server *s,
// TODO: whitelist/blacklist a lot more replies in here.
// TODO: we should either strip the first parameter from the resulting
// buffer line, or at least put it in brackets
if (msg->params.len > 1)
{
struct buffer *x;
if ((x = str_map_find (&s->irc_buffer_map, msg->params.vector[1])))
buffer = x;
}
if (msg->params.len < 2)
break;
struct buffer *x;
if ((x = str_map_find (&s->irc_buffer_map, msg->params.vector[1])))
buffer = x;
// A JOIN request should be split at commas,
// then for each element produce either a JOIN response, or a numeric.
(void) irc_satisfy_join (s, msg->params.vector[1]);
}
if (buffer)