Wed, 14 May 2025 15:13:23 -0500
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/
--- 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