--- a/libpurple/protocols/ircv3/purpleircv3connection.c Mon Dec 04 02:13:29 2023 -0600
+++ b/libpurple/protocols/ircv3/purpleircv3connection.c Mon Dec 04 02:20:09 2023 -0600
@@ -401,6 +401,57 @@
/******************************************************************************
+ *****************************************************************************/ +purple_ircv3_connection_ctcp_request_default_handler(G_GNUC_UNUSED PurpleIRCv3Connection *connection, + G_GNUC_UNUSED PurpleConversation *conversation, + PurpleMessage *message, + if(!purple_strempty(params)) { + contents = g_strdup_printf(_("requested CTCP %s: %s"), command, + contents = g_strdup_printf(_("requested CTCP %s"), + purple_message_set_contents(message, contents); + g_clear_pointer(&contents, g_free); +purple_ircv3_connection_ctcp_response_default_handler(G_GNUC_UNUSED PurpleIRCv3Connection *connection, + G_GNUC_UNUSED PurpleConversation *conversation, + PurpleMessage *message, + if(!purple_strempty(params)) { + contents = g_strdup_printf(_("CTCP %s response: %s"), command, + contents = g_strdup_printf(_("CTCP %s response was empty"), + purple_message_set_contents(message, contents); + g_clear_pointer(&contents, g_free); +/****************************************************************************** *****************************************************************************/
@@ -595,46 +646,67 @@
* PurpleIRCv3Connection::ctcp-request:
* @connection: The instance.
+ * @conversation: The conversation. + * @message: The message. * @command: The CTCP command.
* @params: (nullable): The CTCP parameters.
* This signal is emitted after a CTCP request has been received.
+ * Signal handlers should return TRUE if they fully handled the request and + * do not want it echoed out to the user. + * Handlers may also modify the message. For example, the CTCP ACTION + * command has its message contents replaced with just the CTCP parameters + * and sets the [property@Message:action] to %TRUE and then returns %TRUE. signals[SIG_CTCP_REQUEST] = g_signal_new_class_handler(
G_OBJECT_CLASS_TYPE(klass),
+ G_CALLBACK(purple_ircv3_connection_ctcp_request_default_handler), + g_signal_accumulator_true_handled,
+ PURPLE_TYPE_CONVERSATION, * PurpleIRCv3Connection::ctcp-response:
* @connection: The instance.
+ * @conversation: The conversation. + * @message: The message. * @command: The CTCP command.
* @params: (nullable): The CTCP parameters.
* This signal is emitted after a CTCP response has been received.
+ * Signal handlers should return TRUE if they fully handled the response + * and do not want it echoed out to the user. + * Handlers may modify @conversation or @message to depending on their signals[SIG_CTCP_RESPONSE] = g_signal_new_class_handler(
G_OBJECT_CLASS_TYPE(klass),
+ G_CALLBACK(purple_ircv3_connection_ctcp_response_default_handler), + g_signal_accumulator_true_handled,
+ PURPLE_TYPE_CONVERSATION, @@ -659,28 +731,44 @@
g_type_class_unref(hack);
purple_ircv3_connection_emit_ctcp_request(PurpleIRCv3Connection *connection,
+ PurpleConversation *conversation, + PurpleMessage *message, - g_return_if_fail(PURPLE_IRCV3_IS_CONNECTION(connection));
- g_return_if_fail(!purple_strempty(command));
- g_signal_emit(connection, signals[SIG_CTCP_REQUEST], 0, command,
+ g_return_val_if_fail(PURPLE_IRCV3_IS_CONNECTION(connection), FALSE); + g_return_val_if_fail(PURPLE_IS_CONVERSATION(conversation), FALSE); + g_return_val_if_fail(PURPLE_IS_MESSAGE(message), FALSE); + g_return_val_if_fail(!purple_strempty(command), FALSE); + g_signal_emit(connection, signals[SIG_CTCP_REQUEST], 0, conversation, + message, command, parameters, &ret);
purple_ircv3_connection_emit_ctcp_response(PurpleIRCv3Connection *connection,
+ PurpleConversation *conversation, + PurpleMessage *message, - g_return_if_fail(PURPLE_IRCV3_IS_CONNECTION(connection));
- g_return_if_fail(!purple_strempty(command));
- g_signal_emit(connection, signals[SIG_CTCP_RESPONSE], 0, command,
+ g_return_val_if_fail(PURPLE_IRCV3_IS_CONNECTION(connection), FALSE); + g_return_val_if_fail(PURPLE_IS_CONVERSATION(conversation), FALSE); + g_return_val_if_fail(PURPLE_IS_MESSAGE(message), FALSE); + g_return_val_if_fail(!purple_strempty(command), FALSE); + g_signal_emit(connection, signals[SIG_CTCP_RESPONSE], 0, conversation, + message, command, parameters, &ret); /******************************************************************************
--- a/libpurple/protocols/ircv3/purpleircv3connection.h Mon Dec 04 02:13:29 2023 -0600
+++ b/libpurple/protocols/ircv3/purpleircv3connection.h Mon Dec 04 02:20:09 2023 -0600
@@ -65,28 +65,46 @@
* purple_ircv3_connection_emit_ctcp_request:
* @connection: The instance.
+ * @conversation: The conversation. + * @message: The message. * @command: The CTCP command.
* @parameters: (nullable): The CTCP parameters.
* Emits the [signal@Connection:ctcp-request] signal with the given @command
+ * and @parameters which originated from @message in @conversation. + * The message may be modified by a signal handler. For example, the default + * handler will output an internationalized string that describes what command + * Returns: %TRUE if the request was handled and the message should not be + * echoed, otherwise %FALSE. -G_GNUC_INTERNAL void purple_ircv3_connection_emit_ctcp_request(PurpleIRCv3Connection *connection, const char *command, const char *parameters);
+G_GNUC_INTERNAL gboolean purple_ircv3_connection_emit_ctcp_request(PurpleIRCv3Connection *connection, PurpleConversation *conversation, PurpleMessage *message, const char *command, const char *parameters); * purple_ircv3_connection_emit_ctcp_response:
* @connection: The instance.
+ * @conversation: The conversation. + * @message: The message. * @command: The CTCP command.
* @parameters: (nullable): The CTCP parameters.
* Emits the [signal@Connection:ctcp-response] signal with the given @command
+ * and @parameters which originated from @message in @conversation. + * The message may be modified by a signal handler. For example, the default + * handler will output an internationalized string that describes what the + * Returns: %TRUE if the request was handled and the message should not be + * echoed, otherwise %FALSE. -G_GNUC_INTERNAL void purple_ircv3_connection_emit_ctcp_response(PurpleIRCv3Connection *connection, const char *command, const char *parameters);
+G_GNUC_INTERNAL gboolean purple_ircv3_connection_emit_ctcp_response(PurpleIRCv3Connection *connection, PurpleConversation *conversation, PurpleMessage *message, const char *command, const char *parameters); * purple_ircv3_connection_writef:
--- a/libpurple/protocols/ircv3/purpleircv3ctcp.c Mon Dec 04 02:13:29 2023 -0600
+++ b/libpurple/protocols/ircv3/purpleircv3ctcp.c Mon Dec 04 02:20:09 2023 -0600
@@ -25,79 +25,66 @@
/******************************************************************************
*****************************************************************************/
purple_ircv3_ctcp_handle(PurpleIRCv3Connection *connection,
+ PurpleConversation *conversation, - const char *contents = NULL;
- g_return_if_fail(PURPLE_IRCV3_IS_CONNECTION(connection));
- g_return_if_fail(PURPLE_IS_MESSAGE(message));
+ PurpleMessageFlags flags; + const char *contents = NULL; - contents = purple_message_get_contents(message);
- if(contents != NULL && contents[0] == PURPLE_IRCV3_CTCP_DELIMITER) {
- PurpleMessageFlags flags;
- /* Move past the delimiter. */
+ g_return_val_if_fail(PURPLE_IRCV3_IS_CONNECTION(connection), FALSE); + g_return_val_if_fail(PURPLE_IS_CONVERSATION(conversation), FALSE); + g_return_val_if_fail(PURPLE_IS_MESSAGE(message), FALSE); - /* Find the delimiter for the command. */
- ptr = g_strstr_len(contents, -1, " ");
- /* If we don't have a space, then we have no parameters. */
- size_t len = strlen(contents);
+ contents = purple_message_get_contents(message); + if(contents == NULL || contents[0] != PURPLE_IRCV3_CTCP_DELIMITER) { - command = g_strdup(contents);
- if(command[len - 1] == PURPLE_IRCV3_CTCP_DELIMITER) {
- command[len - 1] = '\0';
+ /* Move past the delimiter. */ - command = g_strndup(contents, ptr - contents);
+ /* Find the delimiter for the command. */ + ptr = g_strstr_len(contents, -1, " "); + /* If we don't have a space, then we have no parameters. */ + size_t len = strlen(contents); - params = g_strdup(ptr + 1);
- if(params[len - 1] == PURPLE_IRCV3_CTCP_DELIMITER) {
- params[len - 1] = '\0';
+ command = g_strdup(contents); + if(command[len - 1] == PURPLE_IRCV3_CTCP_DELIMITER) { + command[len - 1] = '\0'; - flags = purple_message_get_flags(message);
- if(flags & PURPLE_MESSAGE_NOTIFY) {
- if(!purple_strempty(params)) {
- contents = g_strdup_printf(_("CTCP %s response: %s"), command,
- contents = g_strdup_printf(_("CTCP %s response was empty"),
+ command = g_strndup(contents, ptr - contents); + params = g_strdup(ptr + 1); + if(params[len - 1] == PURPLE_IRCV3_CTCP_DELIMITER) { + params[len - 1] = '\0'; - purple_ircv3_connection_emit_ctcp_response(connection, command,
- if(!purple_strempty(params)) {
- contents = g_strdup_printf(_("requested CTCP %s: %s"), command,
- contents = g_strdup_printf(_("requested CTCP %s"), command);
+ flags = purple_message_get_flags(message); + if(flags & PURPLE_MESSAGE_NOTIFY) { + ret = purple_ircv3_connection_emit_ctcp_response(connection, + ret = purple_ircv3_connection_emit_ctcp_request(connection, conversation, - purple_ircv3_connection_emit_ctcp_request(connection, command,
+ g_clear_pointer(&command, g_free); + g_clear_pointer(¶ms, g_free); - if(!purple_strempty(contents)) {
- purple_message_set_contents(message, contents);
- g_clear_pointer(&contents, g_free);
- g_clear_pointer(&command, g_free);
- g_clear_pointer(¶ms, g_free);
--- a/libpurple/protocols/ircv3/purpleircv3ctcp.h Mon Dec 04 02:13:29 2023 -0600
+++ b/libpurple/protocols/ircv3/purpleircv3ctcp.h Mon Dec 04 02:20:09 2023 -0600
@@ -34,15 +34,18 @@
* purple_ircv3_ctcp_handle: (skip)
- * @connection: The connection instance.
- * @message: The message instance.
+ * @connection: The connection. + * @conversation: The conversation. + * @message: The message. * Check if @message is a CTCP message and handles it accordingly.
+ * Returns: %TRUE if the message was a CTCP message and %FALSE otherwise. -void purple_ircv3_ctcp_handle(PurpleIRCv3Connection *connection, PurpleMessage *message);
+gboolean purple_ircv3_ctcp_handle(PurpleIRCv3Connection *connection, PurpleConversation *conversation, PurpleMessage *message); --- a/libpurple/protocols/ircv3/purpleircv3messagehandlers.c Mon Dec 04 02:13:29 2023 -0600
+++ b/libpurple/protocols/ircv3/purpleircv3messagehandlers.c Mon Dec 04 02:20:09 2023 -0600
@@ -229,9 +229,9 @@
/* Check if this is a CTCP message. */
- purple_ircv3_ctcp_handle(connection, message);
- purple_conversation_write_message(conversation, message);
+ if(!purple_ircv3_ctcp_handle(connection, conversation, message)) { + purple_conversation_write_message(conversation, message); g_clear_pointer(&nick, g_free);
g_clear_object(&message);