degesch: mostly implement NICK handling
Except for the corner case where two buffers merge.
This commit is contained in:
parent
3fa9a67a59
commit
590fc6cf26
92
degesch.c
92
degesch.c
@ -403,10 +403,6 @@ struct app_context
|
||||
// especially for away status polling)
|
||||
|
||||
// XXX: there can be buffers for non-existent users
|
||||
// TODO: user buffers rename on nick changes
|
||||
// TODO: move entries in "irc_buffer_map" and "irc_users" when that happens
|
||||
// TODO: user buffers may merge when an existing user renames to match
|
||||
// the name of a buffer for a non-existent user
|
||||
// TODO: initialize key_strxfrm according to server properties;
|
||||
// note that collisions may arise on reconnecting
|
||||
// TODO: when disconnected, get rid of all users everywhere;
|
||||
@ -1156,6 +1152,49 @@ buffer_activate (struct app_context *ctx, struct buffer *buffer)
|
||||
refresh_prompt (ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
buffer_merge (struct app_context *ctx,
|
||||
struct buffer *buffer, struct buffer *merged)
|
||||
{
|
||||
// TODO: try to merge the buffers as best as we can
|
||||
}
|
||||
|
||||
static void
|
||||
buffer_rename (struct app_context *ctx,
|
||||
struct buffer *buffer, const char *new_name)
|
||||
{
|
||||
hard_assert (buffer->type == BUFFER_PM);
|
||||
|
||||
struct buffer *collision =
|
||||
str_map_find (&ctx->irc_buffer_map, new_name);
|
||||
if (collision)
|
||||
{
|
||||
// TODO: use full weechat-style buffer names
|
||||
// to prevent name collisions with the global buffer
|
||||
hard_assert (collision->type == BUFFER_PM);
|
||||
|
||||
// When there's a collision, there's not much else we can do
|
||||
// other than somehow trying to merge them
|
||||
buffer_merge (ctx, collision, buffer);
|
||||
// TODO: log a status message about the merge
|
||||
if (ctx->current_buffer == buffer)
|
||||
buffer_activate (ctx, collision);
|
||||
buffer_remove (ctx, buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise we just rename the buffer and that's it
|
||||
str_map_set (&ctx->buffers_by_name, buffer->name, NULL);
|
||||
str_map_set (&ctx->buffers_by_name, new_name, buffer);
|
||||
|
||||
free (buffer->name);
|
||||
buffer->name = xstrdup (new_name);
|
||||
|
||||
// We might have renamed the current buffer
|
||||
refresh_prompt (ctx);
|
||||
}
|
||||
}
|
||||
|
||||
static struct buffer *
|
||||
buffer_at_index (struct app_context *ctx, int n)
|
||||
{
|
||||
@ -1848,13 +1887,31 @@ irc_handle_nick (struct app_context *ctx, const struct irc_message *msg)
|
||||
if (!msg->prefix || msg->params.len < 1)
|
||||
return;
|
||||
|
||||
const char *new_nickname = msg->params.vector[0];
|
||||
|
||||
char *nickname = irc_cut_nickname (msg->prefix);
|
||||
struct user *user = str_map_find (&ctx->irc_users, nickname);
|
||||
free (nickname);
|
||||
if (!user)
|
||||
return;
|
||||
|
||||
const char *new_nickname = msg->params.vector[0];
|
||||
// What the fuck
|
||||
// TODO: probably log a message and force a reconnect
|
||||
if (str_map_find (&ctx->irc_users, new_nickname))
|
||||
return;
|
||||
|
||||
// Log a message in any PM buffer and rename it;
|
||||
// we may even have one for ourselves
|
||||
struct buffer *pm_buffer =
|
||||
str_map_find (&ctx->irc_buffer_map, user->nickname);
|
||||
if (pm_buffer)
|
||||
{
|
||||
buffer_send (ctx, pm_buffer, BUFFER_LINE_NICK, 0,
|
||||
msg->prefix, NULL, "%s", new_nickname);
|
||||
// TODO: use a full weechat-style buffer name here
|
||||
buffer_rename (ctx, pm_buffer, new_nickname);
|
||||
}
|
||||
|
||||
if (irc_is_this_us (ctx, msg->prefix))
|
||||
{
|
||||
// Log a message in all open buffers on this server
|
||||
@ -1863,26 +1920,21 @@ irc_handle_nick (struct app_context *ctx, const struct irc_message *msg)
|
||||
struct buffer *buffer;
|
||||
while ((buffer = str_map_iter_next (&iter)))
|
||||
{
|
||||
// We've already done that
|
||||
if (buffer == pm_buffer)
|
||||
continue;
|
||||
|
||||
buffer_send (ctx, buffer, BUFFER_LINE_NICK, 0,
|
||||
NULL, NULL, "%s", new_nickname);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Log a message in any PM buffer
|
||||
struct buffer *buffer =
|
||||
str_map_find (&ctx->irc_buffer_map, user->nickname);
|
||||
if (buffer)
|
||||
{
|
||||
buffer_send (ctx, buffer, BUFFER_LINE_NICK, 0,
|
||||
msg->prefix, NULL, "%s", new_nickname);
|
||||
// TODO: rename the buffer, and if it collides, merge them
|
||||
}
|
||||
|
||||
// Log a message in all channels the user is in
|
||||
LIST_FOR_EACH (struct user_channel, iter, user->channels)
|
||||
{
|
||||
buffer = str_map_find (&ctx->irc_buffer_map, iter->channel->name);
|
||||
struct buffer *buffer =
|
||||
str_map_find (&ctx->irc_buffer_map, iter->channel->name);
|
||||
hard_assert (buffer != NULL);
|
||||
buffer_send (ctx, buffer, BUFFER_LINE_NICK, 0,
|
||||
msg->prefix, NULL, "%s", new_nickname);
|
||||
@ -1890,6 +1942,9 @@ irc_handle_nick (struct app_context *ctx, const struct irc_message *msg)
|
||||
}
|
||||
|
||||
// Finally rename the user
|
||||
str_map_set (&ctx->irc_users, new_nickname, user_ref (user));
|
||||
str_map_set (&ctx->irc_users, user->nickname, NULL);
|
||||
|
||||
free (user->nickname);
|
||||
user->nickname = xstrdup (new_nickname);
|
||||
|
||||
@ -2644,8 +2699,11 @@ on_irc_disconnected (struct app_context *ctx)
|
||||
xclose (ctx->irc_fd);
|
||||
ctx->irc_fd = -1;
|
||||
ctx->irc_ready = false;
|
||||
|
||||
str_map_set (&ctx->irc_users, ctx->irc_user->nickname, NULL);
|
||||
user_unref (ctx->irc_user);
|
||||
ctx->irc_user = NULL;
|
||||
|
||||
free (ctx->irc_user_mode);
|
||||
ctx->irc_user_mode = NULL;
|
||||
free (ctx->irc_user_host);
|
||||
@ -2815,6 +2873,8 @@ irc_connect (struct app_context *ctx, struct error **e)
|
||||
// XXX: maybe we should wait for the first message from the server
|
||||
ctx->irc_user = user_new ();
|
||||
ctx->irc_user->nickname = xstrdup (nickname);
|
||||
str_map_set (&ctx->irc_users, nickname, user_ref (ctx->irc_user));
|
||||
|
||||
ctx->irc_user_mode = xstrdup ("");
|
||||
ctx->irc_user_host = NULL;
|
||||
return true;
|
||||
|
Loading…
Reference in New Issue
Block a user