summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSébastien Helleu <flashcode@flashtux.org>2024-04-06 22:44:04 +0200
committerSébastien Helleu <flashcode@flashtux.org>2024-04-06 22:44:04 +0200
commit40bfded594a7821340b8434c4fb459ec2cde6f6d (patch)
tree5f764d23de1b4a44098ad732a5449436c9d0c2c1 /src
parent2c3c9a3ee70c7adc7cc6f620cde6c50d42677dc7 (diff)
downloadweechat-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.c140
-rw-r--r--src/plugins/irc/irc-ctcp.h5
-rw-r--r--src/plugins/irc/irc-protocol.c55
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);