pidgin: 8cebefbc: 2008.08.16 - ccpaging <ecc_hy(at)hotmail...
csyfek at gmail.com
csyfek at gmail.com
Fri Sep 12 10:30:41 EDT 2008
-----------------------------------------------------------------
Revision: 8cebefbc6cd5d84acb69c74e69e8821f11dd225d
Ancestor: f12c8903079425d7850fa183df0b3f937b2952be
Author: csyfek at gmail.com
Date: 2008-09-11T13:25:07
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/8cebefbc6cd5d84acb69c74e69e8821f11dd225d
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:
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.
-------------- next part --------------
============================================================
--- libpurple/protocols/qq/AUTHORS c46c7dfe83578267955d8b41cb3a2e3df7c44577
+++ libpurple/protocols/qq/AUTHORS 9010c8d4979848a7d3c99d2a5338f11067a58ab9
@@ -1,35 +1,38 @@ Code Contributors
Code Contributors
-=====
-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
+=========
+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
Lovely Patch Writers
-=====
-gnap : message displaying, documentation
-manphiz : qun processing
-moo : qun processing
-Coly Li : qun processing
+=========
+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
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
+=========
+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
khc at pidgin.im
qulogic at pidgin.im
rlaager at pidgin.im
-OpenQ Team
-LumaQQ Team
-OpenQ Google Group
+OpenQ Google Group : http://groups.google.com/group/openq
============================================================
--- libpurple/protocols/qq/ChangeLog 4ed95b382ab28c61dc0a3833a75d776e61952d5e
+++ libpurple/protocols/qq/ChangeLog d1c1aa5ec35e4616ee6b82d1902fb89aa8c8e8d8
@@ -1,6 +1,17 @@
+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 6903a2b652ab9269e046c9bf44f9d11371a42a17
+++ libpurple/protocols/qq/buddy_info.c 8692742a441f53367bb7b6f606d7b59a74ecb2bc
@@ -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(qd, QQ_CMD_GET_USER_INFO, (guint8 *) uid_str, strlen(uid_str));
+ qq_send_cmd(gc, QQ_CMD_GET_USER_INFO, (guint8 *) uid_str, strlen(uid_str));
query = g_new0(qq_info_query, 1);
query->uid = uid;
@@ -293,6 +293,20 @@ 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)
@@ -314,7 +328,6 @@ 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;
@@ -446,7 +459,7 @@ static void qq_send_packet_modify_info(P
bytes += qq_put8(raw_data + bytes, bar);
- qq_send_cmd(qd, QQ_CMD_UPDATE_INFO, raw_data, bytes);
+ qq_send_cmd(gc, QQ_CMD_UPDATE_INFO, raw_data, bytes);
}
@@ -697,8 +710,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(PURPLE_DEBUG_INFO, "QQ", "Update info ACK OK\n");
- purple_notify_info(gc, NULL, _("Your information has been updated"), NULL);
+ purple_debug_info("QQ", "Update info ACK OK\n");
+ purple_notify_info(gc, NULL, _("My information has been updated"), NULL);
}
}
@@ -746,8 +759,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 = 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)");
+ 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);
gboolean icon_global = purple_account_get_bool(gc->account, "use-global-buddyicon", TRUE);
if (!icon_path)
@@ -756,13 +769,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 (buddy_icon_dir && !(g_ascii_strncasecmp(icon_path, buddy_icon_dir, dir_len) == 0
+ if (!(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(PURPLE_DEBUG_ERROR, "QQ", "%s\n", errmsg);
+ purple_debug_error("QQ", "%s\n", errmsg);
else
purple_notify_error(gc, _("Invalid QQ Face"), errmsg, NULL);
g_free(errmsg);
@@ -775,7 +788,7 @@ void qq_set_my_buddy_icon(PurpleConnecti
/* ensure face number in proper range */
if (icon_num > QQ_FACES) {
if (icon_global)
- purple_debug(PURPLE_DEBUG_ERROR, "QQ", "%s\n", errmsg);
+ purple_debug_error("QQ", "%s\n", errmsg);
else
purple_notify_error(gc, _("Invalid QQ Face"), errmsg, NULL);
g_free(errmsg);
@@ -798,8 +811,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)) && (qq_buddy_icon_dir() != NULL))
+ if (old_icon_num == NULL ||
+ strcmp(icon_num_str, old_icon_num))
{
gchar *icon_path;
@@ -902,19 +915,21 @@ void qq_info_query_free(qq_data *qd)
void qq_info_query_free(qq_data *qd)
{
- gint i;
+ gint count;
qq_info_query *p;
g_return_if_fail(qd != NULL);
- i = 0;
+ count = 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);
- i++;
+ count++;
}
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "%d info queries are freed!\n", i);
+ if (count > 0) {
+ purple_debug_info("QQ", "%d info queries are freed!\n", count);
+ }
}
void qq_send_packet_get_level(PurpleConnection *gc, guint32 uid)
@@ -927,10 +942,10 @@ void qq_send_packet_get_level(PurpleConn
bytes += qq_put32(buf + bytes, uid);
qd = (qq_data *) gc->proto_data;
- qq_send_cmd(qd, QQ_CMD_GET_LEVEL, buf, bytes);
+ qq_send_cmd(gc, QQ_CMD_GET_LEVEL, buf, bytes);
}
-void qq_send_packet_get_buddies_levels(PurpleConnection *gc)
+void qq_request_get_buddies_levels(PurpleConnection *gc, gint update_class)
{
guint8 *buf;
guint16 size;
@@ -942,12 +957,11 @@ void qq_send_packet_get_buddies_levels(P
if ( qd->buddies == NULL) {
return;
}
- /* server only sends back levels for online buddies, no point
- * in asking for anyone else */
- size = 4 * g_list_length(qd->buddies) + 1;
+ /* server only reply levels for online buddies */
+ size = 4 * g_list_length(qd->buddies) + 1 + 4;
buf = g_newa(guint8, size);
bytes += qq_put8(buf + bytes, 0x00);
-
+
while (NULL != node) {
q_bud = (qq_buddy *) node->data;
if (NULL != q_bud) {
@@ -955,7 +969,10 @@ void qq_send_packet_get_buddies_levels(P
}
node = node->next;
}
- qq_send_cmd(qd, QQ_CMD_GET_LEVEL, buf, size);
+
+ /* 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);
}
void qq_process_get_level_reply(guint8 *decr_buf, gint decr_len, PurpleConnection *gc)
@@ -970,9 +987,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(PURPLE_DEBUG_ERROR, "QQ",
+ purple_debug_error("QQ",
"Get levels list of abnormal length. Truncating last %d bytes.\n", decr_len % 12);
decr_len -= (decr_len % 12);
}
@@ -980,19 +997,18 @@ void qq_process_get_level_reply(guint8 *
bytes += 1;
/* this byte seems random */
/*
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "Byte one of get_level packet: %d\n", buf[0]);
+ 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(PURPLE_DEBUG_INFO, "QQ_LEVEL",
- "%d, tmOnline: %d, level: %d, tmRemainder: %d\n",
+ 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(PURPLE_DEBUG_WARNING, "QQ", "Got my levels as %d\n", qd->my_level);
+ purple_debug_warning("QQ", "Got my levels as %d\n", qd->my_level);
continue;
}
@@ -1000,7 +1016,7 @@ void qq_process_get_level_reply(guint8 *
if (purple_name == NULL) {
continue;
}
-
+
b = purple_find_buddy(account, purple_name);
g_free(purple_name);
@@ -1008,10 +1024,9 @@ void qq_process_get_level_reply(guint8 *
if (b != NULL) {
q_bud = (qq_buddy *) b->proto_data;
}
-
+
if (q_bud == NULL) {
- purple_debug(PURPLE_DEBUG_ERROR, "QQ",
- "Got levels of %d not in my buddy list\n", uid);
+ purple_debug_error("QQ", "Got levels of %d not in my buddy list\n", uid);
continue;
}
============================================================
--- libpurple/protocols/qq/buddy_info.h 62ff812350c859993cfed122110108f0d87b0b1b
+++ libpurple/protocols/qq/buddy_info.h 1788934386864124acf1163392f41bea2c5eaad9
@@ -51,14 +51,14 @@
#define QQ_FRIEND_FLAG_MOBILE 0x10
#define QQ_FRIEND_FLAG_BIND_MOBILE 0x20
*/
-#define QQ_COMM_FLAG_QQ_MEMBER 0x02
-#define QQ_COMM_FLAG_QQ_VIP 0x04
+#define QQ_COMM_FLAG_QQ_VIP 0x02
+#define QQ_COMM_FLAG_QQ_MEMBER 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_SPACE 0x02
+#define QQ_EXT_FLAG_ZONE 0x02
#define QQ_BUDDY_GENDER_GG 0x00
#define QQ_BUDDY_GENDER_MM 0x01
@@ -67,7 +67,15 @@
#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);
@@ -75,6 +83,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_send_packet_get_buddies_levels(PurpleConnection *gc);
+void qq_request_get_buddies_levels(PurpleConnection *gc, gint update_class);
void qq_process_get_level_reply(guint8 *buf, gint buf_len, PurpleConnection *gc);
#endif
============================================================
--- libpurple/protocols/qq/buddy_list.c 19f9e2ad310d5eb343b54d6bd41b75019994d0ff
+++ libpurple/protocols/qq/buddy_list.c 902dfa24074b09d996a0a2d4ff89b38c00d3e947
@@ -56,7 +56,7 @@ typedef struct _qq_buddy_online {
} qq_buddy_online;
/* get a list of online_buddies */
-void qq_send_packet_get_buddies_online(PurpleConnection *gc, guint8 position)
+void qq_request_get_buddies_online(PurpleConnection *gc, guint8 position, gint update_class)
{
qq_data *qd;
guint8 *raw_data;
@@ -77,15 +77,14 @@ void qq_send_packet_get_buddies_online(P
/* 003-004 */
bytes += qq_put16(raw_data + bytes, 0x0000);
- qq_send_cmd(qd, QQ_CMD_GET_BUDDIES_ONLINE, raw_data, 5);
+ qq_send_cmd_mess(gc, QQ_CMD_GET_BUDDIES_ONLINE, raw_data, 5, update_class, 0);
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_send_packet_get_buddies_list(PurpleConnection *gc, guint16 position)
+void qq_request_get_buddies_list(PurpleConnection *gc, guint16 position, gint update_class)
{
- qq_data *qd = (qq_data *) gc->proto_data;
guint8 raw_data[16] = {0};
gint bytes = 0;
@@ -98,13 +97,12 @@ void qq_send_packet_get_buddies_list(Pur
* March 22, found the 00,00,00 starts to work as well */
bytes += qq_put8(raw_data + bytes, 0x00);
- qq_send_cmd(qd, QQ_CMD_GET_BUDDIES_LIST, raw_data, bytes);
+ qq_send_cmd_mess(gc, QQ_CMD_GET_BUDDIES_LIST, raw_data, bytes, update_class, 0);
}
/* get all list, buddies & Quns with groupsid support */
-void qq_send_packet_get_buddies_and_rooms(PurpleConnection *gc, guint32 position)
+void qq_request_get_buddies_and_rooms(PurpleConnection *gc, guint32 position, gint update_class)
{
- qq_data *qd = (qq_data *) gc->proto_data;
guint8 raw_data[16] = {0};
gint bytes = 0;
@@ -116,7 +114,7 @@ void qq_send_packet_get_buddies_and_room
bytes += qq_put32(raw_data + bytes, 0x00000000);
bytes += qq_put32(raw_data + bytes, position);
- qq_send_cmd(qd, QQ_CMD_GET_BUDDIES_AND_ROOMS, raw_data, bytes);
+ qq_send_cmd_mess(gc, QQ_CMD_GET_BUDDIES_AND_ROOMS, raw_data, bytes, update_class, 0);
}
/* parse the data into qq_buddy_status */
@@ -146,8 +144,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(PURPLE_DEBUG_INFO, "QQ_STATUS",
- "uid: %d, U1: %d, ip: %s:%d, U2:%d, status:%d, U3:%04X\n",
+ 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);
@@ -180,13 +178,12 @@ guint8 qq_process_get_buddies_online_rep
count = 0;
while (bytes < data_len) {
if (data_len - bytes < QQ_ONLINE_BUDDY_ENTRY_LEN) {
- purple_debug(PURPLE_DEBUG_ERROR, "QQ",
- "[buddies online] only %d, need %d",
+ 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 */
@@ -204,31 +201,29 @@ 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(PURPLE_DEBUG_ERROR, "QQ",
- "uid=0 or entry complete len(%d) != %d",
+ 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(PURPLE_DEBUG_WARNING, "QQ",
- "I am in online list %d\n", bo.bs.uid);
+ 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(PURPLE_DEBUG_ERROR, "QQ",
+ 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(PURPLE_DEBUG_ERROR, "QQ",
+ purple_debug_error("QQ",
"Got an online buddy %d, but not in my buddy list\n", bo.bs.uid);
continue;
}
@@ -247,11 +242,11 @@ guint8 qq_process_get_buddies_online_rep
}
if(bytes > data_len) {
- purple_debug(PURPLE_DEBUG_ERROR, "QQ",
+ purple_debug_error("QQ",
"qq_process_get_buddies_online_reply: Dangerous error! maybe protocol changed, notify developers!\n");
}
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "Received %d online buddies, nextposition=%u\n",
+ purple_debug_info("QQ", "Received %d online buddies, nextposition=%u\n",
count, (guint) position);
return position;
}
@@ -274,7 +269,7 @@ guint16 qq_process_get_buddies_list_repl
qd = (qq_data *) gc->proto_data;
if (data_len <= 2) {
- purple_debug(PURPLE_DEBUG_ERROR, "QQ", "empty buddies list");
+ purple_debug_error("QQ", "empty buddies list");
return -1;
}
/* qq_show_packet("QQ get buddies list", data, data_len); */
@@ -305,7 +300,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(PURPLE_DEBUG_INFO, "QQ",
+ 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);
@@ -315,7 +310,7 @@ guint16 qq_process_get_buddies_list_repl
}
#if 1
- purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ 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
@@ -334,11 +329,11 @@ guint16 qq_process_get_buddies_list_repl
}
if(bytes > data_len) {
- purple_debug(PURPLE_DEBUG_ERROR, "QQ",
+ purple_debug_error("QQ",
"qq_process_get_buddies_list_reply: Dangerous error! maybe protocol changed, notify developers!");
}
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "Received %d buddies, nextposition=%u\n",
+ purple_debug_info("QQ", "Received %d buddies, nextposition=%u\n",
count, (guint) position);
return position;
}
@@ -364,8 +359,7 @@ guint32 qq_process_get_buddies_and_rooms
bytes += qq_get8(&reply_code, data + bytes);
if(0 != reply_code) {
- purple_debug(PURPLE_DEBUG_WARNING, "QQ",
- "qq_process_get_buddies_and_rooms, %d", reply_code);
+ purple_debug_warning("QQ", "qq_process_get_buddies_and_rooms, %d", reply_code);
}
bytes += qq_get32(&unknown, data + bytes);
@@ -381,48 +375,45 @@ guint32 qq_process_get_buddies_and_rooms
/* 05: groupid*4 */ /* seems to always be 0 */
bytes += qq_get8(&groupid, data + bytes);
/*
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "groupid: %i\n", groupid);
+ purple_debug_info("QQ", "groupid: %i\n", groupid);
groupid >>= 2;
*/
if (uid == 0 || (type != 0x1 && type != 0x4)) {
- purple_debug(PURPLE_DEBUG_INFO, "QQ",
- "Buddy entry, uid=%d, type=%d", uid, type);
+ 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_send_packet_get_buddies_list */
+ /* don't do anything but count - buddies are handled by
+ * qq_request_get_buddies_list */
++i;
} else { /* a group */
group = qq_room_search_id(gc, uid);
if(group == NULL) {
- purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ 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_status = QQ_GROUP_MEMBER_STATUS_IS_MEMBER;
+ group->my_role = QQ_ROOM_ROLE_YES;
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(PURPLE_DEBUG_ERROR, "QQ",
+ purple_debug_error("QQ",
"qq_process_get_buddies_and_rooms: Dangerous error! maybe protocol changed, notify developers!");
}
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "Received %d buddies and %d groups, nextposition=%u\n", i, j, (guint) position);
+ 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 */
@@ -441,9 +432,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);
@@ -460,7 +451,7 @@ gint get_icon_offset(PurpleConnection *g
}
/* send a packet to change my online status */
-void qq_send_packet_change_status(PurpleConnection *gc)
+void qq_request_change_status(PurpleConnection *gc, gint update_class)
{
qq_data *qd;
guint8 raw_data[16] = {0};
@@ -469,13 +460,13 @@ void qq_send_packet_change_status(Purple
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->logged_in)
+ if (!qd->is_login)
return;
if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_INVISIBLE)) {
@@ -497,7 +488,7 @@ void qq_send_packet_change_status(Purple
bytes += qq_put8(raw_data + bytes, away_cmd);
bytes += qq_put32(raw_data + bytes, misc_status);
- qq_send_cmd(qd, QQ_CMD_CHANGE_ONLINE_STATUS, raw_data, bytes);
+ qq_send_cmd_mess(gc, QQ_CMD_CHANGE_STATUS, raw_data, bytes, update_class, 0);
}
/* parse the reply packet for change_status */
@@ -513,15 +504,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(PURPLE_DEBUG_WARNING, "QQ", "Change status fail 0x%02X\n", reply);
+ purple_debug_warning("QQ", "Change status fail 0x%02X\n", reply);
return;
}
- /* purple_debug(PURPLE_DEBUG_INFO, "QQ", "Change status OK\n"); */
+ /* 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);
@@ -532,7 +523,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;
@@ -547,16 +538,16 @@ void qq_process_buddy_change_status(guin
qd = (qq_data *) gc->proto_data;
if (data_len < 35) {
- purple_debug(PURPLE_DEBUG_ERROR, "QQ", "[buddy status change] only %d, need 35 bytes\n", data_len);
+ 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);
@@ -565,13 +556,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(PURPLE_DEBUG_ERROR, "QQ",
+ purple_debug_error("QQ",
"got information of unknown buddy %d\n", bs.uid);
return;
}
- 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) {
+ 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;
}
@@ -589,24 +580,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(PURPLE_DEBUG_ERROR, "QQ", "Not find purple name: %d\n", q_bud->uid);
+ 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(PURPLE_DEBUG_ERROR, "QQ", "Not find buddy: %d\n", q_bud->uid);
+ 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_refresh = time(NULL);
+ q_bud->last_update = time(NULL);
/* purple supports signon and idle time
* but it is not much use for QQ, I do not use them */
@@ -630,10 +621,10 @@ void qq_update_buddy_contact(PurpleConne
break;
default:
status_id = "invisible";
- purple_debug(PURPLE_DEBUG_ERROR, "QQ", "unknown status: %x\n", q_bud->status);
+ purple_debug_error("QQ", "unknown status: %x\n", q_bud->status);
break;
}
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "buddy %d %s\n", q_bud->uid, status_id);
+ 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)
@@ -664,7 +655,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_refresh + QQ_UPDATE_ONLINE_INTERVAL
+ if (q_bud != NULL && now > q_bud->last_update + 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 d69cbb9b2e26383154467b6d47cacbe6d38eb005
+++ libpurple/protocols/qq/buddy_list.h 794a9c7da4eb380f57107828529a94d654afc3db
@@ -42,19 +42,19 @@ enum {
enum {
QQ_BUDDY_OFFLINE = 0x00,
- QQ_BUDDY_ONLINE_NORMAL = 0x0a,
- QQ_BUDDY_ONLINE_OFFLINE = 0x14,
- QQ_BUDDY_ONLINE_AWAY = 0x1e,
- QQ_BUDDY_ONLINE_INVISIBLE = 0x28
+ QQ_BUDDY_ONLINE_NORMAL = 10,
+ QQ_BUDDY_ONLINE_OFFLINE = 20,
+ QQ_BUDDY_ONLINE_AWAY = 30,
+ QQ_BUDDY_ONLINE_INVISIBLE = 40
};
-void qq_send_packet_get_buddies_online(PurpleConnection *gc, guint8 position);
+void qq_request_get_buddies_online(PurpleConnection *gc, guint8 position, gint update_class);
guint8 qq_process_get_buddies_online_reply(guint8 *data, gint data_len, PurpleConnection *gc);
-void qq_send_packet_get_buddies_list(PurpleConnection *gc, guint16 position);
+void qq_request_get_buddies_list(PurpleConnection *gc, guint16 position, gint update_class);
guint16 qq_process_get_buddies_list_reply(guint8 *data, gint data_len, PurpleConnection *gc);
-void qq_send_packet_get_buddies_and_rooms(PurpleConnection *gc, guint32 position);
+void qq_request_get_buddies_and_rooms(PurpleConnection *gc, guint32 position, gint update_class);
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_send_packet_change_status(PurpleConnection *gc);
+void qq_request_change_status(PurpleConnection *gc, gint update_class);
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 d19581650142be4fa3db797f2ca04efae553818e
+++ libpurple/protocols/qq/buddy_opt.c 17be05a5e83a7c2dc34c5e332950e77304837fb7
@@ -60,19 +60,17 @@ 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(qd, QQ_CMD_DEL_BUDDY, (guint8 *) uid_str, strlen(uid_str));
+ qq_send_cmd(gc, 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;
@@ -80,7 +78,7 @@ static void _qq_send_packet_remove_self_
bytes += qq_put32(raw_data + bytes, uid);
- qq_send_cmd(qd, QQ_CMD_REMOVE_SELF, raw_data, bytes);
+ qq_send_cmd(gc, QQ_CMD_REMOVE_SELF, raw_data, bytes);
}
/* try to add a buddy without authentication */
@@ -94,7 +92,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(qd, QQ_CMD_ADD_BUDDY_WO_AUTH, (guint8 *) uid_str, strlen(uid_str));
+ qq_send_cmd(gc, 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);
@@ -106,7 +104,6 @@ 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;
@@ -128,7 +125,7 @@ static void _qq_send_packet_buddy_auth(P
g_free(text_qq);
}
- qq_send_cmd(qd, QQ_CMD_BUDDY_AUTH, raw_data, bytes);
+ qq_send_cmd(gc, 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)
@@ -204,11 +201,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(_("Input your reason:"));
+ msg2 = g_strdup(_("Message:"));
nombre = uid_to_purple_name(uid);
purple_request_input(gc, _("Reject request"), msg1, msg2,
- _("Sorry, you are not my type..."), TRUE, FALSE,
+ _("Sorry, you are not my style..."), TRUE, FALSE,
NULL, _("Reject"), G_CALLBACK(_qq_reject_add_request_real), _("Cancel"), NULL,
purple_connection_get_account(gc), nombre, NULL,
g2);
@@ -261,7 +258,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(PURPLE_DEBUG_WARNING, "QQ", "Add buddy with auth request failed\n");
+ purple_debug_warning("QQ", "Add buddy with auth request failed\n");
if (NULL == (segments = split_data(data, data_len, "\x1f", 2))) {
return;
}
@@ -269,7 +266,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(PURPLE_DEBUG_INFO, "QQ", "Add buddy with auth request OK\n");
+ purple_debug_info("QQ", "Add buddy with auth request OK\n");
}
}
@@ -284,16 +281,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(PURPLE_DEBUG_WARNING, "QQ", "Remove buddy fails\n");
+ purple_debug_warning("QQ", "Remove buddy fails\n");
} else { /* if reply */
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "Remove buddy OK\n");
+ 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;
@@ -303,11 +300,12 @@ void qq_process_remove_self_reply(guint8
if (data[0] != QQ_REMOVE_SELF_REPLY_OK) {
/* there is no reason return from server */
- purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Remove self fails\n");
+ purple_debug_warning("QQ", "Remove self fails\n");
+ purple_notify_info(gc, NULL, _("Failed removing from friend's buddy list"), NULL);
} else { /* if reply */
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "Remove self from a buddy OK\n");
+ purple_debug_info("QQ", "Remove from a buddy OK\n");
/* TODO: Does the user really need to be notified about this? */
- purple_notify_info(gc, NULL, _("You have successfully removed yourself from your friend's buddy list"), NULL);
+ purple_notify_info(gc, NULL, _("Successed removing from friend's buddy list"), NULL);
}
}
@@ -340,25 +338,25 @@ void qq_process_add_buddy_reply(guint8 *
}
if (for_uid == 0) { /* we have no record for this */
- purple_debug(PURPLE_DEBUG_ERROR, "QQ", "We have no record for add buddy reply [%d], discard\n", seq);
+ purple_debug_error("QQ", "We have no record for add buddy reply [%d], discard\n", seq);
return;
} else {
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "Add buddy reply [%d] is for id [%d]\n", seq, for_uid);
+ 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(PURPLE_DEBUG_ERROR, "QQ", "Add buddy reply is to [%s], not me!", uid);
+ 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(PURPLE_DEBUG_WARNING, "QQ", "Add buddy attempt fails, need authentication\n");
+ 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)
@@ -366,7 +364,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(_("User %d needs authentication"), for_uid);
+ msg = g_strdup_printf(_("%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?"),
@@ -397,7 +395,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(PURPLE_DEBUG_WARNING, "QQ", "Add new group: %s\n", group_name);
+ purple_debug_warning("QQ", "Add new group: %s\n", group_name);
}
return g;
@@ -440,11 +438,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_send_packet_get_buddies_online(gc, 0);
+ qq_request_get_buddies_online(gc, 0, 0);
}
purple_blist_add_buddy(b, NULL, g, NULL);
- purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Add new buddy: [%s]\n", name);
+ purple_debug_warning("QQ", "Add new buddy: [%s]\n", name);
g_free(name);
g_free(group_name);
@@ -454,8 +452,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->logged_in=TRUE AFTER serv_finish_login(gc) */
+ * it also calls this funtion, so we have to
+ * define qd->is_login=TRUE AFTER serv_finish_login(gc) */
void qq_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
{
qq_data *qd;
@@ -463,7 +461,7 @@ void qq_add_buddy(PurpleConnection *gc,
PurpleBuddy *b;
qd = (qq_data *) gc->proto_data;
- if (!qd->logged_in)
+ if (!qd->is_login)
return; /* IMPORTANT ! */
uid = purple_name_to_uid(buddy->name);
@@ -474,8 +472,8 @@ void qq_add_buddy(PurpleConnection *gc,
if (b != NULL)
purple_blist_remove_buddy(b);
purple_notify_error(gc, NULL,
- _("QQid Error"),
- _("Invalid QQid"));
+ _("QQ Number Error"),
+ _("Invalid QQ Number"));
}
}
@@ -490,7 +488,7 @@ void qq_remove_buddy(PurpleConnection *g
qd = (qq_data *) gc->proto_data;
uid = purple_name_to_uid(buddy->name);
- if (!qd->logged_in)
+ if (!qd->is_login)
return;
if (uid > 0)
@@ -502,7 +500,7 @@ void qq_remove_buddy(PurpleConnection *g
if (q_bud != NULL)
qd->buddies = g_list_remove(qd->buddies, q_bud);
else
- purple_debug(PURPLE_DEBUG_WARNING, "QQ", "We have no qq_buddy record for %s\n", buddy->name);
+ 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 */
@@ -514,41 +512,45 @@ void qq_add_buddy_request_free(qq_data *
/* free add buddy request queue */
void qq_add_buddy_request_free(qq_data *qd)
{
- gint i;
+ gint count;
qq_add_buddy_request *p;
- i = 0;
- while (qd->add_buddy_request) {
+ count = 0;
+ while (qd->add_buddy_request != NULL) {
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);
- i++;
+ count++;
}
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "%d add buddy requests are freed!\n", i);
+ if (count > 0) {
+ purple_debug_info("QQ", "%d add buddy requests are freed!\n", count);
+ }
}
/* free up all qq_buddy */
void qq_buddies_list_free(PurpleAccount *account, qq_data *qd)
{
- gint i;
+ gint count;
qq_buddy *p;
gchar *name;
PurpleBuddy *b;
- i = 0;
+ count = 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(PURPLE_DEBUG_INFO, "QQ", "qq_buddy %s not found in purple proto_data\n", name);
+ purple_debug_info("QQ", "qq_buddy %s not found in purple proto_data\n", name);
g_free(name);
g_free(p);
- i++;
+ count++;
}
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "%d qq_buddy structures are freed!\n", i);
+ if (count > 0) {
+ purple_debug_info("QQ", "%d qq_buddy structures are freed!\n", count);
+ }
}
============================================================
--- libpurple/protocols/qq/char_conv.c 56df688312bd04d8a02cd864840335c7ee7a0f06
+++ libpurple/protocols/qq/char_conv.c 5ab4d96c8a4512a964b50263e2fd8588ecc37dc0
@@ -113,7 +113,7 @@ static gchar *_my_convert(const gchar *s
}
/* conversion error */
- purple_debug(PURPLE_DEBUG_ERROR, "QQ_CONVERT", "%s\n", error->message);
+ 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(PURPLE_DEBUG_INFO, "QQ_MESG",
+ 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 6f016b37ef0b595dc8e1aa75c2177636c4eadba7
+++ libpurple/protocols/qq/file_trans.c 2775840f1f4b59ea87cddfc4d8a71b825f1ecd3a
@@ -22,10 +22,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
-#ifdef _WIN32
-#define random rand
-#endif
-
#include "internal.h"
#include "debug.h"
@@ -62,7 +58,7 @@ static guint32 _gen_file_key(void)
{
guint8 seed;
- seed = random();
+ seed = rand() & 0xFF;
return _get_file_key(seed);
}
@@ -261,7 +257,7 @@ static gint _qq_send_file(PurpleConnecti
if (bytes == len + 12) {
_qq_xfer_write(raw_data, bytes, qd->xfer);
} else
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "send_file: want %d but got %d\n", len + 12, bytes);
+ purple_debug_info("QQ", "send_file: want %d but got %d\n", len + 12, bytes);
return bytes;
}
@@ -323,13 +319,13 @@ void qq_send_file_ctl_packet(PurpleConne
bytes_expected = 61;
break;
default:
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "qq_send_file_ctl_packet: Unknown packet type[%d]\n",
+ 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(PURPLE_DEBUG_ERROR, "QQ", "qq_send_file_ctl_packet: Expected to get %d bytes, but get %d",
+ purple_debug_error("QQ", "qq_send_file_ctl_packet: Expected to get %d bytes, but get %d",
bytes_expected, bytes);
return;
}
@@ -346,24 +342,24 @@ void qq_send_file_ctl_packet(PurpleConne
guint8 *buf;
int buflen;
hex_dump = hex_dump_to_str(encrypted_data, encrypted_len);
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "encrypted packet: \n%s", hex_dump);
+ 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(PURPLE_DEBUG_INFO, "QQ", "decrypt success\n");
+ purple_debug_info("QQ", "decrypt success\n");
if (buflen == bytes && memcmp(raw_data, buf, buflen) == 0)
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "checksum ok\n");
+ purple_debug_info("QQ", "checksum ok\n");
hex_dump = hex_dump_to_str(buf, buflen);
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "decrypted packet: \n%s", hex_dump);
+ purple_debug_info("QQ", "decrypted packet: \n%s", hex_dump);
g_free(hex_dump);
} else {
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "decrypt fail\n");
+ purple_debug_info("QQ", "decrypt fail\n");
}
#endif
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "<== send %s packet\n", qq_get_file_cmd_desc(packet_type));
+ 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);
}
@@ -410,7 +406,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(PURPLE_DEBUG_INFO, "QQ",
+ purple_debug_info("QQ",
"start transfering data, %d fragments with %d length each\n",
info->fragment_num, info->fragment_len);
/* Unknown */
@@ -435,7 +431,7 @@ static void _qq_send_file_data_packet(Pu
filename_len);
break;
case QQ_FILE_DATA_INFO:
- purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ 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)); */
@@ -448,7 +444,7 @@ static void _qq_send_file_data_packet(Pu
bytes += qq_putdata(raw_data + bytes, data, len);
break;
case QQ_FILE_EOF:
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "end of sending data\n");
+ 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);
@@ -474,7 +470,7 @@ static void _qq_send_file_data_packet(Pu
break;
}
}
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "<== send %s packet\n", qq_get_file_cmd_desc(packet_type));
+ 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);
}
@@ -516,7 +512,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(PURPLE_DEBUG_ERROR, "QQ", "Error decrypt rcv file ctrl packet\n");
+ purple_debug_error("QQ", "Error decrypt rcv file ctrl packet\n");
return;
}
@@ -526,7 +522,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(PURPLE_DEBUG_INFO, "QQ", "==> [%d] receive %s packet\n", seq, qq_get_file_cmd_desc(packet_type));
+ 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:");
@@ -566,7 +562,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(PURPLE_DEBUG_INFO, "QQ", "unprocess file command %d\n", packet_type);
+ purple_debug_info("QQ", "unprocess file command %d\n", packet_type);
}
}
@@ -577,7 +573,7 @@ static void _qq_recv_file_progess(Purple
ft_info *info = (ft_info *) xfer->data;
guint32 mask;
- purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ 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) {
@@ -585,11 +581,11 @@ static void _qq_recv_file_progess(Purple
purple_xfer_cancel_local(xfer);
return;
}
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "object file opened for writing\n");
+ 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(PURPLE_DEBUG_INFO, "QQ", "duplicate %dth fragment, drop it!\n", index+1);
+ purple_debug_info("QQ", "duplicate %dth fragment, drop it!\n", index+1);
return;
}
@@ -609,7 +605,7 @@ static void _qq_recv_file_progess(Purple
if (mask & 0x8000) mask = 0x0001;
else mask = mask << 1;
}
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "procceed %dth fragment, slide window status %o, max_fragment_index %d\n",
+ purple_debug_info("QQ", "procceed %dth fragment, slide window status %o, max_fragment_index %d\n",
index, info->window, info->max_fragment_index);
}
@@ -654,12 +650,12 @@ static void _qq_update_send_progess(Purp
PurpleXfer *xfer = qd->xfer;
ft_info *info = (ft_info *) xfer->data;
- purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ 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(PURPLE_DEBUG_INFO, "QQ", "duplicate %dth fragment, drop it!\n", fragment_index+1);
+ purple_debug_info("QQ", "duplicate %dth fragment, drop it!\n", fragment_index+1);
return;
}
mask = 0x1 << (fragment_index % sizeof(info->window));
@@ -696,7 +692,7 @@ static void _qq_update_send_progess(Purp
else mask = mask << 1;
}
}
- purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ 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);
}
@@ -737,7 +733,7 @@ static void _qq_process_recv_file_data(P
info->max_fragment_index = 0;
info->window = 0;
- purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ 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,
@@ -747,7 +743,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(PURPLE_DEBUG_INFO, "QQ",
+ purple_debug_info("QQ",
"received %dth fragment with length %d, offset %d\n",
fragment_index, fragment_len, fragment_offset);
@@ -756,7 +752,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(PURPLE_DEBUG_INFO, "QQ", "end of receiving\n");
+ 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;
@@ -795,11 +791,11 @@ static void _qq_process_recv_file_data(P
purple_xfer_end(qd->xfer);
break;
case QQ_FILE_BASIC_INFO:
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "here\n");
+ 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(PURPLE_DEBUG_INFO, "QQ", "_qq_process_recv_file_data: unknown packet type [%d]\n",
+ purple_debug_info("QQ", "_qq_process_recv_file_data: unknown packet type [%d]\n",
packet_type);
break;
}
@@ -824,6 +820,6 @@ void qq_process_recv_file(PurpleConnecti
_qq_process_recv_file_data(gc, data + bytes, len - bytes);
break;
default:
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "unknown packet tag");
+ purple_debug_info("QQ", "unknown packet tag");
}
}
============================================================
--- libpurple/protocols/qq/group.c a3e4159f84756290c5fa166286e2f5353db574a4
+++ libpurple/protocols/qq/group.c b63a859e4c351c158e6a89d580e3f27d8c274c59
@@ -64,7 +64,7 @@ GList *qq_chat_info(PurpleConnection *gc
pce = g_new0(struct proto_chat_entry, 1);
pce->label = _("ID: ");
- pce->identifier = QQ_GROUP_KEY_EXTERNAL_ID;
+ pce->identifier = QQ_ROOM_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_GROUP_KEY_EXTERNAL_ID, g_strdup(chat_name));
+ g_hash_table_insert(defaults, QQ_ROOM_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_GROUP_KEY_EXTERNAL_ID, FALSE);
+ f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, _("Group ID"), QQ_ROOM_KEY_EXTERNAL_ID, FALSE);
fields = g_list_append(fields, f);
- f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, _("Creator"), QQ_GROUP_KEY_CREATOR_UID, FALSE);
+ f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, _("Creator"), QQ_ROOM_KEY_CREATOR_UID, FALSE);
fields = g_list_append(fields, f);
f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING,
- _("Group Description"), QQ_GROUP_KEY_GROUP_DESC_UTF8, FALSE);
+ _("Group Description"), QQ_ROOM_KEY_DESC_UTF8, FALSE);
fields = g_list_append(fields, f);
- f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", QQ_GROUP_KEY_INTERNAL_ID, TRUE);
+ f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", QQ_ROOM_KEY_INTERNAL_ID, TRUE);
fields = g_list_append(fields, f);
- f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", QQ_GROUP_KEY_TYPE, TRUE);
+ f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", QQ_ROOM_KEY_TYPE, TRUE);
fields = g_list_append(fields, f);
- f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, _("Auth"), QQ_GROUP_KEY_AUTH_TYPE, TRUE);
+ f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, _("Auth"), QQ_ROOM_KEY_AUTH_TYPE, TRUE);
fields = g_list_append(fields, f);
- f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", QQ_GROUP_KEY_GROUP_CATEGORY, TRUE);
+ f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", QQ_ROOM_KEY_CATEGORY, TRUE);
fields = g_list_append(fields, f);
- f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", QQ_GROUP_KEY_GROUP_NAME_UTF8, TRUE);
+ f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", QQ_ROOM_KEY_TITLE_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 external group ID"),
- _("You can only search for permanent QQ groups\n"),
+ _("Please enter Qun number"),
+ _("You can only search for permanent Qun\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(PURPLE_DEBUG_INFO, "QQ", "We have no QQ Qun\n");
+ purple_debug_info("QQ", "We have no QQ Qun\n");
return;
}
@@ -178,8 +178,7 @@ void qq_group_init(PurpleConnection *gc)
continue;
count++;
- qq_send_room_cmd_only(gc, QQ_ROOM_CMD_GET_INFO, group->id);
}
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "Load %d QQ Qun configurations\n", count);
+ purple_debug_info("QQ", "Load %d QQ Qun configurations\n", count);
}
============================================================
--- libpurple/protocols/qq/group.h 6d3c438063856a59dbc1f546de3e30ed96373e61
+++ libpurple/protocols/qq/group.h 138edcd1acfee105682a012c88f97c552670320b
@@ -34,27 +34,27 @@ typedef enum {
#define PURPLE_GROUP_QQ_QUN "QQ 群"
typedef enum {
- 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;
+ 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;
typedef struct _qq_group {
/* all these will be saved when we exit Purple */
- qq_group_member_status my_status; /* my status for this group */
- gchar *my_status_desc; /* my status description */
+ qq_room_role my_role; /* my role for this room */
+ gchar *my_role_desc; /* my role description */
guint32 id;
guint32 ext_id;
guint8 type8; /* permanent or temporory */
guint32 creator_uid;
- guint32 group_category;
+ guint32 category;
guint8 auth_type;
- gchar *group_name_utf8;
- gchar *group_desc_utf8;
+ gchar *title_utf8;
+ gchar *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 a98dc976b1feae948a46b3b27d97234555cb5d70
+++ libpurple/protocols/qq/group_conv.c e1a84ee06d272314ac5e9a7881414143368bc618
@@ -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->group_name_utf8, purple_connection_get_account(gc));
+ group->title_utf8, purple_connection_get_account(gc));
if (conv == NULL) /* show only one window per group */
- serv_got_joined_chat(gc, qd->channel++, group->group_name_utf8);
+ serv_got_joined_chat(gc, qd->channel++, group->title_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->group_name_utf8, purple_connection_get_account(gc));
+ group->title_utf8, purple_connection_get_account(gc));
if (conv != NULL && group->members != NULL) {
list = group->members;
while (list != NULL) {
============================================================
--- libpurple/protocols/qq/group_find.c 30312495840bc0286f16541ac847a387638d5b3e
+++ libpurple/protocols/qq/group_find.c 3770c52e75ed6cd6dd9d5528bc37b49f9dad436d
@@ -110,10 +110,10 @@ qq_group *qq_group_find_by_channel(Purpl
group = NULL;
while (list != NULL) {
group = (qq_group *) list->data;
- if (group->group_name_utf8 == NULL) {
+ if (group->title_utf8 == NULL) {
continue;
}
- if (!g_ascii_strcasecmp(purple_conversation_get_name(conv), group->group_name_utf8))
+ if (!g_ascii_strcasecmp(purple_conversation_get_name(conv), group->title_utf8))
break;
list = list->next;
}
@@ -167,3 +167,83 @@ 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 8978a58ba32f8e2fd770e56de5b84c1051e3d7c0
+++ libpurple/protocols/qq/group_find.h 11c372e0accfd6fa0a0f1d725a619139cc9a27ec
@@ -32,10 +32,12 @@ 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 3d3fb0dbfe4e3796b77a2d43596d330feaf73cd1
+++ libpurple/protocols/qq/group_free.c 9062c677324a6d7d94a07885f3f4656da177f617
@@ -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_status_desc);
- g_free(group->group_name_utf8);
- g_free(group->group_desc_utf8);
+ g_free(group->my_role_desc);
+ g_free(group->title_utf8);
+ g_free(group->desc_utf8);
g_free(group->notice_utf8);
g_free(group);
}
@@ -64,16 +64,18 @@ void qq_group_free_all(qq_data *qd)
void qq_group_free_all(qq_data *qd)
{
qq_group *group;
- gint i;
+ gint count;
+
g_return_if_fail(qd != NULL);
-
- i = 0;
+ count = 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++;
}
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "%d groups are freed\n", i);
+ if (count > 0) {
+ purple_debug_info("QQ", "%d rooms are freed\n", count);
+ }
}
============================================================
--- libpurple/protocols/qq/group_im.c f9094b9361ff1fb22d670d6ddd1e937b9df0a7b4
+++ libpurple/protocols/qq/group_im.c c46e53482e9fb4ee95c0a19023b3b85e3bd2fe06
@@ -41,6 +41,7 @@
#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 {
@@ -85,12 +86,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(PURPLE_DEBUG_ERROR, "QQ",
+ 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 */
@@ -98,7 +99,7 @@ void qq_process_group_cmd_im(guint8 *dat
}
/* receive an application to join the group */
-void qq_process_recv_group_im_apply_join(guint8 *data, gint len, guint32 id, PurpleConnection *gc)
+void qq_process_room_msg_apply_join(guint8 *data, gint len, guint32 id, PurpleConnection *gc)
{
guint32 ext_id, user_uid;
guint8 type8;
@@ -119,8 +120,8 @@ void qq_process_recv_group_im_apply_join
bytes += convert_as_pascal_string(data + bytes, &reason_utf8, QQ_CHARSET_DEFAULT);
- msg = g_strdup_printf(_("User %d requested to join group %d"), user_uid, ext_id);
- reason = g_strdup_printf(_("Reason: %s"), reason_utf8);
+ msg = g_strdup_printf(_("%d requested to join Qun %d"), user_uid, ext_id);
+ reason = g_strdup_printf(_("Message: %s"), reason_utf8);
g = g_new0(group_member_opt, 1);
g->gc = gc;
@@ -149,7 +150,7 @@ void qq_process_recv_group_im_apply_join
}
/* the request to join a group is rejected */
-void qq_process_recv_group_im_been_rejected(guint8 *data, gint len, guint32 id, PurpleConnection *gc)
+void qq_process_room_msg_been_rejected(guint8 *data, gint len, guint32 id, PurpleConnection *gc)
{
guint32 ext_id, admin_uid;
guint8 type8;
@@ -170,14 +171,14 @@ void qq_process_recv_group_im_been_rejec
bytes += convert_as_pascal_string(data + bytes, &reason_utf8, QQ_CHARSET_DEFAULT);
msg = g_strdup_printf
- (_("Your request to join group %d has been rejected by admin %d"), ext_id, admin_uid);
- reason = g_strdup_printf(_("Reason: %s"), reason_utf8);
+ (_("Your request to join Qun %d has been rejected by admin %d"), ext_id, admin_uid);
+ reason = g_strdup_printf(_("Message: %s"), reason_utf8);
purple_notify_warning(gc, _("QQ Qun Operation"), msg, reason);
group = qq_room_search_id(gc, id);
if (group != NULL) {
- group->my_status = QQ_GROUP_MEMBER_STATUS_NOT_MEMBER;
+ group->my_role = QQ_ROOM_ROLE_NO;
qq_group_refresh(gc, group);
}
@@ -187,7 +188,7 @@ void qq_process_recv_group_im_been_rejec
}
/* the request to join a group is approved */
-void qq_process_recv_group_im_been_approved(guint8 *data, gint len, guint32 id, PurpleConnection *gc)
+void qq_process_room_msg_been_approved(guint8 *data, gint len, guint32 id, PurpleConnection *gc)
{
guint32 ext_id, admin_uid;
guint8 type8;
@@ -208,13 +209,13 @@ void qq_process_recv_group_im_been_appro
bytes += convert_as_pascal_string(data + bytes, &reason_utf8, QQ_CHARSET_DEFAULT);
msg = g_strdup_printf
- (_("Your request to join group %d has been approved by admin %d"), ext_id, admin_uid);
+ (_("Your request to join Qun %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_status = QQ_GROUP_MEMBER_STATUS_IS_MEMBER;
+ group->my_role = QQ_ROOM_ROLE_YES;
qq_group_refresh(gc, group);
}
@@ -223,7 +224,7 @@ void qq_process_recv_group_im_been_appro
}
/* process the packet when removed from a group */
-void qq_process_recv_group_im_been_removed(guint8 *data, gint len, guint32 id, PurpleConnection *gc)
+void qq_process_room_msg_been_removed(guint8 *data, gint len, guint32 id, PurpleConnection *gc)
{
guint32 ext_id, uid;
guint8 type8;
@@ -241,12 +242,12 @@ void qq_process_recv_group_im_been_remov
g_return_if_fail(ext_id > 0 && uid > 0);
- msg = g_strdup_printf(_("You [%d] have left group \"%d\""), uid, ext_id);
+ msg = g_strdup_printf(_("[%d] removed from Qun \"%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_status = QQ_GROUP_MEMBER_STATUS_NOT_MEMBER;
+ group->my_role = QQ_ROOM_ROLE_NO;
qq_group_refresh(gc, group);
}
@@ -254,7 +255,7 @@ void qq_process_recv_group_im_been_remov
}
/* process the packet when added to a group */
-void qq_process_recv_group_im_been_added(guint8 *data, gint len, guint32 id, PurpleConnection *gc)
+void qq_process_room_msg_been_added(guint8 *data, gint len, guint32 id, PurpleConnection *gc)
{
guint32 ext_id, uid;
guint8 type8;
@@ -272,18 +273,18 @@ void qq_process_recv_group_im_been_added
g_return_if_fail(ext_id > 0 && uid > 0);
- 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"));
+ 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"));
group = qq_room_search_id(gc, id);
if (group != NULL) {
- group->my_status = QQ_GROUP_MEMBER_STATUS_IS_MEMBER;
+ group->my_role = QQ_ROOM_ROLE_YES;
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_status = QQ_GROUP_MEMBER_STATUS_IS_MEMBER;
+ group->my_role = QQ_ROOM_ROLE_YES;
qq_group_refresh(gc, group);
- qq_send_room_cmd_only(gc, QQ_ROOM_CMD_GET_INFO, group->id);
+ qq_room_update(gc, 0, group->id);
/* the return of this cmd will automatically update the group in blist */
}
@@ -291,7 +292,7 @@ void qq_process_recv_group_im_been_added
}
/* recv an IM from a group chat */
-void qq_process_recv_group_im(guint8 *data, gint data_len, guint32 id, PurpleConnection *gc, guint16 im_type)
+void qq_process_room_msg_normal(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;
@@ -310,7 +311,9 @@ void qq_process_recv_group_im(guint8 *da
qd = (qq_data *) gc->proto_data;
- /* qq_hex_dump(PURPLE_DEBUG_INFO, "QQ", data, data_len, "group im hex dump"); */
+#if 0
+ qq_hex_dump(PURPLE_DEBUG_INFO, "QQ", data, data_len, "group im hex dump");
+#endif
im_group = g_newa(qq_recv_group_im, 1);
@@ -374,13 +377,13 @@ void qq_process_recv_group_im(guint8 *da
group = qq_room_search_id(gc, id);
g_return_if_fail(group != NULL);
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, group->group_name_utf8, purple_connection_get_account(gc));
+ conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, group->title_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_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));
+ 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));
}
if (conv != NULL) {
============================================================
--- libpurple/protocols/qq/group_im.h e031720f93defa4bf87c133d2d1640bf868f1ecd
+++ libpurple/protocols/qq/group_im.h 80dbc5dfa185c472df09adc543fa04eea527b8b8
@@ -31,30 +31,17 @@ 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_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_normal(guint8 *data, gint data_len, guint32 id, PurpleConnection *gc, guint16 im_type);
-/* 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_apply_join(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_rejected(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_approved(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_removed(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);
+void qq_process_room_msg_been_added(guint8 *data, gint len, guint32 id, PurpleConnection *gc);
#endif
============================================================
--- libpurple/protocols/qq/group_info.c a1d15e05c9e82fd75464c23ac95f976054396e02
+++ libpurple/protocols/qq/group_info.c 3ea1d5d410f6718065865401f2ced4e7a05302bb
@@ -41,16 +41,16 @@
* this interval determines if their member info is outdated */
#define QQ_GROUP_CHAT_REFRESH_NICKNAME_INTERNAL 180
-static gboolean _is_group_member_need_update_info(qq_buddy *member)
+static gboolean check_update_interval(qq_buddy *member)
{
g_return_val_if_fail(member != NULL, FALSE);
return (member->nickname == NULL) ||
- (time(NULL) - member->last_refresh) > QQ_GROUP_CHAT_REFRESH_NICKNAME_INTERNAL;
+ (time(NULL) - member->last_update) > 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 _qq_group_set_members_all_offline(qq_group *group)
+static void set_all_offline(qq_group *group)
{
GList *list;
qq_buddy *member;
@@ -64,60 +64,24 @@ static void _qq_group_set_members_all_of
}
}
-/* 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 */
-void qq_send_cmd_group_get_members_info(PurpleConnection *gc, qq_group *group)
+gint qq_request_room_get_buddies(PurpleConnection *gc, qq_group *group, gint update_class)
{
guint8 *raw_data;
gint bytes, num;
GList *list;
qq_buddy *member;
- g_return_if_fail(group != NULL);
+ g_return_val_if_fail(group != NULL, 0);
for (num = 0, list = group->members; list != NULL; list = list->next) {
member = (qq_buddy *) list->data;
- if (_is_group_member_need_update_info(member))
+ if (check_update_interval(member))
num++;
}
if (num <= 0) {
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "No group member info needs to be updated now.\n");
- return;
+ purple_debug_info("QQ", "No group member info needs to be updated now.\n");
+ return 0;
}
raw_data = g_newa(guint8, 4 * num);
@@ -127,12 +91,14 @@ void qq_send_cmd_group_get_members_info(
list = group->members;
while (list != NULL) {
member = (qq_buddy *) list->data;
- if (_is_group_member_need_update_info(member))
+ if (check_update_interval(member))
bytes += qq_put32(raw_data + bytes, member->uid);
list = list->next;
}
- qq_send_room_cmd(gc, QQ_ROOM_CMD_GET_MEMBER_INFO, group->id, raw_data, bytes);
+ qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_BUDDIES, group->id, raw_data, bytes,
+ update_class, 0);
+ return num;
}
void qq_process_room_cmd_get_info(guint8 *data, gint data_len, PurpleConnection *gc)
@@ -174,8 +140,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->group_category), data + bytes);
+ bytes += qq_get16(&unknown, data + bytes);
+ bytes += qq_get32(&(group->category), data + bytes);
bytes += qq_get16(&max_members, data + bytes);
bytes += qq_get8(&unknown1, data + bytes);
/* the following, while Eva:
@@ -183,17 +149,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(PURPLE_DEBUG_INFO, "QQ", "type=%u creatorid=%u category=%u maxmembers=%u\n",
- group->type8, group->creator_uid, group->group_category, max_members);
-
+ purple_debug_info("QQ", "type=%u creatorid=%u category=%u maxmembers=%u\n",
+ group->type8, group->creator_uid, group->category, max_members);
+
/* strlen + <str content> */
- 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 += convert_as_pascal_string(data + bytes, &(group->title_utf8), QQ_CHARSET_DEFAULT);
+ purple_debug_info("QQ", "group \"%s\"\n", group->title_utf8);
bytes += qq_get16(&unknown, data + bytes); /* 0x0000 */
bytes += convert_as_pascal_string(data + bytes, ¬ice, QQ_CHARSET_DEFAULT);
- 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);
+ 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);
num = 0;
/* now comes the member list separated by 0x00 */
@@ -205,7 +171,7 @@ void qq_process_room_cmd_get_info(guint8
#if 0
if(organization != 0 || role != 0) {
- purple_debug(PURPLE_DEBUG_INFO, "QQ_GRP", "%d, organization=%d, role=%d\n", member_uid, organization, role);
+ purple_debug_info("QQ_GRP", "%d, organization=%d, role=%d\n", member_uid, organization, role);
}
#endif
@@ -214,22 +180,22 @@ void qq_process_room_cmd_get_info(guint8
member->role = role;
}
if(bytes > data_len) {
- purple_debug(PURPLE_DEBUG_ERROR, "QQ",
+ purple_debug_error("QQ",
"group_cmd_get_group_info: Dangerous error! maybe protocol changed, notify me!");
}
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "group \"%s\" has %d members\n", group->group_name_utf8, num);
+ purple_debug_info("QQ", "group \"%s\" has %d members\n", group->title_utf8, num);
if (group->creator_uid == qd->uid)
- group->my_status = QQ_GROUP_MEMBER_STATUS_IS_ADMIN;
+ group->my_role = QQ_ROOM_ROLE_ADMIN;
qq_group_refresh(gc, group);
- purple_conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
- group->group_name_utf8, purple_connection_get_account(gc));
+ purple_conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
+ group->title_utf8, purple_connection_get_account(gc));
if(NULL == purple_conv) {
- purple_debug(PURPLE_DEBUG_WARNING, "QQ",
- "Conversation \"%s\" is not open, do not set topic\n", group->group_name_utf8);
+ purple_debug_warning("QQ",
+ "Conversation \"%s\" is not open, do not set topic\n", group->title_utf8);
return;
}
@@ -237,7 +203,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);
}
@@ -252,7 +218,7 @@ void qq_process_room_cmd_get_onlines(gui
g_return_if_fail(data != NULL && len > 0);
if (len <= 3) {
- purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Invalid group online member reply, discard it!\n");
+ purple_debug_error("QQ", "Invalid group online member reply, discard it!\n");
return;
}
@@ -263,13 +229,12 @@ void qq_process_room_cmd_get_onlines(gui
group = qq_room_search_id(gc, id);
if (group == NULL) {
- purple_debug(PURPLE_DEBUG_ERROR, "QQ",
- "We have no group info for internal id [%d]\n", id);
+ purple_debug_error("QQ", "We have no group info for internal id [%d]\n", id);
return;
}
/* set all offline first, then update those online */
- _qq_group_set_members_all_offline(group);
+ set_all_offline(group);
num = 0;
while (bytes < len) {
bytes += qq_get32(&member_uid, data + bytes);
@@ -279,15 +244,15 @@ void qq_process_room_cmd_get_onlines(gui
member->status = QQ_BUDDY_ONLINE_NORMAL;
}
if(bytes > len) {
- purple_debug(PURPLE_DEBUG_ERROR, "QQ",
- "group_cmd_get_online_members: Dangerous error! maybe protocol changed, notify developers!");
+ purple_debug_error("QQ",
+ "group_cmd_get_online_members: Dangerous error! maybe protocol changed, notify developers!");
}
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "Group \"%s\" has %d online members\n", group->group_name_utf8, num);
+ purple_debug_info("QQ", "Group \"%s\" has %d online members\n", group->title_utf8, num);
}
/* process the reply to get_members_info packet */
-void qq_process_room_cmd_get_members(guint8 *data, gint len, PurpleConnection *gc)
+void qq_process_room_cmd_get_buddies(guint8 *data, gint len, PurpleConnection *gc)
{
gint bytes;
gint num;
@@ -300,7 +265,7 @@ void qq_process_room_cmd_get_members(gui
g_return_if_fail(data != NULL && len > 0);
#if 0
- qq_show_packet("qq_process_room_cmd_get_members", data, len);
+ qq_show_packet("qq_process_room_cmd_get_buddies", data, len);
#endif
bytes = 0;
@@ -331,19 +296,19 @@ void qq_process_room_cmd_get_members(gui
qq_filter_str(nick);
member->nickname = g_strdup(nick);
g_free(nick);
-
+
#if 0
- purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ 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_refresh = time(NULL);
+ member->last_update = time(NULL);
}
if (bytes > len) {
- purple_debug(PURPLE_DEBUG_ERROR, "QQ",
+ purple_debug_error("QQ",
"group_cmd_get_members_info: Dangerous error! maybe protocol changed, notify developers!");
}
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "Group \"%s\" obtained %d member info\n", group->group_name_utf8, num);
+ purple_debug_info("QQ", "Group \"%s\" obtained %d member info\n", group->title_utf8, num);
}
============================================================
--- libpurple/protocols/qq/group_info.h ec4f93c82296b45db4f59a84f5d0502dd8c5d77a
+++ libpurple/protocols/qq/group_info.h 5acd27bb23463327232e8d73f22c6b33c7a2fe6d
@@ -29,12 +29,9 @@
#include "connection.h"
#include "group.h"
-void qq_send_cmd_group_get_online_members(PurpleConnection *gc, qq_group *group);
-void qq_send_cmd_group_all_get_online_members(PurpleConnection *gc);
+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);
-
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_members(guint8 *data, gint len, PurpleConnection *gc);
+void qq_process_room_cmd_get_buddies(guint8 *data, gint len, PurpleConnection *gc);
#endif
============================================================
--- libpurple/protocols/qq/group_internal.c 67db78e571818d3665ddd87635ef513d4657d957
+++ libpurple/protocols/qq/group_internal.c 5b542d1d030bca842d226cd9a8045b6b53d6d190
@@ -31,49 +31,49 @@
#include "group_internal.h"
#include "utils.h"
-static gchar *_qq_group_set_my_status_desc(qq_group *group)
+static gchar *get_role_desc(qq_group *group)
{
- const char *status_desc;
+ const char *role_desc;
g_return_val_if_fail(group != NULL, g_strdup(""));
- switch (group->my_status) {
- case QQ_GROUP_MEMBER_STATUS_NOT_MEMBER:
- status_desc = _("I am not a member");
+ switch (group->my_role) {
+ case QQ_ROOM_ROLE_NO:
+ role_desc = _("I am not a member");
break;
- case QQ_GROUP_MEMBER_STATUS_IS_MEMBER:
- status_desc = _("I am a member");
+ case QQ_ROOM_ROLE_YES:
+ role_desc = _("I am a member");
break;
- case QQ_GROUP_MEMBER_STATUS_APPLYING:
- status_desc = _("I am applying to join");
+ case QQ_ROOM_ROLE_REQUESTING:
+ role_desc = _("I am requesting");
break;
- case QQ_GROUP_MEMBER_STATUS_IS_ADMIN:
- status_desc = _("I am the admin");
+ case QQ_ROOM_ROLE_ADMIN:
+ role_desc = _("I am the admin");
break;
default:
- status_desc = _("Unknown status");
+ role_desc = _("Unknown status");
}
- return g_strdup(status_desc);
+ return g_strdup(role_desc);
}
-static void _qq_group_add_to_blist(PurpleConnection *gc, qq_group *group)
+static void add_room_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->group_name_utf8, components);
+ chat = purple_chat_new(purple_connection_get_account(gc), group->title_utf8, components);
g = qq_get_purple_group(PURPLE_GROUP_QQ_QUN);
purple_blist_add_chat(chat, g, NULL);
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "You have added group \"%s\" to blist locally\n", group->group_name_utf8);
+ purple_debug_info("QQ", "You have added group \"%s\" to blist locally\n", group->title_utf8);
}
/* Create a dummy qq_group, which includes only internal_id, ext_id,
- * and potentially group_name_utf8, in case we need to call group_conv_show_window
+ * and potentially title_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 *group_name_utf8)
+ guint32 internal_id, guint32 ext_id, gchar *title_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_status = QQ_GROUP_MEMBER_STATUS_NOT_MEMBER;
- group->my_status_desc = _qq_group_set_my_status_desc(group);
+ group->my_role = QQ_ROOM_ROLE_NO;
+ group->my_role_desc = get_role_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->group_category = 0x01;
+ group->category = 0x01;
group->auth_type = 0x02; /* assume need auth */
- group->group_name_utf8 = g_strdup(group_name_utf8 == NULL ? "" : group_name_utf8);
- group->group_desc_utf8 = g_strdup("");
+ group->title_utf8 = g_strdup(title_utf8 == NULL ? "" : title_utf8);
+ group->desc_utf8 = g_strdup("");
group->notice_utf8 = g_strdup("");
group->members = NULL;
qd->groups = g_list_append(qd->groups, group);
- _qq_group_add_to_blist(gc, group);
+ add_room_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_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_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_INTERNAL_ID), g_strdup_printf("%d", group->id));
- g_hash_table_insert(components, g_strdup(QQ_GROUP_KEY_EXTERNAL_ID),
+ 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_printf("%d", group->ext_id));
- 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_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_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));
+ 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));
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_status =
+ group->my_role =
qq_string_to_dec_value
(NULL ==
g_hash_table_lookup(data,
- 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);
+ 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);
qd->groups = g_list_append(qd->groups, group);
@@ -184,48 +184,54 @@ 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_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 && group->my_role != QQ_ROOM_ROLE_NO) {
+ add_room_to_blist(gc, group);
+ return;
}
+
+ 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 9dbed22a6a1c7c44af8faacaece208c705c2491b
+++ libpurple/protocols/qq/group_internal.h 07c09e08f1a14b607fcbd926aad0a5a0f5900a0f
@@ -28,18 +28,18 @@
#include <glib.h>
#include "group.h"
-#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"
+#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"
-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 792fdd633fd0b395d83701e185a7d007c26c76bd
+++ libpurple/protocols/qq/group_join.c b67c1322991d3e6f1861628109c608deb68af6cf
@@ -42,10 +42,11 @@
#include "header_info.h"
#include "packet_parse.h"
#include "qq_network.h"
+#include "qq_process.h"
enum {
- QQ_GROUP_JOIN_OK = 0x01,
- QQ_GROUP_JOIN_NEED_AUTH = 0x02,
+ QQ_ROOM_JOIN_OK = 0x01,
+ QQ_ROOM_JOIN_NEED_AUTH = 0x02,
};
static void _qq_group_exit_with_gc_and_id(gc_and_uid *g)
@@ -68,20 +69,20 @@ void qq_send_cmd_group_join_group(Purple
{
g_return_if_fail(group != NULL);
- if (group->my_status == QQ_GROUP_MEMBER_STATUS_NOT_MEMBER) {
- group->my_status = QQ_GROUP_MEMBER_STATUS_APPLYING;
+ if (group->my_role == QQ_ROOM_ROLE_NO) {
+ group->my_role = QQ_ROOM_ROLE_REQUESTING;
qq_group_refresh(gc, group);
}
switch (group->auth_type) {
- case QQ_GROUP_AUTH_TYPE_NO_AUTH:
- case QQ_GROUP_AUTH_TYPE_NEED_AUTH:
+ case QQ_ROOM_AUTH_TYPE_NO_AUTH:
+ case QQ_ROOM_AUTH_TYPE_NEED_AUTH:
break;
- case QQ_GROUP_AUTH_TYPE_NO_ADD:
- purple_notify_warning(gc, NULL, _("This group does not allow others to join"), NULL);
+ case QQ_ROOM_AUTH_TYPE_NO_ADD:
+ purple_notify_warning(gc, NULL, _("The Qun does not allow others to join"), NULL);
return;
default:
- purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Unknown group auth type: %d\n", group->auth_type);
+ purple_debug_error("QQ", "Unknown room auth type: %d\n", group->auth_type);
break;
}
@@ -99,10 +100,10 @@ static void _qq_group_join_auth_with_gc_
group = qq_room_search_id(gc, id);
if (group == NULL) {
- purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Can not find qq_group by internal_id: %d\n", id);
+ 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_GROUP_AUTH_REQUEST_APPLY, 0, reason_utf8);
+ qq_send_cmd_group_auth(gc, group, QQ_ROOM_AUTH_REQUEST_APPLY, 0, reason_utf8);
}
}
@@ -112,10 +113,9 @@ static void _qq_group_join_auth(PurpleCo
gc_and_uid *g;
g_return_if_fail(group != NULL);
- purple_debug(PURPLE_DEBUG_INFO, "QQ",
- "Group (internal id: %d) needs authentication\n", group->id);
+ purple_debug_info("QQ", "Group (internal id: %d) needs authentication\n", group->id);
- msg = g_strdup_printf("Group \"%s\" needs authentication\n", group->group_name_utf8);
+ msg = g_strdup_printf("Group \"%s\" needs authentication\n", group->title_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->group_name_utf8, NULL,
+ purple_connection_get_account(gc), group->title_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_GROUP_AUTH_REQUEST_APPLY) {
- group->my_status = QQ_GROUP_MEMBER_STATUS_APPLYING;
+ if (opt == QQ_ROOM_AUTH_REQUEST_APPLY) {
+ group->my_role = QQ_ROOM_ROLE_REQUESTING;
qq_group_refresh(gc, group);
uid = 0;
}
@@ -173,8 +173,7 @@ void qq_process_group_cmd_exit_group(gui
qd = (qq_data *) gc->proto_data;
if (len < 4) {
- purple_debug(PURPLE_DEBUG_ERROR, "QQ",
- "Invalid exit group reply, expect %d bytes, read %d bytes\n", 4, len);
+ purple_debug_error("QQ", "Invalid exit group reply, expect %d bytes, read %d bytes\n", 4, len);
return;
}
@@ -189,7 +188,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 group"), NULL);
+ purple_notify_info(gc, _("QQ Qun Operation"), _("You have successfully left the Qun"), NULL);
}
/* Process the reply to group_auth subcmd */
@@ -203,15 +202,15 @@ void qq_process_group_cmd_join_group_aut
qd = (qq_data *) gc->proto_data;
if (len < 4) {
- purple_debug(PURPLE_DEBUG_ERROR, "QQ",
- "Invalid join group reply, expect %d bytes, read %d bytes\n", 4, len);
+ purple_debug_error("QQ",
+ "Invalid join room 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 Group Auth"),
+ purple_notify_info(gc, _("QQ Qun Auth"),
_("Your authorization request has been accepted by the QQ server"), NULL);
}
@@ -226,11 +225,11 @@ void qq_process_group_cmd_join_group(gui
g_return_if_fail(data != NULL && len > 0);
if (len < 5) {
- purple_debug(PURPLE_DEBUG_ERROR, "QQ",
+ 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);
@@ -240,26 +239,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_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;
+ case QQ_ROOM_JOIN_OK:
+ purple_debug_info("QQ", "Succeed joining group \"%s\"\n", group->title_utf8);
+ group->my_role = QQ_ROOM_ROLE_YES;
qq_group_refresh(gc, group);
/* this must be shown before getting online members */
qq_group_conv_show_window(gc, group);
- qq_send_room_cmd_only(gc, QQ_ROOM_CMD_GET_INFO, group->id);
+ qq_room_update(gc, 0, group->id);
break;
- case QQ_GROUP_JOIN_NEED_AUTH:
- purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ case QQ_ROOM_JOIN_NEED_AUTH:
+ purple_debug_info("QQ",
"Fail joining group [%d] %s, needs authentication\n",
- group->ext_id, group->group_name_utf8);
- group->my_status = QQ_GROUP_MEMBER_STATUS_NOT_MEMBER;
+ group->ext_id, group->title_utf8);
+ group->my_role = QQ_ROOM_ROLE_NO;
qq_group_refresh(gc, group);
_qq_group_join_auth(gc, group);
break;
default:
- purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ purple_debug_info("QQ",
"Error joining group [%d] %s, unknown reply: 0x%02x\n",
- group->ext_id, group->group_name_utf8, reply);
+ group->ext_id, group->title_utf8, reply);
}
}
@@ -274,7 +273,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_GROUP_KEY_EXTERNAL_ID);
+ ext_id_ptr = g_hash_table_lookup(data, QQ_ROOM_KEY_EXTERNAL_ID);
g_return_if_fail(ext_id_ptr != NULL);
errno = 0;
ext_id = strtol(ext_id_ptr, NULL, 10);
@@ -301,7 +300,7 @@ void qq_group_exit(PurpleConnection *gc,
g_return_if_fail(data != NULL);
- id_ptr = g_hash_table_lookup(data, QQ_GROUP_KEY_INTERNAL_ID);
+ id_ptr = g_hash_table_lookup(data, QQ_ROOM_KEY_INTERNAL_ID);
id = strtol(id_ptr, NULL, 10);
g_return_if_fail(id > 0);
@@ -312,8 +311,7 @@ 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 0825fbbfaae115b886258169f07d0512140d20cb
+++ libpurple/protocols/qq/group_join.h df3dae6e6bdfd0a3c12aaf50f0c33e8e66c87ac7
@@ -30,15 +30,15 @@ enum {
#include "group.h"
enum {
- QQ_GROUP_AUTH_TYPE_NO_AUTH = 0x01,
- QQ_GROUP_AUTH_TYPE_NEED_AUTH = 0x02,
- QQ_GROUP_AUTH_TYPE_NO_ADD = 0x03
+ QQ_ROOM_AUTH_TYPE_NO_AUTH = 0x01,
+ QQ_ROOM_AUTH_TYPE_NEED_AUTH = 0x02,
+ QQ_ROOM_AUTH_TYPE_NO_ADD = 0x03
};
enum {
- QQ_GROUP_AUTH_REQUEST_APPLY = 0x01,
- QQ_GROUP_AUTH_REQUEST_APPROVE = 0x02,
- QQ_GROUP_AUTH_REQUEST_REJECT = 0x03
+ QQ_ROOM_AUTH_REQUEST_APPLY = 0x01,
+ QQ_ROOM_AUTH_REQUEST_APPROVE = 0x02,
+ QQ_ROOM_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 cfe88c8ff984e466debb1c62c877f54686a56ac7
+++ libpurple/protocols/qq/group_opt.c 98dd986059a93ab53d153d458a1f9185e335ab2d
@@ -38,6 +38,7 @@
#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,
@@ -67,7 +68,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++)
@@ -88,7 +89,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_GROUP_AUTH_REQUEST_REJECT, g->member, msg_utf8);
+ qq_send_cmd_group_auth(g->gc, group, QQ_ROOM_AUTH_REQUEST_REJECT, g->member, msg_utf8);
g_free(g);
}
@@ -111,11 +112,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(_("Enter your reason:"));
+ msg2 = g_strdup(_("Message:"));
nombre = uid_to_purple_name(g->member);
purple_request_input(g->gc, /* title */ NULL, msg1, msg2,
- _("Sorry, you are not my type..."), /* multiline */ TRUE, /* masked */ FALSE,
+ _("Sorry, you are not my style..."), /* multiline */ TRUE, /* masked */ FALSE,
/* hint */ NULL,
_("Send"), G_CALLBACK(_qq_group_reject_application_real),
_("Cancel"), G_CALLBACK(_qq_group_do_nothing_with_struct),
@@ -133,7 +134,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_GROUP_AUTH_REQUEST_APPROVE, g->member, "");
+ qq_send_cmd_group_auth(g->gc, group, QQ_ROOM_AUTH_REQUEST_APPROVE, g->member, "");
qq_group_find_or_add_member(g->gc, group, g->member);
g_free(g);
}
@@ -189,9 +190,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_GROUP_MEMBER_DEL, del_members);
+ _qq_group_member_opt(gc, group, QQ_ROOM_MEMBER_DEL, del_members);
if (add > 0)
- _qq_group_member_opt(gc, group, QQ_GROUP_MEMBER_ADD, add_members);
+ _qq_group_member_opt(gc, group, QQ_ROOM_MEMBER_ADD, add_members);
}
void qq_group_process_modify_members_reply(guint8 *data, gint len, PurpleConnection *gc)
@@ -209,9 +210,10 @@ void qq_group_process_modify_members_rep
group = qq_room_search_id(gc, id);
g_return_if_fail(group != NULL);
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "Succeed in modify members for Qun %d\n", group->ext_id);
+ purple_debug_info("QQ", "Succeed in modify members for room %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)
@@ -223,8 +225,8 @@ void qq_room_change_info(PurpleConnectio
g_return_if_fail(group != NULL);
- 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);
+ 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);
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);
@@ -237,7 +239,7 @@ void qq_room_change_info(PurpleConnectio
/* 007-008 */
bytes += qq_put16(data + bytes, 0x0000);
/* 009-010 */
- bytes += qq_put16(data + bytes, group->group_category);
+ bytes += qq_put16(data + bytes, group->category);
bytes += qq_put8(data + bytes, strlen(group_name));
bytes += qq_putdata(data + bytes, (guint8 *) group_name, strlen(group_name));
@@ -251,7 +253,7 @@ void qq_room_change_info(PurpleConnectio
bytes += qq_putdata(data + bytes, (guint8 *) group_desc, strlen(group_desc));
if (bytes > data_len) {
- purple_debug(PURPLE_DEBUG_ERROR, "QQ",
+ purple_debug_error("QQ",
"Overflow in qq_room_change_info, max %d bytes, now %d bytes\n",
data_len, bytes);
return;
@@ -274,7 +276,7 @@ void qq_group_process_modify_info_reply(
group = qq_room_search_id(gc, id);
g_return_if_fail(group != NULL);
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "Succeed in modify info for Qun %d\n", group->ext_id);
+ 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);
@@ -297,9 +299,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_GROUP_TYPE_PERMANENT);
+ bytes += qq_put8(data + bytes, QQ_ROOM_TYPE_PERMANENT);
/* 002 */
- bytes += qq_put8(data + bytes, QQ_GROUP_AUTH_TYPE_NEED_AUTH);
+ bytes += qq_put8(data + bytes, QQ_ROOM_AUTH_TYPE_NEED_AUTH);
/* 003-004 */
bytes += qq_put16(data + bytes, 0x0000);
/* 005-006 */
@@ -313,7 +315,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(PURPLE_DEBUG_ERROR, "QQ",
+ purple_debug_error("QQ",
"Overflow in qq_room_create, max %d bytes, now %d bytes\n",
data_len, bytes);
return;
@@ -352,14 +354,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_status = QQ_GROUP_MEMBER_STATUS_IS_ADMIN;
+ group->my_role = QQ_ROOM_ROLE_ADMIN;
group->creator_uid = qd->uid;
qq_group_refresh(gc, group);
qq_send_room_cmd_only(gc, QQ_ROOM_CMD_ACTIVATE, id);
- qq_send_room_cmd_only(gc, QQ_ROOM_CMD_GET_INFO, id);
+ qq_room_update(gc, 0, group->id);
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "Succeed in create Qun, external ID %d\n", group->ext_id);
+ 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;
@@ -368,7 +370,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 Qun details now?"),
+ ("Would you like to set up the detail information now?"),
1,
purple_connection_get_account(gc), NULL, NULL,
g, 2,
@@ -391,7 +393,7 @@ void qq_group_process_activate_group_rep
group = qq_room_search_id(gc, id);
g_return_if_fail(group != NULL);
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "Succeed in activate Qun %d\n", group->ext_id);
+ purple_debug_info("QQ", "Succeed in activate Qun %d\n", group->ext_id);
}
void qq_group_manage_group(PurpleConnection *gc, GHashTable *data)
@@ -402,7 +404,7 @@ void qq_group_manage_group(PurpleConnect
g_return_if_fail(data != NULL);
- id_ptr = g_hash_table_lookup(data, QQ_GROUP_KEY_INTERNAL_ID);
+ id_ptr = g_hash_table_lookup(data, QQ_ROOM_KEY_INTERNAL_ID);
id = strtol(id_ptr, NULL, 10);
g_return_if_fail(id > 0);
============================================================
--- libpurple/protocols/qq/group_opt.h c4a0487f1ba87e92a56d484b63a0ccdbaeda83ef
+++ libpurple/protocols/qq/group_opt.h 59af741aa7f62b30f0697d841497bb2b6798c546
@@ -38,13 +38,13 @@ enum {
} group_member_opt;
enum {
- QQ_GROUP_TYPE_PERMANENT = 0x01,
- QQ_GROUP_TYPE_TEMPORARY
+ QQ_ROOM_TYPE_PERMANENT = 0x01,
+ QQ_ROOM_TYPE_TEMPORARY
};
enum {
- QQ_GROUP_MEMBER_ADD = 0x01,
- QQ_GROUP_MEMBER_DEL
+ QQ_ROOM_MEMBER_ADD = 0x01,
+ QQ_ROOM_MEMBER_DEL
};
void qq_group_modify_members(PurpleConnection *gc, qq_group *group, guint32 *new_members);
============================================================
--- libpurple/protocols/qq/group_search.c fc5206710a5f2e134a0a97e1d59ae1a4f4be9a46
+++ libpurple/protocols/qq/group_search.c 07127dd246f2fbd0032f25f9b06f5abe91ec17f7
@@ -38,8 +38,8 @@ enum {
#include "qq_network.h"
enum {
- QQ_GROUP_SEARCH_TYPE_BY_ID = 0x01,
- QQ_GROUP_SEARCH_TYPE_DEMO = 0x02
+ QQ_ROOM_SEARCH_TYPE_BY_ID = 0x01,
+ QQ_ROOM_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_GROUP_SEARCH_TYPE_DEMO : QQ_GROUP_SEARCH_TYPE_BY_ID;
+ type = (ext_id == 0x00000000) ? QQ_ROOM_SEARCH_TYPE_DEMO : QQ_ROOM_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->group_name_utf8, NULL);
+ room = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_ROOM, group->title_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->group_desc_utf8);
+ purple_roomlist_room_add_field(qd->roomlist, room, 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->group_category);
+ g_snprintf(field, sizeof(field), "%d", group->category);
purple_roomlist_room_add_field(qd->roomlist, room, field);
- purple_roomlist_room_add_field(qd->roomlist, room, group->group_name_utf8);
+ purple_roomlist_room_add_field(qd->roomlist, room, group->title_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.group_category), data + bytes);
- bytes += convert_as_pascal_string(data + bytes, &(group.group_name_utf8), QQ_CHARSET_DEFAULT);
+ bytes += qq_get32(&(group.category), data + bytes);
+ bytes += convert_as_pascal_string(data + bytes, &(group.title_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.group_desc_utf8), QQ_CHARSET_DEFAULT);
+ bytes += convert_as_pascal_string(data + bytes, &(group.desc_utf8), QQ_CHARSET_DEFAULT);
/* end of one qq_group */
if(bytes != len) {
- purple_debug(PURPLE_DEBUG_ERROR, "QQ",
+ 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.group_name_utf8);
+ group.id, group.ext_id, group.title_utf8);
qq_send_cmd_group_join_group(gc, &group);
} else {
_qq_setup_roomlist(qd, &group);
============================================================
--- libpurple/protocols/qq/header_info.c 3b81718aecc45aa7425e5da435eeab9b0096a99b
+++ libpurple/protocols/qq/header_info.c f6c8d5882aa98e81f4f08d75d9e6f09d1e244bf9
@@ -122,7 +122,7 @@ const gchar *qq_get_ver_desc(gint source
case QQ_SERVER_0100:
return "QQ Server 0100";
default:
- return "Unknown";
+ return "Unknown Version";
}
}
@@ -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_ONLINE_STATUS:
- return "QQ_CMD_CHANGE_ONLINE_STATUS";
+ case QQ_CMD_CHANGE_STATUS:
+ return "QQ_CMD_CHANGE_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_RECV_MSG_BUDDY_CHANGE_STATUS:
- return "QQ_CMD_RECV_MSG_BUDDY_CHANGE_STATUS";
+ case QQ_CMD_BUDDY_CHANGE_STATUS:
+ return "QQ_CMD_BUDDY_CHANGE_STATUS";
default:
- return "Unknown";
+ return "Unknown CMD";
}
}
@@ -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_MEMBER_INFO:
- return "QQ_ROOM_CMD_GET_MEMBER_INFO";
+ case QQ_ROOM_CMD_GET_BUDDIES:
+ return "QQ_ROOM_CMD_GET_BUDDIES";
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 QQ Room Command";
+ return "Unknown Room Command";
}
}
============================================================
--- libpurple/protocols/qq/header_info.h b6c6b91c69672f9605fd6dbed3c27a930319b774
+++ libpurple/protocols/qq/header_info.h 1fb677b46ef167f921799cfd63a850c36e429cc8
@@ -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_ONLINE_STATUS = 0x000d, /* change my online status */
+ QQ_CMD_CHANGE_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_RECV_MSG_BUDDY_CHANGE_STATUS = 0x0081, /* buddy change status */
+ QQ_CMD_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_MEMBER_INFO = 0x0c,
+ QQ_ROOM_CMD_GET_BUDDIES = 0x0c,
QQ_ROOM_CMD_CHANGE_CARD = 0x0E,
QQ_ROOM_CMD_GET_REALNAMES = 0x0F,
============================================================
--- libpurple/protocols/qq/im.c 90e409aba8c08748d11f8702874197fa1f8c6a3d
+++ libpurple/protocols/qq/im.c 5d3ec6ec0446db7b0d31d8c2613a1bcd42820909
@@ -209,21 +209,17 @@ 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)
@@ -240,13 +236,61 @@ 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(PURPLE_DEBUG_ERROR, "QQ", "Expect 28 bytes, read %d bytes\n", bytes);
+ 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)
{
@@ -266,7 +310,7 @@ static void _qq_process_recv_normal_im_t
/* now it is QQ_NORMAL_IM_TEXT */
/*
if (*cursor >= (data + len - 1)) {
- purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Received normal IM text is empty\n");
+ purple_debug_warning("QQ", "Received normal IM text is empty\n");
return;
} else
*/
@@ -313,9 +357,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);
@@ -350,19 +394,18 @@ static void _qq_process_recv_normal_im(g
bytes = _qq_normal_im_common_read(data, len, common);
if (bytes < 0) {
- purple_debug (PURPLE_DEBUG_ERROR, "QQ",
- "Fail read the common part of normal IM\n");
+ 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 (PURPLE_DEBUG_INFO, "QQ",
+ 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(PURPLE_DEBUG_WARNING, "QQ", "Received normal IM text is empty\n");
+ purple_debug_warning("QQ", "Received normal IM text is empty\n");
return;
}
_qq_process_recv_normal_im_text(data + bytes, len - bytes, common, gc);
@@ -382,16 +425,50 @@ 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 (PURPLE_DEBUG_WARNING, "QQ",
+ purple_debug_warning("QQ",
"Normal IM, unprocessed type [0x%04x], len %d\n",
common->normal_im_type, im_unprocessed->length);
- qq_show_packet ("QQ unk-im", im_unprocessed->unknown, im_unprocessed->length);
+ qq_show_packet ("QQ", im_unprocessed->unknown, im_unprocessed->length);
return;
}
}
@@ -412,7 +489,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(PURPLE_DEBUG_WARNING, "QQ", "We are kicked out by QQ server\n");
+ 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);
}
@@ -475,7 +552,7 @@ void qq_send_packet_im(PurpleConnection
g_datalist_clear(&attribs);
}
- purple_debug(PURPLE_DEBUG_INFO, "QQ_MESG", "send mesg: %s\n", msg);
+ 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);
@@ -526,9 +603,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(qd, QQ_CMD_SEND_IM, raw_data, bytes);
+ qq_send_cmd(gc, QQ_CMD_SEND_IM, raw_data, bytes);
else
- purple_debug(PURPLE_DEBUG_ERROR, "QQ",
+ purple_debug_error("QQ",
"Fail creating send_im packet, expect %d bytes, build %d bytes\n", raw_len, bytes);
if (font_color)
@@ -549,10 +626,10 @@ void qq_process_send_im_reply(guint8 *da
qd = gc->proto_data;
if (data[0] != QQ_SEND_IM_REPLY_OK) {
- purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Send IM fail\n");
+ purple_debug_warning("QQ", "Send IM fail\n");
purple_notify_error(gc, _("Error"), _("Failed to send IM."), NULL);
} else {
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "IM ACK OK\n");
+ purple_debug_info("QQ", "IM ACK OK\n");
}
}
@@ -569,16 +646,17 @@ 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(PURPLE_DEBUG_ERROR, "QQ", "IM is too short\n");
+ purple_debug_error("QQ", "MSG is too short\n");
return;
} else {
- _qq_send_packet_recv_im_ack(gc, seq, data);
+ /* 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);
}
/* check len first */
if (data_len < 20) { /* length of im_header */
- purple_debug(PURPLE_DEBUG_ERROR, "QQ",
- "Fail read recv IM header, len should longer than 20 bytes, read %d bytes\n", data_len);
+ purple_debug_error("QQ", "Invald MSG header, len %d < 20\n", data_len);
return;
}
@@ -594,77 +672,71 @@ void qq_process_recv_im(guint8 *data, gi
/* im_header prepared */
if (im_header->receiver_uid != qd->uid) { /* should not happen */
- purple_debug(PURPLE_DEBUG_ERROR, "QQ", "IM to [%d], NOT me\n", im_header->receiver_uid);
+ purple_debug_error("QQ", "MSG to [%d], NOT me\n", im_header->receiver_uid);
return;
}
/* check bytes */
if (bytes >= data_len - 1) {
- purple_debug (PURPLE_DEBUG_WARNING, "QQ", "Received IM is empty\n");
+ purple_debug_warning("QQ", "Empty MSG\n");
return;
}
switch (im_header->im_type) {
- 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 */
+ case QQ_RECV_IM_NEWS:
+ _qq_process_recv_news(data + bytes, data_len - bytes, gc);
break;
+ case QQ_RECV_IM_FROM_BUDDY_2006:
+ case QQ_RECV_IM_FROM_UNKNOWN_2006:
case QQ_RECV_IM_TO_UNKNOWN:
- purple_debug(PURPLE_DEBUG_INFO, "QQ",
- "IM from buddy [%d], I am a stranger to him/her\n", im_header->sender_uid);
+ case QQ_RECV_IM_TO_BUDDY:
+ purple_debug_info("QQ", "MSG from buddy [%d]\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(PURPLE_DEBUG_INFO, "QQ", "IM from group, internal_id [%d]\n", im_header->sender_uid);
+ purple_debug_info("QQ", "MSG from room [%d]\n", im_header->sender_uid);
/* sender_uid is in fact id */
- qq_process_recv_group_im(data + bytes, data_len - bytes, im_header->sender_uid, gc, im_header->im_type);
+ qq_process_room_msg_normal(data + bytes, data_len - bytes, im_header->sender_uid, gc, im_header->im_type);
break;
case QQ_RECV_IM_ADD_TO_QUN:
- purple_debug(PURPLE_DEBUG_INFO, "QQ",
- "IM from group, added by group internal_id [%d]\n", im_header->sender_uid);
+ purple_debug_info("QQ", "Notice from [%d], Added\n", im_header->sender_uid);
/* sender_uid is group id
* we need this to create a dummy group and add to blist */
- qq_process_recv_group_im_been_added(data + bytes, data_len - bytes, im_header->sender_uid, gc);
+ qq_process_room_msg_been_added(data + bytes, data_len - bytes, im_header->sender_uid, gc);
break;
case QQ_RECV_IM_DEL_FROM_QUN:
- purple_debug(PURPLE_DEBUG_INFO, "QQ",
- "IM from group, removed by group internal_ID [%d]\n", im_header->sender_uid);
+ purple_debug_info("QQ", "Notice from room [%d], Removed\n", im_header->sender_uid);
/* sender_uid is group id */
- qq_process_recv_group_im_been_removed(data + bytes, data_len - bytes, im_header->sender_uid, gc);
+ qq_process_room_msg_been_removed(data + bytes, data_len - bytes, im_header->sender_uid, gc);
break;
case QQ_RECV_IM_APPLY_ADD_TO_QUN:
- purple_debug(PURPLE_DEBUG_INFO, "QQ",
- "IM from group, apply to join group internal_ID [%d]\n", im_header->sender_uid);
+ purple_debug_info("QQ", "Notice from room [%d], Joined\n", im_header->sender_uid);
/* sender_uid is group id */
- qq_process_recv_group_im_apply_join(data + bytes, data_len - bytes, im_header->sender_uid, gc);
+ qq_process_room_msg_apply_join(data + bytes, data_len - bytes, im_header->sender_uid, gc);
break;
case QQ_RECV_IM_APPROVE_APPLY_ADD_TO_QUN:
- purple_debug(PURPLE_DEBUG_INFO, "QQ",
- "IM for group system info, approved by group internal_id [%d]\n",
+ purple_debug_info("QQ", "Notice from room [%d], Confirm add in\n",
im_header->sender_uid);
/* sender_uid is group id */
- qq_process_recv_group_im_been_approved(data + bytes, data_len - bytes, im_header->sender_uid, gc);
+ qq_process_room_msg_been_approved(data + bytes, data_len - bytes, im_header->sender_uid, gc);
break;
case QQ_RECV_IM_REJCT_APPLY_ADD_TO_QUN:
- purple_debug(PURPLE_DEBUG_INFO, "QQ",
- "IM for group system info, rejected by group internal_id [%d]\n",
+ purple_debug_info("QQ", "Notice from room [%d], Refuse add in\n",
im_header->sender_uid);
/* sender_uid is group id */
- qq_process_recv_group_im_been_rejected(data + bytes, data_len - bytes, im_header->sender_uid, gc);
+ qq_process_room_msg_been_rejected(data + bytes, data_len - bytes, im_header->sender_uid, gc);
break;
case QQ_RECV_IM_SYS_NOTIFICATION:
- purple_debug(PURPLE_DEBUG_INFO, "QQ",
- "IM from [%d], should be a system administrator\n", im_header->sender_uid);
+ purple_debug_info("QQ", "Admin notice from [%d]\n", im_header->sender_uid);
_qq_process_recv_sys_im(data + bytes, data_len - bytes, gc);
break;
default:
- 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));
+ 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);
}
}
============================================================
--- libpurple/protocols/qq/im.h 9bb66bca43da19dfdcd526333228f8dd7648de75
+++ libpurple/protocols/qq/im.h 0dbb0b4261a59a829f78c7b75a43c416ee868329
@@ -41,6 +41,7 @@ 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,
@@ -50,7 +51,9 @@ 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_SYS_NOTIFICATION = 0x0030,
+ QQ_RECV_IM_FROM_BUDDY_2006 = 0x0084,
+ QQ_RECV_IM_FROM_UNKNOWN_2006 = 0x0085,
};
guint8 *qq_get_send_im_tail(const gchar *font_color,
============================================================
--- libpurple/protocols/qq/packet_parse.c 803b01df2d219f62afc4b1813faca0f67c82e5ae
+++ libpurple/protocols/qq/packet_parse.c 21732e9a4c9b39b77a94bd80073695ba1a12c103
@@ -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(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);
+ 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);
#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(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);
+ 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);
#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(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);
+ 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);
#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(PURPLE_DEBUG_INFO, "QQ", "[DBG][getdata] buf %p\n", (void *)buf);
+ 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(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);
+ 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);
#endif
dw_dest = g_ntohl(dw_dest);
#ifdef PARSER_DEBUG
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "[DBG][getime] dw_dest after 0x%08x\n", dw_dest);
+ 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(PURPLE_DEBUG_INFO, "QQ", "[DBG][put8] buf %p\n", (void *)buf);
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "[DBG][put8] b 0x%02x\n", b);
+ purple_debug_info("QQ", "[DBG][put8] buf %p\n", (void *)buf);
+ 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(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);
+ 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);
#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(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);
+ 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);
#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(PURPLE_DEBUG_INFO, "QQ", "[DBG][putdata] buf %p\n", (void *)buf);
+ purple_debug_info("QQ", "[DBG][putdata] buf %p\n", (void *)buf);
#endif
return datalen;
}
============================================================
--- libpurple/protocols/qq/qq.c c1ad87252bd96d8470a6d1768d68e67eb034416a
+++ libpurple/protocols/qq/qq.c 5a34bedb1748ea86e3abef9336083ad12ffa53e7
@@ -24,10 +24,6 @@
#include "internal.h"
-#ifdef _WIN32
-#define random rand
-#endif
-
#include "accountopt.h"
#include "debug.h"
#include "notify.h"
@@ -62,79 +58,72 @@
#define OPENQ_AUTHOR "Puzzlebird"
#define OPENQ_WEBSITE "http://openq.sourceforge.net"
-#define QQ_TCP_PORT 8000
-#define QQ_UDP_PORT 8000
+static GList *server_list_build(gchar select)
+{
+ GList *list = NULL;
-static void server_list_create(PurpleAccount *account) {
+ 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)
+{
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;
- 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;
+ gpi = purple_proxy_get_setup(account);
- 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);
+ qd->use_tcp = TRUE;
+ if (purple_proxy_info_get_type(gpi) == PURPLE_PROXY_UDP) {
+ qd->use_tcp = FALSE;
}
- if (qd->user_server != NULL) {
- qd->servers = g_list_append(qd->servers, qd->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));
return;
}
+
if (qd->use_tcp) {
- 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");
+ qd->servers = server_list_build('T');
return;
}
-
- 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");
+
+ qd->servers = server_list_build('U');
}
-static void server_list_remove_all(qq_data *qd) {
+static void server_list_remove_all(qq_data *qd)
+{
g_return_if_fail(qd != NULL);
- 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");
+ purple_debug_info("QQ", "free server list\n");
g_list_free(qd->servers);
+ qd->curr_server = NULL;
}
static void qq_login(PurpleAccount *account)
@@ -151,6 +140,7 @@ 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;
@@ -165,10 +155,31 @@ static void qq_login(PurpleAccount *acco
}
server_list_create(account);
- purple_debug(PURPLE_DEBUG_INFO, "QQ",
- "Server list has %d\n", g_list_length(qd->servers));
+ purple_debug_info("QQ", "Server list has %d\n", g_list_length(qd->servers));
- qq_connect(account);
+ 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);
}
/* clean up the given QQ connection and free all resources */
@@ -179,12 +190,20 @@ static void qq_close(PurpleConnection *g
g_return_if_fail(gc != NULL && gc->proto_data);
qd = gc->proto_data;
- qq_disconnect(gc);
+ 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 = 0;
+ }
+
+ qq_disconnect(gc);
server_list_remove_all(qd);
-
+
g_free(qd);
-
gc->proto_data = NULL;
}
@@ -212,7 +231,7 @@ static gchar *_qq_status_text(PurpleBudd
g_string_append(status, _("Offline"));
break;
case QQ_BUDDY_ONLINE_NORMAL:
- return NULL;
+ g_string_append(status, _("Online"));
break;
/* TODO What does this status mean? Labelling it as offline... */
case QQ_BUDDY_ONLINE_OFFLINE:
@@ -303,8 +322,8 @@ static void _qq_tooltip_text(PurpleBuddy
g_string_append( str, _(" Video") );
}
- if (q_bud->ext_flag & QQ_EXT_FLAG_SPACE) {
- g_string_append( str, _(" Space") );
+ if (q_bud->ext_flag & QQ_EXT_FLAG_ZONE) {
+ g_string_append( str, _(" Zone") );
}
purple_notify_user_info_add_pair(user_info, _("Flag"), str->str);
@@ -329,7 +348,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;
}
@@ -374,11 +393,11 @@ static GList *_qq_away_states(PurpleAcco
}
/* initiate QQ away with proper change_status packet */
-static void _qq_set_away(PurpleAccount *account, PurpleStatus *status)
+static void _qq_change_status(PurpleAccount *account, PurpleStatus *status)
{
PurpleConnection *gc = purple_account_get_connection(account);
- qq_send_packet_change_status(gc);
+ qq_request_change_status(gc, 0);
}
/* IMPORTANT: PurpleConvImFlags -> PurpleMessageFlags */
@@ -444,7 +463,7 @@ static void _qq_get_info(PurpleConnectio
uid = purple_name_to_uid(who);
if (uid <= 0) {
- purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Not valid QQid: %s\n", who);
+ purple_debug_error("QQ", "Not valid QQid: %s\n", who);
purple_notify_error(gc, NULL, _("Invalid name"), NULL);
return;
}
@@ -516,9 +535,8 @@ static void _qq_menu_show_login_info(Pur
g_string_append(info, "<hr>\n");
- g_string_append_printf(info, _("<b>Server</b>: %s: %d<br>\n"), qd->server_name, qd->real_port);
+ g_string_append_printf(info, _("<b>Server</b>: %s<br>\n"), qd->curr_server);
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");
@@ -633,7 +651,7 @@ static GList *_qq_chat_menu(PurpleBlistN
PurpleMenuAction *act;
m = NULL;
- act = purple_menu_action_new(_("Leave this QQ Qun"), PURPLE_CALLBACK(_qq_menu_unsubscribe_group), NULL, NULL);
+ act = purple_menu_action_new(_("Leave the QQ Qun"), PURPLE_CALLBACK(_qq_menu_unsubscribe_group), NULL, NULL);
m = g_list_append(m, act);
/* TODO: enable this
@@ -708,7 +726,7 @@ static PurplePluginProtocolInfo prpl_inf
NULL, /* set_info */
NULL, /* send_typing */
_qq_get_info, /* get_info */
- _qq_set_away, /* set_away */
+ _qq_change_status, /* change status */
NULL, /* set_idle */
NULL, /* change_passwd */
qq_add_buddy, /* add_buddy */
@@ -800,19 +818,52 @@ 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(_("Connect using TCP"), "use_tcp", TRUE);
+ option = purple_account_option_bool_new(_("Show server notice"), "show_notice", TRUE);
prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- option = purple_account_option_int_new(_("resend interval(s)"), "resend_interval", 10);
+ option = purple_account_option_bool_new(_("Show server news"), "show_news", TRUE);
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);
@@ -823,6 +874,7 @@ 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 17c7a1179cc82fcae2d3231ddf7883b78b7a9804
+++ libpurple/protocols/qq/qq.h b59cc95c61437ae001fd4611c1bbca9f33edca83
@@ -36,6 +36,11 @@
#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;
@@ -63,45 +68,46 @@ struct _qq_buddy {
guint16 timeRemainder;
time_t signon;
time_t idle;
- time_t last_refresh;
+ time_t last_update;
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;
- /* common network resource */
- GList *servers;
- gchar *user_server;
- gint user_port;
+ GSList *openconns;
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*/
- gchar *server_name;
- gboolean is_redirect;
- gchar *real_hostname; /* from real connction */
- guint16 real_port;
- guint reconnect_timeout;
- gint reconnect_times;
+ struct in_addr redirect_ip;
+ guint16 redirect_port;
+ guint check_watcher;
+ guint connect_watcher;
+ gint connect_retry;
- 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_timeout;
+ guint network_watcher;
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;
@@ -112,7 +118,8 @@ struct _qq_data {
guint16 send_seq; /* send sequence number */
guint8 login_mode; /* online of invisible */
- gboolean logged_in; /* used by qq-add_buddy */
+ gboolean is_login; /* used by qq-add_buddy */
+ gboolean is_finish_update;
PurpleXfer *xfer; /* file transfer handler */
@@ -143,6 +150,9 @@ 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 529b343ed51bb7740d680c11e73b2f473bca9d48
+++ libpurple/protocols/qq/qq_base.c 6ca17e28fe0a03df4a08018804b3c0c2a51f0b11
@@ -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(PURPLE_DEBUG_INFO, "QQ", "Got session_key\n");
+ 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(PURPLE_DEBUG_WARNING, "QQ",
+ 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,39 +237,19 @@ 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(PURPLE_DEBUG_ERROR, "QQ",
+ 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 */
- 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;
-
+ qd->redirect_ip.s_addr = lrrp.new_server_ip.s_addr;
+ qd->redirect_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)
{
@@ -281,9 +261,9 @@ void qq_send_packet_token(PurpleConnecti
qd = (qq_data *) gc->proto_data;
bytes += qq_put8(buf + bytes, 0);
-
+
qd->send_seq++;
- qq_send_data(qd, QQ_CMD_TOKEN, qd->send_seq, TRUE, buf, bytes);
+ qq_send_cmd_encrypted(gc, QQ_CMD_TOKEN, qd->send_seq, buf, bytes, TRUE);
}
/* send login packet to QQ server */
@@ -312,14 +292,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 */
@@ -349,14 +329,15 @@ void qq_send_packet_login(PurpleConnecti
bytes += qq_putdata(buf + bytes, encrypted_data, encrypted_len);
qd->send_seq++;
- qq_send_data(qd, QQ_CMD_LOGIN, qd->send_seq, TRUE, buf, bytes);
+ qq_send_cmd_encrypted(gc, QQ_CMD_LOGIN, qd->send_seq, buf, bytes, TRUE);
}
-guint8 qq_process_token_reply(PurpleConnection *gc, gchar *error_msg, guint8 *buf, gint buf_len)
+guint8 qq_process_token_reply(PurpleConnection *gc, 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);
@@ -364,30 +345,37 @@ guint8 qq_process_token_reply(PurpleConn
qd = (qq_data *) gc->proto_data;
ret = buf[0];
-
+
if (ret != QQ_TOKEN_REPLY_OK) {
- purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Unknown request login token reply code : %d\n", buf[0]);
+ purple_debug_error("QQ", "Failed to request token: %d\n", buf[0]);
qq_hex_dump(PURPLE_DEBUG_WARNING, "QQ",
buf, buf_len,
">>> [default] decrypt and dump");
error_msg = try_dump_as_gbk(buf, buf_len);
+ if (error_msg == NULL) {
+ error_msg = g_strdup_printf( _("Invalid token reply code, 0x%02X"), ret);
+ }
+ 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(PURPLE_DEBUG_INFO, "QQ",
+ 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);
@@ -402,48 +390,85 @@ void qq_send_packet_logout(PurpleConnect
qd = (qq_data *) gc->proto_data;
for (i = 0; i < 4; i++)
- qq_send_cmd_detail(qd, QQ_CMD_LOGOUT, 0xffff, FALSE, qd->password_twice_md5, QQ_KEY_LENGTH);
+ qq_send_cmd(gc, QQ_CMD_LOGOUT, qd->password_twice_md5, QQ_KEY_LENGTH);
- qd->logged_in = FALSE; /* update login status AFTER sending logout packets */
+ qd->is_login = FALSE; /* update login status AFTER sending logout packets */
}
/* process the login reply packet */
-guint8 qq_process_login_reply(guint8 *data, gint data_len, PurpleConnection *gc)
+guint8 qq_process_login_reply( PurpleConnection *gc, guint8 *data, gint data_len)
{
qq_data *qd;
- gchar* error_msg;
+ guint8 ret = data[0];
+ gchar *server_reply, *server_reply_utf8;
+ 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 (data[0]) {
+ switch (ret) {
case QQ_LOGIN_REPLY_OK:
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "Login reply is OK\n");
+ purple_debug_info("QQ", "Login OK\n");
return process_login_ok(gc, data, data_len);
case QQ_LOGIN_REPLY_REDIRECT:
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "Login reply is redirect\n");
+ purple_debug_info("QQ", "Redirect new server\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:
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "Login reply is error password\n");
- return process_login_wrong_pwd(gc, data, data_len);
+ 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;
+
case QQ_LOGIN_REPLY_NEED_REACTIVE:
- case QQ_LOGIN_REPLY_REDIRECT_EX:
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "Login reply is not actived or redirect extend\n");
- default:
- break;
- }
+ server_reply = g_strndup((gchar *)data + 1, data_len - 1);
+ server_reply_utf8 = qq_to_utf8(server_reply, QQ_CHARSET_DEFAULT);
- purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Unknown reply code: 0x%02X\n", data[0]);
+ 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]);
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) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_msg);
- g_free(error_msg);
+ 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;
}
- return QQ_LOGIN_REPLY_ERR_MISC;
+
+ purple_connection_error_reason(gc,
+ PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_msg);
+ g_free(error_msg);
+ return ret;
}
/* send keep-alive packet to QQ server (it is a heart-beat) */
@@ -460,11 +485,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(qd, QQ_CMD_KEEP_ALIVE, raw_data, 4);
+ qq_send_cmd(gc, 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;
@@ -478,7 +503,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) {
@@ -488,9 +513,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(PURPLE_DEBUG_INFO, "QQ", "keep alive, %s:%d\n",
+ 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 6d6f1ef5450dc8bc5c06af0135bf2e1573835b04
+++ libpurple/protocols/qq/qq_base.h 1be7d89ee372ed31923b785525b7966caa34db3f
@@ -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, gchar *error_msg, guint8 *buf, gint buf_len);
+guint8 qq_process_token_reply(PurpleConnection *gc, guint8 *buf, gint buf_len);
void qq_send_packet_login(PurpleConnection *gc);
-guint8 qq_process_login_reply(guint8 *data, gint data_len, PurpleConnection *gc);
+guint8 qq_process_login_reply( PurpleConnection *gc, guint8 *data, gint data_len);
void qq_send_packet_logout(PurpleConnection *gc);
============================================================
--- libpurple/protocols/qq/qq_network.c 4364dbec36ac54db6ce17b68698173e582d596de
+++ libpurple/protocols/qq/qq_network.c 3853b123926421d8dd7a315c551b2c20c3bcf71c
@@ -26,11 +26,6 @@
#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"
@@ -44,63 +39,100 @@
#include "utils.h"
#include "qq_process.h"
-/* 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
+#define QQ_DEFAULT_PORT 8000
+/* 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(PURPLE_DEBUG_INFO, "QQ", "Server list is NULL\n");
+ 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->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;
+ 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;
}
-
+
count = g_list_length(qd->servers);
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "Server list has %d\n", count);
+ 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 = random() % count;
+ index = rand() % count;
it = g_list_nth(qd->servers, 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);
+ 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);
return FALSE;
}
- 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);
+ purple_debug_info("QQ", "set new server to %s\n", qd->curr_server);
return TRUE;
}
@@ -115,152 +147,208 @@ static gint packet_get_header(guint8 *he
return bytes;
}
-static gboolean reconnect_later_cb(gpointer data)
+static gboolean connect_check(gpointer data)
{
- PurpleConnection *gc;
+ PurpleConnection *gc = (PurpleConnection *) data;
qq_data *qd;
- gc = (PurpleConnection *) data;
g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, FALSE);
qd = (qq_data *) gc->proto_data;
- qd->reconnect_timeout = 0;
+ if (qd->connect_watcher > 0) {
+ purple_timeout_remove(qd->connect_watcher);
+ qd->connect_watcher = 0;
+ }
- qq_connect(gc->account);
- return FALSE; /* timeout callback stops */
+ 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;
}
-static void reconnect_later(PurpleConnection *gc)
+/* 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)
{
+ PurpleConnection *gc = (PurpleConnection *) data;
qq_data *qd;
+ char *server;
+ int port;
+ gchar **segments;
- g_return_if_fail(gc != NULL && gc->proto_data != NULL);
+ g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, FALSE);
qd = (qq_data *) gc->proto_data;
- qd->reconnect_times--;
- if (qd->reconnect_times < 0) {
+ 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) {
if ( set_new_server(qd) != TRUE) {
purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Failed to connect server"));
- return;
+ _("Failed to connect all servers"));
+ return FALSE;
}
+ qd->connect_retry = QQ_CONNECT_MAX;
}
- 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);
+ 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);
- qd->reconnect_timeout = purple_timeout_add(QQ_RECONNECT_INTERVAL,
- reconnect_later_cb, gc);
+ 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 */
}
/* process the incoming packet from qq_pending */
-static void packet_process(PurpleConnection *gc, guint8 *buf, gint buf_len)
+static gboolean packet_process(PurpleConnection *gc, guint8 *buf, gint buf_len)
{
qq_data *qd;
gint bytes, bytes_not_read;
- gboolean prev_login_status;
-
+ gboolean prev_update_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_if_fail(buf != NULL && buf_len > 0);
+ g_return_val_if_fail(buf != NULL && buf_len > 0, TRUE);
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(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
+ 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) */
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(qd, cmd, seq);
+ trans = qq_trans_find_rcved(gc, cmd, seq);
if (trans == NULL) {
/* new server command */
- qq_trans_add_server_cmd(qd, cmd, seq, buf + bytes, bytes_not_read);
- if ( qd->logged_in ) {
+ qq_trans_add_server_cmd(gc, cmd, seq, buf + bytes, bytes_not_read);
+ if ( qd->is_finish_update ) {
qq_proc_cmd_server(gc, cmd, seq, buf + bytes, bytes_not_read);
}
- return;
+ return TRUE;
}
if (qq_trans_is_dup(trans)) {
- purple_debug(PURPLE_DEBUG_WARNING,
- "QQ", "dup [%05d] %s, discard...\n", seq, qq_get_cmd_desc(cmd));
- return;
+ purple_debug_info("QQ", "dup [%05d] %s, discard...\n", seq, qq_get_cmd_desc(cmd));
+ return TRUE;
}
if (qq_trans_is_server(trans)) {
- if ( qd->logged_in ) {
+ if ( qd->is_finish_update ) {
qq_proc_cmd_server(gc, cmd, seq, buf + bytes, bytes_not_read);
}
- return;
+ return TRUE;
}
- /* 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);
+ 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);
#if 1
- 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);
+ 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;
}
-
- /* 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_login_status != qd->logged_in && qd->logged_in == TRUE) {
- /* logged_in, but we have packets before login */
- qq_trans_process_before_login(qd);
+ 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;
}
+ return TRUE;
}
static void tcp_pending(gpointer data, gint source, PurpleInputCondition cond)
{
- PurpleConnection *gc;
+ PurpleConnection *gc = (PurpleConnection *) data;
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,
@@ -268,8 +356,9 @@ static void tcp_pending(gpointer data, g
return;
}
- qd = (qq_data *) gc->proto_data;
-
+ conn = connection_find(qd, source);
+ g_return_if_fail(conn != NULL);
+
/* test code, not using tcp_rxqueue
memset(pkt,0, sizeof(pkt));
buf_len = read(qd->fd, pkt, sizeof(pkt));
@@ -278,8 +367,8 @@ static void tcp_pending(gpointer data, g
}
return;
*/
-
- buf_len = read(qd->fd, buf, sizeof(buf));
+
+ buf_len = read(source, buf, sizeof(buf));
if (buf_len < 0) {
if (errno == EAGAIN)
/* No worries */
@@ -299,93 +388,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(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;
-
+ /* 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;
+
pkt = g_newa(guint8, MAX_PACKET_SIZE);
- while (1) {
- if (qd->tcp_rxlen < QQ_TCP_HEADER_LENGTH) {
+ while (PURPLE_CONNECTION_IS_VALID(gc)) {
+ if (qd->openconns == NULL) {
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, qd->tcp_rxqueue + bytes);
- if (qd->tcp_rxlen < pkt_len) {
+ bytes += qq_get16(&pkt_len, conn->tcp_rxqueue + bytes);
+ if (conn->tcp_rxlen < pkt_len) {
break;
}
- /*
- purple_debug(PURPLE_DEBUG_INFO, "TCP_PENDING",
- "Packet len is %d bytes, rxlen is %d\n", pkt_len, qd->tcp_rxlen);
- */
+ /* purple_debug_info("TCP_PENDING", "Packet len=%d, rxlen=%d\n", pkt_len, conn->tcp_rxlen); */
if ( pkt_len < QQ_TCP_HEADER_LENGTH
- || *(qd->tcp_rxqueue + bytes) != QQ_PACKET_TAG
- || *(qd->tcp_rxqueue + pkt_len - 1) != QQ_PACKET_TAIL) {
+ || *(conn->tcp_rxqueue + bytes) != QQ_PACKET_TAG
+ || *(conn->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");
- 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);
+ jump = memchr(conn->tcp_rxqueue + 1, QQ_PACKET_TAIL, conn->tcp_rxlen - 1);
if ( !jump ) {
- 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;
+ 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;
return;
}
/* jump and over QQ_PACKET_TAIL */
- 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;
+ 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;
continue;
}
memset(pkt, 0, MAX_PACKET_SIZE);
- g_memmove(pkt, qd->tcp_rxqueue + bytes, pkt_len - bytes);
-
+ g_memmove(pkt, conn->tcp_rxqueue + bytes, pkt_len - bytes);
+
/* jump to next packet */
- 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;
+ 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;
} else {
- /* purple_debug(PURPLE_DEBUG_ERROR, "TCP_PENDING", "free tcp_rxqueue\n"); */
- g_free(qd->tcp_rxqueue);
- qd->tcp_rxqueue = NULL;
+ /* purple_debug_info("TCP_PENDING", "free tcp_rxqueue\n"); */
+ g_free(conn->tcp_rxqueue);
+ conn->tcp_rxqueue = NULL;
}
if (pkt == NULL) {
continue;
}
- /* do not call packet_process before jump
- * packet_process may call disconnect and destory tcp_rxqueue */
- packet_process(gc, pkt, pkt_len - bytes);
+ /* 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;
+ }
}
}
static void udp_pending(gpointer data, gint source, PurpleInputCondition cond)
{
- PurpleConnection *gc;
+ PurpleConnection *gc = (PurpleConnection *) data;
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,
@@ -393,13 +482,10 @@ 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(qd->fd, buf, MAX_PACKET_SIZE);
+ buf_len = read(source, buf, MAX_PACKET_SIZE);
if (buf_len <= 0) {
purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Unable to read from socket"));
@@ -419,73 +505,95 @@ 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(qq_data *qd, guint8 *data, gint data_len)
+static gint udp_send_out(PurpleConnection *gc, guint8 *data, gint data_len)
{
+ qq_data *qd;
gint ret;
- g_return_val_if_fail(qd != NULL && qd->fd >= 0 && data != NULL && data_len > 0, -1);
+ g_return_val_if_fail(data != NULL && data_len > 0, -1);
- /*
- purple_debug(PURPLE_DEBUG_INFO, "UDP_SEND_OUT", "Send %d bytes to socket %d\n", data_len, qd->fd);
- */
-
+ 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
+
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(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));
+ 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));
}
return ret;
}
static void tcp_can_write(gpointer data, gint source, PurpleInputCondition cond)
{
- qq_data *qd = data;
+ PurpleConnection *gc = (PurpleConnection *) data;
+ qq_data *qd;
+ qq_connection *conn;
int ret, writelen;
- writelen = purple_circ_buffer_get_max_read(qd->tcp_txbuf);
+ 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);
if (writelen == 0) {
- purple_input_remove(qd->tx_handler);
- qd->tx_handler = 0;
+ purple_input_remove(conn->can_write_handler);
+ conn->can_write_handler = 0;
return;
}
- 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);
+ ret = write(source, conn->tcp_txbuf->outptr, writelen);
+ purple_debug_info("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(qd->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Write Error"));
return;
}
- purple_circ_buffer_mark_read(qd->tcp_txbuf, ret);
+ purple_circ_buffer_mark_read(conn->tcp_txbuf, ret);
}
-static gint tcp_send_out(qq_data *qd, guint8 *data, gint data_len)
+static gint tcp_send_out(PurpleConnection *gc, guint8 *data, gint data_len)
{
+ qq_data *qd;
+ qq_connection *conn;
gint ret;
- g_return_val_if_fail(qd != NULL && qd->fd >= 0 && data != NULL && data_len > 0, -1);
+ g_return_val_if_fail(data != NULL && data_len > 0, -1);
- /*
- purple_debug(PURPLE_DEBUG_INFO, "TCP_SEND_OUT", "Send %d bytes to socket %d\n", data_len, qd->fd);
- */
+ g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, -1);
+ qd = (qq_data *) gc->proto_data;
- if (qd->tx_handler == 0) {
+ 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) {
ret = write(qd->fd, data, data_len);
} else {
ret = -1;
@@ -493,28 +601,28 @@ static gint tcp_send_out(qq_data *qd, gu
}
/*
- purple_debug(PURPLE_DEBUG_INFO, "TCP_SEND_OUT",
+ 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(PURPLE_DEBUG_INFO, "TCP_SEND_OUT", "Socket is busy and send later\n");
+ 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(PURPLE_DEBUG_ERROR, "TCP_SEND_OUT",
+ purple_debug_error("TCP_SEND_OUT",
"Send to socket %d failed: %d, %s\n", qd->fd, errno, g_strerror(errno));
- purple_connection_error_reason(qd->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, g_strerror(errno));
+ purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, g_strerror(errno));
return ret;
}
if (ret < data_len) {
- purple_debug(PURPLE_DEBUG_INFO, "TCP_SEND_OUT",
+ purple_debug_info("TCP_SEND_OUT",
"Add %d bytes to buffer\n", data_len - ret);
- if (qd->tx_handler == 0) {
- qd->tx_handler = purple_input_add(qd->fd, PURPLE_INPUT_WRITE, tcp_can_write, qd);
+ if (conn->can_write_handler == 0) {
+ conn->can_write_handler = purple_input_add(qd->fd, PURPLE_INPUT_WRITE, tcp_can_write, gc);
}
- purple_circ_buffer_append(qd->tcp_txbuf, data + ret, data_len - ret);
+ purple_circ_buffer_append(conn->tcp_txbuf, data + ret, data_len - ret);
}
return ret;
}
@@ -528,17 +636,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(qd);
+ is_lost_conn = qq_trans_scan(gc);
if (is_lost_conn) {
purple_connection_error_reason(gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Connection lost"));
return TRUE;
}
- if ( !qd->logged_in ) {
+ if ( !qd->is_login ) {
return TRUE;
}
-
+
qd->itv_count.keep_alive--;
if (qd->itv_count.keep_alive <= 0) {
qd->itv_count.keep_alive = qd->itv_config.keep_alive;
@@ -553,55 +661,30 @@ static gboolean network_timeout(gpointer
qd->itv_count.update--;
if (qd->itv_count.update <= 0) {
qd->itv_count.update = qd->itv_config.update;
- qq_send_packet_get_buddies_online(gc, 0);
-
- qq_send_cmd_group_all_get_online_members(gc);
+ qq_update_online(gc, 0);
return TRUE;
}
return TRUE; /* if return FALSE, timeout callback stops */
}
-/* 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)
+static void do_request_token(PurpleConnection *gc)
{
qq_data *qd;
- PurpleConnection *gc;
gchar *conn_msg;
const gchar *passwd;
- PurpleAccount *account ;
- gc = (PurpleConnection *) data;
+ /* _qq_show_socket("Got login socket", source); */
- 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 */
- srandom(time(NULL));
- qd->send_seq = random() & 0x0000ffff;
- qd->fd = source;
- qd->logged_in = FALSE;
+ srand(time(NULL));
+ qd->send_seq = rand() & 0xffff;
+
+ qd->is_login = FALSE;
+ qd->is_finish_update = FALSE;
qd->channel = 1;
qd->uid = strtol(purple_account_get_username(purple_connection_get_account(gc)), NULL, 10);
@@ -614,260 +697,94 @@ static void qq_connect_cb(gpointer data,
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_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;
+ g_return_if_fail(qd->network_watcher == 0);
+ qd->network_watcher = purple_timeout_add_seconds(qd->itv_config.resend, network_timeout, gc);
- 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("Login as %d", qd->uid);
- purple_connection_update_progress(gc, conn_msg, QQ_CONNECT_STEPS - 1, QQ_CONNECT_STEPS);
+ conn_msg = g_strdup_printf(_("Request token"));
+ purple_connection_update_progress(gc, conn_msg, 2, QQ_CONNECT_STEPS);
g_free(conn_msg);
qq_send_packet_token(gc);
}
-static void udp_can_write(gpointer data, gint source, PurpleInputCondition cond)
+/* 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)
{
PurpleConnection *gc;
qq_data *qd;
- socklen_t len;
- int error=0, ret;
+ PurpleAccount *account ;
+ qq_connection *conn;
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;
- 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;
-
+ if (!PURPLE_CONNECTION_IS_VALID(gc)) {
+ purple_debug_info("QQ_CONN", "Invalid connection\n");
close(source);
-
- purple_debug_error("proxy", "getsockopt SO_ERROR check: %s\n", g_strerror(error));
-
- qq_connect_cb(gc, -1, _("Unable to connect"));
return;
}
- 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"));
+ 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);
return;
}
- 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);
+ /* _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);
}
- 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);
+ do_request_token( gc );
}
-/* establish a generic QQ connection
- * TCP/UDP, and direct/redirected */
-void qq_connect(PurpleAccount *account)
+gboolean connect_to_server(PurpleConnection *gc, gchar *server, gint port)
{
- PurpleConnection *gc;
+ PurpleAccount *account ;
qq_data *qd;
gchar *conn_msg;
- gc = purple_account_get_connection(account);
- g_return_if_fail(gc != NULL && gc->proto_data != NULL);
-
+ g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, FALSE);
+ account = purple_connection_get_account(gc);
qd = (qq_data *) gc->proto_data;
-
- /* 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) {
+ if (server == NULL || strlen(server) == 0 || port == 0) {
purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("hostname is NULL or port is 0"));
- return;
+ _("Invalid server or port"));
+ return FALSE;
}
- conn_msg = g_strdup_printf( _("Connecting server %s, retries %d"),
- qd->real_hostname, qd->reconnect_times);
+ conn_msg = g_strdup_printf( _("Connecting server %s, retries %d"), server, port);
purple_connection_update_progress(gc, conn_msg, 1, QQ_CONNECT_STEPS);
g_free(conn_msg);
- 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;
+ purple_debug_info("QQ", "Connect to %s:%d\n", server, port);
- 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;
+ if (qd->conn_data != NULL) {
+ purple_proxy_connect_cancel(qd->conn_data);
+ qd->conn_data = NULL;
}
-
- 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"));
+ 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;
}
+ return TRUE;
}
/* clean up qq_data structure and all its components
@@ -879,65 +796,32 @@ void qq_disconnect(PurpleConnection *gc)
g_return_if_fail(gc != NULL && gc->proto_data != NULL);
qd = (qq_data *) gc->proto_data;
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "Disconnecting ...\n");
+ purple_debug_info("QQ", "Disconnecting ...\n");
- if (qd->network_timeout > 0) {
- purple_timeout_remove(qd->network_timeout);
- qd->network_timeout = 0;
+ if (qd->network_watcher > 0) {
+ purple_debug_info("QQ", "Remove network watcher\n");
+ purple_timeout_remove(qd->network_watcher);
+ qd->network_watcher = 0;
}
/* finish all I/O */
- if (qd->fd >= 0 && qd->logged_in) {
+ if (qd->fd >= 0 && qd->is_login) {
qq_send_packet_logout(gc);
}
- if (gc->inpa > 0) {
- purple_input_remove(gc->inpa);
- gc->inpa = 0;
+ /* 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;
}
+ connection_free_all(qd);
+ qd->fd = -1;
- if (qd->fd >= 0) {
- close(qd->fd);
- qd->fd = -1;
- }
+ qq_trans_remove_all(gc);
- 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(PURPLE_DEBUG_INFO, "QQ", "free token\n");
+ purple_debug_info("QQ", "free token\n");
g_free(qd->token);
qd->token = NULL;
qd->token_len = 0;
@@ -955,13 +839,13 @@ void qq_disconnect(PurpleConnection *gc)
qq_buddies_list_free(gc->account, qd);
}
-static gint encap(qq_data *qd, guint8 *buf, gint maxlen, guint16 cmd, guint16 seq,
+static gint packet_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) {
@@ -971,7 +855,7 @@ static gint encap(qq_data *qd, guint8 *b
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);
@@ -987,109 +871,144 @@ static gint encap(qq_data *qd, guint8 *b
}
/* data has been encrypted before */
-gint qq_send_data(qq_data *qd, guint16 cmd, guint16 seq, gboolean need_ack,
- guint8 *data, gint data_len)
+static gint packet_send_out(PurpleConnection *gc, guint16 cmd, guint16 seq, guint8 *data, gint data_len)
{
+ qq_data *qd;
guint8 *buf;
gint buf_len;
gint bytes_sent;
- g_return_val_if_fail(qd != NULL, -1);
+ 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);
buf = g_newa(guint8, MAX_PACKET_SIZE);
memset(buf, 0, MAX_PACKET_SIZE);
- buf_len = encap(qd, buf, MAX_PACKET_SIZE, cmd, seq, data, data_len);
+ buf_len = packet_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(qd, buf, buf_len);
+ bytes_sent = tcp_send_out(gc, buf, buf_len);
} else {
- bytes_sent = udp_send_out(qd, buf, buf_len);
+ bytes_sent = udp_send_out(gc, 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(qd, cmd, seq, data, data_len);
+ qq_trans_add_client_cmd(gc, cmd, seq, data, data_len, 0, 0);
}
-
-#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;
+ return send_len;
}
-/* 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)
+/* 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)
{
+ qq_data *qd;
guint8 *encrypted_data;
gint encrypted_len;
+ gint bytes_sent;
- g_return_val_if_fail(qd != NULL, -1);
+ 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);
/* 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(PURPLE_DEBUG_ERROR, "QQ_ENCRYPT",
- "Error len %d: [%05d] 0x%04X %s\n",
+ purple_debug_error("QQ_ENCRYPT", "Error len %d: [%05d] 0x%04X %s\n",
encrypted_len, seq, cmd, qq_get_cmd_desc(cmd));
return -1;
}
-#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);
+ 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;
}
-/* 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)
+gint qq_send_cmd_mess(PurpleConnection *gc, guint16 cmd, guint8 *data, gint data_len,
+ gint update_class, guint32 ship32)
{
- g_return_val_if_fail(qd != NULL, -1);
+ 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(data != NULL && data_len > 0, -1);
- qd->send_seq++;
- return qq_send_cmd_detail(qd, cmd, qd->send_seq, TRUE, data, data_len);
+ 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);
}
-gint qq_send_room_cmd_noid(PurpleConnection *gc, guint8 room_cmd,
- guint8 *data, gint 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)
{
- return qq_send_room_cmd(gc, room_cmd, 0, data, 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);
}
-gint qq_send_room_cmd_only(PurpleConnection *gc, guint8 room_cmd, guint32 room_id)
+/* 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)
{
- g_return_val_if_fail(room_cmd > 0 && room_id > 0, -1);
- return qq_send_room_cmd(gc, room_cmd, room_id, NULL, 0);
+#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);
}
-gint qq_send_room_cmd(PurpleConnection *gc, guint8 room_cmd, guint32 room_id,
- guint8 *data, gint data_len)
+static gint send_room_cmd(PurpleConnection *gc, guint8 room_cmd, guint32 room_id,
+ guint8 *data, gint data_len, gint update_class, guint32 ship32)
{
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;
@@ -1106,6 +1025,7 @@ gint qq_send_room_cmd(PurpleConnection *
if (data != NULL && data_len > 0) {
buf_len += qq_putdata(buf + buf_len, data, data_len);
}
+
qd->send_seq++;
seq = qd->send_seq;
@@ -1114,32 +1034,43 @@ gint qq_send_room_cmd(PurpleConnection *
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(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));
+ 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);
return -1;
}
- /* 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);
-
+ bytes_sent = packet_send_out(gc, QQ_CMD_ROOM, seq, encrypted_data, encrypted_len);
#if 1
/* qq_show_packet("QQ_SEND_DATA", buf, 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);
+ 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);
#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 2cdd0ad833eabce487e648a3199219fd25f6492e
+++ libpurple/protocols/qq/qq_network.h d179aeabf6d58c136f1d465b18e23a4c64abcc60
@@ -32,19 +32,23 @@
#define QQ_CONNECT_STEPS 3 /* steps in connection */
-void qq_connect(PurpleAccount *account);
+gboolean qq_connect_later(gpointer data);
void qq_disconnect(PurpleConnection *gc);
-void qq_connect_later(PurpleConnection *gc);
-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_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_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 9dfd5fbbb3544fd5b8f71905085661c643d1a563
+++ libpurple/protocols/qq/qq_process.c 0cdaf6d2e2e957e9a0666ac0c2ccf0e25c9bfd5a
@@ -26,11 +26,6 @@
#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"
@@ -88,8 +83,7 @@ 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;
@@ -102,20 +96,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(PURPLE_DEBUG_WARNING, "QQ",
- "Can not decrypt server cmd by session key, [%05d], 0x%04X %s, len %d\n",
+ 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(PURPLE_DEBUG_WARNING, "QQ",
- "Server cmd decrypted is empty, [%05d], 0x%04X %s, len %d\n",
+ 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:
@@ -124,7 +118,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_RECV_MSG_BUDDY_CHANGE_STATUS:
+ case QQ_CMD_BUDDY_CHANGE_STATUS:
qq_process_buddy_change_status(data, data_len, gc);
break;
default:
@@ -133,98 +127,198 @@ void qq_proc_cmd_server(PurpleConnection
}
}
-static void process_cmd_login(PurpleConnection *gc, guint8 *data, gint data_len)
+static void process_room_cmd_notify(PurpleConnection *gc,
+ guint8 room_cmd, guint8 room_id, guint8 reply, 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;
- guint ret_8;
+ qq_group *group;
+ gint ret;
g_return_if_fail (gc != NULL && gc->proto_data != NULL);
-
qd = (qq_data *) gc->proto_data;
- 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");
+ 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;
+ }
- purple_connection_set_state(gc, PURPLE_CONNECTED);
- qd->logged_in = TRUE; /* must be defined after sev_finish_login */
+ 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;
+ }
+}
- /* now initiate QQ Qun, do it first as it may take longer to finish */
- qq_group_init(gc);
+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 goes on updating my icon/nickname, not showing info_window */
- qd->modifying_face = FALSE;
+ g_return_if_fail (gc != NULL && gc->proto_data != NULL);
+ qd = (qq_data *) gc->proto_data;
- qq_send_packet_get_info(gc, qd->uid, FALSE);
- /* grab my level */
- qq_send_packet_get_level(gc, qd->uid);
+ 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_change_status(gc);
+ 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;
+ }
+}
- /* refresh buddies */
- qq_send_packet_get_buddies_list(gc, 0);
+void qq_update_all(PurpleConnection *gc, guint16 cmd)
+{
+ qq_data *qd;
- /* refresh groups */
- qq_send_packet_get_buddies_and_rooms(gc, 0);
+ g_return_if_fail (gc != NULL && gc->proto_data != NULL);
+ qd = (qq_data *) gc->proto_data;
- return;
+ 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;
}
+}
- 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);
- */
+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");
return;
}
-
- 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."));
+ if (next_group == NULL ) {
+ purple_debug_info("QQ", "finished update online buddies\n");
return;
}
- 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;
+ 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;
}
}
-static void process_room_cmd_notify(PurpleConnection *gc,
- guint8 room_cmd, guint8 room_id, guint8 reply_cmd, guint8 reply, guint8 *data, gint data_len)
+void qq_update_online(PurpleConnection *gc, guint16 cmd)
{
- 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);
+ 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;
+ }
}
-void qq_proc_room_cmd_reply(PurpleConnection *gc,
- guint16 seq, guint8 room_cmd, guint32 room_id, 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,
+ gint update_class, guint32 ship32)
{
qq_data *qd;
guint8 *data;
@@ -239,58 +333,57 @@ 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(PURPLE_DEBUG_WARNING, "QQ",
- "Can not decrypt room cmd by session key, [%05d], 0x%02X %s for %d, len %d\n",
+ 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(PURPLE_DEBUG_WARNING, "QQ",
- "Invaild room id, [%05d], 0x%02X %s for %d, len %d\n",
+ 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(PURPLE_DEBUG_WARNING, "QQ",
- "Invaild len of room cmd decrypted, [%05d], 0x%02X %s for %d, len %d\n",
+ 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(PURPLE_DEBUG_WARNING, "QQ",
- "Missing room id in [%05d], 0x%02X %s for %d, len %d\n",
+ 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(PURPLE_DEBUG_WARNING, "QQ",
- "Missing room cmd in reply 0x%02X %s, [%05d], 0x%02X %s for %d, len %d\n",
+ 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(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;
+ purple_debug_warning("QQ",
+ _("You are not a member of QQ Qun \"%s\"\n"), group->title_utf8);
+ group->my_role = QQ_ROOM_ROLE_NO;
qq_group_refresh(gc, group);
}
break;
@@ -300,7 +393,7 @@ void qq_proc_room_cmd_reply(PurpleConnec
purple_roomlist_set_in_progress(qd->roomlist, FALSE);
}
default:
- process_room_cmd_notify(gc, room_cmd, room_id, reply_cmd, reply, data + bytes, data_len - bytes);
+ process_room_cmd_notify(gc, reply_cmd, room_id, reply, data + bytes, data_len - bytes);
}
return;
}
@@ -309,10 +402,6 @@ 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);
@@ -346,30 +435,90 @@ void qq_proc_room_cmd_reply(PurpleConnec
if (group != NULL)
qq_group_conv_refresh_online_member(gc, group);
break;
- case QQ_ROOM_CMD_GET_MEMBER_INFO:
- qq_process_room_cmd_get_members(data + bytes, data_len - bytes, gc);
+ case QQ_ROOM_CMD_GET_BUDDIES:
+ qq_process_room_cmd_get_buddies(data + bytes, data_len - bytes, gc);
if (group != NULL)
qq_group_conv_refresh_online_member(gc, group);
break;
default:
- purple_debug(PURPLE_DEBUG_WARNING, "QQ",
- "Unknow room cmd 0x%02X %s\n",
+ 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_reply(PurpleConnection *gc,
- guint16 cmd, guint16 seq, guint8 *rcved, gint rcved_len)
+void qq_proc_cmd_login(PurpleConnection *gc, 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;
- gchar *error_msg = NULL;
+ gboolean is_unknow = FALSE;
g_return_if_fail(rcved_len > 0);
@@ -377,61 +526,23 @@ void qq_proc_cmd_reply(PurpleConnection
qd = (qq_data *) gc->proto_data;
data = g_newa(guint8, rcved_len);
- 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;
- }
+ 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 (data_len <= 0) {
- purple_debug(PURPLE_DEBUG_WARNING, "QQ",
- "Reply decrypted is empty, [%05d], 0x%04X %s, len %d\n",
+ 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;
@@ -450,7 +561,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_ONLINE_STATUS:
+ case QQ_CMD_CHANGE_STATUS:
qq_process_change_status_reply(data, data_len, gc);
break;
case QQ_CMD_SEND_IM:
@@ -462,41 +573,53 @@ 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(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", "Requesting for more online buddies\n");
+ qq_request_get_buddies_online(gc, ret_8, update_class);
+ return;
}
+ 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(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);
+ 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;
}
+ 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(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", "Requesting for more buddies and groups\n");
+ qq_request_get_buddies_and_rooms(gc, ret_32, update_class);
+ return;
}
+ 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 85481566d6e1810595242ecd79f2cdd00533b4c1
+++ libpurple/protocols/qq/qq_process.h 2f018e76532ac55f6c6241268da8606ff3ad811b
@@ -30,12 +30,24 @@
#include "qq.h"
-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);
+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);
#endif
============================================================
--- libpurple/protocols/qq/qq_trans.c 5428a1f0f85c64a6e38cab4fc2777c98a2e4a853
+++ libpurple/protocols/qq/qq_trans.c 166bf6c83885256e73dfc43353cec519daa9a131
@@ -37,8 +37,35 @@
#define QQ_RESEND_MAX 3 /* max resend per packet */
-qq_transaction *qq_trans_find_rcved(qq_data *qd, guint16 cmd, guint16 seq)
+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_data *qd = (qq_data *)gc->proto_data;
GList *curr;
GList *next;
qq_transaction *trans;
@@ -50,19 +77,21 @@ qq_transaction *qq_trans_find_rcved(qq_d
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_data(qd, trans->cmd, trans->seq, FALSE, trans->data, trans->data_len);
+ qq_send_cmd_encrypted(gc, trans->cmd, trans->seq, trans->data, trans->data_len, FALSE);
}
}
+ */
return trans;
}
}
@@ -70,20 +99,20 @@ qq_transaction *qq_trans_find_rcved(qq_d
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
@@ -102,115 +131,122 @@ 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(qq_data *qd, qq_transaction *trans)
+static void trans_remove(PurpleConnection *gc, qq_transaction *trans)
{
+ qq_data *qd = (qq_data *)gc->proto_data;
g_return_if_fail(qd != NULL && trans != NULL);
-
- purple_debug(PURPLE_DEBUG_INFO, "QQ_TRANS",
+
+#if 0
+ 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(qq_data *qd, guint16 cmd, guint16 seq, guint8 *data, gint data_len)
+void qq_trans_add_client_cmd(PurpleConnection *gc,
+ guint16 cmd, guint16 seq, guint8 *data, gint data_len, gint update_class, guint32 ship32)
{
- qq_transaction *trans = g_new0(qq_transaction, 1);
+ qq_data *qd = (qq_data *)gc->proto_data;
+ qq_transaction *trans = trans_create(gc, qd->fd, cmd, seq, data, data_len, update_class, ship32);
- 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_CLI_IMPORT;
+ trans->flag |= QQ_TRANS_IS_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;
- 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",
+#if 0
+ 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(qq_data *qd, guint16 seq, guint8 room_cmd, guint32 room_id,
- guint8 *data, gint data_len)
+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)
{
- qq_transaction *trans = g_new0(qq_transaction, 1);
+ 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);
- 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;
- 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",
+#if 0
+ 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(qq_data *qd, guint16 cmd, guint16 seq, guint8 *data, gint data_len)
+void qq_trans_add_server_cmd(PurpleConnection *gc,
+ guint16 cmd, guint16 seq, guint8 *data, gint data_len)
{
- qq_transaction *trans = g_new0(qq_transaction, 1);
+ 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);
- g_return_if_fail(trans != NULL);
-
trans->flag = QQ_TRANS_IS_SERVER;
- if ( !qd->logged_in ) {
+ if ( !qd->is_login ) {
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;
- 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",
+#if 0
+ 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(qq_data *qd)
+void qq_trans_process_before_login(PurpleConnection *gc)
{
+ qq_data *qd = (qq_data *)gc->proto_data;
GList *curr;
GList *next;
qq_transaction *trans;
@@ -221,42 +257,44 @@ void qq_trans_process_before_login(qq_da
while( (curr = next) ) {
next = curr->next;
trans = (qq_transaction *) (curr->data);
- /* purple_debug(PURPLE_DEBUG_ERROR, "QQ_TRANS", "Scan [%d]\n", trans->seq); */
-
+#if 0
+ purple_debug_info("QQ_TRANS", "Scan [%d]\n", trans->seq);
+#endif
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(PURPLE_DEBUG_ERROR, "QQ_TRANS",
+ purple_debug_info("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(qd->gc, trans->seq, trans->cmd, trans->data, trans->data_len);
+ qq_proc_cmd_reply(gc, trans->seq, trans->cmd, trans->data, trans->data_len, trans->update_class, trans->ship32);
}
- /* purple_debug(PURPLE_DEBUG_INFO, "QQ_TRANS", "Scan finished\n"); */
+ /* purple_debug_info("QQ_TRANS", "Scan finished\n"); */
return;
}
-gboolean qq_trans_scan(qq_data *qd)
+gboolean qq_trans_scan(PurpleConnection *gc)
{
+ 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(PURPLE_DEBUG_INFO, "QQ_TRANS", "Scan [%d]\n", trans->seq); */
-
+ /* purple_debug_info("QQ_TRANS", "Scan [%d]\n", trans->seq); */
+
if (trans->flag & QQ_TRANS_BEFORE_LOGIN) {
/* keep server cmd before login*/
continue;
@@ -270,67 +308,60 @@ gboolean qq_trans_scan(qq_data *qd)
if (trans->rcved_times > 0) {
/* Has been received */
- trans_remove(qd, trans);
+ trans_remove(gc, trans);
continue;
}
if (trans->flag & QQ_TRANS_IS_SERVER) {
continue;
}
-
+
/* Never get reply */
trans->send_retries--;
if (trans->send_retries <= 0) {
- purple_debug(PURPLE_DEBUG_WARNING, "QQ_TRANS",
+ purple_debug_warning("QQ_TRANS",
"[%d] %s is lost.\n",
trans->seq, qq_get_cmd_desc(trans->cmd));
- if (trans->flag & QQ_TRANS_CLI_IMPORT) {
+ if (trans->flag & QQ_TRANS_IS_IMPORT) {
return TRUE;
}
- purple_debug(PURPLE_DEBUG_ERROR, "QQ_TRANS",
+ 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(qd, trans);
+ trans_remove(gc, trans);
continue;
}
- purple_debug(PURPLE_DEBUG_ERROR, "QQ_TRANS",
+ 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_data(qd, trans->cmd, trans->seq, FALSE, trans->data, trans->data_len);
+ qq_send_cmd_encrypted(gc, trans->cmd, trans->seq, trans->data, trans->data_len, FALSE);
}
- /* purple_debug(PURPLE_DEBUG_INFO, "QQ_TRANS", "Scan finished\n"); */
+ /* purple_debug_info("QQ_TRANS", "Scan finished\n"); */
return FALSE;
}
/* clean up send trans and free all contents */
-void qq_trans_remove_all(qq_data *qd)
+void qq_trans_remove_all(PurpleConnection *gc)
{
- GList *curr;
- GList *next;
+ qq_data *qd = (qq_data *)gc->proto_data;
qq_transaction *trans;
gint count = 0;
- 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);
+ while(qd->transactions != NULL) {
+ trans = (qq_transaction *) (qd->transactions->data);
+ qd->transactions = g_list_remove(qd->transactions, trans);
+ if (trans->data) g_free(trans->data);
+ g_free(trans);
+
count++;
- curr = next;
}
- g_list_free(qd->transactions);
-
- purple_debug(PURPLE_DEBUG_INFO, "QQ_TRANS", "Free all %d packets\n", count);
+ if (count > 0) {
+ purple_debug_info("QQ_TRANS", "Free all %d packets\n", count);
+ }
}
============================================================
--- libpurple/protocols/qq/qq_trans.h f4ace6ce706004259974c5198b24d9ac5daaa541
+++ libpurple/protocols/qq/qq_trans.h f2aa20b1890c075f7279612c60de46c2565f10f2
@@ -28,44 +28,27 @@
#include <glib.h>
#include "qq.h"
-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*/
-};
+typedef struct _qq_transaction qq_transaction;
-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);
+qq_transaction *qq_trans_find_rcved(PurpleConnection *gc, 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(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,
+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,
guint8 *data, gint data_len);
-void qq_trans_process_before_login(qq_data *qd);
-gboolean qq_trans_scan(qq_data *qd);
-void qq_trans_remove_all(qq_data *qd);
+void qq_trans_process_before_login(PurpleConnection *gc);
+gboolean qq_trans_scan(PurpleConnection *gc);
+void qq_trans_remove_all(PurpleConnection *gc);
#endif
============================================================
--- libpurple/protocols/qq/send_file.c d8145843c01450a9064f4b31328ad9ca7761d1d7
+++ libpurple/protocols/qq/send_file.c 0377a21744db2dc5edfd2fb7d9a4c427a3e68250
@@ -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(PURPLE_DEBUG_INFO, "QQ",
+ 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(PURPLE_DEBUG_INFO, "QQ",
+ 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(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)
+ 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)
);
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(PURPLE_DEBUG_INFO, "QQ", "file closed\n");
+ purple_debug_info("QQ", "file closed\n");
}
if (info->major_fd != 0) {
close(info->major_fd);
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "major port closed\n");
+ purple_debug_info("QQ", "major port closed\n");
}
if (info->minor_fd != 0) {
close(info->minor_fd);
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "minor port closed\n");
+ purple_debug_info("QQ", "minor port closed\n");
}
/*
if (info->buffer != NULL) {
munmap(info->buffer, purple_xfer_get_size(xfer));
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "file mapping buffer is freed.\n");
+ 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(PURPLE_DEBUG_INFO, "QQ", "remote internet ip[%s:%d], major port[%d], real ip[%s], minor port[%d]\n",
+ 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(PURPLE_DEBUG_INFO, "QQ", "local real ip is %x", info->local_real_ip);
+ 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(PURPLE_DEBUG_INFO, "QQ", "UDP Major Channel created on port[%d]\n",
+ 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(PURPLE_DEBUG_INFO, "QQ", "UDP Minor Channel created on port[%d]\n",
+ 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 (qd, QQ_CMD_SEND_IM, raw_data, bytes);
+ qq_send_cmd(gc, QQ_CMD_SEND_IM, raw_data, bytes);
else
- purple_debug (PURPLE_DEBUG_INFO, "qq_send_packet_file_request",
+ 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(PURPLE_DEBUG_INFO, "QQ", "I've accepted the file transfer request from %d\n", to_uid);
+ 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 (qd, QQ_CMD_SEND_IM, raw_data, bytes);
+ qq_send_cmd(gc, QQ_CMD_SEND_IM, raw_data, bytes);
else
- purple_debug (PURPLE_DEBUG_INFO, "qq_send_packet_file_accept",
+ 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(PURPLE_DEBUG_INFO, "QQ", "<== sending qq file notify ip packet\n");
+ 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 (qd, QQ_CMD_SEND_IM, raw_data, bytes);
+ qq_send_cmd(gc, QQ_CMD_SEND_IM, raw_data, bytes);
else
- purple_debug (PURPLE_DEBUG_INFO, "qq_send_packet_file_notify",
+ 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(PURPLE_DEBUG_INFO, "_qq_send_packet_file_reject", "start");
+ 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 (qd, QQ_CMD_SEND_IM, raw_data, bytes);
+ qq_send_cmd(gc, QQ_CMD_SEND_IM, raw_data, bytes);
else
- purple_debug (PURPLE_DEBUG_INFO, "qq_send_packet_file",
+ 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(PURPLE_DEBUG_INFO, "_qq_send_packet_file_cancel", "start\n");
+ 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(PURPLE_DEBUG_INFO, "_qq_send_packet_file_cancel", "before create header\n");
+ 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(PURPLE_DEBUG_INFO, "_qq_send_packet_file_cancel", "end create header\n");
+ purple_debug_info("_qq_send_packet_file_cancel", "end create header\n");
if (packet_len == 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);
+ purple_debug_info("_qq_send_packet_file_cancel", "before send cmd\n");
+ qq_send_cmd(gc, QQ_CMD_SEND_IM, raw_data, bytes);
}
else
- purple_debug (PURPLE_DEBUG_INFO, "qq_send_packet_file",
+ purple_debug_info("qq_send_packet_file",
"%d bytes expected but got %d bytes\n",
packet_len, bytes);
- purple_debug (PURPLE_DEBUG_INFO, "qq_send_packet_file_cancel", "end\n");
+ 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 (PURPLE_DEBUG_WARNING, "QQ",
+ purple_debug_warning("QQ",
"Received file reject message is empty\n");
return;
}
@@ -724,8 +724,7 @@ void qq_process_recv_file_cancel (guint8
/* border has been checked before
if (*cursor >= (data + data_len - 1)) {
- purple_debug (PURPLE_DEBUG_WARNING, "QQ",
- "Received file reject message is empty\n");
+ purple_debug_warning("QQ", "Received file reject message is empty\n");
return;
}
*/
@@ -755,8 +754,7 @@ void qq_process_recv_file_accept(guint8
info = (ft_info *) qd->xfer->data;
if (data_len <= 30 + QQ_CONN_INFO_LEN) {
- purple_debug (PURPLE_DEBUG_WARNING, "QQ",
- "Received file reject message is empty\n");
+ purple_debug_warning("QQ", "Received file reject message is empty\n");
return;
}
@@ -789,8 +787,7 @@ void qq_process_recv_file_request(guint8
info->to_uid = sender_uid;
if (data_len <= 2 + 30 + QQ_CONN_INFO_LEN) {
- purple_debug (PURPLE_DEBUG_WARNING, "QQ",
- "Received file request message is empty\n");
+ purple_debug_warning("QQ", "Received file request message is empty\n");
return;
}
bytes = 0;
@@ -806,7 +803,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(PURPLE_DEBUG_WARNING, "QQ",
+ 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);
@@ -826,11 +823,11 @@ void qq_process_recv_file_request(guint8
qq_update_buddy_contact(gc, q_bud);
}
else
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "buddy %d is already online\n", sender_uid);
+ purple_debug_info("QQ", "buddy %d is already online\n", sender_uid);
}
else
- purple_debug(PURPLE_DEBUG_WARNING, "QQ", "buddy %d is not in list\n", sender_uid);
+ purple_debug_warning("QQ", "buddy %d is not in list\n", sender_uid);
g_free(sender_name);
g_strfreev(fileinfo);
@@ -892,8 +889,7 @@ 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 (PURPLE_DEBUG_WARNING, "QQ",
- "Received file notify message is empty\n");
+ purple_debug_warning("QQ", "Received file notify message is empty\n");
return;
}
============================================================
--- libpurple/protocols/qq/sys_msg.c 6e80379b474adc9cdf0823a8a8985f65678fdc0c
+++ libpurple/protocols/qq/sys_msg.c b727ae40ad2e341625c4a13fa5405afc921bbe96
@@ -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_cmd_detail(qd, QQ_CMD_ACK_SYS_MSG, 0, FALSE, ack, ack_len);
+ qq_send_server_reply(gc, QQ_CMD_ACK_SYS_MSG, 0, ack, ack_len);
else
- purple_debug(PURPLE_DEBUG_ERROR, "QQ",
+ 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(_("User %s rejected your request"), from);
- reason = g_strdup_printf(_("Reason: %s"), msg_utf8);
+ message = g_strdup_printf(_("Requestion rejected by %s"), from);
+ reason = g_strdup_printf(_("Message: %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(_("User %s approved your request"), from);
+ message = g_strdup_printf(_("Requestion approved by %s"), 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 your buddy list"), from);
+ message = g_strdup_printf(_("%s is not in buddy list"), from);
purple_request_action(gc, NULL, message,
- _("Would you like to add him?"), PURPLE_DEFAULT_ACTION_NONE,
+ _("Would you add?"), PURPLE_DEFAULT_ACTION_NONE,
purple_connection_get_account(gc), name, NULL,
g2, 3,
_("Cancel"), NULL,
@@ -279,14 +279,19 @@ 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(_("Notice from: %s"), from);
+ title = g_strdup_printf(_("QQ Server Notice from %s:"), from);
content = g_strdup_printf(_("%s"), msg_utf8);
- purple_notify_info(gc, NULL, title, content);
+ 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);
+}
g_free(title);
g_free(content);
}
@@ -310,12 +315,19 @@ 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(PURPLE_DEBUG_ERROR, "QQ", "Recv sys msg to [%s], not me!, discard\n", to);
+ 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);
@@ -333,12 +345,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(PURPLE_DEBUG_WARNING, "QQ",
+ purple_debug_warning("QQ",
"QQ server says there is newer version than %s\n", qq_get_ver_desc(QQ_CLIENT));
break;
default:
- 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);
+ purple_debug_warning("QQ", "Recv unknown sys msg code: %s\n", code);
+ purple_debug_warning("QQ", "the msg is : %s\n", msg_utf8);
}
g_free(msg_utf8);
g_strfreev(segments);
============================================================
--- libpurple/protocols/qq/utils.c 034fd3fc8d7e12ad0491c8e5b6bc0799c1d2a10b
+++ libpurple/protocols/qq/utils.c 539d1c7f385eae718d39ad78e11d7367da291373
@@ -47,8 +47,8 @@
struct sockaddr_in sin;
socklen_t len = sizeof(sin);
getsockname(fd, (struct sockaddr *)&sin, &len);
- purple_debug(PURPLE_DEBUG_INFO, desc, "%s:%d\n",
- inet_ntoa(sin.sin_addr), g_ntohs(sin.sin_port));
+ 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(PURPLE_DEBUG_ERROR, "QQ",
- "Invalid data, expect %d fields, found only %d, discard\n", expected_fields, i);
+ 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(PURPLE_DEBUG_WARNING, "QQ",
- "Dangerous data, expect %d fields, found %d, return all\n", expected_fields, i);
+ 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(PURPLE_DEBUG_WARNING, "QQ", "field[%d] is %s\n", j, segments[j]);
+ 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(PURPLE_DEBUG_WARNING, "QQ", "Try extract GB msg: %s\n", msg_utf8);
+ 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(PURPLE_DEBUG_WARNING, "QQ",
+ 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(PURPLE_DEBUG_WARNING, "QQ",
- "Invalid char \'%c\' found in hex string!\n", *cursor);
+ purple_debug_warning("QQ", "Invalid char \'%c\' found in hex string!\n",
+ *cursor);
g_free(hex_str);
return NULL;
}
@@ -284,8 +284,7 @@ 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(PURPLE_DEBUG_WARNING, "QQ",
- "Invalid char found in hex string!\n");
+ purple_debug_warning("QQ", "Invalid char found in hex string!\n");
g_free(hex_str);
return NULL;
}
@@ -362,22 +361,7 @@ void qq_show_packet(const gchar *desc, c
void qq_show_packet(const gchar *desc, const guint8 *buf, gint len)
{
- /*
- 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,
- "");
+ qq_hex_dump(PURPLE_DEBUG_INFO, "QQ", buf, len, desc);
}
/* convert face num from packet (0-299) to local face (1-100) */
@@ -397,5 +381,16 @@ 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 NULL;
+ return QQ_BUDDY_ICON_DIR;
}
+
+#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 fe344b9710669a7efae22d9cc4180d2ae7423150
+++ libpurple/protocols/qq/utils.h a391181cf3622cac8ce340dc75b39779c362456b
@@ -56,5 +56,6 @@ 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