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)
|
// especially for away status polling)
|
||||||
|
|
||||||
// XXX: there can be buffers for non-existent users
|
// 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;
|
// TODO: initialize key_strxfrm according to server properties;
|
||||||
// note that collisions may arise on reconnecting
|
// note that collisions may arise on reconnecting
|
||||||
// TODO: when disconnected, get rid of all users everywhere;
|
// 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);
|
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 *
|
static struct buffer *
|
||||||
buffer_at_index (struct app_context *ctx, int n)
|
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)
|
if (!msg->prefix || msg->params.len < 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
const char *new_nickname = msg->params.vector[0];
|
||||||
|
|
||||||
char *nickname = irc_cut_nickname (msg->prefix);
|
char *nickname = irc_cut_nickname (msg->prefix);
|
||||||
struct user *user = str_map_find (&ctx->irc_users, nickname);
|
struct user *user = str_map_find (&ctx->irc_users, nickname);
|
||||||
free (nickname);
|
free (nickname);
|
||||||
if (!user)
|
if (!user)
|
||||||
return;
|
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))
|
if (irc_is_this_us (ctx, msg->prefix))
|
||||||
{
|
{
|
||||||
// Log a message in all open buffers on this server
|
// 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;
|
struct buffer *buffer;
|
||||||
while ((buffer = str_map_iter_next (&iter)))
|
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,
|
buffer_send (ctx, buffer, BUFFER_LINE_NICK, 0,
|
||||||
NULL, NULL, "%s", new_nickname);
|
NULL, NULL, "%s", new_nickname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
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
|
// Log a message in all channels the user is in
|
||||||
LIST_FOR_EACH (struct user_channel, iter, user->channels)
|
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);
|
hard_assert (buffer != NULL);
|
||||||
buffer_send (ctx, buffer, BUFFER_LINE_NICK, 0,
|
buffer_send (ctx, buffer, BUFFER_LINE_NICK, 0,
|
||||||
msg->prefix, NULL, "%s", new_nickname);
|
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
|
// 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);
|
free (user->nickname);
|
||||||
user->nickname = xstrdup (new_nickname);
|
user->nickname = xstrdup (new_nickname);
|
||||||
|
|
||||||
@ -2644,8 +2699,11 @@ on_irc_disconnected (struct app_context *ctx)
|
|||||||
xclose (ctx->irc_fd);
|
xclose (ctx->irc_fd);
|
||||||
ctx->irc_fd = -1;
|
ctx->irc_fd = -1;
|
||||||
ctx->irc_ready = false;
|
ctx->irc_ready = false;
|
||||||
|
|
||||||
|
str_map_set (&ctx->irc_users, ctx->irc_user->nickname, NULL);
|
||||||
user_unref (ctx->irc_user);
|
user_unref (ctx->irc_user);
|
||||||
ctx->irc_user = NULL;
|
ctx->irc_user = NULL;
|
||||||
|
|
||||||
free (ctx->irc_user_mode);
|
free (ctx->irc_user_mode);
|
||||||
ctx->irc_user_mode = NULL;
|
ctx->irc_user_mode = NULL;
|
||||||
free (ctx->irc_user_host);
|
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
|
// XXX: maybe we should wait for the first message from the server
|
||||||
ctx->irc_user = user_new ();
|
ctx->irc_user = user_new ();
|
||||||
ctx->irc_user->nickname = xstrdup (nickname);
|
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_mode = xstrdup ("");
|
||||||
ctx->irc_user_host = NULL;
|
ctx->irc_user_host = NULL;
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
Reference in New Issue
Block a user