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)
|
||||
|
||||
struct user *user; ///< Reference to user
|
||||
char *modes; ///< Ordered @+... characters
|
||||
struct str prefixes; ///< Ordered @+... characters
|
||||
};
|
||||
|
||||
static struct channel_user *
|
||||
channel_user_new (void)
|
||||
{
|
||||
struct channel_user *self = xcalloc (1, sizeof *self);
|
||||
str_init (&self->prefixes);
|
||||
return self;
|
||||
}
|
||||
|
||||
@ -834,7 +835,7 @@ static void
|
||||
channel_user_destroy (struct channel_user *self)
|
||||
{
|
||||
user_unref (self->user);
|
||||
free (self->modes);
|
||||
str_free (&self->prefixes);
|
||||
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 ();
|
||||
channel_user->user = user;
|
||||
channel_user->modes = xstrdup ("");
|
||||
LIST_PREPEND (channel->users, channel_user);
|
||||
|
||||
// Finally log the message
|
||||
@ -3938,8 +3938,8 @@ struct mode_processor
|
||||
|
||||
char **params; ///< Mode string parameters
|
||||
|
||||
struct server *s; ///< Who does the changes
|
||||
struct channel *channel; ///< The channel we're modifying
|
||||
struct server *s; ///< Server
|
||||
struct channel *channel; ///< The channel being modified
|
||||
|
||||
// Internals:
|
||||
|
||||
@ -3978,24 +3978,27 @@ mode_processor_do_user (struct mode_processor *self)
|
||||
if (!channel_user)
|
||||
return;
|
||||
|
||||
char prefix = self->s->irc_chanuser_prefixes
|
||||
[strchr (self->s->irc_chanuser_modes, self->mode_char)
|
||||
- self->s->irc_chanuser_modes];
|
||||
const char *all_prefixes = self->s->irc_chanuser_prefixes;
|
||||
const char *all_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"?
|
||||
char *modes = channel_user->modes;
|
||||
char *pos = strchr (modes, self->mode_char);
|
||||
struct str *prefixes = &channel_user->prefixes;
|
||||
const char *pos = strchr (prefixes->str, prefix);
|
||||
if (self->adding == !!pos)
|
||||
return;
|
||||
|
||||
if (self->adding)
|
||||
{
|
||||
// FIXME: this doesn't give two fucks about the correct order
|
||||
channel_user->modes = xstrdup_printf ("%s%c", modes, prefix);
|
||||
free (modes);
|
||||
// Add the new mode prefix while retaining the right order
|
||||
char *old_prefixes = str_steal (prefixes);
|
||||
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
|
||||
memmove (pos, pos + 1, strlen (pos + 1));
|
||||
str_remove_slice (prefixes, pos - prefixes->str, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -4689,26 +4692,27 @@ irc_process_names (struct server *s, struct channel *channel)
|
||||
for (size_t i = 0; i < updates->len; i++)
|
||||
{
|
||||
const char *item = updates->vector[i];
|
||||
const char *nick = item + strspn (item, s->irc_chanuser_prefixes);
|
||||
char *modes = xstrndup (item, nick - item);
|
||||
size_t n_prefixes = strspn (item, s->irc_chanuser_prefixes);
|
||||
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);
|
||||
if (!channel_user)
|
||||
{
|
||||
channel_user = channel_user_new ();
|
||||
channel_user->user = irc_get_or_make_user (s, nick);
|
||||
channel_user->modes = modes;
|
||||
LIST_PREPEND (channel->users, channel_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->modes[0] != modes[0])
|
||||
{
|
||||
free (channel_user->modes);
|
||||
channel_user->modes = modes;
|
||||
}
|
||||
else
|
||||
free (modes);
|
||||
else 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":
|
||||
@ -4721,7 +4725,7 @@ irc_process_names (struct server *s, struct channel *channel)
|
||||
str_vector_init (&v);
|
||||
LIST_FOR_EACH (struct channel_user, iter, channel->users)
|
||||
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, ' ');
|
||||
str_vector_free (&v);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user