diff options
author | Sébastien Helleu <flashcode@flashtux.org> | 2024-04-06 22:44:04 +0200 |
---|---|---|
committer | Sébastien Helleu <flashcode@flashtux.org> | 2024-04-06 22:44:04 +0200 |
commit | 40bfded594a7821340b8434c4fb459ec2cde6f6d (patch) | |
tree | 5f764d23de1b4a44098ad732a5449436c9d0c2c1 /src | |
parent | 2c3c9a3ee70c7adc7cc6f620cde6c50d42677dc7 (diff) | |
download | weechat-40bfded594a7821340b8434c4fb459ec2cde6f6d.zip |
irc: fix display of reply for CTCP request received on a channel when capability echo-message is enabled
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/irc/irc-ctcp.c | 140 | ||||
-rw-r--r-- | src/plugins/irc/irc-ctcp.h | 5 | ||||
-rw-r--r-- | src/plugins/irc/irc-protocol.c | 55 |
3 files changed, 150 insertions, 50 deletions
diff --git a/src/plugins/irc/irc-ctcp.c b/src/plugins/irc/irc-ctcp.c index 8b400041f..405bed8b3 100644 --- a/src/plugins/irc/irc-ctcp.c +++ b/src/plugins/irc/irc-ctcp.c @@ -170,6 +170,45 @@ irc_ctcp_get_reply (struct t_irc_server *server, const char *ctcp) } /* + * Extracts CTCP type and arguments from message, which format is: + * \01TYPE arguments...\01 + * + * Strings *type and *arguments are set with type and arguments parsed, + * both are set to NULL in case of error. + */ + +void +irc_ctcp_parse_type_arguments (const char *message, + char **type, char **arguments) +{ + const char *pos_end, *pos_space; + + if (!message || !type || !arguments) + return; + + *type = NULL; + *arguments = NULL; + + if (message[0] != '\01') + return; + + pos_end = strrchr (message + 1, '\01'); + if (!pos_end) + return; + + pos_space = strchr (message + 1, ' '); + + *type = weechat_strndup ( + message + 1, + (pos_space) ? pos_space - message - 1 : pos_end - message - 1); + if (!*type) + return; + + *arguments = (pos_space) ? + weechat_strndup (pos_space + 1, pos_end - pos_space - 1) : NULL; +} + +/* * Displays CTCP requested by a nick. */ @@ -319,7 +358,68 @@ irc_ctcp_display_reply_from_nick (struct t_irc_protocol_ctxt *ctxt, } /* - * Displays CTCP replied to a nick. + * Displays CTCP reply to a nick (internal function). + */ + +void +irc_ctcp_display_reply_to_nick_internal (struct t_irc_protocol_ctxt *ctxt, + const char *target, + const char *type, + const char *args) +{ + weechat_printf_date_tags ( + irc_msgbuffer_get_target_buffer (ctxt->server, target, NULL, + "ctcp", NULL), + 0, + irc_protocol_tags (ctxt, + "irc_ctcp,irc_ctcp_reply,self_msg," + "notify_none,no_highlight"), + _("%sCTCP reply to %s%s%s: %s%s%s%s%s"), + weechat_prefix ("network"), + irc_nick_color_for_msg (ctxt->server, 0, NULL, target), + target, + IRC_COLOR_RESET, + IRC_COLOR_CHAT_CHANNEL, + type, + (args && args[0]) ? IRC_COLOR_RESET : "", + (args && args[0]) ? " " : "", + (args) ? args : ""); +} + +/* + * Displays CTCP reply to a nick. + */ + +void +irc_ctcp_display_reply_to_nick (struct t_irc_protocol_ctxt *ctxt, + const char *target, + const char *arguments) +{ + char *ctcp_type, *ctcp_args, *ctcp_args_no_colors; + + if (!ctxt || !arguments || (arguments[0] != '\01')) + return; + + irc_ctcp_parse_type_arguments (arguments, &ctcp_type, &ctcp_args); + + if (ctcp_type) + { + ctcp_args_no_colors = (ctcp_args) ? + irc_color_decode (ctcp_args, 1) : NULL; + irc_ctcp_display_reply_to_nick_internal (ctxt, target, ctcp_type, + ctcp_args_no_colors); + if (ctcp_args_no_colors) + free (ctcp_args_no_colors); + } + + if (ctcp_type) + free (ctcp_type); + if (ctcp_args) + free (ctcp_args); +} + +/* + * Replies to CTCP from a nick and displays reply. */ void @@ -328,8 +428,8 @@ irc_ctcp_reply_to_nick (struct t_irc_protocol_ctxt *ctxt, const char *arguments) { struct t_arraylist *list_messages; - int i, list_size; - char *msg_color, *dup_ctcp, *dup_ctcp_upper, *dup_args; + int i, list_size, length; + char *dup_ctcp, *dup_ctcp_upper, *dup_args, *message; const char *ptr_message; dup_ctcp = NULL; @@ -373,7 +473,8 @@ irc_ctcp_reply_to_nick (struct t_irc_protocol_ctxt *ctxt, if (!list_messages) goto end; - if (weechat_config_boolean (irc_config_look_display_ctcp_reply)) + if (weechat_config_boolean (irc_config_look_display_ctcp_reply) + && !weechat_hashtable_has_key (ctxt->server->cap_list, "echo-message")) { list_size = weechat_arraylist_size (list_messages); for (i = 0; i < list_size; i++) @@ -381,27 +482,16 @@ irc_ctcp_reply_to_nick (struct t_irc_protocol_ctxt *ctxt, ptr_message = (const char *)weechat_arraylist_get (list_messages, i); if (!ptr_message) break; - msg_color = irc_color_decode (ptr_message, 1); - if (!msg_color) - break; - weechat_printf_date_tags ( - irc_msgbuffer_get_target_buffer (ctxt->server, ctxt->nick, - NULL, "ctcp", NULL), - 0, - irc_protocol_tags (ctxt, - "irc_ctcp,irc_ctcp_reply,self_msg," - "notify_none,no_highlight"), - _("%sCTCP reply to %s%s%s: %s%s%s%s%s"), - weechat_prefix ("network"), - irc_nick_color_for_msg (ctxt->server, 0, NULL, ctxt->nick), - ctxt->nick, - IRC_COLOR_RESET, - IRC_COLOR_CHAT_CHANNEL, - dup_ctcp_upper, - (msg_color[0]) ? IRC_COLOR_RESET : "", - (msg_color[0]) ? " " : "", - msg_color); - free (msg_color); + /* build arguments: '\01' + CTCP + ' ' + message + '\01' */ + length = 1 + strlen (dup_ctcp_upper) + 1 + strlen (ptr_message) + 1 + 1; + message = malloc (length); + if (message) + { + snprintf (message, length, + "\01%s %s\01", dup_ctcp_upper, ptr_message); + irc_ctcp_display_reply_to_nick (ctxt, ctxt->nick, message); + free (message); + } } } diff --git a/src/plugins/irc/irc-ctcp.h b/src/plugins/irc/irc-ctcp.h index 11cd250fe..083d1ef1d 100644 --- a/src/plugins/irc/irc-ctcp.h +++ b/src/plugins/irc/irc-ctcp.h @@ -38,8 +38,13 @@ extern char *irc_ctcp_convert_legacy_format (const char *format); extern const char *irc_ctcp_get_default_reply (const char *ctcp); extern const char *irc_ctcp_get_reply (struct t_irc_server *server, const char *ctcp); +extern void irc_ctcp_parse_type_arguments (const char *message, + char **type, char **arguments); extern void irc_ctcp_display_reply_from_nick (struct t_irc_protocol_ctxt *ctxt, const char *arguments); +extern void irc_ctcp_display_reply_to_nick (struct t_irc_protocol_ctxt *ctxt, + const char *target, + const char *arguments); extern char *irc_ctcp_eval_reply (struct t_irc_server *server, const char *format); extern void irc_ctcp_recv (struct t_irc_protocol_ctxt *ctxt, diff --git a/src/plugins/irc/irc-protocol.c b/src/plugins/irc/irc-protocol.c index 32e5a91b8..ac1fb725d 100644 --- a/src/plugins/irc/irc-protocol.c +++ b/src/plugins/irc/irc-protocol.c @@ -2538,10 +2538,24 @@ IRC_PROTOCOL_CALLBACK(notice) weechat_hashtable_set (ctxt->server->echo_msg_recv, ctxt->irc_message, &time_now); } - if (!cap_echo_message || !msg_already_received) + if (!cap_echo_message || !ctxt->nick_is_me) { irc_ctcp_display_reply_from_nick (ctxt, pos_args); } + else + { + if (msg_already_received) + { + irc_ctcp_display_reply_from_nick (ctxt, pos_args); + } + else + { + irc_ctcp_display_reply_to_nick ( + ctxt, + (ctxt->nick_is_me) ? pos_target : ctxt->nick, + pos_args); + } + } if (msg_already_received) weechat_hashtable_remove (ctxt->server->echo_msg_recv, ctxt->irc_message); } @@ -3033,36 +3047,27 @@ irc_protocol_privmsg_display_ctcp_send (struct t_irc_protocol_ctxt *ctxt, const char *target, const char *arguments) { - const char *pos_space, *pos_end; char *ctcp_type, *ctcp_args; if (!arguments || !arguments[0]) return; - pos_end = strrchr (arguments + 1, '\01'); - if (!pos_end) - return; + irc_ctcp_parse_type_arguments (arguments, &ctcp_type, &ctcp_args); - pos_space = strchr (arguments + 1, ' '); - - ctcp_type = weechat_strndup ( - arguments + 1, - (pos_space) ? - pos_space - arguments - 1 : pos_end - arguments - 1); - ctcp_args = (pos_space) ? - weechat_strndup (pos_space + 1, pos_end - pos_space - 1) : NULL; - - irc_input_user_message_display ( - ctxt->server, - ctxt->date, - ctxt->date_usec, - ctxt->tags, - target, - ctxt->address, - "privmsg", - ctcp_type, - ctcp_args, - 0); /* decode_colors */ + if (ctcp_type) + { + irc_input_user_message_display ( + ctxt->server, + ctxt->date, + ctxt->date_usec, + ctxt->tags, + target, + ctxt->address, + "privmsg", + ctcp_type, + ctcp_args, + 0); /* decode_colors */ + } if (ctcp_type) free (ctcp_type); |