pidgin.openq: 8c50cfe6: 2008.09.19 - ccpaging <ccpaging(at)gmail...
csyfek at gmail.com
csyfek at gmail.com
Fri Sep 19 10:50:34 EDT 2008
-----------------------------------------------------------------
Revision: 8c50cfe68a5cab6521acc54fedd6797e6c8b863f
Ancestor: f962fe110e106e4da1e9e5c101204f05f378847d
Author: csyfek at gmail.com
Date: 2008-09-19T14:46:41
Branch: im.pidgin.pidgin.openq
URL: http://d.pidgin.im/viewmtn/revision/info/8c50cfe68a5cab6521acc54fedd6797e6c8b863f
Deleted entries:
libpurple/protocols/qq/sys_msg.c
libpurple/protocols/qq/sys_msg.h
Modified files:
libpurple/protocols/qq/ChangeLog
libpurple/protocols/qq/Makefile.am
libpurple/protocols/qq/Makefile.mingw
libpurple/protocols/qq/buddy_info.c
libpurple/protocols/qq/buddy_info.h
libpurple/protocols/qq/buddy_list.c
libpurple/protocols/qq/buddy_opt.c
libpurple/protocols/qq/buddy_opt.h
libpurple/protocols/qq/group.c
libpurple/protocols/qq/group_internal.c
libpurple/protocols/qq/group_join.c
libpurple/protocols/qq/group_join.h
libpurple/protocols/qq/group_opt.c
libpurple/protocols/qq/header_info.c
libpurple/protocols/qq/header_info.h
libpurple/protocols/qq/im.c
libpurple/protocols/qq/packet_parse.c
libpurple/protocols/qq/qq.c libpurple/protocols/qq/qq.h
libpurple/protocols/qq/qq_network.c
libpurple/protocols/qq/qq_process.c
libpurple/protocols/qq/qq_process.h
libpurple/protocols/qq/qq_trans.c
ChangeLog:
2008.09.19 - ccpaging <ccpaging(at)gmail.com>
* Rewrite buddy modify info, there is a ticket for this problem
* Use ship32 to trans action code between request packet and reply packet process
-------------- next part --------------
============================================================
--- libpurple/protocols/qq/ChangeLog d6669d0d61d0e5bd3aae1804b1457e86c2cc3c25
+++ libpurple/protocols/qq/ChangeLog 41cba40cf8042b37628ca0c7e4eda546d980903b
@@ -1,3 +1,7 @@
+2008.09.19 - ccpaging <ccpaging(at)gmail.com>
+ * Rewrite buddy modify info, there is a ticket for this problem
+ * Use ship32 to trans action code between request packet and reply packet process
+
2008.09.15 - csyfek <csyfek(at)gmail.com>
* im.pidgin.pidgin.openq branch
============================================================
--- libpurple/protocols/qq/Makefile.am fed4df19dbb26165288380bca5a1690fc6080ec4
+++ libpurple/protocols/qq/Makefile.am 2b1030056344af9a423a29ad3a8ca21831baf583
@@ -54,8 +54,6 @@ QQSOURCES = \
send_file.h \
qq_trans.c \
qq_trans.h \
- sys_msg.c \
- sys_msg.h \
utils.c \
utils.h
============================================================
--- libpurple/protocols/qq/Makefile.mingw 191eb1afcc761822b86b98cd9ab3f1fb7ded2a34
+++ libpurple/protocols/qq/Makefile.mingw bfdbb323f7edc788f1e3ce2ed7f3731791b4de5a
@@ -64,7 +64,6 @@ C_SRC = \
qq_process.c \
qq_trans.c \
send_file.c \
- sys_msg.c \
utils.c
OBJECTS = $(C_SRC:%.c=%.o)
============================================================
--- libpurple/protocols/qq/buddy_info.c d6c8cba2a6f8f74296de423942273c94a4f1b815
+++ libpurple/protocols/qq/buddy_info.c 20ae76b726968ba91406b83eabe311b503650f6b
@@ -36,29 +36,6 @@
#include "qq_base.h"
#include "qq_network.h"
-#define QQ_PRIMARY_INFORMATION _("Primary Information")
-#define QQ_ADDITIONAL_INFORMATION _("Additional Information")
-#define QQ_INTRO _("Personal Introduction")
-#define QQ_NUMBER _("QQ Number")
-#define QQ_NICKNAME _("Nickname")
-#define QQ_NAME _("Name")
-#define QQ_AGE _("Age")
-#define QQ_GENDER _("Gender")
-#define QQ_COUNTRY _("Country/Region")
-#define QQ_PROVINCE _("Province/State")
-#define QQ_CITY _("City")
-#define QQ_HOROSCOPE _("Horoscope Symbol")
-#define QQ_OCCUPATION _("Occupation")
-#define QQ_ZODIAC _("Zodiac Sign")
-#define QQ_BLOOD _("Blood Type")
-#define QQ_COLLEGE _("College")
-#define QQ_EMAIL _("Email")
-#define QQ_ADDRESS _("Address")
-#define QQ_ZIPCODE _("Zipcode")
-#define QQ_CELL _("Cellphone Number")
-#define QQ_TELEPHONE _("Phone Number")
-#define QQ_HOMEPAGE _("Homepage")
-
#define QQ_HOROSCOPE_SIZE 13
static const gchar *horoscope_names[] = {
"-", N_("Aquarius"), N_("Pisces"), N_("Aries"), N_("Taurus"),
@@ -78,223 +55,166 @@ static const gchar *blood_types[] = {
"-", "A", "B", "O", "AB", N_("Other")
};
-#define QQ_GENDER_SIZE 2
+#define QQ_PUBLISH_SIZE 3
+static const gchar *publish_types[] = {
+ N_("Visible"), N_("Firend Only"), N_("Private")
+};
+
+#define QQ_GENDER_SIZE 3
static const gchar *genders[] = {
+ N_("Private"),
N_("Male"),
- N_("Female")
+ N_("Female"),
};
-#define QQ_CONTACT_FIELDS 37
+static const gchar *genders_zh[] = {
+ N_("-"),
+ N_("\xc4\xd0"),
+ N_("\xc5\xae"),
+};
+
#define QQ_FACES 100
-/* There is no user id stored in the reply packet for information query
- * we have to manually store the query, so that we know the query source */
-typedef struct _qq_info_query {
- guint32 uid;
- gboolean show_window;
- gboolean modify_info;
-} qq_info_query;
+enum {
+ QQ_INFO_UID = 0, QQ_INFO_NICK, QQ_INFO_COUNTRY, QQ_INFO_PROVINCE, QQ_INFO_ZIPCODE,
+ QQ_INFO_ADDR, QQ_INFO_TEL, QQ_INFO_AGE, QQ_INFO_GENDER, QQ_INFO_NAME, QQ_INFO_EMAIL,
+ QQ_INFO_PG_SN, QQ_INFO_PG_NUM, QQ_INFO_PG_SP, QQ_INFO_PG_BASE_NUM, QQ_INFO_PG_TYPE,
+ QQ_INFO_OCCU, QQ_INFO_HOME_PAGE, QQ_INFO_AUTH_TYPE, QQ_INFO_UNKNOW1, QQ_INFO_UNKNOW2,
+ QQ_INFO_FACE, QQ_INFO_MOBILE, QQ_INFO_MOBILE_TYPE, QQ_INFO_INTRO, QQ_INFO_CITY,
+ QQ_INFO_UNKNOW3, QQ_INFO_UNKNOW4, QQ_INFO_UNKNOW5,
+ QQ_INFO_IS_PUB_MOBILE, QQ_INFO_IS_PUB_CONTACT, QQ_INFO_COLLEGE, QQ_INFO_HOROSCOPE,
+ QQ_INFO_ZODIAC, QQ_INFO_BLOOD, QQ_INFO_SHOW, QQ_INFO_UNKNOW6,
+ QQ_INFO_LAST,
+};
-typedef struct _contact_info {
- gchar *uid;
- gchar *nick;
- gchar *country;
- gchar *province;
- gchar *zipcode;
- gchar *address;
- gchar *tel;
- gchar *age;
- gchar *gender;
- gchar *name;
- gchar *email;
- gchar *pager_sn;
- gchar *pager_num;
- gchar *pager_sp;
- gchar *pager_base_num;
- gchar *pager_type;
- gchar *occupation;
- gchar *homepage;
- gchar *auth_type;
- gchar *unknown1;
- gchar *unknown2;
- gchar *face;
- gchar *hp_num;
- gchar *hp_type;
- gchar *intro;
- gchar *city;
- gchar *unknown3;
- gchar *unknown4;
- gchar *unknown5;
- gchar *is_open_hp;
- gchar *is_open_contact;
- gchar *college;
- gchar *horoscope;
- gchar *zodiac;
- gchar *blood;
- gchar *qq_show;
- gchar *unknown6; /* always 0x2D */
-} contact_info;
+enum {
+ QQ_FIELD_UNUSED = 0, QQ_FIELD_BASE, QQ_FIELD_EXT, QQ_FIELD_CONTACT, QQ_FIELD_ADDR
+};
-/* We get an info packet on ourselves before we modify our information.
- * Even though not all of the information is modifiable, it still
- * all needs to be there when we send out the modify info packet */
-typedef struct _modify_info_data {
- PurpleConnection *gc;
- contact_info *info;
-} modify_info_data;
+enum {
+ QQ_FIELD_LABEL = 0, QQ_FIELD_STRING, QQ_FIELD_MULTI, QQ_FIELD_BOOL, QQ_FIELD_CHOICE,
+};
-/* return -1 as a sentinel */
-static gint choice_index(const gchar *value, const gchar **choice, gint choice_size)
-{
- gint len, i;
+typedef struct {
+ int iclass;
+ int type;
+ char *id;
+ char *text;
+ const gchar **choice;
+ int choice_size;
+} QQ_FIELD_INFO;
- len = strlen(value);
- if (len > 3 || len == 0) return -1;
- for (i = 0; i < len; i++) {
- if (!g_ascii_isdigit(value[i]))
- return -1;
- }
- i = strtol(value, NULL, 10);
- if (i >= choice_size)
- return -1;
+static const QQ_FIELD_INFO field_infos[] = {
+ { QQ_FIELD_BASE, QQ_FIELD_STRING, "uid", N_("QQ Number"), NULL, 0 },
+ { QQ_FIELD_BASE, QQ_FIELD_STRING, "nick", N_("Nickname"), NULL, 0 },
+ { QQ_FIELD_ADDR, QQ_FIELD_STRING, "country", N_("Country/Region"), NULL, 0 },
+ { QQ_FIELD_ADDR, QQ_FIELD_STRING, "province", N_("Province/State"), NULL, 0 },
+ { QQ_FIELD_ADDR, QQ_FIELD_STRING, "zipcode", N_("Zipcode"), NULL, 0 },
+ { QQ_FIELD_ADDR, QQ_FIELD_STRING, "address", N_("Address"), NULL, 0 },
+ { QQ_FIELD_CONTACT, QQ_FIELD_STRING, "tel", N_("Phone Number"), NULL, 0 },
+ { QQ_FIELD_BASE, QQ_FIELD_STRING, "age", N_("Age"), NULL, 0 },
+ { QQ_FIELD_BASE, QQ_FIELD_CHOICE, "gender", N_("Gender"), genders, QQ_GENDER_SIZE },
+ { QQ_FIELD_BASE, QQ_FIELD_STRING, "name", N_("Name"), NULL, 0 },
+ { QQ_FIELD_CONTACT, QQ_FIELD_STRING, "email", N_("Email"), NULL, 0 },
+ { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "pg_sn", "Pager Serial Num", NULL, 0 },
+ { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "pg_num", "Pager Num", NULL, 0 },
+ { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "pg_sp", "Pager Serivce Provider", NULL, 0 },
+ { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "pg_sta", "Pager Station Num", NULL, 0 },
+ { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "pg_type", "Pager Type", NULL, 0 },
+ { QQ_FIELD_BASE, QQ_FIELD_STRING, "occupation", N_("Occupation"), NULL, 0 },
+ { QQ_FIELD_CONTACT, QQ_FIELD_STRING, "homepage", N_("Homepage"), NULL, 0 },
+ { QQ_FIELD_BASE, QQ_FIELD_BOOL, "auth", N_("Authorize adding"), NULL, 0 },
+ { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "unknow1", "Unknow1", NULL, 0 },
+ { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "unknow2", "Unknow2", NULL, 0 },
+ { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "face", "Face", NULL, 0 },
+ { QQ_FIELD_CONTACT, QQ_FIELD_STRING, "mobile", N_("Cellphone Number"), NULL, 0 },
+ { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "mobile_type","Cellphone Type", NULL, 0 },
+ { QQ_FIELD_BASE, QQ_FIELD_MULTI, "intro", N_("Personal Introduction"), NULL, 0 },
+ { QQ_FIELD_ADDR, QQ_FIELD_STRING, "city", N_("City/Area"), NULL, 0 },
+ { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "unknow3", "Unknow3", NULL, 0 },
+ { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "unknow4", "Unknow4", NULL, 0 },
+ { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "unknow5", "Unknow5", NULL, 0 },
+ { QQ_FIELD_UNUSED, QQ_FIELD_CHOICE, "pub_mobile", N_("Publish Mobile"), publish_types, QQ_PUBLISH_SIZE },
+ { QQ_FIELD_CONTACT, QQ_FIELD_CHOICE, "pub_contact", N_("Publish Contact"), publish_types, QQ_PUBLISH_SIZE },
+ { QQ_FIELD_EXT, QQ_FIELD_STRING, "college", N_("College"), NULL, 0 },
+ { QQ_FIELD_EXT, QQ_FIELD_CHOICE, "horoscope", N_("Horoscope"), horoscope_names, QQ_HOROSCOPE_SIZE },
+ { QQ_FIELD_EXT, QQ_FIELD_CHOICE, "zodiac", N_("Zodiac"), zodiac_names, QQ_ZODIAC_SIZE },
+ { QQ_FIELD_EXT, QQ_FIELD_CHOICE, "blood", N_("Blood"), blood_types, QQ_BLOOD_SIZE },
+ { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "qq_show", "QQ Show", NULL, 0 },
+ { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "unknow6", "Unknow6", NULL, 0 }
+};
- return i;
-}
+typedef struct _modify_info_request {
+ PurpleConnection *gc;
+ int iclass;
+ gchar **segments;
+} modify_info_request;
-/* return should be freed */
-static gchar *field_value(const gchar *field, const gchar **choice, gint choice_size)
+#ifdef DEBUG
+static void info_debug(gchar **segments)
{
- gint index, len;
-
- len = strlen(field);
- if (len == 0) {
- return NULL;
- } else if (choice != NULL) {
- /* some choice fields are also customizable */
- index = choice_index(field, choice, choice_size);
- if (index == -1) {
- if (strcmp(field, "-") != 0) {
- return qq_to_utf8(field, QQ_CHARSET_DEFAULT);
- } else {
- return NULL;
- }
- /* else ASCIIized index */
- } else {
- if (strcmp(choice[index], "-") != 0)
- return g_strdup(choice[index]);
- else
- return NULL;
+ int index;
+ gchar *utf8_str;
+ for (index = 0; segments[index] != NULL && index < QQ_INFO_LAST; index++) {
+ if (field_infos[index].type == QQ_FIELD_STRING
+ || field_infos[index].type == QQ_FIELD_LABEL
+ || field_infos[index].type == QQ_FIELD_MULTI
+ || index == QQ_INFO_GENDER) {
+ utf8_str = qq_to_utf8(segments[index], QQ_CHARSET_DEFAULT);
+ purple_debug_info("QQ_BUDDY_INFO", "%s: %s\n", field_infos[index]. text, utf8_str);
+ g_free(utf8_str);
+ continue;
}
- } else {
- if (strcmp(field, "-") != 0) {
- return qq_to_utf8(field, QQ_CHARSET_DEFAULT);
- } else {
- return NULL;
- }
+ purple_debug_info("QQ_BUDDY_INFO", "%s: %s\n", field_infos[index]. text, segments[index]);
}
}
+#endif
-static gboolean append_field_value(PurpleNotifyUserInfo *user_info, const gchar *field,
- const gchar *title, const gchar **choice, gint choice_size)
+static void info_display_only(PurpleConnection *gc, gchar **segments)
{
- gchar *value = field_value(field, choice, choice_size);
+ PurpleNotifyUserInfo *user_info;
+ gchar *utf8_value;
+ int index;
+ int choice_num;
- if (value != NULL) {
- purple_notify_user_info_add_pair(user_info, title, value);
- g_free(value);
+ user_info = purple_notify_user_info_new();
- return TRUE;
- }
+ for (index = 1; segments[index] != NULL && index < QQ_INFO_LAST; index++) {
+ if (field_infos[index].iclass == QQ_FIELD_UNUSED) {
+ continue;
+ }
+ switch (field_infos[index].type) {
+ case QQ_FIELD_BOOL:
+ purple_notify_user_info_add_pair(user_info, field_infos[index].text,
+ strtol(segments[index], NULL, 10) ? _("True") : _("False"));
+ break;
+ case QQ_FIELD_CHOICE:
+ choice_num = strtol(segments[index], NULL, 10);
+ if (choice_num < 0 || choice_num >= field_infos[index].choice_size) choice_num = 0;
- return FALSE;
-}
-
-static PurpleNotifyUserInfo *
- info_to_notify_user_info(const contact_info *info)
-{
- PurpleNotifyUserInfo *user_info = purple_notify_user_info_new();
- const gchar *intro;
- gboolean has_extra_info = FALSE;
-
- purple_notify_user_info_add_pair(user_info, QQ_NUMBER, info->uid);
-
- append_field_value(user_info, info->nick, QQ_NICKNAME, NULL, 0);
- append_field_value(user_info, info->name, QQ_NAME, NULL, 0);
- append_field_value(user_info, info->age, QQ_AGE, NULL, 0);
- append_field_value(user_info, info->gender, QQ_GENDER, genders, QQ_GENDER_SIZE);
- append_field_value(user_info, info->country, QQ_COUNTRY, NULL, 0);
- append_field_value(user_info, info->province, QQ_PROVINCE, NULL, 0);
- append_field_value(user_info, info->city, QQ_CITY, NULL, 0);
-
- purple_notify_user_info_add_section_header(user_info, QQ_ADDITIONAL_INFORMATION);
-
- has_extra_info |= append_field_value(user_info, info->horoscope, QQ_HOROSCOPE, horoscope_names, QQ_HOROSCOPE_SIZE);
- has_extra_info |= append_field_value(user_info, info->occupation, QQ_OCCUPATION, NULL, 0);
- has_extra_info |= append_field_value(user_info, info->zodiac, QQ_ZODIAC, zodiac_names, QQ_ZODIAC_SIZE);
- has_extra_info |= append_field_value(user_info, info->blood, QQ_BLOOD, blood_types, QQ_BLOOD_SIZE);
- has_extra_info |= append_field_value(user_info, info->college, QQ_COLLEGE, NULL, 0);
- has_extra_info |= append_field_value(user_info, info->email, QQ_EMAIL, NULL, 0);
- has_extra_info |= append_field_value(user_info, info->address, QQ_ADDRESS, NULL, 0);
- has_extra_info |= append_field_value(user_info, info->zipcode, QQ_ZIPCODE, NULL, 0);
- has_extra_info |= append_field_value(user_info, info->hp_num, QQ_CELL, NULL, 0);
- has_extra_info |= append_field_value(user_info, info->tel, QQ_TELEPHONE, NULL, 0);
- has_extra_info |= append_field_value(user_info, info->homepage, QQ_HOMEPAGE, NULL, 0);
-
- if (!has_extra_info)
- purple_notify_user_info_remove_last_item(user_info);
-
- intro = field_value(info->intro, NULL, 0);
- if (intro) {
- purple_notify_user_info_add_pair(user_info, QQ_INTRO, intro);
+ purple_notify_user_info_add_pair(user_info, field_infos[index].text, field_infos[index].choice[choice_num]);
+ break;
+ case QQ_FIELD_LABEL:
+ case QQ_FIELD_STRING:
+ case QQ_FIELD_MULTI:
+ default:
+ if (strlen(segments[index]) != 0) {
+ utf8_value = qq_to_utf8(segments[index], QQ_CHARSET_DEFAULT);
+ purple_notify_user_info_add_pair(user_info, field_infos[index].text, utf8_value);
+ g_free(utf8_value);
+ }
+ break;
+ }
}
- /* for debugging */
- /*
- g_string_append_printf(info_text, "<br /><br /><b>%s</b><br />", "Miscellaneous");
- append_field_value(info_text, info->pager_sn, "pager_sn", NULL, 0);
- append_field_value(info_text, info->pager_num, "pager_num", NULL, 0);
- append_field_value(info_text, info->pager_sp, "pager_sp", NULL, 0);
- append_field_value(info_text, info->pager_base_num, "pager_base_num", NULL, 0);
- append_field_value(info_text, info->pager_type, "pager_type", NULL, 0);
- append_field_value(info_text, info->auth_type, "auth_type", NULL, 0);
- append_field_value(info_text, info->unknown1, "unknown1", NULL, 0);
- append_field_value(info_text, info->unknown2, "unknown2", NULL, 0);
- append_field_value(info_text, info->face, "face", NULL, 0);
- append_field_value(info_text, info->hp_type, "hp_type", NULL, 0);
- append_field_value(info_text, info->unknown3, "unknown3", NULL, 0);
- append_field_value(info_text, info->unknown4, "unknown4", NULL, 0);
- append_field_value(info_text, info->unknown5, "unknown5", NULL, 0);
- append_field_value(info_text, info->is_open_hp, "is_open_hp", NULL, 0);
- append_field_value(info_text, info->is_open_contact, "is_open_contact", NULL, 0);
- append_field_value(info_text, info->qq_show, "qq_show", NULL, 0);
- append_field_value(info_text, info->unknown6, "unknown6", NULL, 0);
- */
+ purple_notify_userinfo(gc, segments[0], user_info, NULL, NULL);
- return user_info;
+ purple_notify_user_info_destroy(user_info);
+ g_strfreev(segments);
}
-/* send a packet to get detailed information of uid */
-void qq_send_packet_get_info(PurpleConnection *gc, guint32 uid, gboolean show_window)
-{
- qq_data *qd;
- gchar uid_str[11];
- qq_info_query *query;
-
- g_return_if_fail(uid != 0);
-
- qd = (qq_data *) gc->proto_data;
- g_snprintf(uid_str, sizeof(uid_str), "%d", uid);
- qq_send_cmd(gc, QQ_CMD_GET_BUDDY_INFO, (guint8 *) uid_str, strlen(uid_str));
-
- query = g_new0(qq_info_query, 1);
- query->uid = uid;
- query->show_window = show_window;
- query->modify_info = FALSE;
- qd->info_query = g_list_append(qd->info_query, query);
-}
-
void qq_request_buddy_info(PurpleConnection *gc, guint32 uid,
- gint update_class, guint32 ship32)
+ gint update_class, int action)
{
qq_data *qd;
gchar raw_data[16] = {0};
@@ -304,399 +224,216 @@ void qq_request_buddy_info(PurpleConnect
qd = (qq_data *) gc->proto_data;
g_snprintf(raw_data, sizeof(raw_data), "%d", uid);
qq_send_cmd_mess(gc, QQ_CMD_GET_BUDDY_INFO, (guint8 *) raw_data, strlen(raw_data),
- update_class, ship32);
+ update_class, action);
}
-/* set up the fields requesting personal information and send a get_info packet
- * for myself */
-void qq_prepare_modify_info(PurpleConnection *gc)
-{
- qq_data *qd;
- GList *ql;
- qq_info_query *query;
-
- qd = (qq_data *) gc->proto_data;
- qq_send_packet_get_info(gc, qd->uid, FALSE);
- /* traverse backwards so we get the most recent info_query */
- for (ql = g_list_last(qd->info_query); ql != NULL; ql = g_list_previous(ql)) {
- query = ql->data;
- if (query->uid == qd->uid)
- query->modify_info = TRUE;
- }
-}
-
/* send packet to modify personal information */
-static void qq_send_packet_modify_info(PurpleConnection *gc, contact_info *info)
+static void request_modify_info(PurpleConnection *gc, gchar **segments)
{
gint bytes = 0;
guint8 raw_data[MAX_PACKET_SIZE - 128] = {0};
guint8 bar;
+ gchar *join;
- g_return_if_fail(info != NULL);
+ g_return_if_fail(segments != NULL);
bar = 0x1f;
bytes += qq_put8(raw_data + bytes, bar);
+ bytes += qq_put8(raw_data + bytes, bar);
/* important! skip the first uid entry */
- /*
- for (i = 1; i < QQ_CONTACT_FIELDS; i++) {
- create_packet_b(raw_data, &cursor, bar);
- create_packet_data(raw_data, &cursor, (guint8 *) segments[i], strlen(segments[i]));
- }
- */
- /* uid */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->uid, strlen(info->uid));
- /* nick */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->nick, strlen(info->nick));
- /* country */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->country, strlen(info->country));
- /* province */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->province, strlen(info->province));
- /* zipcode */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->zipcode, strlen(info->zipcode));
- /* address */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->address, strlen(info->address));
- /* tel */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->tel, strlen(info->tel));
- /* age */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->age, strlen(info->age));
- /* gender */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->gender, strlen(info->gender));
- /* name */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->name, strlen(info->name));
- /* email */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->email, strlen(info->email));
- /* pager_sn */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->pager_sn, strlen(info->pager_sn));
- /* pager_num */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->pager_num, strlen(info->pager_num));
- /* pager_sp */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->pager_sp, strlen(info->pager_sp));
- /* pager_base_num */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->pager_base_num, strlen(info->pager_base_num));
- /* pager_type */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->pager_type, strlen(info->pager_type));
- /* occupation */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->occupation, strlen(info->occupation));
- /* homepage */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->homepage, strlen(info->homepage));
- /* auth_type */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->auth_type, strlen(info->auth_type));
- /* unknown1 */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->unknown1, strlen(info->unknown1));
- /* unknown2 */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->unknown2, strlen(info->unknown2));
- /* face */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->face, strlen(info->face));
- /* hp_num */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->hp_num, strlen(info->hp_num));
- /* hp_type */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->hp_type, strlen(info->hp_type));
- /* intro */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->intro, strlen(info->intro));
- /* city */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->city, strlen(info->city));
- /* unknown3 */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->unknown3, strlen(info->unknown3));
- /* unknown4 */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->unknown4, strlen(info->unknown4));
- /* unknown5 */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->unknown5, strlen(info->unknown5));
- /* is_open_hp */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->is_open_hp, strlen(info->is_open_hp));
- /* is_open_contact */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->is_open_contact, strlen(info->is_open_contact));
- /* college */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->college, strlen(info->college));
- /* horoscope */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->horoscope, strlen(info->horoscope));
- /* zodiac */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->zodiac, strlen(info->zodiac));
- /* blood */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->blood, strlen(info->blood));
- /* qq_show */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->qq_show, strlen(info->qq_show));
- /* unknown6 */
- bytes += qq_put8(raw_data + bytes, bar);
- bytes += qq_putdata(raw_data + bytes, (guint8 *)info->unknown6, strlen(info->unknown6));
+ join = g_strjoinv("\x1f", segments +1);
+ bytes += qq_putdata(raw_data + bytes, (guint8 *)join, strlen(join));
+ g_free(join);
bytes += qq_put8(raw_data + bytes, bar);
+ /* qq_show_packet("request_modify_info", raw_data, bytes); */
qq_send_cmd(gc, QQ_CMD_UPDATE_INFO, raw_data, bytes);
-
}
-static void modify_info_cancel_cb(modify_info_data *mid)
+static void info_modify_cancel_cb(modify_info_request *info_request)
{
- qq_data *qd;
-
- qd = (qq_data *) mid->gc->proto_data;
- qd->modifying_info = FALSE;
-
- g_strfreev((gchar **) mid->info);
- g_free(mid);
+ g_strfreev(info_request->segments);
+ g_free(info_request);
}
-static gchar *parse_field(PurpleRequestField *field, gboolean choice)
-{
- gchar *value;
-
- if (choice) {
- value = g_strdup_printf("%d", purple_request_field_choice_get_value(field));
- } else {
- value = (gchar *) purple_request_field_string_get_value(field);
- if (value == NULL)
- value = g_strdup("-");
- else
- value = utf8_to_qq(value, QQ_CHARSET_DEFAULT);
- }
-
- return value;
-}
-
/* parse fields and send info packet */
-static void modify_info_ok_cb(modify_info_data *mid, PurpleRequestFields *fields)
+static void info_modify_ok_cb(modify_info_request *info_request, PurpleRequestFields *fields)
{
PurpleConnection *gc;
qq_data *qd;
- GList *groups;
- contact_info *info;
+ gchar **segments;
+ int index;
+ const char *utf8_str;
+ gchar *value;
+ int choice_num;
- gc = mid->gc;
+ gc = info_request->gc;
+ g_return_if_fail(gc != NULL && info_request->gc);
qd = (qq_data *) gc->proto_data;
- qd->modifying_info = FALSE;
+ segments = info_request->segments;
+ g_return_if_fail(segments != NULL);
- info = mid->info;
-
- groups = purple_request_fields_get_groups(fields);
- while (groups != NULL) {
- PurpleRequestFieldGroup *group = groups->data;
- const char *g_name = purple_request_field_group_get_title(group);
- GList *fields = purple_request_field_group_get_fields(group);
-
- if (g_name == NULL)
+ for (index = 1; segments[index] != NULL && index < QQ_INFO_LAST; index++) {
+ if (field_infos[index].iclass == QQ_FIELD_UNUSED) {
continue;
+ }
+ if (!purple_request_fields_exists(fields, field_infos[index].id)) {
+ continue;
+ }
+ switch (field_infos[index].type) {
+ case QQ_FIELD_BOOL:
+ value = purple_request_fields_get_bool(fields, field_infos[index].id)
+ ? g_strdup("1") : g_strdup("0");
+ g_free(segments[index]);
+ segments[index] = value;
+ break;
+ case QQ_FIELD_CHOICE:
+ choice_num = purple_request_fields_get_choice(fields, field_infos[index].id);
+ if (choice_num < 0 || choice_num >= field_infos[index].choice_size) choice_num = 0;
- while (fields != NULL) {
- PurpleRequestField *field = fields->data;
- const char *f_id = purple_request_field_get_id(field);
-
- if (!strcmp(QQ_PRIMARY_INFORMATION, g_name)) {
-
- if (!strcmp(f_id, "uid"))
- info->uid = parse_field(field, FALSE);
- else if (!strcmp(f_id, "nick"))
- info->nick = parse_field(field, FALSE);
- else if (!strcmp(f_id, "name"))
- info->name = parse_field(field, FALSE);
- else if (!strcmp(f_id, "age"))
- info->age = parse_field(field, FALSE);
- else if (!strcmp(f_id, "gender"))
- info->gender = parse_field(field, TRUE);
- else if (!strcmp(f_id, "country"))
- info->country = parse_field(field, FALSE);
- else if (!strcmp(f_id, "province"))
- info->province = parse_field(field, FALSE);
- else if (!strcmp(f_id, "city"))
- info->city = parse_field(field, FALSE);
-
- } else if (!strcmp(QQ_ADDITIONAL_INFORMATION, g_name)) {
-
- if (!strcmp(f_id, "horoscope"))
- info->horoscope = parse_field(field, TRUE);
- else if (!strcmp(f_id, "occupation"))
- info->occupation = parse_field(field, FALSE);
- else if (!strcmp(f_id, "zodiac"))
- info->zodiac = parse_field(field, TRUE);
- else if (!strcmp(f_id, "blood"))
- info->blood = parse_field(field, TRUE);
- else if (!strcmp(f_id, "college"))
- info->college = parse_field(field, FALSE);
- else if (!strcmp(f_id, "email"))
- info->email = parse_field(field, FALSE);
- else if (!strcmp(f_id, "address"))
- info->address = parse_field(field, FALSE);
- else if (!strcmp(f_id, "zipcode"))
- info->zipcode = parse_field(field, FALSE);
- else if (!strcmp(f_id, "hp_num"))
- info->hp_num = parse_field(field, FALSE);
- else if (!strcmp(f_id, "tel"))
- info->tel = parse_field(field, FALSE);
- else if (!strcmp(f_id, "homepage"))
- info->homepage = parse_field(field, FALSE);
-
- } else if (!strcmp(QQ_INTRO, g_name)) {
-
- if (!strcmp(f_id, "intro"))
- info->intro = parse_field(field, FALSE);
-
- }
-
- fields = fields->next;
+ if (index == QQ_INFO_GENDER) {
+ /* QQ Server only recept gender in Chinese */
+ value = g_strdup(genders_zh[choice_num]);
+ } else {
+ value = g_strdup_printf("%d", choice_num);
+ }
+ g_free(segments[index]);
+ segments[index] = value;
+ break;
+ case QQ_FIELD_LABEL:
+ case QQ_FIELD_STRING:
+ case QQ_FIELD_MULTI:
+ default:
+ utf8_str = purple_request_fields_get_string(fields, field_infos[index].id);
+ if (utf8_str == NULL) {
+ value = g_strdup("-");
+ } else {
+ value = utf8_to_qq(utf8_str, QQ_CHARSET_DEFAULT);
+ if (value == NULL) value = g_strdup("-");
+ }
+ g_free(segments[index]);
+ segments[index] = value;
+ break;
}
-
- groups = groups->next;
}
+ request_modify_info(gc, segments);
- /* This casting looks like a horrible idea to me -DAA
- * yes, rewritten -s3e
- * qq_send_packet_modify_info(gc, (gchar **) info);
- */
- qq_send_packet_modify_info(gc, info);
-
- g_strfreev((gchar **) mid->info);
- g_free(mid);
+ g_strfreev(segments);
+ g_free(info_request);
}
-static PurpleRequestFieldGroup *setup_field_group(PurpleRequestFields *fields, const gchar *title)
+static void field_request_new(PurpleRequestFieldGroup *group, gint index, gchar **segments)
{
- PurpleRequestFieldGroup *group;
-
- group = purple_request_field_group_new(title);
- purple_request_fields_add_group(fields, group);
-
- return group;
-}
-
-static void add_string_field_to_group(PurpleRequestFieldGroup *group,
- const gchar *id, const gchar *title, const gchar *value)
-{
PurpleRequestField *field;
gchar *utf8_value;
+ int choice_num;
+ int i;
- utf8_value = qq_to_utf8(value, QQ_CHARSET_DEFAULT);
- field = purple_request_field_string_new(id, title, utf8_value, FALSE);
- purple_request_field_group_add_field(group, field);
- g_free(utf8_value);
-}
+ g_return_if_fail(index >=0 && segments[index] != NULL && index < QQ_INFO_LAST);
-static void add_choice_field_to_group(PurpleRequestFieldGroup *group,
- const gchar *id, const gchar *title, const gchar *value,
- const gchar **choice, gint choice_size)
-{
- PurpleRequestField *field;
- gint i, index;
+ switch (field_infos[index].type) {
+ case QQ_FIELD_STRING:
+ case QQ_FIELD_MULTI:
+ utf8_value = qq_to_utf8(segments[index], QQ_CHARSET_DEFAULT);
+ if (field_infos[index].type == QQ_FIELD_STRING) {
+ field = purple_request_field_string_new(
+ field_infos[index].id, field_infos[index].text, utf8_value, FALSE);
+ } else {
+ field = purple_request_field_string_new(
+ field_infos[index].id, field_infos[index].text, utf8_value, TRUE);
+ }
+ purple_request_field_group_add_field(group, field);
+ g_free(utf8_value);
+ break;
+ case QQ_FIELD_BOOL:
+ field = purple_request_field_bool_new(
+ field_infos[index].id, field_infos[index].text,
+ strtol(segments[index], NULL, 10) ? TRUE : FALSE);
+ purple_request_field_group_add_field(group, field);
+ break;
+ case QQ_FIELD_CHOICE:
+ choice_num = strtol(segments[index], NULL, 10);
+ if (choice_num < 0 || choice_num >= field_infos[index].choice_size) choice_num = 0;
- index = choice_index(value, choice, choice_size);
- field = purple_request_field_choice_new(id, title, index);
- for (i = 0; i < choice_size; i++)
- purple_request_field_choice_add(field, choice[i]);
- purple_request_field_group_add_field(group, field);
+ if (index == QQ_INFO_GENDER && strlen(segments[index]) != 0) {
+ for (i = 0; i < QQ_GENDER_SIZE; i++) {
+ if (strcmp(segments[index], genders_zh[i]) == 0) {
+ choice_num = i;
+ }
+ }
+ }
+ field = purple_request_field_choice_new(
+ field_infos[index].id, field_infos[index].text, choice_num);
+ for (i = 0; i < field_infos[index].choice_size; i++) {
+ purple_request_field_choice_add(field, field_infos[index].choice[i]);
+ }
+ purple_request_field_group_add_field(group, field);
+ break;
+ case QQ_FIELD_LABEL:
+ default:
+ field = purple_request_field_label_new(field_infos[index].id, segments[index]);
+ purple_request_field_group_add_field(group, field);
+ break;
+ }
}
-/* take the info returned by a get_info packet for myself and set up a request form */
-static void create_modify_info_dialogue(PurpleConnection *gc, const contact_info *info)
+static void info_modify_dialogue(PurpleConnection *gc, gchar **segments, int iclass)
{
qq_data *qd;
PurpleRequestFieldGroup *group;
PurpleRequestFields *fields;
- PurpleRequestField *field;
- modify_info_data *mid;
+ modify_info_request *info_request;
+ gchar *utf8_title, *utf8_prim;
+ int index;
- /* so we only have one dialog open at a time */
qd = (qq_data *) gc->proto_data;
- if (!qd->modifying_info) {
- qd->modifying_info = TRUE;
+ /* Keep one dialog once a time */
+ purple_request_close_with_handle(gc);
- fields = purple_request_fields_new();
+ fields = purple_request_fields_new();
+ group = purple_request_field_group_new(NULL);
+ purple_request_fields_add_group(fields, group);
- group = setup_field_group(fields, QQ_PRIMARY_INFORMATION);
- field = purple_request_field_string_new("uid", QQ_NUMBER, info->uid, FALSE);
- purple_request_field_group_add_field(group, field);
- purple_request_field_string_set_editable(field, FALSE);
- add_string_field_to_group(group, "nick", QQ_NICKNAME, info->nick);
- add_string_field_to_group(group, "name", QQ_NAME, info->name);
- add_string_field_to_group(group, "age", QQ_AGE, info->age);
- add_choice_field_to_group(group, "gender", QQ_GENDER, info->gender, genders, QQ_GENDER_SIZE);
- add_string_field_to_group(group, "country", QQ_COUNTRY, info->country);
- add_string_field_to_group(group, "province", QQ_PROVINCE, info->province);
- add_string_field_to_group(group, "city", QQ_CITY, info->city);
+ for (index = 1; segments[index] != NULL && index < QQ_INFO_LAST; index++) {
+ if (field_infos[index].iclass != iclass) {
+ continue;
+ }
+ field_request_new(group, index, segments);
+ }
- group = setup_field_group(fields, QQ_ADDITIONAL_INFORMATION);
- add_choice_field_to_group(group, "horoscope", QQ_HOROSCOPE, info->horoscope, horoscope_names, QQ_HOROSCOPE_SIZE);
- add_string_field_to_group(group, "occupation", QQ_OCCUPATION, info->occupation);
- add_choice_field_to_group(group, "zodiac", QQ_ZODIAC, info->zodiac, zodiac_names, QQ_ZODIAC_SIZE);
- add_choice_field_to_group(group, "blood", QQ_BLOOD, info->blood, blood_types, QQ_BLOOD_SIZE);
- add_string_field_to_group(group, "college", QQ_COLLEGE, info->college);
- add_string_field_to_group(group, "email", QQ_EMAIL, info->email);
- add_string_field_to_group(group, "address", QQ_ADDRESS, info->address);
- add_string_field_to_group(group, "zipcode", QQ_ZIPCODE, info->zipcode);
- add_string_field_to_group(group, "hp_num", QQ_CELL, info->hp_num);
- add_string_field_to_group(group, "tel", QQ_TELEPHONE, info->tel);
- add_string_field_to_group(group, "homepage", QQ_HOMEPAGE, info->homepage);
+ switch (iclass) {
+ case QQ_FIELD_CONTACT:
+ utf8_title = g_strdup(_("Modify Contact"));
+ utf8_prim = g_strdup_printf("%s for %s", _("Modify Contact"), segments[0]);
+ case QQ_FIELD_ADDR:
+ utf8_title = g_strdup(_("Modify Address"));
+ utf8_prim = g_strdup_printf("%s for %s", _("Modify Address"), segments[0]);
+ case QQ_FIELD_EXT:
+ utf8_title = g_strdup(_("Modify Extend Information"));
+ utf8_prim = g_strdup_printf("%s for %s", _("Modify Extend Information"), segments[0]);
+ break;
+ case QQ_FIELD_BASE:
+ default:
+ utf8_title = g_strdup(_("Modify Information"));
+ utf8_prim = g_strdup_printf("%s for %s", _("Modify Information"), segments[0]);
+ }
- group = setup_field_group(fields, QQ_INTRO);
- field = purple_request_field_string_new("intro", QQ_INTRO, info->intro, TRUE);
- purple_request_field_group_add_field(group, field);
+ info_request = g_new0(modify_info_request, 1);
+ info_request->gc = gc;
+ info_request->iclass = iclass;
+ info_request->segments = segments;
- /* prepare unmodifiable info */
- mid = g_new0(modify_info_data, 1);
- mid->gc = gc;
- /* QQ_CONTACT_FIELDS+1 so that the array is NULL-terminated and can be g_strfreev()'ed later */
- mid->info = (contact_info *) g_new0(gchar *, QQ_CONTACT_FIELDS+1);
- mid->info->pager_sn = g_strdup(info->pager_sn);
- mid->info->pager_num = g_strdup(info->pager_num);
- mid->info->pager_sp = g_strdup(info->pager_sp);
- mid->info->pager_base_num = g_strdup(info->pager_base_num);
- mid->info->pager_type = g_strdup(info->pager_type);
- mid->info->auth_type = g_strdup(info->auth_type);
- mid->info->unknown1 = g_strdup(info->unknown1);
- mid->info->unknown2 = g_strdup(info->unknown2);
- mid->info->face = g_strdup(info->face);
- mid->info->hp_type = g_strdup(info->hp_type);
- mid->info->unknown3 = g_strdup(info->unknown3);
- mid->info->unknown4 = g_strdup(info->unknown4);
- mid->info->unknown5 = g_strdup(info->unknown5);
- /* TODO stop hiding these 2 */
- mid->info->is_open_hp = g_strdup(info->is_open_hp);
- mid->info->is_open_contact = g_strdup(info->is_open_contact);
- mid->info->qq_show = g_strdup(info->qq_show);
- mid->info->unknown6 = g_strdup(info->unknown6);
+ purple_request_fields(gc, utf8_title, utf8_prim, NULL, fields,
+ _("Update"), G_CALLBACK(info_modify_ok_cb),
+ _("Cancel"), G_CALLBACK(info_modify_cancel_cb),
+ purple_connection_get_account(gc), NULL, NULL,
+ info_request);
- purple_request_fields(gc, _("Modify information"),
- _("Modify information"), NULL, fields,
- _("Update information"), G_CALLBACK(modify_info_ok_cb),
- _("Cancel"), G_CALLBACK(modify_info_cancel_cb),
- purple_connection_get_account(gc), NULL, NULL,
- mid);
- }
+ g_free(utf8_title);
+ g_free(utf8_prim);
}
/* process the reply of modify_info packet */
@@ -715,7 +452,7 @@ void qq_process_modify_info_reply(guint8
}
}
-static void _qq_send_packet_modify_face(PurpleConnection *gc, gint face_num)
+static void request_set_buddy_icon(PurpleConnection *gc, gint face_num)
{
PurpleAccount *account = purple_connection_get_account(gc);
PurplePresence *presence = purple_account_get_presence(account);
@@ -732,11 +469,10 @@ static void _qq_send_packet_modify_face(
}
qd->my_icon = 3 * (face_num - 1) + offset;
- qd->modifying_face = TRUE;
- qq_send_packet_get_info(gc, qd->uid, FALSE);
+ qq_request_buddy_info(gc, qd->uid, 0, QQ_BUDDY_INFO_SET_ICON);
}
-void qq_set_buddy_icon_for_user(PurpleAccount *account, const gchar *who, const gchar *icon_num, const gchar *iconfile)
+static void buddy_local_icon_set(PurpleAccount *account, const gchar *who, const gchar *icon_num, const gchar *iconfile)
{
gchar *data;
gsize len;
@@ -749,7 +485,7 @@ void qq_set_buddy_icon_for_user(PurpleAc
}
/* TODO: custom faces for QQ members and users with level >= 16 */
-void qq_set_my_buddy_icon(PurpleConnection *gc, PurpleStoredImage *img)
+void qq_set_buddy_icon(PurpleConnection *gc, PurpleStoredImage *img)
{
gchar *icon;
gint icon_num;
@@ -796,13 +532,13 @@ void qq_set_my_buddy_icon(PurpleConnecti
}
g_free(errmsg);
/* tell server my icon changed */
- _qq_send_packet_modify_face(gc, icon_num);
+ request_set_buddy_icon(gc, icon_num);
/* display in blist */
- qq_set_buddy_icon_for_user(account, account->username, icon, icon_path);
+ buddy_local_icon_set(account, account->username, icon, icon_path);
}
-static void _qq_update_buddy_icon(PurpleAccount *account, const gchar *name, gint face)
+static void buddy_local_icon_upate(PurpleAccount *account, const gchar *name, gint face)
{
PurpleBuddy *buddy;
gchar *icon_num_str = face_to_icon_str(face);
@@ -820,14 +556,14 @@ static void _qq_update_buddy_icon(Purple
QQ_ICON_PREFIX, icon_num_str,
QQ_ICON_SUFFIX, NULL);
- qq_set_buddy_icon_for_user(account, name, icon_num_str, icon_path);
+ buddy_local_icon_set(account, name, icon_num_str, icon_path);
g_free(icon_path);
}
g_free(icon_num_str);
}
/* after getting info or modify myself, refresh the buddy list accordingly */
-static void qq_refresh_buddy_and_myself(contact_info *info, PurpleConnection *gc)
+static void qq_refresh_buddy_and_myself(gchar **segments, PurpleConnection *gc)
{
PurpleBuddy *b;
qq_data *qd;
@@ -837,11 +573,11 @@ static void qq_refresh_buddy_and_myself(
PurpleAccount *account = purple_connection_get_account(gc);
qd = (qq_data *) gc->proto_data;
- purple_name = uid_to_purple_name(strtol(info->uid, NULL, 10));
+ purple_name = uid_to_purple_name(strtol(segments[QQ_INFO_UID], NULL, 10));
- alias_utf8 = qq_to_utf8(info->nick, QQ_CHARSET_DEFAULT);
- if (qd->uid == strtol(info->uid, NULL, 10)) { /* it is me */
- qd->my_icon = strtol(info->face, NULL, 10);
+ alias_utf8 = qq_to_utf8(segments[QQ_INFO_NICK], QQ_CHARSET_DEFAULT);
+ if (qd->uid == strtol(segments[QQ_INFO_UID], NULL, 10)) { /* it is me */
+ qd->my_icon = strtol(segments[QQ_INFO_FACE], NULL, 10);
if (alias_utf8 != NULL)
purple_account_set_alias(account, alias_utf8);
}
@@ -849,87 +585,73 @@ static void qq_refresh_buddy_and_myself(
b = purple_find_buddy(gc->account, purple_name);
q_bud = (b == NULL) ? NULL : (qq_buddy *) b->proto_data;
if (q_bud != NULL) { /* I have this buddy */
- q_bud->age = strtol(info->age, NULL, 10);
- q_bud->gender = strtol(info->gender, NULL, 10);
- q_bud->face = strtol(info->face, NULL, 10);
+ q_bud->age = strtol(segments[QQ_INFO_AGE], NULL, 10);
+ q_bud->gender = strtol(segments[QQ_INFO_GENDER], NULL, 10);
+ q_bud->face = strtol(segments[QQ_INFO_FACE], NULL, 10);
if (alias_utf8 != NULL)
q_bud->nickname = g_strdup(alias_utf8);
qq_update_buddy_contact(gc, q_bud);
- _qq_update_buddy_icon(gc->account, purple_name, q_bud->face);
+ buddy_local_icon_upate(gc->account, purple_name, q_bud->face);
}
g_free(purple_name);
g_free(alias_utf8);
}
/* process reply to get_info packet */
-void qq_process_get_buddy_info(guint8 *data, gint data_len, PurpleConnection *gc)
+void qq_process_get_buddy_info(guint8 *data, gint data_len, guint32 action, PurpleConnection *gc)
{
- gchar **segments;
- qq_info_query *query;
qq_data *qd;
- contact_info *info;
- GList *list, *query_list;
- PurpleNotifyUserInfo *user_info;
+ gchar **segments;
g_return_if_fail(data != NULL && data_len != 0);
qd = (qq_data *) gc->proto_data;
- list = query_list = NULL;
- info = NULL;
- if (NULL == (segments = split_data(data, data_len, "\x1e", QQ_CONTACT_FIELDS)))
+ if (NULL == (segments = split_data(data, data_len, "\x1e", QQ_INFO_LAST)))
return;
- info = (contact_info *) segments;
- if (qd->modifying_face && strtol(info->face, NULL, 10) != qd->my_icon) {
- gchar *icon = g_strdup_printf("%d", qd->my_icon);
- qd->modifying_face = FALSE;
- g_free(info->face);
- info->face = icon;
- qq_send_packet_modify_info(gc, (contact_info *)segments);
- }
+#ifdef DEBUG
+ info_debug(segments);
+#endif
- qq_refresh_buddy_and_myself(info, gc);
+ if (action == QQ_BUDDY_INFO_SET_ICON) {
+ if (strtol(segments[QQ_INFO_FACE], NULL, 10) != qd->my_icon) {
+ gchar *icon = g_strdup_printf("%d", qd->my_icon);
- query_list = qd->info_query;
- /* ensure we're processing the right query */
- while (query_list) {
- query = (qq_info_query *) query_list->data;
- if (query->uid == atoi(info->uid)) {
- if (query->show_window) {
- user_info = info_to_notify_user_info(info);
- purple_notify_userinfo(gc, info->uid, user_info, NULL, NULL);
- purple_notify_user_info_destroy(user_info);
- } else if (query->modify_info) {
- create_modify_info_dialogue(gc, info);
- }
- qd->info_query = g_list_remove(qd->info_query, qd->info_query->data);
- g_free(query);
- break;
+ g_free(segments[QQ_INFO_FACE]);
+ segments[QQ_INFO_FACE] = icon;
+
+ request_modify_info(gc, segments);
+ qq_refresh_buddy_and_myself(segments, gc);
}
- query_list = query_list->next;
+ g_strfreev(segments);
+ return;
}
- g_strfreev(segments);
-}
-
-void qq_info_query_free(qq_data *qd)
-{
- gint count;
- qq_info_query *p;
-
- g_return_if_fail(qd != NULL);
-
- 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);
- count++;
+ qq_refresh_buddy_and_myself(segments, gc);
+ switch (action) {
+ case QQ_BUDDY_INFO_DISPLAY:
+ info_display_only(gc, segments);
+ break;
+ case QQ_BUDDY_INFO_SET_ICON:
+ break;
+ case QQ_BUDDY_INFO_MODIFY_BASE:
+ info_modify_dialogue(gc, segments, QQ_FIELD_BASE);
+ break;
+ case QQ_BUDDY_INFO_MODIFY_EXT:
+ info_modify_dialogue(gc, segments, QQ_FIELD_EXT);
+ break;
+ case QQ_BUDDY_INFO_MODIFY_ADDR:
+ info_modify_dialogue(gc, segments, QQ_FIELD_ADDR);
+ break;
+ case QQ_BUDDY_INFO_MODIFY_CONTACT:
+ info_modify_dialogue(gc, segments, QQ_FIELD_CONTACT);
+ break;
+ default:
+ g_strfreev(segments);
+ break;
}
- if (count > 0) {
- purple_debug_info("QQ", "%d info queries are freed!\n", count);
- }
+ return;
}
void qq_request_get_level(PurpleConnection *gc, guint32 uid)
============================================================
--- libpurple/protocols/qq/buddy_info.h 1ac122f76dd136bbcd3cb7fb68e90d547f0b0a69
+++ libpurple/protocols/qq/buddy_info.h 9fd1ac8dd9d96be3205a67ac53be1ee106d7ad9d
@@ -70,18 +70,19 @@ enum {
enum {
QQ_BUDDY_INFO_UPDATE_ONLY = 0,
QQ_BUDDY_INFO_DISPLAY,
- QQ_BUDDY_INFO_MODIFY,
+ QQ_BUDDY_INFO_SET_ICON,
+ QQ_BUDDY_INFO_MODIFY_BASE,
+ QQ_BUDDY_INFO_MODIFY_EXT,
+ QQ_BUDDY_INFO_MODIFY_ADDR,
+ QQ_BUDDY_INFO_MODIFY_CONTACT,
};
-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);
+ gint update_class, int action);
+void qq_set_buddy_icon(PurpleConnection *gc, PurpleStoredImage *img);
void qq_process_modify_info_reply(guint8 *data, gint data_len, PurpleConnection *gc);
-void qq_process_get_buddy_info(guint8 *data, gint data_len, PurpleConnection *gc);
-void qq_info_query_free(qq_data *qd);
+void qq_process_get_buddy_info(guint8 *data, gint data_len, guint32 action, PurpleConnection *gc);
+
void qq_request_get_level(PurpleConnection *gc, guint32 uid);
void qq_request_get_buddies_level(PurpleConnection *gc, gint update_class);
void qq_process_get_level_reply(guint8 *buf, gint buf_len, PurpleConnection *gc);
============================================================
--- libpurple/protocols/qq/buddy_list.c 7ecaa1ef8197c4a10c2459438c1235736cdb97fb
+++ libpurple/protocols/qq/buddy_list.c 9b1ed5dfeeed12c2f6879cba8e4e6aecb8398414
@@ -311,8 +311,7 @@ guint16 qq_process_get_buddies_list_repl
}
#if 1
- purple_debug_info("QQ",
- "buddy [%09d]: ext_flag=0x%02x, comm_flag=0x%02x, nick=%s\n",
+ 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
@@ -321,7 +320,7 @@ guint16 qq_process_get_buddies_list_repl
g_free(name);
if (b == NULL) {
- b = qq_add_buddy_by_recv_packet(gc, q_bud->uid, TRUE, FALSE);
+ b = qq_create_buddy(gc, q_bud->uid, TRUE, FALSE);
}
b->proto_data = q_bud;
============================================================
--- libpurple/protocols/qq/buddy_opt.c dd97c76aecca5f5faa6445642a21e74f4aeae891
+++ libpurple/protocols/qq/buddy_opt.c d3534cf0719079b8d8ef27b6e5e1e0f1fd03ea43
@@ -26,6 +26,7 @@
#include "internal.h"
#include "notify.h"
#include "request.h"
+#include "privacy.h"
#include "buddy_info.h"
#include "buddy_list.h"
@@ -52,24 +53,19 @@ enum {
QQ_MY_AUTH_REQUEST = 0x32, /* ASCII value of "2" */
};
-typedef struct _qq_add_buddy_request {
- guint32 uid;
- guint16 seq;
-} qq_add_buddy_request;
-
/* send packet to remove a buddy from my buddy list */
-static void _qq_send_packet_remove_buddy(PurpleConnection *gc, guint32 uid)
+static void request_buddy_remove(PurpleConnection *gc, guint32 uid)
{
gchar uid_str[11];
g_return_if_fail(uid > 0);
g_snprintf(uid_str, sizeof(uid_str), "%d", uid);
- qq_send_cmd(gc, QQ_CMD_DEL_BUDDY, (guint8 *) uid_str, strlen(uid_str));
+ qq_send_cmd(gc, QQ_CMD_BUDDY_REMOVE, (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)
+static void request_buddy_remove_me(PurpleConnection *gc, guint32 uid)
{
guint8 raw_data[16] = {0};
gint bytes = 0;
@@ -78,31 +74,24 @@ static void _qq_send_packet_remove_self_
bytes += qq_put32(raw_data + bytes, uid);
- qq_send_cmd(gc, QQ_CMD_REMOVE_SELF, raw_data, bytes);
+ qq_send_cmd(gc, QQ_CMD_REMOVE_ME, raw_data, bytes);
}
/* try to add a buddy without authentication */
-static void _qq_send_packet_add_buddy(PurpleConnection *gc, guint32 uid)
+static void request_buddy_add_no_auth(PurpleConnection *gc, guint32 uid)
{
- qq_data *qd = (qq_data *) gc->proto_data;
- qq_add_buddy_request *req;
gchar uid_str[11];
g_return_if_fail(uid > 0);
/* we need to send the ascii code of this uid to qq server */
g_snprintf(uid_str, sizeof(uid_str), "%d", uid);
- qq_send_cmd(gc, QQ_CMD_ADD_BUDDY_WO_AUTH, (guint8 *) uid_str, strlen(uid_str));
-
- /* must be set after sending packet to get the correct send_seq */
- req = g_new0(qq_add_buddy_request, 1);
- req->seq = qd->send_seq;
- req->uid = uid;
- qd->add_buddy_request = g_list_append(qd->add_buddy_request, req);
+ qq_send_cmd_mess(gc, QQ_CMD_BUDDY_ADD_NO_AUTH,
+ (guint8 *) uid_str, strlen(uid_str), 0, uid);
}
/* 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)
+static void request_buddy_auth(PurpleConnection *gc, guint32 uid, const gchar response, const gchar *text)
{
gchar *text_qq, uid_str[11];
guint8 bar, *raw_data;
@@ -125,130 +114,256 @@ static void _qq_send_packet_buddy_auth(P
g_free(text_qq);
}
- qq_send_cmd(gc, QQ_CMD_BUDDY_AUTH, raw_data, bytes);
+ qq_send_cmd(gc, QQ_CMD_BUDDY_ADD_AUTH, raw_data, bytes);
}
-static void _qq_send_packet_add_buddy_auth_with_gc_and_uid(gc_and_uid *g, const gchar *text)
+static void request_buddy_add_auth_cb(qq_add_request *add_req, const gchar *text)
{
- PurpleConnection *gc;
- guint32 uid;
- g_return_if_fail(g != NULL);
+ g_return_if_fail(add_req != NULL);
+ if (add_req->gc == NULL || add_req->uid == 0) {
+ g_free(add_req);
+ return;
+ }
- gc = g->gc;
- uid = g->uid;
- g_return_if_fail(uid != 0);
+ request_buddy_auth(add_req->gc, add_req->uid, QQ_MY_AUTH_REQUEST, text);
+ g_free(add_req);
+}
- _qq_send_packet_buddy_auth(gc, uid, QQ_MY_AUTH_REQUEST, text);
- g_free(g);
+/* the real packet to reject and request is sent from here */
+static void buddy_add_deny_reason_cb(qq_add_request *add_req, const gchar *reason)
+{
+ g_return_if_fail(add_req != NULL);
+ if (add_req->gc == NULL || add_req->uid == 0) {
+ g_free(add_req);
+ return;
+ }
+
+ request_buddy_auth(add_req->gc, add_req->uid, QQ_MY_AUTH_REJECT, reason);
+ g_free(add_req);
}
-/* the real packet to reject and request is sent from here */
-static void _qq_reject_add_request_real(gc_and_uid *g, const gchar *reason)
+/* we approve other's request of adding me as friend */
+static void buddy_add_authorize_cb(qq_add_request *add_req)
{
+ g_return_if_fail(add_req != NULL);
+ if (add_req->gc == NULL || add_req->uid != 0) {
+ g_free(add_req);
+ return;
+ }
+
+ request_buddy_auth(add_req->gc, add_req->uid, QQ_MY_AUTH_APPROVE, NULL);
+ g_free(add_req);
+}
+
+/* we reject other's request of adding me as friend */
+static void buddy_add_deny_cb(qq_add_request *add_req)
+{
gint uid;
+ gchar *msg1, *msg2;
PurpleConnection *gc;
+ gchar *purple_name;
- g_return_if_fail(g != NULL);
+ g_return_if_fail(add_req != NULL);
+ if (add_req->gc == NULL || add_req->uid == 0) {
+ g_free(add_req);
+ return;
+ }
- gc = g->gc;
- uid = g->uid;
- g_return_if_fail(uid != 0);
+ gc = add_req->gc;
+ uid = add_req->uid;
- _qq_send_packet_buddy_auth(gc, uid, QQ_MY_AUTH_REJECT, reason);
- g_free(g);
+ msg1 = g_strdup_printf(_("You rejected %d's request"), uid);
+ msg2 = g_strdup(_("Message:"));
+
+ purple_name = uid_to_purple_name(uid);
+ purple_request_input(gc, _("Reject request"), msg1, msg2,
+ _("Sorry, you are not my style..."), TRUE, FALSE,
+ NULL, _("Reject"), G_CALLBACK(buddy_add_deny_reason_cb), _("Cancel"), NULL,
+ purple_connection_get_account(gc), purple_name, NULL,
+ add_req);
+ g_free(purple_name);
}
-/* we approve other's request of adding me as friend */
-void qq_approve_add_request_with_gc_and_uid(gc_and_uid *g)
+/* suggested by rakescar at linuxsir, can still approve after search */
+static void buddy_add_check_info_cb(qq_add_request *add_req)
{
- gint uid;
PurpleConnection *gc;
+ guint32 uid;
+ gchar *purple_name;
- g_return_if_fail(g != NULL);
+ g_return_if_fail(add_req != NULL);
+ if (add_req->gc == NULL || add_req->uid == 0) {
+ g_free(add_req);
+ return;
+ }
- gc = g->gc;
- uid = g->uid;
- g_return_if_fail(uid != 0);
+ gc = add_req->gc;
+ uid = add_req->uid;
- _qq_send_packet_buddy_auth(gc, uid, QQ_MY_AUTH_APPROVE, NULL);
- g_free(g);
+ qq_request_buddy_info(gc, uid, 0, QQ_BUDDY_INFO_DISPLAY);
+
+ purple_name = uid_to_purple_name(uid);
+ purple_request_action
+ (gc, NULL, _("Do you approve the requestion?"), "",
+ PURPLE_DEFAULT_ACTION_NONE,
+ purple_connection_get_account(gc), purple_name, NULL,
+ add_req, 2,
+ _("Reject"), G_CALLBACK(buddy_add_deny_cb),
+ _("Approve"), G_CALLBACK(buddy_add_authorize_cb));
+ g_free(purple_name);
}
-void qq_do_nothing_with_gc_and_uid(gc_and_uid *g, const gchar *msg)
+/* add a buddy and send packet to QQ server
+ * note that when purple load local cached buddy list into its blist
+ * it also calls this funtion, so we have to
+ * define qd->is_login=TRUE AFTER serv_finish_login(gc) */
+void qq_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
{
- g_free(g);
+ qq_data *qd;
+ guint32 uid;
+ PurpleBuddy *b;
+
+ qd = (qq_data *) gc->proto_data;
+ if (!qd->is_login)
+ return; /* IMPORTANT ! */
+
+ uid = purple_name_to_uid(buddy->name);
+ if (uid > 0) {
+ request_buddy_add_no_auth(gc, uid);
+ return;
+ }
+
+ b = purple_find_buddy(gc->account, buddy->name);
+ if (b != NULL) {
+ purple_blist_remove_buddy(b);
+ }
+ purple_notify_error(gc, NULL, _("QQ Number Error"), _("Invalid QQ Number"));
}
-/* we reject other's request of adding me as friend */
-void qq_reject_add_request_with_gc_and_uid(gc_and_uid *g)
+void qq_change_buddys_group(PurpleConnection *gc, const char *who,
+ const char *old_group, const char *new_group)
{
gint uid;
- gchar *msg1, *msg2;
- PurpleConnection *gc;
- gc_and_uid *g2;
- gchar *nombre;
+ g_return_if_fail(who != NULL);
- g_return_if_fail(g != NULL);
+ if (strcmp(new_group, PURPLE_GROUP_QQ_UNKNOWN) == 0) {
+ if (purple_privacy_check(gc->account, who)) {
+ purple_privacy_deny(gc->account, who, TRUE, FALSE);
+ } else {
+ purple_privacy_deny_add(gc->account, who, TRUE);
+ }
+ return;
+ }
- gc = g->gc;
- uid = g->uid;
+ if (strcmp(old_group, PURPLE_GROUP_QQ_UNKNOWN) != 0) {
+ return;
+ }
+
+ uid = purple_name_to_uid(who);
g_return_if_fail(uid != 0);
- g_free(g);
+ purple_privacy_deny_remove(gc->account, who, TRUE);
- g2 = g_new0(gc_and_uid, 1);
- g2->gc = gc;
- g2->uid = uid;
+ purple_debug_info("QQ", "Add unknow buddy %d\n", uid);
+ request_buddy_add_no_auth(gc, uid);
+}
- msg1 = g_strdup_printf(_("You rejected %d's request"), uid);
- msg2 = g_strdup(_("Message:"));
+static void buddy_cancel_cb(qq_add_request *add_req, const gchar *msg)
+{
+ g_return_if_fail(add_req != NULL);
+ g_free(add_req);
+}
- nombre = uid_to_purple_name(uid);
- purple_request_input(gc, _("Reject request"), msg1, msg2,
- _("Sorry, you are not my style..."), TRUE, FALSE,
- NULL, _("Reject"), G_CALLBACK(_qq_reject_add_request_real), _("Cancel"), NULL,
- purple_connection_get_account(gc), nombre, NULL,
- g2);
- g_free(nombre);
+static void buddy_add_no_auth_cb(qq_add_request *add_req)
+{
+ g_return_if_fail(add_req != NULL);
+ if (add_req->gc == NULL || add_req->uid == 0) {
+ g_free(add_req);
+ return;
+ }
+
+ request_buddy_add_no_auth(add_req->gc, add_req->uid);
+ g_free(add_req);
}
-void qq_add_buddy_with_gc_and_uid(gc_and_uid *g)
+static void buddy_remove_both_cb(qq_add_request *add_req)
{
- gint uid;
PurpleConnection *gc;
+ qq_data *qd;
+ gchar *purple_name;
+ PurpleBuddy *buddy;
+ qq_buddy *q_buddy;
- g_return_if_fail(g != NULL);
+ g_return_if_fail(add_req != NULL);
+ if (add_req->gc == NULL || add_req->uid == 0) {
+ g_free(add_req);
+ return;
+ }
- gc = g->gc;
- uid = g->uid;
- g_return_if_fail(uid != 0);
+ gc = add_req->gc;
+ qd = (qq_data *) gc->proto_data;
- _qq_send_packet_add_buddy(gc, uid);
- g_free(g);
+ request_buddy_remove(gc, add_req->uid);
+ request_buddy_remove_me(gc, add_req->uid);
+
+ purple_name = uid_to_purple_name(add_req->uid);
+ buddy = purple_find_buddy(gc->account, purple_name);
+ if (buddy == NULL) {
+ g_free(add_req);
+ return;
+ }
+
+ q_buddy = (qq_buddy *) buddy->proto_data;
+ if (q_buddy != NULL)
+ qd->buddies = g_list_remove(qd->buddies, q_buddy);
+ else
+ purple_debug_warning("QQ", "We have no qq_buddy record for %s\n", buddy->name);
+
+ purple_blist_remove_buddy(buddy);
+ g_free(add_req);
}
-void qq_block_buddy_with_gc_and_uid(gc_and_uid *g)
+/* remove a buddy from my list and remove myself from his list */
+/* TODO: re-enable this */
+void qq_remove_buddy_and_me(PurpleBlistNode * node)
{
+ PurpleConnection *gc;
+ qq_data *qd;
guint32 uid;
- PurpleConnection *gc;
- PurpleBuddy buddy;
- PurpleGroup group;
+ qq_add_request *add_req;
+ PurpleBuddy *buddy;
+ const gchar *who;
- g_return_if_fail(g != NULL);
+ g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
- gc = g->gc;
- uid = g->uid;
+ buddy = (PurpleBuddy *) node;
+ gc = purple_account_get_connection(buddy->account);
+ qd = (qq_data *) gc->proto_data;
+ if (!qd->is_login)
+ return;
+
+ who = buddy->name;
+ g_return_if_fail(who != NULL);
+
+ uid = purple_name_to_uid(who);
g_return_if_fail(uid > 0);
- buddy.name = uid_to_purple_name(uid);
- group.name = PURPLE_GROUP_QQ_BLOCKED;
+ add_req = g_new0(qq_add_request, 1);
+ add_req->gc = gc;
+ add_req->uid = uid;
- qq_remove_buddy(gc, &buddy, &group);
- _qq_send_packet_remove_self_from(gc, uid);
+ purple_request_action(gc, _("Block Buddy"),
+ "Are you sure you want to block this buddy?",
+ NULL,
+ 1,
+ purple_connection_get_account(gc), NULL, NULL,
+ add_req, 2,
+ _("Cancel"), G_CALLBACK(buddy_cancel_cb),
+ _("Block"), G_CALLBACK(buddy_remove_both_cb));
}
/* process reply to add_buddy_auth request */
-void qq_process_add_buddy_auth_reply(guint8 *data, gint data_len, PurpleConnection *gc)
+void qq_process_buddy_add_auth(guint8 *data, gint data_len, PurpleConnection *gc)
{
qq_data *qd;
gchar **segments, *msg_utf8;
@@ -271,7 +386,7 @@ void qq_process_add_buddy_auth_reply(gui
}
/* process the server reply for my request to remove a buddy */
-void qq_process_remove_buddy_reply(guint8 *data, gint data_len, PurpleConnection *gc)
+void qq_process_buddy_remove(guint8 *data, gint data_len, PurpleConnection *gc)
{
qq_data *qd;
@@ -291,7 +406,7 @@ void qq_process_remove_buddy_reply(guint
}
/* 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_buddy_remove_me(guint8 *data, gint data_len, PurpleConnection *gc)
{
qq_data *qd;
@@ -302,91 +417,75 @@ void qq_process_remove_self_reply(guint8
if (data[0] != QQ_REMOVE_SELF_REPLY_OK) {
/* there is no reason return from server */
purple_debug_warning("QQ", "Remove self fails\n");
- purple_notify_info(gc, _("QQ Buddy"), _("Failed:"), _("Remove from other's buddy list"));
+ purple_notify_info(gc, _("QQ Buddy"), _("Failed:"), _("Remove me from other's buddy list"));
} else { /* if reply */
purple_debug_info("QQ", "Remove from a buddy OK\n");
- /* TODO: Does the user really need to be notified about this? */
+#if 0
purple_notify_info(gc, _("QQ Buddy"), _("Successed:"), _("Remove from other's buddy list"));
+#endif
}
}
-void qq_process_add_buddy_reply(guint8 *data, gint data_len, guint16 seq, PurpleConnection *gc)
+void qq_process_buddy_add_no_auth(guint8 *data, gint data_len, guint32 uid, PurpleConnection *gc)
{
qq_data *qd;
- gint for_uid;
- gchar *msg, **segments, *uid, *reply;
- GList *list;
+ gchar *msg, **segments, *dest_uid, *reply;
PurpleBuddy *b;
- gc_and_uid *g;
- qq_add_buddy_request *req;
+ qq_add_request *add_req;
gchar *nombre;
g_return_if_fail(data != NULL && data_len != 0);
- for_uid = 0;
qd = (qq_data *) gc->proto_data;
- list = qd->add_buddy_request;
- while (list != NULL) {
- req = (qq_add_buddy_request *) list->data;
- if (req->seq == seq) { /* reply to this */
- for_uid = req->uid;
- qd->add_buddy_request = g_list_remove(qd->add_buddy_request, qd->add_buddy_request->data);
- g_free(req);
- break;
- }
- list = list->next;
- }
-
- if (for_uid == 0) { /* we have no record for this */
- purple_debug_error("QQ", "We have no record for add buddy reply [%d], discard\n", seq);
+ if (uid == 0) { /* we have no record for this */
+ purple_debug_error("QQ", "Process buddy add, unknow id\n");
return;
} else {
- purple_debug_info("QQ", "Add buddy reply [%d] is for id [%d]\n", seq, for_uid);
+ purple_debug_info("QQ", "Process buddy add for id [%d]\n", uid);
}
if (NULL == (segments = split_data(data, data_len, "\x1f", 2)))
return;
- uid = segments[0];
+ dest_uid = segments[0];
reply = segments[1];
- if (strtol(uid, NULL, 10) != qd->uid) { /* should not happen */
- purple_debug_error("QQ", "Add buddy reply is to [%s], not me!", uid);
+ if (strtol(dest_uid, NULL, 10) != qd->uid) { /* should not happen */
+ purple_debug_error("QQ", "Add buddy reply is to [%s], not me!", dest_uid);
g_strfreev(segments);
return;
}
if (strtol(reply, NULL, 10) > 0) { /* need auth */
purple_debug_warning("QQ", "Add buddy attempt fails, need authentication\n");
- nombre = uid_to_purple_name(for_uid);
+ nombre = uid_to_purple_name(uid);
b = purple_find_buddy(gc->account, nombre);
if (b != NULL)
purple_blist_remove_buddy(b);
- g = g_new0(gc_and_uid, 1);
- g->gc = gc;
- g->uid = for_uid;
- msg = g_strdup_printf(_("%d needs authentication"), for_uid);
+ add_req = g_new0(qq_add_request, 1);
+ add_req->gc = gc;
+ add_req->uid = uid;
+ msg = g_strdup_printf(_("%d needs authentication"), 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?"),
TRUE, FALSE, NULL, _("Send"),
- G_CALLBACK
- (_qq_send_packet_add_buddy_auth_with_gc_and_uid),
- _("Cancel"), G_CALLBACK(qq_do_nothing_with_gc_and_uid),
+ G_CALLBACK(request_buddy_add_auth_cb),
+ _("Cancel"), G_CALLBACK(buddy_cancel_cb),
purple_connection_get_account(gc), nombre, NULL,
- g);
+ add_req);
g_free(msg);
g_free(nombre);
} else { /* add OK */
- qq_add_buddy_by_recv_packet(gc, for_uid, TRUE, TRUE);
- msg = g_strdup_printf(_("Add into %d's buddy list"), for_uid);
+ qq_create_buddy(gc, uid, TRUE, TRUE);
+ msg = g_strdup_printf(_("Add into %d's buddy list"), uid);
purple_notify_info(gc, _("QQ Buddy"), _("Successed:"), msg);
g_free(msg);
}
g_strfreev(segments);
}
-PurpleGroup *qq_get_purple_group(const gchar *group_name)
+PurpleGroup *qq_create_group(const gchar *group_name)
{
PurpleGroup *g;
@@ -404,131 +503,93 @@ PurpleGroup *qq_get_purple_group(const g
/* we add new buddy, if the received packet is from someone not in my list
* return the PurpleBuddy that is just created */
-PurpleBuddy *qq_add_buddy_by_recv_packet(PurpleConnection *gc, guint32 uid, gboolean is_known, gboolean create)
+PurpleBuddy *qq_create_buddy(PurpleConnection *gc, guint32 uid, gboolean is_known, gboolean create)
{
- PurpleAccount *a;
- PurpleBuddy *b;
- PurpleGroup *g;
+ PurpleBuddy *buddy;
+ PurpleGroup *group;
qq_data *qd;
qq_buddy *q_bud;
- gchar *name, *group_name;
+ gchar *buddy_name, *group_name;
- a = gc->account;
+ g_return_val_if_fail(gc->account != NULL && uid != 0, NULL);
qd = (qq_data *) gc->proto_data;
- g_return_val_if_fail(a != NULL && uid != 0, NULL);
- group_name = is_known ?
- g_strdup_printf(PURPLE_GROUP_QQ_FORMAT, purple_account_get_username(a)) : g_strdup(PURPLE_GROUP_QQ_UNKNOWN);
+ if (is_known) {
+ group_name = g_strdup_printf(PURPLE_GROUP_QQ_FORMAT,
+ purple_account_get_username(gc->account));
+ } else {
+ group_name = g_strdup(PURPLE_GROUP_QQ_UNKNOWN);
+ }
- g = qq_get_purple_group(group_name);
+ group = qq_create_group(group_name);
- name = uid_to_purple_name(uid);
- b = purple_find_buddy(gc->account, name);
+ buddy_name = uid_to_purple_name(uid);
+ buddy = purple_find_buddy(gc->account, buddy_name);
/* remove old, we can not simply return here
* because there might be old local copy of this buddy */
- if (b != NULL)
- purple_blist_remove_buddy(b);
+ if (buddy != NULL)
+ purple_blist_remove_buddy(buddy);
- b = purple_buddy_new(a, name, NULL);
+ buddy = purple_buddy_new(gc->account, buddy_name, NULL);
+ if ( !is_known ) {
+ if (purple_privacy_check(gc->account, buddy_name)) {
+ purple_privacy_deny(gc->account, buddy_name, TRUE, FALSE);
+ } else {
+ purple_privacy_deny_add(gc->account, buddy_name, TRUE);
+ }
+ }
if (!create)
- b->proto_data = NULL;
+ buddy->proto_data = NULL;
else {
q_bud = g_new0(qq_buddy, 1);
q_bud->uid = uid;
- b->proto_data = q_bud;
+ buddy->proto_data = q_bud;
qd->buddies = g_list_append(qd->buddies, q_bud);
- qq_send_packet_get_info(gc, q_bud->uid, FALSE);
+ qq_request_buddy_info(gc, qd->uid, 0, 0);
qq_request_get_buddies_online(gc, 0, 0);
+ qq_request_get_level(gc, qd->uid);
}
- purple_blist_add_buddy(b, NULL, g, NULL);
- purple_debug_warning("QQ", "Add new buddy: [%s]\n", name);
+ purple_blist_add_buddy(buddy, NULL, group, NULL);
+ purple_debug_warning("QQ", "Add new buddy: [%s]\n", buddy_name);
- g_free(name);
+ g_free(buddy_name);
g_free(group_name);
- return b;
+ return buddy;
}
-/* add a buddy and send packet to QQ server
- * note that when purple load local cached buddy list into its blist
- * it also calls this funtion, so we have to
- * define qd->is_login=TRUE AFTER serv_finish_login(gc) */
-void qq_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
-{
- qq_data *qd;
- guint32 uid;
- PurpleBuddy *b;
-
- qd = (qq_data *) gc->proto_data;
- if (!qd->is_login)
- return; /* IMPORTANT ! */
-
- uid = purple_name_to_uid(buddy->name);
- if (uid > 0)
- _qq_send_packet_add_buddy(gc, uid);
- else {
- b = purple_find_buddy(gc->account, buddy->name);
- if (b != NULL)
- purple_blist_remove_buddy(b);
- purple_notify_error(gc, NULL,
- _("QQ Number Error"),
- _("Invalid QQ Number"));
- }
-}
-
/* remove a buddy and send packet to QQ server accordingly */
void qq_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
{
qq_data *qd;
- PurpleBuddy *b;
qq_buddy *q_bud;
guint32 uid;
+ g_return_if_fail(gc != NULL && gc->proto_data != NULL);
+ g_return_if_fail(buddy != NULL);
qd = (qq_data *) gc->proto_data;
+
uid = purple_name_to_uid(buddy->name);
-
if (!qd->is_login)
return;
- if (uid > 0)
- _qq_send_packet_remove_buddy(gc, uid);
-
- b = purple_find_buddy(gc->account, buddy->name);
- if (b != NULL) {
- q_bud = (qq_buddy *) b->proto_data;
- if (q_bud != NULL)
- qd->buddies = g_list_remove(qd->buddies, q_bud);
- else
- purple_debug_warning("QQ", "We have no qq_buddy record for %s\n", buddy->name);
- /* 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 */
- if (g_ascii_strcasecmp(group->name, PURPLE_GROUP_QQ_BLOCKED) == 0)
- purple_blist_remove_buddy(b);
+ if (uid > 0) {
+ request_buddy_remove(gc, uid);
}
-}
-/* free add buddy request queue */
-void qq_add_buddy_request_free(qq_data *qd)
-{
- gint count;
- qq_add_buddy_request *p;
+ q_bud = (qq_buddy *) buddy->proto_data;
+ if (q_bud != NULL)
+ qd->buddies = g_list_remove(qd->buddies, q_bud);
+ else
+ purple_debug_warning("QQ", "We have no qq_buddy record for %s\n", buddy->name);
- 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);
- count++;
- }
- if (count > 0) {
- purple_debug_info("QQ", "%d add buddy requests are freed!\n", count);
- }
+ /* Do not call purple_blist_remove_buddy,
+ * otherwise purple segmentation fault */
}
-/* free up all qq_buddy */
+/* free all qq_buddy */
void qq_buddies_list_free(PurpleAccount *account, qq_data *qd)
{
gint count;
@@ -555,3 +616,149 @@ void qq_buddies_list_free(PurpleAccount
purple_debug_info("QQ", "%d qq_buddy structures are freed!\n", count);
}
}
+
+/* someone wants to add you to his buddy list */
+static void server_buddy_add_request(PurpleConnection *gc, gchar *from, gchar *to, gchar *msg_utf8)
+{
+ gchar *message, *reason;
+ guint32 uid;
+ qq_add_request *g, *g2;
+ PurpleBuddy *b;
+ gchar *name;
+
+ g_return_if_fail(from != NULL && to != NULL);
+
+ uid = strtol(from, NULL, 10);
+ g = g_new0(qq_add_request, 1);
+ g->gc = gc;
+ g->uid = uid;
+
+ name = uid_to_purple_name(uid);
+
+ /* TODO: this should go through purple_account_request_authorization() */
+ message = g_strdup_printf(_("%s wants to add you [%s] as a friend"), from, to);
+ reason = g_strdup_printf(_("Message: %s"), msg_utf8);
+
+ purple_request_action
+ (gc, NULL, message, reason, PURPLE_DEFAULT_ACTION_NONE,
+ purple_connection_get_account(gc), name, NULL,
+ g, 3,
+ _("Reject"),
+ G_CALLBACK(buddy_add_deny_cb),
+ _("Approve"),
+ G_CALLBACK(buddy_add_authorize_cb),
+ _("Search"), G_CALLBACK(buddy_add_check_info_cb));
+
+ g_free(message);
+ g_free(reason);
+
+ /* XXX: Is this needed once the above goes through purple_account_request_authorization()? */
+ b = purple_find_buddy(gc->account, name);
+ if (b == NULL) { /* the person is not in my list */
+ g2 = g_new0(qq_add_request, 1);
+ g2->gc = gc;
+ g2->uid = strtol(from, NULL, 10);
+ message = g_strdup_printf(_("%s is not in buddy list"), from);
+ purple_request_action(gc, NULL, message,
+ _("Would you add?"), PURPLE_DEFAULT_ACTION_NONE,
+ purple_connection_get_account(gc), name, NULL,
+ g2, 3,
+ _("Cancel"), NULL,
+ _("Add"), G_CALLBACK(buddy_add_no_auth_cb),
+ _("Search"), G_CALLBACK(buddy_add_check_info_cb));
+ g_free(message);
+ }
+
+ g_free(name);
+}
+
+/* when you are added by a person, QQ server will send sys message */
+static void server_buddy_added(PurpleConnection *gc, gchar *from, gchar *to, gchar *msg_utf8)
+{
+ gchar *message;
+ PurpleBuddy *b;
+ guint32 uid;
+ qq_add_request *add_req;
+ gchar *name;
+
+ g_return_if_fail(from != NULL && to != NULL);
+
+ uid = strtol(from, NULL, 10);
+ name = uid_to_purple_name(uid);
+ b = purple_find_buddy(gc->account, name);
+
+ if (b == NULL) { /* the person is not in my list */
+ add_req = g_new0(qq_add_request, 1);
+ add_req->gc = gc;
+ add_req->uid = uid; /* only need to get value */
+ message = g_strdup_printf(_("You have been added by %s"), from);
+ purple_request_action(gc, NULL, message,
+ _("Would you like to add him?"),
+ PURPLE_DEFAULT_ACTION_NONE,
+ purple_connection_get_account(gc), name, NULL,
+ add_req, 3,
+ _("Cancel"), G_CALLBACK(buddy_cancel_cb),
+ _("Add"), G_CALLBACK(buddy_add_no_auth_cb),
+ _("Search"), G_CALLBACK(buddy_add_check_info_cb));
+ } else {
+ message = g_strdup_printf(_("%s added you [%s] to buddy list"), from, to);
+ purple_notify_info(gc, _("QQ Budy"), _("Successed:"), message);
+ }
+
+ g_free(name);
+ g_free(message);
+}
+
+/* the buddy approves your request of adding him/her as your friend */
+static void server_buddy_added_me(PurpleConnection *gc, gchar *from, gchar *to, gchar *msg_utf8)
+{
+ gchar *message;
+ qq_data *qd;
+
+ g_return_if_fail(from != NULL && to != NULL);
+
+ qd = (qq_data *) gc->proto_data;
+ qq_create_buddy(gc, strtol(from, NULL, 10), TRUE, TRUE);
+
+ message = g_strdup_printf(_("Requestion approved by %s"), from);
+ purple_notify_info(gc, _("QQ Buddy"), _("Notice:"), message);
+
+ g_free(message);
+}
+
+/* you are rejected by the person */
+static void server_buddy_rejected_me(PurpleConnection *gc, gchar *from, gchar *to, gchar *msg_utf8)
+{
+ gchar *message, *reason;
+
+ g_return_if_fail(from != NULL && to != NULL);
+
+ message = g_strdup_printf(_("Requestion rejected by %s"), from);
+ reason = g_strdup_printf(_("Message: %s"), msg_utf8);
+
+ purple_notify_info(gc, _("QQ Buddy"), message, reason);
+ g_free(message);
+ g_free(reason);
+}
+
+void qq_process_buddy_from_server(PurpleConnection *gc, int funct,
+ gchar *from, gchar *to, gchar *msg_utf8)
+{
+ switch (funct) {
+ case QQ_SERVER_BUDDY_ADDED:
+ server_buddy_added(gc, from, to, msg_utf8);
+ break;
+ case QQ_SERVER_BUDDY_ADD_REQUEST:
+ server_buddy_add_request(gc, from, to, msg_utf8);
+ break;
+ case QQ_SERVER_BUDDY_ADDED_ME:
+ server_buddy_added_me(gc, from, to, msg_utf8);
+ break;
+ case QQ_SERVER_BUDDY_REJECTED_ME:
+ server_buddy_rejected_me(gc, from, to, msg_utf8);
+ break;
+ default:
+ purple_debug_warning("QQ", "Unknow buddy operate (%d) from server\n", funct);
+ break;
+ }
+}
============================================================
--- libpurple/protocols/qq/buddy_opt.h ac9e37c18d7db3eb191f9096bdf6f3819a6a84f4
+++ libpurple/protocols/qq/buddy_opt.h b73cafe14e55a79a265b7f2ef8ac9801f0577774
@@ -30,33 +30,21 @@
#include "qq.h"
-typedef struct _gc_and_uid gc_and_uid;
-
-struct _gc_and_uid {
- guint32 uid;
- PurpleConnection *gc;
-};
-
-void qq_approve_add_request_with_gc_and_uid(gc_and_uid *g);
-void qq_reject_add_request_with_gc_and_uid(gc_and_uid *g);
-
-void qq_add_buddy_with_gc_and_uid(gc_and_uid *g);
-void qq_block_buddy_with_gc_and_uid(gc_and_uid *g);
-
-void qq_do_nothing_with_gc_and_uid(gc_and_uid *g, const gchar *msg);
-
-void qq_process_remove_buddy_reply(guint8 *buf, gint buf_len, PurpleConnection *gc);
-void qq_process_remove_self_reply(guint8 *data, gint data_len, PurpleConnection *gc);
-void qq_process_add_buddy_reply(guint8 *data, gint data_len, guint16 seq, PurpleConnection *gc);
-void qq_process_add_buddy_auth_reply(guint8 *data, gint data_len, PurpleConnection *gc);
-PurpleBuddy *qq_add_buddy_by_recv_packet(PurpleConnection *gc, guint32 uid, gboolean is_known, gboolean create);
void qq_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group);
+void qq_change_buddys_group(PurpleConnection *gc, const char *who,
+ const char *old_group, const char *new_group);
+void qq_remove_buddy_and_me(PurpleBlistNode * node);
+void qq_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group);
+PurpleBuddy *qq_create_buddy(PurpleConnection *gc, guint32 uid, gboolean is_known, gboolean create);
+void qq_buddies_list_free(PurpleAccount *account, qq_data *qd);
-PurpleGroup *qq_get_purple_group(const gchar *group_name);
+void qq_process_buddy_remove(guint8 *buf, gint buf_len, PurpleConnection *gc);
+void qq_process_buddy_remove_me(guint8 *data, gint data_len, PurpleConnection *gc);
+void qq_process_buddy_add_no_auth(guint8 *data, gint data_len, guint32 uid, PurpleConnection *gc);
+void qq_process_buddy_add_auth(guint8 *data, gint data_len, PurpleConnection *gc);
+void qq_process_buddy_from_server(PurpleConnection *gc, int funct,
+ gchar *from, gchar *to, gchar *msg_utf8);
-void qq_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group);
-void qq_add_buddy_request_free(qq_data *qd);
+PurpleGroup *qq_create_group(const gchar *group_name);
-void qq_buddies_list_free(PurpleAccount *account, qq_data *qd);
-
#endif
============================================================
--- libpurple/protocols/qq/group.c 4156644554b1da039cbb013b3ca1318d700fedd5
+++ libpurple/protocols/qq/group.c 0dc229d6263edb2c6a6fa1ee7f661d125b99cee7
@@ -34,7 +34,7 @@
#include "utils.h"
#include "qq_network.h"
#include "header_info.h"
-#include "group.h"
+#include "group_free.h"
static void _qq_group_search_callback(PurpleConnection *gc, const gchar *input)
{
============================================================
--- libpurple/protocols/qq/group_internal.c 9c1c472072ff1a2fbe1ca02066b0ecb6b9ebf9b6
+++ libpurple/protocols/qq/group_internal.c 1877bfc0f0735292c875f9c1e4c0a2b27b5463d7
@@ -63,7 +63,7 @@ static void add_room_to_blist(PurpleConn
PurpleChat *chat;
components = qq_group_to_hashtable(group);
chat = purple_chat_new(purple_connection_get_account(gc), group->title_utf8, components);
- g = qq_get_purple_group(PURPLE_GROUP_QQ_QUN);
+ g = qq_create_group(PURPLE_GROUP_QQ_QUN);
purple_blist_add_chat(chat, g, NULL);
purple_debug_info("QQ", "You have added group \"%s\" to blist locally\n", group->title_utf8);
}
============================================================
--- libpurple/protocols/qq/group_join.c 27e1b45f39d86e6ebfd9eced35bc30f6f9ea03d3
+++ libpurple/protocols/qq/group_join.c 1dc85c7d1bc5f5fb56c0a1c6aece13022460e4a8
@@ -29,11 +29,9 @@
#include "request.h"
#include "server.h"
-#include "buddy_opt.h"
#include "char_conv.h"
#include "group_conv.h"
#include "group_find.h"
-#include "group_free.h"
#include "group_internal.h"
#include "group_info.h"
#include "group_join.h"
@@ -51,19 +49,28 @@ enum {
QQ_ROOM_JOIN_DENIED = 0x03,
};
-static void _qq_group_exit_with_gc_and_id(gc_and_uid *g)
+static void group_quit_cb(qq_add_request *add_req)
{
PurpleConnection *gc;
guint32 id;
qq_group *group;
- gc = g->gc;
- id = g->uid;
+ if (add_req->gc == NULL || add_req->uid == 0) {
+ g_free(add_req);
+ return;
+ }
+ gc = add_req->gc;
+ id = add_req->uid;
+
group = qq_room_search_id(gc, id);
- g_return_if_fail(group != NULL);
+ if (group == NULL) {
+ g_free(add_req);
+ return;
+ }
qq_send_room_cmd_only(gc, QQ_ROOM_CMD_QUIT, group->id);
+ g_free(add_req);
}
/* send packet to join a group without auth */
@@ -95,44 +102,53 @@ void qq_request_room_join(PurpleConnecti
qq_send_room_cmd_only(gc, QQ_ROOM_CMD_JOIN, group->id);
}
-static void _qq_group_join_auth_with_gc_and_id(gc_and_uid *g, const gchar *reason_utf8)
+static void group_join_cb(qq_add_request *add_req, const gchar *reason_utf8)
{
- PurpleConnection *gc;
qq_group *group;
- guint32 id;
- gc = g->gc;
- id = g->uid;
+ g_return_if_fail(add_req != NULL);
+ if (add_req->gc == NULL || add_req->uid == 0) {
+ g_free(add_req);
+ return;
+ }
- group = qq_room_search_id(gc, id);
+ group = qq_room_search_id(add_req->gc, add_req->uid);
if (group == NULL) {
- 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", add_req->uid);
+ g_free(add_req);
return;
- } else { /* everything is OK */
- qq_send_cmd_group_auth(gc, group, QQ_ROOM_AUTH_REQUEST_APPLY, 0, reason_utf8);
}
+
+ qq_send_cmd_group_auth(add_req->gc, group, QQ_ROOM_AUTH_REQUEST_APPLY, 0, reason_utf8);
+ g_free(add_req);
}
+void qq_group_cancel_cb(qq_add_request *add_req, const gchar *msg)
+{
+ g_return_if_fail(add_req != NULL);
+ g_free(add_req);
+}
+
static void _qq_group_join_auth(PurpleConnection *gc, qq_group *group)
{
gchar *msg;
- gc_and_uid *g;
+ qq_add_request *add_req;
g_return_if_fail(group != NULL);
purple_debug_info("QQ", "Group (internal id: %d) needs authentication\n", group->id);
msg = g_strdup_printf("Group \"%s\" needs authentication\n", group->title_utf8);
- g = g_new0(gc_and_uid, 1);
- g->gc = gc;
- g->uid = group->id;
+ add_req = g_new0(qq_add_request, 1);
+ add_req->gc = gc;
+ add_req->uid = group->id;
purple_request_input(gc, NULL, msg,
_("Input request here"),
_("Would you be my friend?"), TRUE, FALSE, NULL,
_("Send"),
- G_CALLBACK(_qq_group_join_auth_with_gc_and_id),
- _("Cancel"), G_CALLBACK(qq_do_nothing_with_gc_and_uid),
+ G_CALLBACK(group_join_cb),
+ _("Cancel"), G_CALLBACK(qq_group_cancel_cb),
purple_connection_get_account(gc), group->title_utf8, NULL,
- g);
+ add_req);
g_free(msg);
}
@@ -308,7 +324,7 @@ void qq_group_exit(PurpleConnection *gc,
{
gchar *id_ptr;
guint32 id;
- gc_and_uid *g;
+ qq_add_request *add_req;
g_return_if_fail(data != NULL);
@@ -317,16 +333,16 @@ void qq_group_exit(PurpleConnection *gc,
g_return_if_fail(id > 0);
- g = g_new0(gc_and_uid, 1);
- g->gc = gc;
- g->uid = id;
+ add_req = g_new0(qq_add_request, 1);
+ add_req->gc = gc;
+ add_req->uid = id;
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."),
1,
purple_connection_get_account(gc), NULL, NULL,
- g, 2, _("Cancel"),
- G_CALLBACK(qq_do_nothing_with_gc_and_uid),
- _("Continue"), G_CALLBACK(_qq_group_exit_with_gc_and_id));
+ add_req, 2, _("Cancel"),
+ G_CALLBACK(qq_group_cancel_cb),
+ _("Continue"), G_CALLBACK(group_quit_cb));
}
============================================================
--- libpurple/protocols/qq/group_join.h 3b40893ee013641ea28952bcd577f6ec6c062453
+++ libpurple/protocols/qq/group_join.h c66eec2d0af474f149a15208c3692f0348d6bc68
@@ -49,4 +49,5 @@ void qq_process_group_cmd_join_group(gui
void qq_process_group_cmd_join_group_auth(guint8 *data, gint len, PurpleConnection *gc);
void qq_process_group_cmd_join_group(guint8 *data, gint len, PurpleConnection *gc);
+void qq_group_cancel_cb(qq_add_request *add_req, const gchar *msg);
#endif
============================================================
--- libpurple/protocols/qq/group_opt.c ec942076087ba676c65b84419b2fbb09ac50baca
+++ libpurple/protocols/qq/group_opt.c 87b480c3666e20d961653cf0f0e16dbabcb50cb1
@@ -97,7 +97,7 @@ void qq_group_search_application_with_st
{
g_return_if_fail(g != NULL && g->gc != NULL && g->member > 0);
- qq_send_packet_get_info(g->gc, g->member, TRUE); /* we want to see window */
+ qq_request_buddy_info(g->gc, g->member, 0, QQ_BUDDY_INFO_DISPLAY);
purple_request_action(g->gc, NULL, _("Do you want to approve the request?"), "",
PURPLE_DEFAULT_ACTION_NONE,
purple_connection_get_account(g->gc), NULL, NULL,
@@ -322,17 +322,24 @@ void qq_room_create_new(PurpleConnection
qq_send_room_cmd_noid(gc, QQ_ROOM_CMD_CREATE, data, bytes);
}
-static void qq_group_setup_with_gc_and_uid(gc_and_uid *g)
+static void qq_group_setup_cb(qq_add_request *add_req)
{
qq_group *group;
- g_return_if_fail(g != NULL && g->gc != NULL && g->uid > 0);
+ g_return_if_fail(add_req != NULL);
+ if (add_req->gc == NULL || add_req->uid == 0) {
+ g_free(add_req);
+ return;
+ }
- group = qq_room_search_id(g->gc, g->uid);
- g_return_if_fail(group != NULL);
+ group = qq_room_search_id(add_req->gc, add_req->uid);
+ if (group == NULL) {
+ g_free(add_req);
+ return;
+ }
/* TODO insert UI code here */
/* qq_group_detail_window_show(g->gc, group); */
- g_free(g);
+ g_free(add_req);
}
void qq_group_process_create_group_reply(guint8 *data, gint len, PurpleConnection *gc)
@@ -340,7 +347,7 @@ void qq_group_process_create_group_reply
gint bytes;
guint32 id, ext_id;
qq_group *group;
- gc_and_uid *g;
+ qq_add_request *add_req;
qq_data *qd;
g_return_if_fail(data != NULL);
@@ -362,19 +369,18 @@ void qq_group_process_create_group_reply
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;
- g->uid = id;
+ add_req = g_new0(qq_add_request, 1);
+ add_req->gc = gc;
+ add_req->uid = id;
purple_request_action(gc, _("QQ Qun Operation"),
_("You have successfully created a Qun"),
- _
- ("Would you like to set up the detail information now?"),
+ _("Would you like to set up the detail information now?"),
1,
purple_connection_get_account(gc), NULL, NULL,
- g, 2,
- _("Setup"), G_CALLBACK(qq_group_setup_with_gc_and_uid),
- _("Cancel"), G_CALLBACK(qq_do_nothing_with_gc_and_uid));
+ add_req, 2,
+ _("Setup"), G_CALLBACK(qq_group_setup_cb),
+ _("Cancel"), G_CALLBACK(qq_group_cancel_cb));
}
void qq_group_process_activate_group_reply(guint8 *data, gint len, PurpleConnection *gc)
============================================================
--- libpurple/protocols/qq/header_info.c fdaaac088f6dcef16a7b21f53805cf9cd3c1dafd
+++ libpurple/protocols/qq/header_info.c 2a513cf15a10847e24922596fcd0d05c5f2412d2
@@ -140,12 +140,12 @@ const gchar *qq_get_cmd_desc(gint cmd)
return "QQ_CMD_SEARCH_USER";
case QQ_CMD_GET_BUDDY_INFO:
return "QQ_CMD_GET_BUDDY_INFO";
- case QQ_CMD_ADD_BUDDY_WO_AUTH:
- return "QQ_CMD_ADD_BUDDY_WO_AUTH";
- case QQ_CMD_DEL_BUDDY:
- return "QQ_CMD_DEL_BUDDY";
- case QQ_CMD_BUDDY_AUTH:
- return "QQ_CMD_BUDDY_AUTH";
+ case QQ_CMD_BUDDY_ADD_NO_AUTH:
+ return "QQ_CMD_BUDDY_ADD_NO_AUTH";
+ case QQ_CMD_BUDDY_REMOVE:
+ return "QQ_CMD_BUDDY_REMOVE";
+ case QQ_CMD_BUDDY_ADD_AUTH:
+ return "QQ_CMD_BUDDY_ADD_AUTH";
case QQ_CMD_CHANGE_STATUS:
return "QQ_CMD_CHANGE_STATUS";
case QQ_CMD_ACK_SYS_MSG:
@@ -154,8 +154,8 @@ const gchar *qq_get_cmd_desc(gint cmd)
return "QQ_CMD_SEND_IM";
case QQ_CMD_RECV_IM:
return "QQ_CMD_RECV_IM";
- case QQ_CMD_REMOVE_SELF:
- return "QQ_CMD_REMOVE_SELF";
+ case QQ_CMD_REMOVE_ME:
+ return "QQ_CMD_REMOVE_ME";
case QQ_CMD_LOGIN:
return "QQ_CMD_LOGIN";
case QQ_CMD_GET_BUDDIES_LIST:
============================================================
--- libpurple/protocols/qq/header_info.h 2291a5a989742f72bf23e068817c4c67d4d00c7a
+++ libpurple/protocols/qq/header_info.h 8241e8f0df57be7a021443c7796c1c249c539b5f
@@ -44,14 +44,14 @@ enum {
QQ_CMD_UPDATE_INFO = 0x0004, /* update information */
QQ_CMD_SEARCH_USER = 0x0005, /* search for user */
QQ_CMD_GET_BUDDY_INFO = 0x0006, /* get user information */
- 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_BUDDY_ADD_NO_AUTH = 0x0009, /* add buddy without auth */
+ QQ_CMD_BUDDY_REMOVE = 0x000a, /* delete a buddy */
+ QQ_CMD_BUDDY_ADD_AUTH = 0x000b, /* buddy authentication */
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 */
- QQ_CMD_REMOVE_SELF = 0x001c, /* remove self */
+ QQ_CMD_REMOVE_ME = 0x001c, /* remove self */
QQ_CMD_REQUEST_KEY = 0x001d, /* request key for file transfer */
QQ_CMD_CELL_PHONE_1 = 0x0021, /* cell phone 1 */
QQ_CMD_LOGIN = 0x0022, /* login */
@@ -98,4 +98,12 @@ const gchar *qq_get_room_cmd_desc(gint r
const gchar *qq_get_room_cmd_desc(gint room_cmd);
+enum {
+ QQ_SERVER_BUDDY_ADDED = 0x01,
+ QQ_SERVER_BUDDY_ADD_REQUEST = 0x02,
+ QQ_SERVER_BUDDY_ADDED_ME = 0x03,
+ QQ_SERVER_BUDDY_REJECTED_ME = 0x04,
+ QQ_SERVER_NOTICE= 0x06,
+ QQ_SERVER_NEW_CLIENT = 0x09
+};
#endif
============================================================
--- libpurple/protocols/qq/im.c 9137a2f36795ef39af707659233a0f884f082664
+++ libpurple/protocols/qq/im.c 702c7ac1372e88b719dd20b88f106b41e75c155a
@@ -355,7 +355,7 @@ static void _qq_process_recv_normal_im_t
name = uid_to_purple_name(common->sender_uid);
b = purple_find_buddy(gc->account, name);
if (b == NULL) {
- qq_add_buddy_by_recv_packet(gc, common->sender_uid, FALSE, TRUE);
+ qq_create_buddy(gc, common->sender_uid, FALSE, TRUE);
b = purple_find_buddy(gc->account, name);
}
qq_b = (b == NULL) ? NULL : (qq_buddy *) b->proto_data;
============================================================
--- libpurple/protocols/qq/packet_parse.c 21732e9a4c9b39b77a94bd80073695ba1a12c103
+++ libpurple/protocols/qq/packet_parse.c 62cdbf4a27fb94fdb2458c47a37eae5367bd6c2d
@@ -38,7 +38,7 @@
#define PARSER_DEBUG
#endif
-/* read one byte from buf,
+/* read one byte from buf,
* return the number of bytes read if succeeds, otherwise return -1 */
gint qq_get8(guint8 *b, guint8 *buf)
{
@@ -53,7 +53,7 @@ gint qq_get8(guint8 *b, guint8 *buf)
}
-/* read two bytes as "guint16" from buf,
+/* read two bytes as "guint16" from buf,
* return the number of bytes read if succeeds, otherwise return -1 */
gint qq_get16(guint16 *w, guint8 *buf)
{
@@ -67,7 +67,7 @@ gint qq_get16(guint16 *w, guint8 *buf)
return sizeof(w_dest);
}
-/* read four bytes as "guint32" from buf,
+/* read four bytes as "guint32" from buf,
* return the number of bytes read if succeeds, otherwise return -1 */
gint qq_get32(guint32 *dw, guint8 *buf)
{
@@ -87,7 +87,7 @@ gint qq_getIP(struct in_addr *ip, guint8
return sizeof(struct in_addr);
}
-/* read datalen bytes from buf,
+/* read datalen bytes from buf,
* return the number of bytes read if succeeds, otherwise return -1 */
gint qq_getdata(guint8 *data, gint datalen, guint8 *buf)
{
@@ -171,7 +171,7 @@ gint qq_putdata(guint8 *buf, const guint
* return the number of bytes packed, otherwise return -1 */
gint qq_putdata(guint8 *buf, const guint8 *data, const int datalen)
{
- memcpy(buf, data, datalen);
+ memcpy(buf, data, datalen);
#ifdef PARSER_DEBUG
purple_debug_info("QQ", "[DBG][putdata] buf %p\n", (void *)buf);
#endif
============================================================
--- libpurple/protocols/qq/qq.c e0cfd8ddb5718cead0b5a384dfc8aa2445c7a5d2
+++ libpurple/protocols/qq/qq.c a07a58489c8d3ba77a04a9a8b5f5877df11221ba
@@ -456,7 +456,7 @@ static int _qq_chat_send(PurpleConnectio
}
/* send packet to get who's detailed information */
-static void _qq_get_info(PurpleConnection *gc, const gchar *who)
+static void qq_show_buddy_info(PurpleConnection *gc, const gchar *who)
{
guint32 uid;
qq_data *qd;
@@ -471,59 +471,65 @@ static void _qq_get_info(PurpleConnectio
}
qq_request_get_level(gc, uid);
- qq_send_packet_get_info(gc, uid, TRUE);
+ qq_request_buddy_info(gc, uid, 0, QQ_BUDDY_INFO_DISPLAY);
}
-/* get my own information */
-static void _qq_menu_modify_my_info(PurplePluginAction *action)
+static void action_update_all_rooms(PurplePluginAction *action)
{
PurpleConnection *gc = (PurpleConnection *) action->context;
qq_data *qd;
+ qd = (qq_data *) gc->proto_data;
- qd = (qq_data *) gc->proto_data;
- qq_prepare_modify_info(gc);
+ if ( !qd->is_login ) {
+ return;
+ }
+
+ qq_update_all_rooms(gc, 0, 0);
}
-static void _qq_menu_change_password(PurplePluginAction *action)
+static void action_modify_info_base(PurplePluginAction *action)
{
- purple_notify_uri(NULL, "https://password.qq.com");
+ PurpleConnection *gc = (PurpleConnection *) action->context;
+ qq_data *qd;
+
+ qd = (qq_data *) gc->proto_data;
+ qq_request_buddy_info(gc, qd->uid, 0, QQ_BUDDY_INFO_MODIFY_BASE);
}
-/* remove a buddy from my list and remove myself from his list */
-/* TODO: re-enable this
-static void _qq_menu_block_buddy(PurpleBlistNode * node)
+static void action_modify_info_ext(PurplePluginAction *action)
{
- guint32 uid;
- gc_and_uid *g;
- PurpleBuddy *buddy;
- PurpleConnection *gc;
- const gchar *who;
+ PurpleConnection *gc = (PurpleConnection *) action->context;
+ qq_data *qd;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+ qd = (qq_data *) gc->proto_data;
+ qq_request_buddy_info(gc, qd->uid, 0, QQ_BUDDY_INFO_MODIFY_EXT);
+}
- buddy = (PurpleBuddy *) node;
- gc = purple_account_get_connection(buddy->account);
- who = buddy->name;
- g_return_if_fail(who != NULL);
+static void action_modify_info_addr(PurplePluginAction *action)
+{
+ PurpleConnection *gc = (PurpleConnection *) action->context;
+ qq_data *qd;
- uid = purple_name_to_uid(who);
- g_return_if_fail(uid > 0);
+ qd = (qq_data *) gc->proto_data;
+ qq_request_buddy_info(gc, qd->uid, 0, QQ_BUDDY_INFO_MODIFY_ADDR);
+}
- g = g_new0(gc_and_uid, 1);
- g->gc = gc;
- g->uid = uid;
+static void action_modify_info_contact(PurplePluginAction *action)
+{
+ PurpleConnection *gc = (PurpleConnection *) action->context;
+ qq_data *qd;
- purple_request_action(gc, _("Block Buddy"),
- _("Are you sure you want to block this buddy?"), NULL,
- 1, g, 2,
- _("Cancel"),
- G_CALLBACK(qq_do_nothing_with_gc_and_uid),
- _("Block"), G_CALLBACK(qq_block_buddy_with_gc_and_uid));
+ qd = (qq_data *) gc->proto_data;
+ qq_request_buddy_info(gc, qd->uid, 0, QQ_BUDDY_INFO_MODIFY_CONTACT);
}
-*/
+static void action_change_password(PurplePluginAction *action)
+{
+ purple_notify_uri(NULL, "https://password.qq.com");
+}
+
/* show a brief summary of what we get from login packet */
-static void _qq_menu_account_info(PurplePluginAction *action)
+static void action_show_account_info(PurplePluginAction *action)
{
PurpleConnection *gc = (PurpleConnection *) action->context;
qq_data *qd;
@@ -628,21 +634,33 @@ static void _qq_menu_send_file(PurpleBli
#endif
/* protocol related menus */
-static GList *_qq_actions(PurplePlugin *plugin, gpointer context)
+static GList *qq_actions(PurplePlugin *plugin, gpointer context)
{
GList *m;
PurplePluginAction *act;
m = NULL;
- act = purple_plugin_action_new(_("Set My Information"), _qq_menu_modify_my_info);
+ act = purple_plugin_action_new(_("Modify Information"), action_modify_info_base);
m = g_list_append(m, act);
- act = purple_plugin_action_new(_("Change Password"), _qq_menu_change_password);
+ act = purple_plugin_action_new(_("Modify Extend Information"), action_modify_info_ext);
m = g_list_append(m, act);
- act = purple_plugin_action_new(_("Account Information"), _qq_menu_account_info);
+ act = purple_plugin_action_new(_("Modify Address"), action_modify_info_addr);
m = g_list_append(m, act);
+ act = purple_plugin_action_new(_("Modify Contact"), action_modify_info_contact);
+ m = g_list_append(m, act);
+
+ act = purple_plugin_action_new(_("Change Password"), action_change_password);
+ m = g_list_append(m, act);
+
+ act = purple_plugin_action_new(_("Account Information"), action_show_account_info);
+ m = g_list_append(m, act);
+
+ act = purple_plugin_action_new(_("Update all QQ Quns"), action_update_all_rooms);
+ m = g_list_append(m, act);
+
/*
act = purple_plugin_action_new(_("Qun: Search a permanent Qun"), _qq_menu_search_or_add_permanent_group);
m = g_list_append(m, act);
@@ -676,17 +694,18 @@ static GList *_qq_buddy_menu(PurpleBlist
static GList *_qq_buddy_menu(PurpleBlistNode * node)
{
GList *m;
+ PurpleMenuAction *act;
if(PURPLE_BLIST_NODE_IS_CHAT(node))
return _qq_chat_menu(node);
m = NULL;
+ act = purple_menu_action_new(_("Remove both side"), PURPLE_CALLBACK(qq_remove_buddy_and_me), NULL, NULL); /* add NULL by gfhuang */
+ m = g_list_append(m, act);
+
/* TODO : not working, temp commented out by gfhuang */
#if 0
-
- act = purple_menu_action_new(_("Block this buddy"), PURPLE_CALLBACK(_qq_menu_block_buddy), NULL, NULL); /* add NULL by gfhuang */
- m = g_list_append(m, act);
/* if (q_bud && is_online(q_bud->status)) { */
act = purple_menu_action_new(_("Send File"), PURPLE_CALLBACK(_qq_menu_send_file), NULL, NULL); /* add NULL by gfhuang */
m = g_list_append(m, act);
@@ -705,7 +724,7 @@ static void _qq_get_chat_buddy_info(Purp
purple_name = chat_name_to_purple_name(who);
if (purple_name != NULL)
- _qq_get_info(gc, purple_name);
+ qq_show_buddy_info(gc, purple_name);
}
/* convert chat nickname to qq-uid to invite individual IM to buddy */
@@ -735,7 +754,7 @@ static PurplePluginProtocolInfo prpl_inf
_qq_send_im, /* send_im */
NULL, /* set_info */
NULL, /* send_typing */
- _qq_get_info, /* get_info */
+ qq_show_buddy_info, /* get_info */
_qq_change_status, /* change status */
NULL, /* set_idle */
NULL, /* change_passwd */
@@ -760,12 +779,12 @@ static PurplePluginProtocolInfo prpl_inf
_qq_get_chat_buddy_info, /* get_cb_info */
NULL, /* get_cb_away */
NULL, /* alias_buddy */
- NULL, /* group_buddy */
+ qq_change_buddys_group, /* group_buddy */
NULL, /* rename_group */
NULL, /* buddy_free */
NULL, /* convo_closed */
NULL, /* normalize */
- qq_set_my_buddy_icon, /* set_buddy_icon */
+ qq_set_buddy_icon, /* set_buddy_icon */
NULL, /* remove_group */
_qq_get_chat_buddy_real_name, /* get_cb_real_name */
NULL, /* set_chat_topic */
@@ -815,7 +834,7 @@ static PurplePluginInfo info = {
NULL, /**< ui_info */
&prpl_info, /**< extra_info */
NULL, /**< prefs_info */
- _qq_actions,
+ qq_actions,
/* padding */
NULL,
@@ -878,7 +897,7 @@ static void init_plugin(PurplePlugin *pl
purple_prefs_add_bool("/plugins/prpl/qq/show_fake_video", FALSE);
purple_prefs_add_bool("/plugins/prpl/qq/show_room_when_newin", TRUE);
purple_prefs_add_int("/plugins/prpl/qq/resend_interval", 3);
- purple_prefs_add_int("/plugins/prpl/qq/resend_times", 4);
+ purple_prefs_add_int("/plugins/prpl/qq/resend_times", 10);
}
PURPLE_INIT_PLUGIN(qq, init_plugin, info);
============================================================
--- libpurple/protocols/qq/qq.h 3ddfd3f8cd67a42ceb9dbe7e8e1d4540a034c05e
+++ libpurple/protocols/qq/qq.h 7d26c6dc840ce378d9b814a90c231c4af6e41c7f
@@ -40,7 +40,13 @@ typedef struct _qq_net_stat qq_net_stat;
typedef struct _qq_buddy qq_buddy;
typedef struct _qq_interval qq_interval;
typedef struct _qq_net_stat qq_net_stat;
+typedef struct _qq_add_request qq_add_request;
+struct _qq_add_request {
+ guint32 uid;
+ PurpleConnection *gc;
+};
+
struct _qq_interval {
gint resend;
gint keep_alive;
@@ -151,15 +157,8 @@ struct _qq_data {
GSList *joining_groups;
GSList *adding_groups_from_server; /* internal ids of groups the server wants in my blist */
GList *buddies;
- GList *contact_info_window;
GList *group_info_window;
- GList *info_query;
- GList *add_buddy_request;
- /* 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;
};
============================================================
--- libpurple/protocols/qq/qq_network.c acc9eb8a8d8abb8a7230923a29e51d949a2f69f2
+++ libpurple/protocols/qq/qq_network.c a8e9da018f66d0d8ce5641e76142356bb0cd03a3
@@ -285,6 +285,10 @@ static gboolean packet_process(PurpleCon
update_class = qq_trans_get_class(trans);
ship32 = qq_trans_get_ship(trans);
+ if (update_class != 0 || ship32 != 0) {
+ purple_debug_info("QQ", "Process in Update class %d, ship32 %d\n",
+ update_class, ship32);
+ }
switch (cmd) {
case QQ_CMD_TOKEN:
@@ -998,8 +1002,6 @@ void qq_disconnect(PurpleConnection *gc)
qd->my_ip.s_addr = 0;
qq_group_free_all(qd);
- qq_add_buddy_request_free(qd);
- qq_info_query_free(qd);
qq_buddies_list_free(gc->account, qd);
}
============================================================
--- libpurple/protocols/qq/qq_process.c 92d4fd7a3a8e5d7db7b46fcbac1d64024464831d
+++ libpurple/protocols/qq/qq_process.c 587c83dd9bd715ffdc1da1e0a6cce725971355ef
@@ -30,10 +30,10 @@
#include "buddy_list.h"
#include "buddy_opt.h"
#include "group_info.h"
-#include "group_free.h"
#include "char_conv.h"
#include "qq_crypt.h"
+#include "group_search.h"
#include "group_conv.h"
#include "group_find.h"
#include "group_internal.h"
@@ -41,7 +41,6 @@
#include "group_info.h"
#include "group_join.h"
#include "group_opt.h"
-#include "group_search.h"
#include "header_info.h"
#include "qq_base.h"
@@ -50,7 +49,6 @@
#include "packet_parse.h"
#include "qq_network.h"
#include "qq_trans.h"
-#include "sys_msg.h"
#include "utils.h"
enum {
@@ -83,6 +81,111 @@ static void process_cmd_unknow(PurpleCon
}
}
+/* Send ACK if the sys message needs an ACK */
+static void _qq_send_packet_ack_msg_sys(PurpleConnection *gc, guint8 code, guint32 from, guint16 seq)
+{
+ qq_data *qd;
+ guint8 bar, *ack;
+ gchar *str;
+ 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;
+ ack = g_newa(guint8, ack_len);
+
+ bytes = 0;
+ bytes += qq_put8(ack + bytes, code);
+ bytes += qq_put8(ack + bytes, bar);
+ bytes += qq_putdata(ack + bytes, (guint8 *) str, strlen(str));
+ bytes += qq_put8(ack + bytes, bar);
+ bytes += qq_put16(ack + bytes, seq);
+
+ g_free(str);
+
+ if (bytes == ack_len) /* creation OK */
+ qq_send_server_reply(gc, QQ_CMD_ACK_SYS_MSG, 0, ack, ack_len);
+ else
+ purple_debug_error("QQ",
+ "Fail creating sys msg ACK, expect %d bytes, build %d bytes\n", ack_len, bytes);
+}
+
+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(_("From %s:"), from);
+ content = g_strdup_printf(_("%s"), msg_utf8);
+
+ if (qd->is_show_notice) {
+ purple_notify_info(gc, _("QQ Server Notice"), title, content);
+ } else {
+ purple_debug_info("QQ", "QQ Server notice from %s:\n%s", from, msg_utf8);
+}
+ g_free(title);
+ g_free(content);
+}
+
+static void process_server_msg(guint8 *data, gint data_len, guint16 seq, PurpleConnection *gc)
+{
+ qq_data *qd;
+ gchar **segments, *code, *from, *to, *msg, *msg_utf8;
+ int funct;
+
+ g_return_if_fail(data != NULL && data_len != 0);
+
+ qd = (qq_data *) gc->proto_data;
+
+ if (NULL == (segments = split_data(data, data_len, "\x1f", 4)))
+ return;
+ code = segments[0];
+ from = segments[1];
+ to = segments[2];
+ msg = segments[3];
+
+ _qq_send_packet_ack_msg_sys(gc, code[0], strtol(from, NULL, 10), seq);
+
+ if (strtol(to, NULL, 10) != qd->uid) { /* not to me */
+ purple_debug_error("QQ", "Recv sys msg to [%s], not me!, discard\n", to);
+ g_strfreev(segments);
+ return;
+ }
+
+ msg_utf8 = qq_to_utf8(msg, QQ_CHARSET_DEFAULT);
+ if (from == NULL && msg_utf8) {
+ purple_debug_error("QQ", "Recv NULL sys msg to [%s], discard\n", to);
+ g_strfreev(segments);
+ g_free(msg_utf8);
+ return;
+ }
+
+ funct = strtol(code, NULL, 10);
+ switch (funct) {
+ case QQ_SERVER_BUDDY_ADDED:
+ case QQ_SERVER_BUDDY_ADD_REQUEST:
+ case QQ_SERVER_BUDDY_ADDED_ME:
+ case QQ_SERVER_BUDDY_REJECTED_ME:
+ qq_process_buddy_from_server(gc, funct, from, to, msg_utf8);
+ break;
+ case QQ_SERVER_NOTICE:
+ _qq_process_msg_sys_notice(gc, from, to, msg_utf8);
+ break;
+ case QQ_SERVER_NEW_CLIENT:
+ purple_debug_warning("QQ",
+ "QQ Server has newer client than %s\n", qq_get_ver_desc(QQ_CLIENT));
+ break;
+ default:
+ purple_debug_warning("QQ", "Recv unknown sys msg code: %s\nMsg: %s\n", code, msg_utf8);
+ }
+ g_free(msg_utf8);
+ g_strfreev(segments);
+}
+
void qq_proc_server_cmd(PurpleConnection *gc, guint16 cmd, guint16 seq, guint8 *rcved, gint rcved_len)
{
qq_data *qd;
@@ -116,7 +219,7 @@ void qq_proc_server_cmd(PurpleConnection
qq_process_recv_im(data, data_len, seq, gc);
break;
case QQ_CMD_RECV_MSG_SYS:
- qq_process_msg_sys(data, data_len, seq, gc);
+ process_server_msg(data, data_len, seq, gc);
break;
case QQ_CMD_BUDDY_CHANGE_STATUS:
qq_process_buddy_change_status(data, data_len, gc);
@@ -189,7 +292,7 @@ void qq_update_room(PurpleConnection *gc
}
}
-static void update_all_rooms(PurpleConnection *gc, guint8 room_cmd, guint32 room_id)
+void qq_update_all_rooms(PurpleConnection *gc, guint8 room_cmd, guint32 room_id)
{
qq_data *qd;
gboolean is_new_turn = FALSE;
@@ -244,7 +347,7 @@ void qq_update_all(PurpleConnection *gc,
switch (cmd) {
case 0:
- qq_request_buddy_info(gc, qd->uid, QQ_CMD_CLASS_UPDATE_ALL, QQ_BUDDY_INFO_UPDATE_ONLY);
+ qq_request_buddy_info(gc, qd->uid, QQ_CMD_CLASS_UPDATE_ALL, 0);
break;
case QQ_CMD_GET_BUDDY_INFO:
qq_request_change_status(gc, QQ_CMD_CLASS_UPDATE_ALL);
@@ -263,7 +366,7 @@ void qq_update_all(PurpleConnection *gc,
break;
case QQ_CMD_GET_BUDDIES_ONLINE:
/* last command */
- update_all_rooms(gc, 0, 0);
+ qq_update_all_rooms(gc, 0, 0);
break;
default:
break;
@@ -451,9 +554,8 @@ void qq_proc_room_cmd(PurpleConnection *
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) {
- update_all_rooms(gc, room_cmd, room_id);
+ qq_update_all_rooms(gc, room_cmd, room_id);
return;
}
if (update_class == QQ_CMD_CLASS_UPDATE_ONLINE) {
@@ -506,9 +608,6 @@ void qq_proc_login_cmd(PurpleConnection
/* 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;
-
/* is_login, but we have packets before login */
qq_trans_process_remained(gc);
@@ -555,20 +654,20 @@ void qq_proc_client_cmd(PurpleConnection
case QQ_CMD_UPDATE_INFO:
qq_process_modify_info_reply(data, data_len, gc);
break;
- case QQ_CMD_ADD_BUDDY_WO_AUTH:
- qq_process_add_buddy_reply(data, data_len, seq, gc);
+ case QQ_CMD_BUDDY_ADD_NO_AUTH:
+ qq_process_buddy_add_no_auth(data, data_len, ship32, gc);
break;
- case QQ_CMD_DEL_BUDDY:
- qq_process_remove_buddy_reply(data, data_len, gc);
+ case QQ_CMD_BUDDY_REMOVE:
+ qq_process_buddy_remove(data, data_len, gc);
break;
- case QQ_CMD_REMOVE_SELF:
- qq_process_remove_self_reply(data, data_len, gc);
+ case QQ_CMD_REMOVE_ME:
+ qq_process_buddy_remove_me(data, data_len, gc);
break;
- case QQ_CMD_BUDDY_AUTH:
- qq_process_add_buddy_auth_reply(data, data_len, gc);
+ case QQ_CMD_BUDDY_ADD_AUTH:
+ qq_process_buddy_add_auth(data, data_len, gc);
break;
case QQ_CMD_GET_BUDDY_INFO:
- qq_process_get_buddy_info(data, data_len, gc);
+ qq_process_get_buddy_info(data, data_len, ship32, gc);
break;
case QQ_CMD_CHANGE_STATUS:
qq_process_change_status_reply(data, data_len, gc);
============================================================
--- libpurple/protocols/qq/qq_process.h daf522411883f437790ee7a6bea67f70f0842d35
+++ libpurple/protocols/qq/qq_process.h 8c9135998e632d7d4b13a3373fde6fee15053896
@@ -34,6 +34,7 @@ enum {
QQ_CMD_CLASS_NONE = 0,
QQ_CMD_CLASS_UPDATE_ALL,
QQ_CMD_CLASS_UPDATE_ONLINE,
+ QQ_CMD_CLASS_UPDATE_BUDDY,
QQ_CMD_CLASS_UPDATE_ROOM,
};
@@ -49,5 +50,6 @@ void qq_update_room(PurpleConnection *gc
void qq_update_all(PurpleConnection *gc, guint16 cmd);
void qq_update_online(PurpleConnection *gc, guint16 cmd);
void qq_update_room(PurpleConnection *gc, guint8 room_cmd, guint32 room_id);
+void qq_update_all_rooms(PurpleConnection *gc, guint8 room_cmd, guint32 room_id);
#endif
============================================================
--- libpurple/protocols/qq/qq_trans.c e34b93f6399a872a447715a13e8dc4e1b6866dd5
+++ libpurple/protocols/qq/qq_trans.c f513eebd952e6d6aaefa38b76dbc42f2bca7f3a5
@@ -131,6 +131,7 @@ static qq_transaction *trans_create(Purp
}
trans->update_class = update_class;
+ trans->ship32 = ship32;
return trans;
}
More information about the Commits
mailing list