IRCv3: Add the quote command to send raw messages

Thu, 02 Jan 2025 22:48:11 -0600

author
Gary Kramlich <grim@reaperworld.com>
date
Thu, 02 Jan 2025 22:48:11 -0600
changeset 43126
5b5a883528e0
parent 43125
06367e26ef2f
child 43127
eae3279e871c

IRCv3: Add the quote command to send raw messages

This uses Ibis.Message.parse to create the message which means it supports
everything in a normal message assuming you can pass it into the command input
field.

I also cleaned up the indentation on the query command.

Testing Done:
Tried with no parameters and verified nothing was sent. Then sent messages with invalid commands as well as a `TAGMSG` with the `@+typing=active` tag to a channel from the status window and verified it was sent and that another client recognized the typing tag.

Bugs closed: PIDGIN-18019

Reviewed at https://reviews.imfreedom.org/r/3719/

protocols/ircv3/purpleircv3commands.c file | annotate | diff | comparison | revisions
protocols/ircv3/purpleircv3commands.h file | annotate | diff | comparison | revisions
protocols/ircv3/purpleircv3protocol.c file | annotate | diff | comparison | revisions
--- a/protocols/ircv3/purpleircv3commands.c	Thu Jan 02 22:46:22 2025 -0600
+++ b/protocols/ircv3/purpleircv3commands.c	Thu Jan 02 22:48:11 2025 -0600
@@ -33,45 +33,77 @@
                               GStrv params,
                               G_GNUC_UNUSED gpointer data)
 {
-    PurpleIRCv3Connection *v3_connection = NULL;
-    PurpleAccount *account = NULL;
-    PurpleConnection *connection = NULL;
-    PurpleConversation *new_conversation = NULL;
-    guint n_params = 0;
+	PurpleIRCv3Connection *v3_connection = NULL;
+	PurpleAccount *account = NULL;
+	PurpleConnection *connection = NULL;
+	PurpleConversation *new_conversation = NULL;
+	guint n_params = 0;
+
+	n_params = g_strv_length(params);
+	if(n_params < 1) {
+		return FALSE;
+	}
+
+	account = purple_conversation_get_account(conversation);
+	connection = purple_account_get_connection(account);
+	v3_connection = PURPLE_IRCV3_CONNECTION(connection);
+
+	new_conversation = purple_ircv3_connection_find_or_create_conversation(v3_connection,
+	                                                                       params[0]);
 
-    n_params = g_strv_length(params);
-    if(n_params < 1) {
-        return FALSE;
-    }
+	if(n_params > 1) {
+		PurpleMessage *message = NULL;
+		PurpleContactInfo *info = NULL;
+		PurpleConversationMember *member = NULL;
+		PurpleConversationMembers *members = NULL;
+		char *contents = NULL;
 
-    account = purple_conversation_get_account(conversation);
-    connection = purple_account_get_connection(account);
-    v3_connection = PURPLE_IRCV3_CONNECTION(connection);
+		info = purple_account_get_contact_info(account);
+		members = purple_conversation_get_members(conversation);
+		member = purple_conversation_members_find_member(members, info);
+
+		contents = g_strjoinv(" ", params + 1);
 
-    new_conversation = purple_ircv3_connection_find_or_create_conversation(v3_connection,
-                                                                           params[0]);
+		message = purple_message_new(member, contents);
+		g_free(contents);
+
+		purple_conversation_send_message_async(new_conversation, message, NULL,
+		                                       NULL, NULL);
 
-    if(n_params > 1) {
-        PurpleMessage *message = NULL;
-        PurpleContactInfo *info = NULL;
-        PurpleConversationMember *member = NULL;
-        PurpleConversationMembers *members = NULL;
-        char *contents = NULL;
+		g_clear_object(&message);
+	}
+
+	return TRUE;
+}
 
-        info = purple_account_get_contact_info(account);
-        members = purple_conversation_get_members(conversation);
-        member = purple_conversation_members_find_member(members, info);
+gboolean
+purple_ircv3_command_quote_cb(G_GNUC_UNUSED PurpleCommand *command,
+                              PurpleConversation *conversation,
+                              GStrv params,
+                              G_GNUC_UNUSED gpointer data)
+{
+	IbisMessage *message = NULL;
+	char *raw = NULL;
+
+	raw = g_strjoinv(" ", params);
+	message = ibis_message_parse(raw, NULL);
+	g_free(raw);
 
-        contents = g_strjoinv(" ", params + 1);
-
-        message = purple_message_new(member, contents);
-        g_free(contents);
+	if(IBIS_IS_MESSAGE(message)) {
+		PurpleIRCv3Connection *v3_connection = NULL;
+		PurpleAccount *account = NULL;
+		PurpleConnection *connection = NULL;
+		IbisClient *client = NULL;
 
-        purple_conversation_send_message_async(new_conversation, message, NULL,
-                                               NULL, NULL);
+		account = purple_conversation_get_account(conversation);
+		connection = purple_account_get_connection(account);
+		v3_connection = PURPLE_IRCV3_CONNECTION(connection);
+		client = purple_ircv3_connection_get_client(v3_connection);
 
-        g_clear_object(&message);
-    }
+		ibis_client_write(client, message);
 
-    return TRUE;
+		return TRUE;
+	}
+
+	return FALSE;
 }
--- a/protocols/ircv3/purpleircv3commands.h	Thu Jan 02 22:46:22 2025 -0600
+++ b/protocols/ircv3/purpleircv3commands.h	Thu Jan 02 22:48:11 2025 -0600
@@ -35,6 +35,7 @@
 G_BEGIN_DECLS
 
 G_GNUC_INTERNAL gboolean purple_ircv3_command_query_cb(PurpleCommand *command, PurpleConversation *conversation, GStrv params, gpointer data);
+G_GNUC_INTERNAL gboolean purple_ircv3_command_quote_cb(PurpleCommand *command, PurpleConversation *conversation, GStrv params, gpointer data);
 
 G_END_DECLS
 
--- a/protocols/ircv3/purpleircv3protocol.c	Thu Jan 02 22:46:22 2025 -0600
+++ b/protocols/ircv3/purpleircv3protocol.c	Thu Jan 02 22:48:11 2025 -0600
@@ -243,6 +243,16 @@
 	                        G_CALLBACK(purple_ircv3_command_query_cb),
 	                        protocol, G_CONNECT_DEFAULT);
 	purple_command_manager_add(manager, command);
+
+	command = purple_command_new("quote", "IRCv3", 1000);
+	purple_command_set_summary(command,
+	                           _("Sends the command directly to the server"));
+	tags = purple_command_get_tags(command);
+	purple_tags_add(tags, "protocol-id:" PURPLE_IRCV3_PROTOCOL_ID);
+	g_signal_connect_object(command, "executed",
+	                        G_CALLBACK(purple_ircv3_command_quote_cb),
+	                        protocol, G_CONNECT_DEFAULT);
+	purple_command_manager_add(manager, command);
 }
 
 static void

mercurial