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);
|
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
|
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;
|
struct str_vector nicks;
|
||||||
str_vector_init (&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))
|
if (!on_channel && (iter->c->mode & IRC_USER_MODE_INVISIBLE))
|
||||||
continue;
|
continue;
|
||||||
|
if (used_nicks)
|
||||||
struct str result;
|
str_map_set (used_nicks, iter->c->nickname, (void *) 1);
|
||||||
str_init (&result);
|
str_vector_add_owned (&nicks,
|
||||||
irc_append_prefixes (c, iter, &result);
|
irc_make_rpl_namreply_item (c, iter->c, iter));
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
irc_send_reply_vector (c, IRC_RPL_NAMREPLY,
|
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);
|
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
|
static void
|
||||||
irc_handle_names (const struct irc_message *msg, struct client *c)
|
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;
|
struct channel *chan;
|
||||||
if (msg->params.len == 0)
|
if (msg->params.len == 0)
|
||||||
{
|
{
|
||||||
|
struct str_map used;
|
||||||
|
str_map_init (&used);
|
||||||
|
used.key_xfrm = irc_strxfrm;
|
||||||
|
|
||||||
struct str_map_iter iter;
|
struct str_map_iter iter;
|
||||||
str_map_iter_init (&iter, &c->ctx->channels);
|
str_map_iter_init (&iter, &c->ctx->channels);
|
||||||
while ((chan = str_map_iter_next (&iter)))
|
while ((chan = str_map_iter_next (&iter)))
|
||||||
if (!(chan->modes & (IRC_CHAN_MODE_PRIVATE | IRC_CHAN_MODE_SECRET))
|
if (!(chan->modes & (IRC_CHAN_MODE_PRIVATE | IRC_CHAN_MODE_SECRET))
|
||||||
|| channel_get_user (chan, c))
|
|| 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, "*");
|
irc_send_reply (c, IRC_RPL_ENDOFNAMES, "*");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2159,7 +2199,7 @@ irc_handle_names (const struct irc_message *msg, struct client *c)
|
||||||
&& (!(chan->modes & IRC_CHAN_MODE_SECRET)
|
&& (!(chan->modes & IRC_CHAN_MODE_SECRET)
|
||||||
|| channel_get_user (chan, c)))
|
|| 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]);
|
irc_send_reply (c, IRC_RPL_ENDOFNAMES, channels.vector[i]);
|
||||||
}
|
}
|
||||||
str_vector_free (&channels);
|
str_vector_free (&channels);
|
||||||
|
@ -2606,7 +2646,7 @@ irc_try_join (struct client *c, const char *channel_name, const char *key)
|
||||||
free (message);
|
free (message);
|
||||||
|
|
||||||
irc_send_rpl_topic (c, chan);
|
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);
|
irc_send_reply (c, IRC_RPL_ENDOFNAMES, chan->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue