Mercurial > pidgin
changeset 24161:7c0a56c5fea0
2008.10.14 - ccpaging <ccpaging(at)gmail.com>
* 2007 remove buddy ok
* Removed group_search.c/h
author | SHiNE CsyFeK <csyfek@gmail.com> |
---|---|
date | Tue, 28 Oct 2008 16:44:09 +0000 |
parents | d35672443baa |
children | f4f29fac96c6 |
files | libpurple/protocols/qq/ChangeLog libpurple/protocols/qq/buddy_info.c libpurple/protocols/qq/buddy_opt.c libpurple/protocols/qq/buddy_opt.h libpurple/protocols/qq/char_conv.c libpurple/protocols/qq/group_im.c libpurple/protocols/qq/group_join.c libpurple/protocols/qq/group_opt.c libpurple/protocols/qq/group_search.c libpurple/protocols/qq/group_search.h libpurple/protocols/qq/qq.c libpurple/protocols/qq/qq_base.c libpurple/protocols/qq/qq_base.h libpurple/protocols/qq/qq_define.c libpurple/protocols/qq/qq_define.h libpurple/protocols/qq/qq_process.c libpurple/protocols/qq/utils.c |
diffstat | 17 files changed, 421 insertions(+), 423 deletions(-) [+] |
line wrap: on
line diff
--- a/libpurple/protocols/qq/ChangeLog Tue Oct 28 16:42:46 2008 +0000 +++ b/libpurple/protocols/qq/ChangeLog Tue Oct 28 16:44:09 2008 +0000 @@ -1,3 +1,7 @@ +2008.10.14 - ccpaging <ccpaging(at)gmail.com> + * 2007 remove buddy ok + * Removed group_search.c/h + 2008.10.10 - ccpaging <ccpaging(at)gmail.com> * Support part of 'buddy' protocol of QQ2007/2008
--- a/libpurple/protocols/qq/buddy_info.c Tue Oct 28 16:42:46 2008 +0000 +++ b/libpurple/protocols/qq/buddy_info.c Tue Oct 28 16:44:09 2008 +0000 @@ -157,6 +157,7 @@ #ifdef DEBUG static void info_debug(gchar **segments) { +#if 0 int index; gchar *utf8_str; for (index = 0; segments[index] != NULL && index < QQ_INFO_LAST; index++) { @@ -171,6 +172,7 @@ } purple_debug_info("QQ_BUDDY_INFO", "%s: %s\n", field_infos[index].text, segments[index]); } +#endif } #endif @@ -454,8 +456,8 @@ data[data_len] = '\0'; if (qd->uid != atoi((gchar *) data)) { /* return should be my uid */ - purple_debug_info("QQ", "Update info ACK OK\n"); - qq_got_attention(gc, _("Successed changing buddy information.")); + purple_debug_info("QQ", "Failed Updating info\n"); + qq_got_attention(gc, _("Failed changing buddy information.")); } } @@ -551,7 +553,7 @@ if (face < 1 || face > QQ_FACES) { icon = 1; } - + icon_name = g_strdup_printf("%s%d%s", QQ_ICON_PREFIX, icon, QQ_ICON_SUFFIX); return icon_name; } @@ -591,7 +593,7 @@ gsize icon_file_size; g_return_if_fail(account != NULL && who != NULL); - + purple_debug_info("QQ", "Update %s icon to %d\n", who, face); icon_name = qq_get_icon_name(face);
--- a/libpurple/protocols/qq/buddy_opt.c Tue Oct 28 16:42:46 2008 +0000 +++ b/libpurple/protocols/qq/buddy_opt.c Tue Oct 28 16:44:09 2008 +0000 @@ -42,7 +42,6 @@ #define PURPLE_GROUP_QQ_FORMAT "QQ (%s)" #define QQ_REMOVE_SELF_REPLY_OK 0x00 -#define QQ_ADD_BUDDY_AUTH_REPLY_OK 0x30 /* ASCII value of "0" */ enum { QQ_MY_AUTH_APPROVE = 0x30, /* ASCII value of "0" */ @@ -202,6 +201,82 @@ qq_send_cmd_mess(gc, QQ_CMD_BUDDY_REMOVE, (guint8 *) uid_str, bytes, 0, uid); } +static void request_buddy_remove_2007(PurpleConnection *gc, + guint32 uid, guint8 *auth, guint8 auth_len) +{ + gint bytes; + guint8 *raw_data; + gchar uid_str[16]; + + g_return_if_fail(uid != 0); + g_return_if_fail(auth != NULL && auth_len > 0); + + raw_data = g_newa(guint8, auth_len + sizeof(uid_str) ); + bytes = 0; + bytes += qq_put8(raw_data + bytes, auth_len); + bytes += qq_putdata(raw_data + bytes, auth, auth_len); + + g_snprintf(uid_str, sizeof(uid_str), "%d", uid); + bytes += qq_putdata(raw_data + bytes, (guint8 *)uid_str, strlen(uid_str)); + + qq_send_cmd_mess(gc, QQ_CMD_BUDDY_REMOVE, raw_data, bytes, 0, uid); +} + +void qq_request_auth_info(PurpleConnection *gc, guint8 cmd, guint16 sub_cmd, guint32 uid) +{ + guint8 raw_data[16]; + gint bytes; + + g_return_if_fail(uid > 0); + bytes = 0; + bytes += qq_put8(raw_data + bytes, cmd); + bytes += qq_put16(raw_data + bytes, sub_cmd); + bytes += qq_put32(raw_data + bytes, uid); + + qq_send_cmd_mess(gc, QQ_CMD_AUTH_INFO, raw_data, bytes, 0, uid); +} + +void qq_process_auth_info(PurpleConnection *gc, guint8 *data, gint data_len, guint32 uid) +{ + qq_data *qd; + gint bytes; + guint8 cmd, reply; + guint16 sub_cmd; + guint8 *auth = NULL; + guint8 auth_len = 0; + + g_return_if_fail(data != NULL && data_len != 0); + g_return_if_fail(uid != 0); + + qd = (qq_data *) gc->proto_data; + + qq_show_packet("qq_process_auth_info", 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 (bytes + 2 <= data_len) { + bytes += 1; /* skip 1 byte, 0x00 */ + bytes += qq_get8(&auth_len, data + bytes); + if (auth_len > 0) { + g_return_if_fail(bytes + auth_len <= data_len); + auth = g_newa(guint8, auth_len); + bytes += qq_getdata(auth, auth_len, data + bytes); + } + } else { + qq_show_packet("No auth info", data, data_len); + } + + if (cmd == QQ_AUTH_INFO_BUDDY && sub_cmd == QQ_AUTH_INFO_REMOVE_BUDDY) { + g_return_if_fail(auth != NULL && auth_len > 0); + request_buddy_remove_2007(gc, uid, auth, auth_len); + } + if (cmd == QQ_AUTH_INFO_BUDDY && sub_cmd == QQ_AUTH_INFO_ADD_BUDDY) { + } + purple_debug_info("QQ", "Got auth info cmd 0x%x, sub 0x%x, reply 0x%x\n", + cmd, sub_cmd, reply); +} + /* try to remove myself from someone's buddy list */ static void request_buddy_remove_me(PurpleConnection *gc, guint32 uid) { @@ -280,11 +355,18 @@ g_free(add_req); } -/* we approve other's request of adding me as friend */ -static void buddy_add_authorize_cb(qq_buddy_req *add_req) +static void buddy_add_deny_noreason_cb(qq_buddy_req *add_req) { + buddy_add_deny_reason_cb(add_req, NULL); +} + +/* we approve other's request of adding me as friend */ +static void buddy_add_authorize_cb(gpointer data) +{ + qq_buddy_req *add_req = (qq_buddy_req *)data; + g_return_if_fail(add_req != NULL); - if (add_req->gc == NULL || add_req->uid != 0) { + if (add_req->gc == NULL || add_req->uid == 0) { g_free(add_req); return; } @@ -294,61 +376,17 @@ } /* we reject other's request of adding me as friend */ -static void buddy_add_deny_cb(qq_buddy_req *add_req) +static void buddy_add_deny_cb(gpointer data) { - gint uid; - gchar *msg1, *msg2; - PurpleConnection *gc; - gchar *purple_name; - - g_return_if_fail(add_req != NULL); - if (add_req->gc == NULL || add_req->uid == 0) { - g_free(add_req); - return; - } - - gc = add_req->gc; - uid = add_req->uid; - - msg1 = g_strdup_printf(_("You rejected %d's request"), uid); - msg2 = g_strdup(_("Message:")); - - purple_name = uid_to_purple_name(uid); - purple_request_input(gc, _("Reject request"), msg1, msg2, - _("Sorry, you are not my style..."), TRUE, FALSE, - NULL, _("Reject"), G_CALLBACK(buddy_add_deny_reason_cb), _("Cancel"), NULL, - purple_connection_get_account(gc), purple_name, NULL, + qq_buddy_req *add_req = (qq_buddy_req *)data; + gchar *who = uid_to_purple_name(add_req->uid); + purple_request_input(add_req->gc, NULL, _("Authorization denied message:"), + NULL, _("Sorry, You are not my style."), TRUE, FALSE, NULL, + _("OK"), G_CALLBACK(buddy_add_deny_reason_cb), + _("Cancel"), G_CALLBACK(buddy_add_deny_noreason_cb), + purple_connection_get_account(add_req->gc), who, NULL, add_req); - g_free(purple_name); -} - -/* suggested by rakescar@linuxsir, can still approve after search */ -static void buddy_add_check_info_cb(qq_buddy_req *add_req) -{ - PurpleConnection *gc; - guint32 uid; - gchar *purple_name; - - g_return_if_fail(add_req != NULL); - if (add_req->gc == NULL || add_req->uid == 0) { - g_free(add_req); - return; - } - - gc = add_req->gc; - uid = add_req->uid; - - qq_request_buddy_info(gc, uid, 0, QQ_BUDDY_INFO_DISPLAY); - - purple_name = uid_to_purple_name(uid); - purple_request_action - (gc, NULL, _("Do you approve the requestion?"), "", - PURPLE_DEFAULT_ACTION_NONE, - purple_connection_get_account(gc), purple_name, NULL, - add_req, 2, - _("Reject"), G_CALLBACK(buddy_add_deny_cb), - _("Approve"), G_CALLBACK(buddy_add_authorize_cb)); - g_free(purple_name); + g_free(who); } /* add a buddy and send packet to QQ server @@ -410,17 +448,18 @@ qd = (qq_data *) gc->proto_data; - if (data[0] != QQ_ADD_BUDDY_AUTH_REPLY_OK) { - if (NULL == (segments = split_data(data, data_len, "\x1f", 2))) { - purple_notify_error(gc, _("QQ Buddy"), _("Failed sending authorize"), NULL); - return; - } - msg_utf8 = qq_to_utf8(segments[1], QQ_CHARSET_DEFAULT); - purple_notify_error(gc, _("QQ Buddy"), _("Failed sending authorize"), msg_utf8); - g_free(msg_utf8); - } else { - qq_got_attention(gc, _("Successed sending authorize")); + if (data[0] == '0') { + purple_debug_info("QQ", "Reply OK for sending authorize\n"); + return; } + + if (NULL == (segments = split_data(data, data_len, "\x1f", 2))) { + purple_notify_error(gc, _("QQ Buddy"), _("Failed sending authorize"), NULL); + return; + } + msg_utf8 = qq_to_utf8(segments[1], QQ_CHARSET_DEFAULT); + purple_notify_error(gc, _("QQ Buddy"), _("Failed sending authorize"), msg_utf8); + g_free(msg_utf8); } /* process the server reply for my request to remove a buddy */ @@ -436,19 +475,14 @@ if (data[0] != 0) { msg = g_strdup_printf(_("Failed removing buddy %d"), uid); purple_notify_info(gc, _("QQ Buddy"), msg, NULL); - if (buddy == NULL) { - /* Add buddy with no-auth */ - qq_buddy_new(gc, uid); - } - } else { - msg = g_strdup_printf(_("Successed removing buddy %d"), uid); - qq_got_attention(gc, _("Successed removing budy.")); - if (buddy != NULL) { - /* remove buddy again */ - qq_buddy_free(buddy); - } + g_free(msg); } - g_free(msg); + + purple_debug_info("QQ", "Reply OK for removing buddy\n"); + /* remove buddy again */ + if (buddy != NULL) { + qq_buddy_free(buddy); + } } /* process the server reply for my request to remove myself from a buddy */ @@ -460,13 +494,12 @@ g_return_if_fail(data != NULL && data_len != 0); qd = (qq_data *) gc->proto_data; - if (data[0] != 0) { - msg = g_strdup_printf(_("Failed removing me from %d's buddy list"), uid); - purple_notify_info(gc, _("QQ Buddy"), msg, NULL); - } else { - msg = g_strdup_printf(_("Successed removing me from %d's buddy list"), uid); - qq_got_attention(gc, msg); + if (data[0] == 0) { + purple_debug_info("QQ", "Reply OK for removing me from %d's buddy list\n", uid); + return; } + msg = g_strdup_printf(_("Failed removing me from %d's buddy list"), uid); + purple_notify_info(gc, _("QQ Buddy"), msg, NULL); g_free(msg); } @@ -482,7 +515,7 @@ qd = (qq_data *) gc->proto_data; - if (uid == 0) { /* we have no record for this */ + if (uid == 0) { purple_debug_error("QQ", "Process buddy add, unknow id\n"); return; } @@ -512,9 +545,7 @@ } qq_request_get_buddies_online(gc, 0, 0); - msg = g_strdup_printf(_("Successed adding into %d's buddy list"), uid); - qq_got_attention(gc, msg); - g_free(msg); + purple_debug_info("QQ", "Successed adding into %d's buddy list", uid); g_strfreev(segments); return; } @@ -538,10 +569,10 @@ add_req->uid = uid; msg = g_strdup_printf(_("%d needs authentication"), uid); purple_request_input(gc, _("Add buddy authorize"), msg, - _("Input request here"), /* TODO: Awkward string to fix post string freeze - standardize auth dialogues? -evands */ + _("Input request here"), _("Would you be my friend?"), - TRUE, FALSE, NULL, _("Send"), - G_CALLBACK(request_buddy_add_auth_cb), + TRUE, FALSE, NULL, + _("Send"), G_CALLBACK(request_buddy_add_auth_cb), _("Cancel"), G_CALLBACK(buddy_cancel_cb), purple_connection_get_account(gc), who, NULL, add_req); @@ -565,9 +596,13 @@ return; uid = purple_name_to_uid(buddy->name); - if (uid > 0) { - request_buddy_remove(gc, uid); - request_buddy_remove_me(gc, uid); + if (uid > 0 && uid != qd->uid) { + if (qd->client_version > 2005) { + qq_request_auth_info(gc, QQ_AUTH_INFO_BUDDY, QQ_AUTH_INFO_REMOVE_BUDDY, uid); + } else { + request_buddy_remove(gc, uid); + request_buddy_remove_me(gc, uid); + } } if (buddy->proto_data) { @@ -582,99 +617,85 @@ } /* someone wants to add you to his buddy list */ -static void server_buddy_add_request(PurpleConnection *gc, gchar *from, gchar *to, gchar *msg_utf8) +static void server_buddy_add_request(PurpleConnection *gc, gchar *from, gchar *to, + guint8 *data, gint data_len) { - gchar *message, *reason; + PurpleAccount *account = purple_connection_get_account(gc); + qq_buddy_req *add_req; + gchar *who; + gchar *msg, *reason; + + g_return_if_fail(from != NULL && to != NULL); + + add_req = g_new0(qq_buddy_req, 1); + add_req->gc = gc; + add_req->uid = strtol(from, NULL, 10);; + + if (purple_prefs_get_bool("/plugins/prpl/qq/auto_get_authorize_info")) { + qq_request_buddy_info(gc, add_req->uid, 0, QQ_BUDDY_INFO_DISPLAY); + } + who = uid_to_purple_name(add_req->uid); + + if (data_len <= 0) { + reason = g_strdup( _("No reason given") ); + } else { + msg = g_strndup((gchar *)data, data_len); + reason = qq_to_utf8(msg, QQ_CHARSET_DEFAULT); + if (reason == NULL) reason = g_strdup( _("Unknown reason") ); + g_free(msg); + } + purple_account_request_authorization(account, + from, NULL, + NULL, reason, + purple_find_buddy(account, who) != NULL, + buddy_add_authorize_cb, + buddy_add_deny_cb, + add_req); + + g_free(reason); + g_free(who); +} + +/* when you are added by a person, QQ server will send sys message */ +static void server_buddy_added(PurpleConnection *gc, gchar *from, gchar *to, + guint8 *data, gint data_len) +{ + PurpleAccount *account = purple_connection_get_account(gc); + PurpleBuddy *buddy; guint32 uid; - qq_buddy_req *g, *g2; - PurpleBuddy *b; - gchar *name; + qq_buddy_req *add_req; + gchar *who; + gchar *primary; g_return_if_fail(from != NULL && to != NULL); uid = strtol(from, NULL, 10); - g = g_new0(qq_buddy_req, 1); - g->gc = gc; - g->uid = uid; - - name = uid_to_purple_name(uid); - - /* TODO: this should go through purple_account_request_authorization() */ - message = g_strdup_printf(_("%s wants to add you [%s] as a friend"), from, to); - reason = g_strdup_printf(_("Message: %s"), msg_utf8); + who = uid_to_purple_name(uid); - purple_request_action - (gc, NULL, message, reason, PURPLE_DEFAULT_ACTION_NONE, - purple_connection_get_account(gc), name, NULL, - g, 3, - _("Reject"), - G_CALLBACK(buddy_add_deny_cb), - _("Approve"), - G_CALLBACK(buddy_add_authorize_cb), - _("Search"), G_CALLBACK(buddy_add_check_info_cb)); - - g_free(message); - g_free(reason); - - /* XXX: Is this needed once the above goes through purple_account_request_authorization()? */ - b = purple_find_buddy(gc->account, name); - if (b == NULL) { /* the person is not in my list */ - g2 = g_new0(qq_buddy_req, 1); - g2->gc = gc; - g2->uid = strtol(from, NULL, 10); - message = g_strdup_printf(_("%s is not in buddy list"), from); - purple_request_action(gc, NULL, message, - _("Would you add?"), PURPLE_DEFAULT_ACTION_NONE, - purple_connection_get_account(gc), name, NULL, - g2, 3, - _("Cancel"), NULL, - _("Add"), G_CALLBACK(buddy_add_no_auth_cb), - _("Search"), G_CALLBACK(buddy_add_check_info_cb)); - g_free(message); + buddy = purple_find_buddy(account, who); + if (buddy != NULL) { + purple_account_notify_added(account, from, to, NULL, NULL); } - g_free(name); -} - -/* when you are added by a person, QQ server will send sys message */ -static void server_buddy_added(PurpleConnection *gc, gchar *from, gchar *to, gchar *msg_utf8) -{ - gchar *message; - PurpleBuddy *b; - guint32 uid; - qq_buddy_req *add_req; - gchar *name; - - g_return_if_fail(from != NULL && to != NULL); - - uid = strtol(from, NULL, 10); - name = uid_to_purple_name(uid); - b = purple_find_buddy(gc->account, name); + add_req = g_new0(qq_buddy_req, 1); + add_req->gc = gc; + add_req->uid = uid; /* only need to get value */ + primary = g_strdup_printf(_("You have been added by %s"), from); + purple_request_action(gc, NULL, primary, + _("Would you like to add him?"), + PURPLE_DEFAULT_ACTION_NONE, + purple_connection_get_account(gc), who, NULL, + add_req, 2, + _("Cancel"), G_CALLBACK(buddy_cancel_cb), + _("Add"), G_CALLBACK(buddy_add_no_auth_cb)); - if (b == NULL) { /* the person is not in my list */ - add_req = g_new0(qq_buddy_req, 1); - add_req->gc = gc; - add_req->uid = uid; /* only need to get value */ - message = g_strdup_printf(_("You have been added by %s"), from); - purple_request_action(gc, NULL, message, - _("Would you like to add him?"), - PURPLE_DEFAULT_ACTION_NONE, - purple_connection_get_account(gc), name, NULL, - add_req, 3, - _("Cancel"), G_CALLBACK(buddy_cancel_cb), - _("Add"), G_CALLBACK(buddy_add_no_auth_cb), - _("Search"), G_CALLBACK(buddy_add_check_info_cb)); - } else { - message = g_strdup_printf(_("Successed adding into %s's buddy list"), from); - qq_got_attention(gc, message); - } - - g_free(name); - g_free(message); + g_free(who); + g_free(primary); } /* the buddy approves your request of adding him/her as your friend */ -static void server_buddy_added_me(PurpleConnection *gc, gchar *from, gchar *to, gchar *msg_utf8) +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; @@ -696,28 +717,43 @@ qq_request_get_level(gc, uid); } - purple_account_notify_added(account, from, to, NULL, msg_utf8); + purple_account_notify_added(account, to, from, NULL, NULL); } /* you are rejected by the person */ -static void server_buddy_rejected_me(PurpleConnection *gc, gchar *from, gchar *to, gchar *msg_utf8) +static void server_buddy_rejected_me(PurpleConnection *gc, gchar *from, gchar *to, + guint8 *data, gint data_len) { - gchar *message, *reason; guint32 uid; PurpleBuddy *buddy; + gchar *msg, *msg_utf8; + gchar *primary, *secondary; g_return_if_fail(from != NULL && to != NULL); - message = g_strdup_printf(_("Requestion rejected by %s"), from); - reason = g_strdup_printf(_("Message: %s"), msg_utf8); + if (data_len <= 0) { + msg = g_strdup( _("No reason given") ); + } else { + msg = g_strndup((gchar *)data, data_len); + } + msg_utf8 = qq_to_utf8(msg, QQ_CHARSET_DEFAULT); + if (msg_utf8 == NULL) { + msg_utf8 = g_strdup( _("Unknown reason") ); + } + g_free(msg); - purple_notify_info(gc, _("QQ Buddy"), message, reason); - g_free(message); - g_free(reason); - + primary = g_strdup_printf(_("Rejected by %s"), from); + secondary = g_strdup_printf(_("Message: %s"), msg_utf8); + + purple_notify_info(gc, _("QQ Buddy"), primary, secondary); + + g_free(msg_utf8); + g_free(primary); + g_free(secondary); + uid = strtol(from, NULL, 10); g_return_if_fail(uid != 0); - + buddy = qq_buddy_find(gc, uid); if (buddy != NULL && buddy->proto_data != NULL) { /* Not authorized now, free buddy data */ @@ -727,20 +763,23 @@ } void qq_process_buddy_from_server(PurpleConnection *gc, int funct, - gchar *from, gchar *to, gchar *msg_utf8) + gchar *from, gchar *to, guint8 *data, gint data_len) { switch (funct) { case QQ_SERVER_BUDDY_ADDED: - server_buddy_added(gc, from, to, msg_utf8); + server_buddy_added(gc, from, to, data, data_len); break; case QQ_SERVER_BUDDY_ADD_REQUEST: - server_buddy_add_request(gc, from, to, msg_utf8); + server_buddy_add_request(gc, from, to, data, data_len); + break; + case QQ_MSG_SYS_ADD_FRIEND_REQUEST_EX: + // server_buddy_add_request_ex(gc, from, to, data, data_len); break; case QQ_SERVER_BUDDY_ADDED_ME: - server_buddy_added_me(gc, from, to, msg_utf8); + server_buddy_added_me(gc, from, to, data, data_len); break; case QQ_SERVER_BUDDY_REJECTED_ME: - server_buddy_rejected_me(gc, from, to, msg_utf8); + server_buddy_rejected_me(gc, from, to, data, data_len); break; default: purple_debug_warning("QQ", "Unknow buddy operate (%d) from server\n", funct);
--- a/libpurple/protocols/qq/buddy_opt.h Tue Oct 28 16:42:46 2008 +0000 +++ b/libpurple/protocols/qq/buddy_opt.h Tue Oct 28 16:44:09 2008 +0000 @@ -30,6 +30,17 @@ #include "qq.h" +enum { + QQ_AUTH_INFO_BUDDY = 0x01, + QQ_AUTH_INFO_ROOM = 0x02, + + QQ_AUTH_INFO_ADD_BUDDY = 0x0001, + QQ_AUTH_INFO_TEMP_SESSION = 0x0003, + QQ_AUTH_INFO_CLUSTER = 0x0002, + QQ_AUTH_INFO_REMOVE_BUDDY = 0x0006, + QQ_AUTH_INFO_UPDATE_BUDDY_INFO = 0x0007, +}; + void qq_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group); void qq_change_buddys_group(PurpleConnection *gc, const char *who, const char *old_group, const char *new_group); @@ -41,7 +52,10 @@ void qq_process_buddy_add_no_auth(guint8 *data, gint data_len, guint32 uid, PurpleConnection *gc); void qq_process_buddy_add_auth(guint8 *data, gint data_len, PurpleConnection *gc); void qq_process_buddy_from_server(PurpleConnection *gc, int funct, - gchar *from, gchar *to, gchar *msg_utf8); + gchar *from, gchar *to, guint8 *data, gint data_len); + +void qq_request_auth_info(PurpleConnection *gc, guint8 cmd, guint16 sub_cmd, guint32 uid); +void qq_process_auth_info(PurpleConnection *gc, guint8 *data, gint data_len, guint32 uid); qq_buddy_data *qq_buddy_data_find(PurpleConnection *gc, guint32 uid); void qq_buddy_data_free(qq_buddy_data *bd);
--- a/libpurple/protocols/qq/char_conv.c Tue Oct 28 16:42:46 2008 +0000 +++ b/libpurple/protocols/qq/char_conv.c Tue Oct 28 16:44:09 2008 +0000 @@ -37,7 +37,7 @@ #define QQ_CHARSET_ENG "ISO-8859-1" #define QQ_NULL_MSG "(NULL)" /* return this if conversion fails */ -#define QQ_NULL_SMILEY "(Broken)" /* return this if smiley conversion fails */ +#define QQ_NULL_SMILEY "<IMG ID=\"0\">" /* return this if smiley conversion fails */ const gchar qq_smiley_map[QQ_SMILEY_AMOUNT] = { 0x41, 0x43, 0x42, 0x44, 0x45, 0x46, 0x47, 0x48,
--- a/libpurple/protocols/qq/group_im.c Tue Oct 28 16:42:46 2008 +0000 +++ b/libpurple/protocols/qq/group_im.c Tue Oct 28 16:44:09 2008 +0000 @@ -213,7 +213,7 @@ rmd = qq_room_data_find(gc, room_id); g_return_if_fail(rmd != NULL); - if (conv == NULL && purple_prefs_get_bool("/plugins/prpl/qq/show_room_when_newin")) { + if (conv == NULL && purple_prefs_get_bool("/plugins/prpl/qq/auto_popup_conversation")) { conv = qq_room_conv_open(gc, rmd); }
--- a/libpurple/protocols/qq/group_join.c Tue Oct 28 16:42:46 2008 +0000 +++ b/libpurple/protocols/qq/group_join.c Tue Oct 28 16:44:09 2008 +0000 @@ -137,13 +137,13 @@ qq_room_req *add_req; g_return_if_fail(rmd != NULL); - purple_debug_info("QQ", "Group (internal id: %d) needs authentication\n", rmd->id); + purple_debug_info("QQ", "Room (internal id: %d) needs authentication\n", rmd->id); - msg = g_strdup_printf("Group \"%s\" needs authentication\n", rmd->title_utf8); + msg = g_strdup_printf("QQ Qun %d needs authentication\n", rmd->ext_id); add_req = g_new0(qq_room_req, 1); add_req->gc = gc; add_req->id = rmd->id; - purple_request_input(gc, NULL, msg, + purple_request_input(gc, _("Join QQ Qun"), msg, _("Input request here"), _("Would you be my friend?"), TRUE, FALSE, NULL, _("Send"),
--- a/libpurple/protocols/qq/group_opt.c Tue Oct 28 16:42:46 2008 +0000 +++ b/libpurple/protocols/qq/group_opt.c Tue Oct 28 16:44:09 2008 +0000 @@ -83,42 +83,12 @@ g_free(add_req); } -static void member_join_reject_send_cb(qq_room_req *add_req, gchar *msg_utf8) -{ - qq_room_data *rmd; - g_return_if_fail(add_req != NULL && add_req->gc != NULL && add_req->id > 0 && add_req->member > 0); - rmd = qq_room_data_find(add_req->gc, add_req->id); - g_return_if_fail(rmd != NULL); - qq_send_cmd_group_auth(add_req->gc, rmd, QQ_ROOM_AUTH_REQUEST_REJECT, add_req->member, msg_utf8); - g_free(add_req); -} - -static void member_join_reject_cb(qq_room_req *add_req) +static void member_join_authorize_cb(gpointer data) { - gchar *msg1, *msg2, *who; - g_return_if_fail(add_req != NULL && add_req->gc != NULL && add_req->member > 0); - - msg1 = g_strdup_printf(_("You rejected %d's request"), add_req->member); - msg2 = g_strdup(_("Message:")); - - who = uid_to_purple_name(add_req->member); - purple_request_input(add_req->gc, /* title */ NULL, msg1, msg2, - _("Sorry, you are not my style..."), /* multiline */ TRUE, /* masked */ FALSE, - /* hint */ NULL, - _("Send"), G_CALLBACK(member_join_reject_send_cb), - _("Cancel"), G_CALLBACK(room_req_cancel_cb), - purple_connection_get_account(add_req->gc), who, NULL, - add_req); - - g_free(msg1); - g_free(msg2); - g_free(who); -} - -static void member_join_authorize_cb(qq_room_req *add_req) -{ + qq_room_req *add_req = (qq_room_req *)data; qq_room_data *rmd; - g_return_if_fail(add_req != NULL && add_req->gc != NULL && add_req->id > 0 && add_req->member > 0); + g_return_if_fail(add_req != NULL && add_req->gc != NULL); + g_return_if_fail(add_req->id > 0 && add_req->member > 0); rmd = qq_room_data_find(add_req->gc, add_req->id); g_return_if_fail(rmd != NULL); @@ -127,17 +97,37 @@ g_free(add_req); } -static void member_join_search_cb(qq_room_req *add_req) +static void member_join_deny_reason_cb(qq_room_req *add_req, gchar *msg_utf8) { - g_return_if_fail(add_req != NULL && add_req->gc != NULL && add_req->member > 0); + qq_room_data *rmd; + g_return_if_fail(add_req != NULL && add_req->gc != NULL); + g_return_if_fail(add_req->id > 0 && add_req->member > 0); + rmd = qq_room_data_find(add_req->gc, add_req->id); + g_return_if_fail(rmd != NULL); + qq_send_cmd_group_auth(add_req->gc, rmd, QQ_ROOM_AUTH_REQUEST_REJECT, add_req->member, msg_utf8); + g_free(add_req); +} + +static void member_join_deny_noreason_cb(qq_room_req *add_req, gchar *msg_utf8) +{ + member_join_deny_reason_cb(add_req, NULL); +} - qq_request_buddy_info(add_req->gc, add_req->member, 0, QQ_BUDDY_INFO_DISPLAY); - purple_request_action(add_req->gc, NULL, _("Do you want to approve the request?"), "", - PURPLE_DEFAULT_ACTION_NONE, - purple_connection_get_account(add_req->gc), NULL, NULL, - add_req, 2, - _("Reject"), G_CALLBACK(member_join_reject_cb), - _("Approve"), G_CALLBACK(member_join_authorize_cb)); +static void member_join_deny_cb(gpointer data) +{ + qq_room_req *add_req = (qq_room_req *)data; + gchar *who; + g_return_if_fail(add_req != NULL && add_req->gc != NULL); + g_return_if_fail(add_req->id > 0 && add_req->member > 0); + + who = uid_to_purple_name(add_req->member); + purple_request_input(add_req->gc, NULL, _("Authorization denied message:"), + NULL, _("Sorry, you are not our style ..."), TRUE, FALSE, NULL, + _("OK"), G_CALLBACK(member_join_deny_reason_cb), + _("Cancel"), G_CALLBACK(member_join_deny_noreason_cb), + purple_connection_get_account(add_req->gc), who, NULL, + add_req); + g_free(who); } void qq_group_modify_members(PurpleConnection *gc, qq_room_data *rmd, guint32 *new_members) @@ -425,7 +415,7 @@ { guint32 ext_id, member_id; guint8 type8; - gchar *reason_utf8, *msg, *reason; + gchar *msg, *reason; qq_room_req *add_req; gchar *who; gint bytes = 0; @@ -442,7 +432,7 @@ g_return_if_fail(ext_id > 0 && member_id > 0); - bytes += qq_get_vstr(&reason_utf8, QQ_CHARSET_DEFAULT, data + bytes); + bytes += qq_get_vstr(&reason, QQ_CHARSET_DEFAULT, data + bytes); add_req = g_new0(qq_room_req, 1); add_req->gc = gc; @@ -456,35 +446,32 @@ if (qq_room_buddy_find(rmd, member_id)) { purple_debug_info("QQ", "Approve join, buddy joined before\n"); msg = g_strdup_printf(_("%d requested to join Qun %d for %s"), - member_id, ext_id, reason_utf8); + member_id, ext_id, reason); qq_room_got_chat_in(gc, id, 0, msg, now); qq_send_cmd_group_auth(gc, rmd, QQ_ROOM_AUTH_REQUEST_APPROVE, member_id, ""); g_free(msg); - g_free(reason_utf8); + g_free(reason); return; } + if (purple_prefs_get_bool("/plugins/prpl/qq/auto_get_authorize_info")) { + qq_request_buddy_info(gc, member_id, 0, QQ_BUDDY_INFO_DISPLAY); + } who = uid_to_purple_name(member_id); msg = g_strdup_printf(_("%d request to join Qun %d"), member_id, ext_id); - reason = g_strdup_printf(_("Message: %s"), reason_utf8); purple_request_action(gc, _("QQ Qun Operation"), msg, reason, PURPLE_DEFAULT_ACTION_NONE, purple_connection_get_account(gc), who, NULL, - add_req, 3, - _("Approve"), - G_CALLBACK - (member_join_authorize_cb), - _("Reject"), - G_CALLBACK - (member_join_reject_cb), - _("Search"), G_CALLBACK(member_join_search_cb)); + add_req, 2, + _("Deny"), G_CALLBACK(member_join_deny_cb), + _("Authorize"), G_CALLBACK(member_join_authorize_cb)); g_free(who); g_free(msg); g_free(reason); - g_free(reason_utf8); + g_free(reason); } /* the request to join a group is rejected */
--- a/libpurple/protocols/qq/group_search.c Tue Oct 28 16:42:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/** - * @file group_search.c - * - * purple - * - * Purple is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include "internal.h" - -#include "debug.h" - -#include "char_conv.h" -#include "group_internal.h" -#include "group_join.h" -#include "group_search.h" -#include "utils.h" -#include "qq_define.h" -#include "packet_parse.h" -#include "qq_network.h" -
--- a/libpurple/protocols/qq/group_search.h Tue Oct 28 16:42:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -/** - * @file group_search.h - * - * purple - * - * Purple is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef _QQ_GROUP_SEARCH_H_ -#define _QQ_GROUP_SEARCH_H_ - -#include <glib.h> -#include "connection.h" - -#endif
--- a/libpurple/protocols/qq/qq.c Tue Oct 28 16:42:46 2008 +0000 +++ b/libpurple/protocols/qq/qq.c Tue Oct 28 16:44:09 2008 +0000 @@ -1212,7 +1212,8 @@ purple_prefs_add_none("/plugins/prpl/qq"); purple_prefs_add_bool("/plugins/prpl/qq/show_status_by_icon", TRUE); purple_prefs_add_bool("/plugins/prpl/qq/show_fake_video", FALSE); - purple_prefs_add_bool("/plugins/prpl/qq/show_room_when_newin", TRUE); + purple_prefs_add_bool("/plugins/prpl/qq/auto_popup_conversation", FALSE); + purple_prefs_add_bool("/plugins/prpl/qq/auto_get_authorize_info", TRUE); purple_prefs_add_int("/plugins/prpl/qq/resend_interval", 3); purple_prefs_add_int("/plugins/prpl/qq/resend_times", 10); }
--- a/libpurple/protocols/qq/qq_base.c Tue Oct 28 16:42:46 2008 +0000 +++ b/libpurple/protocols/qq/qq_base.c Tue Oct 28 16:44:09 2008 +0000 @@ -293,50 +293,44 @@ guint8 qq_process_token(PurpleConnection *gc, guint8 *buf, gint buf_len) { qq_data *qd; + gint bytes; guint8 ret; - int token_len; - gchar *error_msg; + guint8 token_len; + gchar *msg; g_return_val_if_fail(buf != NULL && buf_len != 0, QQ_LOGIN_REPLY_ERR); g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, QQ_LOGIN_REPLY_ERR); qd = (qq_data *) gc->proto_data; - ret = buf[0]; + bytes = 0; + bytes += qq_get8(&ret, buf + bytes); + bytes += qq_get8(&token_len, buf + bytes); if (ret != QQ_LOGIN_REPLY_OK) { - purple_debug_error("QQ", "Failed to request token: %d\n", buf[0]); - qq_hex_dump(PURPLE_DEBUG_WARNING, "QQ", - buf, buf_len, - ">>> [default] decrypt and dump"); - error_msg = try_dump_as_gbk(buf, buf_len); - if (error_msg == NULL) { - error_msg = g_strdup_printf( _("Invalid token reply code, 0x%02X"), ret); - } + qq_show_packet("Failed requesting token", buf, buf_len); + + msg = g_strdup_printf( _("Failed requesting token, 0x%02X"), ret ); purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, - error_msg); - g_free(error_msg); + msg); + g_free(msg); return QQ_LOGIN_REPLY_ERR; } - token_len = buf_len-2; - if (token_len <= 0) { - error_msg = g_strdup_printf( _("Invalid token len, %d"), token_len); + if (bytes + token_len < buf_len) { + msg = g_strdup_printf( _("Invalid token len, %d"), token_len); purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, - error_msg); - g_free(error_msg); + msg); + g_free(msg); return QQ_LOGIN_REPLY_ERR; } - if (buf[1] != token_len) { - purple_debug_info("QQ", - "Invalid token len. Packet specifies length of %d, actual length is %d\n", buf[1], buf_len-2); + if (bytes + token_len > buf_len) { + purple_debug_info("QQ", "Extra token data, %d %d\n", token_len, buf_len - bytes); } - qq_hex_dump(PURPLE_DEBUG_INFO, "QQ", - buf+2, token_len, - "<<< got a token -> [default] decrypt and dump"); + qq_show_packet("Got token", buf + bytes, buf_len - bytes); if (qd->ld.token != NULL) { g_free(qd->ld.token); @@ -645,7 +639,7 @@ qd = (qq_data *) gc->proto_data; g_return_val_if_fail (data != NULL, QQ_LOGIN_REPLY_ERR); - + /* qq_show_packet("Get Server", data, data_len); */ bytes = 0; bytes += qq_get16(&ret, data + bytes); @@ -913,7 +907,7 @@ qd->ld.token_ex = g_realloc(qd->ld.token_ex, qd->ld.token_ex_len); bytes += qq_getdata(qd->ld.token_ex, qd->ld.token_ex_len, data + bytes); /* qq_show_packet("Get token ex", qd->ld.token_ex, qd->ld.token_ex_len); */ - + if(reply != 1) { purple_debug_info("QQ", "Captcha verified, result %d\n", reply); @@ -934,7 +928,7 @@ bytes += qq_getdata(qd->captcha.token, qd->captcha.token_len, data + bytes); /* qq_show_packet("Get captcha token", qd->captcha.token, qd->captcha.token_len); */ - purple_debug_info("QQ", "Request next captcha %d, new %d, total %d\n", + purple_debug_info("QQ", "Request next captcha %d, new %d, total %d\n", qd->captcha.next_index, captcha_len, qd->captcha.data_len); if(qd->captcha.next_index > 0) { @@ -1031,7 +1025,7 @@ /* put length into first 2 bytes */ qq_put8(raw_data + 1, bytes - 2); - + /* tail */ bytes += qq_put16(raw_data + bytes, 0x0003); bytes += qq_put8(raw_data + bytes, 0); @@ -1251,13 +1245,12 @@ if (ret != 0) { msg = g_strndup((gchar *)data + bytes, data_len - bytes); msg_utf8 = qq_to_utf8(msg, QQ_CHARSET_DEFAULT); + g_free(msg); switch (ret) { case 0x05: - error = g_strdup_printf( - _("Server is busy now (0x%02X), Please try later\n%s"), - ret, msg_utf8); - break; + purple_debug_error("QQ", "Server busy for %s\n", msg_utf8); + return QQ_LOGIN_REPLY_REDIRECT; case 0x0A: /* 0a 2d 9a 4b 9a 01 01 00 00 00 05 00 00 00 00 79 0e 5f fd */ /* Missing get server before login*/ @@ -1277,7 +1270,6 @@ g_free(error); g_free(msg_utf8); - g_free(msg); return QQ_LOGIN_REPLY_ERR; } @@ -1444,12 +1436,12 @@ if (ret != 0) { msg = g_strndup((gchar *)data + bytes, data_len - bytes); msg_utf8 = qq_to_utf8(msg, QQ_CHARSET_DEFAULT); + g_free(msg); switch (ret) { case 0x05: - error = g_strdup_printf( - _("Server is busy now (0x%02X), Please try later\n%s"), - ret, msg_utf8); + purple_debug_error("QQ", "Server busy for %s\n", msg_utf8); + return QQ_LOGIN_REPLY_REDIRECT; break; default: error = g_strdup_printf( @@ -1467,7 +1459,6 @@ g_free(error); g_free(msg_utf8); - g_free(msg); return QQ_LOGIN_REPLY_ERR; }
--- a/libpurple/protocols/qq/qq_base.h Tue Oct 28 16:42:46 2008 +0000 +++ b/libpurple/protocols/qq/qq_base.h Tue Oct 28 16:44:09 2008 +0000 @@ -31,8 +31,8 @@ #define QQ_LOGIN_REPLY_OK 0x00 #define QQ_LOGIN_REPLY_REDIRECT 0x01 /* defined by myself */ -#define QQ_LOGIN_REPLY_CAPTCHA_DLG 0xfc -#define QQ_LOGIN_REPLY_NEXT_TOKEN_EX 0xfd +#define QQ_LOGIN_REPLY_CAPTCHA_DLG 0xfd +#define QQ_LOGIN_REPLY_NEXT_TOKEN_EX 0xfe #define QQ_LOGIN_REPLY_ERR 0xff #define QQ_LOGIN_MODE_NORMAL 0x0a
--- a/libpurple/protocols/qq/qq_define.c Tue Oct 28 16:42:46 2008 +0000 +++ b/libpurple/protocols/qq/qq_define.c Tue Oct 28 16:44:09 2008 +0000 @@ -179,8 +179,8 @@ return "QQ_CMD_TOKEN_EX"; case QQ_CMD_CHECK_PWD: return "QQ_CMD_CHECK_PWD"; - case QQ_CMD_BUDDY_AUTH: - return "QQ_CMD_BUDDY_AUTH"; + case QQ_CMD_AUTH_INFO: + return "QQ_CMD_AUTH_INFO"; case QQ_CMD_BUDDY_ADD_NO_AUTH_EX: return "QQ_CMD_BUDDY_ADD_NO_AUTH_EX"; case QQ_CMD_BUDDY_ADD_AUTH_EX:
--- a/libpurple/protocols/qq/qq_define.h Tue Oct 28 16:42:46 2008 +0000 +++ b/libpurple/protocols/qq/qq_define.h Tue Oct 28 16:44:09 2008 +0000 @@ -70,7 +70,7 @@ QQ_CMD_GET_SERVER = 0x0091, /* select login server */ QQ_CMD_TOKEN_EX = 0x00BA, /* get LOGIN token */ QQ_CMD_CHECK_PWD = 0x00DD, /* Password verify */ - QQ_CMD_BUDDY_AUTH = 0x00AE, /* the request verification of information */ + QQ_CMD_AUTH_INFO = 0x00AE, /* the request verification of information */ QQ_CMD_BUDDY_ADD_NO_AUTH_EX = 0x00A7, /* add friend without auth */ QQ_CMD_BUDDY_ADD_AUTH_EX = 0x00A8, /* add buddy with auth */ }; @@ -108,12 +108,16 @@ const gchar *qq_get_room_cmd_desc(gint room_cmd); enum { - QQ_SERVER_BUDDY_ADDED = 0x01, - QQ_SERVER_BUDDY_ADD_REQUEST = 0x02, - QQ_SERVER_BUDDY_ADDED_ME = 0x03, - QQ_SERVER_BUDDY_REJECTED_ME = 0x04, - QQ_SERVER_NOTICE= 0x06, - QQ_SERVER_NEW_CLIENT = 0x09 + QQ_SERVER_BUDDY_ADDED = 1, + QQ_SERVER_BUDDY_ADD_REQUEST = 2, + QQ_SERVER_BUDDY_ADDED_ME = 3, + QQ_SERVER_BUDDY_REJECTED_ME = 4, + QQ_SERVER_NOTICE= 6, + QQ_SERVER_NEW_CLIENT = 9, + QQ_MSG_SYS_BEING_ADDED_EX = 40, + QQ_MSG_SYS_ADD_FRIEND_REQUEST_EX = 41, + QQ_MSG_SYS_ADDED_BY_CORRECT_ANSWER = 42, + QQ_MSG_SYS_ADD_FRIEND_APPROVED_AND_ADD = 43, }; enum {
--- a/libpurple/protocols/qq/qq_process.c Tue Oct 28 16:42:46 2008 +0000 +++ b/libpurple/protocols/qq/qq_process.c Tue Oct 28 16:44:09 2008 +0000 @@ -58,7 +58,7 @@ static void process_unknow_cmd(PurpleConnection *gc,const gchar *title, guint8 *data, gint data_len, guint16 cmd, guint16 seq) { qq_data *qd; - gchar *msg_utf8 = NULL; + gchar *msg; g_return_if_fail(data != NULL && data_len != 0); @@ -71,11 +71,9 @@ ">>> [%d] %s -> [default] decrypt and dump", seq, qq_get_cmd_desc(cmd)); - msg_utf8 = try_dump_as_gbk(data, data_len); - if (msg_utf8 != NULL) { - purple_notify_info(gc, _("QQ Error"), title, msg_utf8); - g_free(msg_utf8); - } + msg = g_strdup_printf("Unknow command 0x%02X, %s", cmd, qq_get_cmd_desc(cmd)); + purple_notify_info(gc, _("QQ Error"), title, msg); + g_free(msg); } /* parse the reply to send_im */ @@ -356,42 +354,47 @@ } /* Send ACK if the sys message needs an ACK */ -static void request_server_ack(PurpleConnection *gc, guint8 code, guint32 from, guint16 seq) +static void request_server_ack(PurpleConnection *gc, gchar *funct_str, gchar *from, guint16 seq) { qq_data *qd; - guint8 bar, *ack; - gchar *str; - gint ack_len, bytes; + guint8 *raw_data; + gint bytes; + guint8 bar; + g_return_if_fail(funct_str != NULL && from != NULL); qd = (qq_data *) gc->proto_data; - str = g_strdup_printf("%d", from); + bar = 0x1e; - ack_len = 1 + 1 + strlen(str) + 1 + 2; - ack = g_newa(guint8, ack_len); + raw_data = g_newa(guint8, strlen(funct_str) + strlen(from) + 16); bytes = 0; - bytes += qq_put8(ack + bytes, code); - bytes += qq_put8(ack + bytes, bar); - bytes += qq_putdata(ack + bytes, (guint8 *) str, strlen(str)); - bytes += qq_put8(ack + bytes, bar); - bytes += qq_put16(ack + bytes, seq); + bytes += qq_putdata(raw_data + bytes, (guint8 *)funct_str, strlen(funct_str)); + bytes += qq_put8(raw_data + bytes, bar); + bytes += qq_putdata(raw_data + bytes, (guint8 *)from, strlen(from)); + bytes += qq_put8(raw_data + bytes, bar); + bytes += qq_put16(raw_data + bytes, seq); - g_free(str); - - if (bytes == ack_len) /* creation OK */ - qq_send_server_reply(gc, QQ_CMD_ACK_SYS_MSG, 0, ack, ack_len); - else - purple_debug_error("QQ", - "Fail creating sys msg ACK, expect %d bytes, build %d bytes\n", ack_len, bytes); + qq_send_server_reply(gc, QQ_CMD_ACK_SYS_MSG, 0, raw_data, bytes); } -static void do_server_notice(PurpleConnection *gc, gchar *from, gchar *to, gchar *msg_utf8) +static void do_server_notice(PurpleConnection *gc, gchar *from, gchar *to, + guint8 *data, gint data_len) { qq_data *qd = (qq_data *) gc->proto_data; + gchar *msg, *msg_utf8; gchar *title, *content; - g_return_if_fail(from != NULL && to != NULL); + g_return_if_fail(from != NULL && to != NULL && data_len > 0); + + msg = g_strndup((gchar *)data, data_len); + msg_utf8 = qq_to_utf8(msg, QQ_CHARSET_DEFAULT); + g_free(msg); + if (msg_utf8 == NULL) { + purple_debug_error("QQ", "Recv NULL sys msg from %s to %s, discard\n", + from, to); + return; + } title = g_strdup_printf(_("From %s:"), from); content = g_strdup_printf(_("Server notice From %s: \n%s"), from, msg_utf8); @@ -401,62 +404,72 @@ } else { purple_debug_info("QQ", "QQ Server notice from %s:\n%s", from, msg_utf8); } + g_free(msg_utf8); g_free(title); g_free(content); } -static void process_server_msg(guint8 *data, gint data_len, guint16 seq, PurpleConnection *gc) +static void process_server_msg(PurpleConnection *gc, guint8 *data, gint data_len, guint16 seq) { qq_data *qd; - gchar **segments, *code, *from, *to, *msg, *msg_utf8; - int funct; + guint8 *data_str; + gchar **segments; + gchar *funct_str, *from, *to; + gint bytes, funct; g_return_if_fail(data != NULL && data_len != 0); qd = (qq_data *) gc->proto_data; - if (NULL == (segments = split_data(data, data_len, "\x1f", 4))) + data_str = g_newa(guint8, data_len + 1); + g_memmove(data_str, data, data_len); + data_str[data_len] = 0x00; + + segments = g_strsplit_set((gchar *) data_str, "\x1f", 0); + g_return_if_fail(segments != NULL); + if (g_strv_length(segments) < 3) { + purple_debug_warning("QQ", "Server message segments is less than 3\n"); + g_strfreev(segments); return; - code = segments[0]; + } + + bytes = 0; + funct_str = segments[0]; + bytes += strlen(funct_str) + 1; from = segments[1]; + bytes += strlen(from) + 1; to = segments[2]; - msg = segments[3]; + bytes += strlen(to) + 1; - request_server_ack(gc, code[0], strtol(from, NULL, 10), seq); + request_server_ack(gc, funct_str, from, seq); + qq_show_packet("Server MSG", data, data_len); if (strtol(to, NULL, 10) != qd->uid) { /* not to me */ purple_debug_error("QQ", "Recv sys msg to [%s], not me!, discard\n", to); g_strfreev(segments); return; } - msg_utf8 = qq_to_utf8(msg, QQ_CHARSET_DEFAULT); - if (from == NULL && msg_utf8) { - purple_debug_error("QQ", "Recv NULL sys msg to [%s], discard\n", to); - g_strfreev(segments); - g_free(msg_utf8); - return; - } - - funct = strtol(code, NULL, 10); + funct = strtol(funct_str, NULL, 10); switch (funct) { case QQ_SERVER_BUDDY_ADDED: case QQ_SERVER_BUDDY_ADD_REQUEST: case QQ_SERVER_BUDDY_ADDED_ME: case QQ_SERVER_BUDDY_REJECTED_ME: - qq_process_buddy_from_server(gc, funct, from, to, msg_utf8); + case QQ_MSG_SYS_ADD_FRIEND_REQUEST_EX: + qq_process_buddy_from_server(gc, funct, from, to, data + bytes, data_len - bytes); break; case QQ_SERVER_NOTICE: - do_server_notice(gc, from, to, msg_utf8); + do_server_notice(gc, from, to, data + bytes, data_len - bytes); break; case QQ_SERVER_NEW_CLIENT: purple_debug_warning("QQ", "QQ Server has newer client version\n"); break; default: - purple_debug_warning("QQ", "Recv unknown sys msg code: %s\nMsg: %s\n", code, msg_utf8); + qq_show_packet("Recv unknown sys msg", data, data_len); + purple_debug_warning("QQ", "Recv unknown sys msg code: %s\n", funct_str); break; } - g_free(msg_utf8); g_strfreev(segments); } @@ -493,7 +506,7 @@ process_private_msg(data, data_len, seq, gc); break; case QQ_CMD_RECV_MSG_SYS: - process_server_msg(data, data_len, seq, gc); + process_server_msg(gc, data, data_len, seq); break; case QQ_CMD_BUDDY_CHANGE_STATUS: qq_process_buddy_change_status(data, data_len, gc); @@ -946,8 +959,16 @@ case QQ_CMD_LOGIN: if (qd->client_version == 2008) { ret_8 = qq_process_login_2008(gc, data, data_len); + if ( ret_8 == QQ_LOGIN_REPLY_REDIRECT) { + qq_request_get_server(gc); + return QQ_LOGIN_REPLY_OK; + } } else if (qd->client_version == 2007) { ret_8 = qq_process_login_2007(gc, data, data_len); + if ( ret_8 == QQ_LOGIN_REPLY_REDIRECT) { + qq_request_get_server(gc); + return QQ_LOGIN_REPLY_OK; + } } else { ret_8 = qq_process_login(gc, data, data_len); } @@ -1075,6 +1096,9 @@ } purple_debug_info("QQ", "All buddies and groups received\n"); break; + case QQ_CMD_AUTH_INFO: + qq_process_auth_info(gc, data, data_len, ship32); + break; default: process_unknow_cmd(gc, _("Unknow CLIENT CMD"), data, data_len, cmd, seq); is_unknow = TRUE;
--- a/libpurple/protocols/qq/utils.c Tue Oct 28 16:42:46 2008 +0000 +++ b/libpurple/protocols/qq/utils.c Tue Oct 28 16:44:09 2008 +0000 @@ -336,6 +336,6 @@ void qq_show_packet(const gchar *desc, const guint8 *buf, gint len) { - qq_hex_dump(PURPLE_DEBUG_INFO, "QQ", buf, len, desc); + qq_hex_dump(PURPLE_DEBUG_WARNING, "QQ", buf, len, desc); }