PurpleBuddy * qq_buddy_find_or_new( PurpleConnection *gc, guint32 uid, guint8 group_id) { PurpleBuddy *buddy; qq_buddy_data *bd; qq_data *qd; GSList *l; qq_group * g; PurpleGroup * old_group; g_return_val_if_fail(gc->account != NULL && uid != 0, NULL); qd = (qq_data *)gc->proto_data; buddy = qq_buddy_find(gc, uid); /* group_id==0xFF only when add an unknown stranger */ if (group_id==0xFF) { if (buddy) goto buddy_data_check; else group_id=0; //add stranger to group 0 } /* find input group_id */ for (l=qd->group_list; l; l=l->next) { if (((qq_group *)(l->data))->group_id == group_id) break; } /* if group_id found */ if (l) { if (buddy) //if buddy already exist, we need check if he is in new group { old_group = purple_buddy_get_group(buddy); g = (qq_group *)l->data; if (old_group != purple_find_group(g->group_name)) { qq_buddy_free(buddy); } else goto buddy_data_check; } old_group = purple_find_group(((qq_group *)(l->data))->group_name); buddy = qq_buddy_new(gc, uid, old_group); } else { if (group_id==0) { if (!buddy) buddy = qq_buddy_new(gc, uid, NULL); goto buddy_data_check; } purple_debug_error("QQ","cannot find group id: %u", group_id); return NULL; } buddy_data_check: if (purple_buddy_get_protocol_data(buddy) != NULL) return buddy; bd = qq_buddy_data_new(uid); purple_buddy_set_protocol_data(buddy, bd); return buddy; }
/* * QQInfo */ QQInfo* qq_info_new() { QQInfo *info = g_slice_new0(QQInfo); info -> need_vcimage = FALSE; info -> me = qq_buddy_new(); info -> buddies = g_ptr_array_new(); info -> groups = g_ptr_array_new(); info -> recentcons = g_ptr_array_new(); info -> categories = g_ptr_array_new(); info -> buddies_ht = g_hash_table_new(g_str_hash, g_str_equal); info -> buddies_number_ht = g_hash_table_new(g_str_hash, g_str_equal); info -> groups_ht = g_hash_table_new(g_str_hash, g_str_equal); info -> groups_number_ht = g_hash_table_new(g_str_hash, g_str_equal); info -> lock = g_mutex_new(); info -> clientid = g_string_new(""); info -> psessionid = g_string_new(""); GTimeVal now; g_get_current_time(&now); glong v = now.tv_usec; v = (v - v % 1000) / 1000; v = v % 10000 * 10000; info -> msg_id = v; return info; }
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); }
PurpleBuddy *qq_buddy_find_or_new(PurpleConnection *gc, guint32 uid) { PurpleBuddy *buddy; g_return_val_if_fail(gc->account != NULL && uid != 0, NULL); buddy = qq_buddy_find(gc, uid); if (buddy == NULL) { buddy = qq_buddy_new(gc, uid); if (buddy == NULL) { return NULL; } } if (buddy->proto_data != NULL) { return buddy; } buddy->proto_data = qq_buddy_data_new(uid); return buddy; }
PurpleBuddy *qq_buddy_find_or_new(PurpleConnection *gc, guint32 uid) { PurpleBuddy *buddy; qq_buddy_data *bd; g_return_val_if_fail(gc->account != NULL && uid != 0, NULL); buddy = qq_buddy_find(gc, uid); if (buddy == NULL) { buddy = qq_buddy_new(gc, uid); if (buddy == NULL) { return NULL; } } if (purple_buddy_get_protocol_data(buddy) != NULL) { return buddy; } bd = qq_buddy_data_new(uid); purple_buddy_set_protocol_data(buddy, bd); return buddy; }
gint db_get_buddy(sqlite3 *db, const gchar *owner, QQBuddy *bdy, gint *cnt) { if(db == NULL || owner == NULL || bdy == NULL){ return SQLITE_ERROR; } GString *sql = g_string_sized_new(500); g_string_append(sql, "select " "vip_info, nick, markname," "country, province, city, gender," "face, flag," "blood, shengxiao, constel, phone, mobile, email," "occupation, college, homepage, personal, lnick, " "birthday_y, birthday_m, birthday_d " "from buddies where owner="); g_string_append_printf(sql, "'%s' and qqnumber='%s';" , owner, bdy -> qqnumber -> str); sqlite3_stmt *stmt = NULL; if(sqlite3_prepare_v2(db, sql -> str, 500, &stmt, NULL) != SQLITE_OK){ g_warning("prepare sql error. SQL(%s) (%s, %d)", sql -> str , __FILE__, __LINE__); g_string_free(sql, TRUE); return SQLITE_ERROR; } g_string_free(sql, TRUE); gint retcode = SQLITE_OK; gint idx, y, m, d; gint num = 0; while(TRUE){ retcode = sqlite3_step(stmt); switch(retcode) { case SQLITE_ROW: bdy = qq_buddy_new(); idx = -1; qq_buddy_set(bdy, "vip_info", sqlite3_column_int(stmt, ++idx)); qq_buddy_set(bdy, "nick", (const gchar *)sqlite3_column_text(stmt, ++idx)); qq_buddy_set(bdy, "markname", (const gchar *)sqlite3_column_text(stmt, ++idx)); qq_buddy_set(bdy, "country", (const gchar *)sqlite3_column_text(stmt, ++idx)); qq_buddy_set(bdy, "province", (const gchar *)sqlite3_column_text(stmt, ++idx)); qq_buddy_set(bdy, "city", (const gchar *)sqlite3_column_text(stmt, ++idx)); qq_buddy_set(bdy, "gender", (const gchar *)sqlite3_column_text(stmt, ++idx)); qq_buddy_set(bdy, "face", (const gchar *)sqlite3_column_text(stmt, ++idx)); qq_buddy_set(bdy, "flag", (const gchar *)sqlite3_column_text(stmt, ++idx)); qq_buddy_set(bdy, "blood", sqlite3_column_int(stmt, ++idx)); qq_buddy_set(bdy, "shengxiao", sqlite3_column_int(stmt, ++idx)); qq_buddy_set(bdy, "constel", sqlite3_column_int(stmt, ++idx)); qq_buddy_set(bdy, "phone", (const gchar *)sqlite3_column_text(stmt, ++idx)); qq_buddy_set(bdy, "mobile", (const gchar *)sqlite3_column_text(stmt,++idx)); qq_buddy_set(bdy, "email", (const gchar *)sqlite3_column_text(stmt, ++idx)); qq_buddy_set(bdy, "occupation", (const gchar *)sqlite3_column_text(stmt, ++idx)); qq_buddy_set(bdy, "college", (const gchar *)sqlite3_column_text(stmt, ++idx)); qq_buddy_set(bdy, "homepage", (const gchar *)sqlite3_column_text(stmt, ++idx)); qq_buddy_set(bdy, "personal", (const gchar *)sqlite3_column_text(stmt, ++idx)); qq_buddy_set(bdy, "lnick", (const gchar *)sqlite3_column_text(stmt, ++idx)); y = sqlite3_column_int(stmt, ++idx); m = sqlite3_column_int(stmt, ++idx); d = sqlite3_column_int(stmt, ++idx); qq_buddy_set(bdy, "birthday", y, m, d); ++num; break; case SQLITE_DONE: retcode = SQLITE_OK; goto out_label; break; default: g_warning("sqlite3_step error!(%s, %d)", __FILE__, __LINE__); goto out_label; break; } } out_label: if(cnt != NULL){ *cnt = num; } sqlite3_finalize(stmt); return retcode; }
/* process received extended (2007) text IM */ static void process_extend_im_text(PurpleConnection *gc, guint8 *data, gint len, qq_im_header *im_header) { qq_data *qd; guint16 purple_msg_type; gchar *who; gchar *msg_smiley, *msg_fmt, *msg_utf8; PurpleBuddy *buddy; qq_buddy_data *bd; gint bytes, tail_len; qq_im_format *fmt = NULL; struct { /* now comes the part for text only */ guint16 msg_seq; guint32 send_time; guint16 sender_icon; guint32 has_font_attr; guint8 unknown1[8]; guint8 fragment_count; guint8 fragment_index; guint8 msg_id; guint8 unknown2; guint8 msg_type; gchar *msg; /* no fixed length, ends with 0x00 */ guint8 fromMobileQQ; } im_text; g_return_if_fail (data != NULL && len > 0); g_return_if_fail(im_header != NULL); qd = (qq_data *) gc->proto_data; memset(&im_text, 0, sizeof(im_text)); /* qq_show_packet("Extend IM text", data, len); */ bytes = 0; bytes += qq_get16(&(im_text.msg_seq), data + bytes); bytes += qq_get32(&(im_text.send_time), data + bytes); bytes += qq_get16(&(im_text.sender_icon), data + bytes); bytes += qq_get32(&(im_text.has_font_attr), data + bytes); bytes += qq_getdata(im_text.unknown1, sizeof(im_text.unknown1), data + bytes); bytes += qq_get8(&(im_text.fragment_count), data + bytes); bytes += qq_get8(&(im_text.fragment_index), data + bytes); bytes += qq_get8(&(im_text.msg_id), data + bytes); bytes += 1; /* skip 0x00 */ bytes += qq_get8(&(im_text.msg_type), data + bytes); purple_debug_info("QQ", "IM Seq %u, id %04X, fragment %d-%d, type %d, %s\n", im_text.msg_seq, im_text.msg_id, im_text.fragment_count, im_text.fragment_index, im_text.msg_type, im_text.has_font_attr ? "exist font atrr" : ""); if (im_text.has_font_attr) { fmt = qq_im_fmt_new(); tail_len = qq_get_im_tail(fmt, data + bytes, len - bytes); im_text.msg = g_strndup((gchar *)(data + bytes), len - tail_len); } else { im_text.msg = g_strndup((gchar *)(data + bytes), len - bytes); } /* qq_show_packet("IM text", (guint8 *)im_text.msg , strlen(im_text.msg)); */ if(im_text.fragment_count == 0) im_text.fragment_count = 1; who = uid_to_purple_name(im_header->uid_from); buddy = purple_find_buddy(gc->account, who); if (buddy == NULL) { /* create no-auth buddy */ buddy = qq_buddy_new(gc, im_header->uid_from); } bd = (buddy == NULL) ? NULL : purple_buddy_get_protocol_data(buddy); if (bd != NULL) { bd->client_tag = im_header->version_from; bd->face = im_text.sender_icon; qq_update_buddy_icon(gc->account, who, bd->face); } purple_msg_type = 0; msg_smiley = qq_emoticon_to_purple(im_text.msg); if (fmt != NULL) { msg_fmt = qq_im_fmt_to_purple(fmt, msg_smiley); msg_utf8 = qq_to_utf8(msg_fmt, QQ_CHARSET_DEFAULT); g_free(msg_fmt); qq_im_fmt_free(fmt); } else { msg_utf8 = qq_to_utf8(msg_smiley, QQ_CHARSET_DEFAULT); } g_free(msg_smiley); /* send encoded to purple, note that we use im_text.send_time, * not the time we receive the message * as it may have been delayed when I am not online. */ serv_got_im(gc, who, msg_utf8, purple_msg_type, (time_t) im_text.send_time); g_free(msg_utf8); g_free(who); g_free(im_text.msg); }