degesch: refactor irc_process_names()

This commit is contained in:
Přemysl Eric Janouch 2015-06-06 00:38:58 +02:00
parent f9eddb8ee2
commit ac6ee9ea80
1 changed files with 33 additions and 28 deletions

View File

@ -4679,12 +4679,36 @@ irc_handle_rpl_namreply (struct server *s, const struct irc_message *msg)
split_str_ignore_empty (nicks, ' ', &channel->names_buf); split_str_ignore_empty (nicks, ' ', &channel->names_buf);
} }
static void
irc_sync_channel_user (struct server *s, struct channel *channel,
const char *nickname, const char *prefixes)
{
struct user *user = irc_get_or_make_user (s, nickname);
struct channel_user *channel_user =
irc_channel_get_user (channel, user);
if (!channel_user)
{
irc_channel_link_user (channel, user, prefixes);
return;
}
user_unref (user);
// If our idea of the user's modes disagrees with what the server's
// sent us (the most powerful modes differ), use the latter one
if (channel_user->prefixes.str[0] != prefixes[0])
{
str_reset (&channel_user->prefixes);
str_append (&channel_user->prefixes, prefixes);
}
}
static void static void
irc_process_names (struct server *s, struct channel *channel) irc_process_names (struct server *s, struct channel *channel)
{ {
struct str_map map; struct str_map present;
str_map_init (&map); str_map_init (&present);
map.key_xfrm = s->irc_strxfrm; present.key_xfrm = s->irc_strxfrm;
struct str_vector *updates = &channel->names_buf; struct str_vector *updates = &channel->names_buf;
for (size_t i = 0; i < updates->len; i++) for (size_t i = 0; i < updates->len; i++)
@ -4694,38 +4718,19 @@ irc_process_names (struct server *s, struct channel *channel)
const char *nickname = item + n_prefixes; const char *nickname = item + n_prefixes;
// Store the nickname in a hashset // Store the nickname in a hashset
str_map_set (&map, nickname, (void *) 1); str_map_set (&present, nickname, (void *) 1);
char prefixes[n_prefixes + 1]; char *prefixes = xstrndup (item, n_prefixes);
memcpy (prefixes, item, n_prefixes); irc_sync_channel_user (s, channel, nickname, prefixes);
prefixes[n_prefixes] = '\0'; free (prefixes);
struct user *user = irc_get_or_make_user (s, nickname);
struct channel_user *channel_user =
irc_channel_get_user (channel, user);
if (!channel_user)
{
irc_channel_link_user (channel, user, prefixes);
continue;
}
user_unref (user);
// If our idea of the user's modes disagrees with what the server's
// sent us (the most powerful modes differ), use the latter one
if (channel_user->prefixes.str[0] == prefixes[0])
continue;
str_reset (&channel_user->prefixes);
str_append (&channel_user->prefixes, prefixes);
} }
// Get rid of channel users missing from "updates" // Get rid of channel users missing from "updates"
LIST_FOR_EACH (struct channel_user, iter, channel->users) LIST_FOR_EACH (struct channel_user, iter, channel->users)
if (!str_map_find (&map, iter->user->nickname)) if (!str_map_find (&present, iter->user->nickname))
irc_channel_unlink_user (channel, iter); irc_channel_unlink_user (channel, iter);
str_map_free (&map); str_map_free (&present);
str_vector_reset (&channel->names_buf); str_vector_reset (&channel->names_buf);
struct str_vector v; struct str_vector v;