void qq_process_auth_token( PurpleConnection *gc, guint8 *data, gint data_len, guint32 dataptr, qq_buddy_opt_req *opt_req ) { gint bytes; guint8 cmd, reply; guint16 sub_cmd; guint8 *code = NULL; guint16 code_len = 0; g_return_if_fail(data != NULL && data_len != 0); g_return_if_fail(opt_req && opt_req->uid != 0); //qq_show_packet("qq_process_auth_token", data, data_len); bytes = 0; bytes += qq_get8(&cmd, data + bytes); bytes += qq_get16(&sub_cmd, data + bytes); bytes += qq_get8(&reply, data + bytes); /* if reply == 0x01, we need request captcha */ if (reply) { /* if this is end, means you have submitted the wrong captcha */ if (bytes>=data_len) { qq_request_auth_token(gc, QQ_AUTH_INFO_BUDDY, QQ_AUTH_INFO_ADD_BUDDY, 0, opt_req); return; } bytes += qq_get_vstr(&code, NULL, sizeof(guint16), data + bytes); purple_util_fetch_url_request( (gchar *)code, TRUE, NULL, TRUE, NULL, TRUE, auth_token_captcha_input_cb, opt_req); return; } bytes += qq_get16(&opt_req->auth_len, data + bytes); g_return_if_fail(opt_req->auth_len > 0); g_return_if_fail(bytes + opt_req->auth_len <= data_len); opt_req->auth = g_new0(guint8, opt_req->auth_len); bytes += qq_getdata(opt_req->auth, opt_req->auth_len, data + bytes); if (cmd == QQ_AUTH_INFO_BUDDY && sub_cmd == QQ_AUTH_INFO_REMOVE_BUDDY) { qq_request_remove_buddy(gc, opt_req); return; } if (sub_cmd == QQ_AUTH_INFO_ADD_BUDDY) { if (opt_req->auth_type == 0x01) add_buddy_authorize_input(gc, opt_req); else if (opt_req->auth_type == 0x00) qq_request_search_uid(gc, opt_req); return; } if (cmd == QQ_AUTH_INFO_BUDDY && sub_cmd == QQ_AUTH_INFO_UPDATE_BUDDY_INFO) { request_change_info(gc, (guint8 *)dataptr, code, code_len); return; } purple_debug_info("QQ", "Got auth info cmd 0x%x, sub 0x%x, reply 0x%x\n", cmd, sub_cmd, reply); }
/* process reply to get_info packet */ void qq_process_get_buddy_info(guint8 *data, gint data_len, guint32 action, PurpleConnection *gc) { qq_data *qd; gchar **segments; gint field_count; gchar *icon_name; g_return_if_fail(data != NULL && data_len != 0); qd = (qq_data *) gc->proto_data; if (qd->client_version >= 2008) { field_count = QQ_INFO_LAST; } else { field_count = QQ_INFO_LAST_2007; } if (NULL == (segments = split_data(data, data_len, "\x1e", field_count))) return; #ifdef DEBUG info_debug(segments); #endif if (action == QQ_BUDDY_INFO_SET_ICON) { if (strtol(segments[QQ_INFO_FACE], NULL, 10) != qd->my_icon) { icon_name = g_strdup_printf("%d", qd->my_icon); g_free(segments[QQ_INFO_FACE]); segments[QQ_INFO_FACE] = icon_name; /* Update me in buddy list */ update_buddy_info(gc, segments); /* send new face to server */ request_change_info(gc, segments); } g_strfreev(segments); return; } update_buddy_info(gc, segments); switch (action) { case QQ_BUDDY_INFO_DISPLAY: info_display_only(gc, segments); break; case QQ_BUDDY_INFO_SET_ICON: g_return_if_reached(); break; case QQ_BUDDY_INFO_MODIFY_BASE: info_modify_dialogue(gc, segments, QQ_FIELD_BASE); break; case QQ_BUDDY_INFO_MODIFY_EXT: info_modify_dialogue(gc, segments, QQ_FIELD_EXT); break; case QQ_BUDDY_INFO_MODIFY_ADDR: info_modify_dialogue(gc, segments, QQ_FIELD_ADDR); break; case QQ_BUDDY_INFO_MODIFY_CONTACT: info_modify_dialogue(gc, segments, QQ_FIELD_CONTACT); break; default: g_strfreev(segments); break; } return; }
/* parse fields and send info packet */ static void info_modify_ok_cb(modify_info_request *info_request, PurpleRequestFields *fields) { PurpleConnection *gc; qq_data *qd; gchar **segments; int index; const char *utf8_str; gchar *value; int choice_num; gc = info_request->gc; g_return_if_fail(gc != NULL && info_request->gc); qd = (qq_data *) gc->proto_data; segments = info_request->segments; g_return_if_fail(segments != NULL); for (index = 1; segments[index] != NULL && index < QQ_INFO_LAST; index++) { if (field_infos[index].iclass == QQ_FIELD_UNUSED) { continue; } if (!purple_request_fields_exists(fields, field_infos[index].id)) { continue; } switch (field_infos[index].type) { case QQ_FIELD_BOOL: value = purple_request_fields_get_bool(fields, field_infos[index].id) ? g_strdup("1") : g_strdup("0"); g_free(segments[index]); segments[index] = value; break; case QQ_FIELD_CHOICE: choice_num = purple_request_fields_get_choice(fields, field_infos[index].id); if (choice_num < 0 || choice_num >= field_infos[index].choice_size) choice_num = 0; if (index == QQ_INFO_GENDER) { /* QQ Server only recept gender in Chinese */ value = g_strdup(genders_zh[choice_num]); } else { value = g_strdup_printf("%d", choice_num); } g_free(segments[index]); segments[index] = value; break; case QQ_FIELD_LABEL: case QQ_FIELD_STRING: case QQ_FIELD_MULTI: default: utf8_str = purple_request_fields_get_string(fields, field_infos[index].id); if (utf8_str == NULL) { value = g_strdup("-"); } else { value = utf8_to_qq(utf8_str, QQ_CHARSET_DEFAULT); if (value == NULL) value = g_strdup("-"); } g_free(segments[index]); segments[index] = value; break; } } request_change_info(gc, segments); g_strfreev(segments); g_free(info_request); }