Mercurial > pidgin.yaz
annotate libgaim/protocols/qq/buddy_info.c @ 15140:63d554c2675d
[gaim-migrate @ 17925]
This seems like a reasonable way to tell the prpl if we're using a local or global buddy icon.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Huetsch <markhuetsch> |
---|---|
date | Sat, 09 Dec 2006 07:20:46 +0000 |
parents | e952a5fc97b3 |
children | b81e4e44b509 |
rev | line source |
---|---|
14192 | 1 /** |
15026 | 2 * @file buddy_info.c |
14192 | 3 * |
15026 | 4 * gaim |
14192 | 5 * |
15026 | 6 * Gaim is the legal property of its developers, whose names are too numerous |
7 * to list here. Please refer to the COPYRIGHT file distributed with this | |
8 * source distribution. | |
14192 | 9 * |
10 * This program is free software; you can redistribute it and/or modify | |
11 * it under the terms of the GNU General Public License as published by | |
12 * the Free Software Foundation; either version 2 of the License, or | |
13 * (at your option) any later version. | |
14 * | |
15 * This program is distributed in the hope that it will be useful, | |
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 * GNU General Public License for more details. | |
19 * | |
20 * You should have received a copy of the GNU General Public License | |
21 * along with this program; if not, write to the Free Software | |
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
23 */ | |
24 | |
25 #include "internal.h" | |
26 #include "debug.h" | |
27 #include "notify.h" | |
28 #include "request.h" | |
29 | |
30 #include "utils.h" | |
31 #include "packet_parse.h" | |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
32 #include "buddy_info.h" |
14192 | 33 #include "char_conv.h" |
34 #include "crypt.h" | |
35 #include "header_info.h" | |
36 #include "keep_alive.h" | |
37 #include "send_core.h" | |
38 | |
14611 | 39 #define QQ_PRIMARY_INFORMATION _("Primary Information") |
40 #define QQ_ADDITIONAL_INFORMATION _("Additional Information") | |
41 #define QQ_INTRO _("Personal Introduction") | |
42 #define QQ_NUMBER _("QQ Number") | |
43 #define QQ_NICKNAME _("Nickname") | |
44 #define QQ_NAME _("Name") | |
45 #define QQ_AGE _("Age") | |
46 #define QQ_GENDER _("Gender") | |
47 #define QQ_COUNTRY _("Country/Region") | |
48 #define QQ_PROVINCE _("Province/State") | |
49 #define QQ_CITY _("City") | |
50 #define QQ_HOROSCOPE _("Horoscope Symbol") | |
51 #define QQ_OCCUPATION _("Occupation") | |
52 #define QQ_ZODIAC _("Zodiac Sign") | |
53 #define QQ_BLOOD _("Blood Type") | |
54 #define QQ_COLLEGE _("College") | |
55 #define QQ_EMAIL _("Email") | |
56 #define QQ_ADDRESS _("Address") | |
57 #define QQ_ZIPCODE _("Zipcode") | |
58 #define QQ_CELL _("Cellphone Number") | |
59 #define QQ_TELEPHONE _("Phone Number") | |
60 #define QQ_HOMEPAGE _("Homepage") | |
14192 | 61 |
14611 | 62 #define QQ_HOROSCOPE_SIZE 13 |
14192 | 63 static const gchar *horoscope_names[] = { |
14611 | 64 "-", N_("Aquarius"), N_("Pisces"), N_("Aries"), N_("Taurus"), |
65 N_("Gemini"), N_("Cancer"), N_("Leo"), N_("Virgo"), N_("Libra"), | |
66 N_("Scorpio"), N_("Sagittarius"), N_("Capricorn") | |
14192 | 67 }; |
68 | |
14611 | 69 #define QQ_ZODIAC_SIZE 13 |
70 static const gchar *zodiac_names[] = { | |
71 "-", N_("Rat"), N_("Ox"), N_("Tiger"), N_("Rabbit"), | |
72 N_("Dragon"), N_("Snake"), N_("Horse"), N_("Goat"), N_("Monkey"), | |
73 N_("Rooster"), N_("Dog"), N_("Pig") | |
14192 | 74 }; |
75 | |
14611 | 76 #define QQ_BLOOD_SIZE 6 |
77 static const gchar *blood_types[] = { | |
78 "-", "A", "B", "O", "AB", N_("Other") | |
14192 | 79 }; |
80 | |
14611 | 81 #define QQ_GENDER_SIZE 2 |
82 static const gchar *genders[] = { | |
83 N_("Male"), | |
84 N_("Female") | |
14192 | 85 }; |
86 | |
14611 | 87 #define QQ_CONTACT_FIELDS 37 |
14192 | 88 |
14611 | 89 /* There is no user id stored in the reply packet for information query |
90 * we have to manually store the query, so that we know the query source */ | |
91 typedef struct _qq_info_query { | |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
92 guint32 uid; |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
93 gboolean show_window; |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
94 gboolean modify_info; |
14611 | 95 } qq_info_query; |
14192 | 96 |
14611 | 97 /* We get an info packet on ourselves before we modify our information. |
98 * Even though not all of the information is modifiable, it still | |
99 * all needs to be there when we send out the modify info packet */ | |
100 typedef struct _modify_info_data { | |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
101 GaimConnection *gc; |
14611 | 102 contact_info *info; |
103 } modify_info_data; | |
14192 | 104 |
14611 | 105 /* return -1 as a sentinel */ |
106 static gint choice_index(const gchar *value, const gchar **choice, gint choice_size) | |
14192 | 107 { |
108 gint len, i; | |
109 | |
110 len = strlen(value); | |
14611 | 111 if (len > 3 || len == 0) return -1; |
112 for (i = 0; i < len; i++) { | |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
113 if (!g_ascii_isdigit(value[i])) |
14611 | 114 return -1; |
115 } | |
116 i = strtol(value, NULL, 10); | |
117 if (i >= choice_size) | |
118 return -1; | |
119 | |
120 return i; | |
121 } | |
122 | |
123 /* return should be freed */ | |
124 static gchar *field_value(const gchar *field, const gchar **choice, gint choice_size) | |
125 { | |
126 gint index, len; | |
127 | |
128 len = strlen(field); | |
129 if (len == 0) { | |
130 return NULL; | |
131 } else if (choice != NULL) { | |
132 /* some choice fields are also customizable */ | |
133 index = choice_index(field, choice, choice_size); | |
134 if (index == -1) { | |
135 if (strcmp(field, "-") != 0) { | |
136 return qq_to_utf8(field, QQ_CHARSET_DEFAULT); | |
137 } else { | |
138 return NULL; | |
139 } | |
140 /* else ASCIIized index */ | |
141 } else { | |
142 if (strcmp(choice[index], "-") != 0) | |
143 return g_strdup(choice[index]); | |
144 else | |
145 return NULL; | |
146 } | |
147 } else { | |
148 if (strcmp(field, "-") != 0) { | |
149 return qq_to_utf8(field, QQ_CHARSET_DEFAULT); | |
150 } else { | |
151 return NULL; | |
152 } | |
153 } | |
154 } | |
155 | |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
156 static void append_field_value(GString *info_text, const gchar *field, |
14611 | 157 const gchar *title, const gchar **choice, gint choice_size) |
158 { | |
159 gchar *value = field_value(field, choice, choice_size); | |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
160 |
14611 | 161 if (value != NULL) { |
162 g_string_append_printf(info_text, "<br /><b>%s:</b> %s", title, value); | |
163 g_free(value); | |
164 } | |
14192 | 165 } |
166 | |
14611 | 167 static GString *info_to_str(const contact_info *info) |
14192 | 168 { |
14611 | 169 GString *info_text, *extra_info; |
170 const gchar *intro; | |
171 gint len; | |
14192 | 172 |
173 info_text = g_string_new(""); | |
14611 | 174 g_string_append_printf(info_text, "<b>%s</b><br /><br />", QQ_PRIMARY_INFORMATION); |
175 g_string_append_printf(info_text, "<b>%s:</b> %s", QQ_NUMBER, info->uid); | |
176 append_field_value(info_text, info->nick, QQ_NICKNAME, NULL, 0); | |
177 append_field_value(info_text, info->name, QQ_NAME, NULL, 0); | |
178 append_field_value(info_text, info->age, QQ_AGE, NULL, 0); | |
179 append_field_value(info_text, info->gender, QQ_GENDER, genders, QQ_GENDER_SIZE); | |
180 append_field_value(info_text, info->country, QQ_COUNTRY, NULL, 0); | |
181 append_field_value(info_text, info->province, QQ_PROVINCE, NULL, 0); | |
182 append_field_value(info_text, info->city, QQ_CITY, NULL, 0); | |
183 | |
184 extra_info = g_string_new(""); | |
185 g_string_append_printf(extra_info, "<br /><br /><b>%s</b><br />", QQ_ADDITIONAL_INFORMATION); | |
186 len = extra_info->len; | |
187 append_field_value(extra_info, info->horoscope, QQ_HOROSCOPE, horoscope_names, QQ_HOROSCOPE_SIZE); | |
188 append_field_value(extra_info, info->occupation, QQ_OCCUPATION, NULL, 0); | |
189 append_field_value(extra_info, info->zodiac, QQ_ZODIAC, zodiac_names, QQ_ZODIAC_SIZE); | |
190 append_field_value(extra_info, info->blood, QQ_BLOOD, blood_types, QQ_BLOOD_SIZE); | |
191 append_field_value(extra_info, info->college, QQ_COLLEGE, NULL, 0); | |
192 append_field_value(extra_info, info->email, QQ_EMAIL, NULL, 0); | |
193 append_field_value(extra_info, info->address, QQ_ADDRESS, NULL, 0); | |
194 append_field_value(extra_info, info->zipcode, QQ_ZIPCODE, NULL, 0); | |
195 append_field_value(extra_info, info->hp_num, QQ_CELL, NULL, 0); | |
196 append_field_value(extra_info, info->tel, QQ_TELEPHONE, NULL, 0); | |
197 append_field_value(extra_info, info->homepage, QQ_HOMEPAGE, NULL, 0); | |
198 if (len != extra_info->len) | |
199 g_string_append(info_text, extra_info->str); | |
200 g_string_free(extra_info, TRUE); | |
201 | |
202 intro = field_value(info->intro, NULL, 0); | |
203 if (intro) { | |
204 g_string_append_printf(info_text, "<br /><br /><b>%s</b><br /><br />", QQ_INTRO); | |
205 g_string_append(info_text, intro); | |
206 } | |
207 | |
208 /* for debugging */ | |
209 /* | |
210 g_string_append_printf(info_text, "<br /><br /><b>%s</b><br />", "Miscellaneous"); | |
211 append_field_value(info_text, info->pager_sn, "pager_sn", NULL, 0); | |
212 append_field_value(info_text, info->pager_num, "pager_num", NULL, 0); | |
213 append_field_value(info_text, info->pager_sp, "pager_sp", NULL, 0); | |
214 append_field_value(info_text, info->pager_base_num, "pager_base_num", NULL, 0); | |
215 append_field_value(info_text, info->pager_type, "pager_type", NULL, 0); | |
216 append_field_value(info_text, info->auth_type, "auth_type", NULL, 0); | |
217 append_field_value(info_text, info->unknown1, "unknown1", NULL, 0); | |
218 append_field_value(info_text, info->unknown2, "unknown2", NULL, 0); | |
219 append_field_value(info_text, info->face, "face", NULL, 0); | |
220 append_field_value(info_text, info->hp_type, "hp_type", NULL, 0); | |
221 append_field_value(info_text, info->unknown3, "unknown3", NULL, 0); | |
222 append_field_value(info_text, info->unknown4, "unknown4", NULL, 0); | |
223 append_field_value(info_text, info->unknown5, "unknown5", NULL, 0); | |
224 append_field_value(info_text, info->is_open_hp, "is_open_hp", NULL, 0); | |
225 append_field_value(info_text, info->is_open_contact, "is_open_contact", NULL, 0); | |
226 append_field_value(info_text, info->qq_show, "qq_show", NULL, 0); | |
227 append_field_value(info_text, info->unknown6, "unknown6", NULL, 0); | |
228 */ | |
14192 | 229 |
230 return info_text; | |
231 } | |
232 | |
233 /* send a packet to get detailed information of uid */ | |
14265 | 234 void qq_send_packet_get_info(GaimConnection *gc, guint32 uid, gboolean show_window) |
14192 | 235 { |
236 qq_data *qd; | |
14519 | 237 gchar uid_str[11]; |
14192 | 238 qq_info_query *query; |
239 | |
14629 | 240 g_return_if_fail(uid != 0); |
14192 | 241 |
242 qd = (qq_data *) gc->proto_data; | |
14519 | 243 g_snprintf(uid_str, sizeof(uid_str), "%d", uid); |
14192 | 244 qq_send_cmd(gc, QQ_CMD_GET_USER_INFO, TRUE, 0, TRUE, (guint8 *) uid_str, strlen(uid_str)); |
245 | |
246 query = g_new0(qq_info_query, 1); | |
247 query->uid = uid; | |
248 query->show_window = show_window; | |
249 query->modify_info = FALSE; | |
250 qd->info_query = g_list_append(qd->info_query, query); | |
251 } | |
252 | |
253 /* set up the fields requesting personal information and send a get_info packet | |
254 * for myself */ | |
255 void qq_prepare_modify_info(GaimConnection *gc) | |
256 { | |
257 qq_data *qd; | |
258 GList *ql; | |
259 qq_info_query *query; | |
260 | |
261 qd = (qq_data *) gc->proto_data; | |
262 qq_send_packet_get_info(gc, qd->uid, FALSE); | |
263 /* traverse backwards so we get the most recent info_query */ | |
264 for (ql = g_list_last(qd->info_query); ql != NULL; ql = g_list_previous(ql)) { | |
265 query = ql->data; | |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
266 if (query->uid == qd->uid) |
14192 | 267 query->modify_info = TRUE; |
268 } | |
269 } | |
270 | |
271 /* send packet to modify personal information */ | |
14611 | 272 static void qq_send_packet_modify_info(GaimConnection *gc, gchar **segments) |
14192 | 273 { |
274 gint i; | |
275 guint8 *raw_data, *cursor, bar; | |
276 | |
14629 | 277 g_return_if_fail(segments != NULL); |
14192 | 278 |
279 bar = 0x1f; | |
280 raw_data = g_newa(guint8, MAX_PACKET_SIZE - 128); | |
281 cursor = raw_data; | |
282 | |
283 create_packet_b(raw_data, &cursor, bar); | |
284 | |
14611 | 285 /* important! skip the first uid entry */ |
14192 | 286 for (i = 1; i < QQ_CONTACT_FIELDS; i++) { |
287 create_packet_b(raw_data, &cursor, bar); | |
14611 | 288 create_packet_data(raw_data, &cursor, (guint8 *) segments[i], strlen(segments[i])); |
14192 | 289 } |
290 create_packet_b(raw_data, &cursor, bar); | |
291 | |
292 qq_send_cmd(gc, QQ_CMD_UPDATE_INFO, TRUE, 0, TRUE, raw_data, cursor - raw_data); | |
293 | |
294 } | |
295 | |
296 static void modify_info_cancel_cb(modify_info_data *mid) | |
297 { | |
298 qq_data *qd; | |
299 | |
300 qd = (qq_data *) mid->gc->proto_data; | |
301 qd->modifying_info = FALSE; | |
302 | |
14611 | 303 g_strfreev((gchar **) mid->info); |
14192 | 304 g_free(mid); |
305 } | |
306 | |
14611 | 307 static gchar *parse_field(GList **list, gboolean choice) |
14192 | 308 { |
14611 | 309 gchar *value; |
310 GaimRequestField *field; | |
14192 | 311 |
14611 | 312 field = (GaimRequestField *) (*list)->data; |
313 if (choice) { | |
314 value = g_strdup_printf("%d", gaim_request_field_choice_get_value(field)); | |
14192 | 315 } else { |
14611 | 316 value = (gchar *) gaim_request_field_string_get_value(field); |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
317 if (value == NULL) |
14192 | 318 value = g_strdup("-"); |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
319 else |
14192 | 320 value = utf8_to_qq(value, QQ_CHARSET_DEFAULT); |
321 } | |
14611 | 322 *list = g_list_remove_link(*list, *list); |
323 | |
324 return value; | |
14192 | 325 } |
326 | |
14611 | 327 /* parse fields and send info packet */ |
14192 | 328 static void modify_info_ok_cb(modify_info_data *mid, GaimRequestFields *fields) |
329 { | |
330 GaimConnection *gc; | |
331 qq_data *qd; | |
14611 | 332 GList *list, *groups; |
14192 | 333 contact_info *info; |
334 | |
335 gc = mid->gc; | |
336 qd = (qq_data *) gc->proto_data; | |
337 qd->modifying_info = FALSE; | |
14611 | 338 |
339 info = mid->info; | |
340 | |
14192 | 341 groups = gaim_request_fields_get_groups(fields); |
14611 | 342 list = gaim_request_field_group_get_fields(groups->data); |
343 info->uid = parse_field(&list, FALSE); | |
344 info->nick = parse_field(&list, FALSE); | |
345 info->name = parse_field(&list, FALSE); | |
346 info->age = parse_field(&list, FALSE); | |
347 info->gender = parse_field(&list, TRUE); | |
348 info->country = parse_field(&list, FALSE); | |
349 info->province = parse_field(&list, FALSE); | |
350 info->city = parse_field(&list, FALSE); | |
351 groups = g_list_remove_link(groups, groups); | |
352 list = gaim_request_field_group_get_fields(groups->data); | |
353 info->horoscope = parse_field(&list, TRUE); | |
354 info->occupation = parse_field(&list, FALSE); | |
355 info->zodiac = parse_field(&list, TRUE); | |
356 info->blood = parse_field(&list, TRUE); | |
357 info->college = parse_field(&list, FALSE); | |
358 info->email = parse_field(&list, FALSE); | |
359 info->address = parse_field(&list, FALSE); | |
360 info->zipcode = parse_field(&list, FALSE); | |
361 info->hp_num = parse_field(&list, FALSE); | |
362 info->tel = parse_field(&list, FALSE); | |
363 info->homepage = parse_field(&list, FALSE); | |
364 groups = g_list_remove_link(groups, groups); | |
365 list = gaim_request_field_group_get_fields(groups->data); | |
366 info->intro = parse_field(&list, FALSE); | |
367 groups = g_list_remove_link(groups, groups); | |
14192 | 368 |
14611 | 369 qq_send_packet_modify_info(gc, (gchar **) info); |
370 | |
371 g_strfreev((gchar **) mid->info); | |
14192 | 372 g_free(mid); |
373 } | |
374 | |
14611 | 375 static GaimRequestFieldGroup *setup_field_group(GaimRequestFields *fields, const gchar *title) |
14192 | 376 { |
14611 | 377 GaimRequestFieldGroup *group; |
14192 | 378 |
14611 | 379 group = gaim_request_field_group_new(title); |
380 gaim_request_fields_add_group(fields, group); | |
381 | |
382 return group; | |
383 } | |
14192 | 384 |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
385 static void add_string_field_to_group(GaimRequestFieldGroup *group, |
14611 | 386 const gchar *id, const gchar *title, const gchar *value) |
387 { | |
388 GaimRequestField *field; | |
389 gchar *utf8_value; | |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
390 |
14611 | 391 utf8_value = qq_to_utf8(value, QQ_CHARSET_DEFAULT); |
392 field = gaim_request_field_string_new(id, title, utf8_value, FALSE); | |
393 gaim_request_field_group_add_field(group, field); | |
394 g_free(utf8_value); | |
14192 | 395 } |
396 | |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
397 static void add_choice_field_to_group(GaimRequestFieldGroup *group, |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
398 const gchar *id, const gchar *title, const gchar *value, |
14611 | 399 const gchar **choice, gint choice_size) |
400 { | |
401 GaimRequestField *field; | |
402 gint i, index; | |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
403 |
14611 | 404 index = choice_index(value, choice, choice_size); |
405 field = gaim_request_field_choice_new(id, title, index); | |
406 for (i = 0; i < choice_size; i++) | |
407 gaim_request_field_choice_add(field, choice[i]); | |
408 gaim_request_field_group_add_field(group, field); | |
409 } | |
410 | |
411 /* take the info returned by a get_info packet for myself and set up a request form */ | |
412 static void create_modify_info_dialogue(GaimConnection *gc, const contact_info *info) | |
14192 | 413 { |
414 qq_data *qd; | |
14611 | 415 GaimRequestFieldGroup *group; |
14192 | 416 GaimRequestFields *fields; |
417 GaimRequestField *field; | |
418 modify_info_data *mid; | |
419 | |
420 /* so we only have one dialog open at a time */ | |
421 qd = (qq_data *) gc->proto_data; | |
422 if (!qd->modifying_info) { | |
423 qd->modifying_info = TRUE; | |
424 | |
425 fields = gaim_request_fields_new(); | |
426 | |
14611 | 427 group = setup_field_group(fields, QQ_PRIMARY_INFORMATION); |
428 field = gaim_request_field_string_new("uid", QQ_NUMBER, info->uid, FALSE); | |
429 gaim_request_field_group_add_field(group, field); | |
14192 | 430 gaim_request_field_string_set_editable(field, FALSE); |
14611 | 431 add_string_field_to_group(group, "nick", QQ_NICKNAME, info->nick); |
432 add_string_field_to_group(group, "name", QQ_NAME, info->name); | |
433 add_string_field_to_group(group, "age", QQ_AGE, info->age); | |
434 add_choice_field_to_group(group, "gender", QQ_GENDER, info->gender, genders, QQ_GENDER_SIZE); | |
435 add_string_field_to_group(group, "country", QQ_COUNTRY, info->country); | |
436 add_string_field_to_group(group, "province", QQ_PROVINCE, info->province); | |
437 add_string_field_to_group(group, "city", QQ_CITY, info->city); | |
438 group = setup_field_group(fields, QQ_ADDITIONAL_INFORMATION); | |
439 add_choice_field_to_group(group, "horoscope", QQ_HOROSCOPE, info->horoscope, horoscope_names, QQ_HOROSCOPE_SIZE); | |
440 add_string_field_to_group(group, "occupation", QQ_OCCUPATION, info->occupation); | |
441 add_choice_field_to_group(group, "zodiac", QQ_ZODIAC, info->zodiac, zodiac_names, QQ_ZODIAC_SIZE); | |
442 add_choice_field_to_group(group, "blood", QQ_BLOOD, info->blood, blood_types, QQ_BLOOD_SIZE); | |
443 add_string_field_to_group(group, "college", QQ_COLLEGE, info->college); | |
444 add_string_field_to_group(group, "email", QQ_EMAIL, info->email); | |
445 add_string_field_to_group(group, "address", QQ_ADDRESS, info->address); | |
446 add_string_field_to_group(group, "zipcode", QQ_ZIPCODE, info->zipcode); | |
447 add_string_field_to_group(group, "hp_num", QQ_CELL, info->hp_num); | |
448 add_string_field_to_group(group, "tel", QQ_TELEPHONE, info->tel); | |
449 add_string_field_to_group(group, "homepage", QQ_HOMEPAGE, info->homepage); | |
14192 | 450 |
14611 | 451 group = setup_field_group(fields, QQ_INTRO); |
452 field = gaim_request_field_string_new("intro", QQ_INTRO, info->intro, TRUE); | |
453 gaim_request_field_group_add_field(group, field); | |
454 | |
455 /* prepare unmodifiable info */ | |
14192 | 456 mid = g_new0(modify_info_data, 1); |
457 mid->gc = gc; | |
14611 | 458 /* QQ_CONTACT_FIELDS+1 so that the array is NULL-terminated and can be g_strfreev()'ed later */ |
459 mid->info = (contact_info *) g_new0(gchar *, QQ_CONTACT_FIELDS+1); | |
460 mid->info->pager_sn = g_strdup(info->pager_sn); | |
461 mid->info->pager_num = g_strdup(info->pager_num); | |
462 mid->info->pager_sp = g_strdup(info->pager_sp); | |
463 mid->info->pager_base_num = g_strdup(info->pager_base_num); | |
464 mid->info->pager_type = g_strdup(info->pager_type); | |
465 mid->info->auth_type = g_strdup(info->auth_type); | |
466 mid->info->unknown1 = g_strdup(info->unknown1); | |
467 mid->info->unknown2 = g_strdup(info->unknown2); | |
468 mid->info->face = g_strdup(info->face); | |
469 mid->info->hp_type = g_strdup(info->hp_type); | |
470 mid->info->unknown3 = g_strdup(info->unknown3); | |
471 mid->info->unknown4 = g_strdup(info->unknown4); | |
472 mid->info->unknown5 = g_strdup(info->unknown5); | |
473 /* TODO stop hiding these 2 */ | |
474 mid->info->is_open_hp = g_strdup(info->is_open_hp); | |
475 mid->info->is_open_contact = g_strdup(info->is_open_contact); | |
476 mid->info->qq_show = g_strdup(info->qq_show); | |
477 mid->info->unknown6 = g_strdup(info->unknown6); | |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
478 |
14192 | 479 gaim_request_fields(gc, _("Modify my information"), |
480 _("Modify my information"), NULL, fields, | |
481 _("Update my information"), G_CALLBACK(modify_info_ok_cb), | |
482 _("Cancel"), G_CALLBACK(modify_info_cancel_cb), | |
483 mid); | |
484 } | |
485 } | |
486 | |
487 /* process the reply of modify_info packet */ | |
488 void qq_process_modify_info_reply(guint8 *buf, gint buf_len, GaimConnection *gc) | |
489 { | |
490 qq_data *qd; | |
491 gint len; | |
492 guint8 *data; | |
493 | |
494 g_return_if_fail(buf != NULL && buf_len != 0); | |
495 | |
496 qd = (qq_data *) gc->proto_data; | |
497 len = buf_len; | |
498 data = g_newa(guint8, len); | |
499 | |
500 if (qq_crypt(DECRYPT, buf, buf_len, qd->session_key, data, &len)) { | |
501 data[len] = '\0'; | |
502 if (qd->uid == atoi((gchar *) data)) { /* return should be my uid */ | |
503 gaim_debug(GAIM_DEBUG_INFO, "QQ", "Update info ACK OK\n"); | |
504 gaim_notify_info(gc, NULL, _("Your information has been updated"), NULL); | |
505 } | |
506 } else { | |
507 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Error decrypt modify info reply\n"); | |
508 } | |
509 } | |
510 | |
15072 | 511 static void _qq_send_packet_modify_face(GaimConnection *gc, gint face_num) |
512 { | |
513 GaimAccount *account = gaim_connection_get_account(gc); | |
514 GaimPresence *presence = gaim_account_get_presence(account); | |
515 qq_data *qd = (qq_data *) gc->proto_data; | |
516 gint offset; | |
517 | |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
518 if(gaim_presence_is_status_primitive_active(presence, GAIM_STATUS_INVISIBLE)) { |
15072 | 519 offset = 2; |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
520 } else if(gaim_presence_is_status_primitive_active(presence, GAIM_STATUS_AWAY) |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
521 || gaim_presence_is_status_primitive_active(presence, GAIM_STATUS_EXTENDED_AWAY)) { |
15072 | 522 offset = 1; |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
523 } else { |
15072 | 524 offset = 0; |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
525 } |
15072 | 526 |
527 qd->my_icon = 3 * (face_num - 1) + offset; | |
528 qd->modifying_face = TRUE; | |
529 qq_send_packet_get_info(gc, qd->uid, FALSE); | |
530 } | |
531 | |
532 void qq_set_buddy_icon_for_user(GaimAccount *account, const gchar *who, const gchar *iconfile) | |
533 { | |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
534 FILE *file; |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
535 struct stat st; |
15072 | 536 |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
537 g_return_if_fail(g_stat(iconfile, &st) == 0); |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
538 file = g_fopen(iconfile, "rb"); |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
539 if (file) { |
15072 | 540 GaimBuddyIcon *icon; |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
541 size_t data_len; |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
542 gchar *data = g_new(gchar, st.st_size + 1); |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
543 data_len = fread(data, 1, st.st_size, file); |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
544 fclose(file); |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
545 gaim_buddy_icons_set_for_user(account, who, data, data_len); |
15072 | 546 icon = gaim_buddy_icons_find(account, who); |
547 gaim_buddy_icon_set_path(icon, iconfile); | |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
548 } |
15072 | 549 } |
550 | |
15140 | 551 /* TODO: custom faces for QQ members and users with level >= 16 */ |
15072 | 552 void qq_set_my_buddy_icon(GaimConnection *gc, const gchar *iconfile) |
553 { | |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
554 gchar *icon; |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
555 gint icon_num; |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
556 GaimAccount *account = gaim_connection_get_account(gc); |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
557 const gchar *icon_path = gaim_account_get_buddy_icon_path(account); |
15139 | 558 const gchar *buddy_icon_dir = qq_buddy_icon_dir(); |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
559 gint prefix_len = strlen(QQ_ICON_PREFIX); |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
560 gint suffix_len = strlen(QQ_ICON_SUFFIX); |
15139 | 561 gint dir_len = strlen(buddy_icon_dir); |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
562 gint icon_len = strlen(icon_path) - dir_len - 1 - prefix_len - suffix_len; |
15139 | 563 gchar *errmsg = g_strconcat(_("You are attempting to set a custom face. Gaim currently only allows the standard faces. Please choose an image from "), buddy_icon_dir, ".", NULL); |
15140 | 564 gboolean icon_global = gaim_account_get_bool(gc->account, "use-global-buddyicon", TRUE); |
15072 | 565 |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
566 /* make sure we're using an appropriate icon */ |
15139 | 567 if (!(g_ascii_strncasecmp(icon_path, buddy_icon_dir, dir_len) == 0 |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
568 && icon_path[dir_len] == G_DIR_SEPARATOR |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
569 && g_ascii_strncasecmp(icon_path + dir_len + 1, QQ_ICON_PREFIX, prefix_len) == 0 |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
570 && g_ascii_strncasecmp(icon_path + dir_len + 1 + prefix_len + icon_len, QQ_ICON_SUFFIX, suffix_len) == 0 |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
571 && icon_len <= 3)) { |
15140 | 572 if (icon_global) |
573 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "%s\n", errmsg); | |
574 else | |
575 gaim_notify_error(gc, _("Invalid QQ Face"), errmsg, NULL); | |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
576 g_free(errmsg); |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
577 return; |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
578 } |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
579 /* strip everything but number */ |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
580 icon = g_strndup(icon_path + dir_len + 1 + prefix_len, icon_len); |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
581 icon_num = strtol(icon, NULL, 10); |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
582 g_free(icon); |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
583 /* ensure face number in proper range */ |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
584 if (icon_num > QQ_FACES) { |
15140 | 585 if (icon_global) |
586 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "%s\n", errmsg); | |
587 else | |
588 gaim_notify_error(gc, _("Invalid QQ Face"), errmsg, NULL); | |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
589 g_free(errmsg); |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
590 return; |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
591 } |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
592 g_free(errmsg); |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
593 /* tell server my icon changed */ |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
594 _qq_send_packet_modify_face(gc, icon_num); |
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
595 /* display in blist */ |
15072 | 596 qq_set_buddy_icon_for_user(account, account->username, icon_path); |
597 } | |
598 | |
15139 | 599 |
600 static void _qq_update_buddy_icon(GaimAccount *account, const gchar *name, gint face) | |
601 { | |
602 gchar *icon_path; | |
603 GaimBuddyIcon *icon = gaim_buddy_icons_find(account, name); | |
604 gchar *icon_num_str = face_to_icon_str(face); | |
605 const gchar *old_path = gaim_buddy_icon_get_path(icon); | |
606 const gchar *buddy_icon_dir = qq_buddy_icon_dir(); | |
607 | |
608 icon_path = g_strconcat(buddy_icon_dir, G_DIR_SEPARATOR_S, QQ_ICON_PREFIX, | |
609 icon_num_str, QQ_ICON_SUFFIX, NULL); | |
610 if (icon == NULL || old_path == NULL | |
611 || g_ascii_strcasecmp(icon_path, old_path) != 0) | |
612 qq_set_buddy_icon_for_user(account, name, icon_path); | |
613 g_free(icon_num_str); | |
614 g_free(icon_path); | |
615 } | |
616 | |
14192 | 617 /* after getting info or modify myself, refresh the buddy list accordingly */ |
618 void qq_refresh_buddy_and_myself(contact_info *info, GaimConnection *gc) | |
619 { | |
620 GaimBuddy *b; | |
621 qq_data *qd; | |
622 qq_buddy *q_bud; | |
15072 | 623 gchar *alias_utf8, *gaim_name; |
624 GaimAccount *account = gaim_connection_get_account(gc); | |
14192 | 625 |
626 qd = (qq_data *) gc->proto_data; | |
15072 | 627 gaim_name = uid_to_gaim_name(strtol(info->uid, NULL, 10)); |
14192 | 628 |
629 alias_utf8 = qq_to_utf8(info->nick, QQ_CHARSET_DEFAULT); | |
630 if (qd->uid == strtol(info->uid, NULL, 10)) { /* it is me */ | |
631 qd->my_icon = strtol(info->face, NULL, 10); | |
632 if (alias_utf8 != NULL) | |
15072 | 633 gaim_account_set_alias(account, alias_utf8); |
14192 | 634 } |
635 /* update buddy list (including myself, if myself is the buddy) */ | |
15072 | 636 b = gaim_find_buddy(gc->account, gaim_name); |
14192 | 637 q_bud = (b == NULL) ? NULL : (qq_buddy *) b->proto_data; |
638 if (q_bud != NULL) { /* I have this buddy */ | |
639 q_bud->age = strtol(info->age, NULL, 10); | |
640 q_bud->gender = strtol(info->gender, NULL, 10); | |
15072 | 641 q_bud->face = strtol(info->face, NULL, 10); |
14192 | 642 if (alias_utf8 != NULL) |
643 q_bud->nickname = g_strdup(alias_utf8); | |
644 qq_update_buddy_contact(gc, q_bud); | |
15139 | 645 _qq_update_buddy_icon(gc->account, gaim_name, q_bud->face); |
14192 | 646 } |
15072 | 647 g_free(gaim_name); |
14192 | 648 g_free(alias_utf8); |
649 } | |
650 | |
651 /* process reply to get_info packet */ | |
652 void qq_process_get_info_reply(guint8 *buf, gint buf_len, GaimConnection *gc) | |
653 { | |
654 gint len; | |
655 guint8 *data; | |
656 gchar **segments; | |
657 qq_info_query *query; | |
658 qq_data *qd; | |
659 contact_info *info; | |
660 GList *list, *query_list; | |
661 GString *info_text; | |
662 | |
663 g_return_if_fail(buf != NULL && buf_len != 0); | |
664 | |
665 qd = (qq_data *) gc->proto_data; | |
666 list = query_list = NULL; | |
667 len = buf_len; | |
668 data = g_newa(guint8, len); | |
669 info = NULL; | |
670 | |
671 if (qq_crypt(DECRYPT, buf, buf_len, qd->session_key, data, &len)) { | |
672 if (NULL == (segments = split_data(data, len, "\x1e", QQ_CONTACT_FIELDS))) | |
673 return; | |
674 | |
675 info = (contact_info *) segments; | |
14265 | 676 if (qd->modifying_face && strtol(info->face, NULL, 10) != qd->my_icon) { |
15072 | 677 gchar *icon = g_strdup_printf("%d", qd->my_icon); |
14265 | 678 qd->modifying_face = FALSE; |
15072 | 679 g_free(info->face); |
680 info->face = icon; | |
14611 | 681 qq_send_packet_modify_info(gc, segments); |
14265 | 682 } |
683 | |
14192 | 684 qq_refresh_buddy_and_myself(info, gc); |
685 | |
686 query_list = qd->info_query; | |
687 /* ensure we're processing the right query */ | |
688 while (query_list) { | |
689 query = (qq_info_query *) query_list->data; | |
690 if (query->uid == atoi(info->uid)) { | |
691 if (query->show_window) { | |
14611 | 692 info_text = info_to_str(info); |
14192 | 693 gaim_notify_userinfo(gc, info->uid, info_text->str, NULL, NULL); |
694 g_string_free(info_text, TRUE); | |
695 } else if (query->modify_info) { | |
14611 | 696 create_modify_info_dialogue(gc, info); |
14192 | 697 } |
698 qd->info_query = g_list_remove(qd->info_query, qd->info_query->data); | |
699 g_free(query); | |
700 break; | |
701 } | |
702 query_list = query_list->next; | |
703 } | |
704 | |
705 g_strfreev(segments); | |
706 } else { | |
707 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Error decrypt get info reply\n"); | |
708 } | |
709 } | |
710 | |
711 void qq_info_query_free(qq_data *qd) | |
712 { | |
713 gint i; | |
714 qq_info_query *p; | |
715 | |
716 g_return_if_fail(qd != NULL); | |
717 | |
718 i = 0; | |
719 while (qd->info_query != NULL) { | |
720 p = (qq_info_query *) (qd->info_query->data); | |
721 qd->info_query = g_list_remove(qd->info_query, p); | |
722 g_free(p); | |
723 i++; | |
724 } | |
725 gaim_debug(GAIM_DEBUG_INFO, "QQ", "%d info queries are freed!\n", i); | |
726 } | |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
727 |
15139 | 728 void qq_send_packet_get_level(GaimConnection *gc, guint32 uid) |
729 { | |
730 guint8 buf[5]; | |
731 guint32 tmp = g_htonl(uid); | |
732 buf[0] = 0; | |
733 memcpy(buf+1, &tmp, 4); | |
734 qq_send_cmd(gc, QQ_CMD_GET_LEVEL, TRUE, 0, TRUE, buf, 5); | |
735 } | |
736 | |
737 void qq_send_packet_get_buddies_levels(GaimConnection *gc) | |
738 { | |
739 guint8 *buf, *tmp, size; | |
740 qq_buddy *q_bud; | |
741 GList *node; | |
742 qq_data *qd = (qq_data *) gc->proto_data; | |
743 | |
744 /* server only sends back levels for online buddies, no point | |
745 * in asking for anyone else */ | |
746 size = 4*g_list_length(qd->buddies) + 1; | |
747 buf = g_new0(guint8, size); | |
748 tmp = buf + 1; | |
749 | |
750 for (node = qd->buddies; node != NULL; node = node->next) { | |
751 guint32 tmp4; | |
752 q_bud = (qq_buddy *) node->data; | |
753 if (q_bud != NULL) { | |
754 tmp4 = g_htonl(q_bud->uid); | |
755 memcpy(tmp, &tmp4, 4); | |
756 tmp += 4; | |
757 } | |
758 } | |
759 qq_send_cmd(gc, QQ_CMD_GET_LEVEL, TRUE, 0, TRUE, buf, size); | |
760 qd->last_get_levels = time(NULL); | |
761 g_free(buf); | |
762 } | |
763 | |
764 void qq_process_get_level_reply(guint8 *buf, gint buf_len, GaimConnection *gc) | |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
765 { |
15139 | 766 guint32 uid, onlineTime; |
767 guint16 level, timeRemainder; | |
768 gchar *gaim_name; | |
769 GaimBuddy *b; | |
770 qq_buddy *q_bud; | |
771 gint decr_len, i; | |
772 guint8 *decr_buf, *tmp; | |
773 GaimAccount *account = gaim_connection_get_account(gc); | |
774 qq_data *qd = (qq_data *) gc->proto_data; | |
775 | |
776 decr_len = buf_len; | |
777 decr_buf = g_new0(guint8, buf_len); | |
778 if (!qq_crypt(DECRYPT, buf, buf_len, qd->session_key, decr_buf, &decr_len)) { | |
779 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Couldn't decrypt get level packet\n"); | |
780 } | |
781 | |
782 decr_len--; | |
783 if (decr_len % 12 != 0) { | |
784 gaim_debug(GAIM_DEBUG_ERROR, "QQ", | |
785 "Get levels list of abnormal length. Truncating last %d bytes.\n", decr_len % 12); | |
786 decr_len -= (decr_len % 12); | |
787 } | |
788 | |
789 tmp = decr_buf + 1; | |
790 /* this byte seems random */ | |
791 /* | |
792 gaim_debug(GAIM_DEBUG_INFO, "QQ", "Byte one of get_level packet: %d\n", buf[0]); | |
793 */ | |
794 for (i = 0; i < decr_len; i += 12) { | |
795 uid = g_ntohl(*(guint32 *) tmp); | |
796 tmp += 4; | |
797 onlineTime = g_ntohl(*(guint32 *) tmp); | |
798 tmp += 4; | |
799 level = g_ntohs(*(guint16 *) tmp); | |
800 tmp += 2; | |
801 timeRemainder = g_ntohs(*(guint16 *) tmp); | |
802 tmp += 2; | |
803 /* | |
804 gaim_debug(GAIM_DEBUG_INFO, "QQ", "Level packet entry:\nuid: %d\nonlineTime: %d\nlevel: %d\ntimeRemainder: %d\n", | |
805 uid, onlineTime, level, timeRemainder); | |
806 */ | |
807 gaim_name = uid_to_gaim_name(uid); | |
808 b = gaim_find_buddy(account, gaim_name); | |
809 q_bud = (b == NULL) ? NULL : (qq_buddy *) b->proto_data; | |
810 | |
811 if (q_bud != NULL) { | |
812 q_bud->onlineTime = onlineTime; | |
813 q_bud->level = level; | |
814 q_bud->timeRemainder = timeRemainder; | |
815 } else { | |
816 gaim_debug(GAIM_DEBUG_ERROR, "QQ", | |
817 "Got an online buddy %d, but not in my buddy list\n", uid); | |
818 } | |
819 g_free(gaim_name); | |
820 } | |
821 g_free(decr_buf); | |
15076
2c93b0620065
[gaim-migrate @ 17859]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
15072
diff
changeset
|
822 } |