diff options
author | Přemysl Eric Janouch <p@janouch.name> | 2021-05-30 08:06:38 +0200 |
---|---|---|
committer | Přemysl Eric Janouch <p@janouch.name> | 2021-05-30 08:06:38 +0200 |
commit | c1d69e36304c09869f5948695b87252a3a898d47 (patch) | |
tree | 5eaca0c979031c653eb606351f353bcac253526f /degesch.c | |
parent | c75ef167f21c398856706468ca3917f9b64cef32 (diff) | |
download | xK-c1d69e36304c09869f5948695b87252a3a898d47.tar.gz xK-c1d69e36304c09869f5948695b87252a3a898d47.tar.xz xK-c1d69e36304c09869f5948695b87252a3a898d47.zip |
degesch: add support for IRCv3 chghost
This is somewhat similar to a nick change.
Diffstat (limited to 'degesch.c')
-rw-r--r-- | degesch.c | 56 |
1 files changed, 55 insertions, 1 deletions
@@ -2341,7 +2341,7 @@ static struct config_schema g_config_server[] = .type = CONFIG_ITEM_STRING_ARRAY, .validate = config_validate_nonjunk_string, .default_ = "\"multi-prefix,invite-notify,server-time,echo-message," - "message-tags,away-notify,cap-notify\"" }, + "message-tags,away-notify,cap-notify,chghost\"" }, { .name = "tls", .comment = "Whether to use TLS", @@ -4035,6 +4035,13 @@ log_full (struct app_context *ctx, struct server *s, struct buffer *buffer, log_server ((s), (buffer), BUFFER_LINE_STATUS | BUFFER_LINE_UNIMPORTANT, \ "#n is now known as #n", (old), (new_)) +#define log_chghost_self(s, buffer, new_) \ + log_server ((s), (buffer), BUFFER_LINE_STATUS | BUFFER_LINE_UNIMPORTANT, \ + "You are now #N", (new_)) +#define log_chghost(s, buffer, old, new_) \ + log_server ((s), (buffer), BUFFER_LINE_STATUS | BUFFER_LINE_UNIMPORTANT, \ + "#N is now #N", (old), (new_)) + #define log_outcoming_notice(s, buffer, who, text) \ log_server_status ((s), (buffer), "#s(#n): #m", "Notice", (who), (text)) #define log_outcoming_privmsg(s, buffer, prefixes, who, text) \ @@ -6670,6 +6677,52 @@ irc_handle_cap (struct server *s, const struct irc_message *msg) } static void +irc_handle_chghost (struct server *s, const struct irc_message *msg) +{ + if (!msg->prefix || msg->params.len < 2) + return; + + char *nickname = irc_cut_nickname (msg->prefix); + struct user *user = str_map_find (&s->irc_users, nickname); + free (nickname); + if (!user) + return; + + // We don't remember the userhost part, we only log the change + char *new_prefix = xstrdup_printf ("%s!%s@%s", user->nickname, + msg->params.vector[0], msg->params.vector[1]); + + if (irc_is_this_us (s, msg->prefix)) + { + log_chghost_self (s, s->buffer, new_prefix); + + // Log a message in all open buffers on this server + struct str_map_iter iter = str_map_iter_make (&s->irc_buffer_map); + struct buffer *buffer; + while ((buffer = str_map_iter_next (&iter))) + log_chghost_self (s, buffer, new_prefix); + } + else + { + // Log a message in any PM buffer + struct buffer *buffer = + str_map_find (&s->irc_buffer_map, user->nickname); + if (buffer) + log_chghost (s, buffer, msg->prefix, new_prefix); + + // Log a message in all channels the user is in + LIST_FOR_EACH (struct user_channel, iter, user->channels) + { + buffer = str_map_find (&s->irc_buffer_map, iter->channel->name); + hard_assert (buffer != NULL); + log_chghost (s, buffer, msg->prefix, new_prefix); + } + } + + free (new_prefix); +} + +static void irc_handle_error (struct server *s, const struct irc_message *msg) { if (msg->params.len < 1) @@ -7310,6 +7363,7 @@ static struct irc_handler g_irc_handlers[] = { "AUTHENTICATE", irc_handle_authenticate }, { "AWAY", irc_handle_away }, { "CAP", irc_handle_cap }, + { "CHGHOST", irc_handle_chghost }, { "ERROR", irc_handle_error }, { "INVITE", irc_handle_invite }, { "JOIN", irc_handle_join }, |