libpurple/protocols/qq/buddy_info.c

branch
release-2.4.3
changeset 23190
ce258cadbd9e
parent 22685
f3a524370c38
child 23192
2f00b04db5cb
equal deleted inserted replaced
23188:eab7aad90c95 23190:ce258cadbd9e
92 guint32 uid; 92 guint32 uid;
93 gboolean show_window; 93 gboolean show_window;
94 gboolean modify_info; 94 gboolean modify_info;
95 } qq_info_query; 95 } qq_info_query;
96 96
97 typedef struct _contact_info {
98 gchar *uid;
99 gchar *nick;
100 gchar *country;
101 gchar *province;
102 gchar *zipcode;
103 gchar *address;
104 gchar *tel;
105 gchar *age;
106 gchar *gender;
107 gchar *name;
108 gchar *email;
109 gchar *pager_sn;
110 gchar *pager_num;
111 gchar *pager_sp;
112 gchar *pager_base_num;
113 gchar *pager_type;
114 gchar *occupation;
115 gchar *homepage;
116 gchar *auth_type;
117 gchar *unknown1;
118 gchar *unknown2;
119 gchar *face;
120 gchar *hp_num;
121 gchar *hp_type;
122 gchar *intro;
123 gchar *city;
124 gchar *unknown3;
125 gchar *unknown4;
126 gchar *unknown5;
127 gchar *is_open_hp;
128 gchar *is_open_contact;
129 gchar *college;
130 gchar *horoscope;
131 gchar *zodiac;
132 gchar *blood;
133 gchar *qq_show;
134 gchar *unknown6; /* always 0x2D */
135 } contact_info;
136
97 /* We get an info packet on ourselves before we modify our information. 137 /* We get an info packet on ourselves before we modify our information.
98 * Even though not all of the information is modifiable, it still 138 * 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 */ 139 * all needs to be there when we send out the modify info packet */
100 typedef struct _modify_info_data { 140 typedef struct _modify_info_data {
101 PurpleConnection *gc; 141 PurpleConnection *gc;
135 if (strcmp(field, "-") != 0) { 175 if (strcmp(field, "-") != 0) {
136 return qq_to_utf8(field, QQ_CHARSET_DEFAULT); 176 return qq_to_utf8(field, QQ_CHARSET_DEFAULT);
137 } else { 177 } else {
138 return NULL; 178 return NULL;
139 } 179 }
140 /* else ASCIIized index */ 180 /* else ASCIIized index */
141 } else { 181 } else {
142 if (strcmp(choice[index], "-") != 0) 182 if (strcmp(choice[index], "-") != 0)
143 return g_strdup(choice[index]); 183 return g_strdup(choice[index]);
144 else 184 else
145 return NULL; 185 return NULL;
159 gchar *value = field_value(field, choice, choice_size); 199 gchar *value = field_value(field, choice, choice_size);
160 200
161 if (value != NULL) { 201 if (value != NULL) {
162 purple_notify_user_info_add_pair(user_info, title, value); 202 purple_notify_user_info_add_pair(user_info, title, value);
163 g_free(value); 203 g_free(value);
164 204
165 return TRUE; 205 return TRUE;
166 } 206 }
167 207
168 return FALSE; 208 return FALSE;
169 } 209 }
170 210
171 static PurpleNotifyUserInfo * 211 static PurpleNotifyUserInfo *
172 info_to_notify_user_info(const contact_info *info) 212 info_to_notify_user_info(const contact_info *info)
173 { 213 {
174 PurpleNotifyUserInfo *user_info = purple_notify_user_info_new(); 214 PurpleNotifyUserInfo *user_info = purple_notify_user_info_new();
175 const gchar *intro; 215 const gchar *intro;
176 gboolean has_extra_info = FALSE; 216 gboolean has_extra_info = FALSE;
207 purple_notify_user_info_add_pair(user_info, QQ_INTRO, intro); 247 purple_notify_user_info_add_pair(user_info, QQ_INTRO, intro);
208 } 248 }
209 249
210 /* for debugging */ 250 /* for debugging */
211 /* 251 /*
212 g_string_append_printf(info_text, "<br /><br /><b>%s</b><br />", "Miscellaneous"); 252 g_string_append_printf(info_text, "<br /><br /><b>%s</b><br />", "Miscellaneous");
213 append_field_value(info_text, info->pager_sn, "pager_sn", NULL, 0); 253 append_field_value(info_text, info->pager_sn, "pager_sn", NULL, 0);
214 append_field_value(info_text, info->pager_num, "pager_num", NULL, 0); 254 append_field_value(info_text, info->pager_num, "pager_num", NULL, 0);
215 append_field_value(info_text, info->pager_sp, "pager_sp", NULL, 0); 255 append_field_value(info_text, info->pager_sp, "pager_sp", NULL, 0);
216 append_field_value(info_text, info->pager_base_num, "pager_base_num", NULL, 0); 256 append_field_value(info_text, info->pager_base_num, "pager_base_num", NULL, 0);
217 append_field_value(info_text, info->pager_type, "pager_type", NULL, 0); 257 append_field_value(info_text, info->pager_type, "pager_type", NULL, 0);
218 append_field_value(info_text, info->auth_type, "auth_type", NULL, 0); 258 append_field_value(info_text, info->auth_type, "auth_type", NULL, 0);
219 append_field_value(info_text, info->unknown1, "unknown1", NULL, 0); 259 append_field_value(info_text, info->unknown1, "unknown1", NULL, 0);
220 append_field_value(info_text, info->unknown2, "unknown2", NULL, 0); 260 append_field_value(info_text, info->unknown2, "unknown2", NULL, 0);
221 append_field_value(info_text, info->face, "face", NULL, 0); 261 append_field_value(info_text, info->face, "face", NULL, 0);
222 append_field_value(info_text, info->hp_type, "hp_type", NULL, 0); 262 append_field_value(info_text, info->hp_type, "hp_type", NULL, 0);
223 append_field_value(info_text, info->unknown3, "unknown3", NULL, 0); 263 append_field_value(info_text, info->unknown3, "unknown3", NULL, 0);
224 append_field_value(info_text, info->unknown4, "unknown4", NULL, 0); 264 append_field_value(info_text, info->unknown4, "unknown4", NULL, 0);
225 append_field_value(info_text, info->unknown5, "unknown5", NULL, 0); 265 append_field_value(info_text, info->unknown5, "unknown5", NULL, 0);
226 append_field_value(info_text, info->is_open_hp, "is_open_hp", NULL, 0); 266 append_field_value(info_text, info->is_open_hp, "is_open_hp", NULL, 0);
227 append_field_value(info_text, info->is_open_contact, "is_open_contact", NULL, 0); 267 append_field_value(info_text, info->is_open_contact, "is_open_contact", NULL, 0);
228 append_field_value(info_text, info->qq_show, "qq_show", NULL, 0); 268 append_field_value(info_text, info->qq_show, "qq_show", NULL, 0);
229 append_field_value(info_text, info->unknown6, "unknown6", NULL, 0); 269 append_field_value(info_text, info->unknown6, "unknown6", NULL, 0);
230 */ 270 */
231 271
232 return user_info; 272 return user_info;
233 } 273 }
234 274
235 /* send a packet to get detailed information of uid */ 275 /* send a packet to get detailed information of uid */
269 query->modify_info = TRUE; 309 query->modify_info = TRUE;
270 } 310 }
271 } 311 }
272 312
273 /* send packet to modify personal information */ 313 /* send packet to modify personal information */
274 static void qq_send_packet_modify_info(PurpleConnection *gc, gchar **segments) 314 static void qq_send_packet_modify_info(PurpleConnection *gc, contact_info *info)
275 { 315 {
276 gint i; 316 gint bytes = 0;
277 guint8 *raw_data, *cursor, bar; 317 guint8 raw_data[MAX_PACKET_SIZE - 128] = {0};
278 318 guint8 bar;
279 g_return_if_fail(segments != NULL); 319
320 g_return_if_fail(info != NULL);
280 321
281 bar = 0x1f; 322 bar = 0x1f;
282 raw_data = g_newa(guint8, MAX_PACKET_SIZE - 128); 323
283 cursor = raw_data; 324 bytes += qq_put8(raw_data + bytes, bar);
284
285 create_packet_b(raw_data, &cursor, bar);
286 325
287 /* important! skip the first uid entry */ 326 /* important! skip the first uid entry */
288 for (i = 1; i < QQ_CONTACT_FIELDS; i++) { 327 /*
289 create_packet_b(raw_data, &cursor, bar); 328 for (i = 1; i < QQ_CONTACT_FIELDS; i++) {
290 create_packet_data(raw_data, &cursor, (guint8 *) segments[i], strlen(segments[i])); 329 create_packet_b(raw_data, &cursor, bar);
291 } 330 create_packet_data(raw_data, &cursor, (guint8 *) segments[i], strlen(segments[i]));
292 create_packet_b(raw_data, &cursor, bar); 331 }
293 332 */
294 qq_send_cmd(gc, QQ_CMD_UPDATE_INFO, TRUE, 0, TRUE, raw_data, cursor - raw_data); 333 /* uid */
334 bytes += qq_put8(raw_data + bytes, bar);
335 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->uid, strlen(info->uid));
336 /* nick */
337 bytes += qq_put8(raw_data + bytes, bar);
338 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->nick, strlen(info->nick));
339 /* country */
340 bytes += qq_put8(raw_data + bytes, bar);
341 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->country, strlen(info->country));
342 /* province */
343 bytes += qq_put8(raw_data + bytes, bar);
344 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->province, strlen(info->province));
345 /* zipcode */
346 bytes += qq_put8(raw_data + bytes, bar);
347 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->zipcode, strlen(info->zipcode));
348 /* address */
349 bytes += qq_put8(raw_data + bytes, bar);
350 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->address, strlen(info->address));
351 /* tel */
352 bytes += qq_put8(raw_data + bytes, bar);
353 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->tel, strlen(info->tel));
354 /* age */
355 bytes += qq_put8(raw_data + bytes, bar);
356 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->age, strlen(info->age));
357 /* gender */
358 bytes += qq_put8(raw_data + bytes, bar);
359 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->gender, strlen(info->gender));
360 /* name */
361 bytes += qq_put8(raw_data + bytes, bar);
362 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->name, strlen(info->name));
363 /* email */
364 bytes += qq_put8(raw_data + bytes, bar);
365 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->email, strlen(info->email));
366 /* pager_sn */
367 bytes += qq_put8(raw_data + bytes, bar);
368 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->pager_sn, strlen(info->pager_sn));
369 /* pager_num */
370 bytes += qq_put8(raw_data + bytes, bar);
371 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->pager_num, strlen(info->pager_num));
372 /* pager_sp */
373 bytes += qq_put8(raw_data + bytes, bar);
374 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->pager_sp, strlen(info->pager_sp));
375 /* pager_base_num */
376 bytes += qq_put8(raw_data + bytes, bar);
377 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->pager_base_num, strlen(info->pager_base_num));
378 /* pager_type */
379 bytes += qq_put8(raw_data + bytes, bar);
380 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->pager_type, strlen(info->pager_type));
381 /* occupation */
382 bytes += qq_put8(raw_data + bytes, bar);
383 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->occupation, strlen(info->occupation));
384 /* homepage */
385 bytes += qq_put8(raw_data + bytes, bar);
386 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->homepage, strlen(info->homepage));
387 /* auth_type */
388 bytes += qq_put8(raw_data + bytes, bar);
389 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->auth_type, strlen(info->auth_type));
390 /* unknown1 */
391 bytes += qq_put8(raw_data + bytes, bar);
392 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->unknown1, strlen(info->unknown1));
393 /* unknown2 */
394 bytes += qq_put8(raw_data + bytes, bar);
395 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->unknown2, strlen(info->unknown2));
396 /* face */
397 bytes += qq_put8(raw_data + bytes, bar);
398 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->face, strlen(info->face));
399 /* hp_num */
400 bytes += qq_put8(raw_data + bytes, bar);
401 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->hp_num, strlen(info->hp_num));
402 /* hp_type */
403 bytes += qq_put8(raw_data + bytes, bar);
404 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->hp_type, strlen(info->hp_type));
405 /* intro */
406 bytes += qq_put8(raw_data + bytes, bar);
407 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->intro, strlen(info->intro));
408 /* city */
409 bytes += qq_put8(raw_data + bytes, bar);
410 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->city, strlen(info->city));
411 /* unknown3 */
412 bytes += qq_put8(raw_data + bytes, bar);
413 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->unknown3, strlen(info->unknown3));
414 /* unknown4 */
415 bytes += qq_put8(raw_data + bytes, bar);
416 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->unknown4, strlen(info->unknown4));
417 /* unknown5 */
418 bytes += qq_put8(raw_data + bytes, bar);
419 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->unknown5, strlen(info->unknown5));
420 /* is_open_hp */
421 bytes += qq_put8(raw_data + bytes, bar);
422 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->is_open_hp, strlen(info->is_open_hp));
423 /* is_open_contact */
424 bytes += qq_put8(raw_data + bytes, bar);
425 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->is_open_contact, strlen(info->is_open_contact));
426 /* college */
427 bytes += qq_put8(raw_data + bytes, bar);
428 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->college, strlen(info->college));
429 /* horoscope */
430 bytes += qq_put8(raw_data + bytes, bar);
431 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->horoscope, strlen(info->horoscope));
432 /* zodiac */
433 bytes += qq_put8(raw_data + bytes, bar);
434 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->zodiac, strlen(info->zodiac));
435 /* blood */
436 bytes += qq_put8(raw_data + bytes, bar);
437 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->blood, strlen(info->blood));
438 /* qq_show */
439 bytes += qq_put8(raw_data + bytes, bar);
440 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->qq_show, strlen(info->qq_show));
441 /* unknown6 */
442 bytes += qq_put8(raw_data + bytes, bar);
443 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->unknown6, strlen(info->unknown6));
444
445 bytes += qq_put8(raw_data + bytes, bar);
446
447 qq_send_cmd(gc, QQ_CMD_UPDATE_INFO, TRUE, 0, TRUE, raw_data, bytes);
295 448
296 } 449 }
297 450
298 static void modify_info_cancel_cb(modify_info_data *mid) 451 static void modify_info_cancel_cb(modify_info_data *mid)
299 { 452 {
405 } 558 }
406 559
407 groups = groups->next; 560 groups = groups->next;
408 } 561 }
409 562
410 /* This casting looks like a horrible idea to me -DAA */ 563 /* This casting looks like a horrible idea to me -DAA
411 qq_send_packet_modify_info(gc, (gchar **) info); 564 * yes, rewritten -s3e
565 * qq_send_packet_modify_info(gc, (gchar **) info);
566 */
567 qq_send_packet_modify_info(gc, info);
412 568
413 g_strfreev((gchar **) mid->info); 569 g_strfreev((gchar **) mid->info);
414 g_free(mid); 570 g_free(mid);
415 } 571 }
416 572
518 mid->info->is_open_contact = g_strdup(info->is_open_contact); 674 mid->info->is_open_contact = g_strdup(info->is_open_contact);
519 mid->info->qq_show = g_strdup(info->qq_show); 675 mid->info->qq_show = g_strdup(info->qq_show);
520 mid->info->unknown6 = g_strdup(info->unknown6); 676 mid->info->unknown6 = g_strdup(info->unknown6);
521 677
522 purple_request_fields(gc, _("Modify my information"), 678 purple_request_fields(gc, _("Modify my information"),
523 _("Modify my information"), NULL, fields, 679 _("Modify my information"), NULL, fields,
524 _("Update my information"), G_CALLBACK(modify_info_ok_cb), 680 _("Update my information"), G_CALLBACK(modify_info_ok_cb),
525 _("Cancel"), G_CALLBACK(modify_info_cancel_cb), 681 _("Cancel"), G_CALLBACK(modify_info_cancel_cb),
526 purple_connection_get_account(gc), NULL, NULL, 682 purple_connection_get_account(gc), NULL, NULL,
527 mid); 683 mid);
528 } 684 }
529 } 685 }
530 686
531 /* process the reply of modify_info packet */ 687 /* process the reply of modify_info packet */
532 void qq_process_modify_info_reply(guint8 *buf, gint buf_len, PurpleConnection *gc) 688 void qq_process_modify_info_reply(guint8 *buf, gint buf_len, PurpleConnection *gc)
576 void qq_set_buddy_icon_for_user(PurpleAccount *account, const gchar *who, const gchar *icon_num, const gchar *iconfile) 732 void qq_set_buddy_icon_for_user(PurpleAccount *account, const gchar *who, const gchar *icon_num, const gchar *iconfile)
577 { 733 {
578 gchar *data; 734 gchar *data;
579 gsize len; 735 gsize len;
580 736
581 if (!g_file_get_contents(iconfile, &data, &len, NULL)) 737 if (!g_file_get_contents(iconfile, &data, &len, NULL)) {
582 g_return_if_reached(); 738 g_return_if_reached();
583 else 739 } else {
584 {
585 purple_buddy_icons_set_for_user(account, who, data, len, icon_num); 740 purple_buddy_icons_set_for_user(account, who, data, len, icon_num);
586 } 741 }
587 } 742 }
588 743
589 /* TODO: custom faces for QQ members and users with level >= 16 */ 744 /* TODO: custom faces for QQ members and users with level >= 16 */
606 761
607 icon_len = strlen(icon_path) - dir_len - 1 - prefix_len - suffix_len; 762 icon_len = strlen(icon_path) - dir_len - 1 - prefix_len - suffix_len;
608 763
609 /* make sure we're using an appropriate icon */ 764 /* make sure we're using an appropriate icon */
610 if (!(g_ascii_strncasecmp(icon_path, buddy_icon_dir, dir_len) == 0 765 if (!(g_ascii_strncasecmp(icon_path, buddy_icon_dir, dir_len) == 0
611 && icon_path[dir_len] == G_DIR_SEPARATOR 766 && icon_path[dir_len] == G_DIR_SEPARATOR
612 && g_ascii_strncasecmp(icon_path + dir_len + 1, QQ_ICON_PREFIX, prefix_len) == 0 767 && g_ascii_strncasecmp(icon_path + dir_len + 1, QQ_ICON_PREFIX, prefix_len) == 0
613 && g_ascii_strncasecmp(icon_path + dir_len + 1 + prefix_len + icon_len, QQ_ICON_SUFFIX, suffix_len) == 0 768 && g_ascii_strncasecmp(icon_path + dir_len + 1 + prefix_len + icon_len, QQ_ICON_SUFFIX, suffix_len) == 0
614 && icon_len <= 3)) { 769 && icon_len <= 3)) {
615 if (icon_global) 770 if (icon_global)
616 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "%s\n", errmsg); 771 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "%s\n", errmsg);
617 else 772 else
618 purple_notify_error(gc, _("Invalid QQ Face"), errmsg, NULL); 773 purple_notify_error(gc, _("Invalid QQ Face"), errmsg, NULL);
619 g_free(errmsg); 774 g_free(errmsg);
648 803
649 if ((buddy = purple_find_buddy(account, name))) 804 if ((buddy = purple_find_buddy(account, name)))
650 old_icon_num = purple_buddy_icons_get_checksum_for_user(buddy); 805 old_icon_num = purple_buddy_icons_get_checksum_for_user(buddy);
651 806
652 if (old_icon_num == NULL || 807 if (old_icon_num == NULL ||
653 strcmp(icon_num_str, old_icon_num)) 808 strcmp(icon_num_str, old_icon_num))
654 { 809 {
655 gchar *icon_path; 810 gchar *icon_path;
656 811
657 icon_path = g_strconcat(qq_buddy_icon_dir(), G_DIR_SEPARATOR_S, 812 icon_path = g_strconcat(qq_buddy_icon_dir(), G_DIR_SEPARATOR_S,
658 QQ_ICON_PREFIX, icon_num_str, 813 QQ_ICON_PREFIX, icon_num_str,
659 QQ_ICON_SUFFIX, NULL); 814 QQ_ICON_SUFFIX, NULL);
660 815
661 qq_set_buddy_icon_for_user(account, name, icon_num_str, icon_path); 816 qq_set_buddy_icon_for_user(account, name, icon_num_str, icon_path);
662 g_free(icon_path); 817 g_free(icon_path);
663 } 818 }
664 g_free(icon_num_str); 819 g_free(icon_num_str);
665 } 820 }
666 821
667 /* after getting info or modify myself, refresh the buddy list accordingly */ 822 /* after getting info or modify myself, refresh the buddy list accordingly */
668 void qq_refresh_buddy_and_myself(contact_info *info, PurpleConnection *gc) 823 static void qq_refresh_buddy_and_myself(contact_info *info, PurpleConnection *gc)
669 { 824 {
670 PurpleBuddy *b; 825 PurpleBuddy *b;
671 qq_data *qd; 826 qq_data *qd;
672 qq_buddy *q_bud; 827 qq_buddy *q_bud;
673 gchar *alias_utf8, *purple_name; 828 gchar *alias_utf8, *purple_name;
726 if (qd->modifying_face && strtol(info->face, NULL, 10) != qd->my_icon) { 881 if (qd->modifying_face && strtol(info->face, NULL, 10) != qd->my_icon) {
727 gchar *icon = g_strdup_printf("%d", qd->my_icon); 882 gchar *icon = g_strdup_printf("%d", qd->my_icon);
728 qd->modifying_face = FALSE; 883 qd->modifying_face = FALSE;
729 g_free(info->face); 884 g_free(info->face);
730 info->face = icon; 885 info->face = icon;
731 qq_send_packet_modify_info(gc, segments); 886 qq_send_packet_modify_info(gc, (contact_info *)segments);
732 } 887 }
733 888
734 qq_refresh_buddy_and_myself(info, gc); 889 qq_refresh_buddy_and_myself(info, gc);
735 890
736 query_list = qd->info_query; 891 query_list = qd->info_query;
775 purple_debug(PURPLE_DEBUG_INFO, "QQ", "%d info queries are freed!\n", i); 930 purple_debug(PURPLE_DEBUG_INFO, "QQ", "%d info queries are freed!\n", i);
776 } 931 }
777 932
778 void qq_send_packet_get_level(PurpleConnection *gc, guint32 uid) 933 void qq_send_packet_get_level(PurpleConnection *gc, guint32 uid)
779 { 934 {
780 guint8 buf[5]; 935 guint8 buf[16] = {0};
781 guint32 tmp = g_htonl(uid); 936 gint bytes = 0;
782 buf[0] = 0; 937
783 memcpy(buf+1, &tmp, 4); 938 bytes += qq_put8(buf + bytes, 0x00);
784 qq_send_cmd(gc, QQ_CMD_GET_LEVEL, TRUE, 0, TRUE, buf, 5); 939 bytes += qq_put32(buf + bytes, uid);
940
941 qq_send_cmd(gc, QQ_CMD_GET_LEVEL, TRUE, 0, TRUE, buf, bytes);
785 } 942 }
786 943
787 void qq_send_packet_get_buddies_levels(PurpleConnection *gc) 944 void qq_send_packet_get_buddies_levels(PurpleConnection *gc)
788 { 945 {
789 guint8 *buf, *tmp; 946 guint8 *buf;
790 guint16 size; 947 guint16 size;
791 qq_buddy *q_bud; 948 qq_buddy *q_bud;
792 qq_data *qd = (qq_data *) gc->proto_data; 949 qq_data *qd = (qq_data *) gc->proto_data;
793 GList *node = qd->buddies; 950 GList *node = qd->buddies;
951 gint bytes = 0;
794 952
795 if (qd->buddies) { 953 if (qd->buddies) {
796 /* server only sends back levels for online buddies, no point 954 /* server only sends back levels for online buddies, no point
797 * in asking for anyone else */ 955 * in asking for anyone else */
798 size = 4*g_list_length(qd->buddies) + 1; 956 size = 4 * g_list_length(qd->buddies) + 1;
799 buf = g_new0(guint8, size); 957 buf = g_new0(guint8, size);
800 tmp = buf + 1; 958 bytes += 1;
801 959
802 while (node != NULL) { 960 while (NULL != node) {
803 guint32 tmp4;
804 q_bud = (qq_buddy *) node->data; 961 q_bud = (qq_buddy *) node->data;
805 if (q_bud != NULL) { 962 if (NULL != q_bud) {
806 tmp4 = g_htonl(q_bud->uid); 963 bytes += qq_put32(buf + bytes, q_bud->uid);
807 memcpy(tmp, &tmp4, 4);
808 tmp += 4;
809 } 964 }
810 node = node->next; 965 node = node->next;
811 } 966 }
812 qq_send_cmd(gc, QQ_CMD_GET_LEVEL, TRUE, 0, TRUE, buf, size); 967 qq_send_cmd(gc, QQ_CMD_GET_LEVEL, TRUE, 0, TRUE, buf, size);
813 g_free(buf); 968 g_free(buf);
820 guint16 level, timeRemainder; 975 guint16 level, timeRemainder;
821 gchar *purple_name; 976 gchar *purple_name;
822 PurpleBuddy *b; 977 PurpleBuddy *b;
823 qq_buddy *q_bud; 978 qq_buddy *q_bud;
824 gint decr_len, i; 979 gint decr_len, i;
825 guint8 *decr_buf, *tmp; 980 guint8 *decr_buf;
826 PurpleAccount *account = purple_connection_get_account(gc); 981 PurpleAccount *account = purple_connection_get_account(gc);
827 qq_data *qd = (qq_data *) gc->proto_data; 982 qq_data *qd = (qq_data *) gc->proto_data;
828 983 gint bytes = 0;
984
829 decr_len = buf_len; 985 decr_len = buf_len;
830 decr_buf = g_new0(guint8, buf_len); 986 decr_buf = g_new0(guint8, buf_len);
831 if (!qq_decrypt(buf, buf_len, qd->session_key, decr_buf, &decr_len)) { 987 if (!qq_decrypt(buf, buf_len, qd->session_key, decr_buf, &decr_len)) {
832 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Couldn't decrypt get level packet\n"); 988 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Couldn't decrypt get level packet\n");
833 } 989 }
834 990
835 decr_len--; 991 decr_len--;
836 if (decr_len % 12 != 0) { 992 if (decr_len % 12 != 0) {
837 purple_debug(PURPLE_DEBUG_ERROR, "QQ", 993 purple_debug(PURPLE_DEBUG_ERROR, "QQ",
838 "Get levels list of abnormal length. Truncating last %d bytes.\n", decr_len % 12); 994 "Get levels list of abnormal length. Truncating last %d bytes.\n", decr_len % 12);
839 decr_len -= (decr_len % 12); 995 decr_len -= (decr_len % 12);
840 } 996 }
841 997
842 tmp = decr_buf + 1; 998 bytes += 1;
843 /* this byte seems random */ 999 /* this byte seems random */
844 /* 1000 /*
845 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Byte one of get_level packet: %d\n", buf[0]); 1001 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Byte one of get_level packet: %d\n", buf[0]);
846 */ 1002 */
847 for (i = 0; i < decr_len; i += 12) { 1003 for (i = 0; i < decr_len; i += 12) {
848 uid = g_ntohl(*(guint32 *) tmp); 1004 bytes += qq_get32(&uid, decr_buf + bytes);
849 tmp += 4; 1005 bytes += qq_get32(&onlineTime, decr_buf + bytes);
850 onlineTime = g_ntohl(*(guint32 *) tmp); 1006 bytes += qq_get16(&level, decr_buf + bytes);
851 tmp += 4; 1007 bytes += qq_get16(&timeRemainder, decr_buf + bytes);
852 level = g_ntohs(*(guint16 *) tmp); 1008 purple_debug(PURPLE_DEBUG_INFO, "QQ",
853 tmp += 2; 1009 "Level packet entry:\nuid: %d\nonlineTime: %d\nlevel: %d\ntimeRemainder: %d\n",
854 timeRemainder = g_ntohs(*(guint16 *) tmp);
855 tmp += 2;
856 /*
857 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Level packet entry:\nuid: %d\nonlineTime: %d\nlevel: %d\ntimeRemainder: %d\n",
858 uid, onlineTime, level, timeRemainder); 1010 uid, onlineTime, level, timeRemainder);
859 */
860 purple_name = uid_to_purple_name(uid); 1011 purple_name = uid_to_purple_name(uid);
861 b = purple_find_buddy(account, purple_name); 1012 b = purple_find_buddy(account, purple_name);
862 q_bud = (b == NULL) ? NULL : (qq_buddy *) b->proto_data; 1013 q_bud = (b == NULL) ? NULL : (qq_buddy *) b->proto_data;
863 1014
864 if (q_bud != NULL || uid == qd->uid) { 1015 if (q_bud != NULL || uid == qd->uid) {
870 if (uid == qd->uid) { 1021 if (uid == qd->uid) {
871 qd->my_level = level; 1022 qd->my_level = level;
872 } 1023 }
873 } else { 1024 } else {
874 purple_debug(PURPLE_DEBUG_ERROR, "QQ", 1025 purple_debug(PURPLE_DEBUG_ERROR, "QQ",
875 "Got an online buddy %d, but not in my buddy list\n", uid); 1026 "Got an online buddy %d, but not in my buddy list\n", uid);
876 } 1027 }
877 g_free(purple_name); 1028 g_free(purple_name);
878 } 1029 }
879 g_free(decr_buf); 1030 g_free(decr_buf);
880 } 1031 }

mercurial