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."),