comparison libpurple/protocols/qq/qq_trans.c @ 24019:147ada94a1d8

2008.08.16 - ccpaging <ecc_hy(at)hotmail.com> * Rename group to room. If you used pidginqq before, this may create a new room with same title, you may delete old one * Replace purple_debug with purple_debug_info, purple_debug_warning, purple_debug_error * Add server notice and server new, and two options to turn on/off * Minor modify for reducing transaction's debug infor * Minor modifies for system notice and QQ news. * Add 4 new strings need translate compare with p10.
author SHiNE CsyFeK <csyfek@gmail.com>
date Thu, 11 Sep 2008 13:25:07 +0000
parents 5f454b975a99
children 23cec4360d4a 25f62d21b3f8
comparison
equal deleted inserted replaced
24018:40a4e02027f4 24019:147ada94a1d8
35 #include "qq_process.h" 35 #include "qq_process.h"
36 #include "qq_trans.h" 36 #include "qq_trans.h"
37 37
38 #define QQ_RESEND_MAX 3 /* max resend per packet */ 38 #define QQ_RESEND_MAX 3 /* max resend per packet */
39 39
40 qq_transaction *qq_trans_find_rcved(qq_data *qd, guint16 cmd, guint16 seq) 40 enum {
41 { 41 QQ_TRANS_IS_SERVER = 0x01, /* Is server command or client command */
42 QQ_TRANS_IS_IMPORT = 0x02, /* Only notice if not get reply; or resend, disconn if reties get 0*/
43 QQ_TRANS_BEFORE_LOGIN = 0x04, /* server command before login*/
44 };
45
46 struct _qq_transaction {
47 guint8 flag;
48 guint16 seq;
49 guint16 cmd;
50
51 guint8 room_cmd;
52 guint32 room_id;
53
54 guint8 *data;
55 gint data_len;
56
57 gint fd;
58 gint send_retries;
59 gint rcved_times;
60 gint scan_times;
61
62 gint update_class;
63 guint32 ship32;
64 };
65
66 qq_transaction *qq_trans_find_rcved(PurpleConnection *gc, guint16 cmd, guint16 seq)
67 {
68 qq_data *qd = (qq_data *)gc->proto_data;
42 GList *curr; 69 GList *curr;
43 GList *next; 70 GList *next;
44 qq_transaction *trans; 71 qq_transaction *trans;
45 72
46 if (qd->transactions == NULL) { 73 if (qd->transactions == NULL) {
48 } 75 }
49 76
50 next = qd->transactions; 77 next = qd->transactions;
51 while( (curr = next) ) { 78 while( (curr = next) ) {
52 next = curr->next; 79 next = curr->next;
53 80
54 trans = (qq_transaction *) (curr->data); 81 trans = (qq_transaction *) (curr->data);
55 if(trans->cmd == cmd && trans->seq == seq) { 82 if(trans->cmd == cmd && trans->seq == seq) {
56 if (trans->rcved_times == 0) { 83 if (trans->rcved_times == 0) {
57 trans->scan_times = 0; 84 trans->scan_times = 0;
58 } 85 }
59 trans->rcved_times++; 86 trans->rcved_times++;
87 /* server may not get our confirm reply before, send reply again*/
88 /* only rcved buffer stored in transaction
60 if (qq_trans_is_server(trans) && qq_trans_is_dup(trans)) { 89 if (qq_trans_is_server(trans) && qq_trans_is_dup(trans)) {
61 /* server may not get our confirm reply before, send reply again*/
62 if (trans->data != NULL && trans->data_len > 0) { 90 if (trans->data != NULL && trans->data_len > 0) {
63 qq_send_data(qd, trans->cmd, trans->seq, FALSE, trans->data, trans->data_len); 91 qq_send_cmd_encrypted(gc, trans->cmd, trans->seq, trans->data, trans->data_len, FALSE);
64 } 92 }
65 } 93 }
94 */
66 return trans; 95 return trans;
67 } 96 }
68 } 97 }
69 98
70 return NULL; 99 return NULL;
71 } 100 }
72 101
73 gboolean qq_trans_is_server(qq_transaction *trans) 102 gboolean qq_trans_is_server(qq_transaction *trans)
74 { 103 {
75 g_return_val_if_fail(trans != NULL, FALSE); 104 g_return_val_if_fail(trans != NULL, FALSE);
76 105
77 if (trans->flag & QQ_TRANS_IS_SERVER) 106 if (trans->flag & QQ_TRANS_IS_SERVER)
78 return TRUE; 107 return TRUE;
79 else 108 else
80 return FALSE; 109 return FALSE;
81 } 110 }
82 111
83 gboolean qq_trans_is_dup(qq_transaction *trans) 112 gboolean qq_trans_is_dup(qq_transaction *trans)
84 { 113 {
85 g_return_val_if_fail(trans != NULL, TRUE); 114 g_return_val_if_fail(trans != NULL, TRUE);
86 115
87 if (trans->rcved_times > 1) 116 if (trans->rcved_times > 1)
88 return TRUE; 117 return TRUE;
89 else 118 else
90 return FALSE; 119 return FALSE;
91 } 120 }
100 { 129 {
101 g_return_val_if_fail(trans != NULL, 0); 130 g_return_val_if_fail(trans != NULL, 0);
102 return trans->room_id; 131 return trans->room_id;
103 } 132 }
104 133
134 gint qq_trans_get_class(qq_transaction *trans)
135 {
136 g_return_val_if_fail(trans != NULL, QQ_CMD_CLASS_NONE);
137 return trans->update_class;
138 }
139
140 gint qq_trans_get_ship(qq_transaction *trans)
141 {
142 g_return_val_if_fail(trans != NULL, 0);
143 return trans->ship32;
144 }
145
146 static qq_transaction *trans_create(PurpleConnection *gc, gint fd,
147 guint16 cmd, guint16 seq, guint8 *data, gint data_len, gint update_class, guint32 ship32)
148 {
149 qq_data *qd;
150 qq_transaction *trans;
151
152 g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, NULL);
153 qd = (qq_data *) gc->proto_data;
154
155 trans = g_new0(qq_transaction, 1);
156
157 memset(trans, 0, sizeof(qq_transaction));
158 trans->fd = fd;
159 trans->cmd = cmd;
160 trans->seq = seq;
161
162 trans->data = NULL;
163 trans->data_len = 0;
164 if (data != NULL && data_len > 0) {
165 /* don't use g_strdup, may have 0x00 */
166 trans->data = g_memdup(data, data_len);
167 trans->data_len = data_len;
168 }
169
170 trans->update_class = update_class;
171 return trans;
172 }
173
105 /* Remove a packet with seq from send trans */ 174 /* Remove a packet with seq from send trans */
106 static void trans_remove(qq_data *qd, qq_transaction *trans) 175 static void trans_remove(PurpleConnection *gc, qq_transaction *trans)
107 { 176 {
177 qq_data *qd = (qq_data *)gc->proto_data;
108 g_return_if_fail(qd != NULL && trans != NULL); 178 g_return_if_fail(qd != NULL && trans != NULL);
109 179
110 purple_debug(PURPLE_DEBUG_INFO, "QQ_TRANS", 180 #if 0
181 purple_debug_info("QQ_TRANS",
111 "Remove [%s%05d] retry %d rcved %d scan %d %s\n", 182 "Remove [%s%05d] retry %d rcved %d scan %d %s\n",
112 (trans->flag & QQ_TRANS_IS_SERVER) ? "SRV-" : "", 183 (trans->flag & QQ_TRANS_IS_SERVER) ? "SRV-" : "",
113 trans->seq, 184 trans->seq,
114 trans->send_retries, trans->rcved_times, trans->scan_times, 185 trans->send_retries, trans->rcved_times, trans->scan_times,
115 qq_get_cmd_desc(trans->cmd)); 186 qq_get_cmd_desc(trans->cmd));
116 187 #endif
117 if (trans->data) g_free(trans->data); 188 if (trans->data) g_free(trans->data);
118 qd->transactions = g_list_remove(qd->transactions, trans); 189 qd->transactions = g_list_remove(qd->transactions, trans);
119 g_free(trans); 190 g_free(trans);
120 } 191 }
121 192
122 void qq_trans_add_client_cmd(qq_data *qd, guint16 cmd, guint16 seq, guint8 *data, gint data_len) 193 void qq_trans_add_client_cmd(PurpleConnection *gc,
123 { 194 guint16 cmd, guint16 seq, guint8 *data, gint data_len, gint update_class, guint32 ship32)
124 qq_transaction *trans = g_new0(qq_transaction, 1); 195 {
125 196 qq_data *qd = (qq_data *)gc->proto_data;
126 g_return_if_fail(trans != NULL); 197 qq_transaction *trans = trans_create(gc, qd->fd, cmd, seq, data, data_len, update_class, ship32);
127 198
128 trans->flag = 0;
129 if (cmd == QQ_CMD_TOKEN || cmd == QQ_CMD_LOGIN || cmd == QQ_CMD_KEEP_ALIVE) { 199 if (cmd == QQ_CMD_TOKEN || cmd == QQ_CMD_LOGIN || cmd == QQ_CMD_KEEP_ALIVE) {
130 trans->flag |= QQ_TRANS_CLI_IMPORT; 200 trans->flag |= QQ_TRANS_IS_IMPORT;
131 } 201 }
132 trans->fd = qd->fd;
133 trans->cmd = cmd;
134 trans->seq = seq;
135 trans->room_cmd = 0;
136 trans->room_id = 0;
137 trans->send_retries = QQ_RESEND_MAX; 202 trans->send_retries = QQ_RESEND_MAX;
138 trans->rcved_times = 0; 203 #if 0
139 trans->scan_times = 0; 204 purple_debug_info("QQ_TRANS", "Add client cmd, seq %d, data %p, len %d\n",
140
141 trans->data = NULL;
142 trans->data_len = 0;
143 if (data != NULL && data_len > 0) {
144 trans->data = g_memdup(data, data_len); /* don't use g_strdup, may have 0x00 */
145 trans->data_len = data_len;
146 }
147 purple_debug(PURPLE_DEBUG_INFO, "QQ_TRANS",
148 "Add client cmd, seq = %d, data = %p, len = %d\n",
149 trans->seq, trans->data, trans->data_len); 205 trans->seq, trans->data, trans->data_len);
206 #endif
150 qd->transactions = g_list_append(qd->transactions, trans); 207 qd->transactions = g_list_append(qd->transactions, trans);
151 } 208 }
152 209
153 void qq_trans_add_room_cmd(qq_data *qd, guint16 seq, guint8 room_cmd, guint32 room_id, 210 void qq_trans_add_room_cmd(PurpleConnection *gc,
154 guint8 *data, gint data_len) 211 guint16 seq, guint8 room_cmd, guint32 room_id, guint8 *data, gint data_len,
155 { 212 gint update_class, guint32 ship32)
156 qq_transaction *trans = g_new0(qq_transaction, 1); 213 {
157 214 qq_data *qd = (qq_data *)gc->proto_data;
158 g_return_if_fail(trans != NULL); 215 qq_transaction *trans = trans_create(gc, qd->fd, QQ_CMD_ROOM, seq, data, data_len,
159 216 update_class, ship32);
160 trans->flag = 0; 217
161 trans->fd = qd->fd;
162 trans->seq = seq;
163 trans->cmd = QQ_CMD_ROOM;
164 trans->room_cmd = room_cmd; 218 trans->room_cmd = room_cmd;
165 trans->room_id = room_id; 219 trans->room_id = room_id;
166 trans->send_retries = QQ_RESEND_MAX; 220 trans->send_retries = QQ_RESEND_MAX;
167 trans->rcved_times = 0; 221 #if 0
168 trans->scan_times = 0; 222 purple_debug_info("QQ_TRANS", "Add room cmd, seq %d, data %p, len %d\n",
169
170 trans->data = NULL;
171 trans->data_len = 0;
172 if (data != NULL && data_len > 0) {
173 trans->data = g_memdup(data, data_len); /* don't use g_strdup, may have 0x00 */
174 trans->data_len = data_len;
175 }
176 purple_debug(PURPLE_DEBUG_INFO, "QQ_TRANS",
177 "Add room cmd, seq = %d, data = %p, len = %d\n",
178 trans->seq, trans->data, trans->data_len); 223 trans->seq, trans->data, trans->data_len);
224 #endif
179 qd->transactions = g_list_append(qd->transactions, trans); 225 qd->transactions = g_list_append(qd->transactions, trans);
180 } 226 }
181 227
182 void qq_trans_add_server_cmd(qq_data *qd, guint16 cmd, guint16 seq, guint8 *data, gint data_len) 228 void qq_trans_add_server_cmd(PurpleConnection *gc,
183 { 229 guint16 cmd, guint16 seq, guint8 *data, gint data_len)
184 qq_transaction *trans = g_new0(qq_transaction, 1); 230 {
185 231 qq_data *qd = (qq_data *)gc->proto_data;
186 g_return_if_fail(trans != NULL); 232 qq_transaction *trans = trans_create(gc, qd->fd, cmd, seq, data, data_len, QQ_CMD_CLASS_NONE, 0);
187 233
188 trans->flag = QQ_TRANS_IS_SERVER; 234 trans->flag = QQ_TRANS_IS_SERVER;
189 if ( !qd->logged_in ) { 235 if ( !qd->is_login ) {
190 trans->flag |= QQ_TRANS_BEFORE_LOGIN; 236 trans->flag |= QQ_TRANS_BEFORE_LOGIN;
191 } 237 }
192 trans->fd = qd->fd;
193 trans->cmd = cmd;
194 trans->seq = seq;
195 trans->room_cmd = 0;
196 trans->room_id = 0;
197 trans->send_retries = 0; 238 trans->send_retries = 0;
198 trans->rcved_times = 1; 239 trans->rcved_times = 1;
199 trans->scan_times = 0; 240 #if 0
200 trans->data = NULL; 241 purple_debug_info("QQ_TRANS", "Add server cmd, seq %d, data %p, len %d\n",
201 trans->data_len = 0;
202 if (data != NULL && data_len > 0) {
203 trans->data = g_memdup(data, data_len); /* don't use g_strdup, may have 0x00 */
204 trans->data_len = data_len;
205 }
206 purple_debug(PURPLE_DEBUG_INFO, "QQ_TRANS",
207 "Add server cmd, seq = %d, data = %p, len = %d\n",
208 trans->seq, trans->data, trans->data_len); 242 trans->seq, trans->data, trans->data_len);
243 #endif
209 qd->transactions = g_list_append(qd->transactions, trans); 244 qd->transactions = g_list_append(qd->transactions, trans);
210 } 245 }
211 246
212 void qq_trans_process_before_login(qq_data *qd) 247 void qq_trans_process_before_login(PurpleConnection *gc)
213 { 248 {
249 qq_data *qd = (qq_data *)gc->proto_data;
214 GList *curr; 250 GList *curr;
215 GList *next; 251 GList *next;
216 qq_transaction *trans; 252 qq_transaction *trans;
217 253
218 g_return_if_fail(qd != NULL); 254 g_return_if_fail(qd != NULL);
219 255
220 next = qd->transactions; 256 next = qd->transactions;
221 while( (curr = next) ) { 257 while( (curr = next) ) {
222 next = curr->next; 258 next = curr->next;
223 trans = (qq_transaction *) (curr->data); 259 trans = (qq_transaction *) (curr->data);
224 /* purple_debug(PURPLE_DEBUG_ERROR, "QQ_TRANS", "Scan [%d]\n", trans->seq); */ 260 #if 0
225 261 purple_debug_info("QQ_TRANS", "Scan [%d]\n", trans->seq);
262 #endif
226 if ( !(trans->flag & QQ_TRANS_IS_SERVER) ) { 263 if ( !(trans->flag & QQ_TRANS_IS_SERVER) ) {
227 continue; 264 continue;
228 } 265 }
229 if ( !(trans->flag & QQ_TRANS_BEFORE_LOGIN) ) { 266 if ( !(trans->flag & QQ_TRANS_BEFORE_LOGIN) ) {
230 continue; 267 continue;
231 } 268 }
232 // set QQ_TRANS_BEFORE_LOGIN off 269 /* set QQ_TRANS_BEFORE_LOGIN off */
233 trans->flag &= ~QQ_TRANS_BEFORE_LOGIN; 270 trans->flag &= ~QQ_TRANS_BEFORE_LOGIN;
234 271
235 purple_debug(PURPLE_DEBUG_ERROR, "QQ_TRANS", 272 purple_debug_info("QQ_TRANS",
236 "Process server cmd before login, seq %d, data %p, len %d, send_retries %d\n", 273 "Process server cmd before login, seq %d, data %p, len %d, send_retries %d\n",
237 trans->seq, trans->data, trans->data_len, trans->send_retries); 274 trans->seq, trans->data, trans->data_len, trans->send_retries);
238 275
239 qq_proc_cmd_reply(qd->gc, trans->seq, trans->cmd, trans->data, trans->data_len); 276 qq_proc_cmd_reply(gc, trans->seq, trans->cmd, trans->data, trans->data_len, trans->update_class, trans->ship32);
240 } 277 }
241 278
242 /* purple_debug(PURPLE_DEBUG_INFO, "QQ_TRANS", "Scan finished\n"); */ 279 /* purple_debug_info("QQ_TRANS", "Scan finished\n"); */
243 return; 280 return;
244 } 281 }
245 282
246 gboolean qq_trans_scan(qq_data *qd) 283 gboolean qq_trans_scan(PurpleConnection *gc)
247 { 284 {
285 qq_data *qd = (qq_data *)gc->proto_data;
248 GList *curr; 286 GList *curr;
249 GList *next; 287 GList *next;
250 qq_transaction *trans; 288 qq_transaction *trans;
251 289
252 g_return_val_if_fail(qd != NULL, FALSE); 290 g_return_val_if_fail(qd != NULL, FALSE);
253 291
254 next = qd->transactions; 292 next = qd->transactions;
255 while( (curr = next) ) { 293 while( (curr = next) ) {
256 next = curr->next; 294 next = curr->next;
257 trans = (qq_transaction *) (curr->data); 295 trans = (qq_transaction *) (curr->data);
258 /* purple_debug(PURPLE_DEBUG_INFO, "QQ_TRANS", "Scan [%d]\n", trans->seq); */ 296 /* purple_debug_info("QQ_TRANS", "Scan [%d]\n", trans->seq); */
259 297
260 if (trans->flag & QQ_TRANS_BEFORE_LOGIN) { 298 if (trans->flag & QQ_TRANS_BEFORE_LOGIN) {
261 /* keep server cmd before login*/ 299 /* keep server cmd before login*/
262 continue; 300 continue;
263 } 301 }
264 302
268 continue; 306 continue;
269 } 307 }
270 308
271 if (trans->rcved_times > 0) { 309 if (trans->rcved_times > 0) {
272 /* Has been received */ 310 /* Has been received */
273 trans_remove(qd, trans); 311 trans_remove(gc, trans);
274 continue; 312 continue;
275 } 313 }
276 314
277 if (trans->flag & QQ_TRANS_IS_SERVER) { 315 if (trans->flag & QQ_TRANS_IS_SERVER) {
278 continue; 316 continue;
279 } 317 }
280 318
281 /* Never get reply */ 319 /* Never get reply */
282 trans->send_retries--; 320 trans->send_retries--;
283 if (trans->send_retries <= 0) { 321 if (trans->send_retries <= 0) {
284 purple_debug(PURPLE_DEBUG_WARNING, "QQ_TRANS", 322 purple_debug_warning("QQ_TRANS",
285 "[%d] %s is lost.\n", 323 "[%d] %s is lost.\n",
286 trans->seq, qq_get_cmd_desc(trans->cmd)); 324 trans->seq, qq_get_cmd_desc(trans->cmd));
287 if (trans->flag & QQ_TRANS_CLI_IMPORT) { 325 if (trans->flag & QQ_TRANS_IS_IMPORT) {
288 return TRUE; 326 return TRUE;
289 } 327 }
290 328
291 purple_debug(PURPLE_DEBUG_ERROR, "QQ_TRANS", 329 purple_debug_error("QQ_TRANS",
292 "Lost [%d] %s, data %p, len %d, retries %d\n", 330 "Lost [%d] %s, data %p, len %d, retries %d\n",
293 trans->seq, qq_get_cmd_desc(trans->cmd), 331 trans->seq, qq_get_cmd_desc(trans->cmd),
294 trans->data, trans->data_len, trans->send_retries); 332 trans->data, trans->data_len, trans->send_retries);
295 trans_remove(qd, trans); 333 trans_remove(gc, trans);
296 continue; 334 continue;
297 } 335 }
298 336
299 purple_debug(PURPLE_DEBUG_ERROR, "QQ_TRANS", 337 purple_debug_error("QQ_TRANS",
300 "Resend [%d] %s data %p, len %d, send_retries %d\n", 338 "Resend [%d] %s data %p, len %d, send_retries %d\n",
301 trans->seq, qq_get_cmd_desc(trans->cmd), 339 trans->seq, qq_get_cmd_desc(trans->cmd),
302 trans->data, trans->data_len, trans->send_retries); 340 trans->data, trans->data_len, trans->send_retries);
303 qq_send_data(qd, trans->cmd, trans->seq, FALSE, trans->data, trans->data_len); 341 qq_send_cmd_encrypted(gc, trans->cmd, trans->seq, trans->data, trans->data_len, FALSE);
304 } 342 }
305 343
306 /* purple_debug(PURPLE_DEBUG_INFO, "QQ_TRANS", "Scan finished\n"); */ 344 /* purple_debug_info("QQ_TRANS", "Scan finished\n"); */
307 return FALSE; 345 return FALSE;
308 } 346 }
309 347
310 /* clean up send trans and free all contents */ 348 /* clean up send trans and free all contents */
311 void qq_trans_remove_all(qq_data *qd) 349 void qq_trans_remove_all(PurpleConnection *gc)
312 { 350 {
313 GList *curr; 351 qq_data *qd = (qq_data *)gc->proto_data;
314 GList *next;
315 qq_transaction *trans; 352 qq_transaction *trans;
316 gint count = 0; 353 gint count = 0;
317 354
318 curr = qd->transactions; 355 while(qd->transactions != NULL) {
319 while(curr) { 356 trans = (qq_transaction *) (qd->transactions->data);
320 next = curr->next; 357 qd->transactions = g_list_remove(qd->transactions, trans);
321 358
322 trans = (qq_transaction *) (curr->data); 359 if (trans->data) g_free(trans->data);
323 /* 360 g_free(trans);
324 purple_debug(PURPLE_DEBUG_ERROR, "QQ_TRANS",
325 "Remove to transaction, seq = %d, buf = %p, len = %d\n",
326 trans->seq, trans->buf, trans->len);
327 */
328 trans_remove(qd, trans);
329 361
330 count++; 362 count++;
331 curr = next; 363 }
332 } 364 if (count > 0) {
333 g_list_free(qd->transactions); 365 purple_debug_info("QQ_TRANS", "Free all %d packets\n", count);
334 366 }
335 purple_debug(PURPLE_DEBUG_INFO, "QQ_TRANS", "Free all %d packets\n", count); 367 }
336 }