| 28 |
28 |
| 29 #include "buddy_info.h" |
29 #include "buddy_info.h" |
| 30 #include "buddy_list.h" |
30 #include "buddy_list.h" |
| 31 #include "buddy_opt.h" |
31 #include "buddy_opt.h" |
| 32 #include "group_info.h" |
32 #include "group_info.h" |
| 33 #include "group_free.h" |
|
| 34 #include "char_conv.h" |
33 #include "char_conv.h" |
| 35 #include "qq_crypt.h" |
34 #include "qq_crypt.h" |
| 36 |
35 |
| |
36 #include "group_search.h" |
| 37 #include "group_conv.h" |
37 #include "group_conv.h" |
| 38 #include "group_find.h" |
38 #include "group_find.h" |
| 39 #include "group_internal.h" |
39 #include "group_internal.h" |
| 40 #include "group_im.h" |
40 #include "group_im.h" |
| 41 #include "group_info.h" |
41 #include "group_info.h" |
| 42 #include "group_join.h" |
42 #include "group_join.h" |
| 43 #include "group_opt.h" |
43 #include "group_opt.h" |
| 44 #include "group_search.h" |
|
| 45 |
44 |
| 46 #include "header_info.h" |
45 #include "header_info.h" |
| 47 #include "qq_base.h" |
46 #include "qq_base.h" |
| 48 #include "im.h" |
47 #include "im.h" |
| 49 #include "qq_process.h" |
48 #include "qq_process.h" |
| 50 #include "packet_parse.h" |
49 #include "packet_parse.h" |
| 51 #include "qq_network.h" |
50 #include "qq_network.h" |
| 52 #include "qq_trans.h" |
51 #include "qq_trans.h" |
| 53 #include "sys_msg.h" |
|
| 54 #include "utils.h" |
52 #include "utils.h" |
| 55 |
53 |
| 56 enum { |
54 enum { |
| 57 QQ_ROOM_CMD_REPLY_OK = 0x00, |
55 QQ_ROOM_CMD_REPLY_OK = 0x00, |
| 58 QQ_ROOM_CMD_REPLY_SEARCH_ERROR = 0x02, |
56 QQ_ROOM_CMD_REPLY_SEARCH_ERROR = 0x02, |
| 81 purple_notify_info(gc, _("QQ Error"), title, msg_utf8); |
79 purple_notify_info(gc, _("QQ Error"), title, msg_utf8); |
| 82 g_free(msg_utf8); |
80 g_free(msg_utf8); |
| 83 } |
81 } |
| 84 } |
82 } |
| 85 |
83 |
| |
84 /* Send ACK if the sys message needs an ACK */ |
| |
85 static void _qq_send_packet_ack_msg_sys(PurpleConnection *gc, guint8 code, guint32 from, guint16 seq) |
| |
86 { |
| |
87 qq_data *qd; |
| |
88 guint8 bar, *ack; |
| |
89 gchar *str; |
| |
90 gint ack_len, bytes; |
| |
91 |
| |
92 qd = (qq_data *) gc->proto_data; |
| |
93 |
| |
94 str = g_strdup_printf("%d", from); |
| |
95 bar = 0x1e; |
| |
96 ack_len = 1 + 1 + strlen(str) + 1 + 2; |
| |
97 ack = g_newa(guint8, ack_len); |
| |
98 |
| |
99 bytes = 0; |
| |
100 bytes += qq_put8(ack + bytes, code); |
| |
101 bytes += qq_put8(ack + bytes, bar); |
| |
102 bytes += qq_putdata(ack + bytes, (guint8 *) str, strlen(str)); |
| |
103 bytes += qq_put8(ack + bytes, bar); |
| |
104 bytes += qq_put16(ack + bytes, seq); |
| |
105 |
| |
106 g_free(str); |
| |
107 |
| |
108 if (bytes == ack_len) /* creation OK */ |
| |
109 qq_send_server_reply(gc, QQ_CMD_ACK_SYS_MSG, 0, ack, ack_len); |
| |
110 else |
| |
111 purple_debug_error("QQ", |
| |
112 "Fail creating sys msg ACK, expect %d bytes, build %d bytes\n", ack_len, bytes); |
| |
113 } |
| |
114 |
| |
115 static void _qq_process_msg_sys_notice(PurpleConnection *gc, gchar *from, gchar *to, gchar *msg_utf8) |
| |
116 { |
| |
117 qq_data *qd = (qq_data *) gc->proto_data; |
| |
118 gchar *title, *content; |
| |
119 |
| |
120 g_return_if_fail(from != NULL && to != NULL); |
| |
121 |
| |
122 title = g_strdup_printf(_("From %s:"), from); |
| |
123 content = g_strdup_printf(_("%s"), msg_utf8); |
| |
124 |
| |
125 if (qd->is_show_notice) { |
| |
126 purple_notify_info(gc, _("QQ Server Notice"), title, content); |
| |
127 } else { |
| |
128 purple_debug_info("QQ", "QQ Server notice from %s:\n%s", from, msg_utf8); |
| |
129 } |
| |
130 g_free(title); |
| |
131 g_free(content); |
| |
132 } |
| |
133 |
| |
134 static void process_server_msg(guint8 *data, gint data_len, guint16 seq, PurpleConnection *gc) |
| |
135 { |
| |
136 qq_data *qd; |
| |
137 gchar **segments, *code, *from, *to, *msg, *msg_utf8; |
| |
138 int funct; |
| |
139 |
| |
140 g_return_if_fail(data != NULL && data_len != 0); |
| |
141 |
| |
142 qd = (qq_data *) gc->proto_data; |
| |
143 |
| |
144 if (NULL == (segments = split_data(data, data_len, "\x1f", 4))) |
| |
145 return; |
| |
146 code = segments[0]; |
| |
147 from = segments[1]; |
| |
148 to = segments[2]; |
| |
149 msg = segments[3]; |
| |
150 |
| |
151 _qq_send_packet_ack_msg_sys(gc, code[0], strtol(from, NULL, 10), seq); |
| |
152 |
| |
153 if (strtol(to, NULL, 10) != qd->uid) { /* not to me */ |
| |
154 purple_debug_error("QQ", "Recv sys msg to [%s], not me!, discard\n", to); |
| |
155 g_strfreev(segments); |
| |
156 return; |
| |
157 } |
| |
158 |
| |
159 msg_utf8 = qq_to_utf8(msg, QQ_CHARSET_DEFAULT); |
| |
160 if (from == NULL && msg_utf8) { |
| |
161 purple_debug_error("QQ", "Recv NULL sys msg to [%s], discard\n", to); |
| |
162 g_strfreev(segments); |
| |
163 g_free(msg_utf8); |
| |
164 return; |
| |
165 } |
| |
166 |
| |
167 funct = strtol(code, NULL, 10); |
| |
168 switch (funct) { |
| |
169 case QQ_SERVER_BUDDY_ADDED: |
| |
170 case QQ_SERVER_BUDDY_ADD_REQUEST: |
| |
171 case QQ_SERVER_BUDDY_ADDED_ME: |
| |
172 case QQ_SERVER_BUDDY_REJECTED_ME: |
| |
173 qq_process_buddy_from_server(gc, funct, from, to, msg_utf8); |
| |
174 break; |
| |
175 case QQ_SERVER_NOTICE: |
| |
176 _qq_process_msg_sys_notice(gc, from, to, msg_utf8); |
| |
177 break; |
| |
178 case QQ_SERVER_NEW_CLIENT: |
| |
179 purple_debug_warning("QQ", |
| |
180 "QQ Server has newer client than %s\n", qq_get_ver_desc(QQ_CLIENT)); |
| |
181 break; |
| |
182 default: |
| |
183 purple_debug_warning("QQ", "Recv unknown sys msg code: %s\nMsg: %s\n", code, msg_utf8); |
| |
184 } |
| |
185 g_free(msg_utf8); |
| |
186 g_strfreev(segments); |
| |
187 } |
| |
188 |
| 86 void qq_proc_server_cmd(PurpleConnection *gc, guint16 cmd, guint16 seq, guint8 *rcved, gint rcved_len) |
189 void qq_proc_server_cmd(PurpleConnection *gc, guint16 cmd, guint16 seq, guint8 *rcved, gint rcved_len) |
| 87 { |
190 { |
| 88 qq_data *qd; |
191 qq_data *qd; |
| 89 |
192 |
| 90 guint8 *data; |
193 guint8 *data; |
| 553 |
652 |
| 554 switch (cmd) { |
653 switch (cmd) { |
| 555 case QQ_CMD_UPDATE_INFO: |
654 case QQ_CMD_UPDATE_INFO: |
| 556 qq_process_modify_info_reply(data, data_len, gc); |
655 qq_process_modify_info_reply(data, data_len, gc); |
| 557 break; |
656 break; |
| 558 case QQ_CMD_ADD_BUDDY_WO_AUTH: |
657 case QQ_CMD_BUDDY_ADD_NO_AUTH: |
| 559 qq_process_add_buddy_reply(data, data_len, seq, gc); |
658 qq_process_buddy_add_no_auth(data, data_len, ship32, gc); |
| 560 break; |
659 break; |
| 561 case QQ_CMD_DEL_BUDDY: |
660 case QQ_CMD_BUDDY_REMOVE: |
| 562 qq_process_remove_buddy_reply(data, data_len, gc); |
661 qq_process_buddy_remove(data, data_len, gc); |
| 563 break; |
662 break; |
| 564 case QQ_CMD_REMOVE_SELF: |
663 case QQ_CMD_REMOVE_ME: |
| 565 qq_process_remove_self_reply(data, data_len, gc); |
664 qq_process_buddy_remove_me(data, data_len, gc); |
| 566 break; |
665 break; |
| 567 case QQ_CMD_BUDDY_AUTH: |
666 case QQ_CMD_BUDDY_ADD_AUTH: |
| 568 qq_process_add_buddy_auth_reply(data, data_len, gc); |
667 qq_process_buddy_add_auth(data, data_len, gc); |
| 569 break; |
668 break; |
| 570 case QQ_CMD_GET_BUDDY_INFO: |
669 case QQ_CMD_GET_BUDDY_INFO: |
| 571 qq_process_get_buddy_info(data, data_len, gc); |
670 qq_process_get_buddy_info(data, data_len, ship32, gc); |
| 572 break; |
671 break; |
| 573 case QQ_CMD_CHANGE_STATUS: |
672 case QQ_CMD_CHANGE_STATUS: |
| 574 qq_process_change_status_reply(data, data_len, gc); |
673 qq_process_change_status_reply(data, data_len, gc); |
| 575 break; |
674 break; |
| 576 case QQ_CMD_SEND_IM: |
675 case QQ_CMD_SEND_IM: |