changeset 23625:e8bea84f63b6

merge of '88c7f87fb5a74f975cf06c472059ecf081c54042' and 'fe134224188f83f69a5367395922807444d46f49'
author Mark Doliner <mark@kingant.net>
date Mon, 21 Jul 2008 06:33:06 +0000
parents 60030a36506e (diff) 8dcd6c1b923c (current diff)
children 8c480872b620
files libpurple/protocols/oscar/family_icq.c libpurple/protocols/oscar/oscar.h
diffstat 4 files changed, 68 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/oscar/family_icq.c	Sun Jul 20 19:52:22 2008 +0000
+++ b/libpurple/protocols/oscar/family_icq.c	Mon Jul 21 06:33:06 2008 +0000
@@ -36,6 +36,8 @@
 	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICQ)))
 		return -EINVAL;
 
+	purple_debug_info("oscar", "Requesting offline messages from %s", od->sn);
+
 	bslen = 2 + 4 + 2 + 2;
 
 	byte_stream_new(&bs, 4 + bslen);
@@ -68,6 +70,8 @@
 	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICQ)))
 		return -EINVAL;
 
+	purple_debug_info("oscar", "Acknowledged receipt of offline messages from %s", od->sn);
+
 	bslen = 2 + 4 + 2 + 2;
 
 	byte_stream_new(&bs, 4 + bslen);
@@ -242,6 +246,8 @@
 	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICQ)))
 		return -EINVAL;
 
+	purple_debug_info("oscar", "Requesting ICQ alias for %s", uin);
+
 	bslen = 2 + 4 + 2 + 2 + 2 + 4;
 
 	byte_stream_new(&bs, 4 + bslen);
@@ -259,7 +265,7 @@
 	byte_stream_putle16(&bs, 0x04ba); /* shrug. */
 	byte_stream_putle32(&bs, atoi(uin));
 
-	flap_connection_send_snac(od, conn, SNAC_FAMILY_ICQ, 0x0002, 0x0000, snacid, &bs);
+	flap_connection_send_snac_with_priority(od, conn, SNAC_FAMILY_ICQ, 0x0002, 0x0000, snacid, &bs, /* High priority? */ FALSE);
 
 	byte_stream_destroy(&bs);
 
@@ -303,7 +309,7 @@
 	byte_stream_putle16(&bs, 0x051f); /* shrug. */
 	byte_stream_putle32(&bs, atoi(uin));
 
-	flap_connection_send_snac(od, conn, SNAC_FAMILY_ICQ, 0x0002, 0x0000, snacid, &bs);
+	flap_connection_send_snac_with_priority(od, conn, SNAC_FAMILY_ICQ, 0x0002, 0x0000, snacid, &bs, /* High priority? */ FALSE);
 
 	byte_stream_destroy(&bs);
 
@@ -877,7 +883,7 @@
 				info->next = od->icq_info;
 				od->icq_info = info;
 
-				flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs);
+				flap_connection_send_snac_with_priority(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs, /* High priority? */ FALSE);
 
 				byte_stream_destroy(&bs);
 			}
--- a/libpurple/protocols/oscar/oscar.c	Sun Jul 20 19:52:22 2008 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Mon Jul 21 06:33:06 2008 +0000
@@ -1893,6 +1893,39 @@
 	return 1;
 }
 
+static gboolean purple_requesticqstatusnote(gpointer data)
+{
+	PurpleConnection *gc = data;
+	OscarData *od = gc->proto_data;
+	char *sn;
+	struct aim_ssi_item *ssi_item;
+	aim_tlv_t *note_hash;
+
+	if (!od->statusnotes_queue) {
+		purple_debug_misc("oscar", "No more ICQ status notes to request");
+		od->statusnotes_queue_timer = 0;
+		return FALSE;
+	}
+
+	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);
+	free(sn);
+	
+	return TRUE;
+}
+
+
 static int purple_parse_oncoming(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...)
 {
 	PurpleConnection *gc;
@@ -2074,8 +2107,20 @@
 		if (ssi_item != NULL)
 		{
 			note_hash = aim_tlv_gettlv(ssi_item->data, 0x015c, 1);
-			if (note_hash != NULL)
-				aim_icq_getstatusnote(od, info->sn, note_hash->value, note_hash->length);
+			if (note_hash != NULL) {
+				/* We do automatic rate limiting, so a flood of requests would not disconnect us.
+				 * However, they would mean that we had 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 a single lookup.
+				 */
+				if (!od->statusnotes_queue || (g_slist_find_custom(od->statusnotes_queue, info->sn, (GCompareFunc)strcmp) == NULL)) {
+					od->statusnotes_queue = g_slist_append(od->statusnotes_queue, g_strdup(info->sn));
+
+					if (od->statusnotes_queue_timer)
+						purple_timeout_remove(od->statusnotes_queue_timer);
+					od->statusnotes_queue_timer = purple_timeout_add_seconds(2, purple_requesticqstatusnote, gc);
+				}
+			}
 		}
 	}
 
--- a/libpurple/protocols/oscar/oscar.h	Sun Jul 20 19:52:22 2008 +0000
+++ b/libpurple/protocols/oscar/oscar.h	Mon Jul 21 06:33:06 2008 +0000
@@ -544,6 +544,10 @@
 
 	/** A linked list containing PeerConnections. */
 	GSList *peer_connections;
+	
+	/** Queue of ICQ Status Notes to request. */
+	GSList *statusnotes_queue;
+	gint statusnotes_queue_timer;
 };
 
 /* Valid for calling aim_icq_setstatus() and for aim_userinfo_t->icqinfo.status */
--- a/libpurple/protocols/oscar/oscar_data.c	Sun Jul 20 19:52:22 2008 +0000
+++ b/libpurple/protocols/oscar/oscar_data.c	Mon Jul 21 06:33:06 2008 +0000
@@ -92,6 +92,14 @@
 		od->requesticon = g_slist_remove(od->requesticon, sn);
 		g_free(sn);
 	}
+	while (od->statusnotes_queue)
+	{
+		gchar *sn = od->statusnotes_queue->data;
+		od->statusnotes_queue = g_slist_remove(od->statusnotes_queue, sn);
+		g_free(sn);
+	}
+	if (od->statusnotes_queue_timer)
+		purple_timeout_remove(od->statusnotes_queue_timer);
 	g_free(od->email);
 	g_free(od->newp);
 	g_free(od->oldp);