diff --git a/degesch.c b/degesch.c index 57d8f78..dd7afaa 100644 --- a/degesch.c +++ b/degesch.c @@ -4404,9 +4404,38 @@ irc_handle_rpl_namreply (struct server *s, const struct irc_message *msg) static void irc_process_names (struct server *s, struct channel *channel) { - // TODO: overwrite users with "channel->names_buf", which contains - // [@+]-prefixed nicknames; take care to combine channel user modes + struct str_map map; + str_map_init (&map); + // FIXME: use a server-specific strxfrm + map.key_xfrm = 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]; + // FIXME: use server-specific chanmode characters + const char *nick = item + strspn (item, "@+"); + struct channel_user *channel_user = str_map_find (&map, nick); + if (!channel_user) + { + channel_user = channel_user_new (); + channel_user->user = irc_get_or_make_user (s, nick); + channel_user->modes = xstrdup (""); + LIST_PREPEND (channel->users, channel_user); + } + + // TODO: update the user's modes + } + + // TODO: get rid of channel users missing from "updates": + // either mark them or don't initialize the map with them + + str_map_free (&map); str_vector_reset (&channel->names_buf); } @@ -5637,6 +5666,7 @@ handle_command_names (struct app_context *ctx, char *arguments) if (!server_command_check (ctx, "names", true)) return true; + // TODO: use our list of channel_users instead if we know the channel struct server *s = ctx->current_buffer->server; char *channel_name = try_get_channel (ctx, &arguments); if (!channel_name)