# HG changeset patch # User Tim Ringenbach # Date 1087280183 0 # Node ID 750d9b56a465ab83d6a744e2e2be5f0dbd34c36d # Parent 9da77e36d17767ce28d00b94f3f00795e16ce8ba [gaim-migrate @ 10095] Some improvements to our yahoo buddy icon support. Someone should tell me how to unset a buddy icon for a buddy. Because the way KingAnt told me (which he wasn't sure about anyway) just produces a failed g_return thingy, and does nothing. committer: Tailor Script diff -r 9da77e36d177 -r 750d9b56a465 src/protocols/yahoo/yahoo.c --- a/src/protocols/yahoo/yahoo.c Tue Jun 15 06:13:36 2004 +0000 +++ b/src/protocols/yahoo/yahoo.c Tue Jun 15 06:16:23 2004 +0000 @@ -44,6 +44,7 @@ extern char *yahoo_crypt(const char *, const char *); +#define YAHOO_ICON_CHECKSUM_KEY "icon_checksum" /* #define YAHOO_DEBUG */ static void yahoo_add_buddy(GaimConnection *gc, GaimBuddy *, GaimGroup *); @@ -384,7 +385,7 @@ yahoo_update_status(gc, name, f); } break; - case 197: /* Avatars? */ + case 197: /* Avatars */ { char *decoded, *tmp; guint len; @@ -400,6 +401,28 @@ } break; } + case 192: /* Pictures, aka Buddy Icons, checksum */ + { + int cksum = strtol(pair->value, NULL, 10); + GaimBuddy *b; + + if (!name) + break; + + if (!cksum || (cksum == -1)) { + gaim_buddy_icons_set_for_user(gc->account, name, NULL, 0); + break; + } + + if (!f) + break; + b = gaim_find_buddy(gc->account, name); + yahoo_friend_set_buddy_icon_need_request(f, FALSE); + if (cksum != gaim_blist_node_get_int((GaimBlistNode*)b, YAHOO_ICON_CHECKSUM_KEY)) + yahoo_send_buddy_icon_request(gc, name); + + break; + } case 16: /* Custom error message */ { char *tmp = yahoo_string_decode(gc, pair->value, TRUE); @@ -1857,9 +1880,13 @@ void yahoo_fetch_picture_cb(void *user_data, const char *pic_data, size_t len) { struct yahoo_fetch_picture_data *d = user_data; + GaimBuddy *b; if (GAIM_CONNECTION_IS_VALID(d->gc) && len) { - gaim_buddy_icons_set_for_user(gaim_connection_get_account(d->gc), d->who, pic_data, len); + gaim_buddy_icons_set_for_user(gaim_connection_get_account(d->gc), d->who, (void *)pic_data, len); + b = gaim_find_buddy(gaim_connection_get_account(d->gc), d->who); + if (b) + gaim_blist_node_set_int((GaimBlistNode*)b, YAHOO_ICON_CHECKSUM_KEY, d->checksum); } g_free(d->who); @@ -1872,7 +1899,7 @@ char *who = NULL, *us = NULL; gboolean got_icon_info = FALSE; char *url = NULL; - int checksum = 0; /* ?? */ + int checksum = 0; while (l) { struct yahoo_pair *pair = l->data; @@ -1906,20 +1933,84 @@ l = l->next; } - if (got_icon_info && url) { - /* TODO: make this work p2p, try p2p before the url, check the checksum - * (if that's what it is) before fetching the icon. - */ - struct yahoo_fetch_picture_data *data = g_new0(struct yahoo_fetch_picture_data, 1); - data->gc = gc; - data->who = g_strdup(who); - data->checksum = checksum; - gaim_url_fetch(url, FALSE, "Mozilla/4.0 (compatible; MSIE 5.0)", FALSE, - yahoo_fetch_picture_cb, data); + if (who && got_icon_info && url) { + /* TODO: make this work p2p, try p2p before the url */ + struct yahoo_fetch_picture_data *data; + GaimBuddy *b = gaim_find_buddy(gc->account, who); + if (b && (checksum == gaim_blist_node_get_int((GaimBlistNode*)b, YAHOO_ICON_CHECKSUM_KEY))) + return; + + data = g_new0(struct yahoo_fetch_picture_data, 1); + data->gc = gc; + data->who = g_strdup(who); + data->checksum = checksum; + gaim_url_fetch(url, FALSE, "Mozilla/4.0 (compatible; MSIE 5.0)", FALSE, + yahoo_fetch_picture_cb, data); } } +static void yahoo_process_picture_update(GaimConnection *gc, struct yahoo_packet *pkt) +{ + GSList *l = pkt->hash; + char *who = NULL; + int icon = 0; + + while (l) { + struct yahoo_pair *pair = l->data; + + switch (pair->key) { + case 4: + who = pair->value; + break; + case 5: + /* us */ + break; + case 206: + icon = strtol(pair->value, NULL, 10); + break; + } + l = l->next; + } + + if (who) { + if (icon == 2) + yahoo_send_buddy_icon_request(gc, who); + else if (icon == 0) + gaim_buddy_icons_set_for_user(gc->account, who, NULL, 0); + } +} + +static void yahoo_process_picture_checksum(GaimConnection *gc, struct yahoo_packet *pkt) +{ + GSList *l = pkt->hash; + char *who = NULL; + int checksum = 0; + + while (l) { + struct yahoo_pair *pair = l->data; + + switch (pair->key) { + case 4: + who = pair->value; + break; + case 5: + /* us */ + break; + case 192: + checksum = strtol(pair->value, NULL, 10); + break; + } + l = l->next; + } + + if (who) { + GaimBuddy *b = gaim_find_buddy(gc->account, who); + if (b && (checksum != gaim_blist_node_get_int((GaimBlistNode*)b, YAHOO_ICON_CHECKSUM_KEY))) + yahoo_send_buddy_icon_request(gc, who); + } +} + static void yahoo_packet_process(GaimConnection *gc, struct yahoo_packet *pkt) { switch (pkt->service) { @@ -2014,6 +2105,12 @@ case YAHOO_SERVICE_PICTURE: yahoo_process_picture(gc, pkt); break; + case YAHOO_SERVICE_PICTURE_UPDATE: + yahoo_process_picture_update(gc, pkt); + break; + case YAHOO_SERVICE_PICTURE_CHECKSUM: + yahoo_process_picture_checksum(gc, pkt); + break; default: gaim_debug(GAIM_DEBUG_ERROR, "yahoo", "Unhandled service 0x%02x\n", pkt->service); diff -r 9da77e36d177 -r 750d9b56a465 src/protocols/yahoo/yahoo.h --- a/src/protocols/yahoo/yahoo.h Tue Jun 15 06:13:36 2004 +0000 +++ b/src/protocols/yahoo/yahoo.h Tue Jun 15 06:16:23 2004 +0000 @@ -104,8 +104,11 @@ YAHOO_SERVICE_CHATLOGOUT = 0xa0, YAHOO_SERVICE_CHATPING, YAHOO_SERVICE_COMMENT = 0xa8, + YAHOO_SERVICE_AVATAR = 0xbc, + YAHOO_SERVICE_PICTURE_CHECKSUM = 0xbd, YAHOO_SERVICE_PICTURE = 0xbe, YAHOO_SERVICE_PICTURE_UPDATE = 0xc1, + YAHOO_SERVICE_AVATAR_UPDATE = 0xc7, YAHOO_SERVICE_WEBLOGIN = 0x0226 }; diff -r 9da77e36d177 -r 750d9b56a465 src/protocols/yahoo/yahoo_friend.h --- a/src/protocols/yahoo/yahoo_friend.h Tue Jun 15 06:13:36 2004 +0000 +++ b/src/protocols/yahoo/yahoo_friend.h Tue Jun 15 06:16:23 2004 +0000 @@ -38,7 +38,6 @@ int away; gboolean sms; char *ip; - guint bicon_checksum; gboolean bicon_sent_request; } YahooFriend;