/* remove a buddy and send packet to QQ server accordingly */ void qq_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) { qq_data *qd; qq_buddy_data *bd; guint32 uid; g_return_if_fail(gc != NULL && gc->proto_data != NULL); g_return_if_fail(buddy != NULL); qd = (qq_data *) gc->proto_data; if (!qd->is_login) return; uid = purple_name_to_uid(purple_buddy_get_name(buddy)); if (uid > 0 && uid != qd->uid) { if (qd->client_version > 2005) { qq_request_auth_code(gc, QQ_AUTH_INFO_BUDDY, QQ_AUTH_INFO_REMOVE_BUDDY, uid); } else { request_remove_buddy(gc, uid); request_buddy_remove_me(gc, uid); } } if ((bd = purple_buddy_get_protocol_data(buddy)) != NULL) { qq_buddy_data_free(bd); purple_buddy_set_protocol_data(buddy, NULL); } else { purple_debug_warning("QQ", "Empty buddy data of %s\n", purple_buddy_get_name(buddy)); } /* Do not call purple_blist_remove_buddy, * otherwise purple segmentation fault */ }
/* who is the nickname of buddy in QQ chat-room (Qun) */ static void qq_get_chat_buddy_info(PurpleConnection *gc, gint channel, const gchar *who) { qq_data *qd; gchar *uid_str; guint32 uid; purple_debug_info("QQ", "Get chat buddy info of %s\n", who); g_return_if_fail(who != NULL); uid_str = chat_name_to_purple_name(who); if (uid_str == NULL) { return; } qd = gc->proto_data; uid = purple_name_to_uid(uid_str); g_free(uid_str); if (uid <= 0) { purple_debug_error("QQ", "Not valid chat name: %s\n", who); purple_notify_error(gc, NULL, _("Invalid name"), NULL); return; } qq_request_get_buddy_info(gc, uid, 0, QQ_BUDDY_INFO_DISPLAY); }
/* add a buddy and send packet to QQ server * note that when purple load local cached buddy list into its blist * it also calls this funtion, so we have to * define qd->is_login=TRUE AFTER LOGIN */ void qq_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) { qq_data *qd; guint32 uid; g_return_if_fail(NULL != gc && NULL != gc->proto_data); g_return_if_fail(buddy != NULL); qd = (qq_data *) gc->proto_data; if (!qd->is_login) return; /* IMPORTANT ! */ uid = purple_name_to_uid(purple_buddy_get_name(buddy)); if (uid > 0) { if (qd->client_version > 2005) { request_add_buddy_no_auth_ex(gc, uid); } else { request_add_buddy_no_auth(gc, uid); } return; } purple_notify_error(gc, _("QQ Buddy"), _("Add buddy"), _("Invalid QQ Number")); if (buddy == NULL) { return; } purple_debug_info("QQ", "Remove buddy with invalid QQ number %u\n", uid); qq_buddy_free(buddy); }
/* remove a buddy and send packet to QQ server accordingly */ void qq_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) { qq_data *qd; qq_buddy_data *bd; qq_buddy_opt_req *opt_req; g_return_if_fail(gc != NULL && gc->proto_data != NULL); g_return_if_fail(buddy != NULL); qd = (qq_data *) gc->proto_data; if (!qd->is_login) return; /* free it in qq_request_remove_buddy */ opt_req = g_new0(qq_buddy_opt_req, 1); opt_req->gc = gc; opt_req->uid = purple_name_to_uid(purple_buddy_get_name(buddy)); if (opt_req->uid > 0 && opt_req->uid != qd->uid) { qq_request_auth_token(gc, QQ_AUTH_INFO_BUDDY, QQ_AUTH_INFO_REMOVE_BUDDY, 0, opt_req); } if ((bd = purple_buddy_get_protocol_data(buddy)) != NULL) { qq_buddy_data_free(bd); purple_buddy_set_protocol_data(buddy, NULL); } else { purple_debug_warning("QQ", "Empty buddy data of %s\n", purple_buddy_get_name(buddy)); } }
/* add a buddy and send packet to QQ server * note that when purple load local cached buddy list into its blist * it also calls this funtion, so we have to * define qd->is_login=TRUE AFTER LOGIN */ void qq_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) { qq_data *qd; gchar * group_name; qq_buddy_opt_req *opt_req; g_return_if_fail(NULL != gc && NULL != gc->proto_data); g_return_if_fail(buddy != NULL); qd = (qq_data *) gc->proto_data; if (!qd->is_login) return; /* IMPORTANT ! */ if (purple_buddy_get_protocol_data(buddy)) { purple_notify_error(gc, _("QQ Buddy"), _("Add buddy"), _("Buddy exists")); return; } /* free it in qq_request_add_buddy_touch */ opt_req = g_new0(qq_buddy_opt_req, 1); opt_req->gc = gc; opt_req->uid = purple_name_to_uid(purple_buddy_get_name(buddy)); if (group) { group_name = purple_group_get_name(group); if (!group_name) { purple_notify_error(gc, _("QQ Buddy"), _("Add buddy"), _("Group not exists")); goto free; } opt_req->group_id = group_name_to_id(gc, group_name); if (opt_req->group_id == 0xFF) { purple_notify_error(gc, _("QQ Buddy"), _("Add buddy"), _("Chosen Group not associated with this account")); goto free; } } else opt_req->group_id = 0; if (opt_req->uid > 0) { qq_request_add_buddy_touch(gc, opt_req); return; } purple_notify_error(gc, _("QQ Buddy"), _("Add buddy"), _("Invalid QQ Number")); free: if (buddy == NULL) return; qq_buddy_free(buddy); }
/* send packet to get who's detailed information */ static void qq_show_buddy_info(PurpleConnection *gc, const gchar *who) { guint32 uid; qq_data *qd; qd = gc->proto_data; uid = purple_name_to_uid(who); if (uid <= 0) { purple_debug_error("QQ", "Not valid QQid: %s\n", who); purple_notify_error(gc, NULL, _("Invalid name"), NULL); return; } qq_request_get_level(gc, uid); qq_request_get_buddy_info(gc, uid, 0, QQ_BUDDY_INFO_DISPLAY); }
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); }
gint qq_send_im(PurpleConnection *gc, const gchar *who, const gchar *what, PurpleMessageFlags flags) { qq_data *qd; guint32 uid_to; gint type; qq_im_format *fmt; gchar *msg_stripped, *tmp; GSList *segments, *it; gint msg_len; const gchar *start_invalid; gboolean is_smiley_none; guint8 frag_count, frag_index; guint8 msg_id; g_return_val_if_fail(NULL != gc && NULL != gc->proto_data, -1); g_return_val_if_fail(who != NULL && what != NULL, -1); qd = (qq_data *) gc->proto_data; purple_debug_info("QQ", "Send IM to %s, len %" G_GSIZE_FORMAT ":\n%s\n", who, strlen(what), what); uid_to = purple_name_to_uid(who); if (uid_to == qd->uid) { /* if msg is to myself, bypass the network */ serv_got_im(gc, who, what, flags, time(NULL)); return 1; } type = (flags == PURPLE_MESSAGE_AUTO_RESP ? QQ_IM_AUTO_REPLY : QQ_IM_TEXT); /* qq_show_packet("IM UTF8", (guint8 *)what, strlen(what)); */ msg_stripped = purple_markup_strip_html(what); g_return_val_if_fail(msg_stripped != NULL, -1); /* qq_show_packet("IM Stripped", (guint8 *)what, strlen(what)); */ /* Check and valid utf8 string */ msg_len = strlen(msg_stripped); g_return_val_if_fail(msg_len > 0, -1); if (!g_utf8_validate(msg_stripped, msg_len, &start_invalid)) { if (start_invalid > msg_stripped) { tmp = g_strndup(msg_stripped, start_invalid - msg_stripped); g_free(msg_stripped); msg_stripped = g_strconcat(tmp, _("(Invalid UTF-8 string)"), NULL); g_free(tmp); } else { g_free(msg_stripped); msg_stripped = g_strdup(_("(Invalid UTF-8 string)")); } } is_smiley_none = qq_im_smiley_none(what); segments = qq_im_get_segments(msg_stripped, is_smiley_none); g_free(msg_stripped); if (segments == NULL) { return -1; } qd->send_im_id++; msg_id = (guint8)(qd->send_im_id && 0xFF); fmt = qq_im_fmt_new_by_purple(what); frag_count = g_slist_length(segments); frag_index = 0; for (it = segments; it; it = it->next) { /* request_send_im(gc, uid_to, type, fmt, (gchar *)it->data, msg_id, frag_count, frag_index); */ request_send_im(gc, uid_to, type, fmt, (gchar *)it->data, 0, 0, 0); g_free(it->data); frag_index++; } g_slist_free(segments); qq_im_fmt_free(fmt); return 1; }