[Telepathy-commits] [telepathy-gabble/master] Handle the MUC renaming us on joining
Will Thompson
will.thompson at collabora.co.uk
Sun Feb 1 11:14:54 PST 2009
---
src/muc-channel.c | 67 +++++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 53 insertions(+), 14 deletions(-)
diff --git a/src/muc-channel.c b/src/muc-channel.c
index aaed3e8..aecdc2a 100644
--- a/src/muc-channel.c
+++ b/src/muc-channel.c
@@ -1897,6 +1897,31 @@ handle_unavailable_presence_update (GabbleMucChannel *chan,
tp_handle_unref (contact_handles, actor);
}
+static gboolean
+renamed_by_server (LmMessageNode *x_node)
+{
+ LmMessageNode *child;
+ gboolean is_self = FALSE;
+ gboolean renamed = FALSE;
+
+ for (child = x_node->children; child != NULL; child = child->next)
+ {
+ const gchar *code;
+
+ if (strcmp (child->name, "status") != 0)
+ continue;
+
+ code = lm_message_node_get_attribute (child, "code");
+
+ if (!tp_strdiff (code, "110"))
+ is_self = TRUE;
+ else if (!tp_strdiff (code, "210"))
+ renamed = TRUE;
+ }
+
+ return (is_self && renamed);
+}
+
static void
handle_member_added (GabbleMucChannel *chan,
GabbleMucChannelPrivate *priv,
@@ -1904,11 +1929,13 @@ handle_member_added (GabbleMucChannel *chan,
TpHandleRepoIface *contact_handles,
TpHandle handle,
TpIntSet *handle_singleton,
+ LmMessageNode *x_node,
LmMessageNode *item_node)
{
TpBaseConnection *conn = (TpBaseConnection *) priv->conn;
const gchar *owner_jid = lm_message_node_get_attribute (item_node, "jid");
TpHandle owner_handle = 0;
+ TpIntSet *old_self_handle_singleton = NULL;
if (owner_jid != NULL)
{
@@ -1919,21 +1946,29 @@ handle_member_added (GabbleMucChannel *chan,
DEBUG ("Invalid owner handle '%s', treating as no owner", owner_jid);
}
+ if (renamed_by_server (x_node))
+ {
+ old_self_handle_singleton = tp_intset_new ();
+ tp_intset_add (old_self_handle_singleton, mixin->self_handle);
+
+ tp_group_mixin_change_self_handle ((GObject *) chan, handle);
+ }
+
if (handle == mixin->self_handle &&
owner_handle != conn->self_handle)
{
- /* We know that in XEP-0045 compliant MUCs, nobody else can have
- * the nick we tried to use - the service MUST reject us
- * with code 409/"conflict" in this case. So, if someone in the
- * room has the nick we want, it's us.
+ /* In XEP-0045-compliant MUCs, if we get presence for the jid we asked
+ * for (or for another jid, with status 110 and 210) then we know it's
+ * us. There can't be another user in the MUC with the nick we asked for:
+ * the service MUST reject us with code 409/"conflict" in this case. So,
+ * if someone in the room has the nick we want, it's us.
*
- * If the MUC service fails to comply with this requirement,
- * we get hopelessly confused, but this isn't a regression
- * (we always would have done).
- *
- * FIXME: we ought to respect the 110 and 210 status codes
- * too, so we can detect MUCs renaming us - otherwise the
- * presence aggregator will never stop
+ * If the MUC service fails to comply with this requirement, we get
+ * hopelessly confused. Given that the service isn't required to label
+ * our own presence as 110 ("this is you") and there's no way to label a
+ * presence for the jid we asked for as "not you" it's not possible for a
+ * client not to get hopelessly confused if the service is broken. So
+ * this is the best we can do.
*/
DEBUG ("Overriding ownership of channel-specific handle %u "
"from %u to %u because I know it's mine",
@@ -1981,7 +2016,7 @@ handle_member_added (GabbleMucChannel *chan,
tp_group_mixin_change_members ((GObject *) chan, "",
tp_handle_set_peek (
priv->initial_state_aggregator->members),
- NULL, NULL, NULL, 0, 0);
+ old_self_handle_singleton, NULL, NULL, 0, 0);
initial_state_aggregator_free (
priv->initial_state_aggregator);
@@ -2009,6 +2044,9 @@ handle_member_added (GabbleMucChannel *chan,
{
g_object_set (chan, "state", MUC_STATE_JOINED, NULL);
}
+
+ if (old_self_handle_singleton != NULL)
+ tp_intset_destroy (old_self_handle_singleton);
}
static void
@@ -2016,6 +2054,7 @@ handle_presence_update (GabbleMucChannel *chan,
TpHandleRepoIface *contact_handles,
TpHandle handle,
TpIntSet *handle_singleton,
+ LmMessageNode *x_node,
LmMessageNode *item_node,
const gchar *status_code)
{
@@ -2024,7 +2063,7 @@ handle_presence_update (GabbleMucChannel *chan,
if (!tp_handle_set_is_member (mixin->members, handle))
handle_member_added (chan, priv, mixin, contact_handles, handle,
- handle_singleton, item_node);
+ handle_singleton, x_node, item_node);
if (handle == mixin->self_handle)
{
@@ -2137,7 +2176,7 @@ _gabble_muc_channel_member_presence_updated (GabbleMucChannel *chan,
handle_singleton, item_node, status_code);
else
handle_presence_update (chan, contact_handles, handle, handle_singleton,
- item_node, status_code);
+ x_node, item_node, status_code);
tp_intset_destroy (handle_singleton);
}
--
1.5.6.5
More information about the Telepathy-commits
mailing list