degesch: remove users missing from RPL_NAMREPLY

This commit is contained in:
Přemysl Eric Janouch 2015-06-06 00:10:20 +02:00
parent 4bac248c50
commit 2fe17ae79b

View File

@ -4686,40 +4686,45 @@ irc_process_names (struct server *s, struct channel *channel)
str_map_init (&map); str_map_init (&map);
map.key_xfrm = s->irc_strxfrm; map.key_xfrm = s->irc_strxfrm;
// Initialize list of users
LIST_FOR_EACH (struct channel_user, iter, channel->users)
str_map_set (&map, iter->user->nickname, iter);
// Update them with contents of RPL_NAMES
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++)
{ {
const char *item = updates->vector[i]; const char *item = updates->vector[i];
size_t n_prefixes = strspn (item, s->irc_chanuser_prefixes); size_t n_prefixes = strspn (item, s->irc_chanuser_prefixes);
const char *nick = item + n_prefixes; const char *nickname = item + n_prefixes;
// Store the nickname in a hashset
str_map_set (&map, nickname, (void *) 1);
char prefixes[n_prefixes + 1]; char prefixes[n_prefixes + 1];
memcpy (prefixes, item, n_prefixes); memcpy (prefixes, item, n_prefixes);
prefixes[n_prefixes] = '\0'; prefixes[n_prefixes] = '\0';
struct channel_user *channel_user = str_map_find (&map, nick); struct user *user = irc_get_or_make_user (s, nickname);
struct channel_user *channel_user =
irc_channel_get_user (channel, user);
if (!channel_user) if (!channel_user)
{ {
channel_user = channel_user_new (); channel_user = channel_user_new ();
channel_user->user = irc_get_or_make_user (s, nick); channel_user->user = user;
LIST_PREPEND (channel->users, channel_user); LIST_PREPEND (channel->users, channel_user);
} }
else
user_unref (user);
// If our idea of the user's modes disagrees with what the server's // 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 // sent us (the most powerful modes differ), use the latter one
else if (channel_user->prefixes.str[0] == prefixes[0]) if (channel_user->prefixes.str[0] == prefixes[0])
continue; continue;
str_reset (&channel_user->prefixes); str_reset (&channel_user->prefixes);
str_append (&channel_user->prefixes, prefixes); str_append (&channel_user->prefixes, prefixes);
} }
// TODO: get rid of channel users missing from "updates": // Get rid of channel users missing from "updates"
// either mark them or don't initialize the map with them LIST_FOR_EACH (struct channel_user, iter, channel->users)
if (!str_map_find (&map, iter->user->nickname))
irc_channel_unlink_user (channel, iter);
str_map_free (&map); str_map_free (&map);
str_vector_reset (&channel->names_buf); str_vector_reset (&channel->names_buf);