comparison src/protocols/qq/qq.c @ 14049:8294485b79db

[gaim-migrate @ 16662] Enhanced protocol testing tools, primarily by designing a more useful interface for sending customized packets. committer: Tailor Script <tailor@pidgin.im>
author Mark Huetsch <markhuetsch>
date Mon, 07 Aug 2006 06:17:13 +0000
parents 80891029f5dd
children f78289db8977
comparison
equal deleted inserted replaced
14048:9c4bec886220 14049:8294485b79db
26 #define random rand 26 #define random rand
27 #endif 27 #endif
28 28
29 #include "accountopt.h" 29 #include "accountopt.h"
30 #include "debug.h" 30 #include "debug.h"
31 #include "gtkroomlist.h"
31 #include "notify.h" 32 #include "notify.h"
32 #include "prefs.h" 33 #include "prefs.h"
33 #include "prpl.h" 34 #include "prpl.h"
34 #include "request.h" 35 #include "request.h"
35 #include "server.h" 36 #include "server.h"
584 _("Locate an IP address"), NULL, fields, 585 _("Locate an IP address"), NULL, fields,
585 _("Check"), G_CALLBACK(_qq_menu_locate_ip_cb), _("Cancel"), NULL, gc); 586 _("Check"), G_CALLBACK(_qq_menu_locate_ip_cb), _("Cancel"), NULL, gc);
586 } 587 }
587 */ 588 */
588 589
589 /*
590 static void _qq_menu_search_or_add_permanent_group(GaimPluginAction * action) 590 static void _qq_menu_search_or_add_permanent_group(GaimPluginAction * action)
591 { 591 {
592 gaim_gtk_roomlist_dialog_show(); 592 gaim_gtk_roomlist_dialog_show();
593 } 593 }
594 */
595 594
596 /* 595 /*
597 static void _qq_menu_create_permanent_group(GaimPluginAction * action) 596 static void _qq_menu_create_permanent_group(GaimPluginAction * action)
598 { 597 {
599 GaimConnection *gc = (GaimConnection *) action->context; 598 GaimConnection *gc = (GaimConnection *) action->context;
657 g_return_if_fail (gc != NULL && gc->proto_data != NULL); 656 g_return_if_fail (gc != NULL && gc->proto_data != NULL);
658 qq_send_file(gc, buddy->name, NULL); 657 qq_send_file(gc, buddy->name, NULL);
659 // } 658 // }
660 } 659 }
661 */ 660 */
662 /* 661
663 static void _qq_send_custom_packet(GaimConnection *gc, const gchar *packet) 662 static gboolean _qq_parse_custom_packet_field(GaimRequestFields *fields,
664 { 663 const gchar *id, guint8 **value)
665 guint16 cmd; 664 {
666 guint8 *buffer; 665 GaimRequestField *field;
667 gint len; 666 const gchar *str;
668 667 gint len, i;
669 if (!packet) { 668 gboolean success;
670 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Null packet inputted!\n"); 669
670 success = FALSE;
671 field = gaim_request_fields_get_field(fields, id);
672 str = gaim_request_field_string_get_value(field);
673 if (str) {
674 success = TRUE;
675 if (strcmp(id, "uid") != 0) {
676 *value = hex_str_to_bytes(str, &len);
677 if (!*value || len != 2)
678 success = FALSE;
679 } else {
680 for (i = 0; i < strlen(str); i++) {
681 if (!g_ascii_isdigit(str[i])) {
682 success = FALSE;
683 break;
684 }
685 }
686 if (success) {
687 *(guint32 *) value = strtoul(str, NULL, 10);
688 if (errno == ERANGE)
689 success = FALSE;
690 }
691 }
692 }
693 if (!success)
694 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Invalid entry: %s\n", id);
695 return success;
696 }
697
698 static gboolean _qq_parse_custom_packet_fields(GaimRequestFields *fields,
699 guint8 **client, guint8 **cmd, guint8 **seq, guint32 *uid,
700 guint8 **body, gint *body_len)
701 {
702 GaimRequestField *field;
703 gboolean success;
704
705 success = TRUE;
706 *client = *cmd = *seq = *body = NULL;
707 *uid = 0;
708 success = _qq_parse_custom_packet_field(fields, "client", client);
709 if (success)
710 success = _qq_parse_custom_packet_field(fields, "cmd", cmd);
711 if (success)
712 success = _qq_parse_custom_packet_field(fields, "uid", (guint8 **) uid);
713 if (success)
714 success = _qq_parse_custom_packet_field(fields, "seq", seq);
715 if (success) {
716 field = gaim_request_fields_get_field(fields, "body");
717 *body = hex_str_to_bytes(gaim_request_field_string_get_value(field),
718 body_len);
719 } else {
720 if (*client)
721 g_free(*client);
722 if (*cmd)
723 g_free(*cmd);
724 if (*seq)
725 g_free(*seq);
726 }
727 return success;
728 }
729
730 static void _qq_send_custom_packet_cb(GaimConnection *gc, GaimRequestFields *fields)
731 {
732 guint32 uid;
733 guint8 *buf, *client, *cmd, *seq, *body, *cursor;
734 gint bytes, len;
735 qq_data *qd;
736 gboolean success;
737
738 qd = (qq_data *) gc->proto_data;
739
740 success = _qq_parse_custom_packet_fields(fields, &client, &cmd,
741 &seq, &uid, &body, &len);
742 if (!success) {
743 gaim_notify_error(gc, _("Error"), _("Invalid packet entry"), NULL);
671 return; 744 return;
672 } 745 }
673 if (strlen(packet) > MAX_PACKET_SIZE * 2) { 746
674 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Packet inputted is too large!\n"); 747 if (body)
675 return; 748 g_return_if_fail(len+12 <= MAX_PACKET_SIZE);
749
750 bytes = 0;
751 buf = g_newa(guint8, MAX_PACKET_SIZE);
752 cursor = buf;
753 /* QQ TCP packet has two bytes in the beginning to define packet length
754 * so I leave room here for size */
755 if (qd->use_tcp)
756 bytes += create_packet_w(buf, &cursor, 0x0000);
757 bytes += create_packet_b(buf, &cursor, QQ_PACKET_TAG);
758 bytes += create_packet_w(buf, &cursor, *(guint16 *) client);
759 bytes += create_packet_w(buf, &cursor, *(guint16 *) cmd);
760 bytes += create_packet_w(buf, &cursor, *(guint16 *) seq);
761 bytes += create_packet_dw(buf, &cursor, uid);
762 if (body) {
763 bytes += create_packet_data(buf, &cursor, body, len);
764 g_free(body);
676 } 765 }
677 if (strlen(packet) < 4) { 766 bytes += create_packet_b(buf, &cursor, QQ_PACKET_TAIL);
678 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Packet is impossibly short!\n"); 767
679 return; 768 gaim_debug(GAIM_DEBUG_INFO, "QQ", "Custom packet of length %i\n", bytes);
680 } 769 _qq_show_packet("Outgoing custom packet", buf, bytes);
681 770
682 buffer = hex_str_to_bytes(packet); 771 _qq_send_packet(gc, buf, bytes, *(guint16 *) cmd);
683 if (!buffer) { 772 g_free(client);
684 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Invalid packet inputted!\n"); 773 g_free(cmd);
685 return; 774 g_free(seq);
686 } 775 }
687 // big endian
688 cmd = 256 * buffer[0] + buffer[1];
689 gaim_debug(GAIM_DEBUG_INFO, "QQ", "Inputted CMD: %d\n", cmd);
690
691 len = strlen(buffer) - 2;
692 packet = buffer + 2;
693
694 qq_send_cmd(gc, cmd, TRUE, 0, TRUE, packet, len);
695
696 g_free(buffer);
697 }
698 */
699 776
700 /* send a custom packet to the server - for protocol testing */ 777 /* send a custom packet to the server - for protocol testing */
701 /*
702 static void _qq_menu_send_custom_packet(GaimPluginAction *action) 778 static void _qq_menu_send_custom_packet(GaimPluginAction *action)
703 { 779 {
704 GaimConnection *gc = (GaimConnection *) action->context; 780 GaimConnection *gc;
705 g_return_if_fail(gc != NULL); 781 GaimRequestFields *fields;
706 gaim_request_input(gc, _("Send Custom Packet"), 782 GaimRequestFieldGroup *group;
707 _("Enter the packet in hex here"), 783 GaimRequestField *field;
708 _("Include the command and everything following"), 784 gchar *tmp;
709 NULL, FALSE, FALSE, NULL, 785 qq_data *qd;
710 _("Send"), G_CALLBACK(_qq_send_custom_packet), _("Cancel"), NULL, gc); 786
711 } 787 gc = (GaimConnection *) action->context;
712 */ 788 qd = (qq_data *) gc->proto_data;
789 g_return_if_fail(gc != NULL && qd != NULL);
790
791 fields = gaim_request_fields_new();
792 group = gaim_request_field_group_new(_("Packet Elements"));
793 gaim_request_fields_add_group(fields, group);
794 tmp = g_strdup_printf("%04X", QQ_CLIENT);
795 field = gaim_request_field_string_new("client", _("Client (hex)"), tmp, FALSE);
796 g_free(tmp);
797 gaim_request_field_group_add_field(group, field);
798 field = gaim_request_field_string_new("cmd", _("Command (hex)"), "0000", FALSE);
799 gaim_request_field_group_add_field(group, field);
800 field = gaim_request_field_string_new("seq", _("Sequence (hex)"), "0000", FALSE);
801 gaim_request_field_group_add_field(group, field);
802 tmp = g_strdup_printf("%u", qd->uid);
803 field = gaim_request_field_string_new("uid", _("QQ Number (decimal)"), tmp, FALSE);
804 g_free(tmp);
805 gaim_request_field_group_add_field(group, field);
806 field = gaim_request_field_string_new("body", _("Body (hex)"), NULL, FALSE);
807 gaim_request_field_group_add_field(group, field);
808
809 gaim_request_fields(gc, _("Send a custom packet"),
810 _("Send a custom packet"), NULL, fields,
811 _("Send"), G_CALLBACK(_qq_send_custom_packet_cb),
812 _("Cancel"), NULL,
813 gc);
814 }
713 815
714 /* protocol related menus */ 816 /* protocol related menus */
715 static GList *_qq_actions(GaimPlugin *plugin, gpointer context) 817 static GList *_qq_actions(GaimPlugin *plugin, gpointer context)
716 { 818 {
717 GList *m; 819 GList *m;
725 m = g_list_append(m, act); 827 m = g_list_append(m, act);
726 828
727 act = gaim_plugin_action_new(_("Show Login Information"), _qq_menu_show_login_info); 829 act = gaim_plugin_action_new(_("Show Login Information"), _qq_menu_show_login_info);
728 m = g_list_append(m, act); 830 m = g_list_append(m, act);
729 831
730 /* 832 /*
731 act = gaim_plugin_action_new(_("Send Custom Packet"), _qq_menu_send_custom_packet); 833 act = gaim_plugin_action_new(_("Send Custom Packet"), _qq_menu_send_custom_packet);
732 m = g_list_append(m, act); 834 m = g_list_append(m, act);
733 */ 835 */
734 836
735 /* XXX consider re-enabling this 837 /* XXX consider re-enabling this
736 act = gaim_plugin_action_new(_("Show System Message"), _qq_menu_show_system_message); 838 act = gaim_plugin_action_new(_("Show System Message"), _qq_menu_show_system_message);
737 m = g_list_append(m, act); 839 m = g_list_append(m, act);
738 */ 840 */
739 841
740 /* XXX the old group gtk code needs to moved to the gaim UI before this can be used 842 /*
741 act = gaim_plugin_action_new(_("Qun: Search a permanent Qun"), _qq_menu_search_or_add_permanent_group); 843 act = gaim_plugin_action_new(_("Qun: Search a permanent Qun"), _qq_menu_search_or_add_permanent_group);
742 m = g_list_append(m, act); 844 m = g_list_append(m, act);
743 845
744 act = gaim_plugin_action_new(_("Qun: Create a permanent Qun"), _qq_menu_create_permanent_group); 846 act = gaim_plugin_action_new(_("Qun: Create a permanent Qun"), _qq_menu_create_permanent_group);
745 m = g_list_append(m, act); 847 m = g_list_append(m, act);