degesch: NICK handling cleanup
This commit is contained in:
parent
9603bae003
commit
c3439175d7
86
degesch.c
86
degesch.c
|
@ -4357,27 +4357,6 @@ irc_handle_mode (struct server *s, const struct irc_message *msg)
|
||||||
refresh_prompt (s->ctx);
|
refresh_prompt (s->ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct buffer *
|
|
||||||
irc_handle_buffer_collision (struct server *s,
|
|
||||||
struct buffer *buffer, const char *new_name)
|
|
||||||
{
|
|
||||||
struct buffer *collision = str_map_find (&s->irc_buffer_map, new_name);
|
|
||||||
if (!collision)
|
|
||||||
return buffer;
|
|
||||||
|
|
||||||
// TODO: use full weechat-style buffer names
|
|
||||||
// to prevent name collisions with the global buffer
|
|
||||||
hard_assert (collision->type == buffer->type);
|
|
||||||
|
|
||||||
// When there's a collision, there's not much else we can do
|
|
||||||
// other than somehow try to merge them
|
|
||||||
buffer_merge (s->ctx, collision, buffer);
|
|
||||||
if (s->ctx->current_buffer == buffer)
|
|
||||||
buffer_activate (s->ctx, collision);
|
|
||||||
buffer_remove (s->ctx, buffer);
|
|
||||||
return collision;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
irc_handle_nick (struct server *s, const struct irc_message *msg)
|
irc_handle_nick (struct server *s, const struct irc_message *msg)
|
||||||
{
|
{
|
||||||
|
@ -4392,17 +4371,16 @@ irc_handle_nick (struct server *s, const struct irc_message *msg)
|
||||||
if (!user)
|
if (!user)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool lexicographically_identical =
|
bool lexicographically_different =
|
||||||
!irc_server_strcmp (s, user->nickname, new_nickname);
|
!!irc_server_strcmp (s, user->nickname, new_nickname);
|
||||||
|
|
||||||
// What the fuck, someone renamed themselves to ourselves
|
// What the fuck, someone renamed themselves to ourselves
|
||||||
// TODO: probably log a message and force a reconnect
|
// TODO: probably log a message and force a reconnect
|
||||||
if (!lexicographically_identical
|
if (lexicographically_different
|
||||||
&& !irc_server_strcmp (s, new_nickname, s->irc_user->nickname))
|
&& !irc_server_strcmp (s, new_nickname, s->irc_user->nickname))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Log a message in any PM buffer and rename it;
|
// Log a message in any PM buffer (we may even have one for ourselves)
|
||||||
// we may even have one for ourselves
|
|
||||||
struct buffer *pm_buffer =
|
struct buffer *pm_buffer =
|
||||||
str_map_find (&s->irc_buffer_map, user->nickname);
|
str_map_find (&s->irc_buffer_map, user->nickname);
|
||||||
if (pm_buffer)
|
if (pm_buffer)
|
||||||
|
@ -4413,21 +4391,45 @@ irc_handle_nick (struct server *s, const struct irc_message *msg)
|
||||||
buffer_send (s->ctx, pm_buffer, BUFFER_LINE_NICK, 0,
|
buffer_send (s->ctx, pm_buffer, BUFFER_LINE_NICK, 0,
|
||||||
.who = who,
|
.who = who,
|
||||||
.object = irc_to_utf8 (s->ctx, new_nickname));
|
.object = irc_to_utf8 (s->ctx, new_nickname));
|
||||||
|
}
|
||||||
|
|
||||||
if (!lexicographically_identical)
|
// The new nickname may collide with a user referenced by a PM buffer,
|
||||||
{
|
// or in case of data inconsistency with the server, channels.
|
||||||
// XXX: this code seems a bit ugly (but also necessary)
|
// In the latter case we need the colliding user to leave all of them.
|
||||||
user = user_ref (user);
|
struct user *user_collision = NULL;
|
||||||
|
if (lexicographically_different
|
||||||
|
&& (user_collision = str_map_find (&s->irc_users, new_nickname)))
|
||||||
|
LIST_FOR_EACH (struct user_channel, iter, user_collision->channels)
|
||||||
|
irc_remove_user_from_channel (user_collision, iter->channel);
|
||||||
|
|
||||||
pm_buffer = irc_handle_buffer_collision
|
struct buffer *buffer_collision = NULL;
|
||||||
(s, pm_buffer, new_nickname);
|
if (lexicographically_different
|
||||||
|
&& (buffer_collision = str_map_find (&s->irc_buffer_map, new_nickname)))
|
||||||
|
{
|
||||||
|
hard_assert (buffer_collision->type == BUFFER_PM);
|
||||||
|
hard_assert (buffer_collision->user == user_collision);
|
||||||
|
|
||||||
user_unref (pm_buffer->user);
|
user_unref (buffer_collision->user);
|
||||||
pm_buffer->user = user;
|
buffer_collision->user = user_ref (user);
|
||||||
|
|
||||||
str_map_set (&s->irc_buffer_map, user->nickname, NULL);
|
// There's not much else we can do other than somehow try to merge
|
||||||
str_map_set (&s->irc_buffer_map, new_nickname, pm_buffer);
|
// one buffer into the other. In our case, the original buffer wins.
|
||||||
}
|
buffer_merge (s->ctx, buffer_collision, pm_buffer);
|
||||||
|
if (s->ctx->current_buffer == pm_buffer)
|
||||||
|
buffer_activate (s->ctx, buffer_collision);
|
||||||
|
buffer_remove (s->ctx, pm_buffer);
|
||||||
|
pm_buffer = buffer_collision;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The colliding user should be completely destroyed by now
|
||||||
|
if (lexicographically_different)
|
||||||
|
hard_assert (!str_map_find (&s->irc_users, new_nickname));
|
||||||
|
|
||||||
|
// Now we can rename the PM buffer to reflect the new nickname
|
||||||
|
if (pm_buffer)
|
||||||
|
{
|
||||||
|
str_map_set (&s->irc_buffer_map, user->nickname, NULL);
|
||||||
|
str_map_set (&s->irc_buffer_map, new_nickname, pm_buffer);
|
||||||
|
|
||||||
char *x = xstrdup_printf ("%s.%s", s->name, new_nickname);
|
char *x = xstrdup_printf ("%s.%s", s->name, new_nickname);
|
||||||
buffer_rename (s->ctx, pm_buffer, x);
|
buffer_rename (s->ctx, pm_buffer, x);
|
||||||
|
@ -4464,13 +4466,9 @@ irc_handle_nick (struct server *s, const struct irc_message *msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally rename the user
|
// Finally rename the user as it should be safe now
|
||||||
if (!lexicographically_identical)
|
str_map_set (&s->irc_users, user->nickname, NULL);
|
||||||
{
|
str_map_set (&s->irc_users, new_nickname, user);
|
||||||
// NOTE: this doesn't dereference anything
|
|
||||||
str_map_set (&s->irc_users, user->nickname, NULL);
|
|
||||||
str_map_set (&s->irc_users, new_nickname, user);
|
|
||||||
}
|
|
||||||
|
|
||||||
free (user->nickname);
|
free (user->nickname);
|
||||||
user->nickname = xstrdup (new_nickname);
|
user->nickname = xstrdup (new_nickname);
|
||||||
|
|
Loading…
Reference in New Issue