Mercurial > pidgin
changeset 24164:2a19984c0005
2008.10.27 - ccpaging <ccpaging(at)gmail.com>
* Update 'buddy_adding' protocol
author | SHiNE CsyFeK <csyfek@gmail.com> |
---|---|
date | Tue, 28 Oct 2008 16:47:06 +0000 |
parents | 7f5433ffbf8d |
children | cae676ac3c70 |
files | libpurple/protocols/qq/ChangeLog libpurple/protocols/qq/buddy_opt.c libpurple/protocols/qq/buddy_opt.h libpurple/protocols/qq/char_conv.c libpurple/protocols/qq/char_conv.h libpurple/protocols/qq/group_join.c libpurple/protocols/qq/group_opt.c libpurple/protocols/qq/qq_define.c libpurple/protocols/qq/qq_define.h libpurple/protocols/qq/qq_process.c |
diffstat | 10 files changed, 240 insertions(+), 215 deletions(-) [+] |
line wrap: on
line diff
--- a/libpurple/protocols/qq/ChangeLog Tue Oct 28 16:46:08 2008 +0000 +++ b/libpurple/protocols/qq/ChangeLog Tue Oct 28 16:47:06 2008 +0000 @@ -1,3 +1,6 @@ +2008.10.27 - ccpaging <ccpaging(at)gmail.com> + * Update 'buddy_adding' protocol + 2008.10.22 - ccpaging <ccpaging(at)gmail.com> * 20081022
--- a/libpurple/protocols/qq/buddy_opt.c Tue Oct 28 16:46:08 2008 +0000 +++ b/libpurple/protocols/qq/buddy_opt.c Tue Oct 28 16:47:06 2008 +0000 @@ -66,6 +66,12 @@ g_free(add_req); } +static void buddy_req_cancel_cb(qq_buddy_req *add_req, const gchar *msg) +{ + g_return_if_fail(add_req != NULL); + buddy_req_free(add_req); +} + PurpleGroup *qq_group_find_or_new(const gchar *group_name) { PurpleGroup *g; @@ -234,7 +240,7 @@ qq_send_cmd_mess(gc, QQ_CMD_REMOVE_BUDDY, raw_data, bytes, 0, uid); } -void qq_request_auth_info(PurpleConnection *gc, guint8 cmd, guint16 sub_cmd, guint32 uid) +void qq_request_auth_code(PurpleConnection *gc, guint8 cmd, guint16 sub_cmd, guint32 uid) { guint8 raw_data[16]; gint bytes; @@ -245,180 +251,214 @@ 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); + qq_send_cmd_mess(gc, QQ_CMD_AUTH_CODE, raw_data, bytes, 0, uid); } -void qq_process_auth_info(PurpleConnection *gc, guint8 *data, gint data_len, guint32 uid) +void qq_process_auth_code(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; + guint8 *code = NULL; + guint16 code_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); + qq_show_packet("qq_process_auth_code", 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); - } + g_return_if_fail(bytes + 2 <= data_len); + + bytes += qq_get16(&code_len, data + bytes); + g_return_if_fail(code_len > 0); + g_return_if_fail(bytes + code_len <= data_len); + code = g_newa(guint8, code_len); + bytes += qq_getdata(code, code_len, data + bytes); if (cmd == QQ_AUTH_INFO_BUDDY && sub_cmd == QQ_AUTH_INFO_REMOVE_BUDDY) { - g_return_if_fail(auth != NULL && auth_len > 0); - request_remove_buddy_ex(gc, uid, auth, auth_len); + request_remove_buddy_ex(gc, uid, code, code_len); return; } if (cmd == QQ_AUTH_INFO_BUDDY && sub_cmd == QQ_AUTH_INFO_ADD_BUDDY) { - add_buddy_authorize_input(gc, uid, auth, auth_len); + add_buddy_authorize_input(gc, uid, code, code_len); return; } purple_debug_info("QQ", "Got auth info cmd 0x%x, sub 0x%x, reply 0x%x\n", cmd, sub_cmd, reply); } -#define AUHT_TYPE_QUESTION_GET 0x01 -#define AUTH_TYPE_QUESTION_SET 0x02 -#define AUTH_TYPE_QUESTION_REQUEST 0x03 -#define AUTH_TYPE_QUESTION_ANSWER 0x04 -/* -int EvaAddFriendAuthQuestionPacket::putBody( unsigned char * buf ) +static void add_buddy_question_cb(qq_buddy_req *add_req, const gchar *text) { - int pos = 0; - buf[pos++] = m_AuthStatus; // 0x01, 0x02, 0x03 or 0x04 - - if(m_AuthStatus == AUHT_TYPE_QUESTION_GET) { - buf[pos++] = 0x00; - return pos; + g_return_if_fail(add_req != NULL); + if (add_req->gc == NULL || add_req->uid == 0) { + buddy_req_free(add_req); + return; } - if(m_AuthStatus == AUTH_TYPE_QUESTION_SET){ - printf("question(%d):%s\n", m_Question.length(), m_Question.c_str()); - buf[pos++] = (unsigned char)(m_Question.length() & 0xff); - memcpy(buf + pos, m_Question.c_str(), m_Question.length()); - pos += m_Question.length(); + qq_request_question(add_req->gc, QQ_QUESTION_ANSWER, add_req->uid, NULL, text); + buddy_req_free(add_req); +} - buf[pos++] = (unsigned char)(m_Answer.length() & 0xff); - printf("answer(%d):%s\n", m_Answer.length(), m_Answer.c_str()); - memcpy(buf + pos, m_Answer.c_str(), m_Answer.length()); - pos += m_Answer.length(); +static void add_buddy_question_input(PurpleConnection *gc, guint32 uid, gchar *question) +{ + gchar *who, *msg; + qq_buddy_req *add_req; + g_return_if_fail(uid != 0); + + add_req = g_new0(qq_buddy_req, 1); + add_req->gc = gc; + add_req->uid = uid; + add_req->auth = NULL; + add_req->auth_len = 0; - buf[pos++] = 0x00; -printf("EvaAddFriendAuthQuestionPacket\n"); -for(int i=0;i<pos;i++){ - if(!(i%8)) printf("\n"); - printf("%2x ", buf[i]); + who = uid_to_purple_name(uid); + msg = g_strdup_printf(_("%d needs Q&A"), uid); + purple_request_input(gc, _("Add buddy Q&A"), msg, + _("Input answer here"), + NULL, + TRUE, FALSE, NULL, + _("Send"), G_CALLBACK(add_buddy_question_cb), + _("Cancel"), G_CALLBACK(buddy_req_cancel_cb), + purple_connection_get_account(gc), who, NULL, + add_req); + + g_free(msg); + g_free(who); } -printf("\n\n"); - return pos; - } - // unknown 2 bytes, always 0x0001 - buf[pos++] = 0x00; - buf[pos++] = 0x01; - *((unsigned int *)(buf + pos)) = htonl(m_AddQQNum); - pos+= 4; - - if(m_AuthStatus == AUTH_TYPE_QUESTION_REQUEST) return pos; - - buf[pos++] = (unsigned char)(m_Answer.length() & 0xff); - memcpy(buf + pos, m_Answer.c_str(), m_Answer.length()); - pos += m_Answer.length(); +void qq_request_question(PurpleConnection *gc, + guint8 cmd, guint32 uid, const gchar *question_utf8, const gchar *answer_utf8) +{ + guint8 raw_data[MAX_PACKET_SIZE - 16]; + gint bytes; - return pos; + g_return_if_fail(uid > 0); + bytes = 0; + bytes += qq_put8(raw_data + bytes, cmd); + if (cmd == QQ_QUESTION_GET) { + bytes += qq_put8(raw_data + bytes, 0); + qq_send_cmd_mess(gc, QQ_CMD_BUDDY_QUESTION, raw_data, bytes, 0, uid); + return; + } + if (cmd == QQ_QUESTION_SET) { + bytes += qq_put_vstr(raw_data + bytes, question_utf8, QQ_CHARSET_DEFAULT); + bytes += qq_put_vstr(raw_data + bytes, answer_utf8, QQ_CHARSET_DEFAULT); + bytes += qq_put8(raw_data + bytes, 0); + qq_send_cmd_mess(gc, QQ_CMD_BUDDY_QUESTION, raw_data, bytes, 0, uid); + return; + } + /* Unknow 2 bytes, 0x(00 01) */ + bytes += qq_put8(raw_data + bytes, 0x00); + bytes += qq_put8(raw_data + bytes, 0x01); + g_return_if_fail(uid != 0); + bytes += qq_put32(raw_data + bytes, uid); + if (cmd == QQ_QUESTION_REQUEST) { + qq_send_cmd_mess(gc, QQ_CMD_BUDDY_QUESTION, raw_data, bytes, 0, uid); + return; + } + bytes += qq_put_vstr(raw_data + bytes, answer_utf8, QQ_CHARSET_DEFAULT); + bytes += qq_put8(raw_data + bytes, 0); + qq_send_cmd_mess(gc, QQ_CMD_BUDDY_QUESTION, raw_data, bytes, 0, uid); + return; } -* -void EvaAddFriendAuthQuestionReplyPacket::parseBody( ) + +static void request_add_buddy_by_question(PurpleConnection *gc, guint32 uid, + guint8 *code, guint16 code_len) { -printf("EvaAddFriendAuthQuestionReplyPacket\n"); -for(int i=0;i<bodyLength;i++){ - if(!(i%8)) printf("\n"); - printf("%2x ", decryptedBuf[i]); -} -printf("\n\n"); - int offset = 0; + guint8 raw_data[MAX_PACKET_SIZE - 16]; + gint bytes = 0; - m_AuthStatus = decryptedBuf[offset++]; + g_return_if_fail(uid != 0 && code_len > 0); - if(m_AuthStatus == AUHT_TYPE_QUESTION_GET){ - m_CodeLen = decryptedBuf[offset++]; - if(m_CodeLen){ - if(m_Code) delete [] m_Code; - m_Code = new unsigned char[m_CodeLen+1]; - memcpy(m_Code, decryptedBuf + offset, m_CodeLen); - m_Code[m_CodeLen] = 0x00; - offset += m_CodeLen; - } + bytes = 0; + bytes += qq_put8(raw_data + bytes, 0x10); + bytes += qq_put32(raw_data + bytes, uid); + bytes += qq_put16(raw_data + bytes, 0); + + bytes += qq_put8(raw_data + bytes, 0); + bytes += qq_put8(raw_data + bytes, 0); /* no auth code */ + + bytes += qq_put16(raw_data + bytes, code_len); + bytes += qq_putdata(raw_data + bytes, code, code_len); + + bytes += qq_put8(raw_data + bytes, 1); /* ALLOW ADD ME FLAG */ + bytes += qq_put8(raw_data + bytes, 0); /* group number? */ + qq_send_cmd(gc, QQ_CMD_ADD_BUDDY_AUTH_EX, raw_data, bytes); +} - unsigned int len = decryptedBuf[offset++]; - if(len){ - char *tmp = new char [len+1]; - memcpy(tmp, decryptedBuf + offset, len); - tmp[len] = 0x00; - m_Answer = tmp; - delete []tmp; - offset += len; +void qq_process_question(PurpleConnection *gc, guint8 *data, gint data_len, guint32 uid) +{ + qq_data *qd; + gint bytes; + guint8 cmd, reply; + gchar *question, *answer; + guint16 code_len; + guint8 *code; + + g_return_if_fail(data != NULL && data_len != 0); + + qd = (qq_data *) gc->proto_data; + + qq_show_packet("qq_process_question", data, data_len); + bytes = 0; + bytes += qq_get8(&cmd, data + bytes); + if (cmd == QQ_QUESTION_GET) { + bytes += qq_get_vstr(&question, QQ_CHARSET_DEFAULT, data + bytes); + bytes += qq_get_vstr(&answer, QQ_CHARSET_DEFAULT, data + bytes); + purple_debug_info("QQ", "Get buddy adding Q&A:\n%s\n%s\n", question, answer); + g_free(question); + g_free(answer); + return; + } + if (cmd == QQ_QUESTION_SET) { + bytes += qq_get8(&reply, data + bytes); + if (reply == 0) { + purple_debug_info("QQ", "Successed setting Q&A\n"); + } else { + purple_debug_warning("QQ", "Failed setting Q&A, reply %d\n", reply); } return; } - if(m_AuthStatus == AUTH_TYPE_QUESTION_SET){ - m_ReplyCode = decryptedBuf[offset++]; // 0x00: success, (? -- 0x01: error) - return; - } - - offset+=2; // unknown 2 bytes, always be 0x0001 - - m_ReplyCode = decryptedBuf[offset++]; - - if(m_ReplyCode == 0x01){ - // should be error happened + g_return_if_fail(uid != 0); + bytes += 2; /* skip 2 bytes, 0x(00 01)*/ + if (cmd == QQ_QUESTION_REQUEST) { + bytes += qq_get8(&reply, data + bytes); + if (reply == 0x01) { + purple_debug_warning("QQ", "Failed getting question, reply %d\n", reply); + return; + } + bytes += qq_get_vstr(&question, QQ_CHARSET_DEFAULT, data + bytes); + purple_debug_info("QQ", "Get buddy question:\n%s\n", question); + add_buddy_question_input(gc, uid, question); + g_free(question); return; } - switch(m_AuthStatus){ - case AUTH_TYPE_QUESTION_REQUEST: - m_CodeLen = decryptedBuf[offset++]; - break; - case AUTH_TYPE_QUESTION_ANSWER:{ - m_CodeLen = ntohs( *( (unsigned short *)(decryptedBuf + offset)) ); - offset+=2; + if (cmd == QQ_QUESTION_ANSWER) { + bytes += qq_get8(&reply, data + bytes); + if (reply == 0x01) { + purple_notify_error(gc, _("Add Buddy"), _("Invalid answer."), NULL); + return; } - break; - default: - fprintf(stderr, "Unknown auth status code: 0x%2x\n", m_AuthStatus); + bytes += qq_get16(&code_len, data + bytes); + g_return_if_fail(code_len > 0); + g_return_if_fail(bytes + code_len <= data_len); + + code = g_newa(guint8, code_len); + bytes += qq_getdata(code, code_len, data + bytes); + request_add_buddy_by_question(gc, uid, code, code_len); return; } - if(m_CodeLen){ - if(m_Code) delete [] m_Code; - m_Code = new unsigned char[m_CodeLen+1]; - memcpy(m_Code, decryptedBuf + offset, m_CodeLen); - offset += m_CodeLen; - } - // just in case the url, give it a terminate char - if(m_AuthStatus == AUTH_TYPE_QUESTION_REQUEST || - m_AuthStatus == AUHT_TYPE_QUESTION_GET){ - m_Code[m_CodeLen] = 0x00; - m_CodeLen++; - } + g_return_if_reached(); } - */ /* try to remove myself from someone's buddy list */ static void request_buddy_remove_me(PurpleConnection *gc, guint32 uid) @@ -488,13 +528,11 @@ static void request_add_buddy_auth_ex(PurpleConnection *gc, guint32 uid, const gchar *text, guint8 *auth, guint8 auth_len) { - guint8 *raw_data; + guint8 raw_data[MAX_PACKET_SIZE - 16]; gint bytes = 0; - gchar *msg; g_return_if_fail(uid != 0); - raw_data = g_newa(guint8, QQ_MSG_IM_MAX); bytes = 0; bytes += qq_put8(raw_data + bytes, 0x02); bytes += qq_put32(raw_data + bytes, uid); @@ -508,18 +546,18 @@ bytes += qq_putdata(raw_data + bytes, auth, auth_len); } bytes += qq_put8(raw_data + bytes, 1); /* ALLOW ADD ME FLAG */ - bytes += qq_put8(raw_data + bytes, 0); /* Destination group */ - if (text == NULL) { - bytes += qq_put8(raw_data + bytes, 0); - } else { - msg = utf8_to_qq(text, QQ_CHARSET_DEFAULT); - bytes += qq_put8(raw_data + bytes, strlen(msg)); - bytes += qq_putdata(raw_data + bytes, (guint8 *)msg, strlen(msg)); - g_free(msg); - } + bytes += qq_put8(raw_data + bytes, 0); /* group number? */ + bytes += qq_put_vstr(raw_data + bytes, text, QQ_CHARSET_DEFAULT); qq_send_cmd(gc, QQ_CMD_ADD_BUDDY_AUTH_EX, raw_data, bytes); } +void qq_process_add_buddy_auth_ex(PurpleConnection *gc, guint8 *data, gint data_len, guint32 ship32) +{ + g_return_if_fail(data != NULL && data_len != 0); + + qq_show_packet("qq_process_question", data, data_len); +} + static void add_buddy_auth_cb(qq_buddy_req *add_req, const gchar *text) { qq_data *qd; @@ -586,12 +624,6 @@ g_free(who); } -static void buddy_req_cancel_cb(qq_buddy_req *add_req, const gchar *msg) -{ - g_return_if_fail(add_req != NULL); - buddy_req_free(add_req); -} - static void add_buddy_no_auth_cb(qq_buddy_req *add_req) { qq_data *qd; @@ -855,12 +887,12 @@ case 0x00: /* no authorize */ break; case 0x01: /* authorize */ - qq_request_auth_info(gc, QQ_AUTH_INFO_BUDDY, QQ_AUTH_INFO_ADD_BUDDY, uid); + 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, uid); + qq_request_question(gc, QQ_QUESTION_REQUEST, uid, NULL, NULL); break; default: g_return_if_reached(); @@ -885,7 +917,7 @@ uid = purple_name_to_uid(buddy->name); 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); + 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); @@ -1020,8 +1052,8 @@ gchar *from, guint8 *data, gint data_len) { gint bytes; + guint16 code_len; guint8 *code; - guint16 code_len; g_return_val_if_fail(data != NULL && data_len > 0, 0);
--- a/libpurple/protocols/qq/buddy_opt.h Tue Oct 28 16:46:08 2008 +0000 +++ b/libpurple/protocols/qq/buddy_opt.h Tue Oct 28 16:47:06 2008 +0000 @@ -41,6 +41,13 @@ QQ_AUTH_INFO_UPDATE_BUDDY_INFO = 0x0007, }; +enum { + QQ_QUESTION_GET = 0x01, + QQ_QUESTION_SET = 0x02, + QQ_QUESTION_REQUEST = 0x03, /* get question only*/ + QQ_QUESTION_ANSWER = 0x04, +}; + 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); @@ -59,8 +66,13 @@ void qq_process_buddy_check_code(PurpleConnection *gc, 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); +void qq_request_auth_code(PurpleConnection *gc, guint8 cmd, guint16 sub_cmd, guint32 uid); +void qq_process_auth_code(PurpleConnection *gc, guint8 *data, gint data_len, guint32 uid); +void qq_request_question(PurpleConnection *gc, + guint8 cmd, guint32 uid, const gchar *question_utf8, const gchar *answer_utf8); +void qq_process_question(PurpleConnection *gc, guint8 *data, gint data_len, guint32 uid); + +void qq_process_add_buddy_auth_ex(PurpleConnection *gc, guint8 *data, gint data_len, guint32 ship32); 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:46:08 2008 +0000 +++ b/libpurple/protocols/qq/char_conv.c Tue Oct 28 16:47:06 2008 +0000 @@ -144,6 +144,24 @@ return len + 1; } +gint qq_put_vstr(guint8 *buf, const gchar *str_utf8, const gchar *to_charset) +{ + gchar *str; + guint8 len; + + if (str_utf8 == NULL || (len = strlen(str_utf8)) == 0) { + buf[0] = 0; + return 1; + } + str = do_convert(str_utf8, -1, to_charset, UTF8); + len = strlen(str_utf8); + buf[0] = len; + if (len > 0) { + memcpy(buf + 1, str, len); + } + return 1 + len; +} + /* convert QQ formatted msg to Purple formatted msg (and UTF-8) */ gchar *qq_encode_to_purple(guint8 *data, gint len, const gchar *msg, const gint client_version) {
--- a/libpurple/protocols/qq/char_conv.h Tue Oct 28 16:46:08 2008 +0000 +++ b/libpurple/protocols/qq/char_conv.h Tue Oct 28 16:47:06 2008 +0000 @@ -30,6 +30,7 @@ #define QQ_CHARSET_DEFAULT "GB18030" gint qq_get_vstr(gchar **ret, const gchar *from_charset, guint8 *data); +gint qq_put_vstr(guint8 *buf, const gchar *str_utf8, const gchar *to_charset); gchar *qq_smiley_to_purple(gchar *text); gchar *purple_smiley_to_qq(gchar *text);
--- a/libpurple/protocols/qq/group_join.c Tue Oct 28 16:46:08 2008 +0000 +++ b/libpurple/protocols/qq/group_join.c Tue Oct 28 16:47:06 2008 +0000 @@ -154,31 +154,23 @@ g_free(msg); } -void qq_send_cmd_group_auth(PurpleConnection *gc, qq_room_data *rmd, guint8 opt, guint32 uid, const gchar *reason_utf8) +void qq_send_cmd_group_auth(PurpleConnection *gc, qq_room_data *rmd, + guint8 opt, guint32 uid, const gchar *reason_utf8) { - guint8 *raw_data; - gchar *reason_qq; + guint8 raw_data[MAX_PACKET_SIZE - 16]; gint bytes; g_return_if_fail(rmd != NULL); - if (reason_utf8 == NULL || strlen(reason_utf8) == 0) - reason_qq = g_strdup(""); - else - reason_qq = utf8_to_qq(reason_utf8, QQ_CHARSET_DEFAULT); - if (opt == QQ_ROOM_AUTH_REQUEST_APPLY) { rmd->my_role = QQ_ROOM_ROLE_REQUESTING; uid = 0; } - raw_data = g_newa(guint8, 6 + strlen(reason_qq)); - bytes = 0; bytes += qq_put8(raw_data + bytes, opt); bytes += qq_put32(raw_data + bytes, uid); - bytes += qq_put8(raw_data + bytes, strlen(reason_qq)); - bytes += qq_putdata(raw_data + bytes, (guint8 *) reason_qq, strlen(reason_qq)); + bytes += qq_put_vstr(raw_data + bytes, reason_utf8, QQ_CHARSET_DEFAULT); qq_send_room_cmd(gc, QQ_ROOM_CMD_AUTH, rmd->id, raw_data, bytes); }
--- a/libpurple/protocols/qq/group_opt.c Tue Oct 28 16:46:08 2008 +0000 +++ b/libpurple/protocols/qq/group_opt.c Tue Oct 28 16:47:06 2008 +0000 @@ -209,19 +209,11 @@ void qq_room_change_info(PurpleConnection *gc, qq_room_data *rmd) { - guint8 *data; - gint data_len; + guint8 data[MAX_PACKET_SIZE - 16]; gint bytes; - gchar *group_name, *group_desc, *notice; g_return_if_fail(rmd != NULL); - group_name = rmd->title_utf8 == NULL ? "" : utf8_to_qq(rmd->title_utf8, QQ_CHARSET_DEFAULT); - group_desc = rmd->desc_utf8 == NULL ? "" : utf8_to_qq(rmd->desc_utf8, QQ_CHARSET_DEFAULT); - notice = rmd->notice_utf8 == NULL ? "" : utf8_to_qq(rmd->notice_utf8, QQ_CHARSET_DEFAULT); - - data_len = 64 + strlen(group_name) + strlen(group_desc) + strlen(notice); - data = g_newa(guint8, data_len); bytes = 0; /* 005-005 */ bytes += qq_put8(data + bytes, 0x01); @@ -232,23 +224,13 @@ /* 009-010 */ bytes += qq_put16(data + bytes, rmd->category); - bytes += qq_put8(data + bytes, strlen(group_name)); - bytes += qq_putdata(data + bytes, (guint8 *) group_name, strlen(group_name)); + bytes += qq_put_vstr(data + bytes, rmd->title_utf8, QQ_CHARSET_DEFAULT); bytes += qq_put16(data + bytes, 0x0000); - bytes += qq_put8(data + bytes, strlen(notice)); - bytes += qq_putdata(data+ bytes, (guint8 *) notice, strlen(notice)); - - bytes += qq_put8(data + bytes, strlen(group_desc)); - bytes += qq_putdata(data + bytes, (guint8 *) group_desc, strlen(group_desc)); + bytes += qq_put_vstr(data + bytes, rmd->notice_utf8, QQ_CHARSET_DEFAULT); + bytes += qq_put_vstr(data + bytes, rmd->desc_utf8, QQ_CHARSET_DEFAULT); - if (bytes > data_len) { - purple_debug_error("QQ", - "Overflow in qq_room_change_info, max %d bytes, now %d bytes\n", - data_len, bytes); - return; - } qq_send_room_cmd(gc, QQ_ROOM_CMD_CHANGE_INFO, rmd->id, data, bytes); } @@ -479,7 +461,7 @@ { guint32 ext_id, admin_uid; guint8 type8; - gchar *reason_utf8, *msg, *reason; + gchar *msg, *reason; qq_room_data *rmd; gint bytes; @@ -493,11 +475,10 @@ g_return_if_fail(ext_id > 0 && admin_uid > 0); - bytes += qq_get_vstr(&reason_utf8, QQ_CHARSET_DEFAULT, data + bytes); + bytes += qq_get_vstr(&reason, QQ_CHARSET_DEFAULT, data + bytes); msg = g_strdup_printf (_("Failed to join Qun %d, operated by admin %d"), ext_id, admin_uid); - reason = g_strdup_printf(_("Message: %s"), reason_utf8); purple_notify_warning(gc, _("QQ Qun Operation"), msg, reason); @@ -509,7 +490,6 @@ g_free(msg); g_free(reason); - g_free(reason_utf8); } /* the request to join a group is approved */
--- a/libpurple/protocols/qq/qq_define.c Tue Oct 28 16:46:08 2008 +0000 +++ b/libpurple/protocols/qq/qq_define.c Tue Oct 28 16:47:06 2008 +0000 @@ -179,8 +179,8 @@ return "QQ_CMD_TOKEN_EX"; case QQ_CMD_CHECK_PWD: return "QQ_CMD_CHECK_PWD"; - case QQ_CMD_AUTH_INFO: - return "QQ_CMD_AUTH_INFO"; + case QQ_CMD_AUTH_CODE: + return "QQ_CMD_AUTH_CODE"; case QQ_CMD_ADD_BUDDY_NO_AUTH_EX: return "QQ_CMD_ADD_BUDDY_NO_AUTH_EX"; case QQ_CMD_ADD_BUDDY_AUTH_EX:
--- a/libpurple/protocols/qq/qq_define.h Tue Oct 28 16:46:08 2008 +0000 +++ b/libpurple/protocols/qq/qq_define.h Tue Oct 28 16:47:06 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_AUTH_INFO = 0x00AE, /* the request verification of information */ + QQ_CMD_AUTH_CODE = 0x00AE, /* the request verification of information */ QQ_CMD_ADD_BUDDY_NO_AUTH_EX = 0x00A7, /* add friend without auth */ QQ_CMD_ADD_BUDDY_AUTH_EX = 0x00A8, /* add buddy with auth */ QQ_CMD_BUDDY_CHECK_CODE = 0x00B5,
--- a/libpurple/protocols/qq/qq_process.c Tue Oct 28 16:46:08 2008 +0000 +++ b/libpurple/protocols/qq/qq_process.c Tue Oct 28 16:47:06 2008 +0000 @@ -98,49 +98,30 @@ { qq_data *qd = (qq_data *) gc->proto_data; gint bytes; - guint8 *temp; - guint8 temp_len; gchar *title, *brief, *url; - gchar *title_utf8; - gchar *content, *content_utf8; + gchar *content; g_return_if_fail(data != NULL && data_len != 0); /* qq_show_packet("Rcv news", data, data_len); */ - temp = g_newa(guint8, data_len); - bytes = 4; /* ignore unknown 4 bytes */ - - bytes += qq_get8(&temp_len, data + bytes); - g_return_if_fail(bytes + temp_len <= data_len); - bytes += qq_getdata(temp, temp_len, data+bytes); - title = g_strndup((gchar *)temp, temp_len); + bytes = 4; /* skip unknown 4 bytes */ - bytes += qq_get8(&temp_len, data + bytes); - g_return_if_fail(bytes + temp_len <= data_len); - bytes += qq_getdata(temp, temp_len, data+bytes); - brief = g_strndup((gchar *)temp, temp_len); + bytes += qq_get_vstr(&title, QQ_CHARSET_DEFAULT, data + bytes); + bytes += qq_get_vstr(&brief, QQ_CHARSET_DEFAULT, data + bytes); + bytes += qq_get_vstr(&url, QQ_CHARSET_DEFAULT, data + bytes); - bytes += qq_get8(&temp_len, data + bytes); - g_return_if_fail(bytes + temp_len <= data_len); - bytes += qq_getdata(temp, temp_len, data+bytes); - url = g_strndup((gchar *)temp, temp_len); - - title_utf8 = qq_to_utf8(title, QQ_CHARSET_DEFAULT); content = g_strdup_printf(_("Server News:\n%s\n%s\n%s"), title, brief, url); - content_utf8 = qq_to_utf8(content, QQ_CHARSET_DEFAULT); if (qd->is_show_news) { - qq_got_attention(gc, content_utf8); + qq_got_attention(gc, content); } else { - purple_debug_info("QQ", "QQ Server news:\n%s\n%s", title_utf8, content_utf8); + purple_debug_info("QQ", "QQ Server news:\n%s\n", content); } g_free(title); - g_free(title_utf8); g_free(brief); g_free(url); g_free(content); - g_free(content_utf8); } static void do_msg_sys_30(PurpleConnection *gc, guint8 *data, gint data_len) @@ -1099,12 +1080,18 @@ } 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); + case QQ_CMD_AUTH_CODE: + qq_process_auth_code(gc, data, data_len, ship32); + break; + case QQ_CMD_BUDDY_QUESTION: + qq_process_question(gc, data, data_len, ship32); break; case QQ_CMD_ADD_BUDDY_NO_AUTH_EX: qq_process_add_buddy_no_auth_ex(gc, data, data_len, ship32); break; + case QQ_CMD_ADD_BUDDY_AUTH_EX: + qq_process_add_buddy_auth_ex(gc, data, data_len, ship32); + break; case QQ_CMD_BUDDY_CHECK_CODE: qq_process_buddy_check_code(gc, data, data_len); break;