summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSHiNE CsyFeK <csyfek@gmail.com>2008-07-17 14:43:56 +0000
committerSHiNE CsyFeK <csyfek@gmail.com>2008-07-17 14:43:56 +0000
commitf2cd24c28d39c2362d9cc9b62dfcea94f8508a94 (patch)
treecd9ad54c9baac17beaecad33e48c54ce4da15387
parent88f66f1fa559e19e674ffec30f8dbd532d9ae98e (diff)
downloadpidgin-f2cd24c28d39c2362d9cc9b62dfcea94f8508a94.tar.gz
2008.07.12 - ccpaging <ecc_hy(at)hotmail.com>
* Fixed: Always lost connection. Now send keep alive packet in every 30 seconds * Minor fix for debug information * Filter \r\n and replace with SPCAE in group notive * Fixed a memory leak * Tickets: * Fixes #4024.
-rw-r--r--libpurple/protocols/qq/AUTHORS4
-rw-r--r--libpurple/protocols/qq/ChangeLog8
-rw-r--r--libpurple/protocols/qq/buddy_info.c9
-rw-r--r--libpurple/protocols/qq/buddy_list.c19
-rw-r--r--libpurple/protocols/qq/buddy_status.c4
-rw-r--r--libpurple/protocols/qq/char_conv.c19
-rw-r--r--libpurple/protocols/qq/char_conv.h2
-rw-r--r--libpurple/protocols/qq/group_conv.c4
-rw-r--r--libpurple/protocols/qq/group_free.c2
-rw-r--r--libpurple/protocols/qq/group_info.c47
-rw-r--r--libpurple/protocols/qq/group_internal.c4
-rw-r--r--libpurple/protocols/qq/qq_network.c17
-rw-r--r--libpurple/protocols/qq/qq_trans.c4
-rw-r--r--libpurple/protocols/qq/qq_trans.h2
14 files changed, 95 insertions, 50 deletions
diff --git a/libpurple/protocols/qq/AUTHORS b/libpurple/protocols/qq/AUTHORS
index ff4a835754..5cb48830dd 100644
--- a/libpurple/protocols/qq/AUTHORS
+++ b/libpurple/protocols/qq/AUTHORS
@@ -16,7 +16,7 @@ csyfek : faces, maintainer since 2007
Lovely Patch Writers
=====
-Gnap.An : message displaying, documentation
+gnap : message displaying, documentation
manphiz : qun processing
moo : qun processing
Coly Li : qun processing
@@ -32,4 +32,4 @@ qulogic@pidgin.im
rlaager@pidgin.im
OpenQ Team
LumaQQ Team
-OpenQ@GoogleGroup
+OpenQ Google Group
diff --git a/libpurple/protocols/qq/ChangeLog b/libpurple/protocols/qq/ChangeLog
index a41343366a..d8ff30db42 100644
--- a/libpurple/protocols/qq/ChangeLog
+++ b/libpurple/protocols/qq/ChangeLog
@@ -1,3 +1,11 @@
+2008.07.12 - ccpaging <ecc_hy(at)hotmail.com>
+ * Fixed: Always lost connection. Now send keep alive packet in every 30 seconds
+ * Minor fix for debug information
+ * Filter \r\n and replace with SPCAE in group notive
+ * Fixed a memory leak
+ * Tickets:
+ * Fixes #4024.
+
2008.06.29 - csyfek <csyfek(at)gmail.com>
* Minor bug fix
* Add some doxygen syntax for preparing development documentation
diff --git a/libpurple/protocols/qq/buddy_info.c b/libpurple/protocols/qq/buddy_info.c
index 8363c4965c..4a81474680 100644
--- a/libpurple/protocols/qq/buddy_info.c
+++ b/libpurple/protocols/qq/buddy_info.c
@@ -208,8 +208,8 @@ static gboolean append_field_value(PurpleNotifyUserInfo *user_info, const gchar
return FALSE;
}
- static PurpleNotifyUserInfo *
-info_to_notify_user_info(const contact_info *info)
+static PurpleNotifyUserInfo *
+ info_to_notify_user_info(const contact_info *info)
{
PurpleNotifyUserInfo *user_info = purple_notify_user_info_new();
const gchar *intro;
@@ -826,7 +826,8 @@ static void qq_refresh_buddy_and_myself(contact_info *info, PurpleConnection *gc
PurpleBuddy *b;
qq_data *qd;
qq_buddy *q_bud;
- gchar *alias_utf8, *purple_name;
+ gchar *alias_utf8;
+ gchar *purple_name;
PurpleAccount *account = purple_connection_get_account(gc);
qd = (qq_data *) gc->proto_data;
@@ -1009,7 +1010,7 @@ void qq_process_get_level_reply(guint8 *buf, gint buf_len, PurpleConnection *gc)
bytes += qq_get16(&level, decr_buf + bytes);
bytes += qq_get16(&timeRemainder, decr_buf + bytes);
purple_debug(PURPLE_DEBUG_INFO, "QQ",
- "Level packet entry:\nuid: %d\nonlineTime: %d\nlevel: %d\ntimeRemainder: %d\n",
+ "Level uid: %d, onlineTime: %d, level: %d, timeRemainder: %d\n",
uid, onlineTime, level, timeRemainder);
purple_name = uid_to_purple_name(uid);
b = purple_find_buddy(account, purple_name);
diff --git a/libpurple/protocols/qq/buddy_list.c b/libpurple/protocols/qq/buddy_list.c
index 9408984496..2b9fa66718 100644
--- a/libpurple/protocols/qq/buddy_list.c
+++ b/libpurple/protocols/qq/buddy_list.c
@@ -234,12 +234,11 @@ void qq_process_get_buddies_online_reply(guint8 *buf, gint buf_len, PurpleConnec
"qq_process_get_buddies_online_reply: Dangerous error! maybe protocol changed, notify developers!\n");
}
- if (position != QQ_FRIENDS_ONLINE_POSITION_END) {
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "Received %d online buddies, nextposition=%u\n",
- count, (guint) position);
- if (position != QQ_FRIENDS_ONLINE_POSITION_START) {
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "Requesting for more online buddies\n");
- }
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Received %d online buddies, nextposition=%u\n",
+ count, (guint) position);
+ if (position != QQ_FRIENDS_ONLINE_POSITION_END
+ && position != QQ_FRIENDS_ONLINE_POSITION_START) {
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "Requesting for more online buddies\n");
qq_send_packet_get_buddies_online(gc, position);
} else {
purple_debug(PURPLE_DEBUG_INFO, "QQ", "All online buddies received\n");
@@ -318,8 +317,8 @@ void qq_process_get_buddies_list_reply(guint8 *buf, gint buf_len, PurpleConnecti
if (QQ_DEBUG) {
purple_debug(PURPLE_DEBUG_INFO, "QQ",
- "buddy [%09d]: flag1=0x%02x, comm_flag=0x%02x\n",
- q_bud->uid, q_bud->flag1, q_bud->comm_flag);
+ "buddy [%09d]: flag1=0x%02x, comm_flag=0x%02x, nick=%s\n",
+ q_bud->uid, q_bud->flag1, q_bud->comm_flag, q_bud->nickname);
}
name = uid_to_purple_name(q_bud->uid);
@@ -432,7 +431,9 @@ void qq_process_get_all_list_with_group_reply(guint8 *buf, gint buf_len, PurpleC
purple_debug(PURPLE_DEBUG_INFO, "QQ", "Get all list done, %d buddies and %d Quns\n", i, j);
purple_debug(PURPLE_DEBUG_INFO, "QQ", "Received %d buddies and %d groups, nextposition=%u\n", i, j, (guint) position);
- if (position != QQ_FRIENDS_ALL_LIST_POSITION_START && position != QQ_FRIENDS_ALL_LIST_POSITION_START) {
+
+ if (position != QQ_FRIENDS_ALL_LIST_POSITION_START
+ && position != QQ_FRIENDS_ALL_LIST_POSITION_END) {
purple_debug(PURPLE_DEBUG_INFO, "QQ", "Requesting for more buddies and groups\n");
qq_send_packet_get_all_list_with_group(gc, position);
} else {
diff --git a/libpurple/protocols/qq/buddy_status.c b/libpurple/protocols/qq/buddy_status.c
index d96b65f37a..78f5039723 100644
--- a/libpurple/protocols/qq/buddy_status.c
+++ b/libpurple/protocols/qq/buddy_status.c
@@ -205,7 +205,9 @@ void qq_process_change_status_reply(guint8 *buf, gint buf_len, PurpleConnection
b = purple_find_buddy(gc->account, name);
g_free(name);
q_bud = (b == NULL) ? NULL : (qq_buddy *) b->proto_data;
- qq_update_buddy_contact(gc, q_bud);
+ if (q_bud != NULL) {
+ qq_update_buddy_contact(gc, q_bud);
+ }
}
}
diff --git a/libpurple/protocols/qq/char_conv.c b/libpurple/protocols/qq/char_conv.c
index 6d79a8210d..0dcde4e8c3 100644
--- a/libpurple/protocols/qq/char_conv.c
+++ b/libpurple/protocols/qq/char_conv.c
@@ -123,10 +123,7 @@ static gchar *_my_convert(const gchar *str, gssize len, const gchar *to_charset,
return g_strdup(QQ_NULL_MSG);
}
-/**
- * @brief 把输入作为一个pascal字符串并返回一个用UFT-8转换的c-字符串.\n
- * 返回已读入的字节数,或者当遇到错误时返回-1.该完成转换的UTF-8字符串被保存到ret中
- *
+/*
* take the input as a pascal string and return a converted c-string in UTF-8
* returns the number of bytes read, return -1 if fatal error
* the converted UTF-8 will be saved in ret
@@ -281,3 +278,17 @@ gchar *purple_smiley_to_qq(gchar *text)
g_string_free(converted, FALSE);
return ret;
}
+
+void qq_filter_str(gchar *str) {
+ gchar *temp;
+ if (str == NULL) {
+ return;
+ }
+
+ for (temp = str; *temp != 0; temp++) {
+ if (*temp == '\r' || *temp == '\n') *temp = 0x20;
+ }
+ g_strstrip(str);
+}
+
+
diff --git a/libpurple/protocols/qq/char_conv.h b/libpurple/protocols/qq/char_conv.h
index fc3e671af1..1d6c90bd38 100644
--- a/libpurple/protocols/qq/char_conv.h
+++ b/libpurple/protocols/qq/char_conv.h
@@ -40,5 +40,5 @@ gchar *qq_to_utf8(const gchar *str, const gchar *from_charset);
gchar *qq_encode_to_purple(guint8 *font_attr_data, gint len, const gchar *msg);
gchar *qq_im_filter_html(const gchar *text);
-
+void qq_filter_str(gchar *str);
#endif
diff --git a/libpurple/protocols/qq/group_conv.c b/libpurple/protocols/qq/group_conv.c
index d75fe130f5..1b74aa4e6e 100644
--- a/libpurple/protocols/qq/group_conv.c
+++ b/libpurple/protocols/qq/group_conv.c
@@ -99,7 +99,9 @@ void qq_group_conv_refresh_online_member(PurpleConnection *gc, qq_group *group)
list = list->next;
}
- purple_conv_chat_add_users(PURPLE_CONV_CHAT(conv), names, NULL, flags, FALSE);
+ if (names != NULL && flags != NULL) {
+ purple_conv_chat_add_users(PURPLE_CONV_CHAT(conv), names, NULL, flags, FALSE);
+ }
}
/* clean up names */
while (names != NULL) {
diff --git a/libpurple/protocols/qq/group_free.c b/libpurple/protocols/qq/group_free.c
index f1eab11795..b61f90edad 100644
--- a/libpurple/protocols/qq/group_free.c
+++ b/libpurple/protocols/qq/group_free.c
@@ -55,8 +55,10 @@ 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->notice_utf8);
g_free(group);
}
diff --git a/libpurple/protocols/qq/group_info.c b/libpurple/protocols/qq/group_info.c
index 830b3771cc..c266d69782 100644
--- a/libpurple/protocols/qq/group_info.c
+++ b/libpurple/protocols/qq/group_info.c
@@ -87,7 +87,7 @@ void qq_send_cmd_group_get_online_members(PurpleConnection *gc, qq_group *group)
/* 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",
- "Conv windows for \"%s\" is not on, do not get online members\n", group->group_name_utf8);
+ "Conversation for \"%s\" is not open, ignore to get online members\n", group->group_name_utf8);
return;
}
@@ -141,9 +141,6 @@ void qq_send_cmd_group_get_members_info(PurpleConnection *gc, qq_group *group)
qq_send_group_cmd(gc, group, raw_data, bytes);
}
-/**
- * @brief 处理群信息.当前群信息的处理还不完善,由于版本的不同导致协议的解读有差异.
- */
void qq_process_group_cmd_get_group_info(guint8 *data, gint len, PurpleConnection *gc)
{
qq_group *group;
@@ -157,6 +154,7 @@ void qq_process_group_cmd_get_group_info(guint8 *data, gint len, PurpleConnectio
guint32 unknown4;
guint8 unknown1;
gint bytes, num;
+ gchar *notice;
g_return_if_fail(data != NULL && len > 0);
qd = (qq_data *) gc->proto_data;
@@ -186,22 +184,20 @@ void qq_process_group_cmd_get_group_info(guint8 *data, gint len, PurpleConnectio
bytes += qq_get32(&(group->group_category), data + bytes);
bytes += qq_get16(&max_members, data + bytes);
bytes += qq_get8(&unknown1, data + bytes);
- /* XXX
- * the following, while Eva:
+ /* the following, while Eva:
* 4(unk), 4(verID), 1(nameLen), nameLen(qunNameContent), 1(0x00),
* 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\n",
- group->group_type, group->creator_uid, group->group_category);
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "maxmembers=%u", max_members);
+ purple_debug(PURPLE_DEBUG_INFO, "QQ", "type=%u creatorid=%u category=%u maxmembers=%u\n",
+ group->group_type, group->creator_uid, group->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 += qq_get16(&unknown, data + bytes); /* 0x0000 */
- bytes += convert_as_pascal_string(data + bytes, &(group->notice_utf8), QQ_CHARSET_DEFAULT);
- purple_debug(PURPLE_DEBUG_INFO, "QQ", "notice \"%s\"\n", group->notice_utf8);
+ bytes += convert_as_pascal_string(data + bytes, &notice, 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);
@@ -235,11 +231,16 @@ void qq_process_group_cmd_get_group_info(guint8 *data, gint len, PurpleConnectio
group->group_name_utf8, purple_connection_get_account(gc));
if(NULL == purple_conv) {
purple_debug(PURPLE_DEBUG_WARNING, "QQ",
- "Conv windows for \"%s\" is not on, do not set topic\n", group->group_name_utf8);
- }
- else {
- purple_conv_chat_set_topic(PURPLE_CONV_CHAT(purple_conv), NULL, group->notice_utf8);
+ "Conversation for \"%s\" is not open, do not set topic\n", group->group_name_utf8);
+ return;
}
+
+ /* filter \r\n in notice */
+ 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);
}
void qq_process_group_cmd_get_online_members(guint8 *data, gint len, PurpleConnection *gc)
@@ -296,6 +297,7 @@ void qq_process_group_cmd_get_members_info(guint8 *data, gint len, PurpleConnect
guint16 unknown;
qq_group *group;
qq_buddy *member;
+ gchar *nick;
g_return_if_fail(data != NULL && len > 0);
@@ -318,11 +320,24 @@ void qq_process_group_cmd_get_members_info(guint8 *data, gint len, PurpleConnect
bytes += qq_get16(&(member->face), data + bytes);
bytes += qq_get8(&(member->age), data + bytes);
bytes += qq_get8(&(member->gender), data + bytes);
- bytes += convert_as_pascal_string(data + bytes, &(member->nickname), QQ_CHARSET_DEFAULT);
+ bytes += convert_as_pascal_string(data + bytes, &nick, QQ_CHARSET_DEFAULT);
bytes += qq_get16(&unknown, data + bytes);
bytes += qq_get8(&(member->flag1), data + bytes);
bytes += qq_get8(&(member->comm_flag), data + bytes);
+ /* filter \r\n in nick */
+ qq_filter_str(nick);
+ member->nickname = g_strdup(nick);
+ g_free(nick);
+
+ /*
+ if (QQ_DEBUG) {
+ purple_debug(PURPLE_DEBUG_INFO, "QQ",
+ "member [%09d]: flag1=0x%02x, comm_flag=0x%02x, nick=%s\n",
+ member_uid, member->flag1, member->comm_flag, member->nickname);
+ }
+ */
+
member->last_refresh = time(NULL);
}
if(bytes > len) {
diff --git a/libpurple/protocols/qq/group_internal.c b/libpurple/protocols/qq/group_internal.c
index 7a761913d0..5af15b1a7e 100644
--- a/libpurple/protocols/qq/group_internal.c
+++ b/libpurple/protocols/qq/group_internal.c
@@ -230,9 +230,7 @@ void qq_set_pending_id(GSList **list, guint32 id, gboolean pending)
*list = g_slist_remove(*list, GINT_TO_POINTER(id));
}
-/**
- * @brief Return the location of id in list, or NULL if not found (返回id在链表中的位置,没有找到则返回NULL)
- */
+/* Return the location of id in list, or NULL if not found */
GSList *qq_get_pending_id(GSList *list, guint32 id)
{
return g_slist_find(list, GINT_TO_POINTER(id));
diff --git a/libpurple/protocols/qq/qq_network.c b/libpurple/protocols/qq/qq_network.c
index b2d7b5f08a..83e5b13346 100644
--- a/libpurple/protocols/qq/qq_network.c
+++ b/libpurple/protocols/qq/qq_network.c
@@ -189,13 +189,13 @@ static gboolean packet_is_dup(qq_data *qd, guint16 seq)
return FALSE; /* set mask */
}
-static gboolean packet_check_ack(qq_data *qd, guint16 seq)
+static gboolean packet_check_ack(qq_data *qd, guint16 cmd, guint16 seq)
{
gpointer trans;
g_return_val_if_fail(qd != NULL, FALSE);
- trans = qq_send_trans_find(qd, seq);
+ trans = qq_send_trans_find(qd, cmd, seq);
if (trans == NULL) {
return FALSE;
}
@@ -360,7 +360,7 @@ static void packet_process(PurpleConnection *gc, guint8 *buf, gint buf_len)
/* ack packet, we need to update send tranactions */
/* we do not check duplication for server ack */
- is_reply = packet_check_ack(qd, seq);
+ is_reply = packet_check_ack(qd, cmd, seq);
if ( !is_reply ) {
if ( !qd->logged_in ) {
/* packets before login */
@@ -460,7 +460,10 @@ static void tcp_pending(gpointer data, gint source, PurpleInputCondition cond)
return;
}
- gc->last_received = time(NULL);
+ /* keep alive will be sent in 30 seconds since last_receive
+ * 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);
@@ -565,7 +568,10 @@ static void udp_pending(gpointer data, gint source, PurpleInputCondition cond)
return;
}
- gc->last_received = time(NULL);
+ /* keep alive will be sent in 30 seconds since last_receive
+ * QQ need a keep alive packet in every 60 seconds
+ gc->last_received = time(NULL);
+ */
if (buf_len < QQ_UDP_HEADER_LENGTH) {
if (buf[0] != QQ_PACKET_TAG || buf[buf_len - 1] != QQ_PACKET_TAIL) {
@@ -1240,7 +1246,6 @@ gint qq_send_cmd_detail(qq_data *qd, guint16 cmd, guint16 seq, gboolean need_ack
}
if (QQ_DEBUG) {
- qq_show_packet("QQ_SEND_CMD", buf, buf_len);
purple_debug(PURPLE_DEBUG_INFO, "QQ",
"<== [%05d], %s, total %d bytes is sent %d\n",
seq, qq_get_cmd_desc(cmd), buf_len, bytes_sent);
diff --git a/libpurple/protocols/qq/qq_trans.c b/libpurple/protocols/qq/qq_trans.c
index 9dc5eb52e2..71b7ad6c8f 100644
--- a/libpurple/protocols/qq/qq_trans.c
+++ b/libpurple/protocols/qq/qq_trans.c
@@ -83,7 +83,7 @@ void qq_send_trans_remove(qq_data *qd, gpointer data)
g_free(trans);
}
-gpointer qq_send_trans_find(qq_data *qd, guint16 seq)
+gpointer qq_send_trans_find(qq_data *qd, guint16 cmd, guint16 seq)
{
GList *curr;
GList *next;
@@ -93,7 +93,7 @@ gpointer qq_send_trans_find(qq_data *qd, guint16 seq)
while(curr) {
next = curr->next;
trans = (transaction *) (curr->data);
- if(trans->seq == seq) {
+ if(trans->cmd == cmd && trans->seq == seq) {
return trans;
}
curr = next;
diff --git a/libpurple/protocols/qq/qq_trans.h b/libpurple/protocols/qq/qq_trans.h
index a6bbf9073f..12349a9009 100644
--- a/libpurple/protocols/qq/qq_trans.h
+++ b/libpurple/protocols/qq/qq_trans.h
@@ -30,7 +30,7 @@
void qq_send_trans_append(qq_data *qd, guint8 *buf, gint bus_len, guint16 cmd, guint16 seq);
void qq_send_trans_remove(qq_data *qd, gpointer data);
-gpointer qq_send_trans_find(qq_data *qd, guint16 seq);
+gpointer qq_send_trans_find(qq_data *qd, guint16 cmd, guint16 seq);
void qq_send_trans_remove_all(qq_data *qd);
gint qq_send_trans_scan(qq_data *qd, gint *start, guint8 *buf, gint maxlen, guint16 *cmd, gint *retries);