Mercurial > pidgin.yaz
comparison libpurple/protocols/qq/group_join.c @ 23753:5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
* Commit to Pidgin
2008.08.06 - ccpaging <ecc_hy(at)hotmail.com>
* Rename names of variables, Group, to Room
* Functions of group_network merged into qq_network and qq_process
* Canceled managing glist of group packet, add sub_cmdd and room_id to transaction
* Fixed error of demo group:
If 'room list' and 'room infor' are not setup, response received from server will emits
'room_id = 0' packet.
2008.08.04 - ccpaging <ecc_hy(at)hotmail.com>
* Use new crypt/decrypt functions
* Rename crypt.c/h to qq_crypt.c/h
* Clean code of decrypt functions
* Fixed decryption failure
2008.08.04 - csyfek <csyfek(at)gmail.com>
* Update AUTHORS
author | SHiNE CsyFeK <csyfek@gmail.com> |
---|---|
date | Sun, 10 Aug 2008 04:32:14 +0000 |
parents | 9a5d140400f1 |
children | 967344bc404d |
comparison
equal
deleted
inserted
replaced
23748:107166bb2a64 | 23753:5f454b975a99 |
---|---|
36 #include "group_free.h" | 36 #include "group_free.h" |
37 #include "group_internal.h" | 37 #include "group_internal.h" |
38 #include "group_info.h" | 38 #include "group_info.h" |
39 #include "group_join.h" | 39 #include "group_join.h" |
40 #include "group_opt.h" | 40 #include "group_opt.h" |
41 #include "group_network.h" | |
42 #include "group_search.h" | 41 #include "group_search.h" |
42 #include "header_info.h" | |
43 #include "packet_parse.h" | |
44 #include "qq_network.h" | |
43 | 45 |
44 enum { | 46 enum { |
45 QQ_GROUP_JOIN_OK = 0x01, | 47 QQ_GROUP_JOIN_OK = 0x01, |
46 QQ_GROUP_JOIN_NEED_AUTH = 0x02, | 48 QQ_GROUP_JOIN_NEED_AUTH = 0x02, |
47 }; | 49 }; |
48 | 50 |
49 static void _qq_group_exit_with_gc_and_id(gc_and_uid *g) | 51 static void _qq_group_exit_with_gc_and_id(gc_and_uid *g) |
50 { | 52 { |
51 PurpleConnection *gc; | 53 PurpleConnection *gc; |
52 guint32 internal_group_id; | 54 guint32 id; |
53 qq_group *group; | 55 qq_group *group; |
54 | 56 |
55 gc = g->gc; | 57 gc = g->gc; |
56 internal_group_id = g->uid; | 58 id = g->uid; |
57 | 59 |
58 group = qq_group_find_by_id(gc, internal_group_id, QQ_INTERNAL_ID); | 60 group = qq_room_search_id(gc, id); |
59 g_return_if_fail(group != NULL); | 61 g_return_if_fail(group != NULL); |
60 | 62 |
61 qq_send_cmd_group_exit_group(gc, group); | 63 qq_send_room_cmd_only(gc, QQ_ROOM_CMD_QUIT, group->id); |
62 } | 64 } |
63 | 65 |
64 /* send packet to join a group without auth */ | 66 /* send packet to join a group without auth */ |
65 void qq_send_cmd_group_join_group(PurpleConnection *gc, qq_group *group) | 67 void qq_send_cmd_group_join_group(PurpleConnection *gc, qq_group *group) |
66 { | 68 { |
67 guint8 raw_data[16] = {0}; | |
68 gint bytes = 0; | |
69 | |
70 g_return_if_fail(group != NULL); | 69 g_return_if_fail(group != NULL); |
71 | 70 |
72 if (group->my_status == QQ_GROUP_MEMBER_STATUS_NOT_MEMBER) { | 71 if (group->my_status == QQ_GROUP_MEMBER_STATUS_NOT_MEMBER) { |
73 group->my_status = QQ_GROUP_MEMBER_STATUS_APPLYING; | 72 group->my_status = QQ_GROUP_MEMBER_STATUS_APPLYING; |
74 qq_group_refresh(gc, group); | 73 qq_group_refresh(gc, group); |
84 default: | 83 default: |
85 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Unknown group auth type: %d\n", group->auth_type); | 84 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Unknown group auth type: %d\n", group->auth_type); |
86 break; | 85 break; |
87 } | 86 } |
88 | 87 |
89 bytes = 0; | 88 qq_send_room_cmd_only(gc, QQ_ROOM_CMD_JOIN, group->id); |
90 bytes += qq_put8(raw_data + bytes, QQ_GROUP_CMD_JOIN_GROUP); | |
91 bytes += qq_put32(raw_data + bytes, group->internal_group_id); | |
92 | |
93 qq_send_group_cmd(gc, group, raw_data, bytes); | |
94 } | 89 } |
95 | 90 |
96 static void _qq_group_join_auth_with_gc_and_id(gc_and_uid *g, const gchar *reason_utf8) | 91 static void _qq_group_join_auth_with_gc_and_id(gc_and_uid *g, const gchar *reason_utf8) |
97 { | 92 { |
98 PurpleConnection *gc; | 93 PurpleConnection *gc; |
99 qq_group *group; | 94 qq_group *group; |
100 guint32 internal_group_id; | 95 guint32 id; |
101 | 96 |
102 gc = g->gc; | 97 gc = g->gc; |
103 internal_group_id = g->uid; | 98 id = g->uid; |
104 | 99 |
105 group = qq_group_find_by_id(gc, internal_group_id, QQ_INTERNAL_ID); | 100 group = qq_room_search_id(gc, id); |
106 if (group == NULL) { | 101 if (group == NULL) { |
107 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Can not find qq_group by internal_id: %d\n", internal_group_id); | 102 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Can not find qq_group by internal_id: %d\n", id); |
108 return; | 103 return; |
109 } else { /* everything is OK */ | 104 } else { /* everything is OK */ |
110 qq_send_cmd_group_auth(gc, group, QQ_GROUP_AUTH_REQUEST_APPLY, 0, reason_utf8); | 105 qq_send_cmd_group_auth(gc, group, QQ_GROUP_AUTH_REQUEST_APPLY, 0, reason_utf8); |
111 } | 106 } |
112 } | 107 } |
116 gchar *msg; | 111 gchar *msg; |
117 gc_and_uid *g; | 112 gc_and_uid *g; |
118 g_return_if_fail(group != NULL); | 113 g_return_if_fail(group != NULL); |
119 | 114 |
120 purple_debug(PURPLE_DEBUG_INFO, "QQ", | 115 purple_debug(PURPLE_DEBUG_INFO, "QQ", |
121 "Group (internal id: %d) needs authentication\n", group->internal_group_id); | 116 "Group (internal id: %d) needs authentication\n", group->id); |
122 | 117 |
123 msg = g_strdup_printf("Group \"%s\" needs authentication\n", group->group_name_utf8); | 118 msg = g_strdup_printf("Group \"%s\" needs authentication\n", group->group_name_utf8); |
124 g = g_new0(gc_and_uid, 1); | 119 g = g_new0(gc_and_uid, 1); |
125 g->gc = gc; | 120 g->gc = gc; |
126 g->uid = group->internal_group_id; | 121 g->uid = group->id; |
127 purple_request_input(gc, NULL, msg, | 122 purple_request_input(gc, NULL, msg, |
128 _("Input request here"), | 123 _("Input request here"), |
129 _("Would you be my friend?"), TRUE, FALSE, NULL, | 124 _("Would you be my friend?"), TRUE, FALSE, NULL, |
130 _("Send"), | 125 _("Send"), |
131 G_CALLBACK(_qq_group_join_auth_with_gc_and_id), | 126 G_CALLBACK(_qq_group_join_auth_with_gc_and_id), |
137 | 132 |
138 void qq_send_cmd_group_auth(PurpleConnection *gc, qq_group *group, guint8 opt, guint32 uid, const gchar *reason_utf8) | 133 void qq_send_cmd_group_auth(PurpleConnection *gc, qq_group *group, guint8 opt, guint32 uid, const gchar *reason_utf8) |
139 { | 134 { |
140 guint8 *raw_data; | 135 guint8 *raw_data; |
141 gchar *reason_qq; | 136 gchar *reason_qq; |
142 gint bytes, data_len; | 137 gint bytes; |
143 | 138 |
144 g_return_if_fail(group != NULL); | 139 g_return_if_fail(group != NULL); |
145 | 140 |
146 if (reason_utf8 == NULL || strlen(reason_utf8) == 0) | 141 if (reason_utf8 == NULL || strlen(reason_utf8) == 0) |
147 reason_qq = g_strdup(""); | 142 reason_qq = g_strdup(""); |
152 group->my_status = QQ_GROUP_MEMBER_STATUS_APPLYING; | 147 group->my_status = QQ_GROUP_MEMBER_STATUS_APPLYING; |
153 qq_group_refresh(gc, group); | 148 qq_group_refresh(gc, group); |
154 uid = 0; | 149 uid = 0; |
155 } | 150 } |
156 | 151 |
157 data_len = 10 + strlen(reason_qq) + 1; | 152 raw_data = g_newa(guint8, 6 + strlen(reason_qq)); |
158 raw_data = g_newa(guint8, data_len); | |
159 | 153 |
160 bytes = 0; | 154 bytes = 0; |
161 bytes += qq_put8(raw_data + bytes, QQ_GROUP_CMD_JOIN_GROUP_AUTH); | |
162 bytes += qq_put32(raw_data + bytes, group->internal_group_id); | |
163 bytes += qq_put8(raw_data + bytes, opt); | 155 bytes += qq_put8(raw_data + bytes, opt); |
164 bytes += qq_put32(raw_data + bytes, uid); | 156 bytes += qq_put32(raw_data + bytes, uid); |
165 bytes += qq_put8(raw_data + bytes, strlen(reason_qq)); | 157 bytes += qq_put8(raw_data + bytes, strlen(reason_qq)); |
166 bytes += qq_putdata(raw_data + bytes, (guint8 *) reason_qq, strlen(reason_qq)); | 158 bytes += qq_putdata(raw_data + bytes, (guint8 *) reason_qq, strlen(reason_qq)); |
167 | 159 |
168 if (bytes != data_len) { | 160 qq_send_room_cmd(gc, QQ_ROOM_CMD_AUTH, group->id, raw_data, bytes); |
169 purple_debug(PURPLE_DEBUG_ERROR, "QQ", | |
170 "Fail create packet for %s\n", qq_group_cmd_get_desc(QQ_GROUP_CMD_JOIN_GROUP_AUTH)); | |
171 return; | |
172 } | |
173 | |
174 qq_send_group_cmd(gc, group, raw_data, data_len); | |
175 } | |
176 | |
177 /* send a packet to exit a group */ | |
178 void qq_send_cmd_group_exit_group(PurpleConnection *gc, qq_group *group) | |
179 { | |
180 guint8 raw_data[16] = {0}; | |
181 gint bytes = 0; | |
182 | |
183 g_return_if_fail(group != NULL); | |
184 | |
185 bytes += qq_put8(raw_data + bytes, QQ_GROUP_CMD_EXIT_GROUP); | |
186 bytes += qq_put32(raw_data + bytes, group->internal_group_id); | |
187 | |
188 qq_send_group_cmd(gc, group, raw_data, bytes); | |
189 } | 161 } |
190 | 162 |
191 /* If comes here, cmd is OK already */ | 163 /* If comes here, cmd is OK already */ |
192 void qq_process_group_cmd_exit_group(guint8 *data, gint len, PurpleConnection *gc) | 164 void qq_process_group_cmd_exit_group(guint8 *data, gint len, PurpleConnection *gc) |
193 { | 165 { |
194 gint bytes; | 166 gint bytes; |
195 guint32 internal_group_id; | 167 guint32 id; |
196 PurpleChat *chat; | 168 PurpleChat *chat; |
197 qq_group *group; | 169 qq_group *group; |
198 qq_data *qd; | 170 qq_data *qd; |
199 | 171 |
200 g_return_if_fail(data != NULL && len > 0); | 172 g_return_if_fail(data != NULL && len > 0); |
205 "Invalid exit group reply, expect %d bytes, read %d bytes\n", 4, len); | 177 "Invalid exit group reply, expect %d bytes, read %d bytes\n", 4, len); |
206 return; | 178 return; |
207 } | 179 } |
208 | 180 |
209 bytes = 0; | 181 bytes = 0; |
210 bytes += qq_get32(&internal_group_id, data + bytes); | 182 bytes += qq_get32(&id, data + bytes); |
211 | 183 |
212 group = qq_group_find_by_id(gc, internal_group_id, QQ_INTERNAL_ID); | 184 group = qq_room_search_id(gc, id); |
213 if (group != NULL) { | 185 if (group != NULL) { |
214 chat = purple_blist_find_chat | 186 chat = purple_blist_find_chat |
215 (purple_connection_get_account(gc), g_strdup_printf("%d", group->external_group_id)); | 187 (purple_connection_get_account(gc), g_strdup_printf("%d", group->ext_id)); |
216 if (chat != NULL) | 188 if (chat != NULL) |
217 purple_blist_remove_chat(chat); | 189 purple_blist_remove_chat(chat); |
218 qq_group_delete_internal_record(qd, internal_group_id); | 190 qq_group_delete_internal_record(qd, id); |
219 } | 191 } |
220 purple_notify_info(gc, _("QQ Qun Operation"), _("You have successfully left the group"), NULL); | 192 purple_notify_info(gc, _("QQ Qun Operation"), _("You have successfully left the group"), NULL); |
221 } | 193 } |
222 | 194 |
223 /* Process the reply to group_auth subcmd */ | 195 /* Process the reply to group_auth subcmd */ |
224 void qq_process_group_cmd_join_group_auth(guint8 *data, gint len, PurpleConnection *gc) | 196 void qq_process_group_cmd_join_group_auth(guint8 *data, gint len, PurpleConnection *gc) |
225 { | 197 { |
226 gint bytes; | 198 gint bytes; |
227 guint32 internal_group_id; | 199 guint32 id; |
228 qq_data *qd; | 200 qq_data *qd; |
229 | 201 |
230 g_return_if_fail(data != NULL && len > 0); | 202 g_return_if_fail(data != NULL && len > 0); |
231 qd = (qq_data *) gc->proto_data; | 203 qd = (qq_data *) gc->proto_data; |
232 | 204 |
234 purple_debug(PURPLE_DEBUG_ERROR, "QQ", | 206 purple_debug(PURPLE_DEBUG_ERROR, "QQ", |
235 "Invalid join group reply, expect %d bytes, read %d bytes\n", 4, len); | 207 "Invalid join group reply, expect %d bytes, read %d bytes\n", 4, len); |
236 return; | 208 return; |
237 } | 209 } |
238 bytes = 0; | 210 bytes = 0; |
239 bytes += qq_get32(&internal_group_id, data + bytes); | 211 bytes += qq_get32(&id, data + bytes); |
240 g_return_if_fail(internal_group_id > 0); | 212 g_return_if_fail(id > 0); |
241 | 213 |
242 purple_notify_info(gc, _("QQ Group Auth"), | 214 purple_notify_info(gc, _("QQ Group Auth"), |
243 _("Your authorization request has been accepted by the QQ server"), NULL); | 215 _("Your authorization request has been accepted by the QQ server"), NULL); |
244 } | 216 } |
245 | 217 |
246 /* process group cmd reply "join group" */ | 218 /* process group cmd reply "join group" */ |
247 void qq_process_group_cmd_join_group(guint8 *data, gint len, PurpleConnection *gc) | 219 void qq_process_group_cmd_join_group(guint8 *data, gint len, PurpleConnection *gc) |
248 { | 220 { |
249 gint bytes; | 221 gint bytes; |
250 guint32 internal_group_id; | 222 guint32 id; |
251 guint8 reply; | 223 guint8 reply; |
252 qq_group *group; | 224 qq_group *group; |
253 | 225 |
254 g_return_if_fail(data != NULL && len > 0); | 226 g_return_if_fail(data != NULL && len > 0); |
255 | 227 |
258 "Invalid join group reply, expect %d bytes, read %d bytes\n", 5, len); | 230 "Invalid join group reply, expect %d bytes, read %d bytes\n", 5, len); |
259 return; | 231 return; |
260 } | 232 } |
261 | 233 |
262 bytes = 0; | 234 bytes = 0; |
263 bytes += qq_get32(&internal_group_id, data + bytes); | 235 bytes += qq_get32(&id, data + bytes); |
264 bytes += qq_get8(&reply, data + bytes); | 236 bytes += qq_get8(&reply, data + bytes); |
265 | 237 |
266 /* join group OK */ | 238 /* join group OK */ |
267 group = qq_group_find_by_id(gc, internal_group_id, QQ_INTERNAL_ID); | 239 group = qq_room_search_id(gc, id); |
268 /* need to check if group is NULL or not. */ | 240 /* need to check if group is NULL or not. */ |
269 g_return_if_fail(group != NULL); | 241 g_return_if_fail(group != NULL); |
270 switch (reply) { | 242 switch (reply) { |
271 case QQ_GROUP_JOIN_OK: | 243 case QQ_GROUP_JOIN_OK: |
272 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Succeed joining group \"%s\"\n", group->group_name_utf8); | 244 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Succeed joining group \"%s\"\n", group->group_name_utf8); |
273 group->my_status = QQ_GROUP_MEMBER_STATUS_IS_MEMBER; | 245 group->my_status = QQ_GROUP_MEMBER_STATUS_IS_MEMBER; |
274 qq_group_refresh(gc, group); | 246 qq_group_refresh(gc, group); |
275 /* this must be shown before getting online members */ | 247 /* this must be shown before getting online members */ |
276 qq_group_conv_show_window(gc, group); | 248 qq_group_conv_show_window(gc, group); |
277 qq_send_cmd_group_get_group_info(gc, group); | 249 qq_send_room_cmd_only(gc, QQ_ROOM_CMD_GET_INFO, group->id); |
278 break; | 250 break; |
279 case QQ_GROUP_JOIN_NEED_AUTH: | 251 case QQ_GROUP_JOIN_NEED_AUTH: |
280 purple_debug(PURPLE_DEBUG_INFO, "QQ", | 252 purple_debug(PURPLE_DEBUG_INFO, "QQ", |
281 "Fail joining group [%d] %s, needs authentication\n", | 253 "Fail joining group [%d] %s, needs authentication\n", |
282 group->external_group_id, group->group_name_utf8); | 254 group->ext_id, group->group_name_utf8); |
283 group->my_status = QQ_GROUP_MEMBER_STATUS_NOT_MEMBER; | 255 group->my_status = QQ_GROUP_MEMBER_STATUS_NOT_MEMBER; |
284 qq_group_refresh(gc, group); | 256 qq_group_refresh(gc, group); |
285 _qq_group_join_auth(gc, group); | 257 _qq_group_join_auth(gc, group); |
286 break; | 258 break; |
287 default: | 259 default: |
288 purple_debug(PURPLE_DEBUG_INFO, "QQ", | 260 purple_debug(PURPLE_DEBUG_INFO, "QQ", |
289 "Error joining group [%d] %s, unknown reply: 0x%02x\n", | 261 "Error joining group [%d] %s, unknown reply: 0x%02x\n", |
290 group->external_group_id, group->group_name_utf8, reply); | 262 group->ext_id, group->group_name_utf8, reply); |
291 } | 263 } |
292 } | 264 } |
293 | 265 |
294 /* Attempt to join a group without auth */ | 266 /* Attempt to join a group without auth */ |
295 void qq_group_join(PurpleConnection *gc, GHashTable *data) | 267 void qq_group_join(PurpleConnection *gc, GHashTable *data) |
296 { | 268 { |
297 qq_data *qd; | 269 qq_data *qd; |
298 gchar *external_group_id_ptr; | 270 gchar *ext_id_ptr; |
299 guint32 external_group_id; | 271 guint32 ext_id; |
300 qq_group *group; | 272 qq_group *group; |
301 | 273 |
302 g_return_if_fail(data != NULL); | 274 g_return_if_fail(data != NULL); |
303 qd = (qq_data *) gc->proto_data; | 275 qd = (qq_data *) gc->proto_data; |
304 | 276 |
305 external_group_id_ptr = g_hash_table_lookup(data, QQ_GROUP_KEY_EXTERNAL_ID); | 277 ext_id_ptr = g_hash_table_lookup(data, QQ_GROUP_KEY_EXTERNAL_ID); |
306 g_return_if_fail(external_group_id_ptr != NULL); | 278 g_return_if_fail(ext_id_ptr != NULL); |
307 errno = 0; | 279 errno = 0; |
308 external_group_id = strtol(external_group_id_ptr, NULL, 10); | 280 ext_id = strtol(ext_id_ptr, NULL, 10); |
309 if (errno != 0) { | 281 if (errno != 0) { |
310 purple_notify_error(gc, _("Error"), | 282 purple_notify_error(gc, _("Error"), |
311 _("You entered a group ID outside the acceptable range"), NULL); | 283 _("You entered a group ID outside the acceptable range"), NULL); |
312 return; | 284 return; |
313 } | 285 } |
314 | 286 |
315 group = qq_group_find_by_id(gc, external_group_id, QQ_EXTERNAL_ID); | 287 group = qq_room_search_ext_id(gc, ext_id); |
316 if (group) { | 288 if (group) { |
317 qq_send_cmd_group_join_group(gc, group); | 289 qq_send_cmd_group_join_group(gc, group); |
318 } else { | 290 } else { |
319 qq_set_pending_id(&qd->joining_groups, external_group_id, TRUE); | 291 qq_set_pending_id(&qd->joining_groups, ext_id, TRUE); |
320 qq_send_cmd_group_search_group(gc, external_group_id); | 292 qq_send_cmd_group_search_group(gc, ext_id); |
321 } | 293 } |
322 } | 294 } |
323 | 295 |
324 void qq_group_exit(PurpleConnection *gc, GHashTable *data) | 296 void qq_group_exit(PurpleConnection *gc, GHashTable *data) |
325 { | 297 { |
326 gchar *internal_group_id_ptr; | 298 gchar *id_ptr; |
327 guint32 internal_group_id; | 299 guint32 id; |
328 gc_and_uid *g; | 300 gc_and_uid *g; |
329 | 301 |
330 g_return_if_fail(data != NULL); | 302 g_return_if_fail(data != NULL); |
331 | 303 |
332 internal_group_id_ptr = g_hash_table_lookup(data, "internal_group_id"); | 304 id_ptr = g_hash_table_lookup(data, QQ_GROUP_KEY_INTERNAL_ID); |
333 internal_group_id = strtol(internal_group_id_ptr, NULL, 10); | 305 id = strtol(id_ptr, NULL, 10); |
334 | 306 |
335 g_return_if_fail(internal_group_id > 0); | 307 g_return_if_fail(id > 0); |
336 | 308 |
337 g = g_new0(gc_and_uid, 1); | 309 g = g_new0(gc_and_uid, 1); |
338 g->gc = gc; | 310 g->gc = gc; |
339 g->uid = internal_group_id; | 311 g->uid = id; |
340 | 312 |
341 purple_request_action(gc, _("QQ Qun Operation"), | 313 purple_request_action(gc, _("QQ Qun Operation"), |
342 _("Are you sure you want to leave this Qun?"), | 314 _("Are you sure you want to leave this Qun?"), |
343 _ | 315 _ |
344 ("Note, if you are the creator, \nthis operation will eventually remove this Qun."), | 316 ("Note, if you are the creator, \nthis operation will eventually remove this Qun."), |