pidgin: 365b2b0d: disapproval of revision '8cebefbc6cd5d84...
datallah at pidgin.im
datallah at pidgin.im
Sun Sep 14 23:20:44 EDT 2008
-----------------------------------------------------------------
Revision: 365b2b0d8c5b010ad52640bc3f19a95168d44ded
Ancestor: 8cebefbc6cd5d84acb69c74e69e8821f11dd225d
Author: datallah at pidgin.im
Date: 2008-09-15T03:04:07
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/365b2b0d8c5b010ad52640bc3f19a95168d44ded
Modified files:
libpurple/protocols/qq/AUTHORS
libpurple/protocols/qq/ChangeLog
libpurple/protocols/qq/buddy_info.c
libpurple/protocols/qq/buddy_info.h
libpurple/protocols/qq/buddy_list.c
libpurple/protocols/qq/buddy_list.h
libpurple/protocols/qq/buddy_opt.c
libpurple/protocols/qq/char_conv.c
libpurple/protocols/qq/file_trans.c
libpurple/protocols/qq/group.c
libpurple/protocols/qq/group.h
libpurple/protocols/qq/group_conv.c
libpurple/protocols/qq/group_find.c
libpurple/protocols/qq/group_find.h
libpurple/protocols/qq/group_free.c
libpurple/protocols/qq/group_im.c
libpurple/protocols/qq/group_im.h
libpurple/protocols/qq/group_info.c
libpurple/protocols/qq/group_info.h
libpurple/protocols/qq/group_internal.c
libpurple/protocols/qq/group_internal.h
libpurple/protocols/qq/group_join.c
libpurple/protocols/qq/group_join.h
libpurple/protocols/qq/group_opt.c
libpurple/protocols/qq/group_opt.h
libpurple/protocols/qq/group_search.c
libpurple/protocols/qq/header_info.c
libpurple/protocols/qq/header_info.h
libpurple/protocols/qq/im.c libpurple/protocols/qq/im.h
libpurple/protocols/qq/packet_parse.c
libpurple/protocols/qq/qq.c libpurple/protocols/qq/qq.h
libpurple/protocols/qq/qq_base.c
libpurple/protocols/qq/qq_base.h
libpurple/protocols/qq/qq_network.c
libpurple/protocols/qq/qq_network.h
libpurple/protocols/qq/qq_process.c
libpurple/protocols/qq/qq_process.h
libpurple/protocols/qq/qq_trans.c
libpurple/protocols/qq/qq_trans.h
libpurple/protocols/qq/send_file.c
libpurple/protocols/qq/sys_msg.c
libpurple/protocols/qq/utils.c
libpurple/protocols/qq/utils.h
ChangeLog:
disapproval of revision '8cebefbc6cd5d84acb69c74e69e8821f11dd225d'
-------------- next part --------------
============================================================
--- libpurple/protocols/qq/AUTHORS 9010c8d4979848a7d3c99d2a5338f11067a58ab9
+++ libpurple/protocols/qq/AUTHORS c46c7dfe83578267955d8b41cb3a2e3df7c44577
@@ -1,38 +1,35 @@ Code Contributors
Code Contributors
-=========
-puzzlebird : original author
-gfhuang : patches for libpurple 2.0.0beta2, maintainer
-Yuan Qingyun : patches for libpurple 1.5.0, maintainer
-henryouly : file transfer, udp sock5 proxy and qq_show, maintainer
-hzhr : maintainer
-joymarquis : maintainer
-arfankai : fixed bugs in char_conv.c
-rakescar : provided filter for HTML tag
-yyw : improved performance on PPC linux
-lvxiang : provided ip to location original code
-markhuetsch : OpenQ merge into libpurple, maintainer 2006-2007
-ccpaging : maintainer since 2007
-icesky : maintainer since 2007
-csyfek : faces, maintainer since 2007
+=====
+puzzlebird : original author
+gfhuang : patches for libpurple 2.0.0beta2, maintainer
+henryouly : file transfer, udp sock5 proxy and qq_show, maintainer
+hzhr : maintainer
+joymarquis : maintainer
+arfankai : fixed bugs in char_conv.c
+rakescar : provided filter for HTML tag
+yyw : improved performance on PPC linux
+lvxiang : provided ip to location original code
+markhuetsch : OpenQ merge into libpurple, maintainer 2006-2007
+ccpaging : maintainer since 2007
+icesky : maintainer since 2007
+csyfek : faces, maintainer since 2007
Lovely Patch Writers
-=========
-gnap : message displaying, documentation
-manphiz : qun processing
-moo : qun processing
-Coly Li : qun processing
-Emil Alexiev : captcha verification on login based on LumaQQ for MAC (2007),
- login, add buddy, remove buddy, message exchange and logout
+=====
+gnap : message displaying, documentation
+manphiz : qun processing
+moo : qun processing
+Coly Li : qun processing
Acknowledgement
-=========
-Shufeng Tan : http://sf.net/projects/perl-oicq
-Jeff Ye : http://www.sinomac.com
-Hu Zheng : http://forlinux.yeah.net
-yunfan : http://www.myswear.net
-OpenQ Team : http://openq.linuxsir.org
-LumaQQ Team : http://lumaqq.linuxsir.org
+=====
+Shufeng Tan : http://sf.net/projects/perl-oicq
+Jeff Ye : http://www.sinomac.com
+Hu Zheng : http://forlinux.yeah.net
+yunfan : http://www.myswear.net
khc at pidgin.im
qulogic at pidgin.im
rlaager at pidgin.im
-OpenQ Google Group : http://groups.google.com/group/openq
+OpenQ Team
+LumaQQ Team
+OpenQ Google Group
============================================================
--- libpurple/protocols/qq/ChangeLog d1c1aa5ec35e4616ee6b82d1902fb89aa8c8e8d8
+++ libpurple/protocols/qq/ChangeLog 4ed95b382ab28c61dc0a3833a75d776e61952d5e
@@ -1,17 +1,6 @@
-2008.08.16 - ccpaging <ecc_hy(at)hotmail.com>
- * Rename group to room. If you used pidginqq before, this may create a new room with same title, you may delete old one
- * Replace purple_debug with purple_debug_info, purple_debug_warning, purple_debug_error
- * Add server notice and server new, and two options to turn on/off
- * Minor modify for reducing transaction's debug infor
- * Minor modifies for system notice and QQ news.
- * Add 4 new strings need translate compare with p10.
-
2008.08.10 - csyfek <csyfek(at)gmail.com>
* Commit to Pidgin
-2008.08.07 - ccpaging <ecc_hy(at)hotmail.com>
- * Support managing multi-connections according to simple.c
-
2008.08.06 - ccpaging <ecc_hy(at)hotmail.com>
* Rename names of variables, Group, to Room
* Functions of group_network merged into qq_network and qq_process
============================================================
--- libpurple/protocols/qq/buddy_info.c 8692742a441f53367bb7b6f606d7b59a74ecb2bc
+++ libpurple/protocols/qq/buddy_info.c 6903a2b652ab9269e046c9bf44f9d11371a42a17
@@ -284,7 +284,7 @@ void qq_send_packet_get_info(PurpleConne
qd = (qq_data *) gc->proto_data;
g_snprintf(uid_str, sizeof(uid_str), "%d", uid);
- qq_send_cmd(gc, QQ_CMD_GET_USER_INFO, (guint8 *) uid_str, strlen(uid_str));
+ qq_send_cmd(qd, QQ_CMD_GET_USER_INFO, (guint8 *) uid_str, strlen(uid_str));
query = g_new0(qq_info_query, 1);
query->uid = uid;
@@ -293,20 +293,6 @@ void qq_send_packet_get_info(PurpleConne
qd->info_query = g_list_append(qd->info_query, query);
}
-void qq_request_buddy_info(PurpleConnection *gc, guint32 uid,
- gint update_class, guint32 ship32)
-{
- qq_data *qd;
- gchar raw_data[16] = {0};
-
- g_return_if_fail(uid != 0);
-
- qd = (qq_data *) gc->proto_data;
- g_snprintf(raw_data, sizeof(raw_data), "%d", uid);
- qq_send_cmd_mess(gc, QQ_CMD_GET_USER_INFO, (guint8 *) raw_data, strlen(raw_data),
- update_class, ship32);
-}
-
/* set up the fields requesting personal information and send a get_info packet
* for myself */
void qq_prepare_modify_info(PurpleConnection *gc)
@@ -328,6 +314,7 @@ static void qq_send_packet_modify_info(P
/* send packet to modify personal information */
static void qq_send_packet_modify_info(PurpleConnection *gc, contact_info *info)
{
+ qq_data *qd = (qq_data *) gc->proto_data;
gint bytes = 0;
guint8 raw_data[MAX_PACKET_SIZE - 128] = {0};
guint8 bar;
@@ -459,7 +446,7 @@ static void qq_send_packet_modify_info(P
bytes += qq_put8(raw_data + bytes, bar);
- qq_send_cmd(gc, QQ_CMD_UPDATE_INFO, raw_data, bytes);
+ qq_send_cmd(qd, QQ_CMD_UPDATE_INFO, raw_data, bytes);
}
@@ -710,8 +697,8 @@ void qq_process_modify_info_reply(guint8
data[data_len] = '\0';
if (qd->uid == atoi((gchar *) data)) { /* return should be my uid */
- purple_debug_info("QQ", "Update info ACK OK\n");
- purple_notify_info(gc, NULL, _("My information has been updated"), NULL);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Update info ACK OK\n");
+ purple_notify_info(gc, NULL, _("Your information has been updated"), NULL);
}
}
@@ -759,8 +746,8 @@ void qq_set_my_buddy_icon(PurpleConnecti
const gchar *buddy_icon_dir = qq_buddy_icon_dir();
gint prefix_len = strlen(QQ_ICON_PREFIX);
gint suffix_len = strlen(QQ_ICON_SUFFIX);
- gint dir_len = strlen(buddy_icon_dir);
- gchar *errmsg = g_strdup_printf(_("Setting custom faces is not currently supported. Please choose an image from %s."), buddy_icon_dir);
+ gint dir_len = buddy_icon_dir ? strlen(buddy_icon_dir) : 0;
+ gchar *errmsg = g_strdup_printf(_("Setting custom faces is not currently supported. Please choose an image from %s."), buddy_icon_dir ? buddy_icon_dir : "(null)");
gboolean icon_global = purple_account_get_bool(gc->account, "use-global-buddyicon", TRUE);
if (!icon_path)
@@ -769,13 +756,13 @@ void qq_set_my_buddy_icon(PurpleConnecti
icon_len = strlen(icon_path) - dir_len - 1 - prefix_len - suffix_len;
/* make sure we're using an appropriate icon */
- if (!(g_ascii_strncasecmp(icon_path, buddy_icon_dir, dir_len) == 0
+ if (buddy_icon_dir && !(g_ascii_strncasecmp(icon_path, buddy_icon_dir, dir_len) == 0
&& icon_path[dir_len] == G_DIR_SEPARATOR
&& g_ascii_strncasecmp(icon_path + dir_len + 1, QQ_ICON_PREFIX, prefix_len) == 0
&& g_ascii_strncasecmp(icon_path + dir_len + 1 + prefix_len + icon_len, QQ_ICON_SUFFIX, suffix_len) == 0
&& icon_len <= 3)) {
if (icon_global)
- purple_debug_error("QQ", "%s\n", errmsg);
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ", "%s\n", errmsg);
else
purple_notify_error(gc, _("Invalid QQ Face"), errmsg, NULL);
g_free(errmsg);
@@ -788,7 +775,7 @@ void qq_set_my_buddy_icon(PurpleConnecti
/* ensure face number in proper range */
if (icon_num > QQ_FACES) {
if (icon_global)
- purple_debug_error("QQ", "%s\n", errmsg);
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ", "%s\n", errmsg);
else
purple_notify_error(gc, _("Invalid QQ Face"), errmsg, NULL);
g_free(errmsg);
@@ -811,8 +798,8 @@ static void _qq_update_buddy_icon(Purple
if ((buddy = purple_find_buddy(account, name)))
old_icon_num = purple_buddy_icons_get_checksum_for_user(buddy);
- if (old_icon_num == NULL ||
- strcmp(icon_num_str, old_icon_num))
+ if ((old_icon_num == NULL ||
+ strcmp(icon_num_str, old_icon_num)) && (qq_buddy_icon_dir() != NULL))
{
gchar *icon_path;
@@ -915,21 +902,19 @@ void qq_info_query_free(qq_data *qd)
void qq_info_query_free(qq_data *qd)
{
- gint count;
+ gint i;
qq_info_query *p;
g_return_if_fail(qd != NULL);
- count = 0;
+ i = 0;
while (qd->info_query != NULL) {
p = (qq_info_query *) (qd->info_query->data);
qd->info_query = g_list_remove(qd->info_query, p);
g_free(p);
- count++;
+ i++;
}
- if (count > 0) {
- purple_debug_info("QQ", "%d info queries are freed!\n", count);
- }
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "%d info queries are freed!\n", i);
}
void qq_send_packet_get_level(PurpleConnection *gc, guint32 uid)
@@ -942,10 +927,10 @@ void qq_send_packet_get_level(PurpleConn
bytes += qq_put32(buf + bytes, uid);
qd = (qq_data *) gc->proto_data;
- qq_send_cmd(gc, QQ_CMD_GET_LEVEL, buf, bytes);
+ qq_send_cmd(qd, QQ_CMD_GET_LEVEL, buf, bytes);
}
-void qq_request_get_buddies_levels(PurpleConnection *gc, gint update_class)
+void qq_send_packet_get_buddies_levels(PurpleConnection *gc)
{
guint8 *buf;
guint16 size;
@@ -957,11 +942,12 @@ void qq_request_get_buddies_levels(Purpl
if ( qd->buddies == NULL) {
return;
}
- /* server only reply levels for online buddies */
- size = 4 * g_list_length(qd->buddies) + 1 + 4;
+ /* server only sends back levels for online buddies, no point
+ * in asking for anyone else */
+ size = 4 * g_list_length(qd->buddies) + 1;
buf = g_newa(guint8, size);
bytes += qq_put8(buf + bytes, 0x00);
-
+
while (NULL != node) {
q_bud = (qq_buddy *) node->data;
if (NULL != q_bud) {
@@ -969,10 +955,7 @@ void qq_request_get_buddies_levels(Purpl
}
node = node->next;
}
-
- /* my id should be the end if included */
- bytes += qq_put32(buf + bytes, qd->uid);
- qq_send_cmd_mess(gc, QQ_CMD_GET_LEVEL, buf, size, update_class, 0);
+ qq_send_cmd(qd, QQ_CMD_GET_LEVEL, buf, size);
}
void qq_process_get_level_reply(guint8 *decr_buf, gint decr_len, PurpleConnection *gc)
@@ -987,9 +970,9 @@ void qq_process_get_level_reply(guint8 *
qq_data *qd = (qq_data *) gc->proto_data;
gint bytes = 0;
- decr_len--;
+ decr_len--;
if (decr_len % 12 != 0) {
- purple_debug_error("QQ",
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ",
"Get levels list of abnormal length. Truncating last %d bytes.\n", decr_len % 12);
decr_len -= (decr_len % 12);
}
@@ -997,18 +980,19 @@ void qq_process_get_level_reply(guint8 *
bytes += 1;
/* this byte seems random */
/*
- purple_debug_info("QQ", "Byte one of get_level packet: %d\n", buf[0]);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Byte one of get_level packet: %d\n", buf[0]);
*/
for (i = 0; i < decr_len; i += 12) {
bytes += qq_get32(&uid, decr_buf + bytes);
bytes += qq_get32(&onlineTime, decr_buf + bytes);
bytes += qq_get16(&level, decr_buf + bytes);
bytes += qq_get16(&timeRemainder, decr_buf + bytes);
- purple_debug_info("QQ_LEVEL", "%d, tmOnline: %d, level: %d, tmRemainder: %d\n",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ_LEVEL",
+ "%d, tmOnline: %d, level: %d, tmRemainder: %d\n",
uid, onlineTime, level, timeRemainder);
if (uid == qd->uid) {
qd->my_level = level;
- purple_debug_warning("QQ", "Got my levels as %d\n", qd->my_level);
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Got my levels as %d\n", qd->my_level);
continue;
}
@@ -1016,7 +1000,7 @@ void qq_process_get_level_reply(guint8 *
if (purple_name == NULL) {
continue;
}
-
+
b = purple_find_buddy(account, purple_name);
g_free(purple_name);
@@ -1024,9 +1008,10 @@ void qq_process_get_level_reply(guint8 *
if (b != NULL) {
q_bud = (qq_buddy *) b->proto_data;
}
-
+
if (q_bud == NULL) {
- purple_debug_error("QQ", "Got levels of %d not in my buddy list\n", uid);
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ",
+ "Got levels of %d not in my buddy list\n", uid);
continue;
}
============================================================
--- libpurple/protocols/qq/buddy_info.h 1788934386864124acf1163392f41bea2c5eaad9
+++ libpurple/protocols/qq/buddy_info.h 62ff812350c859993cfed122110108f0d87b0b1b
@@ -51,14 +51,14 @@
#define QQ_FRIEND_FLAG_MOBILE 0x10
#define QQ_FRIEND_FLAG_BIND_MOBILE 0x20
*/
-#define QQ_COMM_FLAG_QQ_VIP 0x02
-#define QQ_COMM_FLAG_QQ_MEMBER 0x04
+#define QQ_COMM_FLAG_QQ_MEMBER 0x02
+#define QQ_COMM_FLAG_QQ_VIP 0x04
#define QQ_COMM_FLAG_TCP_MODE 0x10
#define QQ_COMM_FLAG_MOBILE 0x20
#define QQ_COMM_FLAG_BIND_MOBILE 0x40
#define QQ_COMM_FLAG_VIDEO 0x80
-#define QQ_EXT_FLAG_ZONE 0x02
+#define QQ_EXT_FLAG_SPACE 0x02
#define QQ_BUDDY_GENDER_GG 0x00
#define QQ_BUDDY_GENDER_MM 0x01
@@ -67,15 +67,7 @@
#define QQ_ICON_PREFIX "qq_"
#define QQ_ICON_SUFFIX ".png"
-enum {
- QQ_BUDDY_INFO_UPDATE_ONLY = 0,
- QQ_BUDDY_INFO_DISPLAY,
- QQ_BUDDY_INFO_MODIFY,
-};
-
void qq_send_packet_get_info(PurpleConnection *gc, guint32 uid, gboolean show_window);
-void qq_request_buddy_info(PurpleConnection *gc, guint32 uid,
- gint update_class, guint32 ship32);
void qq_set_my_buddy_icon(PurpleConnection *gc, PurpleStoredImage *img);
void qq_set_buddy_icon_for_user(PurpleAccount *account, const gchar *who, const gchar *icon_num, const gchar *iconfile);
void qq_prepare_modify_info(PurpleConnection *gc);
@@ -83,6 +75,6 @@ void qq_send_packet_get_level(PurpleConn
void qq_process_get_info_reply(guint8 *data, gint data_len, PurpleConnection *gc);
void qq_info_query_free(qq_data *qd);
void qq_send_packet_get_level(PurpleConnection *gc, guint32 uid);
-void qq_request_get_buddies_levels(PurpleConnection *gc, gint update_class);
+void qq_send_packet_get_buddies_levels(PurpleConnection *gc);
void qq_process_get_level_reply(guint8 *buf, gint buf_len, PurpleConnection *gc);
#endif
============================================================
--- libpurple/protocols/qq/buddy_list.c 902dfa24074b09d996a0a2d4ff89b38c00d3e947
+++ libpurple/protocols/qq/buddy_list.c 19f9e2ad310d5eb343b54d6bd41b75019994d0ff
@@ -56,7 +56,7 @@ typedef struct _qq_buddy_online {
} qq_buddy_online;
/* get a list of online_buddies */
-void qq_request_get_buddies_online(PurpleConnection *gc, guint8 position, gint update_class)
+void qq_send_packet_get_buddies_online(PurpleConnection *gc, guint8 position)
{
qq_data *qd;
guint8 *raw_data;
@@ -77,14 +77,15 @@ void qq_request_get_buddies_online(Purpl
/* 003-004 */
bytes += qq_put16(raw_data + bytes, 0x0000);
- qq_send_cmd_mess(gc, QQ_CMD_GET_BUDDIES_ONLINE, raw_data, 5, update_class, 0);
+ qq_send_cmd(qd, QQ_CMD_GET_BUDDIES_ONLINE, raw_data, 5);
qd->last_get_online = time(NULL);
}
-/* position starts with 0x0000,
+/* position starts with 0x0000,
* server may return a position tag if list is too long for one packet */
-void qq_request_get_buddies_list(PurpleConnection *gc, guint16 position, gint update_class)
+void qq_send_packet_get_buddies_list(PurpleConnection *gc, guint16 position)
{
+ qq_data *qd = (qq_data *) gc->proto_data;
guint8 raw_data[16] = {0};
gint bytes = 0;
@@ -97,12 +98,13 @@ void qq_request_get_buddies_list(PurpleC
* March 22, found the 00,00,00 starts to work as well */
bytes += qq_put8(raw_data + bytes, 0x00);
- qq_send_cmd_mess(gc, QQ_CMD_GET_BUDDIES_LIST, raw_data, bytes, update_class, 0);
+ qq_send_cmd(qd, QQ_CMD_GET_BUDDIES_LIST, raw_data, bytes);
}
/* get all list, buddies & Quns with groupsid support */
-void qq_request_get_buddies_and_rooms(PurpleConnection *gc, guint32 position, gint update_class)
+void qq_send_packet_get_buddies_and_rooms(PurpleConnection *gc, guint32 position)
{
+ qq_data *qd = (qq_data *) gc->proto_data;
guint8 raw_data[16] = {0};
gint bytes = 0;
@@ -114,7 +116,7 @@ void qq_request_get_buddies_and_rooms(Pu
bytes += qq_put32(raw_data + bytes, 0x00000000);
bytes += qq_put32(raw_data + bytes, position);
- qq_send_cmd_mess(gc, QQ_CMD_GET_BUDDIES_AND_ROOMS, raw_data, bytes, update_class, 0);
+ qq_send_cmd(qd, QQ_CMD_GET_BUDDIES_AND_ROOMS, raw_data, bytes);
}
/* parse the data into qq_buddy_status */
@@ -144,8 +146,8 @@ static gint get_buddy_status(qq_buddy_st
/* 015-030: unknown key */
bytes += qq_getdata(&(bs->unknown_key[0]), QQ_KEY_LENGTH, data + bytes);
- purple_debug_info("QQ_STATUS",
- "uid: %d, U1: %d, ip: %s:%d, U2:%d, status:%d, U3:%04X\n",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ_STATUS",
+ "uid: %d, U1: %d, ip: %s:%d, U2:%d, status:%d, U3:%04X\n",
bs->uid, bs->unknown1, inet_ntoa(bs->ip), bs->port,
bs->unknown2, bs->status, bs->unknown3);
@@ -178,12 +180,13 @@ guint8 qq_process_get_buddies_online_rep
count = 0;
while (bytes < data_len) {
if (data_len - bytes < QQ_ONLINE_BUDDY_ENTRY_LEN) {
- purple_debug_error("QQ", "[buddies online] only %d, need %d",
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ",
+ "[buddies online] only %d, need %d",
(data_len - bytes), QQ_ONLINE_BUDDY_ENTRY_LEN);
break;
}
memset(&bo, 0 ,sizeof(bo));
-
+
/* set flag */
bytes_buddy = bytes;
/* based on one online buddy entry */
@@ -201,29 +204,31 @@ guint8 qq_process_get_buddies_online_rep
bytes += qq_get8(&bo.ending, data + bytes); /* 0x00 */
if (bo.bs.uid == 0 || (bytes - bytes_buddy) != QQ_ONLINE_BUDDY_ENTRY_LEN) {
- purple_debug_error("QQ", "uid=0 or entry complete len(%d) != %d",
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ",
+ "uid=0 or entry complete len(%d) != %d",
(bytes - bytes_buddy), QQ_ONLINE_BUDDY_ENTRY_LEN);
continue;
} /* check if it is a valid entry */
if (bo.bs.uid == qd->uid) {
- purple_debug_warning("QQ", "I am in online list %d\n", bo.bs.uid);
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ",
+ "I am in online list %d\n", bo.bs.uid);
continue;
}
/* update buddy information */
purple_name = uid_to_purple_name(bo.bs.uid);
if (purple_name == NULL) {
- purple_debug_error("QQ",
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ",
"Got an online buddy %d, but not find purple name\n", bo.bs.uid);
continue;
}
b = purple_find_buddy(purple_connection_get_account(gc), purple_name);
g_free(purple_name);
-
+
q_bud = (b == NULL) ? NULL : (qq_buddy *) b->proto_data;
if (q_bud == NULL) {
- purple_debug_error("QQ",
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ",
"Got an online buddy %d, but not in my buddy list\n", bo.bs.uid);
continue;
}
@@ -242,11 +247,11 @@ guint8 qq_process_get_buddies_online_rep
}
if(bytes > data_len) {
- purple_debug_error("QQ",
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ",
"qq_process_get_buddies_online_reply: Dangerous error! maybe protocol changed, notify developers!\n");
}
- purple_debug_info("QQ", "Received %d online buddies, nextposition=%u\n",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Received %d online buddies, nextposition=%u\n",
count, (guint) position);
return position;
}
@@ -269,7 +274,7 @@ guint16 qq_process_get_buddies_list_repl
qd = (qq_data *) gc->proto_data;
if (data_len <= 2) {
- purple_debug_error("QQ", "empty buddies list");
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ", "empty buddies list");
return -1;
}
/* qq_show_packet("QQ get buddies list", data, data_len); */
@@ -300,7 +305,7 @@ guint16 qq_process_get_buddies_list_repl
bytes_expected = 12 + pascal_len;
if (q_bud->uid == 0 || (bytes - buddy_bytes) != bytes_expected) {
- purple_debug_info("QQ",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
"Buddy entry, expect %d bytes, read %d bytes\n", bytes_expected, bytes - buddy_bytes);
g_free(q_bud->nickname);
g_free(q_bud);
@@ -310,7 +315,7 @@ guint16 qq_process_get_buddies_list_repl
}
#if 1
- purple_debug_info("QQ",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
"buddy [%09d]: ext_flag=0x%02x, comm_flag=0x%02x, nick=%s\n",
q_bud->uid, q_bud->ext_flag, q_bud->comm_flag, q_bud->nickname);
#endif
@@ -329,11 +334,11 @@ guint16 qq_process_get_buddies_list_repl
}
if(bytes > data_len) {
- purple_debug_error("QQ",
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ",
"qq_process_get_buddies_list_reply: Dangerous error! maybe protocol changed, notify developers!");
}
- purple_debug_info("QQ", "Received %d buddies, nextposition=%u\n",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Received %d buddies, nextposition=%u\n",
count, (guint) position);
return position;
}
@@ -359,7 +364,8 @@ guint32 qq_process_get_buddies_and_rooms
bytes += qq_get8(&reply_code, data + bytes);
if(0 != reply_code) {
- purple_debug_warning("QQ", "qq_process_get_buddies_and_rooms, %d", reply_code);
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ",
+ "qq_process_get_buddies_and_rooms, %d", reply_code);
}
bytes += qq_get32(&unknown, data + bytes);
@@ -375,45 +381,48 @@ guint32 qq_process_get_buddies_and_rooms
/* 05: groupid*4 */ /* seems to always be 0 */
bytes += qq_get8(&groupid, data + bytes);
/*
- purple_debug_info("QQ", "groupid: %i\n", groupid);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "groupid: %i\n", groupid);
groupid >>= 2;
*/
if (uid == 0 || (type != 0x1 && type != 0x4)) {
- purple_debug_info("QQ", "Buddy entry, uid=%d, type=%d", uid, type);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ "Buddy entry, uid=%d, type=%d", uid, type);
continue;
- }
+ }
if(0x1 == type) { /* a buddy */
- /* don't do anything but count - buddies are handled by
- * qq_request_get_buddies_list */
+ /* don't do anything but count - buddies are handled by
+ * qq_send_packet_get_buddies_list */
++i;
} else { /* a group */
group = qq_room_search_id(gc, uid);
if(group == NULL) {
- purple_debug_info("QQ",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
"Not find room id %d in qq_process_get_buddies_and_rooms\n", uid);
qq_set_pending_id(&qd->adding_groups_from_server, uid, TRUE);
+ qq_send_room_cmd_only(gc, QQ_ROOM_CMD_GET_INFO, uid);
} else {
- group->my_role = QQ_ROOM_ROLE_YES;
+ group->my_status = QQ_GROUP_MEMBER_STATUS_IS_MEMBER;
qq_group_refresh(gc, group);
+ qq_send_room_cmd_only(gc, QQ_ROOM_CMD_GET_INFO, group->id);
}
++j;
}
}
if(bytes > data_len) {
- purple_debug_error("QQ",
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ",
"qq_process_get_buddies_and_rooms: Dangerous error! maybe protocol changed, notify developers!");
}
- purple_debug_info("QQ", "Received %d buddies and %d groups, nextposition=%u\n", i, j, (guint) position);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Received %d buddies and %d groups, nextposition=%u\n", i, j, (guint) position);
return position;
}
#define QQ_MISC_STATUS_HAVING_VIIDEO 0x00000001
#define QQ_CHANGE_ONLINE_STATUS_REPLY_OK 0x30 /* ASCII value of "0" */
-/* TODO: figure out what's going on with the IP region. Sometimes I get valid IP addresses,
- * but the port number's weird, other times I get 0s. I get these simultaneously on the same buddy,
+/* TODO: figure out what's going on with the IP region. Sometimes I get valid IP addresses,
+ * but the port number's weird, other times I get 0s. I get these simultaneously on the same buddy,
* using different accounts to get info. */
/* check if status means online or offline */
@@ -432,9 +441,9 @@ gint get_icon_offset(PurpleConnection *g
/* Help calculate the correct icon index to tell the server. */
gint get_icon_offset(PurpleConnection *gc)
-{
+{
PurpleAccount *account;
- PurplePresence *presence;
+ PurplePresence *presence;
account = purple_connection_get_account(gc);
presence = purple_account_get_presence(account);
@@ -451,7 +460,7 @@ gint get_icon_offset(PurpleConnection *g
}
/* send a packet to change my online status */
-void qq_request_change_status(PurpleConnection *gc, gint update_class)
+void qq_send_packet_change_status(PurpleConnection *gc)
{
qq_data *qd;
guint8 raw_data[16] = {0};
@@ -460,13 +469,13 @@ void qq_request_change_status(PurpleConn
guint32 misc_status;
gboolean fake_video;
PurpleAccount *account;
- PurplePresence *presence;
+ PurplePresence *presence;
account = purple_connection_get_account(gc);
presence = purple_account_get_presence(account);
qd = (qq_data *) gc->proto_data;
- if (!qd->is_login)
+ if (!qd->logged_in)
return;
if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_INVISIBLE)) {
@@ -488,7 +497,7 @@ void qq_request_change_status(PurpleConn
bytes += qq_put8(raw_data + bytes, away_cmd);
bytes += qq_put32(raw_data + bytes, misc_status);
- qq_send_cmd_mess(gc, QQ_CMD_CHANGE_STATUS, raw_data, bytes, update_class, 0);
+ qq_send_cmd(qd, QQ_CMD_CHANGE_ONLINE_STATUS, raw_data, bytes);
}
/* parse the reply packet for change_status */
@@ -504,15 +513,15 @@ void qq_process_change_status_reply(guin
g_return_if_fail(data != NULL && data_len != 0);
qd = (qq_data *) gc->proto_data;
-
+
bytes = 0;
bytes = qq_get8(&reply, data + bytes);
if (reply != QQ_CHANGE_ONLINE_STATUS_REPLY_OK) {
- purple_debug_warning("QQ", "Change status fail 0x%02X\n", reply);
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Change status fail 0x%02X\n", reply);
return;
}
- /* purple_debug_info("QQ", "Change status OK\n"); */
+ /* purple_debug(PURPLE_DEBUG_INFO, "QQ", "Change status OK\n"); */
name = uid_to_purple_name(qd->uid);
b = purple_find_buddy(gc->account, name);
g_free(name);
@@ -523,7 +532,7 @@ void qq_process_change_status_reply(guin
}
/* it is a server message indicating that one of my buddies has changed its status */
-void qq_process_buddy_change_status(guint8 *data, gint data_len, PurpleConnection *gc)
+void qq_process_buddy_change_status(guint8 *data, gint data_len, PurpleConnection *gc)
{
qq_data *qd;
gint bytes;
@@ -538,16 +547,16 @@ void qq_process_buddy_change_status(guin
qd = (qq_data *) gc->proto_data;
if (data_len < 35) {
- purple_debug_error("QQ", "[buddy status change] only %d, need 35 bytes\n", data_len);
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ", "[buddy status change] only %d, need 35 bytes\n", data_len);
return;
}
-
+
memset(&bs, 0, sizeof(bs));
bytes = 0;
/* 000-030: qq_buddy_status */
bytes += get_buddy_status(&bs, data + bytes);
- /* 031-034: Unknow, maybe my uid */
- /* This has a value of 0 when we've changed our status to
+ /* 031-034: Unknow, maybe my uid */
+ /* This has a value of 0 when we've changed our status to
* QQ_BUDDY_ONLINE_INVISIBLE */
bytes += qq_get32(&my_uid, data + bytes);
@@ -556,13 +565,13 @@ void qq_process_buddy_change_status(guin
g_free(name);
q_bud = (b == NULL) ? NULL : (qq_buddy *) b->proto_data;
if (q_bud == NULL) {
- purple_debug_error("QQ",
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ",
"got information of unknown buddy %d\n", bs.uid);
return;
}
- purple_debug_info("QQ", "status:.uid = %d, q_bud->uid = %d\n", bs.uid , q_bud->uid);
- if(bs.ip.s_addr != 0) {
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "status:.uid = %d, q_bud->uid = %d\n", bs.uid , q_bud->uid);
+ if(bs.ip.s_addr != 0) {
q_bud->ip.s_addr = bs.ip.s_addr;
q_bud->port = bs.port;
}
@@ -580,24 +589,24 @@ void qq_update_buddy_contact(PurpleConne
gchar *purple_name;
PurpleBuddy *bud;
gchar *status_id;
-
+
g_return_if_fail(q_bud != NULL);
purple_name = uid_to_purple_name(q_bud->uid);
if (purple_name == NULL) {
- purple_debug_error("QQ", "Not find purple name: %d\n", q_bud->uid);
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Not find purple name: %d\n", q_bud->uid);
return;
}
bud = purple_find_buddy(gc->account, purple_name);
if (bud == NULL) {
- purple_debug_error("QQ", "Not find buddy: %d\n", q_bud->uid);
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Not find buddy: %d\n", q_bud->uid);
g_free(purple_name);
return;
}
-
+
purple_blist_server_alias_buddy(bud, q_bud->nickname); /* server */
- q_bud->last_update = time(NULL);
+ q_bud->last_refresh = time(NULL);
/* purple supports signon and idle time
* but it is not much use for QQ, I do not use them */
@@ -621,10 +630,10 @@ void qq_update_buddy_contact(PurpleConne
break;
default:
status_id = "invisible";
- purple_debug_error("QQ", "unknown status: %x\n", q_bud->status);
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ", "unknown status: %x\n", q_bud->status);
break;
}
- purple_debug_info("QQ", "buddy %d %s\n", q_bud->uid, status_id);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "buddy %d %s\n", q_bud->uid, status_id);
purple_prpl_got_user_status(gc->account, purple_name, status_id, NULL);
if (q_bud->comm_flag & QQ_COMM_FLAG_MOBILE && q_bud->status != QQ_BUDDY_OFFLINE)
@@ -655,7 +664,7 @@ void qq_refresh_all_buddy_status(PurpleC
while (list != NULL) {
q_bud = (qq_buddy *) list->data;
- if (q_bud != NULL && now > q_bud->last_update + QQ_UPDATE_ONLINE_INTERVAL
+ if (q_bud != NULL && now > q_bud->last_refresh + QQ_UPDATE_ONLINE_INTERVAL
&& q_bud->status != QQ_BUDDY_ONLINE_INVISIBLE) {
q_bud->status = QQ_BUDDY_ONLINE_OFFLINE;
qq_update_buddy_contact(gc, q_bud);
============================================================
--- libpurple/protocols/qq/buddy_list.h 794a9c7da4eb380f57107828529a94d654afc3db
+++ libpurple/protocols/qq/buddy_list.h d69cbb9b2e26383154467b6d47cacbe6d38eb005
@@ -42,19 +42,19 @@ enum {
enum {
QQ_BUDDY_OFFLINE = 0x00,
- QQ_BUDDY_ONLINE_NORMAL = 10,
- QQ_BUDDY_ONLINE_OFFLINE = 20,
- QQ_BUDDY_ONLINE_AWAY = 30,
- QQ_BUDDY_ONLINE_INVISIBLE = 40
+ QQ_BUDDY_ONLINE_NORMAL = 0x0a,
+ QQ_BUDDY_ONLINE_OFFLINE = 0x14,
+ QQ_BUDDY_ONLINE_AWAY = 0x1e,
+ QQ_BUDDY_ONLINE_INVISIBLE = 0x28
};
-void qq_request_get_buddies_online(PurpleConnection *gc, guint8 position, gint update_class);
+void qq_send_packet_get_buddies_online(PurpleConnection *gc, guint8 position);
guint8 qq_process_get_buddies_online_reply(guint8 *data, gint data_len, PurpleConnection *gc);
-void qq_request_get_buddies_list(PurpleConnection *gc, guint16 position, gint update_class);
+void qq_send_packet_get_buddies_list(PurpleConnection *gc, guint16 position);
guint16 qq_process_get_buddies_list_reply(guint8 *data, gint data_len, PurpleConnection *gc);
-void qq_request_get_buddies_and_rooms(PurpleConnection *gc, guint32 position, gint update_class);
+void qq_send_packet_get_buddies_and_rooms(PurpleConnection *gc, guint32 position);
guint32 qq_process_get_buddies_and_rooms(guint8 *data, gint data_len, PurpleConnection *gc);
void qq_refresh_all_buddy_status(PurpleConnection *gc);
@@ -63,7 +63,7 @@ gint get_icon_offset(PurpleConnection *g
gint get_icon_offset(PurpleConnection *gc);
-void qq_request_change_status(PurpleConnection *gc, gint update_class);
+void qq_send_packet_change_status(PurpleConnection *gc);
void qq_process_change_status_reply(guint8 *data, gint data_len, PurpleConnection *gc);
void qq_process_buddy_change_status(guint8 *data, gint data_len, PurpleConnection *gc);
============================================================
--- libpurple/protocols/qq/buddy_opt.c 17be05a5e83a7c2dc34c5e332950e77304837fb7
+++ libpurple/protocols/qq/buddy_opt.c d19581650142be4fa3db797f2ca04efae553818e
@@ -60,17 +60,19 @@ static void _qq_send_packet_remove_buddy
/* send packet to remove a buddy from my buddy list */
static void _qq_send_packet_remove_buddy(PurpleConnection *gc, guint32 uid)
{
+ qq_data *qd = (qq_data *) gc->proto_data;
gchar uid_str[11];
g_return_if_fail(uid > 0);
g_snprintf(uid_str, sizeof(uid_str), "%d", uid);
- qq_send_cmd(gc, QQ_CMD_DEL_BUDDY, (guint8 *) uid_str, strlen(uid_str));
+ qq_send_cmd(qd, QQ_CMD_DEL_BUDDY, (guint8 *) uid_str, strlen(uid_str));
}
/* try to remove myself from someone's buddy list */
static void _qq_send_packet_remove_self_from(PurpleConnection *gc, guint32 uid)
{
+ qq_data *qd = (qq_data *) gc->proto_data;
guint8 raw_data[16] = {0};
gint bytes = 0;
@@ -78,7 +80,7 @@ static void _qq_send_packet_remove_self_
bytes += qq_put32(raw_data + bytes, uid);
- qq_send_cmd(gc, QQ_CMD_REMOVE_SELF, raw_data, bytes);
+ qq_send_cmd(qd, QQ_CMD_REMOVE_SELF, raw_data, bytes);
}
/* try to add a buddy without authentication */
@@ -92,7 +94,7 @@ static void _qq_send_packet_add_buddy(Pu
/* we need to send the ascii code of this uid to qq server */
g_snprintf(uid_str, sizeof(uid_str), "%d", uid);
- qq_send_cmd(gc, QQ_CMD_ADD_BUDDY_WO_AUTH, (guint8 *) uid_str, strlen(uid_str));
+ qq_send_cmd(qd, QQ_CMD_ADD_BUDDY_WO_AUTH, (guint8 *) uid_str, strlen(uid_str));
/* must be set after sending packet to get the correct send_seq */
req = g_new0(qq_add_buddy_request, 1);
@@ -104,6 +106,7 @@ static void _qq_send_packet_buddy_auth(P
/* this buddy needs authentication, text conversion is done at lowest level */
static void _qq_send_packet_buddy_auth(PurpleConnection *gc, guint32 uid, const gchar response, const gchar *text)
{
+ qq_data *qd = (qq_data *) gc->proto_data;
gchar *text_qq, uid_str[11];
guint8 bar, *raw_data;
gint bytes = 0;
@@ -125,7 +128,7 @@ static void _qq_send_packet_buddy_auth(P
g_free(text_qq);
}
- qq_send_cmd(gc, QQ_CMD_BUDDY_AUTH, raw_data, bytes);
+ qq_send_cmd(qd, QQ_CMD_BUDDY_AUTH, raw_data, bytes);
}
static void _qq_send_packet_add_buddy_auth_with_gc_and_uid(gc_and_uid *g, const gchar *text)
@@ -201,11 +204,11 @@ void qq_reject_add_request_with_gc_and_u
g2->uid = uid;
msg1 = g_strdup_printf(_("You rejected %d's request"), uid);
- msg2 = g_strdup(_("Message:"));
+ msg2 = g_strdup(_("Input your reason:"));
nombre = uid_to_purple_name(uid);
purple_request_input(gc, _("Reject request"), msg1, msg2,
- _("Sorry, you are not my style..."), TRUE, FALSE,
+ _("Sorry, you are not my type..."), TRUE, FALSE,
NULL, _("Reject"), G_CALLBACK(_qq_reject_add_request_real), _("Cancel"), NULL,
purple_connection_get_account(gc), nombre, NULL,
g2);
@@ -258,7 +261,7 @@ void qq_process_add_buddy_auth_reply(gui
qd = (qq_data *) gc->proto_data;
if (data[0] != QQ_ADD_BUDDY_AUTH_REPLY_OK) {
- purple_debug_warning("QQ", "Add buddy with auth request failed\n");
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Add buddy with auth request failed\n");
if (NULL == (segments = split_data(data, data_len, "\x1f", 2))) {
return;
}
@@ -266,7 +269,7 @@ void qq_process_add_buddy_auth_reply(gui
purple_notify_error(gc, NULL, _("Add buddy with auth request failed"), msg_utf8);
g_free(msg_utf8);
} else {
- purple_debug_info("QQ", "Add buddy with auth request OK\n");
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Add buddy with auth request OK\n");
}
}
@@ -281,16 +284,16 @@ void qq_process_remove_buddy_reply(guint
if (data[0] != QQ_REMOVE_BUDDY_REPLY_OK) {
/* there is no reason return from server */
- purple_debug_warning("QQ", "Remove buddy fails\n");
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Remove buddy fails\n");
} else { /* if reply */
- purple_debug_info("QQ", "Remove buddy OK\n");
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Remove buddy OK\n");
/* TODO: We don't really need to notify the user about this, do we? */
purple_notify_info(gc, NULL, _("You have successfully removed a buddy"), NULL);
}
}
/* process the server reply for my request to remove myself from a buddy */
-void qq_process_remove_self_reply(guint8 *data, gint data_len, PurpleConnection *gc)
+void qq_process_remove_self_reply(guint8 *data, gint data_len, PurpleConnection *gc)
{
qq_data *qd;
@@ -300,12 +303,11 @@ void qq_process_remove_self_reply(guint8
if (data[0] != QQ_REMOVE_SELF_REPLY_OK) {
/* there is no reason return from server */
- purple_debug_warning("QQ", "Remove self fails\n");
- purple_notify_info(gc, NULL, _("Failed removing from friend's buddy list"), NULL);
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Remove self fails\n");
} else { /* if reply */
- purple_debug_info("QQ", "Remove from a buddy OK\n");
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Remove self from a buddy OK\n");
/* TODO: Does the user really need to be notified about this? */
- purple_notify_info(gc, NULL, _("Successed removing from friend's buddy list"), NULL);
+ purple_notify_info(gc, NULL, _("You have successfully removed yourself from your friend's buddy list"), NULL);
}
}
@@ -338,25 +340,25 @@ void qq_process_add_buddy_reply(guint8 *
}
if (for_uid == 0) { /* we have no record for this */
- purple_debug_error("QQ", "We have no record for add buddy reply [%d], discard\n", seq);
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ", "We have no record for add buddy reply [%d], discard\n", seq);
return;
} else {
- purple_debug_info("QQ", "Add buddy reply [%d] is for id [%d]\n", seq, for_uid);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Add buddy reply [%d] is for id [%d]\n", seq, for_uid);
}
if (NULL == (segments = split_data(data, data_len, "\x1f", 2)))
return;
-
+
uid = segments[0];
reply = segments[1];
if (strtol(uid, NULL, 10) != qd->uid) { /* should not happen */
- purple_debug_error("QQ", "Add buddy reply is to [%s], not me!", uid);
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Add buddy reply is to [%s], not me!", uid);
g_strfreev(segments);
return;
}
if (strtol(reply, NULL, 10) > 0) { /* need auth */
- purple_debug_warning("QQ", "Add buddy attempt fails, need authentication\n");
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Add buddy attempt fails, need authentication\n");
nombre = uid_to_purple_name(for_uid);
b = purple_find_buddy(gc->account, nombre);
if (b != NULL)
@@ -364,7 +366,7 @@ void qq_process_add_buddy_reply(guint8 *
g = g_new0(gc_and_uid, 1);
g->gc = gc;
g->uid = for_uid;
- msg = g_strdup_printf(_("%d needs authentication"), for_uid);
+ msg = g_strdup_printf(_("User %d needs authentication"), for_uid);
purple_request_input(gc, NULL, msg,
_("Input request here"), /* TODO: Awkward string to fix post string freeze - standardize auth dialogues? -evands */
_("Would you be my friend?"),
@@ -395,7 +397,7 @@ PurpleGroup *qq_get_purple_group(const g
if (g == NULL) {
g = purple_group_new(group_name);
purple_blist_add_group(g, NULL);
- purple_debug_warning("QQ", "Add new group: %s\n", group_name);
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Add new group: %s\n", group_name);
}
return g;
@@ -438,11 +440,11 @@ PurpleBuddy *qq_add_buddy_by_recv_packet
b->proto_data = q_bud;
qd->buddies = g_list_append(qd->buddies, q_bud);
qq_send_packet_get_info(gc, q_bud->uid, FALSE);
- qq_request_get_buddies_online(gc, 0, 0);
+ qq_send_packet_get_buddies_online(gc, 0);
}
purple_blist_add_buddy(b, NULL, g, NULL);
- purple_debug_warning("QQ", "Add new buddy: [%s]\n", name);
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Add new buddy: [%s]\n", name);
g_free(name);
g_free(group_name);
@@ -452,8 +454,8 @@ PurpleBuddy *qq_add_buddy_by_recv_packet
/* 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 serv_finish_login(gc) */
+ * it also calls this funtion, so we have to
+ * define qd->logged_in=TRUE AFTER serv_finish_login(gc) */
void qq_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
{
qq_data *qd;
@@ -461,7 +463,7 @@ void qq_add_buddy(PurpleConnection *gc,
PurpleBuddy *b;
qd = (qq_data *) gc->proto_data;
- if (!qd->is_login)
+ if (!qd->logged_in)
return; /* IMPORTANT ! */
uid = purple_name_to_uid(buddy->name);
@@ -472,8 +474,8 @@ void qq_add_buddy(PurpleConnection *gc,
if (b != NULL)
purple_blist_remove_buddy(b);
purple_notify_error(gc, NULL,
- _("QQ Number Error"),
- _("Invalid QQ Number"));
+ _("QQid Error"),
+ _("Invalid QQid"));
}
}
@@ -488,7 +490,7 @@ void qq_remove_buddy(PurpleConnection *g
qd = (qq_data *) gc->proto_data;
uid = purple_name_to_uid(buddy->name);
- if (!qd->is_login)
+ if (!qd->logged_in)
return;
if (uid > 0)
@@ -500,7 +502,7 @@ void qq_remove_buddy(PurpleConnection *g
if (q_bud != NULL)
qd->buddies = g_list_remove(qd->buddies, q_bud);
else
- purple_debug_warning("QQ", "We have no qq_buddy record for %s\n", buddy->name);
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ", "We have no qq_buddy record for %s\n", buddy->name);
/* remove buddy on blist, this does not trigger qq_remove_buddy again
* do this only if the request comes from block request,
* otherwise purple segmentation fault */
@@ -512,45 +514,41 @@ void qq_add_buddy_request_free(qq_data *
/* free add buddy request queue */
void qq_add_buddy_request_free(qq_data *qd)
{
- gint count;
+ gint i;
qq_add_buddy_request *p;
- count = 0;
- while (qd->add_buddy_request != NULL) {
+ i = 0;
+ while (qd->add_buddy_request) {
p = (qq_add_buddy_request *) (qd->add_buddy_request->data);
qd->add_buddy_request = g_list_remove(qd->add_buddy_request, p);
g_free(p);
- count++;
+ i++;
}
- if (count > 0) {
- purple_debug_info("QQ", "%d add buddy requests are freed!\n", count);
- }
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "%d add buddy requests are freed!\n", i);
}
/* free up all qq_buddy */
void qq_buddies_list_free(PurpleAccount *account, qq_data *qd)
{
- gint count;
+ gint i;
qq_buddy *p;
gchar *name;
PurpleBuddy *b;
- count = 0;
+ i = 0;
while (qd->buddies) {
p = (qq_buddy *) (qd->buddies->data);
qd->buddies = g_list_remove(qd->buddies, p);
name = uid_to_purple_name(p->uid);
- b = purple_find_buddy(account, name);
- if(b != NULL)
+ b = purple_find_buddy(account, name);
+ if(b != NULL)
b->proto_data = NULL;
else
- purple_debug_info("QQ", "qq_buddy %s not found in purple proto_data\n", name);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "qq_buddy %s not found in purple proto_data\n", name);
g_free(name);
g_free(p);
- count++;
+ i++;
}
- if (count > 0) {
- purple_debug_info("QQ", "%d qq_buddy structures are freed!\n", count);
- }
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "%d qq_buddy structures are freed!\n", i);
}
============================================================
--- libpurple/protocols/qq/char_conv.c 5ab4d96c8a4512a964b50263e2fd8588ecc37dc0
+++ libpurple/protocols/qq/char_conv.c 56df688312bd04d8a02cd864840335c7ee7a0f06
@@ -113,7 +113,7 @@ static gchar *_my_convert(const gchar *s
}
/* conversion error */
- purple_debug_error("QQ_CONVERT", "%s\n", error->message);
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ_CONVERT", "%s\n", error->message);
qq_hex_dump(PURPLE_DEBUG_WARNING, "QQ_CONVERT",
(guint8 *) str, (len == -1) ? strlen(str) : len,
@@ -182,7 +182,7 @@ gchar *qq_encode_to_purple(guint8 *data,
g_string_append_printf(encoded,
"<font color=\"%s\"><font face=\"%s\"><font size=\"%d\">",
color_code, font_name, font_size / 3);
- purple_debug_info("QQ_MESG",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ_MESG",
"recv <font color=\"%s\"><font face=\"%s\"><font size=\"%d\">\n",
color_code, font_name, font_size / 3);
g_string_append(encoded, msg_utf8);
============================================================
--- libpurple/protocols/qq/file_trans.c 2775840f1f4b59ea87cddfc4d8a71b825f1ecd3a
+++ libpurple/protocols/qq/file_trans.c 6f016b37ef0b595dc8e1aa75c2177636c4eadba7
@@ -22,6 +22,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
+#ifdef _WIN32
+#define random rand
+#endif
+
#include "internal.h"
#include "debug.h"
@@ -58,7 +62,7 @@ static guint32 _gen_file_key(void)
{
guint8 seed;
- seed = rand() & 0xFF;
+ seed = random();
return _get_file_key(seed);
}
@@ -257,7 +261,7 @@ static gint _qq_send_file(PurpleConnecti
if (bytes == len + 12) {
_qq_xfer_write(raw_data, bytes, qd->xfer);
} else
- purple_debug_info("QQ", "send_file: want %d but got %d\n", len + 12, bytes);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "send_file: want %d but got %d\n", len + 12, bytes);
return bytes;
}
@@ -319,13 +323,13 @@ void qq_send_file_ctl_packet(PurpleConne
bytes_expected = 61;
break;
default:
- purple_debug_info("QQ", "qq_send_file_ctl_packet: Unknown packet type[%d]\n",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "qq_send_file_ctl_packet: Unknown packet type[%d]\n",
packet_type);
bytes_expected = 0;
}
if (bytes != bytes_expected) {
- purple_debug_error("QQ", "qq_send_file_ctl_packet: Expected to get %d bytes, but get %d",
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ", "qq_send_file_ctl_packet: Expected to get %d bytes, but get %d",
bytes_expected, bytes);
return;
}
@@ -342,24 +346,24 @@ void qq_send_file_ctl_packet(PurpleConne
guint8 *buf;
int buflen;
hex_dump = hex_dump_to_str(encrypted_data, encrypted_len);
- purple_debug_info("QQ", "encrypted packet: \n%s", hex_dump);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "encrypted packet: \n%s", hex_dump);
g_free(hex_dump);
buf = g_newa(guint8, MAX_PACKET_SIZE);
buflen = encrypted_len;
if (qq_crypt(DECRYPT, encrypted_data, encrypted_len, info->file_session_key, buf, &buflen)) {
- purple_debug_info("QQ", "decrypt success\n");
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "decrypt success\n");
if (buflen == bytes && memcmp(raw_data, buf, buflen) == 0)
- purple_debug_info("QQ", "checksum ok\n");
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "checksum ok\n");
hex_dump = hex_dump_to_str(buf, buflen);
- purple_debug_info("QQ", "decrypted packet: \n%s", hex_dump);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "decrypted packet: \n%s", hex_dump);
g_free(hex_dump);
} else {
- purple_debug_info("QQ", "decrypt fail\n");
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "decrypt fail\n");
}
#endif
- purple_debug_info("QQ", "<== send %s packet\n", qq_get_file_cmd_desc(packet_type));
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "<== send %s packet\n", qq_get_file_cmd_desc(packet_type));
_qq_send_file(gc, encrypted_data, encrypted_len, QQ_FILE_CONTROL_PACKET_TAG, info->to_uid);
}
@@ -406,7 +410,7 @@ static void _qq_send_file_data_packet(Pu
info->fragment_num = (filesize - 1) / QQ_FILE_FRAGMENT_MAXLEN + 1;
info->fragment_len = QQ_FILE_FRAGMENT_MAXLEN;
- purple_debug_info("QQ",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
"start transfering data, %d fragments with %d length each\n",
info->fragment_num, info->fragment_len);
/* Unknown */
@@ -431,7 +435,7 @@ static void _qq_send_file_data_packet(Pu
filename_len);
break;
case QQ_FILE_DATA_INFO:
- purple_debug_info("QQ",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
"sending %dth fragment with length %d, offset %d\n",
fragment_index, len, (fragment_index-1)*fragment_size);
/* bytes += qq_put16(raw_data + bytes, ++(qd->send_seq)); */
@@ -444,7 +448,7 @@ static void _qq_send_file_data_packet(Pu
bytes += qq_putdata(raw_data + bytes, data, len);
break;
case QQ_FILE_EOF:
- purple_debug_info("QQ", "end of sending data\n");
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "end of sending data\n");
/* bytes += qq_put16(raw_data + bytes, info->fragment_num + 1); */
bytes += qq_put16(raw_data + bytes, info->fragment_num);
bytes += qq_put8(raw_data + bytes, sub_type);
@@ -470,7 +474,7 @@ static void _qq_send_file_data_packet(Pu
break;
}
}
- purple_debug_info("QQ", "<== send %s packet\n", qq_get_file_cmd_desc(packet_type));
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "<== send %s packet\n", qq_get_file_cmd_desc(packet_type));
_qq_send_file(gc, raw_data, bytes, QQ_FILE_DATA_PACKET_TAG, info->to_uid);
}
@@ -512,7 +516,7 @@ static void _qq_process_recv_file_ctl_pa
decrypted_data = g_newa(guint8, data_len);
decrypted_len = qq_decrypt(decrypted_data, data, data_len, qd->session_md5);
if ( decrypted_len <= 0 ) {
- purple_debug_error("QQ", "Error decrypt rcv file ctrl packet\n");
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Error decrypt rcv file ctrl packet\n");
return;
}
@@ -522,7 +526,7 @@ static void _qq_process_recv_file_ctl_pa
decryped_bytes += qq_get16(&seq, decrypted_data + decryped_bytes);
decryped_bytes += 4+1+1+19+1; /* skip something */
- purple_debug_info("QQ", "==> [%d] receive %s packet\n", seq, qq_get_file_cmd_desc(packet_type));
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "==> [%d] receive %s packet\n", seq, qq_get_file_cmd_desc(packet_type));
qq_hex_dump(PURPLE_DEBUG_INFO, "QQ",
decrypted_data, decrypted_len,
"decrypted control packet received:");
@@ -562,7 +566,7 @@ static void _qq_process_recv_file_ctl_pa
qq_send_file_ctl_packet(gc, QQ_FILE_CMD_SENDER_SAY_HELLO, fh.sender_uid, 0);
break;
default:
- purple_debug_info("QQ", "unprocess file command %d\n", packet_type);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "unprocess file command %d\n", packet_type);
}
}
@@ -573,7 +577,7 @@ static void _qq_recv_file_progess(Purple
ft_info *info = (ft_info *) xfer->data;
guint32 mask;
- purple_debug_info("QQ",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
"receiving %dth fragment with length %d, slide window status %o, max_fragment_index %d\n",
index, len, info->window, info->max_fragment_index);
if (info->window == 0 && info->max_fragment_index == 0) {
@@ -581,11 +585,11 @@ static void _qq_recv_file_progess(Purple
purple_xfer_cancel_local(xfer);
return;
}
- purple_debug_info("QQ", "object file opened for writing\n");
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "object file opened for writing\n");
}
mask = 0x1 << (index % sizeof(info->window));
if (index < info->max_fragment_index || (info->window & mask)) {
- purple_debug_info("QQ", "duplicate %dth fragment, drop it!\n", index+1);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "duplicate %dth fragment, drop it!\n", index+1);
return;
}
@@ -605,7 +609,7 @@ static void _qq_recv_file_progess(Purple
if (mask & 0x8000) mask = 0x0001;
else mask = mask << 1;
}
- purple_debug_info("QQ", "procceed %dth fragment, slide window status %o, max_fragment_index %d\n",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "procceed %dth fragment, slide window status %o, max_fragment_index %d\n",
index, info->window, info->max_fragment_index);
}
@@ -650,12 +654,12 @@ static void _qq_update_send_progess(Purp
PurpleXfer *xfer = qd->xfer;
ft_info *info = (ft_info *) xfer->data;
- purple_debug_info("QQ",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
"receiving %dth fragment ack, slide window status %o, max_fragment_index %d\n",
fragment_index, info->window, info->max_fragment_index);
if (fragment_index < info->max_fragment_index ||
fragment_index >= info->max_fragment_index + sizeof(info->window)) {
- purple_debug_info("QQ", "duplicate %dth fragment, drop it!\n", fragment_index+1);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "duplicate %dth fragment, drop it!\n", fragment_index+1);
return;
}
mask = 0x1 << (fragment_index % sizeof(info->window));
@@ -692,7 +696,7 @@ static void _qq_update_send_progess(Purp
else mask = mask << 1;
}
}
- purple_debug_info("QQ",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
"procceed %dth fragment ack, slide window status %o, max_fragment_index %d\n",
fragment_index, info->window, info->max_fragment_index);
}
@@ -733,7 +737,7 @@ static void _qq_process_recv_file_data(P
info->max_fragment_index = 0;
info->window = 0;
- purple_debug_info("QQ",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
"start receiving data, %d fragments with %d length each\n",
info->fragment_num, info->fragment_len);
_qq_send_file_data_packet(gc, QQ_FILE_CMD_FILE_OP_ACK, sub_type,
@@ -743,7 +747,7 @@ static void _qq_process_recv_file_data(P
bytes += qq_get32(&fragment_index, data + bytes);
bytes += qq_get32(&fragment_offset, data + bytes);
bytes += qq_get16(&fragment_len, data + bytes);
- purple_debug_info("QQ",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
"received %dth fragment with length %d, offset %d\n",
fragment_index, fragment_len, fragment_offset);
@@ -752,7 +756,7 @@ static void _qq_process_recv_file_data(P
_qq_recv_file_progess(gc, data + bytes, fragment_len, fragment_index, fragment_offset);
break;
case QQ_FILE_EOF:
- purple_debug_info("QQ", "end of receiving\n");
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "end of receiving\n");
_qq_send_file_data_packet(gc, QQ_FILE_CMD_FILE_OP_ACK, sub_type,
0, 0, NULL, 0);
break;
@@ -791,11 +795,11 @@ static void _qq_process_recv_file_data(P
purple_xfer_end(qd->xfer);
break;
case QQ_FILE_BASIC_INFO:
- purple_debug_info("QQ", "here\n");
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "here\n");
_qq_send_file_data_packet(gc, QQ_FILE_DATA_INFO, 0, 0, 0, NULL, 0);
break;
default:
- purple_debug_info("QQ", "_qq_process_recv_file_data: unknown packet type [%d]\n",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "_qq_process_recv_file_data: unknown packet type [%d]\n",
packet_type);
break;
}
@@ -820,6 +824,6 @@ void qq_process_recv_file(PurpleConnecti
_qq_process_recv_file_data(gc, data + bytes, len - bytes);
break;
default:
- purple_debug_info("QQ", "unknown packet tag");
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "unknown packet tag");
}
}
============================================================
--- libpurple/protocols/qq/group.c b63a859e4c351c158e6a89d580e3f27d8c274c59
+++ libpurple/protocols/qq/group.c a3e4159f84756290c5fa166286e2f5353db574a4
@@ -64,7 +64,7 @@ GList *qq_chat_info(PurpleConnection *gc
pce = g_new0(struct proto_chat_entry, 1);
pce->label = _("ID: ");
- pce->identifier = QQ_ROOM_KEY_EXTERNAL_ID;
+ pce->identifier = QQ_GROUP_KEY_EXTERNAL_ID;
m = g_list_append(m, pce);
return m;
@@ -77,7 +77,7 @@ GHashTable *qq_chat_info_defaults(Purple
defaults = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free);
if (chat_name != NULL)
- g_hash_table_insert(defaults, QQ_ROOM_KEY_EXTERNAL_ID, g_strdup(chat_name));
+ g_hash_table_insert(defaults, QQ_GROUP_KEY_EXTERNAL_ID, g_strdup(chat_name));
return defaults;
}
@@ -96,30 +96,30 @@ PurpleRoomlist *qq_roomlist_get_list(Pur
rl = purple_roomlist_new(purple_connection_get_account(gc));
qd->roomlist = rl;
- f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, _("Group ID"), QQ_ROOM_KEY_EXTERNAL_ID, FALSE);
+ f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, _("Group ID"), QQ_GROUP_KEY_EXTERNAL_ID, FALSE);
fields = g_list_append(fields, f);
- f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, _("Creator"), QQ_ROOM_KEY_CREATOR_UID, FALSE);
+ f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, _("Creator"), QQ_GROUP_KEY_CREATOR_UID, FALSE);
fields = g_list_append(fields, f);
f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING,
- _("Group Description"), QQ_ROOM_KEY_DESC_UTF8, FALSE);
+ _("Group Description"), QQ_GROUP_KEY_GROUP_DESC_UTF8, FALSE);
fields = g_list_append(fields, f);
- f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", QQ_ROOM_KEY_INTERNAL_ID, TRUE);
+ f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", QQ_GROUP_KEY_INTERNAL_ID, TRUE);
fields = g_list_append(fields, f);
- f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", QQ_ROOM_KEY_TYPE, TRUE);
+ f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", QQ_GROUP_KEY_TYPE, TRUE);
fields = g_list_append(fields, f);
- f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, _("Auth"), QQ_ROOM_KEY_AUTH_TYPE, TRUE);
+ f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, _("Auth"), QQ_GROUP_KEY_AUTH_TYPE, TRUE);
fields = g_list_append(fields, f);
- f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", QQ_ROOM_KEY_CATEGORY, TRUE);
+ f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", QQ_GROUP_KEY_GROUP_CATEGORY, TRUE);
fields = g_list_append(fields, f);
- f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", QQ_ROOM_KEY_TITLE_UTF8, TRUE);
+ f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", QQ_GROUP_KEY_GROUP_NAME_UTF8, TRUE);
fields = g_list_append(fields, f);
purple_roomlist_set_fields(rl, fields);
purple_roomlist_set_in_progress(qd->roomlist, TRUE);
purple_request_input(gc, _("QQ Qun"),
- _("Please enter Qun number"),
- _("You can only search for permanent Qun\n"),
+ _("Please enter external group ID"),
+ _("You can only search for permanent QQ groups\n"),
NULL, FALSE, FALSE, NULL,
_("Search"), G_CALLBACK(_qq_group_search_callback),
_("Cancel"), G_CALLBACK(_qq_group_search_cancel_callback),
@@ -157,7 +157,7 @@ void qq_group_init(PurpleConnection *gc)
purple_group = purple_find_group(PURPLE_GROUP_QQ_QUN);
if (purple_group == NULL) {
- purple_debug_info("QQ", "We have no QQ Qun\n");
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "We have no QQ Qun\n");
return;
}
@@ -178,7 +178,8 @@ void qq_group_init(PurpleConnection *gc)
continue;
count++;
+ qq_send_room_cmd_only(gc, QQ_ROOM_CMD_GET_INFO, group->id);
}
- purple_debug_info("QQ", "Load %d QQ Qun configurations\n", count);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Load %d QQ Qun configurations\n", count);
}
============================================================
--- libpurple/protocols/qq/group.h 138edcd1acfee105682a012c88f97c552670320b
+++ libpurple/protocols/qq/group.h 6d3c438063856a59dbc1f546de3e30ed96373e61
@@ -34,27 +34,27 @@ typedef enum {
#define PURPLE_GROUP_QQ_QUN "QQ 群"
typedef enum {
- QQ_ROOM_ROLE_NO = 0x00, /* default 0x00 means not member */
- QQ_ROOM_ROLE_YES,
- QQ_ROOM_ROLE_REQUESTING,
- QQ_ROOM_ROLE_ADMIN,
-} qq_room_role;
+ QQ_GROUP_MEMBER_STATUS_NOT_MEMBER = 0x00, /* default 0x00 means not member */
+ QQ_GROUP_MEMBER_STATUS_IS_MEMBER,
+ QQ_GROUP_MEMBER_STATUS_APPLYING,
+ QQ_GROUP_MEMBER_STATUS_IS_ADMIN,
+} qq_group_member_status;
typedef struct _qq_group {
/* all these will be saved when we exit Purple */
- qq_room_role my_role; /* my role for this room */
- gchar *my_role_desc; /* my role description */
+ qq_group_member_status my_status; /* my status for this group */
+ gchar *my_status_desc; /* my status description */
guint32 id;
guint32 ext_id;
guint8 type8; /* permanent or temporory */
guint32 creator_uid;
- guint32 category;
+ guint32 group_category;
guint8 auth_type;
- gchar *title_utf8;
- gchar *desc_utf8;
+ gchar *group_name_utf8;
+ gchar *group_desc_utf8;
/* all these will be loaded from the network */
gchar *notice_utf8; /* group notice by admin */
- GList *members;
+ GList *members;
} qq_group;
GList *qq_chat_info(PurpleConnection *gc);
============================================================
--- libpurple/protocols/qq/group_conv.c e1a84ee06d272314ac5e9a7881414143368bc618
+++ libpurple/protocols/qq/group_conv.c a98dc976b1feae948a46b3b27d97234555cb5d70
@@ -41,9 +41,9 @@ void qq_group_conv_show_window(PurpleCon
qd = (qq_data *) gc->proto_data;
conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
- group->title_utf8, purple_connection_get_account(gc));
+ group->group_name_utf8, purple_connection_get_account(gc));
if (conv == NULL) /* show only one window per group */
- serv_got_joined_chat(gc, qd->channel++, group->title_utf8);
+ serv_got_joined_chat(gc, qd->channel++, group->group_name_utf8);
}
/* refresh online member in group conversation window */
@@ -59,7 +59,7 @@ void qq_group_conv_refresh_online_member
names = NULL;
flags = NULL;
conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
- group->title_utf8, purple_connection_get_account(gc));
+ group->group_name_utf8, purple_connection_get_account(gc));
if (conv != NULL && group->members != NULL) {
list = group->members;
while (list != NULL) {
============================================================
--- libpurple/protocols/qq/group_find.c 3770c52e75ed6cd6dd9d5528bc37b49f9dad436d
+++ libpurple/protocols/qq/group_find.c 30312495840bc0286f16541ac847a387638d5b3e
@@ -110,10 +110,10 @@ qq_group *qq_group_find_by_channel(Purpl
group = NULL;
while (list != NULL) {
group = (qq_group *) list->data;
- if (group->title_utf8 == NULL) {
+ if (group->group_name_utf8 == NULL) {
continue;
}
- if (!g_ascii_strcasecmp(purple_conversation_get_name(conv), group->title_utf8))
+ if (!g_ascii_strcasecmp(purple_conversation_get_name(conv), group->group_name_utf8))
break;
list = list->next;
}
@@ -167,83 +167,3 @@ qq_group *qq_room_search_id(PurpleConnec
return NULL;
}
-
-qq_group *qq_room_get_next(PurpleConnection *gc, guint32 room_id)
-{
- GList *list;
- qq_group *group;
- qq_data *qd;
- gboolean is_find = FALSE;
-
- qd = (qq_data *) gc->proto_data;
-
- if (qd->groups == NULL) {
- return NULL;
- }
-
- if (room_id <= 0) {
- return (qq_group *) qd->groups->data;
- }
-
- list = qd->groups;
- while (list != NULL) {
- group = (qq_group *) list->data;
- list = list->next;
- if (group->id == room_id) {
- is_find = TRUE;
- break;
- }
- }
-
- if ( !is_find || list == NULL) {
- return NULL;
- }
-
- return (qq_group *)list->data;
-}
-
-qq_group *qq_room_get_next_conv(PurpleConnection *gc, guint32 room_id)
-{
- GList *list;
- qq_group *group;
- qq_data *qd;
- gboolean is_find;
-
- qd = (qq_data *) gc->proto_data;
-
- list = qd->groups;
- if (room_id > 0) {
- /* search next room */
- is_find = FALSE;
- while (list != NULL) {
- group = (qq_group *) list->data;
- list = list->next;
- if (group->id == room_id) {
- is_find = TRUE;
- break;
- }
- }
- if ( !is_find || list == NULL) {
- return NULL;
- }
- }
-
- is_find = FALSE;
- while (list != NULL) {
- group = (qq_group *) list->data;
- if (group->my_role == QQ_ROOM_ROLE_YES || group->my_role == QQ_ROOM_ROLE_ADMIN) {
- if (NULL != purple_find_conversation_with_account(
- PURPLE_CONV_TYPE_CHAT,group->title_utf8, purple_connection_get_account(gc))) {
- /* In convseration*/
- is_find = TRUE;
- break;
- }
- }
- list = list->next;
- }
-
- if ( !is_find) {
- return NULL;
- }
- return group;
-}
============================================================
--- libpurple/protocols/qq/group_find.h 11c372e0accfd6fa0a0f1d725a619139cc9a27ec
+++ libpurple/protocols/qq/group_find.h 8978a58ba32f8e2fd770e56de5b84c1051e3d7c0
@@ -32,12 +32,10 @@ qq_buddy *qq_group_find_or_add_member(Pu
qq_buddy *qq_group_find_member_by_uid(qq_group *group, guint32 uid);
void qq_group_remove_member_by_uid(qq_group *group, guint32 uid);
qq_buddy *qq_group_find_or_add_member(PurpleConnection *gc, qq_group *group, guint32 member_uid);
+gboolean qq_group_find_id_by_seq(PurpleConnection *gc, guint16 seq, guint32 *id);
qq_group *qq_group_find_by_channel(PurpleConnection *gc, gint channel);
qq_group *qq_room_search_ext_id(PurpleConnection *gc, guint32 ext_id);
qq_group *qq_room_search_id(PurpleConnection *gc, guint32 room_id);
-qq_group *qq_room_get_next(PurpleConnection *gc, guint32 room_id);
-qq_group *qq_room_get_next_conv(PurpleConnection *gc, guint32 room_id);
-
#endif
============================================================
--- libpurple/protocols/qq/group_free.c 9062c677324a6d7d94a07885f3f4656da177f617
+++ libpurple/protocols/qq/group_free.c 3d3fb0dbfe4e3796b77a2d43596d330feaf73cd1
@@ -54,9 +54,9 @@ void qq_group_free(qq_group *group)
{
g_return_if_fail(group != NULL);
qq_group_free_member(group);
- g_free(group->my_role_desc);
- g_free(group->title_utf8);
- g_free(group->desc_utf8);
+ g_free(group->my_status_desc);
+ g_free(group->group_name_utf8);
+ g_free(group->group_desc_utf8);
g_free(group->notice_utf8);
g_free(group);
}
@@ -64,18 +64,16 @@ void qq_group_free_all(qq_data *qd)
void qq_group_free_all(qq_data *qd)
{
qq_group *group;
- gint count;
-
+ gint i;
g_return_if_fail(qd != NULL);
- count = 0;
+
+ i = 0;
while (qd->groups != NULL) {
+ i++;
group = (qq_group *) qd->groups->data;
qd->groups = g_list_remove(qd->groups, group);
qq_group_free(group);
- count++;
}
- if (count > 0) {
- purple_debug_info("QQ", "%d rooms are freed\n", count);
- }
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "%d groups are freed\n", i);
}
============================================================
--- libpurple/protocols/qq/group_im.c c46e53482e9fb4ee95c0a19023b3b85e3bd2fe06
+++ libpurple/protocols/qq/group_im.c f9094b9361ff1fb22d670d6ddd1e937b9df0a7b4
@@ -41,7 +41,6 @@
#include "header_info.h"
#include "packet_parse.h"
#include "qq_network.h"
-#include "qq_process.h"
#include "utils.h"
typedef struct _qq_recv_group_im {
@@ -86,12 +85,12 @@ void qq_send_packet_group_im(PurpleConne
if (bytes == data_len) /* create OK */
qq_send_room_cmd(gc, QQ_ROOM_CMD_SEND_MSG, group->id, raw_data, data_len);
else
- purple_debug_error("QQ",
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ",
"Fail creating group_im packet, expect %d bytes, build %d bytes\n", data_len, bytes);
}
/* this is the ACK */
-void qq_process_group_cmd_im(guint8 *data, gint len, PurpleConnection *gc)
+void qq_process_group_cmd_im(guint8 *data, gint len, PurpleConnection *gc)
{
/* return should be the internal group id
* but we have nothing to do with it */
@@ -99,7 +98,7 @@ void qq_process_group_cmd_im(guint8 *dat
}
/* receive an application to join the group */
-void qq_process_room_msg_apply_join(guint8 *data, gint len, guint32 id, PurpleConnection *gc)
+void qq_process_recv_group_im_apply_join(guint8 *data, gint len, guint32 id, PurpleConnection *gc)
{
guint32 ext_id, user_uid;
guint8 type8;
@@ -120,8 +119,8 @@ void qq_process_room_msg_apply_join(guin
bytes += convert_as_pascal_string(data + bytes, &reason_utf8, QQ_CHARSET_DEFAULT);
- msg = g_strdup_printf(_("%d requested to join Qun %d"), user_uid, ext_id);
- reason = g_strdup_printf(_("Message: %s"), reason_utf8);
+ msg = g_strdup_printf(_("User %d requested to join group %d"), user_uid, ext_id);
+ reason = g_strdup_printf(_("Reason: %s"), reason_utf8);
g = g_new0(group_member_opt, 1);
g->gc = gc;
@@ -150,7 +149,7 @@ void qq_process_room_msg_apply_join(guin
}
/* the request to join a group is rejected */
-void qq_process_room_msg_been_rejected(guint8 *data, gint len, guint32 id, PurpleConnection *gc)
+void qq_process_recv_group_im_been_rejected(guint8 *data, gint len, guint32 id, PurpleConnection *gc)
{
guint32 ext_id, admin_uid;
guint8 type8;
@@ -171,14 +170,14 @@ void qq_process_room_msg_been_rejected(g
bytes += convert_as_pascal_string(data + bytes, &reason_utf8, QQ_CHARSET_DEFAULT);
msg = g_strdup_printf
- (_("Your request to join Qun %d has been rejected by admin %d"), ext_id, admin_uid);
- reason = g_strdup_printf(_("Message: %s"), reason_utf8);
+ (_("Your request to join group %d has been rejected by admin %d"), ext_id, admin_uid);
+ reason = g_strdup_printf(_("Reason: %s"), reason_utf8);
purple_notify_warning(gc, _("QQ Qun Operation"), msg, reason);
group = qq_room_search_id(gc, id);
if (group != NULL) {
- group->my_role = QQ_ROOM_ROLE_NO;
+ group->my_status = QQ_GROUP_MEMBER_STATUS_NOT_MEMBER;
qq_group_refresh(gc, group);
}
@@ -188,7 +187,7 @@ void qq_process_room_msg_been_rejected(g
}
/* the request to join a group is approved */
-void qq_process_room_msg_been_approved(guint8 *data, gint len, guint32 id, PurpleConnection *gc)
+void qq_process_recv_group_im_been_approved(guint8 *data, gint len, guint32 id, PurpleConnection *gc)
{
guint32 ext_id, admin_uid;
guint8 type8;
@@ -209,13 +208,13 @@ void qq_process_room_msg_been_approved(g
bytes += convert_as_pascal_string(data + bytes, &reason_utf8, QQ_CHARSET_DEFAULT);
msg = g_strdup_printf
- (_("Your request to join Qun %d has been approved by admin %d"), ext_id, admin_uid);
+ (_("Your request to join group %d has been approved by admin %d"), ext_id, admin_uid);
purple_notify_warning(gc, _("QQ Qun Operation"), msg, NULL);
group = qq_room_search_id(gc, id);
if (group != NULL) {
- group->my_role = QQ_ROOM_ROLE_YES;
+ group->my_status = QQ_GROUP_MEMBER_STATUS_IS_MEMBER;
qq_group_refresh(gc, group);
}
@@ -224,7 +223,7 @@ void qq_process_room_msg_been_approved(g
}
/* process the packet when removed from a group */
-void qq_process_room_msg_been_removed(guint8 *data, gint len, guint32 id, PurpleConnection *gc)
+void qq_process_recv_group_im_been_removed(guint8 *data, gint len, guint32 id, PurpleConnection *gc)
{
guint32 ext_id, uid;
guint8 type8;
@@ -242,12 +241,12 @@ void qq_process_room_msg_been_removed(gu
g_return_if_fail(ext_id > 0 && uid > 0);
- msg = g_strdup_printf(_("[%d] removed from Qun \"%d\""), uid, ext_id);
+ msg = g_strdup_printf(_("You [%d] have left group \"%d\""), uid, ext_id);
purple_notify_info(gc, _("QQ Qun Operation"), msg, NULL);
group = qq_room_search_id(gc, id);
if (group != NULL) {
- group->my_role = QQ_ROOM_ROLE_NO;
+ group->my_status = QQ_GROUP_MEMBER_STATUS_NOT_MEMBER;
qq_group_refresh(gc, group);
}
@@ -255,7 +254,7 @@ void qq_process_room_msg_been_removed(gu
}
/* process the packet when added to a group */
-void qq_process_room_msg_been_added(guint8 *data, gint len, guint32 id, PurpleConnection *gc)
+void qq_process_recv_group_im_been_added(guint8 *data, gint len, guint32 id, PurpleConnection *gc)
{
guint32 ext_id, uid;
guint8 type8;
@@ -273,18 +272,18 @@ void qq_process_room_msg_been_added(guin
g_return_if_fail(ext_id > 0 && uid > 0);
- msg = g_strdup_printf(_("[%d] added to Qun \"%d\""), uid, ext_id);
- purple_notify_info(gc, _("QQ Qun Operation"), msg, _("Qun is in buddy list"));
+ msg = g_strdup_printf(_("You [%d] have been added to group \"%d\""), uid, ext_id);
+ purple_notify_info(gc, _("QQ Qun Operation"), msg, _("This group has been added to your buddy list"));
group = qq_room_search_id(gc, id);
if (group != NULL) {
- group->my_role = QQ_ROOM_ROLE_YES;
+ group->my_status = QQ_GROUP_MEMBER_STATUS_IS_MEMBER;
qq_group_refresh(gc, group);
} else { /* no such group, try to create a dummy first, and then update */
group = qq_group_create_internal_record(gc, id, ext_id, NULL);
- group->my_role = QQ_ROOM_ROLE_YES;
+ group->my_status = QQ_GROUP_MEMBER_STATUS_IS_MEMBER;
qq_group_refresh(gc, group);
- qq_room_update(gc, 0, group->id);
+ qq_send_room_cmd_only(gc, QQ_ROOM_CMD_GET_INFO, group->id);
/* the return of this cmd will automatically update the group in blist */
}
@@ -292,7 +291,7 @@ void qq_process_room_msg_been_added(guin
}
/* recv an IM from a group chat */
-void qq_process_room_msg_normal(guint8 *data, gint data_len, guint32 id, PurpleConnection *gc, guint16 im_type)
+void qq_process_recv_group_im(guint8 *data, gint data_len, guint32 id, PurpleConnection *gc, guint16 im_type)
{
gchar *msg_with_purple_smiley, *msg_utf8_encoded, *im_src_name;
guint16 unknown;
@@ -311,9 +310,7 @@ void qq_process_room_msg_normal(guint8 *
qd = (qq_data *) gc->proto_data;
-#if 0
- qq_hex_dump(PURPLE_DEBUG_INFO, "QQ", data, data_len, "group im hex dump");
-#endif
+ /* qq_hex_dump(PURPLE_DEBUG_INFO, "QQ", data, data_len, "group im hex dump"); */
im_group = g_newa(qq_recv_group_im, 1);
@@ -377,13 +374,13 @@ void qq_process_room_msg_normal(guint8 *
group = qq_room_search_id(gc, id);
g_return_if_fail(group != NULL);
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, group->title_utf8, purple_connection_get_account(gc));
+ conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, group->group_name_utf8, purple_connection_get_account(gc));
if (conv == NULL && purple_prefs_get_bool("/plugins/prpl/qq/prompt_group_msg_on_recv")) {
/* New conv should open, get group info*/
- qq_room_update(gc, 0, group->id);
-
- serv_got_joined_chat(gc, qd->channel++, group->title_utf8);
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, group->title_utf8, purple_connection_get_account(gc));
+ qq_send_room_cmd_only(gc, QQ_ROOM_CMD_GET_INFO, group->id);
+
+ serv_got_joined_chat(gc, qd->channel++, group->group_name_utf8);
+ conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, group->group_name_utf8, purple_connection_get_account(gc));
}
if (conv != NULL) {
============================================================
--- libpurple/protocols/qq/group_im.h 80dbc5dfa185c472df09adc543fa04eea527b8b8
+++ libpurple/protocols/qq/group_im.h e031720f93defa4bf87c133d2d1640bf868f1ecd
@@ -31,17 +31,30 @@ void qq_send_packet_group_im(PurpleConne
void qq_send_packet_group_im(PurpleConnection *gc, qq_group *group, const gchar *msg);
+/* void qq_process_group_cmd_im(guint8 *data, guint8 **cursor, gint len, PurpleConnection *gc); */
void qq_process_group_cmd_im(guint8 *data, gint len, PurpleConnection *gc);
-void qq_process_room_msg_normal(guint8 *data, gint data_len, guint32 id, PurpleConnection *gc, guint16 im_type);
+/* void qq_process_recv_group_im(guint8 *data, guint8 **cursor,
+ * gint data_len, guint32 id, PurpleConnection *gc, guint16 im_type); */
+void qq_process_recv_group_im(guint8 *data, gint data_len, guint32 id, PurpleConnection *gc, guint16 im_type);
-void qq_process_room_msg_apply_join(guint8 *data, gint len, guint32 id, PurpleConnection *gc);
+/* void qq_process_recv_group_im_apply_join(guint8 *data, guint8 **cursor, gint len,
+ * guint32 id, PurpleConnection *gc); */
+void qq_process_recv_group_im_apply_join(guint8 *data, gint len, guint32 id, PurpleConnection *gc);
-void qq_process_room_msg_been_rejected(guint8 *data, gint len, guint32 id, PurpleConnection *gc);
+/* void qq_process_recv_group_im_been_rejected(guint8 *data, guint8 **cursor, gint len,
+ * guint32 id, PurpleConnection *gc); */
+void qq_process_recv_group_im_been_rejected(guint8 *data, gint len, guint32 id, PurpleConnection *gc);
-void qq_process_room_msg_been_approved(guint8 *data, gint len, guint32 id, PurpleConnection *gc);
+/* void qq_process_recv_group_im_been_approved(guint8 *data, guint8 **cursor, gint len,
+ * guint32 id, PurpleConnection *gc); */
+void qq_process_recv_group_im_been_approved(guint8 *data, gint len, guint32 id, PurpleConnection *gc);
-void qq_process_room_msg_been_removed(guint8 *data, gint len, guint32 id, PurpleConnection *gc);
+/* void qq_process_recv_group_im_been_removed(guint8 *data, guint8 **cursor, gint len,
+ * guint32 id, PurpleConnection *gc); */
+void qq_process_recv_group_im_been_removed(guint8 *data, gint len, guint32 id, PurpleConnection *gc);
-void qq_process_room_msg_been_added(guint8 *data, gint len, guint32 id, PurpleConnection *gc);
+/* void qq_process_recv_group_im_been_added(guint8 *data, guint8 **cursor, gint len,
+ * guint32 id, PurpleConnection *gc); */
+void qq_process_recv_group_im_been_added(guint8 *data, gint len, guint32 id, PurpleConnection *gc);
#endif
============================================================
--- libpurple/protocols/qq/group_info.c 3ea1d5d410f6718065865401f2ced4e7a05302bb
+++ libpurple/protocols/qq/group_info.c a1d15e05c9e82fd75464c23ac95f976054396e02
@@ -41,16 +41,16 @@
* this interval determines if their member info is outdated */
#define QQ_GROUP_CHAT_REFRESH_NICKNAME_INTERNAL 180
-static gboolean check_update_interval(qq_buddy *member)
+static gboolean _is_group_member_need_update_info(qq_buddy *member)
{
g_return_val_if_fail(member != NULL, FALSE);
return (member->nickname == NULL) ||
- (time(NULL) - member->last_update) > QQ_GROUP_CHAT_REFRESH_NICKNAME_INTERNAL;
+ (time(NULL) - member->last_refresh) > QQ_GROUP_CHAT_REFRESH_NICKNAME_INTERNAL;
}
/* this is done when we receive the reply to get_online_members sub_cmd
* all member are set offline, and then only those in reply packets are online */
-static void set_all_offline(qq_group *group)
+static void _qq_group_set_members_all_offline(qq_group *group)
{
GList *list;
qq_buddy *member;
@@ -64,24 +64,60 @@ static void set_all_offline(qq_group *gr
}
}
+/* send packet to get online group member, called by keep_alive */
+void qq_send_cmd_group_all_get_online_members(PurpleConnection *gc)
+{
+ qq_data *qd;
+ qq_group *group;
+ GList *list;
+
+ g_return_if_fail(gc != NULL && gc->proto_data != NULL);
+ qd = (qq_data *) gc->proto_data;
+
+ list = qd->groups;
+ while (list != NULL) {
+ group = (qq_group *) list->data;
+ if (group->my_status == QQ_GROUP_MEMBER_STATUS_IS_MEMBER ||
+ group->my_status == QQ_GROUP_MEMBER_STATUS_IS_ADMIN)
+ /* no need to get info time and time again, online members enough */
+ qq_send_cmd_group_get_online_members(gc, group);
+
+ list = list->next;
+ }
+}
+
+void qq_send_cmd_group_get_online_members(PurpleConnection *gc, qq_group *group)
+{
+ g_return_if_fail(group != NULL);
+
+ /* only get online members when conversation window is on */
+ if (NULL == purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,group->group_name_utf8, purple_connection_get_account(gc))) {
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ",
+ "Conversation \"%s\" is not open, ignore to get online members\n", group->group_name_utf8);
+ return;
+ }
+
+ qq_send_room_cmd_only(gc, QQ_ROOM_CMD_GET_ONLINES, group->id);
+}
+
/* send packet to get info for each group member */
-gint qq_request_room_get_buddies(PurpleConnection *gc, qq_group *group, gint update_class)
+void qq_send_cmd_group_get_members_info(PurpleConnection *gc, qq_group *group)
{
guint8 *raw_data;
gint bytes, num;
GList *list;
qq_buddy *member;
- g_return_val_if_fail(group != NULL, 0);
+ g_return_if_fail(group != NULL);
for (num = 0, list = group->members; list != NULL; list = list->next) {
member = (qq_buddy *) list->data;
- if (check_update_interval(member))
+ if (_is_group_member_need_update_info(member))
num++;
}
if (num <= 0) {
- purple_debug_info("QQ", "No group member info needs to be updated now.\n");
- return 0;
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "No group member info needs to be updated now.\n");
+ return;
}
raw_data = g_newa(guint8, 4 * num);
@@ -91,14 +127,12 @@ gint qq_request_room_get_buddies(PurpleC
list = group->members;
while (list != NULL) {
member = (qq_buddy *) list->data;
- if (check_update_interval(member))
+ if (_is_group_member_need_update_info(member))
bytes += qq_put32(raw_data + bytes, member->uid);
list = list->next;
}
- qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_BUDDIES, group->id, raw_data, bytes,
- update_class, 0);
- return num;
+ qq_send_room_cmd(gc, QQ_ROOM_CMD_GET_MEMBER_INFO, group->id, raw_data, bytes);
}
void qq_process_room_cmd_get_info(guint8 *data, gint data_len, PurpleConnection *gc)
@@ -140,8 +174,8 @@ void qq_process_room_cmd_get_info(guint8
bytes += qq_get32(&(group->creator_uid), data + bytes);
bytes += qq_get8(&(group->auth_type), data + bytes);
bytes += qq_get32(&unknown4, data + bytes); /* oldCategory */
- bytes += qq_get16(&unknown, data + bytes);
- bytes += qq_get32(&(group->category), data + bytes);
+ bytes += qq_get16(&unknown, data + bytes);
+ bytes += qq_get32(&(group->group_category), data + bytes);
bytes += qq_get16(&max_members, data + bytes);
bytes += qq_get8(&unknown1, data + bytes);
/* the following, while Eva:
@@ -149,17 +183,17 @@ void qq_process_room_cmd_get_info(guint8
* 2(qunNoticeLen), qunNoticeLen(qunNoticeContent, 1(qunDescLen),
* qunDestLen(qunDestcontent)) */
bytes += qq_get8(&unknown1, data + bytes);
- purple_debug_info("QQ", "type=%u creatorid=%u category=%u maxmembers=%u\n",
- group->type8, group->creator_uid, group->category, max_members);
-
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "type=%u creatorid=%u category=%u maxmembers=%u\n",
+ group->type8, group->creator_uid, group->group_category, max_members);
+
/* strlen + <str content> */
- bytes += convert_as_pascal_string(data + bytes, &(group->title_utf8), QQ_CHARSET_DEFAULT);
- purple_debug_info("QQ", "group \"%s\"\n", group->title_utf8);
+ bytes += convert_as_pascal_string(data + bytes, &(group->group_name_utf8), QQ_CHARSET_DEFAULT);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "group \"%s\"\n", group->group_name_utf8);
bytes += qq_get16(&unknown, data + bytes); /* 0x0000 */
bytes += convert_as_pascal_string(data + bytes, ¬ice, QQ_CHARSET_DEFAULT);
- purple_debug_info("QQ", "notice \"%s\"\n", notice);
- bytes += convert_as_pascal_string(data + bytes, &(group->desc_utf8), QQ_CHARSET_DEFAULT);
- purple_debug_info("QQ", "group_desc \"%s\"\n", group->desc_utf8);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "notice \"%s\"\n", notice);
+ bytes += convert_as_pascal_string(data + bytes, &(group->group_desc_utf8), QQ_CHARSET_DEFAULT);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "group_desc \"%s\"\n", group->group_desc_utf8);
num = 0;
/* now comes the member list separated by 0x00 */
@@ -171,7 +205,7 @@ void qq_process_room_cmd_get_info(guint8
#if 0
if(organization != 0 || role != 0) {
- purple_debug_info("QQ_GRP", "%d, organization=%d, role=%d\n", member_uid, organization, role);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ_GRP", "%d, organization=%d, role=%d\n", member_uid, organization, role);
}
#endif
@@ -180,22 +214,22 @@ void qq_process_room_cmd_get_info(guint8
member->role = role;
}
if(bytes > data_len) {
- purple_debug_error("QQ",
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ",
"group_cmd_get_group_info: Dangerous error! maybe protocol changed, notify me!");
}
- purple_debug_info("QQ", "group \"%s\" has %d members\n", group->title_utf8, num);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "group \"%s\" has %d members\n", group->group_name_utf8, num);
if (group->creator_uid == qd->uid)
- group->my_role = QQ_ROOM_ROLE_ADMIN;
+ group->my_status = QQ_GROUP_MEMBER_STATUS_IS_ADMIN;
qq_group_refresh(gc, group);
- purple_conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
- group->title_utf8, purple_connection_get_account(gc));
+ purple_conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
+ group->group_name_utf8, purple_connection_get_account(gc));
if(NULL == purple_conv) {
- purple_debug_warning("QQ",
- "Conversation \"%s\" is not open, do not set topic\n", group->title_utf8);
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ",
+ "Conversation \"%s\" is not open, do not set topic\n", group->group_name_utf8);
return;
}
@@ -203,7 +237,7 @@ void qq_process_room_cmd_get_info(guint8
qq_filter_str(notice);
group->notice_utf8 = strdup(notice);
g_free(notice);
-
+
purple_conv_chat_set_topic(PURPLE_CONV_CHAT(purple_conv), NULL, group->notice_utf8);
}
@@ -218,7 +252,7 @@ void qq_process_room_cmd_get_onlines(gui
g_return_if_fail(data != NULL && len > 0);
if (len <= 3) {
- purple_debug_error("QQ", "Invalid group online member reply, discard it!\n");
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Invalid group online member reply, discard it!\n");
return;
}
@@ -229,12 +263,13 @@ void qq_process_room_cmd_get_onlines(gui
group = qq_room_search_id(gc, id);
if (group == NULL) {
- purple_debug_error("QQ", "We have no group info for internal id [%d]\n", id);
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ",
+ "We have no group info for internal id [%d]\n", id);
return;
}
/* set all offline first, then update those online */
- set_all_offline(group);
+ _qq_group_set_members_all_offline(group);
num = 0;
while (bytes < len) {
bytes += qq_get32(&member_uid, data + bytes);
@@ -244,15 +279,15 @@ void qq_process_room_cmd_get_onlines(gui
member->status = QQ_BUDDY_ONLINE_NORMAL;
}
if(bytes > len) {
- purple_debug_error("QQ",
- "group_cmd_get_online_members: Dangerous error! maybe protocol changed, notify developers!");
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ",
+ "group_cmd_get_online_members: Dangerous error! maybe protocol changed, notify developers!");
}
- purple_debug_info("QQ", "Group \"%s\" has %d online members\n", group->title_utf8, num);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Group \"%s\" has %d online members\n", group->group_name_utf8, num);
}
/* process the reply to get_members_info packet */
-void qq_process_room_cmd_get_buddies(guint8 *data, gint len, PurpleConnection *gc)
+void qq_process_room_cmd_get_members(guint8 *data, gint len, PurpleConnection *gc)
{
gint bytes;
gint num;
@@ -265,7 +300,7 @@ void qq_process_room_cmd_get_buddies(gui
g_return_if_fail(data != NULL && len > 0);
#if 0
- qq_show_packet("qq_process_room_cmd_get_buddies", data, len);
+ qq_show_packet("qq_process_room_cmd_get_members", data, len);
#endif
bytes = 0;
@@ -296,19 +331,19 @@ void qq_process_room_cmd_get_buddies(gui
qq_filter_str(nick);
member->nickname = g_strdup(nick);
g_free(nick);
-
+
#if 0
- purple_debug_info("QQ",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
"member [%09d]: ext_flag=0x%02x, comm_flag=0x%02x, nick=%s\n",
member_uid, member->ext_flag, member->comm_flag, member->nickname);
#endif
- member->last_update = time(NULL);
+ member->last_refresh = time(NULL);
}
if (bytes > len) {
- purple_debug_error("QQ",
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ",
"group_cmd_get_members_info: Dangerous error! maybe protocol changed, notify developers!");
}
- purple_debug_info("QQ", "Group \"%s\" obtained %d member info\n", group->title_utf8, num);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Group \"%s\" obtained %d member info\n", group->group_name_utf8, num);
}
============================================================
--- libpurple/protocols/qq/group_info.h 5acd27bb23463327232e8d73f22c6b33c7a2fe6d
+++ libpurple/protocols/qq/group_info.h ec4f93c82296b45db4f59a84f5d0502dd8c5d77a
@@ -29,9 +29,12 @@
#include "connection.h"
#include "group.h"
-gint qq_request_room_get_buddies(PurpleConnection *gc, qq_group *group, gint update_class);
+void qq_send_cmd_group_get_online_members(PurpleConnection *gc, qq_group *group);
+void qq_send_cmd_group_all_get_online_members(PurpleConnection *gc);
+void qq_send_cmd_group_get_members_info(PurpleConnection *gc, qq_group *group);
+
void qq_process_room_cmd_get_info(guint8 *data, gint len, PurpleConnection *gc);
void qq_process_room_cmd_get_onlines(guint8 *data, gint len, PurpleConnection *gc);
-void qq_process_room_cmd_get_buddies(guint8 *data, gint len, PurpleConnection *gc);
+void qq_process_room_cmd_get_members(guint8 *data, gint len, PurpleConnection *gc);
#endif
============================================================
--- libpurple/protocols/qq/group_internal.c 5b542d1d030bca842d226cd9a8045b6b53d6d190
+++ libpurple/protocols/qq/group_internal.c 67db78e571818d3665ddd87635ef513d4657d957
@@ -31,49 +31,49 @@
#include "group_internal.h"
#include "utils.h"
-static gchar *get_role_desc(qq_group *group)
+static gchar *_qq_group_set_my_status_desc(qq_group *group)
{
- const char *role_desc;
+ const char *status_desc;
g_return_val_if_fail(group != NULL, g_strdup(""));
- switch (group->my_role) {
- case QQ_ROOM_ROLE_NO:
- role_desc = _("I am not a member");
+ switch (group->my_status) {
+ case QQ_GROUP_MEMBER_STATUS_NOT_MEMBER:
+ status_desc = _("I am not a member");
break;
- case QQ_ROOM_ROLE_YES:
- role_desc = _("I am a member");
+ case QQ_GROUP_MEMBER_STATUS_IS_MEMBER:
+ status_desc = _("I am a member");
break;
- case QQ_ROOM_ROLE_REQUESTING:
- role_desc = _("I am requesting");
+ case QQ_GROUP_MEMBER_STATUS_APPLYING:
+ status_desc = _("I am applying to join");
break;
- case QQ_ROOM_ROLE_ADMIN:
- role_desc = _("I am the admin");
+ case QQ_GROUP_MEMBER_STATUS_IS_ADMIN:
+ status_desc = _("I am the admin");
break;
default:
- role_desc = _("Unknown status");
+ status_desc = _("Unknown status");
}
- return g_strdup(role_desc);
+ return g_strdup(status_desc);
}
-static void add_room_to_blist(PurpleConnection *gc, qq_group *group)
+static void _qq_group_add_to_blist(PurpleConnection *gc, qq_group *group)
{
GHashTable *components;
PurpleGroup *g;
PurpleChat *chat;
components = qq_group_to_hashtable(group);
- chat = purple_chat_new(purple_connection_get_account(gc), group->title_utf8, components);
+ chat = purple_chat_new(purple_connection_get_account(gc), group->group_name_utf8, components);
g = qq_get_purple_group(PURPLE_GROUP_QQ_QUN);
purple_blist_add_chat(chat, g, NULL);
- purple_debug_info("QQ", "You have added group \"%s\" to blist locally\n", group->title_utf8);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "You have added group \"%s\" to blist locally\n", group->group_name_utf8);
}
/* Create a dummy qq_group, which includes only internal_id, ext_id,
- * and potentially title_utf8, in case we need to call group_conv_show_window
+ * and potentially group_name_utf8, in case we need to call group_conv_show_window
* right after creation. All other attributes are set to empty.
* We need to send a get_group_info to the QQ server to update it right away */
qq_group *qq_group_create_internal_record(PurpleConnection *gc,
- guint32 internal_id, guint32 ext_id, gchar *title_utf8)
+ guint32 internal_id, guint32 ext_id, gchar *group_name_utf8)
{
qq_group *group;
qq_data *qd;
@@ -82,21 +82,21 @@ qq_group *qq_group_create_internal_recor
qd = (qq_data *) gc->proto_data;
group = g_new0(qq_group, 1);
- group->my_role = QQ_ROOM_ROLE_NO;
- group->my_role_desc = get_role_desc(group);
+ group->my_status = QQ_GROUP_MEMBER_STATUS_NOT_MEMBER;
+ group->my_status_desc = _qq_group_set_my_status_desc(group);
group->id = internal_id;
group->ext_id = ext_id;
group->type8 = 0x01; /* assume permanent Qun */
group->creator_uid = 10000; /* assume by QQ admin */
- group->category = 0x01;
+ group->group_category = 0x01;
group->auth_type = 0x02; /* assume need auth */
- group->title_utf8 = g_strdup(title_utf8 == NULL ? "" : title_utf8);
- group->desc_utf8 = g_strdup("");
+ group->group_name_utf8 = g_strdup(group_name_utf8 == NULL ? "" : group_name_utf8);
+ group->group_desc_utf8 = g_strdup("");
group->notice_utf8 = g_strdup("");
group->members = NULL;
qd->groups = g_list_append(qd->groups, group);
- add_room_to_blist(gc, group);
+ _qq_group_add_to_blist(gc, group);
return group;
}
@@ -124,21 +124,21 @@ GHashTable *qq_group_to_hashtable(qq_gro
{
GHashTable *components;
components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
- g_hash_table_insert(components, g_strdup(QQ_ROOM_KEY_ROLE), g_strdup_printf("%d", group->my_role));
- group->my_role_desc = get_role_desc(group);
+ g_hash_table_insert(components, g_strdup(QQ_GROUP_KEY_MEMBER_STATUS), g_strdup_printf("%d", group->my_status));
+ group->my_status_desc = _qq_group_set_my_status_desc(group);
g_hash_table_insert(components,
- g_strdup(QQ_ROOM_KEY_INTERNAL_ID), g_strdup_printf("%d", group->id));
- g_hash_table_insert(components, g_strdup(QQ_ROOM_KEY_EXTERNAL_ID),
+ g_strdup(QQ_GROUP_KEY_INTERNAL_ID), g_strdup_printf("%d", group->id));
+ g_hash_table_insert(components, g_strdup(QQ_GROUP_KEY_EXTERNAL_ID),
g_strdup_printf("%d", group->ext_id));
- g_hash_table_insert(components, g_strdup(QQ_ROOM_KEY_TYPE), g_strdup_printf("%d", group->type8));
- g_hash_table_insert(components, g_strdup(QQ_ROOM_KEY_CREATOR_UID), g_strdup_printf("%d", group->creator_uid));
+ g_hash_table_insert(components, g_strdup(QQ_GROUP_KEY_TYPE), g_strdup_printf("%d", group->type8));
+ g_hash_table_insert(components, g_strdup(QQ_GROUP_KEY_CREATOR_UID), g_strdup_printf("%d", group->creator_uid));
g_hash_table_insert(components,
- g_strdup(QQ_ROOM_KEY_CATEGORY), g_strdup_printf("%d", group->category));
- g_hash_table_insert(components, g_strdup(QQ_ROOM_KEY_AUTH_TYPE), g_strdup_printf("%d", group->auth_type));
- g_hash_table_insert(components, g_strdup(QQ_ROOM_KEY_ROLE_DESC), g_strdup(group->my_role_desc));
- g_hash_table_insert(components, g_strdup(QQ_ROOM_KEY_TITLE_UTF8), g_strdup(group->title_utf8));
- g_hash_table_insert(components, g_strdup(QQ_ROOM_KEY_DESC_UTF8), g_strdup(group->desc_utf8));
+ g_strdup(QQ_GROUP_KEY_GROUP_CATEGORY), g_strdup_printf("%d", group->group_category));
+ g_hash_table_insert(components, g_strdup(QQ_GROUP_KEY_AUTH_TYPE), g_strdup_printf("%d", group->auth_type));
+ g_hash_table_insert(components, g_strdup(QQ_GROUP_KEY_MEMBER_STATUS_DESC), g_strdup(group->my_status_desc));
+ g_hash_table_insert(components, g_strdup(QQ_GROUP_KEY_GROUP_NAME_UTF8), g_strdup(group->group_name_utf8));
+ g_hash_table_insert(components, g_strdup(QQ_GROUP_KEY_GROUP_DESC_UTF8), g_strdup(group->group_desc_utf8));
return components;
}
@@ -152,22 +152,22 @@ qq_group *qq_group_from_hashtable(Purple
qd = (qq_data *) gc->proto_data;
group = g_new0(qq_group, 1);
- group->my_role =
+ group->my_status =
qq_string_to_dec_value
(NULL ==
g_hash_table_lookup(data,
- QQ_ROOM_KEY_ROLE) ?
- g_strdup_printf("%d", QQ_ROOM_ROLE_NO) :
- g_hash_table_lookup(data, QQ_ROOM_KEY_ROLE));
- group->id = qq_string_to_dec_value(g_hash_table_lookup(data, QQ_ROOM_KEY_INTERNAL_ID));
- group->ext_id = qq_string_to_dec_value(g_hash_table_lookup(data, QQ_ROOM_KEY_EXTERNAL_ID));
- group->type8 = qq_string_to_dec_value(g_hash_table_lookup(data, QQ_ROOM_KEY_TYPE));
- group->creator_uid = qq_string_to_dec_value(g_hash_table_lookup(data, QQ_ROOM_KEY_CREATOR_UID));
- group->category = qq_string_to_dec_value(g_hash_table_lookup(data, QQ_ROOM_KEY_CATEGORY));
- group->auth_type = qq_string_to_dec_value(g_hash_table_lookup(data, QQ_ROOM_KEY_AUTH_TYPE));
- group->title_utf8 = g_strdup(g_hash_table_lookup(data, QQ_ROOM_KEY_TITLE_UTF8));
- group->desc_utf8 = g_strdup(g_hash_table_lookup(data, QQ_ROOM_KEY_DESC_UTF8));
- group->my_role_desc = get_role_desc(group);
+ QQ_GROUP_KEY_MEMBER_STATUS) ?
+ g_strdup_printf("%d", QQ_GROUP_MEMBER_STATUS_NOT_MEMBER) :
+ g_hash_table_lookup(data, QQ_GROUP_KEY_MEMBER_STATUS));
+ group->id = qq_string_to_dec_value(g_hash_table_lookup(data, QQ_GROUP_KEY_INTERNAL_ID));
+ group->ext_id = qq_string_to_dec_value(g_hash_table_lookup(data, QQ_GROUP_KEY_EXTERNAL_ID));
+ group->type8 = qq_string_to_dec_value(g_hash_table_lookup(data, QQ_GROUP_KEY_TYPE));
+ group->creator_uid = qq_string_to_dec_value(g_hash_table_lookup(data, QQ_GROUP_KEY_CREATOR_UID));
+ group->group_category = qq_string_to_dec_value(g_hash_table_lookup(data, QQ_GROUP_KEY_GROUP_CATEGORY));
+ group->auth_type = qq_string_to_dec_value(g_hash_table_lookup(data, QQ_GROUP_KEY_AUTH_TYPE));
+ group->group_name_utf8 = g_strdup(g_hash_table_lookup(data, QQ_GROUP_KEY_GROUP_NAME_UTF8));
+ group->group_desc_utf8 = g_strdup(g_hash_table_lookup(data, QQ_GROUP_KEY_GROUP_DESC_UTF8));
+ group->my_status_desc = _qq_group_set_my_status_desc(group);
qd->groups = g_list_append(qd->groups, group);
@@ -184,54 +184,48 @@ void qq_group_refresh(PurpleConnection *
ext_id = g_strdup_printf("%d", group->ext_id);
chat = purple_blist_find_chat(purple_connection_get_account(gc), ext_id);
g_free(ext_id);
- if (chat == NULL && group->my_role != QQ_ROOM_ROLE_NO) {
- add_room_to_blist(gc, group);
- return;
+ if (chat == NULL && group->my_status != QQ_GROUP_MEMBER_STATUS_NOT_MEMBER) {
+ _qq_group_add_to_blist(gc, group);
+ } else if (chat != NULL) { /* we have a local record, update its info */
+ /* if there is group_name_utf8, we update the group name */
+ if (group->group_name_utf8 != NULL && strlen(group->group_name_utf8) > 0)
+ purple_blist_alias_chat(chat, group->group_name_utf8);
+ g_hash_table_replace(chat->components,
+ g_strdup(QQ_GROUP_KEY_MEMBER_STATUS), g_strdup_printf("%d", group->my_status));
+ group->my_status_desc = _qq_group_set_my_status_desc(group);
+ g_hash_table_replace(chat->components,
+ g_strdup(QQ_GROUP_KEY_MEMBER_STATUS_DESC), g_strdup(group->my_status_desc));
+ g_hash_table_replace(chat->components,
+ g_strdup(QQ_GROUP_KEY_INTERNAL_ID),
+ g_strdup_printf("%d", group->id));
+ g_hash_table_replace(chat->components,
+ g_strdup(QQ_GROUP_KEY_EXTERNAL_ID),
+ g_strdup_printf("%d", group->ext_id));
+ g_hash_table_replace(chat->components,
+ g_strdup(QQ_GROUP_KEY_TYPE), g_strdup_printf("%d", group->type8));
+ g_hash_table_replace(chat->components,
+ g_strdup(QQ_GROUP_KEY_CREATOR_UID), g_strdup_printf("%d", group->creator_uid));
+ g_hash_table_replace(chat->components,
+ g_strdup(QQ_GROUP_KEY_GROUP_CATEGORY),
+ g_strdup_printf("%d", group->group_category));
+ g_hash_table_replace(chat->components,
+ g_strdup(QQ_GROUP_KEY_AUTH_TYPE), g_strdup_printf("%d", group->auth_type));
+ g_hash_table_replace(chat->components,
+ g_strdup(QQ_GROUP_KEY_GROUP_NAME_UTF8), g_strdup(group->group_name_utf8));
+ g_hash_table_replace(chat->components,
+ g_strdup(QQ_GROUP_KEY_GROUP_DESC_UTF8), g_strdup(group->group_desc_utf8));
}
-
- if (chat == NULL) {
- return;
- }
-
- /* we have a local record, update its info */
- /* if there is title_utf8, we update the group name */
- if (group->title_utf8 != NULL && strlen(group->title_utf8) > 0)
- purple_blist_alias_chat(chat, group->title_utf8);
- g_hash_table_replace(chat->components,
- g_strdup(QQ_ROOM_KEY_ROLE), g_strdup_printf("%d", group->my_role));
- group->my_role_desc = get_role_desc(group);
- g_hash_table_replace(chat->components,
- g_strdup(QQ_ROOM_KEY_ROLE_DESC), g_strdup(group->my_role_desc));
- g_hash_table_replace(chat->components,
- g_strdup(QQ_ROOM_KEY_INTERNAL_ID),
- g_strdup_printf("%d", group->id));
- g_hash_table_replace(chat->components,
- g_strdup(QQ_ROOM_KEY_EXTERNAL_ID),
- g_strdup_printf("%d", group->ext_id));
- g_hash_table_replace(chat->components,
- g_strdup(QQ_ROOM_KEY_TYPE), g_strdup_printf("%d", group->type8));
- g_hash_table_replace(chat->components,
- g_strdup(QQ_ROOM_KEY_CREATOR_UID), g_strdup_printf("%d", group->creator_uid));
- g_hash_table_replace(chat->components,
- g_strdup(QQ_ROOM_KEY_CATEGORY),
- g_strdup_printf("%d", group->category));
- g_hash_table_replace(chat->components,
- g_strdup(QQ_ROOM_KEY_AUTH_TYPE), g_strdup_printf("%d", group->auth_type));
- g_hash_table_replace(chat->components,
- g_strdup(QQ_ROOM_KEY_TITLE_UTF8), g_strdup(group->title_utf8));
- g_hash_table_replace(chat->components,
- g_strdup(QQ_ROOM_KEY_DESC_UTF8), g_strdup(group->desc_utf8));
}
-/* NOTE: If we knew how to convert between an external and internal group id, as the official
+/* NOTE: If we knew how to convert between an external and internal group id, as the official
* client seems to, the following would be unnecessary. That would be ideal. */
/* Use list to specify if id's alternate id is pending discovery. */
void qq_set_pending_id(GSList **list, guint32 id, gboolean pending)
{
- if (pending)
+ if (pending)
*list = g_slist_prepend(*list, GINT_TO_POINTER(id));
- else
+ else
*list = g_slist_remove(*list, GINT_TO_POINTER(id));
}
============================================================
--- libpurple/protocols/qq/group_internal.h 07c09e08f1a14b607fcbd926aad0a5a0f5900a0f
+++ libpurple/protocols/qq/group_internal.h 9dbed22a6a1c7c44af8faacaece208c705c2491b
@@ -28,18 +28,18 @@
#include <glib.h>
#include "group.h"
-#define QQ_ROOM_KEY_ROLE "my_role"
-#define QQ_ROOM_KEY_ROLE_DESC "my_role_desc"
-#define QQ_ROOM_KEY_INTERNAL_ID "id"
-#define QQ_ROOM_KEY_EXTERNAL_ID "ext_id"
-#define QQ_ROOM_KEY_TYPE "type"
-#define QQ_ROOM_KEY_CREATOR_UID "creator_uid"
-#define QQ_ROOM_KEY_CATEGORY "category"
-#define QQ_ROOM_KEY_AUTH_TYPE "auth_type"
-#define QQ_ROOM_KEY_TITLE_UTF8 "title_utf8"
-#define QQ_ROOM_KEY_DESC_UTF8 "desc_utf8"
+#define QQ_GROUP_KEY_MEMBER_STATUS "my_status_code"
+#define QQ_GROUP_KEY_MEMBER_STATUS_DESC "my_status_desc"
+#define QQ_GROUP_KEY_INTERNAL_ID "id"
+#define QQ_GROUP_KEY_EXTERNAL_ID "ext_id"
+#define QQ_GROUP_KEY_TYPE "type"
+#define QQ_GROUP_KEY_CREATOR_UID "creator_uid"
+#define QQ_GROUP_KEY_GROUP_CATEGORY "category"
+#define QQ_GROUP_KEY_AUTH_TYPE "auth_type"
+#define QQ_GROUP_KEY_GROUP_NAME_UTF8 "name_utf8"
+#define QQ_GROUP_KEY_GROUP_DESC_UTF8 "desc_utf8"
-qq_group *qq_group_create_internal_record(PurpleConnection *gc,
+qq_group *qq_group_create_internal_record(PurpleConnection *gc,
guint32 internal_id, guint32 ext_id, gchar *group_name_utf8);
void qq_group_delete_internal_record(qq_data *qd, guint32 id);
============================================================
--- libpurple/protocols/qq/group_join.c b67c1322991d3e6f1861628109c608deb68af6cf
+++ libpurple/protocols/qq/group_join.c 792fdd633fd0b395d83701e185a7d007c26c76bd
@@ -42,11 +42,10 @@
#include "header_info.h"
#include "packet_parse.h"
#include "qq_network.h"
-#include "qq_process.h"
enum {
- QQ_ROOM_JOIN_OK = 0x01,
- QQ_ROOM_JOIN_NEED_AUTH = 0x02,
+ QQ_GROUP_JOIN_OK = 0x01,
+ QQ_GROUP_JOIN_NEED_AUTH = 0x02,
};
static void _qq_group_exit_with_gc_and_id(gc_and_uid *g)
@@ -69,20 +68,20 @@ void qq_send_cmd_group_join_group(Purple
{
g_return_if_fail(group != NULL);
- if (group->my_role == QQ_ROOM_ROLE_NO) {
- group->my_role = QQ_ROOM_ROLE_REQUESTING;
+ if (group->my_status == QQ_GROUP_MEMBER_STATUS_NOT_MEMBER) {
+ group->my_status = QQ_GROUP_MEMBER_STATUS_APPLYING;
qq_group_refresh(gc, group);
}
switch (group->auth_type) {
- case QQ_ROOM_AUTH_TYPE_NO_AUTH:
- case QQ_ROOM_AUTH_TYPE_NEED_AUTH:
+ case QQ_GROUP_AUTH_TYPE_NO_AUTH:
+ case QQ_GROUP_AUTH_TYPE_NEED_AUTH:
break;
- case QQ_ROOM_AUTH_TYPE_NO_ADD:
- purple_notify_warning(gc, NULL, _("The Qun does not allow others to join"), NULL);
+ case QQ_GROUP_AUTH_TYPE_NO_ADD:
+ purple_notify_warning(gc, NULL, _("This group does not allow others to join"), NULL);
return;
default:
- purple_debug_error("QQ", "Unknown room auth type: %d\n", group->auth_type);
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Unknown group auth type: %d\n", group->auth_type);
break;
}
@@ -100,10 +99,10 @@ static void _qq_group_join_auth_with_gc_
group = qq_room_search_id(gc, id);
if (group == NULL) {
- purple_debug_error("QQ", "Can not find qq_group by internal_id: %d\n", id);
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Can not find qq_group by internal_id: %d\n", id);
return;
} else { /* everything is OK */
- qq_send_cmd_group_auth(gc, group, QQ_ROOM_AUTH_REQUEST_APPLY, 0, reason_utf8);
+ qq_send_cmd_group_auth(gc, group, QQ_GROUP_AUTH_REQUEST_APPLY, 0, reason_utf8);
}
}
@@ -113,9 +112,10 @@ static void _qq_group_join_auth(PurpleCo
gc_and_uid *g;
g_return_if_fail(group != NULL);
- purple_debug_info("QQ", "Group (internal id: %d) needs authentication\n", group->id);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ "Group (internal id: %d) needs authentication\n", group->id);
- msg = g_strdup_printf("Group \"%s\" needs authentication\n", group->title_utf8);
+ msg = g_strdup_printf("Group \"%s\" needs authentication\n", group->group_name_utf8);
g = g_new0(gc_and_uid, 1);
g->gc = gc;
g->uid = group->id;
@@ -125,7 +125,7 @@ static void _qq_group_join_auth(PurpleCo
_("Send"),
G_CALLBACK(_qq_group_join_auth_with_gc_and_id),
_("Cancel"), G_CALLBACK(qq_do_nothing_with_gc_and_uid),
- purple_connection_get_account(gc), group->title_utf8, NULL,
+ purple_connection_get_account(gc), group->group_name_utf8, NULL,
g);
g_free(msg);
}
@@ -143,8 +143,8 @@ void qq_send_cmd_group_auth(PurpleConnec
else
reason_qq = utf8_to_qq(reason_utf8, QQ_CHARSET_DEFAULT);
- if (opt == QQ_ROOM_AUTH_REQUEST_APPLY) {
- group->my_role = QQ_ROOM_ROLE_REQUESTING;
+ if (opt == QQ_GROUP_AUTH_REQUEST_APPLY) {
+ group->my_status = QQ_GROUP_MEMBER_STATUS_APPLYING;
qq_group_refresh(gc, group);
uid = 0;
}
@@ -173,7 +173,8 @@ void qq_process_group_cmd_exit_group(gui
qd = (qq_data *) gc->proto_data;
if (len < 4) {
- purple_debug_error("QQ", "Invalid exit group reply, expect %d bytes, read %d bytes\n", 4, len);
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ",
+ "Invalid exit group reply, expect %d bytes, read %d bytes\n", 4, len);
return;
}
@@ -188,7 +189,7 @@ void qq_process_group_cmd_exit_group(gui
purple_blist_remove_chat(chat);
qq_group_delete_internal_record(qd, id);
}
- purple_notify_info(gc, _("QQ Qun Operation"), _("You have successfully left the Qun"), NULL);
+ purple_notify_info(gc, _("QQ Qun Operation"), _("You have successfully left the group"), NULL);
}
/* Process the reply to group_auth subcmd */
@@ -202,15 +203,15 @@ void qq_process_group_cmd_join_group_aut
qd = (qq_data *) gc->proto_data;
if (len < 4) {
- purple_debug_error("QQ",
- "Invalid join room reply, expect %d bytes, read %d bytes\n", 4, len);
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ",
+ "Invalid join group reply, expect %d bytes, read %d bytes\n", 4, len);
return;
}
bytes = 0;
bytes += qq_get32(&id, data + bytes);
g_return_if_fail(id > 0);
- purple_notify_info(gc, _("QQ Qun Auth"),
+ purple_notify_info(gc, _("QQ Group Auth"),
_("Your authorization request has been accepted by the QQ server"), NULL);
}
@@ -225,11 +226,11 @@ void qq_process_group_cmd_join_group(gui
g_return_if_fail(data != NULL && len > 0);
if (len < 5) {
- purple_debug_error("QQ",
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ",
"Invalid join group reply, expect %d bytes, read %d bytes\n", 5, len);
return;
}
-
+
bytes = 0;
bytes += qq_get32(&id, data + bytes);
bytes += qq_get8(&reply, data + bytes);
@@ -239,26 +240,26 @@ void qq_process_group_cmd_join_group(gui
/* need to check if group is NULL or not. */
g_return_if_fail(group != NULL);
switch (reply) {
- case QQ_ROOM_JOIN_OK:
- purple_debug_info("QQ", "Succeed joining group \"%s\"\n", group->title_utf8);
- group->my_role = QQ_ROOM_ROLE_YES;
+ case QQ_GROUP_JOIN_OK:
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Succeed joining group \"%s\"\n", group->group_name_utf8);
+ group->my_status = QQ_GROUP_MEMBER_STATUS_IS_MEMBER;
qq_group_refresh(gc, group);
/* this must be shown before getting online members */
qq_group_conv_show_window(gc, group);
- qq_room_update(gc, 0, group->id);
+ qq_send_room_cmd_only(gc, QQ_ROOM_CMD_GET_INFO, group->id);
break;
- case QQ_ROOM_JOIN_NEED_AUTH:
- purple_debug_info("QQ",
+ case QQ_GROUP_JOIN_NEED_AUTH:
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
"Fail joining group [%d] %s, needs authentication\n",
- group->ext_id, group->title_utf8);
- group->my_role = QQ_ROOM_ROLE_NO;
+ group->ext_id, group->group_name_utf8);
+ group->my_status = QQ_GROUP_MEMBER_STATUS_NOT_MEMBER;
qq_group_refresh(gc, group);
_qq_group_join_auth(gc, group);
break;
default:
- purple_debug_info("QQ",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
"Error joining group [%d] %s, unknown reply: 0x%02x\n",
- group->ext_id, group->title_utf8, reply);
+ group->ext_id, group->group_name_utf8, reply);
}
}
@@ -273,7 +274,7 @@ void qq_group_join(PurpleConnection *gc,
g_return_if_fail(data != NULL);
qd = (qq_data *) gc->proto_data;
- ext_id_ptr = g_hash_table_lookup(data, QQ_ROOM_KEY_EXTERNAL_ID);
+ ext_id_ptr = g_hash_table_lookup(data, QQ_GROUP_KEY_EXTERNAL_ID);
g_return_if_fail(ext_id_ptr != NULL);
errno = 0;
ext_id = strtol(ext_id_ptr, NULL, 10);
@@ -300,7 +301,7 @@ void qq_group_exit(PurpleConnection *gc,
g_return_if_fail(data != NULL);
- id_ptr = g_hash_table_lookup(data, QQ_ROOM_KEY_INTERNAL_ID);
+ id_ptr = g_hash_table_lookup(data, QQ_GROUP_KEY_INTERNAL_ID);
id = strtol(id_ptr, NULL, 10);
g_return_if_fail(id > 0);
@@ -311,7 +312,8 @@ void qq_group_exit(PurpleConnection *gc,
purple_request_action(gc, _("QQ Qun Operation"),
_("Are you sure you want to leave this Qun?"),
- _("Note, if you are the creator, \nthis operation will eventually remove this Qun."),
+ _
+ ("Note, if you are the creator, \nthis operation will eventually remove this Qun."),
1,
purple_connection_get_account(gc), NULL, NULL,
g, 2, _("Cancel"),
============================================================
--- libpurple/protocols/qq/group_join.h df3dae6e6bdfd0a3c12aaf50f0c33e8e66c87ac7
+++ libpurple/protocols/qq/group_join.h 0825fbbfaae115b886258169f07d0512140d20cb
@@ -30,15 +30,15 @@ enum {
#include "group.h"
enum {
- QQ_ROOM_AUTH_TYPE_NO_AUTH = 0x01,
- QQ_ROOM_AUTH_TYPE_NEED_AUTH = 0x02,
- QQ_ROOM_AUTH_TYPE_NO_ADD = 0x03
+ QQ_GROUP_AUTH_TYPE_NO_AUTH = 0x01,
+ QQ_GROUP_AUTH_TYPE_NEED_AUTH = 0x02,
+ QQ_GROUP_AUTH_TYPE_NO_ADD = 0x03
};
enum {
- QQ_ROOM_AUTH_REQUEST_APPLY = 0x01,
- QQ_ROOM_AUTH_REQUEST_APPROVE = 0x02,
- QQ_ROOM_AUTH_REQUEST_REJECT = 0x03
+ QQ_GROUP_AUTH_REQUEST_APPLY = 0x01,
+ QQ_GROUP_AUTH_REQUEST_APPROVE = 0x02,
+ QQ_GROUP_AUTH_REQUEST_REJECT = 0x03
};
void qq_send_cmd_group_auth(PurpleConnection *gc, qq_group *group, guint8 opt, guint32 uid, const gchar *reason_utf8);
============================================================
--- libpurple/protocols/qq/group_opt.c 98dd986059a93ab53d153d458a1f9185e335ab2d
+++ libpurple/protocols/qq/group_opt.c cfe88c8ff984e466debb1c62c877f54686a56ac7
@@ -38,7 +38,6 @@
#include "header_info.h"
#include "packet_parse.h"
#include "qq_network.h"
-#include "qq_process.h"
#include "utils.h"
static int _compare_guint32(const void *a,
@@ -68,7 +67,7 @@ static void _qq_group_member_opt(PurpleC
}
data_len = 6 + count * 4;
data = g_newa(guint8, data_len);
-
+
bytes = 0;
bytes += qq_put8(data + bytes, operation);
for (i = 0; i < count; i++)
@@ -89,7 +88,7 @@ static void _qq_group_reject_application
g_return_if_fail(g != NULL && g->gc != NULL && g->id > 0 && g->member > 0);
group = qq_room_search_id(g->gc, g->id);
g_return_if_fail(group != NULL);
- qq_send_cmd_group_auth(g->gc, group, QQ_ROOM_AUTH_REQUEST_REJECT, g->member, msg_utf8);
+ qq_send_cmd_group_auth(g->gc, group, QQ_GROUP_AUTH_REQUEST_REJECT, g->member, msg_utf8);
g_free(g);
}
@@ -112,11 +111,11 @@ void qq_group_reject_application_with_st
g_return_if_fail(g != NULL && g->gc != NULL && g->member > 0);
msg1 = g_strdup_printf(_("You rejected %d's request"), g->member);
- msg2 = g_strdup(_("Message:"));
+ msg2 = g_strdup(_("Enter your reason:"));
nombre = uid_to_purple_name(g->member);
purple_request_input(g->gc, /* title */ NULL, msg1, msg2,
- _("Sorry, you are not my style..."), /* multiline */ TRUE, /* masked */ FALSE,
+ _("Sorry, you are not my type..."), /* multiline */ TRUE, /* masked */ FALSE,
/* hint */ NULL,
_("Send"), G_CALLBACK(_qq_group_reject_application_real),
_("Cancel"), G_CALLBACK(_qq_group_do_nothing_with_struct),
@@ -134,7 +133,7 @@ void qq_group_approve_application_with_s
g_return_if_fail(g != NULL && g->gc != NULL && g->id > 0 && g->member > 0);
group = qq_room_search_id(g->gc, g->id);
g_return_if_fail(group != NULL);
- qq_send_cmd_group_auth(g->gc, group, QQ_ROOM_AUTH_REQUEST_APPROVE, g->member, "");
+ qq_send_cmd_group_auth(g->gc, group, QQ_GROUP_AUTH_REQUEST_APPROVE, g->member, "");
qq_group_find_or_add_member(g->gc, group, g->member);
g_free(g);
}
@@ -190,9 +189,9 @@ void qq_group_modify_members(PurpleConne
qq_group_find_or_add_member(gc, group, add_members[i]);
if (del > 0)
- _qq_group_member_opt(gc, group, QQ_ROOM_MEMBER_DEL, del_members);
+ _qq_group_member_opt(gc, group, QQ_GROUP_MEMBER_DEL, del_members);
if (add > 0)
- _qq_group_member_opt(gc, group, QQ_ROOM_MEMBER_ADD, add_members);
+ _qq_group_member_opt(gc, group, QQ_GROUP_MEMBER_ADD, add_members);
}
void qq_group_process_modify_members_reply(guint8 *data, gint len, PurpleConnection *gc)
@@ -210,10 +209,9 @@ void qq_group_process_modify_members_rep
group = qq_room_search_id(gc, id);
g_return_if_fail(group != NULL);
- purple_debug_info("QQ", "Succeed in modify members for room %d\n", group->ext_id);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Succeed in modify members for Qun %d\n", group->ext_id);
- purple_notify_info(gc, _("QQ Qun Operation"),
- _("You have successfully modified Qun member"), NULL);
+ purple_notify_info(gc, _("QQ Qun Operation"), _("You have successfully modified Qun member"), NULL);
}
void qq_room_change_info(PurpleConnection *gc, qq_group *group)
@@ -225,8 +223,8 @@ void qq_room_change_info(PurpleConnectio
g_return_if_fail(group != NULL);
- group_name = group->title_utf8 == NULL ? "" : utf8_to_qq(group->title_utf8, QQ_CHARSET_DEFAULT);
- group_desc = group->desc_utf8 == NULL ? "" : utf8_to_qq(group->desc_utf8, QQ_CHARSET_DEFAULT);
+ group_name = group->group_name_utf8 == NULL ? "" : utf8_to_qq(group->group_name_utf8, QQ_CHARSET_DEFAULT);
+ group_desc = group->group_desc_utf8 == NULL ? "" : utf8_to_qq(group->group_desc_utf8, QQ_CHARSET_DEFAULT);
notice = group->notice_utf8 == NULL ? "" : utf8_to_qq(group->notice_utf8, QQ_CHARSET_DEFAULT);
data_len = 64 + strlen(group_name) + strlen(group_desc) + strlen(notice);
@@ -239,7 +237,7 @@ void qq_room_change_info(PurpleConnectio
/* 007-008 */
bytes += qq_put16(data + bytes, 0x0000);
/* 009-010 */
- bytes += qq_put16(data + bytes, group->category);
+ bytes += qq_put16(data + bytes, group->group_category);
bytes += qq_put8(data + bytes, strlen(group_name));
bytes += qq_putdata(data + bytes, (guint8 *) group_name, strlen(group_name));
@@ -253,7 +251,7 @@ void qq_room_change_info(PurpleConnectio
bytes += qq_putdata(data + bytes, (guint8 *) group_desc, strlen(group_desc));
if (bytes > data_len) {
- purple_debug_error("QQ",
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ",
"Overflow in qq_room_change_info, max %d bytes, now %d bytes\n",
data_len, bytes);
return;
@@ -276,7 +274,7 @@ void qq_group_process_modify_info_reply(
group = qq_room_search_id(gc, id);
g_return_if_fail(group != NULL);
- purple_debug_info("QQ", "Succeed in modify info for Qun %d\n", group->ext_id);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Succeed in modify info for Qun %d\n", group->ext_id);
qq_group_refresh(gc, group);
purple_notify_info(gc, _("QQ Qun Operation"), _("You have successfully modified Qun information"), NULL);
@@ -299,9 +297,9 @@ void qq_room_create_new(PurpleConnection
bytes = 0;
/* we create the simpleset group, only group name is given */
/* 001 */
- bytes += qq_put8(data + bytes, QQ_ROOM_TYPE_PERMANENT);
+ bytes += qq_put8(data + bytes, QQ_GROUP_TYPE_PERMANENT);
/* 002 */
- bytes += qq_put8(data + bytes, QQ_ROOM_AUTH_TYPE_NEED_AUTH);
+ bytes += qq_put8(data + bytes, QQ_GROUP_AUTH_TYPE_NEED_AUTH);
/* 003-004 */
bytes += qq_put16(data + bytes, 0x0000);
/* 005-006 */
@@ -315,7 +313,7 @@ void qq_room_create_new(PurpleConnection
bytes += qq_put32(data + bytes, qd->uid); /* I am member of coz */
if (bytes > data_len) {
- purple_debug_error("QQ",
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ",
"Overflow in qq_room_create, max %d bytes, now %d bytes\n",
data_len, bytes);
return;
@@ -354,14 +352,14 @@ void qq_group_process_create_group_reply
g_return_if_fail(id > 0 && ext_id);
group = qq_group_create_internal_record(gc, id, ext_id, NULL);
- group->my_role = QQ_ROOM_ROLE_ADMIN;
+ group->my_status = QQ_GROUP_MEMBER_STATUS_IS_ADMIN;
group->creator_uid = qd->uid;
qq_group_refresh(gc, group);
qq_send_room_cmd_only(gc, QQ_ROOM_CMD_ACTIVATE, id);
- qq_room_update(gc, 0, group->id);
+ qq_send_room_cmd_only(gc, QQ_ROOM_CMD_GET_INFO, id);
- purple_debug_info("QQ", "Succeed in create Qun, external ID %d\n", group->ext_id);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Succeed in create Qun, external ID %d\n", group->ext_id);
g = g_new0(gc_and_uid, 1);
g->gc = gc;
@@ -370,7 +368,7 @@ void qq_group_process_create_group_reply
purple_request_action(gc, _("QQ Qun Operation"),
_("You have successfully created a Qun"),
_
- ("Would you like to set up the detail information now?"),
+ ("Would you like to set up the Qun details now?"),
1,
purple_connection_get_account(gc), NULL, NULL,
g, 2,
@@ -393,7 +391,7 @@ void qq_group_process_activate_group_rep
group = qq_room_search_id(gc, id);
g_return_if_fail(group != NULL);
- purple_debug_info("QQ", "Succeed in activate Qun %d\n", group->ext_id);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Succeed in activate Qun %d\n", group->ext_id);
}
void qq_group_manage_group(PurpleConnection *gc, GHashTable *data)
@@ -404,7 +402,7 @@ void qq_group_manage_group(PurpleConnect
g_return_if_fail(data != NULL);
- id_ptr = g_hash_table_lookup(data, QQ_ROOM_KEY_INTERNAL_ID);
+ id_ptr = g_hash_table_lookup(data, QQ_GROUP_KEY_INTERNAL_ID);
id = strtol(id_ptr, NULL, 10);
g_return_if_fail(id > 0);
============================================================
--- libpurple/protocols/qq/group_opt.h 59af741aa7f62b30f0697d841497bb2b6798c546
+++ libpurple/protocols/qq/group_opt.h c4a0487f1ba87e92a56d484b63a0ccdbaeda83ef
@@ -38,13 +38,13 @@ enum {
} group_member_opt;
enum {
- QQ_ROOM_TYPE_PERMANENT = 0x01,
- QQ_ROOM_TYPE_TEMPORARY
+ QQ_GROUP_TYPE_PERMANENT = 0x01,
+ QQ_GROUP_TYPE_TEMPORARY
};
enum {
- QQ_ROOM_MEMBER_ADD = 0x01,
- QQ_ROOM_MEMBER_DEL
+ QQ_GROUP_MEMBER_ADD = 0x01,
+ QQ_GROUP_MEMBER_DEL
};
void qq_group_modify_members(PurpleConnection *gc, qq_group *group, guint32 *new_members);
============================================================
--- libpurple/protocols/qq/group_search.c 07127dd246f2fbd0032f25f9b06f5abe91ec17f7
+++ libpurple/protocols/qq/group_search.c fc5206710a5f2e134a0a97e1d59ae1a4f4be9a46
@@ -38,8 +38,8 @@ enum {
#include "qq_network.h"
enum {
- QQ_ROOM_SEARCH_TYPE_BY_ID = 0x01,
- QQ_ROOM_SEARCH_TYPE_DEMO = 0x02
+ QQ_GROUP_SEARCH_TYPE_BY_ID = 0x01,
+ QQ_GROUP_SEARCH_TYPE_DEMO = 0x02
};
/* send packet to search for qq_group */
@@ -49,7 +49,7 @@ void qq_send_cmd_group_search_group(Purp
gint bytes = 0;
guint8 type;
- type = (ext_id == 0x00000000) ? QQ_ROOM_SEARCH_TYPE_DEMO : QQ_ROOM_SEARCH_TYPE_BY_ID;
+ type = (ext_id == 0x00000000) ? QQ_GROUP_SEARCH_TYPE_DEMO : QQ_GROUP_SEARCH_TYPE_BY_ID;
bytes = 0;
bytes += qq_put8(raw_data + bytes, type);
@@ -63,21 +63,21 @@ static void _qq_setup_roomlist(qq_data *
PurpleRoomlistRoom *room;
gchar field[11];
- room = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_ROOM, group->title_utf8, NULL);
+ room = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_ROOM, group->group_name_utf8, NULL);
g_snprintf(field, sizeof(field), "%d", group->ext_id);
purple_roomlist_room_add_field(qd->roomlist, room, field);
g_snprintf(field, sizeof(field), "%d", group->creator_uid);
purple_roomlist_room_add_field(qd->roomlist, room, field);
- purple_roomlist_room_add_field(qd->roomlist, room, group->desc_utf8);
+ purple_roomlist_room_add_field(qd->roomlist, room, group->group_desc_utf8);
g_snprintf(field, sizeof(field), "%d", group->id);
purple_roomlist_room_add_field(qd->roomlist, room, field);
g_snprintf(field, sizeof(field), "%d", group->type8);
purple_roomlist_room_add_field(qd->roomlist, room, field);
g_snprintf(field, sizeof(field), "%d", group->auth_type);
purple_roomlist_room_add_field(qd->roomlist, room, field);
- g_snprintf(field, sizeof(field), "%d", group->category);
+ g_snprintf(field, sizeof(field), "%d", group->group_category);
purple_roomlist_room_add_field(qd->roomlist, room, field);
- purple_roomlist_room_add_field(qd->roomlist, room, group->title_utf8);
+ purple_roomlist_room_add_field(qd->roomlist, room, group->group_name_utf8);
purple_roomlist_room_add(qd->roomlist, room);
purple_roomlist_set_in_progress(qd->roomlist, FALSE);
@@ -109,14 +109,14 @@ void qq_process_group_cmd_search_group(g
bytes += qq_get16(&(unknown), data + bytes);
bytes += qq_get16(&(unknown), data + bytes);
bytes += qq_get16(&(unknown), data + bytes);
- bytes += qq_get32(&(group.category), data + bytes);
- bytes += convert_as_pascal_string(data + bytes, &(group.title_utf8), QQ_CHARSET_DEFAULT);
+ bytes += qq_get32(&(group.group_category), data + bytes);
+ bytes += convert_as_pascal_string(data + bytes, &(group.group_name_utf8), QQ_CHARSET_DEFAULT);
bytes += qq_get16(&(unknown), data + bytes);
bytes += qq_get8(&(group.auth_type), data + bytes);
- bytes += convert_as_pascal_string(data + bytes, &(group.desc_utf8), QQ_CHARSET_DEFAULT);
+ bytes += convert_as_pascal_string(data + bytes, &(group.group_desc_utf8), QQ_CHARSET_DEFAULT);
/* end of one qq_group */
if(bytes != len) {
- purple_debug_error("QQ",
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ",
"group_cmd_search_group: Dangerous error! maybe protocol changed, notify developers!");
}
@@ -125,7 +125,7 @@ void qq_process_group_cmd_search_group(g
qq_set_pending_id(&qd->joining_groups, group.ext_id, FALSE);
if (qq_room_search_id(gc, group.id) == NULL)
qq_group_create_internal_record(gc,
- group.id, group.ext_id, group.title_utf8);
+ group.id, group.ext_id, group.group_name_utf8);
qq_send_cmd_group_join_group(gc, &group);
} else {
_qq_setup_roomlist(qd, &group);
============================================================
--- libpurple/protocols/qq/header_info.c f6c8d5882aa98e81f4f08d75d9e6f09d1e244bf9
+++ libpurple/protocols/qq/header_info.c 3b81718aecc45aa7425e5da435eeab9b0096a99b
@@ -122,7 +122,7 @@ const gchar *qq_get_ver_desc(gint source
case QQ_SERVER_0100:
return "QQ Server 0100";
default:
- return "Unknown Version";
+ return "Unknown";
}
}
@@ -146,8 +146,8 @@ const gchar *qq_get_cmd_desc(gint cmd)
return "QQ_CMD_DEL_BUDDY";
case QQ_CMD_BUDDY_AUTH:
return "QQ_CMD_BUDDY_AUTH";
- case QQ_CMD_CHANGE_STATUS:
- return "QQ_CMD_CHANGE_STATUS";
+ case QQ_CMD_CHANGE_ONLINE_STATUS:
+ return "QQ_CMD_CHANGE_ONLINE_STATUS";
case QQ_CMD_ACK_SYS_MSG:
return "QQ_CMD_ACK_SYS_MSG";
case QQ_CMD_SEND_IM:
@@ -172,10 +172,10 @@ const gchar *qq_get_cmd_desc(gint cmd)
return "QQ_CMD_TOKEN";
case QQ_CMD_RECV_MSG_SYS:
return "QQ_CMD_RECV_MSG_SYS";
- case QQ_CMD_BUDDY_CHANGE_STATUS:
- return "QQ_CMD_BUDDY_CHANGE_STATUS";
+ case QQ_CMD_RECV_MSG_BUDDY_CHANGE_STATUS:
+ return "QQ_CMD_RECV_MSG_BUDDY_CHANGE_STATUS";
default:
- return "Unknown CMD";
+ return "Unknown";
}
}
@@ -204,8 +204,8 @@ const gchar *qq_get_room_cmd_desc(gint r
return "QQ_ROOM_CMD_SEND_MSG";
case QQ_ROOM_CMD_GET_ONLINES:
return "QQ_ROOM_CMD_GET_ONLINES";
- case QQ_ROOM_CMD_GET_BUDDIES:
- return "QQ_ROOM_CMD_GET_BUDDIES";
+ case QQ_ROOM_CMD_GET_MEMBER_INFO:
+ return "QQ_ROOM_CMD_GET_MEMBER_INFO";
case QQ_ROOM_CMD_CHANGE_CARD:
return "QQ_ROOM_CMD_CHANGE_CARD";
case QQ_ROOM_CMD_GET_REALNAMES:
@@ -231,6 +231,6 @@ const gchar *qq_get_room_cmd_desc(gint r
case QQ_ROOM_CMD_TEMP_GET_MEMBERS:
return "QQ_ROOM_CMD_TEMP_GET_MEMBERS";
default:
- return "Unknown Room Command";
+ return "Unknown QQ Room Command";
}
}
============================================================
--- libpurple/protocols/qq/header_info.h 1fb677b46ef167f921799cfd63a850c36e429cc8
+++ libpurple/protocols/qq/header_info.h b6c6b91c69672f9605fd6dbed3c27a930319b774
@@ -47,7 +47,7 @@ enum {
QQ_CMD_ADD_BUDDY_WO_AUTH = 0x0009, /* add buddy without auth */
QQ_CMD_DEL_BUDDY = 0x000a, /* delete a buddy */
QQ_CMD_BUDDY_AUTH = 0x000b, /* buddy authentication */
- QQ_CMD_CHANGE_STATUS = 0x000d, /* change my online status */
+ QQ_CMD_CHANGE_ONLINE_STATUS = 0x000d, /* change my online status */
QQ_CMD_ACK_SYS_MSG = 0x0012, /* ack system message */
QQ_CMD_SEND_IM = 0x0016, /* send message */
QQ_CMD_RECV_IM = 0x0017, /* receive message */
@@ -59,11 +59,11 @@ enum {
QQ_CMD_GET_BUDDIES_ONLINE = 0x0027, /* get online buddies list */
QQ_CMD_CELL_PHONE_2 = 0x0029, /* cell phone 2 */
QQ_CMD_ROOM = 0x0030, /* room command */
- QQ_CMD_GET_BUDDIES_AND_ROOMS = 0x0058,
+ QQ_CMD_GET_BUDDIES_AND_ROOMS = 0x0058,
QQ_CMD_GET_LEVEL = 0x005C, /* get level for one or more buddies */
QQ_CMD_TOKEN = 0x0062, /* get login token */
QQ_CMD_RECV_MSG_SYS = 0x0080, /* receive a system message */
- QQ_CMD_BUDDY_CHANGE_STATUS = 0x0081, /* buddy change status */
+ QQ_CMD_RECV_MSG_BUDDY_CHANGE_STATUS = 0x0081, /* buddy change status */
};
const gchar *qq_get_cmd_desc(gint type);
@@ -80,7 +80,7 @@ enum {
QQ_ROOM_CMD_QUIT = 0x09,
QQ_ROOM_CMD_SEND_MSG = 0x0a,
QQ_ROOM_CMD_GET_ONLINES = 0x0b,
- QQ_ROOM_CMD_GET_BUDDIES = 0x0c,
+ QQ_ROOM_CMD_GET_MEMBER_INFO = 0x0c,
QQ_ROOM_CMD_CHANGE_CARD = 0x0E,
QQ_ROOM_CMD_GET_REALNAMES = 0x0F,
============================================================
--- libpurple/protocols/qq/im.c 5d3ec6ec0446db7b0d31d8c2613a1bcd42820909
+++ libpurple/protocols/qq/im.c 90e409aba8c08748d11f8702874197fa1f8c6a3d
@@ -209,17 +209,21 @@ static const gchar *qq_get_recv_im_type_
return "QQ_RECV_IM_TEMP_QUN_IM";
case QQ_RECV_IM_QUN_IM:
return "QQ_RECV_IM_QUN_IM";
- case QQ_RECV_IM_NEWS:
- return "QQ_RECV_IM_NEWS";
- case QQ_RECV_IM_FROM_BUDDY_2006:
- return "QQ_RECV_IM_FROM_BUDDY_2006";
- case QQ_RECV_IM_FROM_UNKNOWN_2006:
- return "QQ_RECV_IM_FROM_UNKNOWN_2006";
default:
return "QQ_RECV_IM_UNKNOWN";
}
}
+/* when we receive a message,
+ * we send an ACK which is the first 16 bytes of incoming packet */
+static void _qq_send_packet_recv_im_ack(PurpleConnection *gc, guint16 seq, guint8 *data)
+{
+ qq_data *qd;
+
+ qd = (qq_data *) gc->proto_data;
+ qq_send_cmd_detail(qd, QQ_CMD_RECV_IM, seq, FALSE, data, 16);
+}
+
/* read the common parts of the normal_im,
* returns the bytes read if succeed, or -1 if there is any error */
static gint _qq_normal_im_common_read(guint8 *data, gint len, qq_recv_normal_im_common *common)
@@ -236,61 +240,13 @@ static gint _qq_normal_im_common_read(gu
bytes += qq_get16(&(common->normal_im_type), data + bytes);
if (bytes != 28) { /* read common place fail */
- purple_debug_error("QQ", "Expect 28 bytes, read %d bytes\n", bytes);
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Expect 28 bytes, read %d bytes\n", bytes);
return -1;
}
return bytes;
}
-static void _qq_process_recv_news(guint8 *data, gint data_len, PurpleConnection *gc)
-{
- qq_data *qd = (qq_data *) gc->proto_data;
- gint bytes;
- guint8 *temp;
- guint8 temp_len;
- gchar *title, *brief, *url;
- gchar *content, *content_utf8;
-
- g_return_if_fail(data != NULL && data_len != 0);
-
-#if 0
- qq_show_packet("Rcv news", data, data_len);
-#endif
-
- 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 += 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_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);
-
- content = g_strdup_printf(_("Title: %s\nBrief: %s\n\n%s"), title, brief, url);
- content_utf8 = qq_to_utf8(content, QQ_CHARSET_DEFAULT);
-
- if (qd->is_show_news) {
- purple_notify_info(gc, NULL, _("QQ Server News"), content_utf8);
- } else {
- purple_debug_info("QQ", "QQ Server news:\n%s", content_utf8);
- }
- g_free(title);
- g_free(brief);
- g_free(url);
- g_free(content);
- g_free(content_utf8);
-}
-
/* process received normal text IM */
static void _qq_process_recv_normal_im_text(guint8 *data, gint len, qq_recv_normal_im_common *common, PurpleConnection *gc)
{
@@ -310,7 +266,7 @@ static void _qq_process_recv_normal_im_t
/* now it is QQ_NORMAL_IM_TEXT */
/*
if (*cursor >= (data + len - 1)) {
- purple_debug_warning("QQ", "Received normal IM text is empty\n");
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Received normal IM text is empty\n");
return;
} else
*/
@@ -357,9 +313,9 @@ static void _qq_process_recv_normal_im_t
}
qq_b = (b == NULL) ? NULL : (qq_buddy *) b->proto_data;
if (qq_b != NULL) {
- qq_b->client_version = common->sender_ver;
+ qq_b->client_version = common->sender_ver;
}
-
+
purple_msg_type = (im_text->msg_type == QQ_IM_AUTO_REPLY) ? PURPLE_MESSAGE_AUTO_RESP : 0;
msg_with_purple_smiley = qq_smiley_to_purple(im_text->msg);
@@ -394,18 +350,19 @@ static void _qq_process_recv_normal_im(g
bytes = _qq_normal_im_common_read(data, len, common);
if (bytes < 0) {
- purple_debug_error("QQ", "Fail read the common part of normal IM\n");
+ purple_debug (PURPLE_DEBUG_ERROR, "QQ",
+ "Fail read the common part of normal IM\n");
return;
}
switch (common->normal_im_type) {
case QQ_NORMAL_IM_TEXT:
- purple_debug_info("QQ",
+ purple_debug (PURPLE_DEBUG_INFO, "QQ",
"Normal IM, text type:\n [%d] => [%d], src: %s (%04X)\n",
common->sender_uid, common->receiver_uid,
qq_get_ver_desc (common->sender_ver), common->sender_ver);
if (bytes >= len - 1) {
- purple_debug_warning("QQ", "Received normal IM text is empty\n");
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Received normal IM text is empty\n");
return;
}
_qq_process_recv_normal_im_text(data + bytes, len - bytes, common, gc);
@@ -425,50 +382,16 @@ static void _qq_process_recv_normal_im(g
case QQ_NORMAL_IM_FILE_NOTIFY:
qq_process_recv_file_notify(data + bytes, len - bytes, common->sender_uid, gc);
break;
- case QQ_NORMAL_IM_FILE_REQUEST_TCP:
- /* Check ReceivedFileIM::parseContents in eva*/
- /* some client use this function for detect invisable buddy*/
- purple_debug_warning("QQ", "Normal IM, not support QQ_NORMAL_IM_FILE_REQUEST_TCP\n");
- qq_show_packet ("Not support", data, len);
- break;
- case QQ_NORMAL_IM_FILE_APPROVE_TCP:
- purple_debug_warning("QQ", "Normal IM, not support QQ_NORMAL_IM_FILE_APPROVE_TCP\n");
- qq_show_packet ("Not support", data, len);
- break;
- case QQ_NORMAL_IM_FILE_REJECT_TCP:
- purple_debug_warning("QQ", "Normal IM, not support QQ_NORMAL_IM_FILE_REJECT_TCP\n");
- qq_show_packet ("Not support", data, len);
- break;
- case QQ_NORMAL_IM_FILE_PASV:
- purple_debug_warning("QQ", "Normal IM, not support QQ_NORMAL_IM_FILE_PASV\n");
- qq_show_packet ("Not support", data, len);
- break;
- case QQ_NORMAL_IM_FILE_EX_REQUEST_UDP:
- purple_debug_warning("QQ", "Normal IM, not support QQ_NORMAL_IM_FILE_REQUEST_TCP\n");
- qq_show_packet ("QQ", data, len);
- break;
- case QQ_NORMAL_IM_FILE_EX_REQUEST_ACCEPT:
- purple_debug_warning("QQ", "Normal IM, not support QQ_NORMAL_IM_FILE_EX_REQUEST_ACCEPT\n");
- qq_show_packet ("QQ", data, len);
- break;
- case QQ_NORMAL_IM_FILE_EX_REQUEST_CANCEL:
- purple_debug_warning("QQ", "Normal IM, not support QQ_NORMAL_IM_FILE_EX_REQUEST_CANCEL\n");
- qq_show_packet ("Not support", data, len);
- break;
- case QQ_NORMAL_IM_FILE_EX_NOTIFY_IP:
- purple_debug_warning("QQ", "Normal IM, not support QQ_NORMAL_IM_FILE_EX_NOTIFY_IP\n");
- qq_show_packet ("Not support", data, len);
- break;
default:
im_unprocessed = g_newa (qq_recv_normal_im_unprocessed, 1);
im_unprocessed->common = common;
im_unprocessed->unknown = data + bytes;
im_unprocessed->length = len - bytes;
/* a simple process here, maybe more later */
- purple_debug_warning("QQ",
+ purple_debug (PURPLE_DEBUG_WARNING, "QQ",
"Normal IM, unprocessed type [0x%04x], len %d\n",
common->normal_im_type, im_unprocessed->length);
- qq_show_packet ("QQ", im_unprocessed->unknown, im_unprocessed->length);
+ qq_show_packet ("QQ unk-im", im_unprocessed->unknown, im_unprocessed->length);
return;
}
}
@@ -489,7 +412,7 @@ static void _qq_process_recv_sys_im(guin
reply = strtol(segments[0], NULL, 10);
if (reply == QQ_RECV_SYS_IM_KICK_OUT)
- purple_debug_warning("QQ", "We are kicked out by QQ server\n");
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ", "We are kicked out by QQ server\n");
msg_utf8 = qq_to_utf8(segments[1], QQ_CHARSET_DEFAULT);
purple_notify_warning(gc, NULL, _("System Message"), msg_utf8);
}
@@ -552,7 +475,7 @@ void qq_send_packet_im(PurpleConnection
g_datalist_clear(&attribs);
}
- purple_debug_info("QQ_MESG", "send mesg: %s\n", msg);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ_MESG", "send mesg: %s\n", msg);
msg_filtered = purple_markup_strip_html(msg);
msg_len = strlen(msg_filtered);
now = time(NULL);
@@ -603,9 +526,9 @@ void qq_send_packet_im(PurpleConnection
qq_show_packet("QQ_raw_data debug", raw_data, bytes);
if (bytes == raw_len) /* create packet OK */
- qq_send_cmd(gc, QQ_CMD_SEND_IM, raw_data, bytes);
+ qq_send_cmd(qd, QQ_CMD_SEND_IM, raw_data, bytes);
else
- purple_debug_error("QQ",
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ",
"Fail creating send_im packet, expect %d bytes, build %d bytes\n", raw_len, bytes);
if (font_color)
@@ -626,10 +549,10 @@ void qq_process_send_im_reply(guint8 *da
qd = gc->proto_data;
if (data[0] != QQ_SEND_IM_REPLY_OK) {
- purple_debug_warning("QQ", "Send IM fail\n");
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Send IM fail\n");
purple_notify_error(gc, _("Error"), _("Failed to send IM."), NULL);
} else {
- purple_debug_info("QQ", "IM ACK OK\n");
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "IM ACK OK\n");
}
}
@@ -646,17 +569,16 @@ void qq_process_recv_im(guint8 *data, gi
qd = (qq_data *) gc->proto_data;
if (data_len < 16) { /* we need to ack with the first 16 bytes */
- purple_debug_error("QQ", "MSG is too short\n");
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ", "IM is too short\n");
return;
} else {
- /* when we receive a message,
- * we send an ACK which is the first 16 bytes of incoming packet */
- qq_send_server_reply(gc, QQ_CMD_RECV_IM, seq, data, 16);
+ _qq_send_packet_recv_im_ack(gc, seq, data);
}
/* check len first */
if (data_len < 20) { /* length of im_header */
- purple_debug_error("QQ", "Invald MSG header, len %d < 20\n", data_len);
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ",
+ "Fail read recv IM header, len should longer than 20 bytes, read %d bytes\n", data_len);
return;
}
@@ -672,71 +594,77 @@ void qq_process_recv_im(guint8 *data, gi
/* im_header prepared */
if (im_header->receiver_uid != qd->uid) { /* should not happen */
- purple_debug_error("QQ", "MSG to [%d], NOT me\n", im_header->receiver_uid);
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ", "IM to [%d], NOT me\n", im_header->receiver_uid);
return;
}
/* check bytes */
if (bytes >= data_len - 1) {
- purple_debug_warning("QQ", "Empty MSG\n");
+ purple_debug (PURPLE_DEBUG_WARNING, "QQ", "Received IM is empty\n");
return;
}
switch (im_header->im_type) {
- case QQ_RECV_IM_NEWS:
- _qq_process_recv_news(data + bytes, data_len - bytes, gc);
+ case QQ_RECV_IM_TO_BUDDY:
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ "IM from buddy [%d], I am in his/her buddy list\n", im_header->sender_uid);
+ _qq_process_recv_normal_im(data + bytes, data_len - bytes, gc); /* position and rest length */
break;
- case QQ_RECV_IM_FROM_BUDDY_2006:
- case QQ_RECV_IM_FROM_UNKNOWN_2006:
case QQ_RECV_IM_TO_UNKNOWN:
- case QQ_RECV_IM_TO_BUDDY:
- purple_debug_info("QQ", "MSG from buddy [%d]\n", im_header->sender_uid);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ "IM from buddy [%d], I am a stranger to him/her\n", im_header->sender_uid);
_qq_process_recv_normal_im(data + bytes, data_len - bytes, gc);
break;
case QQ_RECV_IM_UNKNOWN_QUN_IM:
case QQ_RECV_IM_TEMP_QUN_IM:
case QQ_RECV_IM_QUN_IM:
- purple_debug_info("QQ", "MSG from room [%d]\n", im_header->sender_uid);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "IM from group, internal_id [%d]\n", im_header->sender_uid);
/* sender_uid is in fact id */
- qq_process_room_msg_normal(data + bytes, data_len - bytes, im_header->sender_uid, gc, im_header->im_type);
+ qq_process_recv_group_im(data + bytes, data_len - bytes, im_header->sender_uid, gc, im_header->im_type);
break;
case QQ_RECV_IM_ADD_TO_QUN:
- purple_debug_info("QQ", "Notice from [%d], Added\n", im_header->sender_uid);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ "IM from group, added by group internal_id [%d]\n", im_header->sender_uid);
/* sender_uid is group id
* we need this to create a dummy group and add to blist */
- qq_process_room_msg_been_added(data + bytes, data_len - bytes, im_header->sender_uid, gc);
+ qq_process_recv_group_im_been_added(data + bytes, data_len - bytes, im_header->sender_uid, gc);
break;
case QQ_RECV_IM_DEL_FROM_QUN:
- purple_debug_info("QQ", "Notice from room [%d], Removed\n", im_header->sender_uid);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ "IM from group, removed by group internal_ID [%d]\n", im_header->sender_uid);
/* sender_uid is group id */
- qq_process_room_msg_been_removed(data + bytes, data_len - bytes, im_header->sender_uid, gc);
+ qq_process_recv_group_im_been_removed(data + bytes, data_len - bytes, im_header->sender_uid, gc);
break;
case QQ_RECV_IM_APPLY_ADD_TO_QUN:
- purple_debug_info("QQ", "Notice from room [%d], Joined\n", im_header->sender_uid);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ "IM from group, apply to join group internal_ID [%d]\n", im_header->sender_uid);
/* sender_uid is group id */
- qq_process_room_msg_apply_join(data + bytes, data_len - bytes, im_header->sender_uid, gc);
+ qq_process_recv_group_im_apply_join(data + bytes, data_len - bytes, im_header->sender_uid, gc);
break;
case QQ_RECV_IM_APPROVE_APPLY_ADD_TO_QUN:
- purple_debug_info("QQ", "Notice from room [%d], Confirm add in\n",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ "IM for group system info, approved by group internal_id [%d]\n",
im_header->sender_uid);
/* sender_uid is group id */
- qq_process_room_msg_been_approved(data + bytes, data_len - bytes, im_header->sender_uid, gc);
+ qq_process_recv_group_im_been_approved(data + bytes, data_len - bytes, im_header->sender_uid, gc);
break;
case QQ_RECV_IM_REJCT_APPLY_ADD_TO_QUN:
- purple_debug_info("QQ", "Notice from room [%d], Refuse add in\n",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ "IM for group system info, rejected by group internal_id [%d]\n",
im_header->sender_uid);
/* sender_uid is group id */
- qq_process_room_msg_been_rejected(data + bytes, data_len - bytes, im_header->sender_uid, gc);
+ qq_process_recv_group_im_been_rejected(data + bytes, data_len - bytes, im_header->sender_uid, gc);
break;
case QQ_RECV_IM_SYS_NOTIFICATION:
- purple_debug_info("QQ", "Admin notice from [%d]\n", im_header->sender_uid);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ "IM from [%d], should be a system administrator\n", im_header->sender_uid);
_qq_process_recv_sys_im(data + bytes, data_len - bytes, gc);
break;
default:
- purple_debug_warning("QQ", "MSG from [%d], unknown type %s [0x%02x]\n",
- im_header->sender_uid, qq_get_recv_im_type_str(im_header->im_type),
- im_header->im_type);
- qq_show_packet("Unknown MSG type", data, data_len);
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ",
+ "IM from [%d], [0x%02x] %s is not processed\n",
+ im_header->sender_uid,
+ im_header->im_type, qq_get_recv_im_type_str(im_header->im_type));
}
}
============================================================
--- libpurple/protocols/qq/im.h 0dbb0b4261a59a829f78c7b75a43c416ee868329
+++ libpurple/protocols/qq/im.h 9bb66bca43da19dfdcd526333228f8dd7648de75
@@ -41,7 +41,6 @@ enum {
enum {
QQ_RECV_IM_TO_BUDDY = 0x0009,
QQ_RECV_IM_TO_UNKNOWN = 0x000a,
- QQ_RECV_IM_NEWS = 0x0018,
QQ_RECV_IM_UNKNOWN_QUN_IM = 0x0020,
QQ_RECV_IM_ADD_TO_QUN = 0x0021,
QQ_RECV_IM_DEL_FROM_QUN = 0x0022,
@@ -51,9 +50,7 @@ enum {
QQ_RECV_IM_CREATE_QUN = 0x0026,
QQ_RECV_IM_TEMP_QUN_IM = 0x002A,
QQ_RECV_IM_QUN_IM = 0x002B,
- QQ_RECV_IM_SYS_NOTIFICATION = 0x0030,
- QQ_RECV_IM_FROM_BUDDY_2006 = 0x0084,
- QQ_RECV_IM_FROM_UNKNOWN_2006 = 0x0085,
+ QQ_RECV_IM_SYS_NOTIFICATION = 0x0030
};
guint8 *qq_get_send_im_tail(const gchar *font_color,
============================================================
--- libpurple/protocols/qq/packet_parse.c 21732e9a4c9b39b77a94bd80073695ba1a12c103
+++ libpurple/protocols/qq/packet_parse.c 803b01df2d219f62afc4b1813faca0f67c82e5ae
@@ -46,8 +46,8 @@ gint qq_get8(guint8 *b, guint8 *buf)
memcpy(&b_dest, buf, sizeof(b_dest));
*b = b_dest;
#ifdef PARSER_DEBUG
- purple_debug_info("QQ", "[DBG][get8] buf %p\n", (void *)buf);
- purple_debug_info("QQ", "[DBG][get8] b_dest 0x%2x, *b 0x%02x\n", b_dest, *b);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "[DBG][get8] buf %p\n", (void *)buf);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "[DBG][get8] b_dest 0x%2x, *b 0x%02x\n", b_dest, *b);
#endif
return sizeof(b_dest);
}
@@ -61,8 +61,8 @@ gint qq_get16(guint16 *w, guint8 *buf)
memcpy(&w_dest, buf, sizeof(w_dest));
*w = g_ntohs(w_dest);
#ifdef PARSER_DEBUG
- purple_debug_info("QQ", "[DBG][get16] buf %p\n", (void *)buf);
- purple_debug_info("QQ", "[DBG][get16] w_dest 0x%04x, *w 0x%04x\n", w_dest, *w);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "[DBG][get16] buf %p\n", (void *)buf);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "[DBG][get16] w_dest 0x%04x, *w 0x%04x\n", w_dest, *w);
#endif
return sizeof(w_dest);
}
@@ -75,8 +75,8 @@ gint qq_get32(guint32 *dw, guint8 *buf)
memcpy(&dw_dest, buf, sizeof(dw_dest));
*dw = g_ntohl(dw_dest);
#ifdef PARSER_DEBUG
- purple_debug_info("QQ", "[DBG][get32] buf %p\n", (void *)buf);
- purple_debug_info("QQ", "[DBG][get32] dw_dest 0x%08x, *dw 0x%08x\n", dw_dest, *dw);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "[DBG][get32] buf %p\n", (void *)buf);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "[DBG][get32] dw_dest 0x%08x, *dw 0x%08x\n", dw_dest, *dw);
#endif
return sizeof(dw_dest);
}
@@ -93,7 +93,7 @@ gint qq_getdata(guint8 *data, gint datal
{
memcpy(data, buf, datalen);
#ifdef PARSER_DEBUG
- purple_debug_info("QQ", "[DBG][getdata] buf %p\n", (void *)buf);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "[DBG][getdata] buf %p\n", (void *)buf);
#endif
return datalen;
}
@@ -107,12 +107,12 @@ gint qq_getime(time_t *t, guint8 *buf)
guint32 dw_dest;
memcpy(&dw_dest, buf, sizeof(dw_dest));
#ifdef PARSER_DEBUG
- purple_debug_info("QQ", "[DBG][getime] buf %p\n", (void *)buf);
- purple_debug_info("QQ", "[DBG][getime] dw_dest before 0x%08x\n", dw_dest);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "[DBG][getime] buf %p\n", (void *)buf);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "[DBG][getime] dw_dest before 0x%08x\n", dw_dest);
#endif
dw_dest = g_ntohl(dw_dest);
#ifdef PARSER_DEBUG
- purple_debug_info("QQ", "[DBG][getime] dw_dest after 0x%08x\n", dw_dest);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "[DBG][getime] dw_dest after 0x%08x\n", dw_dest);
#endif
memcpy(t, &dw_dest, sizeof(dw_dest));
return sizeof(dw_dest);
@@ -125,8 +125,8 @@ gint qq_put8(guint8 *buf, guint8 b)
{
memcpy(buf, &b, sizeof(b));
#ifdef PARSER_DEBUG
- purple_debug_info("QQ", "[DBG][put8] buf %p\n", (void *)buf);
- purple_debug_info("QQ", "[DBG][put8] b 0x%02x\n", b);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "[DBG][put8] buf %p\n", (void *)buf);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "[DBG][put8] b 0x%02x\n", b);
#endif
return sizeof(b);
}
@@ -139,8 +139,8 @@ gint qq_put16(guint8 *buf, guint16 w)
guint16 w_porter;
w_porter = g_htons(w);
#ifdef PARSER_DEBUG
- purple_debug_info("QQ", "[DBG][put16] buf %p\n", (void *)buf);
- purple_debug_info("QQ", "[DBG][put16] w 0x%04x, w_porter 0x%04x\n", w, w_porter);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "[DBG][put16] buf %p\n", (void *)buf);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "[DBG][put16] w 0x%04x, w_porter 0x%04x\n", w, w_porter);
#endif
memcpy(buf, &w_porter, sizeof(w_porter));
return sizeof(w_porter);
@@ -154,8 +154,8 @@ gint qq_put32(guint8 *buf, guint32 dw)
guint32 dw_porter;
dw_porter = g_htonl(dw);
#ifdef PARSER_DEBUG
- purple_debug_info("QQ", "[DBG][put32] buf %p\n", (void *)buf);
- purple_debug_info("QQ", "[DBG][put32] dw 0x%08x, dw_porter 0x%08x\n", dw, dw_porter);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "[DBG][put32] buf %p\n", (void *)buf);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "[DBG][put32] dw 0x%08x, dw_porter 0x%08x\n", dw, dw_porter);
#endif
memcpy(buf, &dw_porter, sizeof(dw_porter));
return sizeof(dw_porter);
@@ -173,7 +173,7 @@ gint qq_putdata(guint8 *buf, const guint
{
memcpy(buf, data, datalen);
#ifdef PARSER_DEBUG
- purple_debug_info("QQ", "[DBG][putdata] buf %p\n", (void *)buf);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "[DBG][putdata] buf %p\n", (void *)buf);
#endif
return datalen;
}
============================================================
--- libpurple/protocols/qq/qq.c 5a34bedb1748ea86e3abef9336083ad12ffa53e7
+++ libpurple/protocols/qq/qq.c c1ad87252bd96d8470a6d1768d68e67eb034416a
@@ -24,6 +24,10 @@
#include "internal.h"
+#ifdef _WIN32
+#define random rand
+#endif
+
#include "accountopt.h"
#include "debug.h"
#include "notify.h"
@@ -58,72 +62,79 @@
#define OPENQ_AUTHOR "Puzzlebird"
#define OPENQ_WEBSITE "http://openq.sourceforge.net"
-static GList *server_list_build(gchar select)
-{
- GList *list = NULL;
+#define QQ_TCP_PORT 8000
+#define QQ_UDP_PORT 8000
- if ( select == 'T' || select == 'A') {
- list = g_list_append(list, "tcpconn.tencent.com:8000");
- list = g_list_append(list, "tcpconn2.tencent.com:8000");
- list = g_list_append(list, "tcpconn3.tencent.com:8000");
- list = g_list_append(list, "tcpconn4.tencent.com:8000");
- list = g_list_append(list, "tcpconn5.tencent.com:8000");
- list = g_list_append(list, "tcpconn6.tencent.com:8000");
- }
- if ( select == 'U' || select == 'A') {
- list = g_list_append(list, "sz.tencent.com:8000");
- list = g_list_append(list, "sz2.tencent.com:8000");
- list = g_list_append(list, "sz3.tencent.com:8000");
- list = g_list_append(list, "sz4.tencent.com:8000");
- list = g_list_append(list, "sz5.tencent.com:8000");
- list = g_list_append(list, "sz6.tencent.com:8000");
- list = g_list_append(list, "sz7.tencent.com:8000");
- list = g_list_append(list, "sz8.tencent.com:8000");
- list = g_list_append(list, "sz9.tencent.com:8000");
- }
- return list;
-}
-
-static void server_list_create(PurpleAccount *account)
-{
+static void server_list_create(PurpleAccount *account) {
PurpleConnection *gc;
qq_data *qd;
- PurpleProxyInfo *gpi;
const gchar *user_server;
+ int port;
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Create server list\n");
gc = purple_account_get_connection(account);
g_return_if_fail(gc != NULL && gc->proto_data != NULL);
qd = gc->proto_data;
- gpi = purple_proxy_get_setup(account);
+ qd->use_tcp = purple_account_get_bool(account, "use_tcp", TRUE);
+ port = purple_account_get_int(account, "port", 0);
+ if (port == 0) {
+ if (qd->use_tcp) {
+ port = QQ_TCP_PORT;
+ } else {
+ port = QQ_UDP_PORT;
+ }
+ }
+ qd->user_port = port;
- qd->use_tcp = TRUE;
- if (purple_proxy_info_get_type(gpi) == PURPLE_PROXY_UDP) {
- qd->use_tcp = FALSE;
+ g_return_if_fail(qd->user_server == NULL);
+ user_server = purple_account_get_string(account, "server", NULL);
+ if (user_server != NULL && strlen(user_server) > 0) {
+ qd->user_server = g_strdup(user_server);
}
- user_server = purple_account_get_string(account, "server", NULL);
- purple_debug_info("QQ", "Select server '%s'\n", user_server);
- if ( (user_server != NULL && strlen(user_server) > 0) && strcasecmp(user_server, "auto") != 0) {
- qd->servers = g_list_append(qd->servers, g_strdup(user_server));
+ if (qd->user_server != NULL) {
+ qd->servers = g_list_append(qd->servers, qd->user_server);
return;
}
-
if (qd->use_tcp) {
- qd->servers = server_list_build('T');
+ qd->servers = g_list_append(qd->servers, "tcpconn.tencent.com");
+ qd->servers = g_list_append(qd->servers, "tcpconn2.tencent.com");
+ qd->servers = g_list_append(qd->servers, "tcpconn3.tencent.com");
+ qd->servers = g_list_append(qd->servers, "tcpconn4.tencent.com");
+ qd->servers = g_list_append(qd->servers, "tcpconn5.tencent.com");
+ qd->servers = g_list_append(qd->servers, "tcpconn6.tencent.com");
return;
}
-
- qd->servers = server_list_build('U');
+
+ qd->servers = g_list_append(qd->servers, "sz.tencent.com");
+ qd->servers = g_list_append(qd->servers, "sz2.tencent.com");
+ qd->servers = g_list_append(qd->servers, "sz3.tencent.com");
+ qd->servers = g_list_append(qd->servers, "sz4.tencent.com");
+ qd->servers = g_list_append(qd->servers, "sz5.tencent.com");
+ qd->servers = g_list_append(qd->servers, "sz6.tencent.com");
+ qd->servers = g_list_append(qd->servers, "sz7.tencent.com");
+ qd->servers = g_list_append(qd->servers, "sz8.tencent.com");
+ qd->servers = g_list_append(qd->servers, "sz9.tencent.com");
}
-static void server_list_remove_all(qq_data *qd)
-{
+static void server_list_remove_all(qq_data *qd) {
g_return_if_fail(qd != NULL);
- purple_debug_info("QQ", "free server list\n");
+ if (qd->real_hostname) {
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "free real_hostname\n");
+ g_free(qd->real_hostname);
+ qd->real_hostname = NULL;
+ }
+
+ if (qd->user_server != NULL) {
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "free user_server\n");
+ g_free(qd->user_server);
+ qd->user_server = NULL;
+ }
+
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "free server list\n");
g_list_free(qd->servers);
- qd->curr_server = NULL;
}
static void qq_login(PurpleAccount *account)
@@ -140,7 +151,6 @@ static void qq_login(PurpleAccount *acco
gc->flags |= PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_NO_BGCOLOR | PURPLE_CONNECTION_AUTO_RESP;
qd = g_new0(qq_data, 1);
- memset(qd, 0, sizeof(qq_data));
qd->gc = gc;
gc->proto_data = qd;
@@ -155,31 +165,10 @@ static void qq_login(PurpleAccount *acco
}
server_list_create(account);
- purple_debug_info("QQ", "Server list has %d\n", g_list_length(qd->servers));
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ "Server list has %d\n", g_list_length(qd->servers));
- qd->is_show_notice = purple_account_get_bool(account, "show_notice", TRUE);
- qd->is_show_news = purple_account_get_bool(account, "show_news", TRUE);
-
- qd->itv_config.resend = purple_account_get_int(account, "resend_interval", 10);
- if (qd->itv_config.resend <= 0) qd->itv_config.resend = 10;
-
- qd->itv_config.keep_alive = purple_account_get_int(account, "keep_alive_interval", 60);
- if (qd->itv_config.keep_alive < 30) qd->itv_config.keep_alive = 30;
- qd->itv_config.keep_alive /= qd->itv_config.resend;
- qd->itv_count.keep_alive = qd->itv_config.keep_alive;
-
- qd->itv_config.update = purple_account_get_int(account, "update_interval", 300);
- if (qd->itv_config.update > 0) {
- if (qd->itv_config.update < qd->itv_config.keep_alive) {
- qd->itv_config.update = qd->itv_config.keep_alive;
- }
- qd->itv_config.update /= qd->itv_config.resend;
- qd->itv_count.update = qd->itv_config.update;
- } else {
- qd->itv_config.update = 0;
- }
-
- qd->connect_watcher = purple_timeout_add_seconds(0, qq_connect_later, gc);
+ qq_connect(account);
}
/* clean up the given QQ connection and free all resources */
@@ -190,20 +179,12 @@ static void qq_close(PurpleConnection *g
g_return_if_fail(gc != NULL && gc->proto_data);
qd = gc->proto_data;
- if (qd->check_watcher > 0) {
- purple_timeout_remove(qd->check_watcher);
- qd->check_watcher = 0;
- }
+ qq_disconnect(gc);
- if (qd->connect_watcher > 0) {
- purple_timeout_remove(qd->connect_watcher);
- qd->connect_watcher = 0;
- }
-
- qq_disconnect(gc);
server_list_remove_all(qd);
-
+
g_free(qd);
+
gc->proto_data = NULL;
}
@@ -231,7 +212,7 @@ static gchar *_qq_status_text(PurpleBudd
g_string_append(status, _("Offline"));
break;
case QQ_BUDDY_ONLINE_NORMAL:
- g_string_append(status, _("Online"));
+ return NULL;
break;
/* TODO What does this status mean? Labelling it as offline... */
case QQ_BUDDY_ONLINE_OFFLINE:
@@ -322,8 +303,8 @@ static void _qq_tooltip_text(PurpleBuddy
g_string_append( str, _(" Video") );
}
- if (q_bud->ext_flag & QQ_EXT_FLAG_ZONE) {
- g_string_append( str, _(" Zone") );
+ if (q_bud->ext_flag & QQ_EXT_FLAG_SPACE) {
+ g_string_append( str, _(" Space") );
}
purple_notify_user_info_add_pair(user_info, _("Flag"), str->str);
@@ -348,7 +329,7 @@ static const char *_qq_list_emblem(Purpl
{
/* each char** are refering to a filename in pixmaps/purple/status/default/ */
qq_buddy *q_bud;
-
+
if (!b || !(q_bud = b->proto_data)) {
return NULL;
}
@@ -393,11 +374,11 @@ static GList *_qq_away_states(PurpleAcco
}
/* initiate QQ away with proper change_status packet */
-static void _qq_change_status(PurpleAccount *account, PurpleStatus *status)
+static void _qq_set_away(PurpleAccount *account, PurpleStatus *status)
{
PurpleConnection *gc = purple_account_get_connection(account);
- qq_request_change_status(gc, 0);
+ qq_send_packet_change_status(gc);
}
/* IMPORTANT: PurpleConvImFlags -> PurpleMessageFlags */
@@ -463,7 +444,7 @@ static void _qq_get_info(PurpleConnectio
uid = purple_name_to_uid(who);
if (uid <= 0) {
- purple_debug_error("QQ", "Not valid QQid: %s\n", who);
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Not valid QQid: %s\n", who);
purple_notify_error(gc, NULL, _("Invalid name"), NULL);
return;
}
@@ -535,8 +516,9 @@ static void _qq_menu_show_login_info(Pur
g_string_append(info, "<hr>\n");
- g_string_append_printf(info, _("<b>Server</b>: %s<br>\n"), qd->curr_server);
+ g_string_append_printf(info, _("<b>Server</b>: %s: %d<br>\n"), qd->server_name, qd->real_port);
g_string_append_printf(info, _("<b>Connection Mode</b>: %s<br>\n"), qd->use_tcp ? "TCP" : "UDP");
+ g_string_append_printf(info, _("<b>Real hostname</b>: %s: %d<br>\n"), qd->real_hostname, qd->real_port);
g_string_append_printf(info, _("<b>My Public IP</b>: %s<br>\n"), inet_ntoa(qd->my_ip));
g_string_append(info, "<hr>\n");
@@ -651,7 +633,7 @@ static GList *_qq_chat_menu(PurpleBlistN
PurpleMenuAction *act;
m = NULL;
- act = purple_menu_action_new(_("Leave the QQ Qun"), PURPLE_CALLBACK(_qq_menu_unsubscribe_group), NULL, NULL);
+ act = purple_menu_action_new(_("Leave this QQ Qun"), PURPLE_CALLBACK(_qq_menu_unsubscribe_group), NULL, NULL);
m = g_list_append(m, act);
/* TODO: enable this
@@ -726,7 +708,7 @@ static PurplePluginProtocolInfo prpl_inf
NULL, /* set_info */
NULL, /* send_typing */
_qq_get_info, /* get_info */
- _qq_change_status, /* change status */
+ _qq_set_away, /* set_away */
NULL, /* set_idle */
NULL, /* change_passwd */
qq_add_buddy, /* add_buddy */
@@ -818,52 +800,19 @@ static void init_plugin(PurplePlugin *pl
static void init_plugin(PurplePlugin *plugin)
{
PurpleAccountOption *option;
- PurpleKeyValuePair *kvp;
- GList *list = NULL;
- GList *kvlist = NULL;
- GList *entry;
- list = server_list_build('A');
-
- purple_prefs_add_string_list("/plugins/prpl/qq/serverlist", list);
- list = purple_prefs_get_string_list("/plugins/prpl/qq/serverlist");
-
- kvlist = NULL;
- kvp = g_new0(PurpleKeyValuePair, 1);
- kvp->key = g_strdup(_("Auto"));
- kvp->value = g_strdup("auto");
- kvlist = g_list_append(kvlist, kvp);
-
- entry = list;
- while(entry) {
- if (entry->data != NULL && strlen(entry->data) > 0) {
- kvp = g_new0(PurpleKeyValuePair, 1);
- kvp->key = g_strdup(entry->data);
- kvp->value = g_strdup(entry->data);
- kvlist = g_list_append(kvlist, kvp);
- }
- entry = entry->next;
- }
-
- /*
option = purple_account_option_string_new(_("Server"), "server", NULL);
prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
option = purple_account_option_int_new(_("Port"), "port", 0);
prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- */
- option = purple_account_option_list_new(_("Server"), "server", kvlist);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- option = purple_account_option_bool_new(_("Show server notice"), "show_notice", TRUE);
+ option = purple_account_option_bool_new(_("Connect using TCP"), "use_tcp", TRUE);
prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- option = purple_account_option_bool_new(_("Show server news"), "show_news", TRUE);
+ option = purple_account_option_int_new(_("resend interval(s)"), "resend_interval", 10);
prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- option = purple_account_option_int_new(_("Resend interval(s)"), "resend_interval", 10);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
-
option = purple_account_option_int_new(_("Keep alive interval(s)"), "keep_alive_interval", 60);
prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
@@ -874,7 +823,6 @@ static void init_plugin(PurplePlugin *pl
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/prompt_group_msg_on_recv", TRUE);
-
}
PURPLE_INIT_PLUGIN(qq, init_plugin, info);
============================================================
--- libpurple/protocols/qq/qq.h b59cc95c61437ae001fd4611c1bbca9f33edca83
+++ libpurple/protocols/qq/qq.h 17c7a1179cc82fcae2d3231ddf7883b78b7a9804
@@ -36,11 +36,6 @@
#define QQ_KEY_LENGTH 16
-#ifdef _WIN32
-const char *qq_win32_buddy_icon_dir(void);
-#define QQ_BUDDY_ICON_DIR qq_win32_buddy_icon_dir()
-#endif
-
typedef struct _qq_data qq_data;
typedef struct _qq_buddy qq_buddy;
typedef struct _qq_interval qq_interval;
@@ -68,46 +63,45 @@ struct _qq_buddy {
guint16 timeRemainder;
time_t signon;
time_t idle;
- time_t last_update;
+ time_t last_refresh;
gint8 role; /* role in group, used only in group->members list */
};
-typedef struct _qq_connection qq_connection;
-struct _qq_connection {
- int fd; /* socket file handler */
- int input_handler;
-
- /* tcp related */
- int can_write_handler; /* use in tcp_send_out */
- PurpleCircBuffer *tcp_txbuf;
- guint8 *tcp_rxqueue;
- int tcp_rxlen;
-};
-
struct _qq_data {
PurpleConnection *gc;
- GSList *openconns;
+ /* common network resource */
+ GList *servers;
+ gchar *user_server;
+ gint user_port;
gboolean use_tcp; /* network in tcp or udp */
- PurpleProxyConnectData *conn_data;
- gint fd; /* socket file handler */
-
- GList *servers;
- gchar *curr_server; /* point to servers->data, do not free*/
- struct in_addr redirect_ip;
- guint16 redirect_port;
- guint check_watcher;
- guint connect_watcher;
- gint connect_retry;
+ gchar *server_name;
+ gboolean is_redirect;
+ gchar *real_hostname; /* from real connction */
+ guint16 real_port;
+ guint reconnect_timeout;
+ gint reconnect_times;
+ PurpleProxyConnectData *connect_data;
+ gint fd; /* socket file handler */
+ gint tx_handler; /* socket can_write handle, use in udp connecting and tcp send out */
+
qq_interval itv_config;
qq_interval itv_count;
- guint network_watcher;
+ guint network_timeout;
GList *transactions; /* check ack packet and resend */
+ /* tcp related */
+ PurpleCircBuffer *tcp_txbuf;
+ guint8 *tcp_rxqueue;
+ int tcp_rxlen;
+
+ /* udp related */
+ PurpleDnsQueryData *udp_query_data;
+
guint32 uid; /* QQ number */
guint8 *token; /* get from server*/
int token_len;
@@ -118,8 +112,7 @@ struct _qq_data {
guint16 send_seq; /* send sequence number */
guint8 login_mode; /* online of invisible */
- gboolean is_login; /* used by qq-add_buddy */
- gboolean is_finish_update;
+ gboolean logged_in; /* used by qq-add_buddy */
PurpleXfer *xfer; /* file transfer handler */
@@ -150,9 +143,6 @@ struct _qq_data {
/* TODO pass qq_send_packet_get_info() a callback and use signals to get rid of these */
gboolean modifying_info;
gboolean modifying_face;
-
- gboolean is_show_notice;
- gboolean is_show_news;
};
#endif
============================================================
--- libpurple/protocols/qq/qq_base.c 6ca17e28fe0a03df4a08018804b3c0c2a51f0b11
+++ libpurple/protocols/qq/qq_base.c 529b343ed51bb7740d680c11e73b2f473bca9d48
@@ -48,7 +48,7 @@
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xbf, 0x14, 0x11, 0x20,
0x03, 0x9d, 0xb2, 0xe6, 0xb3, 0x11, 0xb7, 0x13,
- 0x95, 0x67, 0xda, 0x2c, 0x01
+ 0x95, 0x67, 0xda, 0x2c, 0x01
}; */
/* for QQ 2003iii 0304, fixed value */
@@ -139,7 +139,7 @@ static void get_session_md5(guint8 *sess
{
guint8 src[QQ_KEY_LENGTH + QQ_KEY_LENGTH];
gint bytes = 0;
-
+
bytes += qq_put32(src + bytes, uid);
bytes += qq_putdata(src + bytes, session_key, QQ_KEY_LENGTH);
@@ -161,7 +161,7 @@ static gint8 process_login_ok(PurpleConn
bytes += qq_get8(&lrop.result, data + bytes);
/* 001-016: session key */
bytes += qq_getdata(lrop.session_key, sizeof(lrop.session_key), data + bytes);
- purple_debug_info("QQ", "Got session_key\n");
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Got session_key\n");
/* 017-020: login uid */
bytes += qq_get32(&lrop.uid, data + bytes);
/* 021-024: server detected user public IP */
@@ -200,16 +200,16 @@ static gint8 process_login_ok(PurpleConn
bytes += qq_getdata((guint8 *) &lrop.unknown6, 8, data + bytes);
if (bytes != QQ_LOGIN_REPLY_OK_PACKET_LEN) { /* fail parsing login info */
- purple_debug_warning("QQ",
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ",
"Fail parsing login info, expect %d bytes, read %d bytes\n",
QQ_LOGIN_REPLY_OK_PACKET_LEN, bytes);
} /* but we still go on as login OK */
memcpy(qd->session_key, lrop.session_key, sizeof(qd->session_key));
get_session_md5(qd->session_md5, qd->uid, qd->session_key);
-
+
qd->my_ip.s_addr = lrop.client_ip.s_addr;
-
+
qd->my_port = lrop.client_port;
qd->login_time = lrop.login_time;
qd->last_login_time = lrop.last_login_time;
@@ -237,19 +237,39 @@ static gint8 process_login_redirect(Purp
bytes += qq_get16(&lrrp.new_server_port, data + bytes);
if (bytes != QQ_LOGIN_REPLY_REDIRECT_PACKET_LEN) {
- purple_debug_error("QQ",
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ",
"Fail parsing login redirect packet, expect %d bytes, read %d bytes\n",
QQ_LOGIN_REPLY_REDIRECT_PACKET_LEN, bytes);
return QQ_LOGIN_REPLY_ERR_MISC;
}
-
+
/* redirect to new server, do not disconnect or connect here
* those connect should be called at packet_process */
- qd->redirect_ip.s_addr = lrrp.new_server_ip.s_addr;
- qd->redirect_port = lrrp.new_server_port;
+ if (qd->real_hostname) {
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "free real_hostname\n");
+ g_free(qd->real_hostname);
+ qd->real_hostname = NULL;
+ }
+ qd->real_hostname = g_strdup( inet_ntoa(lrrp.new_server_ip) );
+ qd->real_port = lrrp.new_server_port;
+
return QQ_LOGIN_REPLY_REDIRECT;
}
+/* process login reply which says wrong password */
+static gint8 process_login_wrong_pwd(PurpleConnection *gc, guint8 *data, gint len)
+{
+ gchar *server_reply, *server_reply_utf8;
+ server_reply = g_new0(gchar, len);
+ g_memmove(server_reply, data + 1, len - 1);
+ server_reply_utf8 = qq_to_utf8(server_reply, QQ_CHARSET_DEFAULT);
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Wrong password, server msg in UTF8: %s\n", server_reply_utf8);
+ g_free(server_reply);
+ g_free(server_reply_utf8);
+
+ return QQ_LOGIN_REPLY_ERR_PWD;
+}
+
/* request before login */
void qq_send_packet_token(PurpleConnection *gc)
{
@@ -261,9 +281,9 @@ void qq_send_packet_token(PurpleConnecti
qd = (qq_data *) gc->proto_data;
bytes += qq_put8(buf + bytes, 0);
-
+
qd->send_seq++;
- qq_send_cmd_encrypted(gc, QQ_CMD_TOKEN, qd->send_seq, buf, bytes, TRUE);
+ qq_send_data(qd, QQ_CMD_TOKEN, qd->send_seq, TRUE, buf, bytes);
}
/* send login packet to QQ server */
@@ -292,14 +312,14 @@ void qq_send_packet_login(PurpleConnecti
memset(raw_data, 0, QQ_LOGIN_DATA_LENGTH);
encrypted_data = g_newa(guint8, QQ_LOGIN_DATA_LENGTH + 16); /* 16 bytes more */
-
+
bytes = 0;
/* now generate the encrypted data
* 000-015 use password_twice_md5 as key to encrypt empty string */
encrypted_len = qq_encrypt(raw_data + bytes, (guint8 *) "", 0, qd->password_twice_md5);
g_return_if_fail(encrypted_len == 16);
bytes += encrypted_len;
-
+
/* 016-016 */
bytes += qq_put8(raw_data + bytes, 0x00);
/* 017-020, used to be IP, now zero */
@@ -329,15 +349,14 @@ void qq_send_packet_login(PurpleConnecti
bytes += qq_putdata(buf + bytes, encrypted_data, encrypted_len);
qd->send_seq++;
- qq_send_cmd_encrypted(gc, QQ_CMD_LOGIN, qd->send_seq, buf, bytes, TRUE);
+ qq_send_data(qd, QQ_CMD_LOGIN, qd->send_seq, TRUE, buf, bytes);
}
-guint8 qq_process_token_reply(PurpleConnection *gc, guint8 *buf, gint buf_len)
+guint8 qq_process_token_reply(PurpleConnection *gc, gchar *error_msg, guint8 *buf, gint buf_len)
{
qq_data *qd;
guint8 ret;
int token_len;
- gchar *error_msg;
g_return_val_if_fail(buf != NULL && buf_len != 0, -1);
@@ -345,37 +364,30 @@ guint8 qq_process_token_reply(PurpleConn
qd = (qq_data *) gc->proto_data;
ret = buf[0];
-
+
if (ret != QQ_TOKEN_REPLY_OK) {
- purple_debug_error("QQ", "Failed to request token: %d\n", buf[0]);
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Unknown request login token reply code : %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);
- }
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_msg);
- g_free(error_msg);
return ret;
}
-
+
token_len = buf_len-2;
if (token_len <= 0) {
error_msg = g_strdup_printf( _("Invalid token len, %d"), token_len);
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_msg);
- g_free(error_msg);
return -1;
}
-
+
if (buf[1] != token_len) {
- purple_debug_info("QQ",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
"Invalid token len. Packet specifies length of %d, actual length is %d\n", buf[1], buf_len-2);
}
qq_hex_dump(PURPLE_DEBUG_INFO, "QQ",
buf+2, token_len,
"<<< got a token -> [default] decrypt and dump");
-
+
qd->token = g_new0(guint8, token_len);
qd->token_len = token_len;
g_memmove(qd->token, buf + 2, qd->token_len);
@@ -390,85 +402,48 @@ void qq_send_packet_logout(PurpleConnect
qd = (qq_data *) gc->proto_data;
for (i = 0; i < 4; i++)
- qq_send_cmd(gc, QQ_CMD_LOGOUT, qd->password_twice_md5, QQ_KEY_LENGTH);
+ qq_send_cmd_detail(qd, QQ_CMD_LOGOUT, 0xffff, FALSE, qd->password_twice_md5, QQ_KEY_LENGTH);
- qd->is_login = FALSE; /* update login status AFTER sending logout packets */
+ qd->logged_in = FALSE; /* update login status AFTER sending logout packets */
}
/* process the login reply packet */
-guint8 qq_process_login_reply( PurpleConnection *gc, guint8 *data, gint data_len)
+guint8 qq_process_login_reply(guint8 *data, gint data_len, PurpleConnection *gc)
{
qq_data *qd;
- guint8 ret = data[0];
- gchar *server_reply, *server_reply_utf8;
- gchar *error_msg;
+ gchar* error_msg;
g_return_val_if_fail(data != NULL && data_len != 0, QQ_LOGIN_REPLY_ERR_MISC);
qd = (qq_data *) gc->proto_data;
- switch (ret) {
+ switch (data[0]) {
case QQ_LOGIN_REPLY_OK:
- purple_debug_info("QQ", "Login OK\n");
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Login reply is OK\n");
return process_login_ok(gc, data, data_len);
case QQ_LOGIN_REPLY_REDIRECT:
- purple_debug_info("QQ", "Redirect new server\n");
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Login reply is redirect\n");
return process_login_redirect(gc, data, data_len);
-
- case QQ_LOGIN_REPLY_REDIRECT_EX:
- purple_debug_error("QQ", "Extend redirect new server, not supported yet\n");
- error_msg = g_strdup( _("Unable login for not support Redirect_EX now") );
- return QQ_LOGIN_REPLY_REDIRECT_EX;
-
case QQ_LOGIN_REPLY_ERR_PWD:
- server_reply = g_strndup((gchar *)data + 1, data_len - 1);
- server_reply_utf8 = qq_to_utf8(server_reply, QQ_CHARSET_DEFAULT);
-
- purple_debug_error("QQ", "Error password: %s\n", server_reply_utf8);
- error_msg = g_strdup_printf( _("Error password: %s"), server_reply_utf8);
-
- g_free(server_reply);
- g_free(server_reply_utf8);
-
- if (!purple_account_get_remember_password(gc->account)) {
- purple_account_set_password(gc->account, NULL);
- }
-
- purple_connection_error_reason(gc,
- PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, error_msg);
- g_free(error_msg);
-
- return QQ_LOGIN_REPLY_ERR_PWD;
-
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Login reply is error password\n");
+ return process_login_wrong_pwd(gc, data, data_len);
case QQ_LOGIN_REPLY_NEED_REACTIVE:
- server_reply = g_strndup((gchar *)data + 1, data_len - 1);
- server_reply_utf8 = qq_to_utf8(server_reply, QQ_CHARSET_DEFAULT);
+ case QQ_LOGIN_REPLY_REDIRECT_EX:
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Login reply is not actived or redirect extend\n");
+ default:
+ break;
+ }
- purple_debug_error("QQ", "Need active: %s\n", server_reply_utf8);
- error_msg = g_strdup_printf( _("Need active: %s"), server_reply_utf8);
-
- g_free(server_reply);
- g_free(server_reply_utf8);
- break;
-
- default:
- purple_debug_error("QQ",
- "Unable login for unknow reply code 0x%02X\n", data[0]);
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Unknown reply code: 0x%02X\n", data[0]);
qq_hex_dump(PURPLE_DEBUG_WARNING, "QQ",
- data, data_len,
- ">>> [default] decrypt and dump");
- error_msg = try_dump_as_gbk(data, data_len);
- if (error_msg == NULL) {
- error_msg = g_strdup_printf(
- _("Unable login for unknow reply code 0x%02X"), data[0] );
- }
- break;
+ data, data_len,
+ ">>> [default] decrypt and dump");
+ error_msg = try_dump_as_gbk(data, data_len);
+ if (error_msg) {
+ purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_msg);
+ g_free(error_msg);
}
-
- purple_connection_error_reason(gc,
- PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_msg);
- g_free(error_msg);
- return ret;
+ return QQ_LOGIN_REPLY_ERR_MISC;
}
/* send keep-alive packet to QQ server (it is a heart-beat) */
@@ -485,11 +460,11 @@ void qq_send_packet_keep_alive(PurpleCon
* the amount of online QQ users, my ip and port */
bytes += qq_put32(raw_data + bytes, qd->uid);
- qq_send_cmd(gc, QQ_CMD_KEEP_ALIVE, raw_data, 4);
+ qq_send_cmd(qd, QQ_CMD_KEEP_ALIVE, raw_data, 4);
}
/* parse the return of keep-alive packet, it includes some system information */
-gboolean qq_process_keep_alive(guint8 *data, gint data_len, PurpleConnection *gc)
+gboolean qq_process_keep_alive(guint8 *data, gint data_len, PurpleConnection *gc)
{
qq_data *qd;
gchar **segments;
@@ -503,7 +478,7 @@ gboolean qq_process_keep_alive(guint8 *d
/* the last one is 60, don't know what it is */
if (NULL == (segments = split_data(data, data_len, "\x1f", 6)))
return TRUE;
-
+
/* segments[0] and segment[1] are all 0x30 ("0") */
qd->total_online = strtol(segments[2], NULL, 10);
if(0 == qd->total_online) {
@@ -513,9 +488,9 @@ gboolean qq_process_keep_alive(guint8 *d
qd->my_ip.s_addr = inet_addr(segments[3]);
qd->my_port = strtol(segments[4], NULL, 10);
- purple_debug_info("QQ", "keep alive, %s:%d\n",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "keep alive, %s:%d\n",
inet_ntoa(qd->my_ip), qd->my_port);
-
+
g_strfreev(segments);
return TRUE;
}
============================================================
--- libpurple/protocols/qq/qq_base.h 1be7d89ee372ed31923b785525b7966caa34db3f
+++ libpurple/protocols/qq/qq_base.h 6d6f1ef5450dc8bc5c06af0135bf2e1573835b04
@@ -44,10 +44,10 @@ void qq_send_packet_token(PurpleConnecti
#define QQ_UPDATE_ONLINE_INTERVAL 300 /* in sec */
void qq_send_packet_token(PurpleConnection *gc);
-guint8 qq_process_token_reply(PurpleConnection *gc, guint8 *buf, gint buf_len);
+guint8 qq_process_token_reply(PurpleConnection *gc, gchar *error_msg, guint8 *buf, gint buf_len);
void qq_send_packet_login(PurpleConnection *gc);
-guint8 qq_process_login_reply( PurpleConnection *gc, guint8 *data, gint data_len);
+guint8 qq_process_login_reply(guint8 *data, gint data_len, PurpleConnection *gc);
void qq_send_packet_logout(PurpleConnection *gc);
============================================================
--- libpurple/protocols/qq/qq_network.c 3853b123926421d8dd7a315c551b2c20c3bcf71c
+++ libpurple/protocols/qq/qq_network.c 4364dbec36ac54db6ce17b68698173e582d596de
@@ -26,6 +26,11 @@
#include "debug.h"
#include "internal.h"
+#ifdef _WIN32
+#define random rand
+#define srandom srand
+#endif
+
#include "buddy_info.h"
#include "group_info.h"
#include "group_free.h"
@@ -39,100 +44,63 @@
#include "utils.h"
#include "qq_process.h"
-#define QQ_DEFAULT_PORT 8000
+/* set QQ_RECONNECT_MAX to 1, when test reconnecting */
+#define QQ_RECONNECT_MAX 4
+#define QQ_RECONNECT_INTERVAL 5000
+#define QQ_KEEP_ALIVE_INTERVAL 60000
+#define QQ_TRANS_INTERVAL 10000
-/* set QQ_CONNECT_MAX to 1, when test reconnecting */
-#define QQ_CONNECT_MAX 3
-#define QQ_CONNECT_INTERVAL 2
-#define QQ_CONNECT_CHECK 5
-#define QQ_KEEP_ALIVE_INTERVAL 60
-#define QQ_TRANS_INTERVAL 10
-
-gboolean connect_to_server(PurpleConnection *gc, gchar *server, gint port);
-
-static qq_connection *connection_find(qq_data *qd, int fd) {
- qq_connection *ret = NULL;
- GSList *entry = qd->openconns;
- while(entry) {
- ret = entry->data;
- if(ret->fd == fd) return ret;
- entry = entry->next;
- }
- return NULL;
-}
-
-static qq_connection *connection_create(qq_data *qd, int fd) {
- qq_connection *ret = g_new0(qq_connection, 1);
- ret->fd = fd;
- qd->openconns = g_slist_append(qd->openconns, ret);
- return ret;
-}
-
-static void connection_remove(qq_data *qd, int fd) {
- qq_connection *conn = connection_find(qd, fd);
- qd->openconns = g_slist_remove(qd->openconns, conn);
-
- g_return_if_fail( conn != NULL );
-
- purple_debug_info("QQ", "Close socket %d\n", conn->fd);
- if(conn->input_handler > 0) purple_input_remove(conn->input_handler);
- if(conn->can_write_handler > 0) purple_input_remove(conn->can_write_handler);
-
- if (conn->fd >= 0) close(conn->fd);
- if(conn->tcp_txbuf != NULL) purple_circ_buffer_destroy(conn->tcp_txbuf);
- if (conn->tcp_rxqueue != NULL) g_free(conn->tcp_rxqueue);
-
- g_free(conn);
-}
-
-static void connection_free_all(qq_data *qd) {
- qq_connection *ret = NULL;
- GSList *entry = qd->openconns;
- while(entry) {
- ret = entry->data;
- connection_remove(qd, ret->fd);
- entry = qd->openconns;
- }
-}
static gboolean set_new_server(qq_data *qd)
{
gint count;
gint index;
GList *it = NULL;
-
+
g_return_val_if_fail(qd != NULL, FALSE);
if (qd->servers == NULL) {
- purple_debug_info("QQ", "Server list is NULL\n");
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Server list is NULL\n");
return FALSE;
}
+ if (qd->real_hostname) {
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "free real_hostname\n");
+ g_free(qd->real_hostname);
+ qd->real_hostname = NULL;
+ }
+
/* remove server used before */
- if (qd->curr_server != NULL) {
- purple_debug_info("QQ",
- "Remove current [%s] from server list\n", qd->curr_server);
- qd->servers = g_list_remove(qd->servers, qd->curr_server);
- qd->curr_server = NULL;
+ if (qd->server_name != NULL) {
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ "Remove previous server [%s]\n", qd->server_name);
+ qd->servers = g_list_remove(qd->servers, qd->server_name);
+ qd->server_name = NULL;
}
-
+
count = g_list_length(qd->servers);
- purple_debug_info("QQ", "Server list has %d\n", count);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Server list has %d\n", count);
if (count <= 0) {
/* no server left, disconnect when result is false */
qd->servers = NULL;
return FALSE;
}
-
+
/* get new server */
- index = rand() % count;
+ index = random() % count;
it = g_list_nth(qd->servers, index);
- qd->curr_server = it->data; /* do not free server_name */
- if (qd->curr_server == NULL || strlen(qd->curr_server) <= 0 ) {
- purple_debug_info("QQ", "Server name at %d is empty\n", index);
+ qd->server_name = it->data; /* do not free server_name */
+ if (qd->server_name == NULL || strlen(qd->server_name) <= 0 ) {
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Server name at %d is empty\n", index);
return FALSE;
}
- purple_debug_info("QQ", "set new server to %s\n", qd->curr_server);
+ qd->real_hostname = g_strdup(qd->server_name);
+ qd->real_port = qd->user_port;
+
+ qd->reconnect_times = QQ_RECONNECT_MAX;
+
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ "set new server to %s:%d\n", qd->real_hostname, qd->real_port);
return TRUE;
}
@@ -147,208 +115,152 @@ static gint packet_get_header(guint8 *he
return bytes;
}
-static gboolean connect_check(gpointer data)
+static gboolean reconnect_later_cb(gpointer data)
{
- PurpleConnection *gc = (PurpleConnection *) data;
+ PurpleConnection *gc;
qq_data *qd;
+ gc = (PurpleConnection *) data;
g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, FALSE);
qd = (qq_data *) gc->proto_data;
- if (qd->connect_watcher > 0) {
- purple_timeout_remove(qd->connect_watcher);
- qd->connect_watcher = 0;
- }
+ qd->reconnect_timeout = 0;
- if (qd->fd >= 0 && qd->token != NULL && qd->token_len >= 0) {
- purple_debug_info("QQ", "Connect ok\n");
- return FALSE;
- }
-
- qd->connect_watcher = purple_timeout_add_seconds(0, qq_connect_later, gc);
- return FALSE;
+ qq_connect(gc->account);
+ return FALSE; /* timeout callback stops */
}
-/* Warning: qq_connect_later destory all connection
- * Any function should be care of use qq_data after call this function
- * Please conside tcp_pending and udp_pending */
-gboolean qq_connect_later(gpointer data)
+static void reconnect_later(PurpleConnection *gc)
{
- PurpleConnection *gc = (PurpleConnection *) data;
qq_data *qd;
- char *server;
- int port;
- gchar **segments;
- g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, FALSE);
+ g_return_if_fail(gc != NULL && gc->proto_data != NULL);
qd = (qq_data *) gc->proto_data;
- if (qd->check_watcher > 0) {
- purple_timeout_remove(qd->check_watcher);
- qd->check_watcher = 0;
- }
- qq_disconnect(gc);
-
- if (qd->redirect_ip.s_addr != 0) {
- /* redirect to new server */
- server = g_strdup_printf("%s:%d", inet_ntoa(qd->redirect_ip), qd->redirect_port);
- qd->servers = g_list_append(qd->servers, server);
- qd->curr_server = server;
-
- qd->redirect_ip.s_addr = 0;
- qd->redirect_port = 0;
- qd->connect_retry = QQ_CONNECT_MAX;
- }
-
- if (qd->curr_server == NULL || strlen (qd->curr_server) == 0 || qd->connect_retry <= 0) {
+ qd->reconnect_times--;
+ if (qd->reconnect_times < 0) {
if ( set_new_server(qd) != TRUE) {
purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Failed to connect all servers"));
- return FALSE;
+ _("Failed to connect server"));
+ return;
}
- qd->connect_retry = QQ_CONNECT_MAX;
}
- segments = g_strsplit_set(qd->curr_server, ":", 0);
- server = g_strdup(segments[0]);
- port = atoi(segments[1]);
- if (port <= 0) {
- purple_debug_info("QQ", "Port not define in %s\n", qd->curr_server);
- port = QQ_DEFAULT_PORT;
- }
- g_strfreev(segments);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ "Reconnect to server %s:%d next retries %d in %d ms\n",
+ qd->real_hostname, qd->real_port,
+ qd->reconnect_times, QQ_RECONNECT_INTERVAL);
- qd->connect_retry--;
- if ( !connect_to_server(gc, server, port) ) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Unable to connect."));
- }
-
- qd->check_watcher = purple_timeout_add_seconds(QQ_CONNECT_CHECK, connect_check, gc);
- return FALSE; /* timeout callback stops */
+ qd->reconnect_timeout = purple_timeout_add(QQ_RECONNECT_INTERVAL,
+ reconnect_later_cb, gc);
}
/* process the incoming packet from qq_pending */
-static gboolean packet_process(PurpleConnection *gc, guint8 *buf, gint buf_len)
+static void packet_process(PurpleConnection *gc, guint8 *buf, gint buf_len)
{
qq_data *qd;
gint bytes, bytes_not_read;
- gboolean prev_update_status;
-
+ gboolean prev_login_status;
+
guint8 header_tag;
guint16 source_tag;
guint16 cmd;
guint16 seq; /* May be ack_seq or send_seq, depends on cmd */
+
guint8 room_cmd;
guint32 room_id;
- gint update_class;
- guint32 ship32;
qq_transaction *trans;
- g_return_val_if_fail(buf != NULL && buf_len > 0, TRUE);
+ g_return_if_fail(buf != NULL && buf_len > 0);
qd = (qq_data *) gc->proto_data;
+ prev_login_status = qd->logged_in;
+
/* Len, header and tail tag have been checked before */
bytes = 0;
bytes += packet_get_header(&header_tag, &source_tag, &cmd, &seq, buf + bytes);
#if 1
- purple_debug_info("QQ", "==> [%05d] 0x%04X %s, source tag 0x%04X len %d\n",
- seq, cmd, qq_get_cmd_desc(cmd), source_tag, buf_len);
-#endif
- /* this is the length of all the encrypted data (also remove tail tag) */
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ "==> [%05d] 0x%04X %s, from (0x%04X %s) len %d\n",
+ seq, cmd, qq_get_cmd_desc(cmd), source_tag, qq_get_ver_desc(source_tag), buf_len);
+#endif
bytes_not_read = buf_len - bytes - 1;
/* ack packet, we need to update send tranactions */
/* we do not check duplication for server ack */
- trans = qq_trans_find_rcved(gc, cmd, seq);
+ trans = qq_trans_find_rcved(qd, cmd, seq);
if (trans == NULL) {
/* new server command */
- qq_trans_add_server_cmd(gc, cmd, seq, buf + bytes, bytes_not_read);
- if ( qd->is_finish_update ) {
+ qq_trans_add_server_cmd(qd, cmd, seq, buf + bytes, bytes_not_read);
+ if ( qd->logged_in ) {
qq_proc_cmd_server(gc, cmd, seq, buf + bytes, bytes_not_read);
}
- return TRUE;
+ return;
}
if (qq_trans_is_dup(trans)) {
- purple_debug_info("QQ", "dup [%05d] %s, discard...\n", seq, qq_get_cmd_desc(cmd));
- return TRUE;
+ purple_debug(PURPLE_DEBUG_WARNING,
+ "QQ", "dup [%05d] %s, discard...\n", seq, qq_get_cmd_desc(cmd));
+ return;
}
if (qq_trans_is_server(trans)) {
- if ( qd->is_finish_update ) {
+ if ( qd->logged_in ) {
qq_proc_cmd_server(gc, cmd, seq, buf + bytes, bytes_not_read);
}
- return TRUE;
+ return;
}
- update_class = qq_trans_get_class(trans);
- ship32 = qq_trans_get_ship(trans);
-
- prev_update_status = qd->is_finish_update;
- switch (cmd) {
- case QQ_CMD_TOKEN:
- if (qq_process_token_reply(gc, buf + bytes, bytes_not_read) == QQ_TOKEN_REPLY_OK) {
- qq_send_packet_login(gc);
- }
- break;
- case QQ_CMD_LOGIN:
- qq_proc_cmd_login(gc, buf + bytes, bytes_not_read);
- /* check is redirect or not, and do it now */
- if (qd->redirect_ip.s_addr != 0) {
- if (qd->check_watcher > 0) {
- purple_timeout_remove(qd->check_watcher);
- qd->check_watcher = 0;
- }
- if (qd->connect_watcher > 0) purple_timeout_remove(qd->connect_watcher);
- qd->connect_watcher = purple_timeout_add_seconds(QQ_CONNECT_INTERVAL, qq_connect_later, gc);
- return FALSE; /* do nothing after this function and return now */
- }
- break;
- case QQ_CMD_ROOM:
- room_cmd = qq_trans_get_room_cmd(trans);
- room_id = qq_trans_get_room_id(trans);
+ /* this is the length of all the encrypted data (also remove tail tag */
+ if (cmd == QQ_CMD_ROOM) {
+ room_cmd = qq_trans_get_room_cmd(trans);
+ room_id = qq_trans_get_room_id(trans);
#if 1
- purple_debug_info("QQ", "%s (0x%02X) for room %d, len %d\n",
- qq_get_room_cmd_desc(room_cmd), room_cmd, room_id, buf_len);
-#endif
- qq_proc_room_cmd_reply(gc, seq, room_cmd, room_id, buf + bytes, bytes_not_read, update_class, ship32);
- break;
- default:
- qq_proc_cmd_reply(gc, cmd, seq, buf + bytes, bytes_not_read, update_class, ship32);
- break;
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ "%s (0x%02X ) for room %d, len %d\n",
+ qq_get_room_cmd_desc(room_cmd), room_cmd, room_id, buf_len);
+#endif
+ qq_proc_room_cmd_reply(gc, seq, room_cmd, room_id, buf + bytes, bytes_not_read);
+ } else {
+ qq_proc_cmd_reply(gc, cmd, seq, buf + bytes, bytes_not_read);
}
+
+ /* check is redirect or not, and do it now */
+ if (qd->is_redirect) {
+ /* free resource except real_hostname and port */
+ qq_disconnect(gc);
+ qd->reconnect_times = QQ_RECONNECT_MAX;
+ reconnect_later(gc);
+ return;
+ }
- if (prev_update_status != qd->is_finish_update && qd->is_finish_update == TRUE) {
- /* is_login, but we have packets before login */
- qq_trans_process_before_login(gc);
- return TRUE;
+ if (prev_login_status != qd->logged_in && qd->logged_in == TRUE) {
+ /* logged_in, but we have packets before login */
+ qq_trans_process_before_login(qd);
}
- return TRUE;
}
static void tcp_pending(gpointer data, gint source, PurpleInputCondition cond)
{
- PurpleConnection *gc = (PurpleConnection *) data;
+ PurpleConnection *gc;
qq_data *qd;
- qq_connection *conn;
guint8 buf[1024]; /* set to 16 when test tcp_rxqueue */
gint buf_len;
gint bytes;
-
+
guint8 *pkt;
guint16 pkt_len;
-
+
gchar *error_msg;
guint8 *jump;
gint jump_len;
+ gc = (PurpleConnection *) data;
g_return_if_fail(gc != NULL && gc->proto_data != NULL);
- qd = (qq_data *) gc->proto_data;
if(cond != PURPLE_INPUT_READ) {
purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
@@ -356,9 +268,8 @@ static void tcp_pending(gpointer data, g
return;
}
- conn = connection_find(qd, source);
- g_return_if_fail(conn != NULL);
-
+ qd = (qq_data *) gc->proto_data;
+
/* test code, not using tcp_rxqueue
memset(pkt,0, sizeof(pkt));
buf_len = read(qd->fd, pkt, sizeof(pkt));
@@ -367,8 +278,8 @@ static void tcp_pending(gpointer data, g
}
return;
*/
-
- buf_len = read(source, buf, sizeof(buf));
+
+ buf_len = read(qd->fd, buf, sizeof(buf));
if (buf_len < 0) {
if (errno == EAGAIN)
/* No worries */
@@ -388,93 +299,93 @@ static void tcp_pending(gpointer data, g
* QQ need a keep alive packet in every 60 seconds
gc->last_received = time(NULL);
*/
- /* purple_debug_info("TCP_PENDING", "Read %d bytes, rxlen is %d\n", buf_len, conn->tcp_rxlen); */
- conn->tcp_rxqueue = g_realloc(conn->tcp_rxqueue, buf_len + conn->tcp_rxlen);
- memcpy(conn->tcp_rxqueue + conn->tcp_rxlen, buf, buf_len);
- conn->tcp_rxlen += buf_len;
-
+ /*
+ purple_debug(PURPLE_DEBUG_INFO, "TCP_PENDING",
+ "Read %d bytes from socket, rxlen is %d\n", buf_len, qd->tcp_rxlen);
+ */
+ qd->tcp_rxqueue = g_realloc(qd->tcp_rxqueue, buf_len + qd->tcp_rxlen);
+ memcpy(qd->tcp_rxqueue + qd->tcp_rxlen, buf, buf_len);
+ qd->tcp_rxlen += buf_len;
+
pkt = g_newa(guint8, MAX_PACKET_SIZE);
- while (PURPLE_CONNECTION_IS_VALID(gc)) {
- if (qd->openconns == NULL) {
+ while (1) {
+ if (qd->tcp_rxlen < QQ_TCP_HEADER_LENGTH) {
break;
}
- if (conn->tcp_rxqueue == NULL) {
- conn->tcp_rxlen = 0;
- break;
- }
- if (conn->tcp_rxlen < QQ_TCP_HEADER_LENGTH) {
- break;
- }
-
+
bytes = 0;
- bytes += qq_get16(&pkt_len, conn->tcp_rxqueue + bytes);
- if (conn->tcp_rxlen < pkt_len) {
+ bytes += qq_get16(&pkt_len, qd->tcp_rxqueue + bytes);
+ if (qd->tcp_rxlen < pkt_len) {
break;
}
- /* purple_debug_info("TCP_PENDING", "Packet len=%d, rxlen=%d\n", pkt_len, conn->tcp_rxlen); */
+ /*
+ purple_debug(PURPLE_DEBUG_INFO, "TCP_PENDING",
+ "Packet len is %d bytes, rxlen is %d\n", pkt_len, qd->tcp_rxlen);
+ */
if ( pkt_len < QQ_TCP_HEADER_LENGTH
- || *(conn->tcp_rxqueue + bytes) != QQ_PACKET_TAG
- || *(conn->tcp_rxqueue + pkt_len - 1) != QQ_PACKET_TAIL) {
+ || *(qd->tcp_rxqueue + bytes) != QQ_PACKET_TAG
+ || *(qd->tcp_rxqueue + pkt_len - 1) != QQ_PACKET_TAIL) {
/* HEY! This isn't even a QQ. What are you trying to pull? */
- purple_debug_warning("TCP_PENDING", "Packet error, no header or tail tag\n");
- jump = memchr(conn->tcp_rxqueue + 1, QQ_PACKET_TAIL, conn->tcp_rxlen - 1);
+ purple_debug(PURPLE_DEBUG_ERROR, "TCP_PENDING",
+ "Packet error, failed to check header and tail tag\n");
+
+ jump = memchr(qd->tcp_rxqueue + 1, QQ_PACKET_TAIL, qd->tcp_rxlen - 1);
if ( !jump ) {
- purple_debug_warning("TCP_PENDING", "Failed to find next tail, clear receive buffer\n");
- g_free(conn->tcp_rxqueue);
- conn->tcp_rxqueue = NULL;
- conn->tcp_rxlen = 0;
+ purple_debug(PURPLE_DEBUG_INFO, "TCP_PENDING",
+ "Failed to find next QQ_PACKET_TAIL, clear receive buffer\n");
+ g_free(qd->tcp_rxqueue);
+ qd->tcp_rxqueue = NULL;
+ qd->tcp_rxlen = 0;
return;
}
/* jump and over QQ_PACKET_TAIL */
- jump_len = (jump - conn->tcp_rxqueue) + 1;
- purple_debug_warning("TCP_PENDING", "Find next tail at %d, jump %d\n", jump_len, jump_len + 1);
- g_memmove(conn->tcp_rxqueue, jump, conn->tcp_rxlen - jump_len);
- conn->tcp_rxlen -= jump_len;
+ jump_len = (jump - qd->tcp_rxqueue) + 1;
+ purple_debug(PURPLE_DEBUG_INFO, "TCP_PENDING",
+ "Find next QQ_PACKET_TAIL at %d, jump %d bytes\n", jump_len, jump_len + 1);
+ g_memmove(qd->tcp_rxqueue, jump, qd->tcp_rxlen - jump_len);
+ qd->tcp_rxlen -= jump_len;
continue;
}
memset(pkt, 0, MAX_PACKET_SIZE);
- g_memmove(pkt, conn->tcp_rxqueue + bytes, pkt_len - bytes);
-
+ g_memmove(pkt, qd->tcp_rxqueue + bytes, pkt_len - bytes);
+
/* jump to next packet */
- conn->tcp_rxlen -= pkt_len;
- if (conn->tcp_rxlen) {
- /* purple_debug_info("TCP_PENDING", "shrink tcp_rxqueue to %d\n", conn->tcp_rxlen); */
- jump = g_memdup(conn->tcp_rxqueue + pkt_len, conn->tcp_rxlen);
- g_free(conn->tcp_rxqueue);
- conn->tcp_rxqueue = jump;
+ qd->tcp_rxlen -= pkt_len;
+ if (qd->tcp_rxlen) {
+ /*
+ purple_debug(PURPLE_DEBUG_ERROR, "TCP_PENDING", "shrink tcp_rxqueue to %d\n", qd->tcp_rxlen);
+ */
+ jump = g_memdup(qd->tcp_rxqueue + pkt_len, qd->tcp_rxlen);
+ g_free(qd->tcp_rxqueue);
+ qd->tcp_rxqueue = jump;
} else {
- /* purple_debug_info("TCP_PENDING", "free tcp_rxqueue\n"); */
- g_free(conn->tcp_rxqueue);
- conn->tcp_rxqueue = NULL;
+ /* purple_debug(PURPLE_DEBUG_ERROR, "TCP_PENDING", "free tcp_rxqueue\n"); */
+ g_free(qd->tcp_rxqueue);
+ qd->tcp_rxqueue = NULL;
}
if (pkt == NULL) {
continue;
}
- /* packet_process may call disconnect and destory data like conn
- * do not call packet_process before jump,
- * break if packet_process return FALSE */
- if (packet_process(gc, pkt, pkt_len - bytes) == FALSE) {
- purple_debug_info("TCP_PENDING", "Connection has been destory\n");
- break;
- }
+ /* do not call packet_process before jump
+ * packet_process may call disconnect and destory tcp_rxqueue */
+ packet_process(gc, pkt, pkt_len - bytes);
}
}
static void udp_pending(gpointer data, gint source, PurpleInputCondition cond)
{
- PurpleConnection *gc = (PurpleConnection *) data;
+ PurpleConnection *gc;
qq_data *qd;
guint8 *buf;
gint buf_len;
gc = (PurpleConnection *) data;
g_return_if_fail(gc != NULL && gc->proto_data != NULL);
- qd = (qq_data *) gc->proto_data;
if(cond != PURPLE_INPUT_READ) {
purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
@@ -482,10 +393,13 @@ static void udp_pending(gpointer data, g
return;
}
+ qd = (qq_data *) gc->proto_data;
+ g_return_if_fail(qd->fd >= 0);
+
buf = g_newa(guint8, MAX_PACKET_SIZE);
/* here we have UDP proxy suppport */
- buf_len = read(source, buf, MAX_PACKET_SIZE);
+ buf_len = read(qd->fd, buf, MAX_PACKET_SIZE);
if (buf_len <= 0) {
purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to read from socket"));
@@ -505,95 +419,73 @@ static void udp_pending(gpointer data, g
return;
}
}
-
- /* packet_process may call disconnect and destory data like conn
- * do not call packet_process before jump,
- * break if packet_process return FALSE */
+
packet_process(gc, buf, buf_len);
}
-static gint udp_send_out(PurpleConnection *gc, guint8 *data, gint data_len)
+static gint udp_send_out(qq_data *qd, guint8 *data, gint data_len)
{
- qq_data *qd;
gint ret;
- g_return_val_if_fail(data != NULL && data_len > 0, -1);
+ g_return_val_if_fail(qd != NULL && qd->fd >= 0 && data != NULL && data_len > 0, -1);
- g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, -1);
- qd = (qq_data *) gc->proto_data;
-
-#if 0
- purple_debug_info("UDP_SEND_OUT", "Send %d bytes to socket %d\n", data_len, qd->fd);
-#endif
-
+ /*
+ purple_debug(PURPLE_DEBUG_INFO, "UDP_SEND_OUT", "Send %d bytes to socket %d\n", data_len, qd->fd);
+ */
+
errno = 0;
ret = send(qd->fd, data, data_len, 0);
if (ret < 0 && errno == EAGAIN) {
return ret;
}
-
+
if (ret < 0) {
/* TODO: what to do here - do we really have to disconnect? */
- purple_debug_error("UDP_SEND_OUT", "Send failed: %d, %s\n", errno, g_strerror(errno));
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, g_strerror(errno));
+ purple_debug(PURPLE_DEBUG_ERROR, "UDP_SEND_OUT", "Send failed: %d, %s\n", errno, g_strerror(errno));
+ purple_connection_error_reason(qd->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, g_strerror(errno));
}
return ret;
}
static void tcp_can_write(gpointer data, gint source, PurpleInputCondition cond)
{
- PurpleConnection *gc = (PurpleConnection *) data;
- qq_data *qd;
- qq_connection *conn;
+ qq_data *qd = data;
int ret, writelen;
- g_return_if_fail(gc != NULL && gc->proto_data != NULL);
- qd = (qq_data *) gc->proto_data;
-
- conn = connection_find(qd, source);
- g_return_if_fail(conn != NULL);
-
- writelen = purple_circ_buffer_get_max_read(conn->tcp_txbuf);
+ writelen = purple_circ_buffer_get_max_read(qd->tcp_txbuf);
if (writelen == 0) {
- purple_input_remove(conn->can_write_handler);
- conn->can_write_handler = 0;
+ purple_input_remove(qd->tx_handler);
+ qd->tx_handler = 0;
return;
}
- ret = write(source, conn->tcp_txbuf->outptr, writelen);
- purple_debug_info("TCP_CAN_WRITE", "total %d bytes is sent %d\n", writelen, ret);
+ ret = write(qd->fd, qd->tcp_txbuf->outptr, writelen);
+ purple_debug(PURPLE_DEBUG_ERROR, "TCP_CAN_WRITE",
+ "total %d bytes is sent %d\n", writelen, ret);
if (ret < 0 && errno == EAGAIN)
return;
else if (ret < 0) {
/* TODO: what to do here - do we really have to disconnect? */
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ purple_connection_error_reason(qd->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Write Error"));
return;
}
- purple_circ_buffer_mark_read(conn->tcp_txbuf, ret);
+ purple_circ_buffer_mark_read(qd->tcp_txbuf, ret);
}
-static gint tcp_send_out(PurpleConnection *gc, guint8 *data, gint data_len)
+static gint tcp_send_out(qq_data *qd, guint8 *data, gint data_len)
{
- qq_data *qd;
- qq_connection *conn;
gint ret;
- g_return_val_if_fail(data != NULL && data_len > 0, -1);
+ g_return_val_if_fail(qd != NULL && qd->fd >= 0 && data != NULL && data_len > 0, -1);
- g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, -1);
- qd = (qq_data *) gc->proto_data;
+ /*
+ purple_debug(PURPLE_DEBUG_INFO, "TCP_SEND_OUT", "Send %d bytes to socket %d\n", data_len, qd->fd);
+ */
- conn = connection_find(qd, qd->fd);
- g_return_val_if_fail(conn, -1);
-
-#if 0
- purple_debug_info("TCP_SEND_OUT", "Send %d bytes to socket %d\n", data_len, qd->fd);
-#endif
-
- if (conn->can_write_handler == 0) {
+ if (qd->tx_handler == 0) {
ret = write(qd->fd, data, data_len);
} else {
ret = -1;
@@ -601,28 +493,28 @@ static gint tcp_send_out(PurpleConnectio
}
/*
- purple_debug_info("TCP_SEND_OUT",
+ purple_debug(PURPLE_DEBUG_INFO, "TCP_SEND_OUT",
"Socket %d, total %d bytes is sent %d\n", qd->fd, data_len, ret);
*/
if (ret < 0 && errno == EAGAIN) {
/* socket is busy, send later */
- purple_debug_info("TCP_SEND_OUT", "Socket is busy and send later\n");
+ purple_debug(PURPLE_DEBUG_INFO, "TCP_SEND_OUT", "Socket is busy and send later\n");
ret = 0;
} else if (ret <= 0) {
/* TODO: what to do here - do we really have to disconnect? */
- purple_debug_error("TCP_SEND_OUT",
+ purple_debug(PURPLE_DEBUG_ERROR, "TCP_SEND_OUT",
"Send to socket %d failed: %d, %s\n", qd->fd, errno, g_strerror(errno));
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, g_strerror(errno));
+ purple_connection_error_reason(qd->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, g_strerror(errno));
return ret;
}
if (ret < data_len) {
- purple_debug_info("TCP_SEND_OUT",
+ purple_debug(PURPLE_DEBUG_INFO, "TCP_SEND_OUT",
"Add %d bytes to buffer\n", data_len - ret);
- if (conn->can_write_handler == 0) {
- conn->can_write_handler = purple_input_add(qd->fd, PURPLE_INPUT_WRITE, tcp_can_write, gc);
+ if (qd->tx_handler == 0) {
+ qd->tx_handler = purple_input_add(qd->fd, PURPLE_INPUT_WRITE, tcp_can_write, qd);
}
- purple_circ_buffer_append(conn->tcp_txbuf, data + ret, data_len - ret);
+ purple_circ_buffer_append(qd->tcp_txbuf, data + ret, data_len - ret);
}
return ret;
}
@@ -636,17 +528,17 @@ static gboolean network_timeout(gpointer
g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, TRUE);
qd = (qq_data *) gc->proto_data;
- is_lost_conn = qq_trans_scan(gc);
+ is_lost_conn = qq_trans_scan(qd);
if (is_lost_conn) {
purple_connection_error_reason(gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Connection lost"));
return TRUE;
}
- if ( !qd->is_login ) {
+ if ( !qd->logged_in ) {
return TRUE;
}
-
+
qd->itv_count.keep_alive--;
if (qd->itv_count.keep_alive <= 0) {
qd->itv_count.keep_alive = qd->itv_config.keep_alive;
@@ -661,30 +553,55 @@ static gboolean network_timeout(gpointer
qd->itv_count.update--;
if (qd->itv_count.update <= 0) {
qd->itv_count.update = qd->itv_config.update;
- qq_update_online(gc, 0);
+ qq_send_packet_get_buddies_online(gc, 0);
+
+ qq_send_cmd_group_all_get_online_members(gc);
return TRUE;
}
return TRUE; /* if return FALSE, timeout callback stops */
}
-static void do_request_token(PurpleConnection *gc)
+/* the callback function after socket is built
+ * we setup the qq protocol related configuration here */
+static void qq_connect_cb(gpointer data, gint source, const gchar *error_message)
{
qq_data *qd;
+ PurpleConnection *gc;
gchar *conn_msg;
const gchar *passwd;
+ PurpleAccount *account ;
- /* _qq_show_socket("Got login socket", source); */
+ gc = (PurpleConnection *) data;
+ if (!PURPLE_CONNECTION_IS_VALID(gc)) {
+ purple_debug(PURPLE_DEBUG_INFO, "QQ_CONN", "Invalid connection\n");
+ close(source);
+ return;
+ }
+
g_return_if_fail(gc != NULL && gc->proto_data != NULL);
+
qd = (qq_data *) gc->proto_data;
+ account = purple_connection_get_account(gc);
+ /* Connect is now complete; clear the PurpleProxyConnectData */
+ qd->connect_data = NULL;
+
+ if (source < 0) { /* socket returns -1 */
+ purple_debug(PURPLE_DEBUG_INFO, "QQ_CONN", "Invalid connection, source is < 0\n");
+ qq_disconnect(gc);
+ reconnect_later(gc);
+ return;
+ }
+
+ /* _qq_show_socket("Got login socket", source); */
+
/* QQ use random seq, to minimize duplicated packets */
- srand(time(NULL));
- qd->send_seq = rand() & 0xffff;
-
- qd->is_login = FALSE;
- qd->is_finish_update = FALSE;
+ srandom(time(NULL));
+ qd->send_seq = random() & 0x0000ffff;
+ qd->fd = source;
+ qd->logged_in = FALSE;
qd->channel = 1;
qd->uid = strtol(purple_account_get_username(purple_connection_get_account(gc)), NULL, 10);
@@ -697,94 +614,260 @@ static void do_request_token(PurpleConne
qq_get_md5(qd->password_twice_md5, sizeof(qd->password_twice_md5),
qd->password_twice_md5, sizeof(qd->password_twice_md5));
- g_return_if_fail(qd->network_watcher == 0);
- qd->network_watcher = purple_timeout_add_seconds(qd->itv_config.resend, network_timeout, gc);
+ g_return_if_fail(qd->network_timeout == 0);
+ qd->itv_config.resend = purple_account_get_int(account, "resend_interval", 10);
+ if (qd->itv_config.resend <= 0) qd->itv_config.resend = 10;
+ qd->itv_config.keep_alive = purple_account_get_int(account, "keep_alive_interval", 60);
+ if (qd->itv_config.keep_alive < 30) qd->itv_config.keep_alive = 30;
+ qd->itv_config.keep_alive /= qd->itv_config.resend;
+ qd->itv_count.keep_alive = qd->itv_config.keep_alive;
+
+ qd->itv_config.update = purple_account_get_int(account, "update_interval", 300);
+ if (qd->itv_config.update > 0) {
+ if (qd->itv_config.update < qd->itv_config.keep_alive) {
+ qd->itv_config.update = qd->itv_config.keep_alive;
+ }
+ qd->itv_config.update /= qd->itv_config.resend;
+ qd->itv_count.update = qd->itv_config.update;
+ } else {
+ qd->itv_config.update = 0;
+ }
+
+ qd->network_timeout = purple_timeout_add(qd->itv_config.resend *1000, network_timeout, gc);
+
+ if (qd->use_tcp)
+ gc->inpa = purple_input_add(qd->fd, PURPLE_INPUT_READ, tcp_pending, gc);
+ else
+ gc->inpa = purple_input_add(qd->fd, PURPLE_INPUT_READ, udp_pending, gc);
+
/* Update the login progress status display */
- conn_msg = g_strdup_printf(_("Request token"));
- purple_connection_update_progress(gc, conn_msg, 2, QQ_CONNECT_STEPS);
+ conn_msg = g_strdup_printf("Login as %d", qd->uid);
+ purple_connection_update_progress(gc, conn_msg, QQ_CONNECT_STEPS - 1, QQ_CONNECT_STEPS);
g_free(conn_msg);
qq_send_packet_token(gc);
}
-/* the callback function after socket is built
- * we setup the qq protocol related configuration here */
-static void connect_cb(gpointer data, gint source, const gchar *error_message)
+static void udp_can_write(gpointer data, gint source, PurpleInputCondition cond)
{
PurpleConnection *gc;
qq_data *qd;
- PurpleAccount *account ;
- qq_connection *conn;
+ socklen_t len;
+ int error=0, ret;
gc = (PurpleConnection *) data;
g_return_if_fail(gc != NULL && gc->proto_data != NULL);
qd = (qq_data *) gc->proto_data;
- account = purple_connection_get_account(gc);
- /* conn_data will be destoryed */
- qd->conn_data = NULL;
- if (!PURPLE_CONNECTION_IS_VALID(gc)) {
- purple_debug_info("QQ_CONN", "Invalid connection\n");
+ purple_debug_info("proxy", "Connected.\n");
+
+ /*
+ * getsockopt after a non-blocking connect returns -1 if something is
+ * really messed up (bad descriptor, usually). Otherwise, it returns 0 and
+ * error holds what connect would have returned if it blocked until now.
+ * Thus, error == 0 is success, error == EINPROGRESS means "try again",
+ * and anything else is a real error.
+ *
+ * (error == EINPROGRESS can happen after a select because the kernel can
+ * be overly optimistic sometimes. select is just a hint that you might be
+ * able to do something.)
+ */
+ len = sizeof(error);
+ ret = getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len);
+ if (ret == 0 && error == EINPROGRESS)
+ return; /* we'll be called again later */
+
+ purple_input_remove(qd->tx_handler);
+ qd->tx_handler = 0;
+ if (ret < 0 || error != 0) {
+ if(ret != 0)
+ error = errno;
+
close(source);
+
+ purple_debug_error("proxy", "getsockopt SO_ERROR check: %s\n", g_strerror(error));
+
+ qq_connect_cb(gc, -1, _("Unable to connect"));
return;
}
- if (source < 0) { /* socket returns -1 */
- purple_debug_info("QQ_CONN",
- "Could not establish a connection with the server:\n%s\n",
- error_message);
- if (qd->connect_watcher > 0) purple_timeout_remove(qd->connect_watcher);
- qd->connect_watcher = purple_timeout_add_seconds(QQ_CONNECT_INTERVAL, qq_connect_later, gc);
+ qq_connect_cb(gc, source, NULL);
+}
+
+static void udp_host_resolved(GSList *hosts, gpointer data, const char *error_message) {
+ PurpleConnection *gc;
+ qq_data *qd;
+ struct sockaddr server_addr;
+ int addr_size;
+ gint fd = -1;
+ int flags;
+
+ gc = (PurpleConnection *) data;
+ g_return_if_fail(gc != NULL && gc->proto_data != NULL);
+
+ qd = (qq_data *) gc->proto_data;
+
+ /* udp_query_data must be set as NULL.
+ * Otherwise purple_dnsquery_destroy in qq_disconnect cause glib double free error */
+ qd->udp_query_data = NULL;
+
+ if (!hosts || !hosts->data) {
+ purple_connection_error_reason(gc,
+ PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ _("Couldn't resolve host"));
return;
}
- /* _qq_show_socket("Got login socket", source); */
- qd->fd = source;
- conn = connection_create(qd, source);
- if (qd->use_tcp) {
- conn->input_handler = purple_input_add(source, PURPLE_INPUT_READ, tcp_pending, gc);
- } else {
- conn->input_handler = purple_input_add(source, PURPLE_INPUT_READ, udp_pending, gc);
+ addr_size = GPOINTER_TO_INT(hosts->data);
+ hosts = g_slist_remove(hosts, hosts->data);
+ memcpy(&server_addr, hosts->data, addr_size);
+ g_free(hosts->data);
+
+ hosts = g_slist_remove(hosts, hosts->data);
+ while(hosts) {
+ hosts = g_slist_remove(hosts, hosts->data);
+ g_free(hosts->data);
+ hosts = g_slist_remove(hosts, hosts->data);
}
- do_request_token( gc );
+ fd = socket(PF_INET, SOCK_DGRAM, 0);
+ if (fd < 0) {
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ",
+ "Unable to create socket: %s\n", g_strerror(errno));
+ return;
+ }
+
+ /* we use non-blocking mode to speed up connection */
+ flags = fcntl(fd, F_GETFL);
+ fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+#ifndef _WIN32
+ fcntl(fd, F_SETFD, FD_CLOEXEC);
+#endif
+
+ /* From Unix-socket-FAQ: http://www.faqs.org/faqs/unix-faq/socket/
+ *
+ * If a UDP socket is unconnected, which is the normal state after a
+ * bind() call, then send() or write() are not allowed, since no
+ * destination is available; only sendto() can be used to send data.
+ *
+ * Calling connect() on the socket simply records the specified address
+ * and port number as being the desired communications partner. That
+ * means that send() or write() are now allowed; they use the destination
+ * address and port given on the connect call as the destination of packets.
+ */
+ if (connect(fd, &server_addr, addr_size) >= 0) {
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Connected.\n");
+ flags = fcntl(fd, F_GETFL);
+ fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
+ qq_connect_cb(gc, fd, NULL);
+ return;
+ }
+
+ /* [EINPROGRESS]
+ * The socket is marked as non-blocking and the connection cannot be
+ * completed immediately. It is possible to select for completion by
+ * selecting the socket for writing.
+ * [EINTR]
+ * A signal interrupted the call.
+ * The connection is established asynchronously.
+ */
+ if ((errno == EINPROGRESS) || (errno == EINTR)) {
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Connect in asynchronous mode.\n");
+ qd->tx_handler = purple_input_add(fd, PURPLE_INPUT_WRITE, udp_can_write, gc);
+ return;
+ }
+
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Connection failed: %s\n", g_strerror(errno));
+ close(fd);
}
-gboolean connect_to_server(PurpleConnection *gc, gchar *server, gint port)
+/* establish a generic QQ connection
+ * TCP/UDP, and direct/redirected */
+void qq_connect(PurpleAccount *account)
{
- PurpleAccount *account ;
+ PurpleConnection *gc;
qq_data *qd;
gchar *conn_msg;
- g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, FALSE);
- account = purple_connection_get_account(gc);
+ gc = purple_account_get_connection(account);
+ g_return_if_fail(gc != NULL && gc->proto_data != NULL);
+
qd = (qq_data *) gc->proto_data;
- if (server == NULL || strlen(server) == 0 || port == 0) {
+
+ /* test set_new_server
+ while (set_new_server(qd)) {
+ purple_debug(PURPLE_DEBUG_INFO, "QQ_TEST",
+ "New server %s:%d Real server %s:%d\n",
+ qd->server_name, qd->user_port, qd->real_hostname, qd->real_port);
+ }
+ purple_debug(PURPLE_DEBUG_INFO, "QQ_TEST", "qd->servers %lu\n",
+ qd->servers);
+ exit(1);
+ */
+ if (qd->server_name == NULL) {
+ /* must be first call this function */
+ if ( set_new_server(qd) != TRUE) {
+ purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ _("Failed to connect server"));
+ return;
+ }
+ }
+
+ if (qd->real_hostname == NULL || qd->real_port == 0) {
purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Invalid server or port"));
- return FALSE;
+ _("hostname is NULL or port is 0"));
+ return;
}
- conn_msg = g_strdup_printf( _("Connecting server %s, retries %d"), server, port);
+ conn_msg = g_strdup_printf( _("Connecting server %s, retries %d"),
+ qd->real_hostname, qd->reconnect_times);
purple_connection_update_progress(gc, conn_msg, 1, QQ_CONNECT_STEPS);
g_free(conn_msg);
- purple_debug_info("QQ", "Connect to %s:%d\n", server, port);
+ if (qd->is_redirect) {
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Redirect to %s:%d\n",
+ qd->real_hostname, qd->real_port);
+ }
+ qd->is_redirect = FALSE;
- if (qd->conn_data != NULL) {
- purple_proxy_connect_cancel(qd->conn_data);
- qd->conn_data = NULL;
+ qd->fd = -1;
+ qd->tx_handler = 0;
+
+ /* QQ connection via UDP/TCP.
+ * Now use Purple proxy function to provide TCP proxy support,
+ * and qq_udp_proxy.c to add UDP proxy support (thanks henry) */
+ if(qd->use_tcp) {
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "TCP Connect to %s:%d\n",
+ qd->real_hostname, qd->real_port);
+
+ /* TODO: is there a good default grow size? */
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Create tcp_txbuf\n");
+ qd->tcp_txbuf = purple_circ_buffer_new(0);
+
+ qd->connect_data = purple_proxy_connect(NULL, account,
+ qd->real_hostname, qd->real_port, qq_connect_cb, gc);
+ if (qd->connect_data == NULL) {
+ purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ _("Unable to connect."));
+ }
+ return;
}
- qd->conn_data = purple_proxy_connect(gc, account, server, port, connect_cb, gc);
- if ( qd->conn_data == NULL ) {
- purple_debug_error("QQ", _("Couldn't create socket"));
- return FALSE;
+
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "UDP Connect to %s:%d\n",
+ qd->real_hostname, qd->real_port);
+
+ g_return_if_fail(qd->udp_query_data == NULL);
+ qd->udp_query_data = purple_dnsquery_a(qd->real_hostname, qd->real_port,
+ udp_host_resolved, gc);
+ if (qd->udp_query_data == NULL) {
+ purple_connection_error_reason(qd->gc,
+ PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ _("Could not resolve hostname"));
}
- return TRUE;
}
/* clean up qq_data structure and all its components
@@ -796,32 +879,65 @@ void qq_disconnect(PurpleConnection *gc)
g_return_if_fail(gc != NULL && gc->proto_data != NULL);
qd = (qq_data *) gc->proto_data;
- purple_debug_info("QQ", "Disconnecting ...\n");
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Disconnecting ...\n");
- if (qd->network_watcher > 0) {
- purple_debug_info("QQ", "Remove network watcher\n");
- purple_timeout_remove(qd->network_watcher);
- qd->network_watcher = 0;
+ if (qd->network_timeout > 0) {
+ purple_timeout_remove(qd->network_timeout);
+ qd->network_timeout = 0;
}
/* finish all I/O */
- if (qd->fd >= 0 && qd->is_login) {
+ if (qd->fd >= 0 && qd->logged_in) {
qq_send_packet_logout(gc);
}
- /* not connected */
- if (qd->conn_data != NULL) {
- purple_debug_info("QQ", "Connect cancel\n");
- purple_proxy_connect_cancel(qd->conn_data);
- qd->conn_data = NULL;
+ if (gc->inpa > 0) {
+ purple_input_remove(gc->inpa);
+ gc->inpa = 0;
}
- connection_free_all(qd);
- qd->fd = -1;
- qq_trans_remove_all(gc);
+ if (qd->fd >= 0) {
+ close(qd->fd);
+ qd->fd = -1;
+ }
+ if (qd->reconnect_timeout > 0) {
+ purple_timeout_remove(qd->reconnect_timeout);
+ qd->reconnect_timeout = 0;
+ }
+
+ if (qd->connect_data != NULL) {
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Cancel connect_data\n");
+ purple_proxy_connect_cancel(qd->connect_data);
+ }
+
+ if(qd->tcp_txbuf != NULL) {
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "destroy tcp_txbuf\n");
+ purple_circ_buffer_destroy(qd->tcp_txbuf);
+ qd->tcp_txbuf = NULL;
+ }
+
+ if (qd->tx_handler) {
+ purple_input_remove(qd->tx_handler);
+ qd->tx_handler = 0;
+ }
+ if (qd->tcp_rxqueue != NULL) {
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "destroy tcp_rxqueue\n");
+ g_free(qd->tcp_rxqueue);
+ qd->tcp_rxqueue = NULL;
+ qd->tcp_rxlen = 0;
+ }
+
+ if (qd->udp_query_data != NULL) {
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "destroy udp_query_data\n");
+ purple_dnsquery_destroy(qd->udp_query_data);
+ qd->udp_query_data = NULL;
+ }
+
+ qq_trans_remove_all(qd);
+
if (qd->token) {
- purple_debug_info("QQ", "free token\n");
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "free token\n");
g_free(qd->token);
qd->token = NULL;
qd->token_len = 0;
@@ -839,13 +955,13 @@ void qq_disconnect(PurpleConnection *gc)
qq_buddies_list_free(gc->account, qd);
}
-static gint packet_encap(qq_data *qd, guint8 *buf, gint maxlen, guint16 cmd, guint16 seq,
+static gint encap(qq_data *qd, guint8 *buf, gint maxlen, guint16 cmd, guint16 seq,
guint8 *data, gint data_len)
{
gint bytes = 0;
g_return_val_if_fail(qd != NULL && buf != NULL && maxlen > 0, -1);
g_return_val_if_fail(data != NULL && data_len > 0, -1);
-
+
/* QQ TCP packet has two bytes in the begining defines packet length
* so leave room here to store packet size */
if (qd->use_tcp) {
@@ -855,7 +971,7 @@ static gint packet_encap(qq_data *qd, gu
bytes += qq_put8(buf + bytes, QQ_PACKET_TAG);
bytes += qq_put16(buf + bytes, QQ_CLIENT);
bytes += qq_put16(buf + bytes, cmd);
-
+
bytes += qq_put16(buf + bytes, seq);
bytes += qq_put32(buf + bytes, qd->uid);
@@ -871,144 +987,109 @@ static gint packet_encap(qq_data *qd, gu
}
/* data has been encrypted before */
-static gint packet_send_out(PurpleConnection *gc, guint16 cmd, guint16 seq, guint8 *data, gint data_len)
+gint qq_send_data(qq_data *qd, guint16 cmd, guint16 seq, gboolean need_ack,
+ guint8 *data, gint data_len)
{
- qq_data *qd;
guint8 *buf;
gint buf_len;
gint bytes_sent;
- g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, -1);
- qd = (qq_data *)gc->proto_data;
+ g_return_val_if_fail(qd != NULL, -1);
g_return_val_if_fail(data != NULL && data_len > 0, -1);
buf = g_newa(guint8, MAX_PACKET_SIZE);
memset(buf, 0, MAX_PACKET_SIZE);
- buf_len = packet_encap(qd, buf, MAX_PACKET_SIZE, cmd, seq, data, data_len);
+ buf_len = encap(qd, buf, MAX_PACKET_SIZE, cmd, seq, data, data_len);
if (buf_len <= 0) {
return -1;
}
if (qd->use_tcp) {
- bytes_sent = tcp_send_out(gc, buf, buf_len);
+ bytes_sent = tcp_send_out(qd, buf, buf_len);
} else {
- bytes_sent = udp_send_out(gc, buf, buf_len);
+ bytes_sent = udp_send_out(qd, buf, buf_len);
}
- return bytes_sent;
-}
-
-gint qq_send_cmd_encrypted(PurpleConnection *gc, guint16 cmd, guint16 seq,
- guint8 *data, gint data_len, gboolean need_ack)
-{
- gint send_len;
-
-#if 1
- purple_debug_info("QQ", "<== [%05d], %s(0x%04X), datalen %d\n",
- seq, qq_get_cmd_desc(cmd), cmd, data_len);
-#endif
-
- send_len = packet_send_out(gc, cmd, seq, data, data_len);
if (need_ack) {
- qq_trans_add_client_cmd(gc, cmd, seq, data, data_len, 0, 0);
+ qq_trans_add_client_cmd(qd, cmd, seq, data, data_len);
}
- return send_len;
+
+#if 1
+ /* qq_show_packet("QQ_SEND_DATA", buf, buf_len); */
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ "<== [%05d], 0x%04X %s, total %d bytes is sent %d\n",
+ seq, cmd, qq_get_cmd_desc(cmd), buf_len, bytes_sent);
+#endif
+ return bytes_sent;
}
-/* Encrypt data with session_key, and send packet out */
-static gint send_cmd_detail(PurpleConnection *gc, guint16 cmd, guint16 seq,
- guint8 *data, gint data_len, gboolean need_ack, gint update_class, guint32 ship32)
+/* Encrypt data with session_key, then call qq_send_data */
+gint qq_send_cmd_detail(qq_data *qd, guint16 cmd, guint16 seq, gboolean need_ack,
+ guint8 *data, gint data_len)
{
- qq_data *qd;
guint8 *encrypted_data;
gint encrypted_len;
- gint bytes_sent;
- g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, -1);
- qd = (qq_data *)gc->proto_data;
+ g_return_val_if_fail(qd != NULL, -1);
g_return_val_if_fail(data != NULL && data_len > 0, -1);
/* at most 16 bytes more */
encrypted_data = g_newa(guint8, data_len + 16);
+#if 0
+ purple_debug(PURPLE_DEBUG_INFO, "QQ_ENCRYPT",
+ "Before %d: [%05d] 0x%04X %s\n",
+ data_len, seq, cmd, qq_get_cmd_desc(cmd));
+#endif
encrypted_len = qq_encrypt(encrypted_data, data, data_len, qd->session_key);
if (encrypted_len < 16) {
- purple_debug_error("QQ_ENCRYPT", "Error len %d: [%05d] 0x%04X %s\n",
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ_ENCRYPT",
+ "Error len %d: [%05d] 0x%04X %s\n",
encrypted_len, seq, cmd, qq_get_cmd_desc(cmd));
return -1;
}
- bytes_sent = packet_send_out(gc, cmd, seq, encrypted_data, encrypted_len);
-
- if (need_ack) {
- qq_trans_add_client_cmd(gc, cmd, seq, encrypted_data, encrypted_len, update_class, ship32);
- }
- return bytes_sent;
+#if 0
+ purple_debug(PURPLE_DEBUG_INFO, "QQ_ENCRYPT",
+ "After %d: [%05d] 0x%04X %s\n",
+ encrypted_len, seq, cmd, qq_get_cmd_desc(cmd));
+#endif
+ return qq_send_data(qd, cmd, seq, need_ack, encrypted_data, encrypted_len);
}
-gint qq_send_cmd_mess(PurpleConnection *gc, guint16 cmd, guint8 *data, gint data_len,
- gint update_class, guint32 ship32)
+/* set seq and need_ack, then call qq_send_cmd_detail */
+gint qq_send_cmd(qq_data *qd, guint16 cmd, guint8 *data, gint data_len)
{
- qq_data *qd;
- guint16 seq;
-
- g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, -1);
- qd = (qq_data *) gc->proto_data;
+ g_return_val_if_fail(qd != NULL, -1);
g_return_val_if_fail(data != NULL && data_len > 0, -1);
- seq = ++qd->send_seq;
-#if 1
- purple_debug_info("QQ", "<== [%05d], %s(0x%04X), datalen %d\n",
- seq, qq_get_cmd_desc(cmd), cmd, data_len);
-#endif
- return send_cmd_detail(gc, cmd, seq, data, data_len, TRUE, update_class, ship32);
+ qd->send_seq++;
+ return qq_send_cmd_detail(qd, cmd, qd->send_seq, TRUE, data, data_len);
}
-/* set seq and need_ack, then call send_cmd_detail */
-gint qq_send_cmd(PurpleConnection *gc, guint16 cmd, guint8 *data, gint data_len)
+gint qq_send_room_cmd_noid(PurpleConnection *gc, guint8 room_cmd,
+ guint8 *data, gint data_len)
{
- qq_data *qd;
- guint16 seq;
- gboolean need_ack;
-
- g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, -1);
- qd = (qq_data *) gc->proto_data;
- g_return_val_if_fail(data != NULL && data_len > 0, -1);
-
- if (cmd != QQ_CMD_LOGOUT) {
- seq = ++qd->send_seq;
- need_ack = TRUE;
- } else {
- seq = 0xFFFF;
- need_ack = FALSE;
- }
-#if 1
- purple_debug_info("QQ", "<== [%05d], %s(0x%04X), datalen %d\n",
- seq, qq_get_cmd_desc(cmd), cmd, data_len);
-#endif
- return send_cmd_detail(gc, cmd, seq, data, data_len, need_ack, 0, 0);
+ return qq_send_room_cmd(gc, room_cmd, 0, data, data_len);
}
-/* set seq and need_ack, then call send_cmd_detail */
-gint qq_send_server_reply(PurpleConnection *gc, guint16 cmd, guint16 seq, guint8 *data, gint data_len)
+gint qq_send_room_cmd_only(PurpleConnection *gc, guint8 room_cmd, guint32 room_id)
{
-#if 1
- purple_debug_info("QQ", "<== [SRV-%05d], %s(0x%04X), datalen %d\n",
- seq, qq_get_cmd_desc(cmd), cmd, data_len);
-#endif
- return send_cmd_detail(gc, cmd, seq, data, data_len, FALSE, 0, 0);
+ g_return_val_if_fail(room_cmd > 0 && room_id > 0, -1);
+ return qq_send_room_cmd(gc, room_cmd, room_id, NULL, 0);
}
-static gint send_room_cmd(PurpleConnection *gc, guint8 room_cmd, guint32 room_id,
- guint8 *data, gint data_len, gint update_class, guint32 ship32)
+gint qq_send_room_cmd(PurpleConnection *gc, guint8 room_cmd, guint32 room_id,
+ guint8 *data, gint data_len)
{
qq_data *qd;
+
guint8 *buf;
gint buf_len;
guint8 *encrypted_data;
gint encrypted_len;
gint bytes_sent;
guint16 seq;
-
+
g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, -1);
qd = (qq_data *) gc->proto_data;
@@ -1025,7 +1106,6 @@ static gint send_room_cmd(PurpleConnecti
if (data != NULL && data_len > 0) {
buf_len += qq_putdata(buf + buf_len, data, data_len);
}
-
qd->send_seq++;
seq = qd->send_seq;
@@ -1034,43 +1114,32 @@ static gint send_room_cmd(PurpleConnecti
encrypted_data = g_newa(guint8, buf_len + 16);
encrypted_len = qq_encrypt(encrypted_data, buf, buf_len, qd->session_key);
if (encrypted_len < 16) {
- purple_debug_error("QQ_ENCRYPT", "Error len %d: [%05d] %s (0x%02X)\n",
- encrypted_len, seq, qq_get_room_cmd_desc(room_cmd), room_cmd);
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ_ENCRYPT",
+ "Error len %d: [%05d] QQ_CMD_ROOM.(0x%02X %s)\n",
+ encrypted_len, seq, room_cmd, qq_get_room_cmd_desc(room_cmd));
return -1;
}
- bytes_sent = packet_send_out(gc, QQ_CMD_ROOM, seq, encrypted_data, encrypted_len);
+ /* Encap header to buf */
+ buf_len = encap(qd, buf, MAX_PACKET_SIZE, QQ_CMD_ROOM, seq, encrypted_data, encrypted_len);
+ if (buf_len <= 0) {
+ return -1;
+ }
+
+ if (qd->use_tcp) {
+ bytes_sent = tcp_send_out(qd, buf, buf_len);
+ } else {
+ bytes_sent = udp_send_out(qd, buf, buf_len);
+ }
+
+ qq_trans_add_room_cmd(qd, seq, room_cmd, room_id, buf, buf_len);
+
#if 1
/* qq_show_packet("QQ_SEND_DATA", buf, buf_len); */
- purple_debug_info("QQ",
- "<== [%05d], %s (0x%02X) to room %d, datalen %d\n",
- seq, qq_get_room_cmd_desc(room_cmd), room_cmd, room_id, buf_len);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ "<== [%05d], QQ_CMD_ROOM.(0x%02X %s) to room %d, total %d bytes is sent %d\n",
+ seq, room_cmd, qq_get_room_cmd_desc(room_cmd), room_id,
+ buf_len, bytes_sent);
#endif
-
- qq_trans_add_room_cmd(gc, seq, room_cmd, room_id, buf, buf_len, update_class, ship32);
return bytes_sent;
}
-
-gint qq_send_room_cmd_mess(PurpleConnection *gc, guint8 room_cmd, guint32 room_id,
- guint8 *data, gint data_len, gint update_class, guint32 ship32)
-{
- return send_room_cmd(gc, room_cmd, room_id, data, data_len, update_class, ship32);
-}
-
-gint qq_send_room_cmd(PurpleConnection *gc, guint8 room_cmd, guint32 room_id,
- guint8 *data, gint data_len)
-{
- return send_room_cmd(gc, room_cmd, room_id, data, data_len, 0, 0);
-}
-
-gint qq_send_room_cmd_noid(PurpleConnection *gc, guint8 room_cmd,
- guint8 *data, gint data_len)
-{
- return send_room_cmd(gc, room_cmd, 0, data, data_len, 0, 0);
-}
-
-gint qq_send_room_cmd_only(PurpleConnection *gc, guint8 room_cmd, guint32 room_id)
-{
- g_return_val_if_fail(room_cmd > 0 && room_id > 0, -1);
- return send_room_cmd(gc, room_cmd, room_id, NULL, 0, 0, 0);
-}
============================================================
--- libpurple/protocols/qq/qq_network.h d179aeabf6d58c136f1d465b18e23a4c64abcc60
+++ libpurple/protocols/qq/qq_network.h 2cdd0ad833eabce487e648a3199219fd25f6492e
@@ -32,23 +32,19 @@
#define QQ_CONNECT_STEPS 3 /* steps in connection */
-gboolean qq_connect_later(gpointer data);
+void qq_connect(PurpleAccount *account);
void qq_disconnect(PurpleConnection *gc);
+void qq_connect_later(PurpleConnection *gc);
-gint qq_send_cmd_encrypted(PurpleConnection *gc, guint16 cmd, guint16 seq,
- guint8 *data, gint data_len, gboolean need_ack);
-gint qq_send_cmd(PurpleConnection *gc, guint16 cmd, guint8 *data, gint datalen);
-gint qq_send_cmd_mess(PurpleConnection *gc, guint16 cmd, guint8 *data, gint data_len,
- gint update_class, guint32 ship32);
+gint qq_send_cmd(qq_data *qd, guint16 cmd, guint8 *data, gint datalen);
+gint qq_send_data(qq_data *qd, guint16 cmd, guint16 seq, gboolean need_ack,
+ guint8 *data, gint data_len);
+gint qq_send_cmd_detail(qq_data *qd, guint16 cmd, guint16 seq, gboolean need_ack,
+ guint8 *data, gint data_len);
-gint qq_send_server_reply(PurpleConnection *gc, guint16 cmd, guint16 seq,
- guint8 *data, gint data_len);
-
gint qq_send_room_cmd(PurpleConnection *gc, guint8 room_cmd, guint32 room_id,
guint8 *data, gint data_len);
-gint qq_send_room_cmd_mess(PurpleConnection *gc, guint8 room_cmd, guint32 room_id,
- guint8 *data, gint data_len, gint update_class, guint32 ship32);
gint qq_send_room_cmd_only(PurpleConnection *gc, guint8 room_cmd, guint32 room_id);
-gint qq_send_room_cmd_noid(PurpleConnection *gc, guint8 room_cmd,
+gint qq_send_room_cmd_noid(PurpleConnection *gc, guint8 room_cmd,
guint8 *data, gint data_len);
#endif
============================================================
--- libpurple/protocols/qq/qq_process.c 0cdaf6d2e2e957e9a0666ac0c2ccf0e25c9bfd5a
+++ libpurple/protocols/qq/qq_process.c 9dfd5fbbb3544fd5b8f71905085661c643d1a563
@@ -26,6 +26,11 @@
#include "debug.h"
#include "internal.h"
+#ifdef _WIN32
+#define random rand
+#define srandom srand
+#endif
+
#include "buddy_info.h"
#include "buddy_list.h"
#include "buddy_opt.h"
@@ -83,7 +88,8 @@ static void process_cmd_unknow(PurpleCon
}
}
-void qq_proc_cmd_server(PurpleConnection *gc, guint16 cmd, guint16 seq, guint8 *rcved, gint rcved_len)
+void qq_proc_cmd_server(PurpleConnection *gc,
+ guint16 cmd, guint16 seq, guint8 *rcved, gint rcved_len)
{
qq_data *qd;
@@ -96,20 +102,20 @@ void qq_proc_cmd_server(PurpleConnection
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",
- "Can not decrypt server cmd by session key, [%05d], 0x%04X %s, len %d\n",
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ",
+ "Can not decrypt server cmd 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",
- "Server cmd decrypted is empty, [%05d], 0x%04X %s, len %d\n",
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ",
+ "Server cmd decrypted is empty, [%05d], 0x%04X %s, len %d\n",
seq, cmd, qq_get_cmd_desc(cmd), rcved_len);
return;
}
-
+
/* now process the packet */
switch (cmd) {
case QQ_CMD_RECV_IM:
@@ -118,7 +124,7 @@ void qq_proc_cmd_server(PurpleConnection
case QQ_CMD_RECV_MSG_SYS:
qq_process_msg_sys(data, data_len, seq, gc);
break;
- case QQ_CMD_BUDDY_CHANGE_STATUS:
+ case QQ_CMD_RECV_MSG_BUDDY_CHANGE_STATUS:
qq_process_buddy_change_status(data, data_len, gc);
break;
default:
@@ -127,198 +133,98 @@ void qq_proc_cmd_server(PurpleConnection
}
}
-static void process_room_cmd_notify(PurpleConnection *gc,
- guint8 room_cmd, guint8 room_id, guint8 reply, guint8 *data, gint data_len)
+static void process_cmd_login(PurpleConnection *gc, guint8 *data, gint data_len)
{
- gchar *msg, *msg_utf8;
- g_return_if_fail(data != NULL && data_len > 0);
-
- msg = g_strndup((gchar *) data, data_len); /* it will append 0x00 */
- msg_utf8 = qq_to_utf8(msg, QQ_CHARSET_DEFAULT);
- g_free(msg);
-
- msg = g_strdup_printf(_("Command %s(0x%02X) id %d, reply [0x%02X]:\n%s"),
- qq_get_room_cmd_desc(room_cmd), room_cmd, room_id, reply, msg_utf8);
-
- purple_notify_error(gc, NULL, _("Invalid QQ Qun reply"), msg);
- g_free(msg);
- g_free(msg_utf8);
-}
-
-void qq_room_update(PurpleConnection *gc, guint8 room_cmd, guint32 room_id)
-{
qq_data *qd;
- qq_group *group;
- gint ret;
+ guint ret_8;
g_return_if_fail (gc != NULL && gc->proto_data != NULL);
+
qd = (qq_data *) gc->proto_data;
- group = qq_room_search_id(gc, room_id);
- if (group == NULL && room_id <= 0) {
- purple_debug_info("QQ", "No room, nothing update\n");
- return;
- }
- if (group == NULL ) {
- purple_debug_warning("QQ", "Failed search room id [%d]\n", room_id);
- return;
- }
+ ret_8 = qq_process_login_reply(data, data_len, gc);
+ if (ret_8 == QQ_LOGIN_REPLY_OK) {
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Login repliess OK; everything is fine\n");
- switch (room_cmd) {
- case 0:
- qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_INFO, group->id, NULL, 0,
- QQ_CMD_CLASS_UPDATE_ROOM, 0);
- break;
- case QQ_ROOM_CMD_GET_INFO:
- ret = qq_request_room_get_buddies(gc, group, QQ_CMD_CLASS_UPDATE_ROOM);
- if (ret <= 0) {
- qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_ONLINES, group->id, NULL, 0,
- QQ_CMD_CLASS_UPDATE_ROOM, 0);
- }
- break;
- case QQ_ROOM_CMD_GET_BUDDIES:
- qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_ONLINES, group->id, NULL, 0,
- QQ_CMD_CLASS_UPDATE_ROOM, 0);
- break;
- case QQ_ROOM_CMD_GET_ONLINES:
- /* last command */
- default:
- break;
- }
-}
+ purple_connection_set_state(gc, PURPLE_CONNECTED);
+ qd->logged_in = TRUE; /* must be defined after sev_finish_login */
-static void update_all_rooms(PurpleConnection *gc, guint8 room_cmd, guint32 room_id)
-{
- qq_data *qd;
- gboolean is_new_turn = FALSE;
- qq_group *next_group;
+ /* now initiate QQ Qun, do it first as it may take longer to finish */
+ qq_group_init(gc);
- g_return_if_fail (gc != NULL && gc->proto_data != NULL);
- qd = (qq_data *) gc->proto_data;
+ /* Now goes on updating my icon/nickname, not showing info_window */
+ qd->modifying_face = FALSE;
- next_group = qq_room_get_next(gc, room_id);
- if (next_group == NULL && room_id <= 0) {
- purple_debug_info("QQ", "No room, nothing update\n");
- qd->is_finish_update = TRUE;
- return;
- }
- if (next_group == NULL ) {
- is_new_turn = TRUE;
- next_group = qq_room_get_next(gc, 0);
- g_return_if_fail(next_group != NULL);
- }
+ qq_send_packet_get_info(gc, qd->uid, FALSE);
+ /* grab my level */
+ qq_send_packet_get_level(gc, qd->uid);
- switch (room_cmd) {
- case 0:
- qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_INFO, next_group->id, NULL, 0,
- QQ_CMD_CLASS_UPDATE_ALL, 0);
- break;
- case QQ_ROOM_CMD_GET_INFO:
- if (!is_new_turn) {
- qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_INFO, next_group->id, NULL, 0,
- QQ_CMD_CLASS_UPDATE_ALL, 0);
- } else {
- qq_request_room_get_buddies(gc, next_group, QQ_CMD_CLASS_UPDATE_ALL);
- }
- break;
- case QQ_ROOM_CMD_GET_BUDDIES:
- /* last command */
- if (!is_new_turn) {
- qq_request_room_get_buddies(gc, next_group, QQ_CMD_CLASS_UPDATE_ALL);
- } else {
- qd->is_finish_update = TRUE;
- }
- break;
- default:
- break;
- }
-}
+ qq_send_packet_change_status(gc);
-void qq_update_all(PurpleConnection *gc, guint16 cmd)
-{
- qq_data *qd;
+ /* refresh buddies */
+ qq_send_packet_get_buddies_list(gc, 0);
- g_return_if_fail (gc != NULL && gc->proto_data != NULL);
- qd = (qq_data *) gc->proto_data;
+ /* refresh groups */
+ qq_send_packet_get_buddies_and_rooms(gc, 0);
- switch (cmd) {
- case 0:
- qq_request_buddy_info(gc, qd->uid, QQ_CMD_CLASS_UPDATE_ALL, QQ_BUDDY_INFO_UPDATE_ONLY);
- break;
- case QQ_CMD_GET_USER_INFO:
- qq_request_change_status(gc, QQ_CMD_CLASS_UPDATE_ALL);
- break;
- case QQ_CMD_CHANGE_STATUS:
- qq_request_get_buddies_list(gc, 0, QQ_CMD_CLASS_UPDATE_ALL);
- break;
- case QQ_CMD_GET_BUDDIES_LIST:
- qq_request_get_buddies_and_rooms(gc, 0, QQ_CMD_CLASS_UPDATE_ALL);
- break;
- case QQ_CMD_GET_BUDDIES_AND_ROOMS:
- qq_request_get_buddies_levels(gc, QQ_CMD_CLASS_UPDATE_ALL);
- 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:
- /* last command */
- update_all_rooms(gc, 0, 0);
- break;
- default:
- break;
+ return;
}
-}
-static void update_all_rooms_online(PurpleConnection *gc, guint8 room_cmd, guint32 room_id)
-{
- qq_data *qd;
- qq_group *next_group;
-
- g_return_if_fail (gc != NULL && gc->proto_data != NULL);
- qd = (qq_data *) gc->proto_data;
-
- next_group = qq_room_get_next_conv(gc, room_id);
- if (next_group == NULL && room_id <= 0) {
- purple_debug_info("QQ", "No room, no update online buddies\n");
+ if (ret_8 == QQ_LOGIN_REPLY_REDIRECT) {
+ qd->is_redirect = TRUE;
+ /*
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ",
+ "Redirected to new server: %s:%d\n", qd->real_hostname, qd->real_port);
+ */
return;
}
- if (next_group == NULL ) {
- purple_debug_info("QQ", "finished update online buddies\n");
+
+ if (ret_8 == QQ_LOGIN_REPLY_ERR_PWD) {
+ if (!purple_account_get_remember_password(gc->account)) {
+ purple_account_set_password(gc->account, NULL);
+ }
+ purple_connection_error_reason(gc,
+ PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Incorrect password."));
return;
}
- switch (room_cmd) {
- case 0:
- qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_ONLINES, next_group->id, NULL, 0,
- QQ_CMD_CLASS_UPDATE_ALL, 0);
- break;
- case QQ_ROOM_CMD_GET_ONLINES:
- qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_ONLINES, next_group->id, NULL, 0,
- QQ_CMD_CLASS_UPDATE_ALL, 0);
- break;
- default:
- break;
+ if (ret_8 == QQ_LOGIN_REPLY_ERR_MISC) {
+ if (purple_debug_is_enabled())
+ purple_connection_error_reason(gc,
+ PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to login. Check debug log."));
+ else
+ purple_connection_error_reason(gc,
+ PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to login"));
+ return;
}
}
-void qq_update_online(PurpleConnection *gc, guint16 cmd)
+static void process_room_cmd_notify(PurpleConnection *gc,
+ guint8 room_cmd, guint8 room_id, guint8 reply_cmd, guint8 reply, guint8 *data, gint data_len)
{
- 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;
- }
+ gchar *msg, *msg_utf8;
+ g_return_if_fail(data != NULL && data_len > 0);
+
+ msg = g_strndup((gchar *) data, data_len); /* it will append 0x00 */
+ msg_utf8 = qq_to_utf8(msg, QQ_CHARSET_DEFAULT);
+ g_free(msg);
+
+ msg = g_strdup_printf(_(
+ "Reply %s(0x%02X )\n"
+ "Sent %s(0x%02X )\n"
+ "Room id %d, reply [0x%02X]: \n"
+ "%s"),
+ qq_get_room_cmd_desc(reply_cmd), reply_cmd,
+ qq_get_room_cmd_desc(room_cmd), room_cmd,
+ room_id, reply, msg_utf8);
+
+ purple_notify_error(gc, NULL, _("Failed room reply"), msg);
+ g_free(msg);
+ g_free(msg_utf8);
}
-void qq_proc_room_cmd_reply(PurpleConnection *gc, guint16 seq,
- guint8 room_cmd, guint32 room_id, guint8 *rcved, gint rcved_len,
- gint update_class, guint32 ship32)
+void qq_proc_room_cmd_reply(PurpleConnection *gc,
+ guint16 seq, guint8 room_cmd, guint32 room_id, guint8 *rcved, gint rcved_len)
{
qq_data *qd;
guint8 *data;
@@ -333,57 +239,58 @@ void qq_proc_room_cmd_reply(PurpleConnec
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",
- "Can not decrypt room cmd by session key, [%05d], 0x%02X %s for %d, len %d\n",
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ",
+ "Can not decrypt room cmd by session key, [%05d], 0x%02X %s for %d, len %d\n",
seq, room_cmd, qq_get_room_cmd_desc(room_cmd), room_id, rcved_len);
qq_show_packet("Can not decrypted", rcved, rcved_len);
return;
}
if (room_id <= 0) {
- purple_debug_warning("QQ",
- "Invaild room id, [%05d], 0x%02X %s for %d, len %d\n",
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ",
+ "Invaild room id, [%05d], 0x%02X %s for %d, len %d\n",
seq, room_cmd, qq_get_room_cmd_desc(room_cmd), room_id, rcved_len);
return;
}
if (data_len <= 2) {
- purple_debug_warning("QQ",
- "Invaild len of room cmd decrypted, [%05d], 0x%02X %s for %d, len %d\n",
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ",
+ "Invaild len of room cmd decrypted, [%05d], 0x%02X %s for %d, len %d\n",
seq, room_cmd, qq_get_room_cmd_desc(room_cmd), room_id, rcved_len);
return;
}
-
+
group = qq_room_search_id(gc, room_id);
if (group == NULL) {
- purple_debug_warning("QQ",
- "Missing room id in [%05d], 0x%02X %s for %d, len %d\n",
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ",
+ "Missing room id in [%05d], 0x%02X %s for %d, len %d\n",
seq, room_cmd, qq_get_room_cmd_desc(room_cmd), room_id, rcved_len);
}
-
+
bytes = 0;
bytes += qq_get8(&reply_cmd, data + bytes);
bytes += qq_get8(&reply, data + bytes);
if (reply_cmd != room_cmd) {
- purple_debug_warning("QQ",
- "Missing room cmd in reply 0x%02X %s, [%05d], 0x%02X %s for %d, len %d\n",
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ",
+ "Missing room cmd in reply 0x%02X %s, [%05d], 0x%02X %s for %d, len %d\n",
reply_cmd, qq_get_room_cmd_desc(reply_cmd),
seq, room_cmd, qq_get_room_cmd_desc(room_cmd), room_id, rcved_len);
}
-
+
/* now process the packet */
if (reply != QQ_ROOM_CMD_REPLY_OK) {
if (group != NULL) {
qq_set_pending_id(&qd->joining_groups, group->ext_id, FALSE);
}
-
+
switch (reply) { /* this should be all errors */
case QQ_ROOM_CMD_REPLY_NOT_MEMBER:
if (group != NULL) {
- purple_debug_warning("QQ",
- _("You are not a member of QQ Qun \"%s\"\n"), group->title_utf8);
- group->my_role = QQ_ROOM_ROLE_NO;
+ purple_debug(PURPLE_DEBUG_WARNING,
+ "QQ",
+ _("You are not a member of group \"%s\"\n"), group->group_name_utf8);
+ group->my_status = QQ_GROUP_MEMBER_STATUS_NOT_MEMBER;
qq_group_refresh(gc, group);
}
break;
@@ -393,7 +300,7 @@ void qq_proc_room_cmd_reply(PurpleConnec
purple_roomlist_set_in_progress(qd->roomlist, FALSE);
}
default:
- process_room_cmd_notify(gc, reply_cmd, room_id, reply, data + bytes, data_len - bytes);
+ process_room_cmd_notify(gc, room_cmd, room_id, reply_cmd, reply, data + bytes, data_len - bytes);
}
return;
}
@@ -402,6 +309,10 @@ void qq_proc_room_cmd_reply(PurpleConnec
switch (reply_cmd) {
case QQ_ROOM_CMD_GET_INFO:
qq_process_room_cmd_get_info(data + bytes, data_len - bytes, gc);
+ if (group != NULL) {
+ qq_send_cmd_group_get_members_info(gc, group);
+ qq_send_cmd_group_get_online_members(gc, group);
+ }
break;
case QQ_ROOM_CMD_CREATE:
qq_group_process_create_group_reply(data + bytes, data_len - bytes, gc);
@@ -435,90 +346,30 @@ void qq_proc_room_cmd_reply(PurpleConnec
if (group != NULL)
qq_group_conv_refresh_online_member(gc, group);
break;
- case QQ_ROOM_CMD_GET_BUDDIES:
- qq_process_room_cmd_get_buddies(data + bytes, data_len - bytes, gc);
+ case QQ_ROOM_CMD_GET_MEMBER_INFO:
+ qq_process_room_cmd_get_members(data + bytes, data_len - bytes, gc);
if (group != NULL)
qq_group_conv_refresh_online_member(gc, group);
break;
default:
- purple_debug_warning("QQ", "Unknow room cmd 0x%02X %s\n",
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ",
+ "Unknow room cmd 0x%02X %s\n",
reply_cmd, qq_get_room_cmd_desc(reply_cmd));
}
-
- purple_debug_info("QQ", "Update class %d\n", update_class);
- if (update_class == QQ_CMD_CLASS_UPDATE_ALL) {
- update_all_rooms(gc, room_cmd, room_id);
- return;
- }
- if (update_class == QQ_CMD_CLASS_UPDATE_ONLINE) {
- update_all_rooms_online(gc, room_cmd, room_id);
- return;
- }
- if (update_class == QQ_CMD_CLASS_UPDATE_ROOM) {
- qq_room_update(gc, room_cmd, room_id);
- }
}
-void qq_proc_cmd_login(PurpleConnection *gc, guint8 *rcved, gint rcved_len)
+void qq_proc_cmd_reply(PurpleConnection *gc,
+ guint16 cmd, guint16 seq, guint8 *rcved, gint rcved_len)
{
qq_data *qd;
- guint8 *data;
- gint data_len;
- guint ret_8;
- g_return_if_fail (gc != NULL && gc->proto_data != NULL);
- qd = (qq_data *) gc->proto_data;
-
- data = g_newa(guint8, rcved_len);
- /* May use password_twice_md5 in the past version like QQ2005*/
- data_len = qq_decrypt(data, rcved, rcved_len, qd->inikey);
- if (data_len >= 0) {
- purple_debug_warning("QQ",
- "Decrypt login reply packet with inikey, %d bytes\n", data_len);
- } else {
- data_len = qq_decrypt(data, rcved, rcved_len, qd->password_twice_md5);
- if (data_len >= 0) {
- purple_debug_warning("QQ",
- "Decrypt login reply packet with password_twice_md5, %d bytes\n", data_len);
- } else {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Can not decrypt login reply"));
- return;
- }
- }
-
- ret_8 = qq_process_login_reply(gc, data, data_len);
- if (ret_8 != QQ_LOGIN_REPLY_OK) {
- return;
- }
-
- purple_debug_info("QQ", "Login repliess OK; everything is fine\n");
-
- purple_connection_set_state(gc, PURPLE_CONNECTED);
- qd->is_login = TRUE; /* must be defined after sev_finish_login */
-
- /* now initiate QQ Qun, do it first as it may take longer to finish */
- qq_group_init(gc);
-
- /* Now goes on updating my icon/nickname, not showing info_window */
- qd->modifying_face = FALSE;
-
- qq_update_all(gc, 0);
- return;
-}
-
-void qq_proc_cmd_reply(PurpleConnection *gc, guint16 cmd, guint16 seq,
- guint8 *rcved, gint rcved_len, gint update_class, guint32 ship32)
-{
- qq_data *qd;
-
guint8 *data;
gint data_len;
guint8 ret_8 = 0;
guint16 ret_16 = 0;
guint32 ret_32 = 0;
- gboolean is_unknow = FALSE;
+ gchar *error_msg = NULL;
g_return_if_fail(rcved_len > 0);
@@ -526,23 +377,61 @@ void qq_proc_cmd_reply(PurpleConnection
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 (cmd == QQ_CMD_TOKEN) {
+ g_memmove(data, rcved, rcved_len);
+ data_len = rcved_len;
+ } else if (cmd == QQ_CMD_LOGIN) {
+ /* May use password_twice_md5 in the past version like QQ2005*/
+ data_len = qq_decrypt(data, rcved, rcved_len, qd->inikey);
+ if (data_len >= 0) {
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ",
+ "Decrypt login reply packet with inikey, %d bytes\n", data_len);
+ } else {
+ data_len = qq_decrypt(data, rcved, rcved_len, qd->password_twice_md5);
+ if (data_len >= 0) {
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ",
+ "Decrypt login reply packet with password_twice_md5, %d bytes\n", data_len);
+ } else {
+ purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ _("Can not decrypt login reply"));
+ return;
+ }
+ }
+ } else {
+ data_len = qq_decrypt(data, rcved, rcved_len, qd->session_key);
+ if (data_len < 0) {
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ",
+ "Can not reply 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",
+ purple_debug(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_TOKEN:
+ ret_8 = qq_process_token_reply(gc, error_msg, data, data_len);
+ if (ret_8 != QQ_TOKEN_REPLY_OK) {
+ if (error_msg == NULL) {
+ error_msg = g_strdup_printf( _("Invalid token reply code, 0x%02X"), ret_8);
+ }
+ purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_msg);
+ g_free(error_msg);
+ return;
+ }
+
+ qq_send_packet_login(gc);
+ break;
+ case QQ_CMD_LOGIN:
+ process_cmd_login(gc, data, data_len);
+ break;
case QQ_CMD_UPDATE_INFO:
qq_process_modify_info_reply(data, data_len, gc);
break;
@@ -561,7 +450,7 @@ void qq_proc_cmd_reply(PurpleConnection
case QQ_CMD_GET_USER_INFO:
qq_process_get_info_reply(data, data_len, gc);
break;
- case QQ_CMD_CHANGE_STATUS:
+ case QQ_CMD_CHANGE_ONLINE_STATUS:
qq_process_change_status_reply(data, data_len, gc);
break;
case QQ_CMD_SEND_IM:
@@ -573,53 +462,41 @@ void qq_proc_cmd_reply(PurpleConnection
case QQ_CMD_GET_BUDDIES_ONLINE:
ret_8 = qq_process_get_buddies_online_reply(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(PURPLE_DEBUG_INFO, "QQ", "Requesting for more online buddies\n");
+ qq_send_packet_get_buddies_online(gc, ret_8);
+ } else {
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "All online buddies received\n");
+ /* Fixme: this should not be called once*/
+ qq_send_packet_get_buddies_levels(gc);
+
+ qq_refresh_all_buddy_status(gc);
}
- purple_debug_info("QQ", "All online buddies received\n");
- qq_refresh_all_buddy_status(gc);
break;
case QQ_CMD_GET_LEVEL:
qq_process_get_level_reply(data, data_len, gc);
break;
case QQ_CMD_GET_BUDDIES_LIST:
ret_16 = qq_process_get_buddies_list_reply(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;
+ if (ret_16 > 0 && ret_16 < 0xffff) {
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Requesting for more buddies\n");
+ qq_send_packet_get_buddies_list(gc, ret_16);
+ } else {
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "All buddies received. Requesting buddies' levels\n");
+ qq_send_packet_get_buddies_online(gc, 0);
}
- purple_debug_info("QQ", "All buddies received. Requesting buddies' levels\n");
break;
case QQ_CMD_GET_BUDDIES_AND_ROOMS:
ret_32 = qq_process_get_buddies_and_rooms(data, data_len, gc);
if (ret_32 > 0 && ret_32 < 0xffffffff) {
- purple_debug_info("QQ", "Requesting for more buddies and groups\n");
- qq_request_get_buddies_and_rooms(gc, ret_32, update_class);
- return;
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Requesting for more buddies and groups\n");
+ qq_send_packet_get_buddies_and_rooms(gc, ret_32);
+ } else {
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "All buddies and groups received\n");
}
- purple_debug_info("QQ", "All buddies and groups received\n");
break;
default:
process_cmd_unknow(gc, "Unknow reply CMD", data, data_len, cmd, seq);
- is_unknow = TRUE;
break;
}
- if (is_unknow)
- 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;
- }
}
============================================================
--- libpurple/protocols/qq/qq_process.h 2f018e76532ac55f6c6241268da8606ff3ad811b
+++ libpurple/protocols/qq/qq_process.h 85481566d6e1810595242ecd79f2cdd00533b4c1
@@ -30,24 +30,12 @@
#include "qq.h"
-enum {
- QQ_CMD_CLASS_NONE = 0,
- QQ_CMD_CLASS_UPDATE_ALL,
- QQ_CMD_CLASS_UPDATE_ONLINE,
- QQ_CMD_CLASS_UPDATE_ROOM,
-};
-
-void qq_proc_cmd_login(PurpleConnection *gc, guint8 *rcved, gint rcved_len);
-void qq_proc_cmd_reply(PurpleConnection *gc, guint16 cmd, guint16 seq,
- guint8 *rcved, gint rcved_len, gint update_class, guint32 ship32);
-void qq_proc_room_cmd_reply(PurpleConnection *gc, guint16 seq,
- guint8 room_cmd, guint32 room_id, guint8 *rcved, gint rcved_len,
- gint update_class, guint32 ship32);
-
-void qq_proc_cmd_server(PurpleConnection *gc, guint16 cmd, guint16 seq, guint8 *rcved, gint rcved_len);
-
-void qq_update_all(PurpleConnection *gc, guint16 cmd);
-void qq_update_online(PurpleConnection *gc, guint16 cmd);
-void qq_room_update(PurpleConnection *gc, guint8 room_cmd, guint32 room_id);
+void qq_proc_cmd_reply(PurpleConnection *gc,
+ guint16 cmd, guint16 seq, guint8 *rcved, gint rcved_len);
+void qq_proc_room_cmd_reply(PurpleConnection *gc,
+ guint16 seq, guint8 room_cmd, guint32 room_id, guint8 *rcved, gint rcved_len);
+
+void qq_proc_cmd_server(PurpleConnection *gc,
+ guint16 cmd, guint16 seq, guint8 *rcved, gint rcved_len);
#endif
============================================================
--- libpurple/protocols/qq/qq_trans.c 166bf6c83885256e73dfc43353cec519daa9a131
+++ libpurple/protocols/qq/qq_trans.c 5428a1f0f85c64a6e38cab4fc2777c98a2e4a853
@@ -37,35 +37,8 @@
#define QQ_RESEND_MAX 3 /* max resend per packet */
-enum {
- QQ_TRANS_IS_SERVER = 0x01, /* Is server command or client command */
- QQ_TRANS_IS_IMPORT = 0x02, /* Only notice if not get reply; or resend, disconn if reties get 0*/
- QQ_TRANS_BEFORE_LOGIN = 0x04, /* server command before login*/
-};
-
-struct _qq_transaction {
- guint8 flag;
- guint16 seq;
- guint16 cmd;
-
- guint8 room_cmd;
- guint32 room_id;
-
- guint8 *data;
- gint data_len;
-
- gint fd;
- gint send_retries;
- gint rcved_times;
- gint scan_times;
-
- gint update_class;
- guint32 ship32;
-};
-
-qq_transaction *qq_trans_find_rcved(PurpleConnection *gc, guint16 cmd, guint16 seq)
+qq_transaction *qq_trans_find_rcved(qq_data *qd, guint16 cmd, guint16 seq)
{
- qq_data *qd = (qq_data *)gc->proto_data;
GList *curr;
GList *next;
qq_transaction *trans;
@@ -77,21 +50,19 @@ qq_transaction *qq_trans_find_rcved(Purp
next = qd->transactions;
while( (curr = next) ) {
next = curr->next;
-
+
trans = (qq_transaction *) (curr->data);
if(trans->cmd == cmd && trans->seq == seq) {
if (trans->rcved_times == 0) {
trans->scan_times = 0;
}
trans->rcved_times++;
- /* server may not get our confirm reply before, send reply again*/
- /* only rcved buffer stored in transaction
if (qq_trans_is_server(trans) && qq_trans_is_dup(trans)) {
+ /* server may not get our confirm reply before, send reply again*/
if (trans->data != NULL && trans->data_len > 0) {
- qq_send_cmd_encrypted(gc, trans->cmd, trans->seq, trans->data, trans->data_len, FALSE);
+ qq_send_data(qd, trans->cmd, trans->seq, FALSE, trans->data, trans->data_len);
}
}
- */
return trans;
}
}
@@ -99,20 +70,20 @@ qq_transaction *qq_trans_find_rcved(Purp
return NULL;
}
-gboolean qq_trans_is_server(qq_transaction *trans)
+gboolean qq_trans_is_server(qq_transaction *trans)
{
g_return_val_if_fail(trans != NULL, FALSE);
-
+
if (trans->flag & QQ_TRANS_IS_SERVER)
return TRUE;
else
return FALSE;
}
-gboolean qq_trans_is_dup(qq_transaction *trans)
+gboolean qq_trans_is_dup(qq_transaction *trans)
{
g_return_val_if_fail(trans != NULL, TRUE);
-
+
if (trans->rcved_times > 1)
return TRUE;
else
@@ -131,122 +102,115 @@ guint32 qq_trans_get_room_id(qq_transact
return trans->room_id;
}
-gint qq_trans_get_class(qq_transaction *trans)
-{
- g_return_val_if_fail(trans != NULL, QQ_CMD_CLASS_NONE);
- return trans->update_class;
-}
-
-gint qq_trans_get_ship(qq_transaction *trans)
-{
- g_return_val_if_fail(trans != NULL, 0);
- return trans->ship32;
-}
-
-static qq_transaction *trans_create(PurpleConnection *gc, gint fd,
- guint16 cmd, guint16 seq, guint8 *data, gint data_len, gint update_class, guint32 ship32)
-{
- qq_data *qd;
- qq_transaction *trans;
-
- g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, NULL);
- qd = (qq_data *) gc->proto_data;
-
- trans = g_new0(qq_transaction, 1);
-
- memset(trans, 0, sizeof(qq_transaction));
- trans->fd = fd;
- trans->cmd = cmd;
- trans->seq = seq;
-
- trans->data = NULL;
- trans->data_len = 0;
- if (data != NULL && data_len > 0) {
- /* don't use g_strdup, may have 0x00 */
- trans->data = g_memdup(data, data_len);
- trans->data_len = data_len;
- }
-
- trans->update_class = update_class;
- return trans;
-}
-
/* Remove a packet with seq from send trans */
-static void trans_remove(PurpleConnection *gc, qq_transaction *trans)
+static void trans_remove(qq_data *qd, qq_transaction *trans)
{
- qq_data *qd = (qq_data *)gc->proto_data;
g_return_if_fail(qd != NULL && trans != NULL);
-
-#if 0
- purple_debug_info("QQ_TRANS",
+
+ purple_debug(PURPLE_DEBUG_INFO, "QQ_TRANS",
"Remove [%s%05d] retry %d rcved %d scan %d %s\n",
(trans->flag & QQ_TRANS_IS_SERVER) ? "SRV-" : "",
trans->seq,
trans->send_retries, trans->rcved_times, trans->scan_times,
qq_get_cmd_desc(trans->cmd));
-#endif
+
if (trans->data) g_free(trans->data);
qd->transactions = g_list_remove(qd->transactions, trans);
g_free(trans);
}
-void qq_trans_add_client_cmd(PurpleConnection *gc,
- guint16 cmd, guint16 seq, guint8 *data, gint data_len, gint update_class, guint32 ship32)
+void qq_trans_add_client_cmd(qq_data *qd, guint16 cmd, guint16 seq, guint8 *data, gint data_len)
{
- qq_data *qd = (qq_data *)gc->proto_data;
- qq_transaction *trans = trans_create(gc, qd->fd, cmd, seq, data, data_len, update_class, ship32);
+ qq_transaction *trans = g_new0(qq_transaction, 1);
+ g_return_if_fail(trans != NULL);
+
+ trans->flag = 0;
if (cmd == QQ_CMD_TOKEN || cmd == QQ_CMD_LOGIN || cmd == QQ_CMD_KEEP_ALIVE) {
- trans->flag |= QQ_TRANS_IS_IMPORT;
+ trans->flag |= QQ_TRANS_CLI_IMPORT;
}
+ trans->fd = qd->fd;
+ trans->cmd = cmd;
+ trans->seq = seq;
+ trans->room_cmd = 0;
+ trans->room_id = 0;
trans->send_retries = QQ_RESEND_MAX;
-#if 0
- purple_debug_info("QQ_TRANS", "Add client cmd, seq %d, data %p, len %d\n",
+ trans->rcved_times = 0;
+ trans->scan_times = 0;
+
+ trans->data = NULL;
+ trans->data_len = 0;
+ if (data != NULL && data_len > 0) {
+ trans->data = g_memdup(data, data_len); /* don't use g_strdup, may have 0x00 */
+ trans->data_len = data_len;
+ }
+ purple_debug(PURPLE_DEBUG_INFO, "QQ_TRANS",
+ "Add client cmd, seq = %d, data = %p, len = %d\n",
trans->seq, trans->data, trans->data_len);
-#endif
qd->transactions = g_list_append(qd->transactions, trans);
}
-void qq_trans_add_room_cmd(PurpleConnection *gc,
- guint16 seq, guint8 room_cmd, guint32 room_id, guint8 *data, gint data_len,
- gint update_class, guint32 ship32)
+void qq_trans_add_room_cmd(qq_data *qd, guint16 seq, guint8 room_cmd, guint32 room_id,
+ guint8 *data, gint data_len)
{
- qq_data *qd = (qq_data *)gc->proto_data;
- qq_transaction *trans = trans_create(gc, qd->fd, QQ_CMD_ROOM, seq, data, data_len,
- update_class, ship32);
+ qq_transaction *trans = g_new0(qq_transaction, 1);
+ g_return_if_fail(trans != NULL);
+
+ trans->flag = 0;
+ trans->fd = qd->fd;
+ trans->seq = seq;
+ trans->cmd = QQ_CMD_ROOM;
trans->room_cmd = room_cmd;
trans->room_id = room_id;
trans->send_retries = QQ_RESEND_MAX;
-#if 0
- purple_debug_info("QQ_TRANS", "Add room cmd, seq %d, data %p, len %d\n",
+ trans->rcved_times = 0;
+ trans->scan_times = 0;
+
+ trans->data = NULL;
+ trans->data_len = 0;
+ if (data != NULL && data_len > 0) {
+ trans->data = g_memdup(data, data_len); /* don't use g_strdup, may have 0x00 */
+ trans->data_len = data_len;
+ }
+ purple_debug(PURPLE_DEBUG_INFO, "QQ_TRANS",
+ "Add room cmd, seq = %d, data = %p, len = %d\n",
trans->seq, trans->data, trans->data_len);
-#endif
qd->transactions = g_list_append(qd->transactions, trans);
}
-void qq_trans_add_server_cmd(PurpleConnection *gc,
- guint16 cmd, guint16 seq, guint8 *data, gint data_len)
+void qq_trans_add_server_cmd(qq_data *qd, guint16 cmd, guint16 seq, guint8 *data, gint data_len)
{
- qq_data *qd = (qq_data *)gc->proto_data;
- qq_transaction *trans = trans_create(gc, qd->fd, cmd, seq, data, data_len, QQ_CMD_CLASS_NONE, 0);
+ qq_transaction *trans = g_new0(qq_transaction, 1);
+ g_return_if_fail(trans != NULL);
+
trans->flag = QQ_TRANS_IS_SERVER;
- if ( !qd->is_login ) {
+ if ( !qd->logged_in ) {
trans->flag |= QQ_TRANS_BEFORE_LOGIN;
}
+ trans->fd = qd->fd;
+ trans->cmd = cmd;
+ trans->seq = seq;
+ trans->room_cmd = 0;
+ trans->room_id = 0;
trans->send_retries = 0;
trans->rcved_times = 1;
-#if 0
- purple_debug_info("QQ_TRANS", "Add server cmd, seq %d, data %p, len %d\n",
+ trans->scan_times = 0;
+ trans->data = NULL;
+ trans->data_len = 0;
+ if (data != NULL && data_len > 0) {
+ trans->data = g_memdup(data, data_len); /* don't use g_strdup, may have 0x00 */
+ trans->data_len = data_len;
+ }
+ purple_debug(PURPLE_DEBUG_INFO, "QQ_TRANS",
+ "Add server cmd, seq = %d, data = %p, len = %d\n",
trans->seq, trans->data, trans->data_len);
-#endif
qd->transactions = g_list_append(qd->transactions, trans);
}
-void qq_trans_process_before_login(PurpleConnection *gc)
+void qq_trans_process_before_login(qq_data *qd)
{
- qq_data *qd = (qq_data *)gc->proto_data;
GList *curr;
GList *next;
qq_transaction *trans;
@@ -257,44 +221,42 @@ void qq_trans_process_before_login(Purpl
while( (curr = next) ) {
next = curr->next;
trans = (qq_transaction *) (curr->data);
-#if 0
- purple_debug_info("QQ_TRANS", "Scan [%d]\n", trans->seq);
-#endif
+ /* purple_debug(PURPLE_DEBUG_ERROR, "QQ_TRANS", "Scan [%d]\n", trans->seq); */
+
if ( !(trans->flag & QQ_TRANS_IS_SERVER) ) {
continue;
}
if ( !(trans->flag & QQ_TRANS_BEFORE_LOGIN) ) {
continue;
}
- /* set QQ_TRANS_BEFORE_LOGIN off */
+ // set QQ_TRANS_BEFORE_LOGIN off
trans->flag &= ~QQ_TRANS_BEFORE_LOGIN;
- purple_debug_info("QQ_TRANS",
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ_TRANS",
"Process server cmd before login, seq %d, data %p, len %d, send_retries %d\n",
trans->seq, trans->data, trans->data_len, trans->send_retries);
- qq_proc_cmd_reply(gc, trans->seq, trans->cmd, trans->data, trans->data_len, trans->update_class, trans->ship32);
+ qq_proc_cmd_reply(qd->gc, trans->seq, trans->cmd, trans->data, trans->data_len);
}
- /* purple_debug_info("QQ_TRANS", "Scan finished\n"); */
+ /* purple_debug(PURPLE_DEBUG_INFO, "QQ_TRANS", "Scan finished\n"); */
return;
}
-gboolean qq_trans_scan(PurpleConnection *gc)
+gboolean qq_trans_scan(qq_data *qd)
{
- qq_data *qd = (qq_data *)gc->proto_data;
GList *curr;
GList *next;
qq_transaction *trans;
g_return_val_if_fail(qd != NULL, FALSE);
-
+
next = qd->transactions;
while( (curr = next) ) {
next = curr->next;
trans = (qq_transaction *) (curr->data);
- /* purple_debug_info("QQ_TRANS", "Scan [%d]\n", trans->seq); */
-
+ /* purple_debug(PURPLE_DEBUG_INFO, "QQ_TRANS", "Scan [%d]\n", trans->seq); */
+
if (trans->flag & QQ_TRANS_BEFORE_LOGIN) {
/* keep server cmd before login*/
continue;
@@ -308,60 +270,67 @@ gboolean qq_trans_scan(PurpleConnection
if (trans->rcved_times > 0) {
/* Has been received */
- trans_remove(gc, trans);
+ trans_remove(qd, trans);
continue;
}
if (trans->flag & QQ_TRANS_IS_SERVER) {
continue;
}
-
+
/* Never get reply */
trans->send_retries--;
if (trans->send_retries <= 0) {
- purple_debug_warning("QQ_TRANS",
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ_TRANS",
"[%d] %s is lost.\n",
trans->seq, qq_get_cmd_desc(trans->cmd));
- if (trans->flag & QQ_TRANS_IS_IMPORT) {
+ if (trans->flag & QQ_TRANS_CLI_IMPORT) {
return TRUE;
}
- purple_debug_error("QQ_TRANS",
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ_TRANS",
"Lost [%d] %s, data %p, len %d, retries %d\n",
trans->seq, qq_get_cmd_desc(trans->cmd),
trans->data, trans->data_len, trans->send_retries);
- trans_remove(gc, trans);
+ trans_remove(qd, trans);
continue;
}
- purple_debug_error("QQ_TRANS",
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ_TRANS",
"Resend [%d] %s data %p, len %d, send_retries %d\n",
trans->seq, qq_get_cmd_desc(trans->cmd),
trans->data, trans->data_len, trans->send_retries);
- qq_send_cmd_encrypted(gc, trans->cmd, trans->seq, trans->data, trans->data_len, FALSE);
+ qq_send_data(qd, trans->cmd, trans->seq, FALSE, trans->data, trans->data_len);
}
- /* purple_debug_info("QQ_TRANS", "Scan finished\n"); */
+ /* purple_debug(PURPLE_DEBUG_INFO, "QQ_TRANS", "Scan finished\n"); */
return FALSE;
}
/* clean up send trans and free all contents */
-void qq_trans_remove_all(PurpleConnection *gc)
+void qq_trans_remove_all(qq_data *qd)
{
- qq_data *qd = (qq_data *)gc->proto_data;
+ GList *curr;
+ GList *next;
qq_transaction *trans;
gint count = 0;
- while(qd->transactions != NULL) {
- trans = (qq_transaction *) (qd->transactions->data);
- qd->transactions = g_list_remove(qd->transactions, trans);
+ curr = qd->transactions;
+ while(curr) {
+ next = curr->next;
+
+ trans = (qq_transaction *) (curr->data);
+ /*
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ_TRANS",
+ "Remove to transaction, seq = %d, buf = %p, len = %d\n",
+ trans->seq, trans->buf, trans->len);
+ */
+ trans_remove(qd, trans);
- if (trans->data) g_free(trans->data);
- g_free(trans);
-
count++;
+ curr = next;
}
- if (count > 0) {
- purple_debug_info("QQ_TRANS", "Free all %d packets\n", count);
- }
+ g_list_free(qd->transactions);
+
+ purple_debug(PURPLE_DEBUG_INFO, "QQ_TRANS", "Free all %d packets\n", count);
}
============================================================
--- libpurple/protocols/qq/qq_trans.h f2aa20b1890c075f7279612c60de46c2565f10f2
+++ libpurple/protocols/qq/qq_trans.h f4ace6ce706004259974c5198b24d9ac5daaa541
@@ -28,27 +28,44 @@
#include <glib.h>
#include "qq.h"
-typedef struct _qq_transaction qq_transaction;
+enum {
+ QQ_TRANS_IS_SERVER = 0x01, /* Is server command or client command */
+ /* prefix QQ_TRANS_CLI is for client command*/
+ QQ_TRANS_CLI_EMERGE = 0x02, /* send at once; or may wait for next reply*/
+ QQ_TRANS_CLI_IMPORT = 0x04, /* Only notice if not get reply; or resend, disconn if reties get 0*/
+ QQ_TRANS_BEFORE_LOGIN = 0x08, /* server command before login*/
+};
-qq_transaction *qq_trans_find_rcved(PurpleConnection *gc, guint16 cmd, guint16 seq);
+typedef struct _qq_transaction {
+ guint8 flag;
+ guint16 seq;
+ guint16 cmd;
+
+ guint8 room_cmd;
+ guint32 room_id;
+
+ guint8 *data;
+ gint data_len;
+
+ gint fd;
+ gint send_retries;
+ gint rcved_times;
+ gint scan_times;
+} qq_transaction;
+
+qq_transaction *qq_trans_find_rcved(qq_data *qd, guint16 cmd, guint16 seq);
gboolean qq_trans_is_server(qq_transaction *trans) ;
gboolean qq_trans_is_dup(qq_transaction *trans);
guint8 qq_trans_get_room_cmd(qq_transaction *trans);
guint32 qq_trans_get_room_id(qq_transaction *trans);
-gint qq_trans_get_class(qq_transaction *trans);
-gint qq_trans_get_ship(qq_transaction *trans);
-void qq_trans_add_client_cmd(PurpleConnection *gc, guint16 cmd, guint16 seq,
- guint8 *data, gint data_len, gint update_class, guint32 ship32);
-void qq_trans_add_room_cmd(PurpleConnection *gc,
- guint16 seq, guint8 room_cmd, guint32 room_id,
- guint8 *data, gint data_len, gint update_class, guint32 ship32);
-
-void qq_trans_add_server_cmd(PurpleConnection *gc, guint16 cmd, guint16 seq,
+void qq_trans_add_client_cmd(qq_data *qd, guint16 cmd, guint16 seq, guint8 *data, gint data_len);
+void qq_trans_add_server_cmd(qq_data *qd, guint16 cmd, guint16 seq, guint8 *data, gint data_len);
+void qq_trans_add_room_cmd(qq_data *qd, guint16 seq, guint8 room_cmd, guint32 room_id,
guint8 *data, gint data_len);
-void qq_trans_process_before_login(PurpleConnection *gc);
-gboolean qq_trans_scan(PurpleConnection *gc);
-void qq_trans_remove_all(PurpleConnection *gc);
+void qq_trans_process_before_login(qq_data *qd);
+gboolean qq_trans_scan(qq_data *qd);
+void qq_trans_remove_all(qq_data *qd);
#endif
============================================================
--- libpurple/protocols/qq/send_file.c 0377a21744db2dc5edfd2fb7d9a4c427a3e68250
+++ libpurple/protocols/qq/send_file.c d8145843c01450a9064f4b31328ad9ca7761d1d7
@@ -54,7 +54,7 @@ static int _qq_in_same_lan(ft_info *info
static int _qq_in_same_lan(ft_info *info)
{
if (info->remote_internet_ip == info->local_internet_ip) return 1;
- purple_debug_info("QQ",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
"Not in the same LAN, remote internet ip[%x], local internet ip[%x]\n",
info->remote_internet_ip
, info->local_internet_ip);
@@ -87,7 +87,7 @@ static ssize_t _qq_xfer_udp_recv(guint8
info = (ft_info *) xfer->data;
sinlen = sizeof(sin);
r = recvfrom(info->recv_fd, buf, len, 0, (struct sockaddr *) &sin, &sinlen);
- purple_debug_info("QQ",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
"==> recv %d bytes from File UDP Channel, remote ip[%s], remote port[%d]\n",
r, inet_ntoa(sin.sin_addr), g_ntohs(sin.sin_port));
return r;
@@ -121,12 +121,12 @@ static ssize_t _qq_xfer_udp_send(const g
sin.sin_port = g_htons(info->remote_minor_port);
sin.sin_addr.s_addr = g_htonl(info->remote_real_ip);
}
- purple_debug_info("QQ", "sending to channel: %d.%d.%d.%d:%d\n",
- sin.sin_addr.s_addr & 0xff,
- (sin.sin_addr.s_addr >> 8) & 0xff,
- (sin.sin_addr.s_addr >> 16) & 0xff,
- sin.sin_addr.s_addr >> 24,
- g_ntohs(sin.sin_port)
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "sending to channel: %d.%d.%d.%d:%d\n",
+ (int)sin.sin_addr.s_addr & 0xff,
+ (int)(sin.sin_addr.s_addr >> 8) & 0xff,
+ (int)(sin.sin_addr.s_addr >> 16) & 0xff,
+ (int)sin.sin_addr.s_addr >> 24,
+ (int)g_ntohs(sin.sin_port)
);
return sendto(info->sender_fd, buf, len, 0, (struct sockaddr *) &sin, sizeof(sin));
}
@@ -207,20 +207,20 @@ static void _qq_xfer_end(PurpleXfer *xfe
qq_xfer_close_file(xfer);
if (info->dest_fp != NULL) {
fclose(info->dest_fp);
- purple_debug_info("QQ", "file closed\n");
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "file closed\n");
}
if (info->major_fd != 0) {
close(info->major_fd);
- purple_debug_info("QQ", "major port closed\n");
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "major port closed\n");
}
if (info->minor_fd != 0) {
close(info->minor_fd);
- purple_debug_info("QQ", "minor port closed\n");
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "minor port closed\n");
}
/*
if (info->buffer != NULL) {
munmap(info->buffer, purple_xfer_get_size(xfer));
- purple_debug_info("QQ", "file mapping buffer is freed.\n");
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "file mapping buffer is freed.\n");
}
*/
g_free(info);
@@ -235,7 +235,7 @@ static void qq_show_conn_info(ft_info *i
real_ip_str = gen_ip_str((guint8 *) &ip);
ip = g_htonl(info->remote_internet_ip);
internet_ip_str = gen_ip_str((guint8 *) &ip);
- purple_debug_info("QQ", "remote internet ip[%s:%d], major port[%d], real ip[%s], minor port[%d]\n",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "remote internet ip[%s:%d], major port[%d], real ip[%s], minor port[%d]\n",
internet_ip_str, info->remote_internet_port,
info->remote_major_port, real_ip_str, info->remote_minor_port
);
@@ -393,7 +393,7 @@ static void _qq_xfer_init_socket(PurpleX
info->local_real_ip = 0x7f000001;
*/
info->local_real_ip = g_ntohl(inet_addr(purple_network_get_my_ip(-1)));
- purple_debug_info("QQ", "local real ip is %x", info->local_real_ip);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "local real ip is %x", info->local_real_ip);
for (i = 0; i < 2; i++) {
sockfd = socket(PF_INET, SOCK_DGRAM, 0);
@@ -412,13 +412,13 @@ static void _qq_xfer_init_socket(PurpleX
case 0:
info->local_major_port = listen_port;
info->major_fd = sockfd;
- purple_debug_info("QQ", "UDP Major Channel created on port[%d]\n",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "UDP Major Channel created on port[%d]\n",
info->local_major_port);
break;
case 1:
info->local_minor_port = listen_port;
info->minor_fd = sockfd;
- purple_debug_info("QQ", "UDP Minor Channel created on port[%d]\n",
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "UDP Minor Channel created on port[%d]\n",
info->local_minor_port);
break;
}
@@ -475,9 +475,9 @@ static void _qq_send_packet_file_request
bytes += qq_putdata (raw_data + bytes, (guint8 *) filelen_str, filelen_strlen);
if (packet_len == bytes)
- qq_send_cmd(gc, QQ_CMD_SEND_IM, raw_data, bytes);
+ qq_send_cmd (qd, QQ_CMD_SEND_IM, raw_data, bytes);
else
- purple_debug_info("qq_send_packet_file_request",
+ purple_debug (PURPLE_DEBUG_INFO, "qq_send_packet_file_request",
"%d bytes expected but got %d bytes\n",
packet_len, bytes);
@@ -497,7 +497,7 @@ static void _qq_send_packet_file_accept(
qd = (qq_data *) gc->proto_data;
info = (ft_info *) qd->xfer->data;
- purple_debug_info("QQ", "I've accepted the file transfer request from %d\n", to_uid);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "I've accepted the file transfer request from %d\n", to_uid);
_qq_xfer_init_socket(qd->xfer);
packet_len = 79;
@@ -516,9 +516,9 @@ static void _qq_send_packet_file_accept(
info->local_real_ip = real_ip;
if (packet_len == bytes)
- qq_send_cmd(gc, QQ_CMD_SEND_IM, raw_data, bytes);
+ qq_send_cmd (qd, QQ_CMD_SEND_IM, raw_data, bytes);
else
- purple_debug_info("qq_send_packet_file_accept",
+ purple_debug (PURPLE_DEBUG_INFO, "qq_send_packet_file_accept",
"%d bytes expected but got %d bytes\n",
packet_len, bytes);
}
@@ -539,13 +539,13 @@ static void _qq_send_packet_file_notifyi
raw_data = g_newa (guint8, packet_len);
bytes = 0;
- purple_debug_info("QQ", "<== sending qq file notify ip packet\n");
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "<== sending qq file notify ip packet\n");
bytes += _qq_create_packet_file_header(raw_data + bytes, to_uid, QQ_FILE_TRANS_NOTIFY, qd, TRUE);
bytes += qq_fill_conn_info(raw_data + bytes, info);
if (packet_len == bytes)
- qq_send_cmd(gc, QQ_CMD_SEND_IM, raw_data, bytes);
+ qq_send_cmd (qd, QQ_CMD_SEND_IM, raw_data, bytes);
else
- purple_debug_info("qq_send_packet_file_notify",
+ purple_debug (PURPLE_DEBUG_INFO, "qq_send_packet_file_notify",
"%d bytes expected but got %d bytes\n",
packet_len, bytes);
@@ -561,7 +561,7 @@ static void _qq_send_packet_file_reject
guint8 *raw_data;
gint packet_len, bytes;
- purple_debug_info("_qq_send_packet_file_reject", "start");
+ purple_debug(PURPLE_DEBUG_INFO, "_qq_send_packet_file_reject", "start");
qd = (qq_data *) gc->proto_data;
packet_len = 64;
@@ -571,9 +571,9 @@ static void _qq_send_packet_file_reject
bytes += _qq_create_packet_file_header(raw_data + bytes, to_uid, QQ_FILE_TRANS_DENY_UDP, qd, TRUE);
if (packet_len == bytes)
- qq_send_cmd(gc, QQ_CMD_SEND_IM, raw_data, bytes);
+ qq_send_cmd (qd, QQ_CMD_SEND_IM, raw_data, bytes);
else
- purple_debug_info("qq_send_packet_file",
+ purple_debug (PURPLE_DEBUG_INFO, "qq_send_packet_file",
"%d bytes expected but got %d bytes\n",
packet_len, bytes);
}
@@ -585,27 +585,27 @@ static void _qq_send_packet_file_cancel
guint8 *raw_data;
gint packet_len, bytes;
- purple_debug_info("_qq_send_packet_file_cancel", "start\n");
+ purple_debug(PURPLE_DEBUG_INFO, "_qq_send_packet_file_cancel", "start\n");
qd = (qq_data *) gc->proto_data;
packet_len = 64;
raw_data = g_newa (guint8, packet_len);
bytes = 0;
- purple_debug_info("_qq_send_packet_file_cancel", "before create header\n");
+ purple_debug(PURPLE_DEBUG_INFO, "_qq_send_packet_file_cancel", "before create header\n");
bytes += _qq_create_packet_file_header(raw_data + bytes, to_uid, QQ_FILE_TRANS_CANCEL, qd, TRUE);
- purple_debug_info("_qq_send_packet_file_cancel", "end create header\n");
+ purple_debug(PURPLE_DEBUG_INFO, "_qq_send_packet_file_cancel", "end create header\n");
if (packet_len == bytes) {
- purple_debug_info("_qq_send_packet_file_cancel", "before send cmd\n");
- qq_send_cmd(gc, QQ_CMD_SEND_IM, raw_data, bytes);
+ purple_debug(PURPLE_DEBUG_INFO, "_qq_send_packet_file_cancel", "before send cmd\n");
+ qq_send_cmd (qd, QQ_CMD_SEND_IM, raw_data, bytes);
}
else
- purple_debug_info("qq_send_packet_file",
+ purple_debug (PURPLE_DEBUG_INFO, "qq_send_packet_file",
"%d bytes expected but got %d bytes\n",
packet_len, bytes);
- purple_debug_info("qq_send_packet_file_cancel", "end\n");
+ purple_debug (PURPLE_DEBUG_INFO, "qq_send_packet_file_cancel", "end\n");
}
/* request to send a file */
@@ -694,7 +694,7 @@ void qq_process_recv_file_reject (guint8
/* border has been checked before
if (*cursor >= (data + data_len - 1)) {
- purple_debug_warning("QQ",
+ purple_debug (PURPLE_DEBUG_WARNING, "QQ",
"Received file reject message is empty\n");
return;
}
@@ -724,7 +724,8 @@ void qq_process_recv_file_cancel (guint8
/* border has been checked before
if (*cursor >= (data + data_len - 1)) {
- purple_debug_warning("QQ", "Received file reject message is empty\n");
+ purple_debug (PURPLE_DEBUG_WARNING, "QQ",
+ "Received file reject message is empty\n");
return;
}
*/
@@ -754,7 +755,8 @@ void qq_process_recv_file_accept(guint8
info = (ft_info *) qd->xfer->data;
if (data_len <= 30 + QQ_CONN_INFO_LEN) {
- purple_debug_warning("QQ", "Received file reject message is empty\n");
+ purple_debug (PURPLE_DEBUG_WARNING, "QQ",
+ "Received file reject message is empty\n");
return;
}
@@ -787,7 +789,8 @@ void qq_process_recv_file_request(guint8
info->to_uid = sender_uid;
if (data_len <= 2 + 30 + QQ_CONN_INFO_LEN) {
- purple_debug_warning("QQ", "Received file request message is empty\n");
+ purple_debug (PURPLE_DEBUG_WARNING, "QQ",
+ "Received file request message is empty\n");
return;
}
bytes = 0;
@@ -803,7 +806,7 @@ void qq_process_recv_file_request(guint8
/* FACE from IP detector, ignored by gfhuang */
if(g_ascii_strcasecmp(fileinfo[0], "FACE") == 0) {
- purple_debug_warning("QQ",
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ",
"Received a FACE ip detect from qq-%d, so he/she must be online :)\n", sender_uid);
b = purple_find_buddy(gc->account, sender_name);
@@ -823,11 +826,11 @@ void qq_process_recv_file_request(guint8
qq_update_buddy_contact(gc, q_bud);
}
else
- purple_debug_info("QQ", "buddy %d is already online\n", sender_uid);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "buddy %d is already online\n", sender_uid);
}
else
- purple_debug_warning("QQ", "buddy %d is not in list\n", sender_uid);
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ", "buddy %d is not in list\n", sender_uid);
g_free(sender_name);
g_strfreev(fileinfo);
@@ -889,7 +892,8 @@ void qq_process_recv_file_notify(guint8
xfer = qd->xfer;
info = (ft_info *) qd->xfer->data;
if (data_len <= 2 + 30 + QQ_CONN_INFO_LEN) {
- purple_debug_warning("QQ", "Received file notify message is empty\n");
+ purple_debug (PURPLE_DEBUG_WARNING, "QQ",
+ "Received file notify message is empty\n");
return;
}
============================================================
--- libpurple/protocols/qq/sys_msg.c b727ae40ad2e341625c4a13fa5405afc921bbe96
+++ libpurple/protocols/qq/sys_msg.c 6e80379b474adc9cdf0823a8a8985f65678fdc0c
@@ -126,7 +126,7 @@ static void _qq_send_packet_ack_msg_sys(
gint ack_len, bytes;
qd = (qq_data *) gc->proto_data;
-
+
str = g_strdup_printf("%d", from);
bar = 0x1e;
ack_len = 1 + 1 + strlen(str) + 1 + 2;
@@ -142,9 +142,9 @@ static void _qq_send_packet_ack_msg_sys(
g_free(str);
if (bytes == ack_len) /* creation OK */
- qq_send_server_reply(gc, QQ_CMD_ACK_SYS_MSG, 0, ack, ack_len);
+ qq_send_cmd_detail(qd, QQ_CMD_ACK_SYS_MSG, 0, FALSE, ack, ack_len);
else
- purple_debug_error("QQ",
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ",
"Fail creating sys msg ACK, expect %d bytes, build %d bytes\n", ack_len, bytes);
}
@@ -194,8 +194,8 @@ static void _qq_process_msg_sys_add_cont
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);
+ message = g_strdup_printf(_("User %s rejected your request"), from);
+ reason = g_strdup_printf(_("Reason: %s"), msg_utf8);
_qq_sys_msg_log_write(gc, message, from);
purple_notify_info(gc, NULL, message, reason);
@@ -214,7 +214,7 @@ static void _qq_process_msg_sys_add_cont
qd = (qq_data *) gc->proto_data;
qq_add_buddy_by_recv_packet(gc, strtol(from, NULL, 10), TRUE, TRUE);
- message = g_strdup_printf(_("Requestion approved by %s"), from);
+ message = g_strdup_printf(_("User %s approved your request"), from);
_qq_sys_msg_log_write(gc, message, from);
purple_notify_info(gc, NULL, message, NULL);
@@ -263,9 +263,9 @@ static void _qq_process_msg_sys_add_cont
g2 = g_new0(gc_and_uid, 1);
g2->gc = gc;
g2->uid = strtol(from, NULL, 10);
- message = g_strdup_printf(_("%s is not in buddy list"), from);
+ message = g_strdup_printf(_("%s is not in your buddy list"), from);
purple_request_action(gc, NULL, message,
- _("Would you add?"), PURPLE_DEFAULT_ACTION_NONE,
+ _("Would you like to add him?"), PURPLE_DEFAULT_ACTION_NONE,
purple_connection_get_account(gc), name, NULL,
g2, 3,
_("Cancel"), NULL,
@@ -279,19 +279,14 @@ static void _qq_process_msg_sys_notice(P
static void _qq_process_msg_sys_notice(PurpleConnection *gc, gchar *from, gchar *to, gchar *msg_utf8)
{
- qq_data *qd = (qq_data *) gc->proto_data;
gchar *title, *content;
g_return_if_fail(from != NULL && to != NULL);
- title = g_strdup_printf(_("QQ Server Notice from %s:"), from);
+ title = g_strdup_printf(_("Notice from: %s"), from);
content = g_strdup_printf(_("%s"), msg_utf8);
- if (qd->is_show_notice) {
- purple_notify_info(gc, NULL, title, content);
- } else {
- purple_debug_info("QQ", "Server notice from %s:\n%s", from, msg_utf8);
-}
+ purple_notify_info(gc, NULL, title, content);
g_free(title);
g_free(content);
}
@@ -315,19 +310,12 @@ void qq_process_msg_sys(guint8 *data, gi
_qq_send_packet_ack_msg_sys(gc, code[0], strtol(from, NULL, 10), seq);
if (strtol(to, NULL, 10) != qd->uid) { /* not to me */
- purple_debug_error("QQ", "Recv sys msg to [%s], not me!, discard\n", to);
+ purple_debug(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;
- }
-
switch (strtol(code, NULL, 10)) {
case QQ_MSG_SYS_BEING_ADDED:
_qq_process_msg_sys_being_added(gc, from, to, msg_utf8);
@@ -345,12 +333,12 @@ void qq_process_msg_sys(guint8 *data, gi
_qq_process_msg_sys_notice(gc, from, to, msg_utf8);
break;
case QQ_MSG_SYS_NEW_VERSION:
- purple_debug_warning("QQ",
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ",
"QQ server says there is newer version than %s\n", qq_get_ver_desc(QQ_CLIENT));
break;
default:
- purple_debug_warning("QQ", "Recv unknown sys msg code: %s\n", code);
- purple_debug_warning("QQ", "the msg is : %s\n", msg_utf8);
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Recv unknown sys msg code: %s\n", code);
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ", "the msg is : %s\n", msg_utf8);
}
g_free(msg_utf8);
g_strfreev(segments);
============================================================
--- libpurple/protocols/qq/utils.c 539d1c7f385eae718d39ad78e11d7367da291373
+++ libpurple/protocols/qq/utils.c 034fd3fc8d7e12ad0491c8e5b6bc0799c1d2a10b
@@ -47,8 +47,8 @@
struct sockaddr_in sin;
socklen_t len = sizeof(sin);
getsockname(fd, (struct sockaddr *)&sin, &len);
- purple_debug_info(desc, "%s:%d\n",
- inet_ntoa(sin.sin_addr), g_ntohs(sin.sin_port));
+ purple_debug(PURPLE_DEBUG_INFO, desc, "%s:%d\n",
+ inet_ntoa(sin.sin_addr), g_ntohs(sin.sin_port));
}
*/
@@ -121,16 +121,16 @@ gchar **split_data(guint8 *data, gint le
for (i = 0; segments[i] != NULL; i++) {;
}
if (i < expected_fields) { /* not enough fields */
- purple_debug_error("QQ", "Invalid data, expect %d fields, found only %d, discard\n",
- expected_fields, i);
+ purple_debug(PURPLE_DEBUG_ERROR, "QQ",
+ "Invalid data, expect %d fields, found only %d, discard\n", expected_fields, i);
g_strfreev(segments);
return NULL;
} else if (i > expected_fields) { /* more fields, OK */
- purple_debug_warning("QQ", "Dangerous data, expect %d fields, found %d, return all\n",
- expected_fields, i);
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ",
+ "Dangerous data, expect %d fields, found %d, return all\n", expected_fields, i);
/* free up those not used */
for (j = expected_fields; j < i; j++) {
- purple_debug_warning("QQ", "field[%d] is %s\n", j, segments[j]);
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ", "field[%d] is %s\n", j, segments[j]);
g_free(segments[j]);
}
@@ -218,7 +218,7 @@ gchar* try_dump_as_gbk(const guint8 *con
msg_utf8 = i < len ? qq_to_utf8((gchar *) &incoming[i], QQ_CHARSET_DEFAULT) : NULL;
if (msg_utf8 != NULL) {
- purple_debug_warning("QQ", "Try extract GB msg: %s\n", msg_utf8);
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Try extract GB msg: %s\n", msg_utf8);
}
return msg_utf8;
}
@@ -257,7 +257,7 @@ guint8 *hex_str_to_bytes(const gchar *co
hex_buffer = strstrip(buffer);
if (strlen(hex_buffer) % 2 != 0) {
- purple_debug_warning("QQ",
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ",
"Unable to convert an odd number of nibbles to a string of bytes!\n");
g_free(hex_buffer);
return NULL;
@@ -272,8 +272,8 @@ guint8 *hex_str_to_bytes(const gchar *co
} else if (g_ascii_isalpha(*cursor) && (gint) *cursor - 87 < 16) {
nibble1 = (gint) *cursor - 87;
} else {
- purple_debug_warning("QQ", "Invalid char \'%c\' found in hex string!\n",
- *cursor);
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ",
+ "Invalid char \'%c\' found in hex string!\n", *cursor);
g_free(hex_str);
return NULL;
}
@@ -284,7 +284,8 @@ guint8 *hex_str_to_bytes(const gchar *co
} else if (g_ascii_isalpha(*cursor) && (gint) (*cursor - 87) < 16) {
nibble2 = (gint) *cursor - 87;
} else {
- purple_debug_warning("QQ", "Invalid char found in hex string!\n");
+ purple_debug(PURPLE_DEBUG_WARNING, "QQ",
+ "Invalid char found in hex string!\n");
g_free(hex_str);
return NULL;
}
@@ -361,7 +362,22 @@ void qq_show_packet(const gchar *desc, c
void qq_show_packet(const gchar *desc, const guint8 *buf, gint len)
{
- qq_hex_dump(PURPLE_DEBUG_INFO, "QQ", buf, len, desc);
+ /*
+ char buf1[8*len+2], buf2[10];
+ int i;
+ buf1[0] = 0;
+ for (i = 0; i < len; i++) {
+ sprintf(buf2, " %02x(%d)", buf[i] & 0xff, buf[i] & 0xff);
+ strcat(buf1, buf2);
+ }
+ strcat(buf1, "\n");
+ purple_debug(PURPLE_DEBUG_INFO, desc, "%s", buf1);
+ */
+
+ /* modified by s3e, 20080424 */
+ qq_hex_dump(PURPLE_DEBUG_INFO, desc,
+ buf, len,
+ "");
}
/* convert face num from packet (0-299) to local face (1-100) */
@@ -381,16 +397,5 @@ const char *qq_buddy_icon_dir(void)
if (purple_prefs_exists("/prpl/qq/buddy_icon_dir"))
return purple_prefs_get_string("/prpl/qq/buddy_icon_dir");
else
- return QQ_BUDDY_ICON_DIR;
+ return NULL;
}
-
-#ifdef _WIN32
-const char *qq_win32_buddy_icon_dir(void)
-{
- static char *dir = NULL;
- if (dir == NULL)
- dir = g_build_filename(wpurple_install_dir(), "pixmaps",
- "purple", "buddy_icons", "qq", NULL);
- return dir;
-}
-#endif
============================================================
--- libpurple/protocols/qq/utils.h a391181cf3622cac8ce340dc75b39779c362456b
+++ libpurple/protocols/qq/utils.h fe344b9710669a7efae22d9cc4180d2ae7423150
@@ -56,6 +56,5 @@ const gchar *qq_buddy_icon_dir(void);
guint8 *hex_str_to_bytes(const gchar *buf, gint *out_len);
const gchar *qq_buddy_icon_dir(void);
-const gchar *qq_win32_buddy_icon_dir(void);
#endif
More information about the Commits
mailing list