pidgin/pidgin

558106ebf999
Parents e128168d9ea5
Children d3117aac63b3
Various clean ups to the IRCv3 connection process

Add a "done" signal to PurpleIRCv3Capabilities so the connection knows when
capability negotiation has completed.

Add a "registration-complete" signal to PurpleIRCv3Connection. This can be used
by plugins to do additional startup commands before we tell libpurple that our
connection is connected. We'll need some more logic around emitting this signal
in the future, but this works for now.

Don't tell libpurple that our connection is connected until the class handler
for the new "registration-complete" signal is called so that libpurple doesn't
try to auto join any channels or anything similar before we're actually ready
for it to do so.

Testing Done:
Connected and verified the changes with some `g_messages` that were removed.
Also used `ngrep` to verify that commands were still being sent correctly.

Reviewed at https://reviews.imfreedom.org/r/2107/
--- a/libpurple/protocols/ircv3/purpleircv3capabilities.c Thu Dec 01 03:18:56 2022 -0600
+++ b/libpurple/protocols/ircv3/purpleircv3capabilities.c Fri Dec 02 12:39:22 2022 -0600
@@ -21,6 +21,8 @@
#include "purpleircv3connection.h"
#include "purpleircv3core.h"
+#define PURPLE_IRCV3_CAPABILITIES_VERSION "302"
+
enum {
PROP_0,
PROP_CONNECTION,
@@ -40,6 +42,7 @@
SIG_READY,
SIG_ACK,
SIG_NAK,
+ SIG_DONE,
N_SIGNALS,
};
static guint signals[N_SIGNALS] = {0, };
@@ -68,6 +71,14 @@
}
}
+static void
+purple_ircv3_capabilities_finish(PurpleIRCv3Capabilities *capabilities) {
+ purple_ircv3_connection_writef(capabilities->connection,
+ "CAP END");
+
+ g_signal_emit(capabilities, signals[SIG_DONE], 0);
+}
+
/******************************************************************************
* PurpleIRCv3Capabilities Implementation
*****************************************************************************/
@@ -247,6 +258,26 @@
G_TYPE_NONE,
1,
G_TYPE_STRING);
+
+ /**
+ * PurpleIRCv3Capabilities::done:
+ * @capabilities: The instance.
+ *
+ * Emitted when all of the requested capabilities have been either ack'd or
+ * nak'd by the server.
+ *
+ * Since: 3.0.0
+ */
+ signals[SIG_DONE] = g_signal_new_class_handler(
+ "done",
+ G_OBJECT_CLASS_TYPE(klass),
+ G_SIGNAL_RUN_LAST,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ G_TYPE_NONE,
+ 0);
}
/******************************************************************************
@@ -293,8 +324,7 @@
* we're done with capability negotiation.
*/
if(capabilities->requests->len == 0) {
- purple_ircv3_connection_writef(capabilities->connection,
- "CAP END");
+ purple_ircv3_capabilities_finish(capabilities);
}
}
@@ -327,7 +357,7 @@
g_free(caps);
if(capabilities->requests->len == 0) {
- purple_ircv3_connection_writef(capabilities->connection, "CAP END");
+ purple_ircv3_capabilities_finish(capabilities);
}
return ret;
@@ -349,6 +379,12 @@
NULL);
}
+void
+purple_ircv3_capabilities_start(PurpleIRCv3Capabilities *capabilities) {
+ purple_ircv3_connection_writef(capabilities->connection, "CAP LS %s",
+ PURPLE_IRCV3_CAPABILITIES_VERSION);
+}
+
gboolean
purple_ircv3_capabilities_message_handler(G_GNUC_UNUSED GHashTable *tags,
G_GNUC_UNUSED const char *source,
--- a/libpurple/protocols/ircv3/purpleircv3capabilities.h Thu Dec 01 03:18:56 2022 -0600
+++ b/libpurple/protocols/ircv3/purpleircv3capabilities.h Fri Dec 02 12:39:22 2022 -0600
@@ -39,6 +39,8 @@
G_GNUC_INTERNAL PurpleIRCv3Capabilities *purple_ircv3_capabilities_new(PurpleIRCv3Connection *connection);
+G_GNUC_INTERNAL void purple_ircv3_capabilities_start(PurpleIRCv3Capabilities *capabilities);
+
G_GNUC_INTERNAL gboolean purple_ircv3_capabilities_message_handler(GHashTable *tags, const char *source, const char *command, guint n_params, GStrv params, GError **error, gpointer data);
/**
--- a/libpurple/protocols/ircv3/purpleircv3connection.c Thu Dec 01 03:18:56 2022 -0600
+++ b/libpurple/protocols/ircv3/purpleircv3connection.c Fri Dec 02 12:39:22 2022 -0600
@@ -31,6 +31,12 @@
};
static GParamSpec *properties[N_PROPERTIES] = {NULL, };
+enum {
+ SIG_REGISTRATION_COMPLETE,
+ N_SIGNALS,
+};
+static guint signals[N_SIGNALS] = {0, };
+
struct _PurpleIRCv3Connection {
PurpleConnection parent;
@@ -189,9 +195,6 @@
return;
}
- purple_connection_set_state(PURPLE_CONNECTION(connection),
- PURPLE_CONNECTION_STATE_CONNECTED);
-
g_message("Successfully connected to %s", connection->server_name);
/* Save our connection and setup our input and outputs. */
@@ -217,12 +220,20 @@
connection);
/* Send our registration commands. */
- purple_ircv3_connection_writef(connection, "CAP LS %s",
- PURPLE_IRCV3_CONNECTION_CAP_VERSION);
+ purple_ircv3_capabilities_start(connection->capabilities);
purple_ircv3_connection_send_user_command(connection);
purple_ircv3_connection_send_nick_command(connection);
}
+static void
+purple_ircv3_connection_caps_done_cb(G_GNUC_UNUSED PurpleIRCv3Capabilities *caps,
+ gpointer data)
+{
+ PurpleIRCv3Connection *connection = data;
+
+ g_signal_emit(connection, signals[SIG_REGISTRATION_COMPLETE], 0);
+}
+
/******************************************************************************
* PurpleConnection Implementation
*****************************************************************************/
@@ -306,6 +317,16 @@
return TRUE;
}
+static void
+purple_ircv3_connection_registration_complete_cb(PurpleIRCv3Connection *connection) {
+ /* Don't set our connection state to connected until we've completed
+ * registration as connected implies that we can start chatting or join
+ * rooms and other "online" activities.
+ */
+ purple_connection_set_state(PURPLE_CONNECTION(connection),
+ PURPLE_CONNECTION_STATE_CONNECTED);
+}
+
/******************************************************************************
* GObject Implementation
*****************************************************************************/
@@ -376,7 +397,11 @@
/* Finally create our objects. */
connection->cancellable = g_cancellable_new();
+
connection->capabilities = purple_ircv3_capabilities_new(connection);
+ g_signal_connect_object(connection->capabilities, "done",
+ G_CALLBACK(purple_ircv3_connection_caps_done_cb),
+ connection, 0);
}
static void
@@ -430,6 +455,29 @@
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
+
+ /* Signals */
+
+ /**
+ * PurpleIRCv3Connection::registration-complete:
+ * @connection: The instance.
+ *
+ * This signal is emitted after the registration process has been
+ * completed. Plugins can use this to perform additional actions before
+ * any channels are auto joined or similar.
+ *
+ * Since: 3.0.0
+ */
+ signals[SIG_REGISTRATION_COMPLETE] = g_signal_new_class_handler(
+ "registration-complete",
+ G_OBJECT_CLASS_TYPE(klass),
+ G_SIGNAL_RUN_LAST,
+ G_CALLBACK(purple_ircv3_connection_registration_complete_cb),
+ NULL,
+ NULL,
+ NULL,
+ G_TYPE_NONE,
+ 0);
}
/******************************************************************************
--- a/libpurple/protocols/ircv3/purpleircv3core.h Thu Dec 01 03:18:56 2022 -0600
+++ b/libpurple/protocols/ircv3/purpleircv3core.h Fri Dec 02 12:39:22 2022 -0600
@@ -27,6 +27,4 @@
#define PURPLE_IRCV3_DOMAIN (g_quark_from_static_string("ircv3-plugin"))
-#define PURPLE_IRCV3_CONNECTION_CAP_VERSION "302"
-
#endif /* PURPLE_IRCV3_CORE_H */