kike: finish implementation of NAMES
This commit is contained in:
parent
dd91b521df
commit
17be991dce
76
kike.c
76
kike.c
@ -2093,8 +2093,26 @@ irc_append_prefixes (struct client *c, struct channel_user *user,
|
||||
str_free (&prefixes);
|
||||
}
|
||||
|
||||
static char *
|
||||
irc_make_rpl_namreply_item
|
||||
(struct client *c, struct client *target, struct channel_user *user)
|
||||
{
|
||||
struct str result;
|
||||
str_init (&result);
|
||||
|
||||
if (user)
|
||||
irc_append_prefixes (c, user, &result);
|
||||
|
||||
str_append (&result, target->nickname);
|
||||
if (c->caps_enabled & IRC_CAP_USERHOST_IN_NAMES)
|
||||
str_append_printf (&result,
|
||||
"!%s@%s", target->username, target->hostname);
|
||||
return str_steal (&result);
|
||||
}
|
||||
|
||||
static void
|
||||
irc_send_rpl_namreply (struct client *c, const struct channel *chan)
|
||||
irc_send_rpl_namreply (struct client *c, const struct channel *chan,
|
||||
struct str_map *used_nicks)
|
||||
{
|
||||
struct str_vector nicks;
|
||||
str_vector_init (&nicks);
|
||||
@ -2110,15 +2128,10 @@ irc_send_rpl_namreply (struct client *c, const struct channel *chan)
|
||||
{
|
||||
if (!on_channel && (iter->c->mode & IRC_USER_MODE_INVISIBLE))
|
||||
continue;
|
||||
|
||||
struct str result;
|
||||
str_init (&result);
|
||||
irc_append_prefixes (c, iter, &result);
|
||||
str_append (&result, iter->c->nickname);
|
||||
if (c->caps_enabled & IRC_CAP_USERHOST_IN_NAMES)
|
||||
str_append_printf (&result,
|
||||
"!%s@%s", iter->c->username, iter->c->hostname);
|
||||
str_vector_add_owned (&nicks, str_steal (&result));
|
||||
if (used_nicks)
|
||||
str_map_set (used_nicks, iter->c->nickname, (void *) 1);
|
||||
str_vector_add_owned (&nicks,
|
||||
irc_make_rpl_namreply_item (c, iter->c, iter));
|
||||
}
|
||||
|
||||
irc_send_reply_vector (c, IRC_RPL_NAMREPLY,
|
||||
@ -2126,6 +2139,30 @@ irc_send_rpl_namreply (struct client *c, const struct channel *chan)
|
||||
str_vector_free (&nicks);
|
||||
}
|
||||
|
||||
static void
|
||||
irc_send_disassociated_names (struct client *c, struct str_map *used)
|
||||
{
|
||||
struct str_vector nicks;
|
||||
str_vector_init (&nicks);
|
||||
|
||||
struct str_map_iter iter;
|
||||
str_map_iter_init (&iter, &c->ctx->users);
|
||||
struct client *target;
|
||||
while ((target = str_map_iter_next (&iter)))
|
||||
{
|
||||
if ((target->mode & IRC_USER_MODE_INVISIBLE)
|
||||
|| str_map_find (used, target->nickname))
|
||||
continue;
|
||||
str_vector_add_owned (&nicks,
|
||||
irc_make_rpl_namreply_item (c, target, NULL));
|
||||
}
|
||||
|
||||
if (nicks.len)
|
||||
irc_send_reply_vector (c, IRC_RPL_NAMREPLY,
|
||||
nicks.vector, '*', "*", "");
|
||||
str_vector_free (&nicks);
|
||||
}
|
||||
|
||||
static void
|
||||
irc_handle_names (const struct irc_message *msg, struct client *c)
|
||||
{
|
||||
@ -2135,18 +2172,21 @@ irc_handle_names (const struct irc_message *msg, struct client *c)
|
||||
struct channel *chan;
|
||||
if (msg->params.len == 0)
|
||||
{
|
||||
struct str_map used;
|
||||
str_map_init (&used);
|
||||
used.key_xfrm = irc_strxfrm;
|
||||
|
||||
struct str_map_iter iter;
|
||||
str_map_iter_init (&iter, &c->ctx->channels);
|
||||
while ((chan = str_map_iter_next (&iter)))
|
||||
if (!(chan->modes & (IRC_CHAN_MODE_PRIVATE | IRC_CHAN_MODE_SECRET))
|
||||
|| channel_get_user (chan, c))
|
||||
irc_send_rpl_namreply (c, chan);
|
||||
irc_send_rpl_namreply (c, chan, &used);
|
||||
|
||||
// Also send all visible users we haven't listed yet
|
||||
irc_send_disassociated_names (c, &used);
|
||||
str_map_free (&used);
|
||||
|
||||
// TODO
|
||||
// If no <channel> parameter is given, a list of all channels and their
|
||||
// occupants is returned. At the end of this list, a list of users who
|
||||
// are visible but either not on any channel or not on a visible channel
|
||||
// are listed as being on `channel' "*".
|
||||
irc_send_reply (c, IRC_RPL_ENDOFNAMES, "*");
|
||||
}
|
||||
else
|
||||
@ -2159,7 +2199,7 @@ irc_handle_names (const struct irc_message *msg, struct client *c)
|
||||
&& (!(chan->modes & IRC_CHAN_MODE_SECRET)
|
||||
|| channel_get_user (chan, c)))
|
||||
{
|
||||
irc_send_rpl_namreply (c, chan);
|
||||
irc_send_rpl_namreply (c, chan, NULL);
|
||||
irc_send_reply (c, IRC_RPL_ENDOFNAMES, channels.vector[i]);
|
||||
}
|
||||
str_vector_free (&channels);
|
||||
@ -2606,7 +2646,7 @@ irc_try_join (struct client *c, const char *channel_name, const char *key)
|
||||
free (message);
|
||||
|
||||
irc_send_rpl_topic (c, chan);
|
||||
irc_send_rpl_namreply (c, chan);
|
||||
irc_send_rpl_namreply (c, chan, NULL);
|
||||
irc_send_reply (c, IRC_RPL_ENDOFNAMES, chan->name);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user