degesch: correctly update user prefixes
This commit is contained in:
parent
c8aff23ab2
commit
7f57bed563
56
degesch.c
56
degesch.c
|
@ -820,13 +820,14 @@ struct channel_user
|
||||||
LIST_HEADER (struct channel_user)
|
LIST_HEADER (struct channel_user)
|
||||||
|
|
||||||
struct user *user; ///< Reference to user
|
struct user *user; ///< Reference to user
|
||||||
char *modes; ///< Ordered @+... characters
|
struct str prefixes; ///< Ordered @+... characters
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct channel_user *
|
static struct channel_user *
|
||||||
channel_user_new (void)
|
channel_user_new (void)
|
||||||
{
|
{
|
||||||
struct channel_user *self = xcalloc (1, sizeof *self);
|
struct channel_user *self = xcalloc (1, sizeof *self);
|
||||||
|
str_init (&self->prefixes);
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -834,7 +835,7 @@ static void
|
||||||
channel_user_destroy (struct channel_user *self)
|
channel_user_destroy (struct channel_user *self)
|
||||||
{
|
{
|
||||||
user_unref (self->user);
|
user_unref (self->user);
|
||||||
free (self->modes);
|
str_free (&self->prefixes);
|
||||||
free (self);
|
free (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3878,7 +3879,6 @@ irc_handle_join (struct server *s, const struct irc_message *msg)
|
||||||
|
|
||||||
struct channel_user *channel_user = channel_user_new ();
|
struct channel_user *channel_user = channel_user_new ();
|
||||||
channel_user->user = user;
|
channel_user->user = user;
|
||||||
channel_user->modes = xstrdup ("");
|
|
||||||
LIST_PREPEND (channel->users, channel_user);
|
LIST_PREPEND (channel->users, channel_user);
|
||||||
|
|
||||||
// Finally log the message
|
// Finally log the message
|
||||||
|
@ -3938,8 +3938,8 @@ struct mode_processor
|
||||||
|
|
||||||
char **params; ///< Mode string parameters
|
char **params; ///< Mode string parameters
|
||||||
|
|
||||||
struct server *s; ///< Who does the changes
|
struct server *s; ///< Server
|
||||||
struct channel *channel; ///< The channel we're modifying
|
struct channel *channel; ///< The channel being modified
|
||||||
|
|
||||||
// Internals:
|
// Internals:
|
||||||
|
|
||||||
|
@ -3978,24 +3978,27 @@ mode_processor_do_user (struct mode_processor *self)
|
||||||
if (!channel_user)
|
if (!channel_user)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char prefix = self->s->irc_chanuser_prefixes
|
const char *all_prefixes = self->s->irc_chanuser_prefixes;
|
||||||
[strchr (self->s->irc_chanuser_modes, self->mode_char)
|
const char *all_modes = self->s->irc_chanuser_modes;
|
||||||
- self->s->irc_chanuser_modes];
|
char prefix = all_prefixes[strchr (all_modes, self->mode_char) - all_modes];
|
||||||
|
|
||||||
// XXX: shouldn't this rather be a "struct str"?
|
struct str *prefixes = &channel_user->prefixes;
|
||||||
char *modes = channel_user->modes;
|
const char *pos = strchr (prefixes->str, prefix);
|
||||||
char *pos = strchr (modes, self->mode_char);
|
|
||||||
if (self->adding == !!pos)
|
if (self->adding == !!pos)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (self->adding)
|
if (self->adding)
|
||||||
{
|
{
|
||||||
// FIXME: this doesn't give two fucks about the correct order
|
// Add the new mode prefix while retaining the right order
|
||||||
channel_user->modes = xstrdup_printf ("%s%c", modes, prefix);
|
char *old_prefixes = str_steal (prefixes);
|
||||||
free (modes);
|
str_init (prefixes);
|
||||||
|
for (const char *p = all_prefixes; *p; p++)
|
||||||
|
if (*p == prefix || strchr (old_prefixes, *p))
|
||||||
|
str_append_c (prefixes, *p);
|
||||||
|
free (old_prefixes);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
memmove (pos, pos + 1, strlen (pos + 1));
|
str_remove_slice (prefixes, pos - prefixes->str, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -4689,26 +4692,27 @@ irc_process_names (struct server *s, struct channel *channel)
|
||||||
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];
|
||||||
const char *nick = item + strspn (item, s->irc_chanuser_prefixes);
|
size_t n_prefixes = strspn (item, s->irc_chanuser_prefixes);
|
||||||
char *modes = xstrndup (item, nick - item);
|
const char *nick = item + n_prefixes;
|
||||||
|
|
||||||
|
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 channel_user *channel_user = str_map_find (&map, nick);
|
||||||
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 = irc_get_or_make_user (s, nick);
|
||||||
channel_user->modes = modes;
|
|
||||||
LIST_PREPEND (channel->users, channel_user);
|
LIST_PREPEND (channel->users, channel_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->modes[0] != modes[0])
|
else if (channel_user->prefixes.str[0] == prefixes[0])
|
||||||
{
|
continue;
|
||||||
free (channel_user->modes);
|
|
||||||
channel_user->modes = modes;
|
str_reset (&channel_user->prefixes);
|
||||||
}
|
str_append (&channel_user->prefixes, prefixes);
|
||||||
else
|
|
||||||
free (modes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: get rid of channel users missing from "updates":
|
// TODO: get rid of channel users missing from "updates":
|
||||||
|
@ -4721,7 +4725,7 @@ irc_process_names (struct server *s, struct channel *channel)
|
||||||
str_vector_init (&v);
|
str_vector_init (&v);
|
||||||
LIST_FOR_EACH (struct channel_user, iter, channel->users)
|
LIST_FOR_EACH (struct channel_user, iter, channel->users)
|
||||||
str_vector_add_owned (&v,
|
str_vector_add_owned (&v,
|
||||||
xstrdup_printf ("%s%s", iter->modes, iter->user->nickname));
|
xstrdup_printf ("%s%s", iter->prefixes.str, iter->user->nickname));
|
||||||
char *all_users = join_str_vector (&v, ' ');
|
char *all_users = join_str_vector (&v, ' ');
|
||||||
str_vector_free (&v);
|
str_vector_free (&v);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue