Mercurial > pidgin
changeset 6784:ea3707dde7a3
[gaim-migrate @ 7323]
marv_sf writes:
"Fixes some issues with idle buddies.
Displays the wireless icon for sms users.
Hopefully makes long contact lists (and long ignore lists,
if such things exist) work.
Notices with a buddy isn't on the server list, and uses the
notauthorized icon, displays a status/tooltip of Not on
server list, and adds a menu item to add them.
It also considates the games and status message hash tables
into a single one, that uses yahoo_friend for its values.
yahoo_friend is nice enough to store the information for all
the above items."
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Sun, 07 Sep 2003 21:59:55 +0000 |
parents | 8105c9cd573f |
children | eb8f949095a5 |
files | src/protocols/yahoo/yahoo.c src/protocols/yahoo/yahoo.h |
diffstat | 2 files changed, 350 insertions(+), 170 deletions(-) [+] |
line wrap: on
line diff
--- a/src/protocols/yahoo/yahoo.c Sun Sep 07 21:00:34 2003 +0000 +++ b/src/protocols/yahoo/yahoo.c Sun Sep 07 21:59:55 2003 +0000 @@ -58,6 +58,28 @@ #define YAHOO_PACKET_HDRLEN (4 + 2 + 2 + 2 + 2 + 4 + 4) +static void yahoo_add_buddy(GaimConnection *gc, const char *who); + +static struct yahoo_friend *yahoo_friend_new() +{ + struct yahoo_friend *ret; + + ret = g_new0(struct yahoo_friend, 1); + ret->status = YAHOO_STATUS_OFFLINE; + + return ret; +} + +static void yahoo_friend_free(gpointer p) +{ + struct yahoo_friend *f = p; + if (f->msg) + g_free(f->msg); + if (f->game) + g_free(f->game); + g_free(f); +} + struct yahoo_packet *yahoo_packet_new(enum yahoo_service service, enum yahoo_status status, int id) { struct yahoo_packet *pkt = g_new0(struct yahoo_packet, 1); @@ -275,16 +297,21 @@ g_free(pkt); } +static void yahoo_update_status(GaimConnection *gc, const char *name, struct yahoo_friend *f) +{ + if (!gc || !name || !f || !gaim_find_buddy(gaim_connection_get_account(gc), name)) + return; + + serv_got_update(gc, name, 1, 0, 0, f->idle, f->away ? UC_UNAVAILABLE : 0); +} + static void yahoo_process_status(GaimConnection *gc, struct yahoo_packet *pkt) { struct yahoo_data *yd = gc->proto_data; GSList *l = pkt->hash; + struct yahoo_friend *f = NULL; char *name = NULL; - int state = 0; - int gamestate = 0; - char *msg = NULL; - int away = 0; - int idle = 0; + while (l) { struct yahoo_pair *pair = l->data; @@ -316,58 +343,79 @@ break; case 7: /* the current buddy */ name = pair->value; + f = g_hash_table_lookup(yd->friends, name); + if (!f) { + f = yahoo_friend_new(); + g_hash_table_insert(yd->friends, g_strdup(name), f); + } break; case 10: /* state */ - state = strtol(pair->value, NULL, 10); - if (state >= YAHOO_STATUS_BRB && state <= YAHOO_STATUS_STEPPEDOUT) - away = 1; + if (!f) + break; + + f->status = strtol(pair->value, NULL, 10); + if ((f->status >= YAHOO_STATUS_BRB) && (f->status <= YAHOO_STATUS_STEPPEDOUT)) + f->away = 1; + else + f->away = 0; + if (f->status == YAHOO_STATUS_IDLE) + f->idle = time(NULL); + if (f->status != YAHOO_STATUS_CUSTOM) { + g_free(f->msg); + f->msg = NULL; + } + if (f->status == YAHOO_STATUS_AVAILABLE) + f->idle = 0; break; case 19: /* custom message */ - msg = pair->value; + if (f) { + if (f->msg) + g_free(f->msg); + f->msg = g_strdup(pair->value); + } break; case 11: /* this is the buddy's session id */ break; case 17: /* in chat? */ break; - case 47: /* is custom status away or not? 2=idle?*/ - away = strtol(pair->value, NULL, 10); + case 47: /* is custom status away or not? 2=idle*/ + if (!f) + break; + f->away = strtol(pair->value, NULL, 10); + if (f->away == 2) + f->idle = time(NULL); break; - case 137: - idle = time(NULL) - strtol(pair->value, NULL, 10); + case 138: /* either we're not idle, or we are but won't say how long */ + if (!f) + break; + + if (f->idle) + f->idle = -1; + break; + case 137: /* usually idle time in seconds, sometimes login time */ + if (!f) + break; + + if (f->status != YAHOO_STATUS_AVAILABLE) + f->idle = time(NULL) - strtol(pair->value, NULL, 10); break; case 13: /* bitmask, bit 0 = pager, bit 1 = chat, bit 2 = game */ - if (pkt->service == YAHOO_SERVICE_LOGOFF || - strtol(pair->value, NULL, 10) == 0) { + if (strtol(pair->value, NULL, 10) == 0) { + if (f) + f->status = YAHOO_STATUS_OFFLINE; serv_got_update(gc, name, 0, 0, 0, 0, 0); break; } - if (g_hash_table_lookup(yd->games, name)) - gamestate = YAHOO_STATUS_GAME; - if (state == YAHOO_STATUS_CUSTOM) { - gpointer val = g_hash_table_lookup(yd->hash, name); - if (val) { - g_free(val); - g_hash_table_insert(yd->hash, name, - msg ? g_strdup(msg) : g_malloc0(1)); - } else - g_hash_table_insert(yd->hash, g_strdup(name), - msg ? g_strdup(msg) : g_malloc0(1)); + + if (f) + yahoo_update_status(gc, name, f); + break; + case 60: /* SMS */ + if (f) { + f->sms = strtol(pair->value, NULL, 10); + yahoo_update_status(gc, name, f); } - if (state == YAHOO_STATUS_AVAILABLE) - serv_got_update(gc, name, 1, 0, 0, 0, gamestate); - else if (state == YAHOO_STATUS_IDLE) - serv_got_update(gc, name, 1, 0, 0, (idle?idle:time(NULL)), (state << 2) | UC_UNAVAILABLE | gamestate); - else { - if (away) - serv_got_update(gc, name, 1, 0, 0, idle, (state << 2) | UC_UNAVAILABLE | gamestate); - else - serv_got_update(gc, name, 1, 0, 0, 0, (state << 2) | gamestate); - } - away = 0; - idle = 0; break; - case 60: /* SMS, but comes after 13. but name hasnt been destroyed yet. */ - break; case 16: /* Custom error message */ gaim_notify_error(gc, NULL, pair->value, NULL); break; @@ -388,60 +436,100 @@ gboolean got_serv_list = FALSE; GaimBuddy *b; GaimGroup *g; + struct yahoo_friend *f = NULL; + struct yahoo_data *yd = gc->proto_data; + + char **lines; + char **split; + char **buddies; + char **tmp, **bud; while (l) { - char **lines; - char **split; - char **buddies; - char **tmp, **bud; - struct yahoo_pair *pair = l->data; l = l->next; switch (pair->key) { case 87: - lines = g_strsplit(pair->value, "\n", -1); - for (tmp = lines; *tmp; tmp++) { - split = g_strsplit(*tmp, ":", 2); - if (!split) - continue; - if (!split[0] || !split[1]) { - g_strfreev(split); - continue; - } - buddies = g_strsplit(split[1], ",", -1); - for (bud = buddies; bud && *bud; bud++) - if (!(b = gaim_find_buddy(gc->account, *bud))) { - if (!(g = gaim_find_group(split[0]))) { - g = gaim_group_new(split[0]); - gaim_blist_add_group(g, NULL); - } - b = gaim_buddy_new(gc->account, *bud, NULL); - gaim_blist_add_buddy(b, NULL, g, NULL); - export = TRUE; - } - g_strfreev(buddies); - g_strfreev(split); - } - g_strfreev(lines); + if (!yd->tmp_serv_blist) + yd->tmp_serv_blist = g_string_new(pair->value); + else + g_string_append(yd->tmp_serv_blist, pair->value); break; case 88: - buddies = g_strsplit(pair->value, ",", -1); - for (bud = buddies; bud && *bud; bud++) { - /* The server is already ignoring the user */ - got_serv_list = TRUE; - gaim_privacy_deny_add(gc->account, *bud, 1); - } - g_strfreev(buddies); + if (!yd->tmp_serv_ilist) + yd->tmp_serv_ilist = g_string_new(pair->value); + else + g_string_append(yd->tmp_serv_ilist, pair->value); break; } - - if (got_serv_list) { - gc->account->perm_deny = 4; - serv_set_permit_deny(gc); - } } + if (pkt->status != 0) + return; + + if (yd->tmp_serv_blist) { + lines = g_strsplit(yd->tmp_serv_blist->str, "\n", -1); + for (tmp = lines; *tmp; tmp++) { + split = g_strsplit(*tmp, ":", 2); + if (!split) + continue; + if (!split[0] || !split[1]) { + g_strfreev(split); + continue; + } + buddies = g_strsplit(split[1], ",", -1); + for (bud = buddies; bud && *bud; bud++) { + if (!(f = g_hash_table_lookup(yd->friends, *bud))) { + f = yahoo_friend_new(*bud); + g_hash_table_insert(yd->friends, g_strdup(*bud), f); + } + if (!(b = gaim_find_buddy(gc->account, *bud))) { + if (!(g = gaim_find_group(split[0]))) { + g = gaim_group_new(split[0]); + gaim_blist_add_group(g, NULL); + } + b = gaim_buddy_new(gc->account, *bud, NULL); + gaim_blist_add_buddy(b, NULL, g, NULL); + export = TRUE; + } /*else { do something here is gaim and yahoo don't agree on the buddies group + GaimGroup *tmpgp; + + tmpgp = gaim_find_buddys_group(b); + if (!tmpgp || !gaim_utf8_strcasecmp(tmpgp->name, split[0])) { + GaimGroup *ng; + if (!(ng = gaim_find_group(split[0])) { + g = gaim_group_new(split[0]); + gaim_blist_add_group(g, NULL); + } */ + + } + g_strfreev(buddies); + g_strfreev(split); + } + g_strfreev(lines); + + g_string_free(yd->tmp_serv_blist, TRUE); + yd->tmp_serv_blist = NULL; + } + + + if (yd->tmp_serv_ilist) { + buddies = g_strsplit(yd->tmp_serv_ilist->str, ",", -1); + for (bud = buddies; bud && *bud; bud++) { + /* The server is already ignoring the user */ + got_serv_list = TRUE; + gaim_privacy_deny_add(gc->account, *bud, 1); + } + g_strfreev(buddies); + + g_string_free(yd->tmp_serv_ilist, TRUE); + yd->tmp_serv_ilist = NULL; + } + + if (got_serv_list) { + gc->account->perm_deny = 4; + serv_set_permit_deny(gc); + } if (export) gaim_blist_save(); } @@ -452,8 +540,10 @@ char *from = NULL; char *stat = NULL; char *game = NULL; + struct yahoo_friend *f = NULL; GSList *l = pkt->hash; struct yahoo_data *yd = (struct yahoo_data*) gc->proto_data; + while (l) { struct yahoo_pair *pair = l->data; if (pair->key == 4) @@ -467,7 +557,7 @@ l = l->next; } - if (!msg) + if (!from || !msg) return; if (!g_ascii_strncasecmp(msg, "TYPING", strlen("TYPING"))) { @@ -477,29 +567,26 @@ serv_got_typing_stopped(gc, from); } else if (!g_ascii_strncasecmp(msg, "GAME", strlen("GAME"))) { GaimBuddy *bud = gaim_find_buddy(gc->account, from); - void *free1=NULL, *free2=NULL; + if (!bud) { gaim_debug(GAIM_DEBUG_WARNING, "yahoo", "%s is playing a game, and doesn't want " "you to know.\n", from); } + f = g_hash_table_lookup(yd->friends, from); + if (!f) + return; /* if they're not on the list, don't bother */ + + if (f->game) { + g_free(f->game); + f->game = NULL; + } + if (*stat == '1') { - if (g_hash_table_lookup_extended (yd->games, from, free1, free2)) { - g_free(free1); - g_free(free2); - } - g_hash_table_insert (yd->games, g_strdup(from), g_strdup(game)); + f->game = g_strdup(game); if (bud) - serv_got_update(gc, from, 1, 0, 0, 0, bud->uc | YAHOO_STATUS_GAME); - } else { - if (g_hash_table_lookup_extended (yd->games, from, free1, free2)) { - g_free(free1); - g_free(free2); - g_hash_table_remove (yd->games, from); - } - if (bud) - serv_got_update(gc, from, 1, 0, 0, 0, bud->uc & ~YAHOO_STATUS_GAME); + yahoo_update_status(gc, from, f); } } } @@ -573,6 +660,7 @@ char *msg = NULL; GSList *l = pkt->hash; GString *buf = NULL; + struct yahoo_data *yd = gc->proto_data; while (l) { struct yahoo_pair *pair = l->data; @@ -596,6 +684,8 @@ g_string_printf(buf, _("%s has (retroactively) denied your request to add them to your list for the following reason: %s."), who, msg); gaim_notify_info(gc, NULL, buf->str, NULL); g_string_free(buf, TRUE); + g_hash_table_remove(yd->friends, who); + serv_got_update(gc, who, 0, 0, 0, 0, 0); } } @@ -695,6 +785,7 @@ char *sn = NULL; GSList *l = pkt->hash; struct yahoo_data *yd = gc->proto_data; + GaimAccount *account = gaim_connection_get_account(gc); while (l) { struct yahoo_pair *pair = l->data; @@ -707,7 +798,6 @@ if (seed) { struct yahoo_packet *pack; - GaimAccount *account = gaim_connection_get_account(gc); const char *name = normalize(gaim_account_get_username(account)); const char *pass = gaim_account_get_password(account); @@ -803,7 +893,7 @@ md5_finish(&ctx, result); to_y64(result96, result, 16); - pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, YAHOO_STATUS_AVAILABLE, 0); + pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, YAHOO_STATUS_AVAILABLE, 0); yahoo_packet_hash(pack, 0, name); yahoo_packet_hash(pack, 6, result6); yahoo_packet_hash(pack, 96, result96); @@ -955,6 +1045,9 @@ case YAHOO_SERVICE_NEWCONTACT: yahoo_process_contact(gc, pkt); break; + case YAHOO_SERVICE_AUTHRESP: + yahoo_process_authresp(gc, pkt); + break; case YAHOO_SERVICE_LIST: yahoo_process_list(gc, pkt); break; @@ -964,9 +1057,6 @@ case YAHOO_SERVICE_IGNORECONTACT: yahoo_process_ignore(gc, pkt); break; - case YAHOO_SERVICE_AUTHRESP: - yahoo_process_authresp(gc, pkt); - break; case YAHOO_SERVICE_CONFINVITE: case YAHOO_SERVICE_CONFADDINVITE: yahoo_process_conference_invite(gc, pkt); @@ -1117,8 +1207,7 @@ gaim_connection_update_progress(gc, _("Connecting"), 1, 2); yd->fd = -1; - yd->hash = g_hash_table_new(g_str_hash, g_str_equal); - yd->games = g_hash_table_new(g_str_hash, g_str_equal); + yd->friends = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, yahoo_friend_free); yd->confs = NULL; yd->conf_id = 2; @@ -1131,21 +1220,13 @@ } -static gboolean yahoo_destroy_hash(gpointer key, gpointer val, gpointer data) -{ - g_free(key); - g_free(val); - return TRUE; -} - static void yahoo_close(GaimConnection *gc) { struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; - g_hash_table_foreach_remove(yd->hash, yahoo_destroy_hash, NULL); - g_hash_table_destroy(yd->hash); - g_hash_table_foreach_remove(yd->games, yahoo_destroy_hash, NULL); - g_hash_table_destroy(yd->games); + g_hash_table_destroy(yd->friends); g_slist_free(yd->confs); + if (yd->chat_name) + g_free(yd->chat_name); if (yd->fd >= 0) close(yd->fd); @@ -1167,13 +1248,30 @@ { int i = 0; char *emblems[4] = {NULL,NULL,NULL,NULL}; + GaimAccount *account; + GaimConnection *gc; + struct yahoo_data *yd; + struct yahoo_friend *f; + + if (!b || !(account = b->account) || !(gc = gaim_account_get_connection(account)) || + !(yd = gc->proto_data)) + return; + + f = g_hash_table_lookup(yd->friends, b->name); + if (!f) { + *se = "notauthorized"; + return; + } + if (b->present == GAIM_BUDDY_OFFLINE) { *se = "offline"; return; } else { - if (b->uc & UC_UNAVAILABLE) + if (f->away) emblems[i++] = "away"; - if (b->uc & YAHOO_STATUS_GAME) + if (f->sms) + emblems[i++] = "wireless"; + if (f->game) emblems[i++] = "game"; } *se = emblems[0]; @@ -1207,6 +1305,8 @@ return _("Invisible"); case YAHOO_STATUS_IDLE: return _("Idle"); + case YAHOO_STATUS_OFFLINE: + return _("Offline"); default: return _("Online"); } @@ -1234,12 +1334,19 @@ static void yahoo_game(GaimConnection *gc, const char *name) { struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; - char *game = g_hash_table_lookup(yd->games, name); + char *game = NULL; char *t; char url[256]; + struct yahoo_friend *f; + f = g_hash_table_lookup(yd->friends, name); + if (!f) + return; + + game = f->game; if (!game) return; + t = game = g_strdup(strstr(game, "ante?room=")); while (*t != '\t') t++; @@ -1252,40 +1359,70 @@ static char *yahoo_status_text(GaimBuddy *b) { struct yahoo_data *yd = (struct yahoo_data*)b->account->gc->proto_data; + struct yahoo_friend *f = NULL; + char *stripped = NULL; - if ((b->uc & UC_UNAVAILABLE) && ((b->uc >> 2) != YAHOO_STATUS_CUSTOM) - && ((b->uc >> 2) != YAHOO_STATUS_IDLE)) - return g_strdup(yahoo_get_status_string(b->uc >> 2)); - else if ((b->uc >> 2) == YAHOO_STATUS_CUSTOM) { - char *stripped = strip_html(g_hash_table_lookup(yd->hash, b->name)); - if(stripped) { - char *ret = g_markup_escape_text(stripped, strlen(stripped)); - g_free(stripped); - return ret; - } - } + f = g_hash_table_lookup(yd->friends, b->name); + if (!f) + return g_strdup(_("Not on server list")); + + switch (f->status) { + case YAHOO_STATUS_AVAILABLE: + return NULL; + case YAHOO_STATUS_IDLE: + if (f->idle == -1) + return g_strdup(yahoo_get_status_string(f->status)); + return NULL; + case YAHOO_STATUS_CUSTOM: + if (!f->msg) + return NULL; + stripped = strip_html(f->msg); + if (stripped) { + char *ret = g_markup_escape_text(stripped, strlen(stripped)); + g_free(stripped); + return ret; + } + return NULL; + default: + return g_strdup(yahoo_get_status_string(f->status)); + } + return NULL; } static char *yahoo_tooltip_text(GaimBuddy *b) { struct yahoo_data *yd = (struct yahoo_data*)b->account->gc->proto_data; - if ((b->uc & UC_UNAVAILABLE) || ((b->uc >> 2) == YAHOO_STATUS_CUSTOM)) { - char *status; - char *ret; - if ((b->uc >> 2) != YAHOO_STATUS_CUSTOM) - status = g_strdup(yahoo_get_status_string(b->uc >> 2)); - else - status = strip_html(g_hash_table_lookup(yd->hash, b->name)); - if(status) { - char *escaped = g_markup_escape_text(status, strlen(status)); - ret = g_strdup_printf(_("<b>Status:</b> %s"), escaped); - g_free(status); - g_free(escaped); - return ret; + struct yahoo_friend *f; + char *escaped, *status, *ret; + + f = g_hash_table_lookup(yd->friends, b->name); + if (!f) + status = g_strdup(_("Not on server list")); + else + switch (f->status) { + case YAHOO_STATUS_IDLE: + if (f->idle == -1) { + status = g_strdup(yahoo_get_status_string(f->status)); + break; + } + return NULL; + case YAHOO_STATUS_CUSTOM: + if (!f->msg) + return NULL; + status = strip_html(f->msg); + break; + default: + status = g_strdup(yahoo_get_status_string(f->status)); + break; } - } - return NULL; + + escaped = g_markup_escape_text(status, strlen(status)); + ret = g_strdup_printf(_("<b>Status:</b> %s"), escaped); + g_free(status); + g_free(escaped); + + return ret; } static GList *yahoo_buddy_menu(GaimConnection *gc, const char *who) @@ -1293,9 +1430,23 @@ GList *m = NULL; struct proto_buddy_menu *pbm; struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; - GaimBuddy *b = gaim_find_buddy(gc->account, who); /* this should never be null. if it is, - segfault and get the bug report. */ static char buf2[1024]; + struct yahoo_friend *f; + + f = g_hash_table_lookup(yd->friends, who); + + if (!f) { + pbm = g_new0(struct proto_buddy_menu, 1); + pbm->label = _("Add Buddy"); + pbm->callback = yahoo_add_buddy; + pbm->gc = gc; + m = g_list_append(m, pbm); + + return m; + } + + if (f->status == YAHOO_STATUS_OFFLINE) + return NULL; pbm = g_new0(struct proto_buddy_menu, 1); pbm->label = _("Join in Chat"); @@ -1309,28 +1460,28 @@ pbm->gc = gc; m = g_list_append(m, pbm); - if (b->uc | YAHOO_STATUS_GAME) { - char *game = g_hash_table_lookup(yd->games, b->name); + if (f->game) { + char *game = f->game; char *room; + char *t; + if (!game) return m; - if (game) { - char *t; - pbm = g_new0(struct proto_buddy_menu, 1); - if (!(room = strstr(game, "&follow="))) /* skip ahead to the url */ - return m; - while (*room && *room != '\t') /* skip to the tab */ - room++; - t = room++; /* room as now at the name */ - while (*t != '\n') - t++; /* replace the \n with a space */ - *t = ' '; - g_snprintf(buf2, sizeof buf2, "%s", room); - pbm->label = buf2; - pbm->callback = yahoo_game; - pbm->gc = gc; - m = g_list_append(m, pbm); - } + + pbm = g_new0(struct proto_buddy_menu, 1); + if (!(room = strstr(game, "&follow="))) /* skip ahead to the url */ + return m; + while (*room && *room != '\t') /* skip to the tab */ + room++; + t = room++; /* room as now at the name */ + while (*t != '\n') + t++; /* replace the \n with a space */ + *t = ' '; + g_snprintf(buf2, sizeof buf2, "%s", room); + pbm->label = buf2; + pbm->callback = yahoo_game; + pbm->gc = gc; + m = g_list_append(m, pbm); } return m; @@ -1471,8 +1622,11 @@ g_snprintf(s, sizeof(s), "%d", yd->current_status); yahoo_packet_hash(pkt, 10, s); if (yd->current_status == YAHOO_STATUS_CUSTOM) { - yahoo_packet_hash(pkt, 47, "1"); yahoo_packet_hash(pkt, 19, msg); + if (gc->is_idle) + yahoo_packet_hash(pkt, 47, "2"); + else + yahoo_packet_hash(pkt, 47, "1"); } yahoo_send_packet(yd, pkt); @@ -1490,12 +1644,23 @@ } else if (!idle && yd->current_status == YAHOO_STATUS_IDLE) { pkt = yahoo_packet_new(YAHOO_SERVICE_ISAWAY, YAHOO_STATUS_AVAILABLE, 0); yd->current_status = YAHOO_STATUS_AVAILABLE; + } else if (idle && gc->away && yd->current_status == YAHOO_STATUS_CUSTOM) { + pkt = yahoo_packet_new(YAHOO_SERVICE_ISAWAY, YAHOO_STATUS_IDLE, 0); + } else if (!idle && gc->away && yd->current_status == YAHOO_STATUS_CUSTOM) { + pkt = yahoo_packet_new(YAHOO_SERVICE_ISAWAY, YAHOO_STATUS_AVAILABLE, 0); } if (pkt) { char buf[4]; g_snprintf(buf, sizeof(buf), "%d", yd->current_status); yahoo_packet_hash(pkt, 10, buf); + if (gc->away && yd->current_status == YAHOO_STATUS_CUSTOM) { + yahoo_packet_hash(pkt, 19, gc->away); + if (idle) + yahoo_packet_hash(pkt, 47, "2"); + else + yahoo_packet_hash(pkt, 47, "1"); /* fixme when available messages are possible */ + } yahoo_send_packet(yd, pkt); yahoo_packet_free(pkt); } @@ -1564,6 +1729,12 @@ static void yahoo_remove_buddy(GaimConnection *gc, const char *who, const char *group) { struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; + struct yahoo_friend *f; + + if (!(f = g_hash_table_lookup(yd->friends, who))) + return; + + g_hash_table_remove(yd->friends, who); struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YAHOO_STATUS_AVAILABLE, 0); yahoo_packet_hash(pkt, 1, gaim_connection_get_display_name(gc)); @@ -1908,7 +2079,6 @@ YAHOO_PAGER_PORT); prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); - my_protocol = plugin; yahoo_init_colorht();
--- a/src/protocols/yahoo/yahoo.h Sun Sep 07 21:00:34 2003 +0000 +++ b/src/protocols/yahoo/yahoo.h Sun Sep 07 21:59:55 2003 +0000 @@ -23,6 +23,8 @@ #ifndef _YAHOO_H_ #define _YAHOO_H_ +#include "prpl.h" + enum yahoo_service { /* these are easier to see in hex */ YAHOO_SERVICE_LOGON = 1, YAHOO_SERVICE_LOGOFF, @@ -100,16 +102,15 @@ YAHOO_STATUS_OFFLINE = 0x5a55aa56, /* don't ask */ YAHOO_STATUS_TYPING = 0x16 }; -#define YAHOO_STATUS_GAME 0x2 /* Games don't fit into the regular status model */ struct yahoo_data { int fd; guchar *rxqueue; int rxlen; - GHashTable *hash; - GHashTable *games; + GHashTable *friends; int current_status; gboolean logged_in; + GString *tmp_serv_blist, *tmp_serv_ilist; GSList *confs; unsigned int conf_id; /* just a counter */ gboolean chat_online; @@ -129,6 +130,15 @@ GSList *hash; }; +struct yahoo_friend { /* we'll call them friends, so we don't confuse them with GaimBuddy */ + enum yahoo_status status; + char *msg; + char *game; + int idle; + int away; + gboolean sms; +}; + struct yahoo_packet *yahoo_packet_new(enum yahoo_service service, enum yahoo_status status, int id); void yahoo_packet_hash(struct yahoo_packet *pkt, int key, const char *value); int yahoo_send_packet(struct yahoo_data *yd, struct yahoo_packet *pkt);