/* the buddy approves your request of adding him/her as your friend */ static void server_buddy_added_me(PurpleConnection *gc, gchar *from, gchar *to, guint8 *data, gint data_len) { PurpleAccount *account = purple_connection_get_account(gc); qq_data *qd; guint32 uid; g_return_if_fail(from != NULL && to != NULL); qd = (qq_data *) gc->proto_data; uid = strtoul(from, NULL, 10); g_return_if_fail(uid > 0); server_buddy_check_code(gc, from, data, data_len); qq_buddy_find_or_new(gc, uid); qq_request_buddy_info(gc, uid, 0, 0); qq_request_get_buddies_online(gc, 0, 0); if (qd->client_version >= 2007) { qq_request_get_level_2007(gc, uid); } else { qq_request_get_level(gc, uid); } purple_account_notify_added(account, to, from, NULL, NULL); }
void qq_process_add_buddy_no_auth(PurpleConnection *gc, guint8 *data, gint data_len, guint32 uid) { qq_data *qd; gchar **segments; gchar *dest_uid, *reply; PurpleBuddy *buddy; g_return_if_fail(data != NULL && data_len != 0); g_return_if_fail(uid != 0); qd = (qq_data *) gc->proto_data; purple_debug_info("QQ", "Process buddy add for id [%u]\n", uid); qq_show_packet("buddy_add_no_auth", data, data_len); if (NULL == (segments = split_data(data, data_len, "\x1f", 2))) return; dest_uid = segments[0]; reply = segments[1]; if (strtoul(dest_uid, NULL, 10) != qd->uid) { /* should not happen */ purple_debug_error("QQ", "Add buddy reply is to [%s], not me!", dest_uid); g_strfreev(segments); return; } if (strtol(reply, NULL, 10) == 0) { /* add OK */ qq_buddy_find_or_new(gc, uid); qq_request_buddy_info(gc, uid, 0, 0); if (qd->client_version >= 2007) { qq_request_get_level_2007(gc, uid); } else { qq_request_get_level(gc, uid); } qq_request_get_buddies_online(gc, 0, 0); purple_debug_info("QQ", "Successed adding into %u's buddy list", uid); g_strfreev(segments); return; } /* need auth */ purple_debug_warning("QQ", "Failed adding buddy, need authorize\n"); buddy = qq_buddy_find(gc, uid); if (buddy == NULL) { buddy = qq_buddy_new(gc, uid); } if (buddy != NULL && buddy->proto_data != NULL) { /* Not authorized now, free buddy data */ qq_buddy_data_free(buddy->proto_data); buddy->proto_data = NULL; } add_buddy_authorize_input(gc, uid, NULL, 0); g_strfreev(segments); }
void qq_process_add_buddy_touch( PurpleConnection *gc, guint8 *data, gint data_len, qq_buddy_opt_req *opt_req ) { qq_data *qd; gint bytes; guint32 dest_uid; guint8 reply; g_return_if_fail(data != NULL && data_len >= 5); g_return_if_fail(opt_req && opt_req->uid != 0); qd = (qq_data *) gc->proto_data; purple_debug_info("QQ", "Process buddy add no auth for id [%u]\n", opt_req->uid); qq_show_packet("buddy_add_no_auth_ex", data, data_len); bytes = 0; bytes += qq_get32(&dest_uid, data + bytes); bytes += qq_get8(&reply, data + bytes); g_return_if_fail(dest_uid == opt_req->uid); if (reply == 0x99) { purple_debug_info("QQ", "Successfully added buddy %u\n", opt_req->uid); qq_buddy_find_or_new(gc, opt_req->uid, opt_req->group_id); qq_request_get_buddy_info(gc, opt_req->uid, 0, 0); qq_request_get_level(gc, opt_req->uid); qq_request_get_buddies_online(gc, 0, 0); return; } if (reply != 0) { purple_debug_info("QQ", "Failed adding buddy %u, Unknown reply 0x%02X\n", opt_req->uid, reply); } /* need auth */ g_return_if_fail(data_len > bytes); bytes += qq_get8(&opt_req->auth_type, data + bytes); purple_debug_warning("QQ", "Adding buddy needs authorize 0x%02X\n", opt_req->auth_type); switch (opt_req->auth_type) { case 0x00: /* no authorize */ case 0x01: /* authorize */ qq_request_auth_token(gc, QQ_AUTH_INFO_BUDDY, QQ_AUTH_INFO_ADD_BUDDY, 0, opt_req); break; case 0x02: /* disable */ break; case 0x03: /* answer question */ qq_request_question(gc, QQ_QUESTION_REQUEST, opt_req->uid, NULL, NULL); break; case 0x04: /* deny! */ break; default: g_return_if_reached(); break; } return; }
/* after getting info or modify myself, refresh the buddy list accordingly */ static void update_buddy_info(PurpleConnection *gc, gchar **segments) { PurpleBuddy *buddy; qq_data *qd; qq_buddy_data *bd; guint32 uid; gchar *who; gchar *alias_utf8; PurpleAccount *account = purple_connection_get_account(gc); qd = (qq_data *) gc->proto_data; uid = strtoul(segments[QQ_INFO_UID], NULL, 10); who = uid_to_purple_name(uid); qq_filter_str(segments[QQ_INFO_NICK]); alias_utf8 = qq_to_utf8(segments[QQ_INFO_NICK], QQ_CHARSET_DEFAULT); if (uid == qd->uid) { /* it is me */ purple_debug_info("QQ", "Got my info\n"); qd->my_icon = strtol(segments[QQ_INFO_FACE], NULL, 10); if (alias_utf8 != NULL) { purple_account_set_alias(account, alias_utf8); } /* add me to buddy list */ buddy = qq_buddy_find_or_new(gc, uid); } else { buddy = purple_find_buddy(gc->account, who); } if (buddy == NULL || buddy->proto_data == NULL) { g_free(who); g_free(alias_utf8); return; } /* update buddy list (including myself, if myself is the buddy) */ bd = (qq_buddy_data *)buddy->proto_data; bd->age = strtol(segments[QQ_INFO_AGE], NULL, 10); bd->gender = strtol(segments[QQ_INFO_GENDER], NULL, 10); bd->face = strtol(segments[QQ_INFO_FACE], NULL, 10); if (alias_utf8 != NULL) { if (bd->nickname) g_free(bd->nickname); bd->nickname = g_strdup(alias_utf8); } bd->last_update = time(NULL); purple_blist_server_alias_buddy(buddy, bd->nickname); /* convert face num from packet (0-299) to local face (1-100) */ qq_update_buddy_icon(gc->account, who, bd->face); g_free(who); g_free(alias_utf8); }
void qq_process_add_buddy_post( PurpleConnection *gc, guint8 *data, gint data_len, guintptr auth_type ) { guint32 uid; g_return_if_fail(data != NULL && data_len != 0); qq_get32(&uid, data+1); //qq_show_packet("qq_process_add_buddy_post", data, data_len); if (auth_type == 0) { qq_buddy_find_or_new(gc, uid, 0xFF); qq_request_get_buddy_info(gc, uid, 0, 0); qq_request_get_buddies_online(gc, 0, 0); qq_request_get_level(gc, uid); } }
void qq_got_message(PurpleConnection *gc, const gchar *msg) { qq_data *qd; gchar *from; time_t now = time(NULL); g_return_if_fail(gc != NULL && gc->proto_data != NULL); qd = gc->proto_data; g_return_if_fail(qd->uid > 0); qq_buddy_find_or_new(gc, qd->uid); from = uid_to_purple_name(qd->uid); serv_got_im(gc, from, msg, PURPLE_MESSAGE_SYSTEM, now); g_free(from); }
static void server_buddy_added(PurpleConnection *gc, gchar *from, gchar *to, guint8 *data, gint data_len) { guint32 uid; g_return_if_fail(from != NULL && to != NULL); g_return_if_fail(data != NULL); qq_show_packet("server_buddy_added", data, data_len); purple_debug_info("QQ", "Buddy %s added \n", from); //server_buddy_check_code(gc, from, data + bytes, data_len - bytes); uid = purple_name_to_uid(from); qq_buddy_find_or_new(gc, uid, 0xFF); qq_request_get_buddy_info(gc, uid, 0, 0); qq_request_get_buddies_online(gc, 0, 0); qq_request_get_level(gc, uid); }
void qq_process_add_buddy_no_auth_ex(PurpleConnection *gc, guint8 *data, gint data_len, guint32 uid) { qq_data *qd; gint bytes; guint32 dest_uid; guint8 reply; guint8 auth_type; g_return_if_fail(data != NULL && data_len >= 5); g_return_if_fail(uid != 0); qd = (qq_data *) gc->proto_data; purple_debug_info("QQ", "Process buddy add no auth for id [%u]\n", uid); qq_show_packet("buddy_add_no_auth_ex", data, data_len); bytes = 0; bytes += qq_get32(&dest_uid, data + bytes); bytes += qq_get8(&reply, data + bytes); g_return_if_fail(dest_uid == uid); if (reply == 0x99) { purple_debug_info("QQ", "Successed adding buddy %u\n", uid); qq_buddy_find_or_new(gc, uid); qq_request_buddy_info(gc, uid, 0, 0); if (qd->client_version >= 2007) { qq_request_get_level_2007(gc, uid); } else { qq_request_get_level(gc, uid); } qq_request_get_buddies_online(gc, 0, 0); return; } if (reply != 0) { purple_debug_info("QQ", "Failed adding buddy %u, Unknow reply 0x%02X\n", uid, reply); } /* need auth */ g_return_if_fail(data_len > bytes); bytes += qq_get8(&auth_type, data + bytes); purple_debug_warning("QQ", "Adding buddy needs authorize 0x%02X\n", auth_type); switch (auth_type) { case 0x00: /* no authorize */ break; case 0x01: /* authorize */ qq_request_auth_code(gc, QQ_AUTH_INFO_BUDDY, QQ_AUTH_INFO_ADD_BUDDY, uid); break; case 0x02: /* disable */ break; case 0x03: /* answer question */ qq_request_question(gc, QQ_QUESTION_REQUEST, uid, NULL, NULL); break; default: g_return_if_reached(); break; } return; }