diff options
author | Přemysl Janouch <p.janouch@gmail.com> | 2015-04-26 22:31:07 +0200 |
---|---|---|
committer | Přemysl Janouch <p.janouch@gmail.com> | 2015-04-26 22:31:07 +0200 |
commit | a66bf15e672f51315147a334238a4df2b00d5318 (patch) | |
tree | 9c14de82b4768d7a060a75beb821dfcac8c20443 | |
parent | 9e548889c72d4279bcf1aa803aff14216b5fd91f (diff) | |
download | xK-a66bf15e672f51315147a334238a4df2b00d5318.tar.gz xK-a66bf15e672f51315147a334238a4df2b00d5318.tar.xz xK-a66bf15e672f51315147a334238a4df2b00d5318.zip |
degesch: process CTCP in PRIVMSG
Finally we can display /me.
-rw-r--r-- | degesch.c | 66 |
1 files changed, 55 insertions, 11 deletions
@@ -2631,43 +2631,87 @@ irc_handle_ping (struct app_context *ctx, const struct irc_message *msg) } static void -irc_handle_privmsg (struct app_context *ctx, const struct irc_message *msg) +irc_handle_ctcp_request (struct app_context *ctx, + const struct irc_message *msg, struct ctcp_chunk *chunk) { - if (!msg->prefix || msg->params.len < 2) - return; + char *nickname = irc_cut_nickname (msg->prefix); + char *nickname_utf8 = irc_to_utf8 (ctx, nickname); + free (nickname); + char *tag_utf8 = irc_to_utf8 (ctx, chunk->tag.str); - const char *target = msg->params.vector[0]; - const char *message = msg->params.vector[1]; - struct buffer *buffer = str_map_find (&ctx->irc_buffer_map, target); + buffer_send_status (ctx, ctx->server_buffer, + "CTCP requested by %s: %s", nickname_utf8, tag_utf8); + // TODO: reply to other CTCPs; + // see http://www.irchelp.org/irchelp/rfc/ctcpspec.html + + free (nickname_utf8); + free (tag_utf8); +} + +static struct buffer * +irc_get_buffer_for_message (struct app_context *ctx, + const struct irc_message *msg, const char *target) +{ + struct buffer *buffer = str_map_find (&ctx->irc_buffer_map, target); if (irc_is_channel (ctx, target)) { struct channel *channel = str_map_find (&ctx->irc_channels, target); hard_assert ((channel && buffer) || (channel && !buffer) || (!channel && !buffer)); - // This is weird, ignoring + // This is weird if (!channel) - return; + return NULL; } else if (!buffer) { + // Implying that the target is us char *nickname = irc_cut_nickname (msg->prefix); buffer = irc_get_or_make_user_buffer (ctx, nickname); free (nickname); } + return buffer; +} + +static void +irc_handle_privmsg_text (struct app_context *ctx, + const struct irc_message *msg, struct str *text, bool is_action) +{ + const char *target = msg->params.vector[0]; + struct buffer *buffer = irc_get_buffer_for_message (ctx, msg, target); if (buffer) { - // TODO: handle CTCP messages // TODO: highlights - buffer_send (ctx, buffer, BUFFER_LINE_PRIVMSG, 0, + enum buffer_line_type type = is_action + ? BUFFER_LINE_ACTION + : BUFFER_LINE_PRIVMSG; + buffer_send (ctx, buffer, type, 0, .who = irc_to_utf8 (ctx, msg->prefix), - .text = irc_to_utf8 (ctx, message)); + .text = irc_to_utf8 (ctx, text->str)); } } static void +irc_handle_privmsg (struct app_context *ctx, const struct irc_message *msg) +{ + if (!msg->prefix || msg->params.len < 2) + return; + + // This ignores empty messages which we should never receive anyway + struct ctcp_chunk *chunks = ctcp_parse (msg->params.vector[1]); + LIST_FOR_EACH (struct ctcp_chunk, iter, chunks) + if (!iter->is_extended) + irc_handle_privmsg_text (ctx, msg, &iter->text, false); + else if (!strcmp (iter->tag.str, "ACTION")) + irc_handle_privmsg_text (ctx, msg, &iter->text, true); + else + irc_handle_ctcp_request (ctx, msg, iter); + ctcp_destroy (chunks); +} + +static void irc_handle_quit (struct app_context *ctx, const struct irc_message *msg) { if (!msg->prefix) |