changeset 25386:2c80f3d839c7

Patch to fix retrieval of ICQ status messages from users of ICQ 6.x, Miranda, and libpurple users. Retrieval of messages from libpurple users works only for statuses that are not Available. Fixes #703, #892, #4904, #4984, #6848. committer: John Bailey <rekkanoryo@rekkanoryo.org>
author Daniel Lj <dimmuxx@yahoo.se>
date Thu, 29 Jan 2009 03:15:57 +0000
parents 075aa09253e7
children 025b7767810c
files ChangeLog libpurple/protocols/oscar/family_icq.c libpurple/protocols/oscar/oscar.c libpurple/protocols/oscar/oscar.h
diffstat 4 files changed, 33 insertions(+), 195 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Jan 29 02:12:16 2009 +0000
+++ b/ChangeLog	Thu Jan 29 03:15:57 2009 +0000
@@ -10,6 +10,9 @@
 	* Beta support for SSL connections for AIM and ICQ accounts.  To
 	  enable, check the "Use SSL" option from the Advanced tab when
 	  editing your AIM or ICQ account. (Paul Aurich)
+	* Fix retrieval of ICQ status messages from users of ICQ 6.x, Miranda,
+	  and other libpurple clients (fixes with libpurple users only on
+	  statuses other than Available). (Daniel Ljungborg)
 
 	Finch:
 	* Allow rebinding keys to change the focused widget (details in the
--- a/libpurple/protocols/oscar/family_icq.c	Thu Jan 29 02:12:16 2009 +0000
+++ b/libpurple/protocols/oscar/family_icq.c	Thu Jan 29 03:15:57 2009 +0000
@@ -456,64 +456,6 @@
 	return 0;
 }
 
-/*
- * getstatusnote may be a misleading name because the response
- * contains a lot of different information but currently it's only
- * used to get that.
- */
-int aim_icq_getstatusnote(OscarData *od, const char *uin, guint8 *note_hash, guint16 note_hash_len)
-{
-	FlapConnection *conn;
-	ByteStream bs;
-	aim_snacid_t snacid;
-	int bslen;
-
-	purple_debug_misc("oscar", "aim_icq_getstatusnote: requesting status note for %s.\n", uin);
-
-	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICQ)))
-	{
-		purple_debug_misc("oscar", "aim_icq_getstatusnote: no connection.\n");
-		return -EINVAL;
-	}
-
-	bslen = 2 + 4 + 2 + 2 + 2 + 2 + 58 + strlen(uin);
-	byte_stream_new(&bs, 4 + bslen);
-
-	snacid = aim_cachesnac(od, SNAC_FAMILY_ICQ, 0x0002, 0x0000, NULL, 0);
-
-	byte_stream_put16(&bs, 0x0001);
-	byte_stream_put16(&bs, bslen);
-
-	byte_stream_putle16(&bs, bslen - 2);
-	byte_stream_putuid(&bs, od);
-	byte_stream_putle16(&bs, 0x07d0); /* I command thee. */
-	byte_stream_putle16(&bs, snacid); /* eh. */
-	byte_stream_putle16(&bs, 0x0fa0); /* shrug. */
-	byte_stream_putle16(&bs, 58 + strlen(uin));
-
-	byte_stream_put32(&bs, 0x05b90002);    /* don't ask */
-	byte_stream_put32(&bs, 0x80000000);
-	byte_stream_put32(&bs, 0x00000006);
-	byte_stream_put32(&bs, 0x00010002);
-	byte_stream_put32(&bs, 0x00020000);
-	byte_stream_put32(&bs, 0x04e30000);
-	byte_stream_put32(&bs, 0x00020002);
-	byte_stream_put32(&bs, 0x00000001);
-
-	byte_stream_put16(&bs, 24 + strlen(uin));
-	byte_stream_put32(&bs, 0x003c0010);
-	byte_stream_putraw(&bs, note_hash, 16); /* status note hash */
-	byte_stream_put16(&bs, 0x0032);        /* buddy uin */
-	byte_stream_put16(&bs, strlen(uin));
-	byte_stream_putstr(&bs, uin);
-
-	flap_connection_send_snac_with_priority(od, conn, SNAC_FAMILY_ICQ, 0x0002, 0x000, snacid, &bs, FALSE);
-
-	byte_stream_destroy(&bs);
-
-	return 0;
-}
-
 static void aim_icq_freeinfo(struct aim_icq_info *info) {
 	int i;
 
--- a/libpurple/protocols/oscar/oscar.c	Thu Jan 29 02:12:16 2009 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Thu Jan 29 03:15:57 2009 +0000
@@ -2074,37 +2074,6 @@
 	return 1;
 }
 
-static gboolean purple_requesticqstatusnote(gpointer data)
-{
-	PurpleConnection *gc = data;
-	OscarData *od = gc->proto_data;
-
-	while (od->statusnotes_queue != NULL)
-	{
-		char *sn;
-		struct aim_ssi_item *ssi_item;
-		aim_tlv_t *note_hash;
-
-		sn = od->statusnotes_queue->data;
-
-		ssi_item = aim_ssi_itemlist_finditem(od->ssi.local,
-											 NULL, sn, AIM_SSI_TYPE_BUDDY);
-		if (ssi_item != NULL)
-		{
-			note_hash = aim_tlv_gettlv(ssi_item->data, 0x015c, 1);
-			if (note_hash != NULL) {
-				aim_icq_getstatusnote(od, sn, note_hash->value, note_hash->length);
-			}
-		}
-
-		od->statusnotes_queue = g_slist_remove(od->statusnotes_queue, sn);
-		g_free(sn);
-	}
-
-	od->statusnotes_queue_timer = 0;
-	return FALSE;
-}
-
 
 static int purple_parse_oncoming(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...)
 {
@@ -2117,6 +2086,10 @@
 	const char *status_id;
 	va_list ap;
 	aim_userinfo_t *info;
+	char *message = NULL;
+	char *itmsurl = NULL;
+	char *tmp;
+	const char *tmp2;
 
 	gc = od->gc;
 	account = purple_connection_get_account(gc);
@@ -2170,50 +2143,32 @@
 	} else {
 		purple_prpl_got_user_status_deactive(account, info->sn, OSCAR_STATUS_ID_MOBILE);
 	}
-
-	if (strcmp(status_id, OSCAR_STATUS_ID_AVAILABLE) == 0)
-	{
-		char *message = NULL;
-		char *itmsurl = NULL;
-		char *tmp;
-		const char *tmp2;
-
-		if (info->status != NULL && info->status[0] != '\0')
-			/* Grab the available message */
-			message = oscar_encoding_to_utf8(account, info->status_encoding,
-					info->status, info->status_len);
-
+	
+	if (info->status != NULL && info->status[0] != '\0')
+	/* Grab the available message */
+		message = oscar_encoding_to_utf8(account, info->status_encoding,
+										 info->status, info->status_len);
+	
+	tmp2 = tmp = (message ? g_markup_escape_text(message, -1) : NULL);
+	
+	if (strcmp(status_id, OSCAR_STATUS_ID_AVAILABLE) == 0) {
 		if (info->itmsurl_encoding && info->itmsurl && info->itmsurl_len)
-			/* Grab the iTunes Music Store URL */
+		/* Grab the iTunes Music Store URL */
 			itmsurl = oscar_encoding_to_utf8(account, info->itmsurl_encoding,
-					info->itmsurl, info->itmsurl_len);
-
-		tmp2 = tmp = (message ? g_markup_escape_text(message, -1) : NULL);
-
+											 info->itmsurl, info->itmsurl_len);
 		if (tmp2 == NULL && itmsurl != NULL)
 			tmp2 = "";
-
+		
 		purple_prpl_got_user_status(account, info->sn, status_id,
-				"message", tmp2, "itmsurl", itmsurl, NULL);
-		g_free(tmp);
-
-		g_free(message);
-		g_free(itmsurl);
+									"message", tmp2, "itmsurl", itmsurl, NULL);
 	}
 	else
-	{
-		PurpleBuddy *b = purple_find_buddy(account, info->sn);
-		PurplePresence *presence = purple_buddy_get_presence(b);
-		PurpleStatus *old_status = purple_presence_get_active_status(presence);
-		PurpleStatus *new_status = purple_presence_get_status(presence, status_id);
-		
-		/* If our status_id would change with this update, pass it to the core.
-		 * However, if our status_id would not change, do nothing, as we would clear out any existing
-		 * attributes on the status prematurely. purple_got_infoblock() will update the message as needed.
-		 */
-		if (old_status != new_status)
-			purple_prpl_got_user_status(account, info->sn, status_id, NULL);
-	}
+		purple_prpl_got_user_status(account, info->sn, status_id, "message", tmp2, NULL);
+	
+	g_free(tmp);
+	
+	g_free(message);
+	g_free(itmsurl);
 
 	/* Login time stuff */
 	if (info->present & AIM_USERINFO_PRESENT_ONLINESINCE)
@@ -2268,51 +2223,6 @@
 		g_free(b16);
 	}
 
-	/*
-	 * If we didn't receive a status message with the status change,
-	 * or if the message is empty, and we have a note hash, then
-	 * query the ICQ6 status note.
-	 *
-	 * TODO: We should probably always query the status note regardless
-	 *       of whether they have a status message set, and we should
-	 *       figure out a way to display both the status note and the
-	 *       status message at the same time.
-	 */
-	if (info->status == NULL || info->status[0] == '\0')
-	{
-		struct aim_ssi_item *ssi_item;
-		aim_tlv_t *note_hash;
-
-		ssi_item = aim_ssi_itemlist_finditem(od->ssi.local,
-				NULL, info->sn, AIM_SSI_TYPE_BUDDY);
-		if (ssi_item != NULL)
-		{
-			note_hash = aim_tlv_gettlv(ssi_item->data, 0x015c, 1);
-			if (note_hash != NULL) {
-				/* We do automatic rate limiting at the FLAP level, so
-				 * a flood of requests won't disconnect us.  However,
-				 * it WOULD mean that we would have to wait a
-				 * potentially long time to be able to message in real
-				 * time again.  Also, since we're requesting with every
-				 * purple_parse_oncoming() call, which often come in
-				 * groups, we should coalesce to do only one lookup per
-				 * buddy.
-				 */
-				if (od->statusnotes_queue == NULL ||
-					g_slist_find_custom(od->statusnotes_queue, info->sn, (GCompareFunc)strcmp) == NULL)
-				{
-					od->statusnotes_queue = g_slist_prepend(od->statusnotes_queue,
-							g_strdup(info->sn));
-
-					if (od->statusnotes_queue_timer > 0)
-						purple_timeout_remove(od->statusnotes_queue_timer);
-					od->statusnotes_queue_timer = purple_timeout_add_seconds(3,
-							purple_requesticqstatusnote, gc);
-				}
-			}
-		}
-	}
-
 	return 1;
 }
 
@@ -5478,7 +5388,6 @@
 	PurpleBuddy *b;
 	PurpleGroup *g;
 	struct aim_ssi_item *ssi_item;
-	aim_tlv_t *note_hash;
 	va_list ap;
 	guint16 snac_subtype, type;
 	const char *name;
@@ -5548,13 +5457,7 @@
 
 	ssi_item = aim_ssi_itemlist_finditem(od->ssi.local,
 			gname, name, AIM_SSI_TYPE_BUDDY);
-	if (ssi_item != NULL)
-	{
-		note_hash = aim_tlv_gettlv(ssi_item->data, 0x015c, 1);
-		if (note_hash != NULL)
-			aim_icq_getstatusnote(od, name, note_hash->value, note_hash->length);
-	}
-	else
+	if (ssi_item == NULL)
 	{
 		purple_debug_error("oscar", "purple_ssi_parseaddmod: "
 				"Could not find ssi item for oncoming buddy %s, "
@@ -5992,19 +5895,8 @@
 		else
 			ret = g_strdup(_("Offline"));
 	}
-	else if (purple_status_is_available(status) && !strcmp(id, OSCAR_STATUS_ID_AVAILABLE))
+	else
 	{
-		/* Available */
-		message = purple_status_get_attr_string(status, "message");
-		if (message != NULL)
-		{
-			ret = g_strdup(message);
-			purple_util_chrreplace(ret, '\n', ' ');
-		}
-	}
-	else if (!purple_status_is_available(status) && !strcmp(id, OSCAR_STATUS_ID_AWAY))
-	{
-		/* Away */
 		message = purple_status_get_attr_string(status, "message");
 		if (message != NULL)
 		{
@@ -6016,13 +5908,15 @@
 			g_free(tmp1);
 			g_free(tmp2);
 		}
+		else if (purple_status_is_available(status))
+		{
+			/* Don't show "Available" as status message in case buddy doesn't have a status message */
+		}
 		else
 		{
-			ret = g_strdup(_("Away"));
+			ret = g_strdup(purple_status_get_name(status));
 		}
 	}
-	else
-		ret = g_strdup(purple_status_get_name(status));
 
 	return ret;
 }
--- a/libpurple/protocols/oscar/oscar.h	Thu Jan 29 02:12:16 2009 +0000
+++ b/libpurple/protocols/oscar/oscar.h	Thu Jan 29 03:15:57 2009 +0000
@@ -1360,7 +1360,6 @@
 int aim_icq_getalias(OscarData *od, const char *uin);
 int aim_icq_getallinfo(OscarData *od, const char *uin);
 int aim_icq_sendsms(OscarData *od, const char *name, const char *msg, const char *alias);
-int aim_icq_getstatusnote(OscarData *od, const char *uin, guint8 *note_hash, guint16 note_hash_len);
 
 
 /* 0x0017 - family_auth.c */