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
1 changed files with 16 additions and 11 deletions

View File

@ -4686,40 +4686,45 @@ irc_process_names (struct server *s, struct channel *channel)
str_map_init (&map);
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;
for (size_t i = 0; i < updates->len; i++)
{
const char *item = updates->vector[i];
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];
memcpy (prefixes, item, n_prefixes);
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)
{
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);
}
else
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
else if (channel_user->prefixes.str[0] == prefixes[0])
if (channel_user->prefixes.str[0] == prefixes[0])
continue;
str_reset (&channel_user->prefixes);
str_append (&channel_user->prefixes, prefixes);
}
// TODO: get rid of channel users missing from "updates":
// either mark them or don't initialize the map with them
// Get rid of channel users missing from "updates"
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_vector_reset (&channel->names_buf);