IRCv3: handle RPL_NOWAWAY and RPL_UNAWAY messages

Wed, 14 May 2025 15:13:23 -0500

author
Markus Fischer <ivanhoe@fiscari.de>
date
Wed, 14 May 2025 15:13:23 -0500
changeset 43254
27610c58b03b
parent 43253
0cc00d7d6215
child 43255
828626110810

IRCv3: handle RPL_NOWAWAY and RPL_UNAWAY messages

Testing Done:
Connected to ZNC and verified with debug outputs that the presences were set as expected.

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

protocols/ircv3/purpleircv3connection.c file | annotate | diff | comparison | revisions
protocols/ircv3/purpleircv3messagehandlers.c file | annotate | diff | comparison | revisions
protocols/ircv3/purpleircv3messagehandlers.h file | annotate | diff | comparison | revisions
--- a/protocols/ircv3/purpleircv3connection.c	Wed May 14 01:54:28 2025 -0500
+++ b/protocols/ircv3/purpleircv3connection.c	Wed May 14 15:13:23 2025 -0500
@@ -460,6 +460,12 @@
 	g_signal_connect_object(client, "message::" IBIS_MSG_AWAY,
 	                        G_CALLBACK(purple_ircv3_message_handler_away),
 	                        connection, G_CONNECT_DEFAULT);
+	g_signal_connect_object(client, "message::" IBIS_RPL_NOWAWAY,
+	                        G_CALLBACK(purple_ircv3_message_handler_nowaway),
+	                        connection, G_CONNECT_DEFAULT);
+	g_signal_connect_object(client, "message::" IBIS_RPL_UNAWAY,
+	                        G_CALLBACK(purple_ircv3_message_handler_unaway),
+	                        connection, G_CONNECT_DEFAULT);
 	g_signal_connect_object(client, "message::" IBIS_MSG_JOIN,
 	                        G_CALLBACK(purple_ircv3_message_handler_join),
 	                        connection, G_CONNECT_DEFAULT);
@@ -992,6 +998,7 @@
 	PurpleContact *contact = NULL;
 	PurpleContactManager *manager = NULL;
 	PurplePresence *presence = NULL;
+	PurplePresencePrimitive cur_primitive = PURPLE_PRESENCE_PRIMITIVE_OFFLINE;
 	IbisTags *tags = NULL;
 	const char *source = NULL;
 	char *nick = NULL;
@@ -1032,10 +1039,17 @@
 	purple_contact_info_set_sid(PURPLE_CONTACT_INFO(contact), source);
 	purple_contact_info_set_display_name(PURPLE_CONTACT_INFO(contact), nick);
 
-	/* Grab the presence and set it as online right away. */
+	/*
+	 * Grab the presence and set it as online if we were offline. It's possible
+	 * that we're already AWAY due to an RPL_NOWAWAY message.
+	 */
 	presence = purple_contact_info_get_presence(PURPLE_CONTACT_INFO(contact));
-	purple_presence_set_primitive(presence,
-	                              PURPLE_PRESENCE_PRIMITIVE_AVAILABLE);
+
+	cur_primitive = purple_presence_get_primitive(presence);
+	if (cur_primitive == PURPLE_PRESENCE_PRIMITIVE_OFFLINE) {
+		purple_presence_set_primitive(presence,
+		                              PURPLE_PRESENCE_PRIMITIVE_AVAILABLE);
+	}
 
 	g_free(nick);
 
--- a/protocols/ircv3/purpleircv3messagehandlers.c	Wed May 14 01:54:28 2025 -0500
+++ b/protocols/ircv3/purpleircv3messagehandlers.c	Wed May 14 15:13:23 2025 -0500
@@ -1291,3 +1291,60 @@
 
 	return TRUE;
 }
+
+gboolean
+purple_ircv3_message_handler_nowaway(G_GNUC_UNUSED IbisClient *client,
+                                     G_GNUC_UNUSED const char *command,
+                                     IbisMessage *ibis_message,
+                                     gpointer data)
+{
+	PurpleIRCv3Connection *connection = data;
+	PurpleContact *contact = NULL;
+	PurplePresence *presence = NULL;
+	GStrv params = NULL;
+	guint n_params = 0;
+
+	params = ibis_message_get_params(ibis_message);
+	n_params = g_strv_length(params);
+
+	if(n_params < 1) {
+		g_message("received RPL_NOWAWAY with %u params, need at least 1", n_params);
+		return FALSE;
+	}
+
+	contact = purple_ircv3_connection_find_or_create_contact_from_nick(connection,
+	                                                                   params[0]);
+	presence = purple_contact_info_get_presence(PURPLE_CONTACT_INFO(contact));
+	purple_presence_set_primitive(presence,
+	                              PURPLE_PRESENCE_PRIMITIVE_AWAY);
+
+	return TRUE;
+}
+
+gboolean
+purple_ircv3_message_handler_unaway(G_GNUC_UNUSED IbisClient *client,
+                                    G_GNUC_UNUSED const char *command,
+                                    IbisMessage *ibis_message,
+                                    gpointer data)
+{
+	PurpleIRCv3Connection *connection = data;
+	PurpleContact *contact = NULL;
+	PurplePresence *presence = NULL;
+	GStrv params = NULL;
+	guint n_params = 0;
+
+	params = ibis_message_get_params(ibis_message);
+	n_params = g_strv_length(params);
+
+	if(n_params < 1) {
+		g_message("received RPL_UNAWAY with %u params, need at least 1", n_params);
+		return FALSE;
+	}
+
+	contact = purple_ircv3_connection_find_or_create_contact_from_nick(connection,
+	                                                                   params[0]);
+	presence = purple_contact_info_get_presence(PURPLE_CONTACT_INFO(contact));
+	purple_presence_set_primitive(presence, PURPLE_PRESENCE_PRIMITIVE_AVAILABLE);
+
+	return TRUE;
+}
--- a/protocols/ircv3/purpleircv3messagehandlers.h	Wed May 14 01:54:28 2025 -0500
+++ b/protocols/ircv3/purpleircv3messagehandlers.h	Wed May 14 15:13:23 2025 -0500
@@ -54,6 +54,8 @@
 G_GNUC_INTERNAL gboolean purple_ircv3_message_handler_kick(IbisClient *client, const char *command, IbisMessage *message, gpointer data);
 G_GNUC_INTERNAL gboolean purple_ircv3_message_handler_mode(IbisClient *client, const char *command, IbisMessage *message, gpointer data);
 G_GNUC_INTERNAL gboolean purple_ircv3_message_handler_whoreply(IbisClient *client, const char *command, IbisMessage *message, gpointer data);
+G_GNUC_INTERNAL gboolean purple_ircv3_message_handler_nowaway(IbisClient *client, const char *command, IbisMessage *message, gpointer data);
+G_GNUC_INTERNAL gboolean purple_ircv3_message_handler_unaway(IbisClient *client, const char *command, IbisMessage *message, gpointer data);
 
 G_END_DECLS
 

mercurial