/* 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; }
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_update_online(PurpleConnection *gc, guint16 cmd) { qq_data *qd; g_return_if_fail (gc != NULL && gc->proto_data != NULL); qd = (qq_data *) gc->proto_data; switch (cmd) { case 0: qq_request_get_buddies_online(gc, 0, QQ_CMD_CLASS_UPDATE_ONLINE); break; case QQ_CMD_GET_BUDDIES_ONLINE: /* last command */ update_all_rooms_online(gc, 0, 0); break; default: break; } qd->online_last_update = time(NULL); }
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_update_all(PurpleConnection *gc, guint16 cmd) { qq_data *qd; g_return_if_fail (gc != NULL && gc->proto_data != NULL); qd = (qq_data *) gc->proto_data; switch (cmd) { case 0: qq_request_get_buddy_info(gc, qd->uid, QQ_CMD_CLASS_UPDATE_ALL, 0); break; case QQ_CMD_GET_BUDDY_INFO: qq_request_change_status(gc, QQ_CMD_CLASS_UPDATE_ALL); break; case QQ_CMD_CHANGE_STATUS: qq_request_get_group_list(gc, 0, QQ_CMD_CLASS_UPDATE_ALL); break; case QQ_CMD_GET_GROUP_LIST: qq_request_get_buddies_list(gc, 0, QQ_CMD_CLASS_UPDATE_ALL); break; case QQ_CMD_GET_BUDDIES_LIST: qq_request_buddy_memo(gc, 0, QQ_CMD_CLASS_UPDATE_ALL, QQ_BUDDY_MEMO_ALIAS); break; case QQ_CMD_BUDDY_MEMO: qq_request_get_buddies_level(gc, QQ_CMD_CLASS_UPDATE_ALL, 0); break; case QQ_CMD_GET_LEVEL: qq_request_get_buddies_online(gc, 0, QQ_CMD_CLASS_UPDATE_ALL); break; case QQ_CMD_GET_BUDDIES_ONLINE: qq_request_get_buddies_sign(gc, QQ_CMD_CLASS_UPDATE_ALL, 0); break; case QQ_CMD_GET_BUDDIES_SIGN: /* last command */ qq_update_all_rooms(gc, 0, 0); break; default: break; } qd->online_last_update = time(NULL); }
void qq_proc_client_cmds(PurpleConnection *gc, guint16 cmd, guint16 seq, guint8 *rcved, gint rcved_len, guint32 update_class, guintptr ship_value) { qq_data *qd; guint8 *data; gint data_len; guint8 ret_8 = 0; guint16 ret_16 = 0; guint32 ret_32 = 0; gboolean not_to_update = FALSE; g_return_if_fail(rcved_len > 0); g_return_if_fail (gc != NULL && gc->proto_data != NULL); qd = (qq_data *) gc->proto_data; data = g_newa(guint8, rcved_len); data_len = qq_decrypt(data, rcved, rcved_len, qd->session_key); if (data_len < 0) { purple_debug_warning("QQ", "Reply can not be decrypted by session key, [%05d], 0x%04X %s, len %d\n", seq, cmd, qq_get_cmd_desc(cmd), rcved_len); qq_show_packet("Can not decrypted", rcved, rcved_len); return; } if (data_len <= 0) { purple_debug_warning("QQ", "Reply decrypted is empty, [%05d], 0x%04X %s, len %d\n", seq, cmd, qq_get_cmd_desc(cmd), rcved_len); return; } switch (cmd) { case QQ_CMD_UPDATE_INFO: qq_process_change_info(gc, data, data_len); break; case QQ_CMD_REMOVE_BUDDY: qq_process_remove_buddy(gc, data, data_len, ship_value); break; case QQ_CMD_REMOVE_ME: qq_process_buddy_remove_me(gc, data, data_len, ship_value); break; case QQ_CMD_GET_BUDDY_INFO: qq_process_get_buddy_info(data, data_len, ship_value, gc); break; case QQ_CMD_CHANGE_STATUS: qq_process_change_status(data, data_len, gc); break; case QQ_CMD_SEND_IM: do_im_ack(data, data_len, gc); break; case QQ_CMD_KEEP_ALIVE: if (qd->client_version >= 2010) { qq_process_keep_alive(data, data_len, gc); } break; case QQ_CMD_GET_BUDDIES_ONLINE: ret_8 = qq_process_get_buddies_online(data, data_len, gc); if (ret_8 > 0 && ret_8 < 0xff) { purple_debug_info("QQ", "Requesting for more online buddies\n"); qq_request_get_buddies_online(gc, ret_8, update_class); return; } purple_debug_info("QQ", "All online buddies received\n"); qq_update_buddies_status(gc); break; case QQ_CMD_GET_LEVEL: qq_process_get_level_reply(data, data_len, gc); if (ship_value) { purple_debug_info("QQ", "Requesting Buddy Level pos: %d\n", ship_value); qq_request_get_buddies_level(gc, 0, ship_value); } break; case QQ_CMD_GET_BUDDIES_SIGN: qq_process_get_buddies_sign(data, data_len, gc); if (ship_value) { purple_debug_info("QQ", "Requesting Buddy Signature pos: %d\n", ship_value); qq_request_get_buddies_sign(gc, 0, ship_value); } break; case QQ_CMD_GET_GROUP_LIST: ret_32 = qq_process_get_group_list(data, data_len, gc); /* if still have remained group name */ if (ret_32) { purple_debug_info("QQ", "Requesting for Group pos: %d\n", ret_32); qq_request_get_group_list(gc, ret_32, 0); not_to_update = TRUE; //not to update else when get_group not finished } break; case QQ_CMD_GET_BUDDIES_LIST: ret_16 = qq_process_get_buddies_list(data, data_len, gc); if (ret_16 > 0 && ret_16 < 0xffff) { purple_debug_info("QQ", "Requesting for more buddies\n"); qq_request_get_buddies_list(gc, ret_16, update_class); return; } purple_debug_info("QQ", "All buddies received. Requesting buddies' levels\n"); break; case QQ_CMD_SEARCH_UID: qq_process_search_uid(gc, data, data_len, ship_value); break; case QQ_CMD_AUTH_TOKEN: qq_process_auth_token(gc, data, data_len, update_class, ship_value); break; case QQ_CMD_BUDDY_QUESTION: qq_process_question(gc, data, data_len, ship_value); break; case QQ_CMD_ADD_BUDDY_TOUCH: qq_process_add_buddy_touch(gc, data, data_len, ship_value); break; case QQ_CMD_ADD_BUDDY_POST: qq_process_add_buddy_post(gc, data, data_len, ship_value); break; /*case QQ_CMD_BUDDY_CHECK_CODE: qq_process_buddy_check_code(gc, data, data_len); break;*/ case QQ_CMD_BUDDY_MEMO: purple_debug_info("QQ", "Receive memo from server!\n"); qq_process_get_buddy_memo(gc, data, data_len, update_class, ship_value); break; default: process_unknown_cmd(gc, _("Unknown CLIENT CMD"), data, data_len, cmd, seq); not_to_update = TRUE; break; } if (not_to_update) return; if (update_class == QQ_CMD_CLASS_NONE) return; purple_debug_info("QQ", "Update class %d\n", update_class); if (update_class == QQ_CMD_CLASS_UPDATE_ALL) { qq_update_all(gc, cmd); return; } if (update_class == QQ_CMD_CLASS_UPDATE_ONLINE) { qq_update_online(gc, cmd); return; } }
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; }