comparison libpurple/protocols/qq/qq_process.c @ 23685:58bb7fc244e4

2008.08.03 - csyfek <csyfek(at)gmail.com> * Commit lost files to Pidgin
author SHiNE CsyFeK <csyfek@gmail.com>
date Sun, 03 Aug 2008 05:13:29 +0000
parents
children eba700811832
comparison
equal deleted inserted replaced
23684:dd30b4323639 23685:58bb7fc244e4
1 /**
2 * @file qq_network.c
3 *
4 * purple
5 *
6 * Purple 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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
23 */
24
25 #include "cipher.h"
26 #include "debug.h"
27 #include "internal.h"
28
29 #ifdef _WIN32
30 #define random rand
31 #define srandom srand
32 #endif
33
34 #include "buddy_info.h"
35 #include "buddy_list.h"
36 #include "buddy_opt.h"
37 #include "group_info.h"
38 #include "group_free.h"
39 #include "char_conv.h"
40 #include "crypt.h"
41 #include "group_network.h"
42 #include "header_info.h"
43 #include "qq_base.h"
44 #include "im.h"
45 #include "qq_process.h"
46 #include "packet_parse.h"
47 #include "qq_network.h"
48 #include "qq_trans.h"
49 #include "sys_msg.h"
50 #include "utils.h"
51
52 /* default process, decrypt and dump */
53 static void process_cmd_unknow(PurpleConnection *gc,gchar *title, guint8 *buf, gint buf_len, guint16 cmd, guint16 seq)
54 {
55 qq_data *qd;
56 guint8 *data;
57 gint data_len;
58 gchar *msg_utf8 = NULL;
59
60 g_return_if_fail(buf != NULL && buf_len != 0);
61
62 qq_show_packet(title, buf, buf_len);
63
64 qd = (qq_data *) gc->proto_data;
65
66 data_len = buf_len;
67 data = g_newa(guint8, data_len);
68 memset(data, 0, data_len);
69 if ( !qq_decrypt(buf, buf_len, qd->session_key, data, &data_len )) {
70 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Fail decrypt packet with default process\n");
71 return;
72 }
73
74 qq_hex_dump(PURPLE_DEBUG_WARNING, "QQ",
75 data, data_len,
76 ">>> [%d] %s -> [default] decrypt and dump",
77 seq, qq_get_cmd_desc(cmd));
78
79 msg_utf8 = try_dump_as_gbk(data, data_len);
80 if (msg_utf8) {
81 g_free(msg_utf8);
82 }
83 }
84
85 void qq_proc_cmd_server(PurpleConnection *gc,
86 guint16 cmd, guint16 seq, guint8 *data, gint data_len)
87 {
88 /* now process the packet */
89 switch (cmd) {
90 case QQ_CMD_RECV_IM:
91 qq_process_recv_im(data, data_len, seq, gc);
92 break;
93 case QQ_CMD_RECV_MSG_SYS:
94 qq_process_msg_sys(data, data_len, seq, gc);
95 break;
96 case QQ_CMD_RECV_MSG_BUDDY_CHANGE_STATUS:
97 qq_process_buddy_change_status(data, data_len, gc);
98 break;
99 default:
100 process_cmd_unknow(gc, "Unknow SERVER CMD", data, data_len, cmd, seq);
101 break;
102 }
103 }
104
105 static void process_cmd_login(PurpleConnection *gc, guint8 *data, gint data_len)
106 {
107 qq_data *qd;
108 guint ret_8;
109
110 g_return_if_fail (gc != NULL && gc->proto_data != NULL);
111
112 qd = (qq_data *) gc->proto_data;
113
114 ret_8 = qq_process_login_reply(data, data_len, gc);
115 if (ret_8 == QQ_LOGIN_REPLY_OK) {
116 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Login repliess OK; everything is fine\n");
117
118 purple_connection_set_state(gc, PURPLE_CONNECTED);
119 qd->logged_in = TRUE; /* must be defined after sev_finish_login */
120
121 /* now initiate QQ Qun, do it first as it may take longer to finish */
122 qq_group_init(gc);
123
124 /* Now goes on updating my icon/nickname, not showing info_window */
125 qd->modifying_face = FALSE;
126
127 qq_send_packet_get_info(gc, qd->uid, FALSE);
128 /* grab my level */
129 qq_send_packet_get_level(gc, qd->uid);
130
131 qq_send_packet_change_status(gc);
132
133 /* refresh buddies */
134 qq_send_packet_get_buddies_list(gc, 0);
135
136 /* refresh groups */
137 qq_send_packet_get_all_list_with_group(gc, 0);
138
139 return;
140 }
141
142 if (ret_8 == QQ_LOGIN_REPLY_REDIRECT) {
143 qd->is_redirect = TRUE;
144 /*
145 purple_debug(PURPLE_DEBUG_WARNING, "QQ",
146 "Redirected to new server: %s:%d\n", qd->real_hostname, qd->real_port);
147 */
148 return;
149 }
150
151 if (ret_8 == QQ_LOGIN_REPLY_ERR_PWD) {
152 if (!purple_account_get_remember_password(gc->account)) {
153 purple_account_set_password(gc->account, NULL);
154 }
155 purple_connection_error_reason(gc,
156 PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Incorrect password."));
157 return;
158 }
159
160 if (ret_8 == QQ_LOGIN_REPLY_ERR_MISC) {
161 if (purple_debug_is_enabled())
162 purple_connection_error_reason(gc,
163 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to login. Check debug log."));
164 else
165 purple_connection_error_reason(gc,
166 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to login"));
167 return;
168 }
169 }
170
171 void qq_proc_cmd_reply(PurpleConnection *gc,
172 guint16 cmd, guint16 seq, guint8 *data, gint data_len)
173 {
174 gboolean ret_bool = FALSE;
175 guint8 ret_8 = 0;
176 guint16 ret_16 = 0;
177 guint32 ret_32 = 0;
178 gchar *error_msg = NULL;
179
180 switch (cmd) {
181 case QQ_CMD_TOKEN:
182 ret_8 = qq_process_token_reply(gc, error_msg, data, data_len);
183 if (ret_8 != QQ_TOKEN_REPLY_OK) {
184 if (error_msg == NULL) {
185 error_msg = g_strdup_printf( _("Invalid token reply code, 0x%02X"), ret_8);
186 }
187 purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_msg);
188 g_free(error_msg);
189 return;
190 }
191
192 qq_send_packet_login(gc);
193 break;
194 case QQ_CMD_LOGIN:
195 process_cmd_login(gc, data, data_len);
196 break;
197 case QQ_CMD_UPDATE_INFO:
198 qq_process_modify_info_reply(data, data_len, gc);
199 break;
200 case QQ_CMD_ADD_BUDDY_WO_AUTH:
201 qq_process_add_buddy_reply(data, data_len, seq, gc);
202 break;
203 case QQ_CMD_DEL_BUDDY:
204 qq_process_remove_buddy_reply(data, data_len, gc);
205 break;
206 case QQ_CMD_REMOVE_SELF:
207 qq_process_remove_self_reply(data, data_len, gc);
208 break;
209 case QQ_CMD_BUDDY_AUTH:
210 qq_process_add_buddy_auth_reply(data, data_len, gc);
211 break;
212 case QQ_CMD_GET_USER_INFO:
213 qq_process_get_info_reply(data, data_len, gc);
214 break;
215 case QQ_CMD_CHANGE_ONLINE_STATUS:
216 qq_process_change_status_reply(data, data_len, gc);
217 break;
218 case QQ_CMD_SEND_IM:
219 qq_process_send_im_reply(data, data_len, gc);
220 break;
221 case QQ_CMD_KEEP_ALIVE:
222 qq_process_keep_alive(data, data_len, gc);
223 break;
224 case QQ_CMD_GET_BUDDIES_ONLINE:
225 ret_8 = qq_process_get_buddies_online_reply(data, data_len, gc);
226 if (ret_8 > 0 && ret_8 < 0xff) {
227 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Requesting for more online buddies\n");
228 qq_send_packet_get_buddies_online(gc, ret_8);
229 } else {
230 purple_debug(PURPLE_DEBUG_INFO, "QQ", "All online buddies received\n");
231 /* Fixme: this should not be called once*/
232 qq_send_packet_get_buddies_levels(gc);
233
234 qq_refresh_all_buddy_status(gc);
235 }
236 break;
237 case QQ_CMD_GET_LEVEL:
238 qq_process_get_level_reply(data, data_len, gc);
239 break;
240 case QQ_CMD_GET_BUDDIES_LIST:
241 ret_16 = qq_process_get_buddies_list_reply(data, data_len, gc);
242 if (ret_16 > 0 && ret_16 < 0xffff) {
243 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Requesting for more buddies\n");
244 qq_send_packet_get_buddies_list(gc, ret_16);
245 } else {
246 purple_debug(PURPLE_DEBUG_INFO, "QQ", "All buddies received. Requesting buddies' levels\n");
247 qq_send_packet_get_buddies_online(gc, 0);
248 }
249 break;
250 case QQ_CMD_GROUP_CMD:
251 qq_process_group_cmd_reply(data, data_len, seq, gc);
252 break;
253 case QQ_CMD_GET_ALL_LIST_WITH_GROUP:
254 ret_32 = qq_process_get_all_list_with_group_reply(data, data_len, gc);
255 if (ret_32 > 0 && ret_32 < 0xffffffff) {
256 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Requesting for more buddies and groups\n");
257 qq_send_packet_get_all_list_with_group(gc, ret_32);
258 } else {
259 purple_debug(PURPLE_DEBUG_INFO, "QQ", "All buddies and groups received\n");
260 }
261 break;
262 default:
263 process_cmd_unknow(gc, "Unknow reply CMD", data, data_len, cmd, seq);
264 break;
265 }
266 }
267