Mercurial > pidgin
comparison libpurple/protocols/qq/group_network.c @ 15373:5fe8042783c1
Rename gtk/ and libgaim/ to pidgin/ and libpurple/
author | Sean Egan <seanegan@gmail.com> |
---|---|
date | Sat, 20 Jan 2007 02:32:10 +0000 |
parents | |
children | 32c366eeeb99 |
comparison
equal
deleted
inserted
replaced
15372:f79e0f4df793 | 15373:5fe8042783c1 |
---|---|
1 /** | |
2 * @file group_network.c | |
3 * | |
4 * gaim | |
5 * | |
6 * Gaim 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
23 */ | |
24 | |
25 #include "debug.h" | |
26 #include "notify.h" | |
27 | |
28 #include "char_conv.h" | |
29 #include "crypt.h" | |
30 #include "group_conv.h" | |
31 #include "group_find.h" | |
32 #include "group_internal.h" | |
33 #include "group_im.h" | |
34 #include "group_info.h" | |
35 #include "group_join.h" | |
36 #include "group_network.h" | |
37 #include "group_opt.h" | |
38 #include "group_search.h" | |
39 #include "header_info.h" | |
40 #include "send_core.h" | |
41 #include "utils.h" | |
42 | |
43 enum { | |
44 QQ_GROUP_CMD_REPLY_OK = 0x00, | |
45 QQ_GROUP_CMD_REPLY_SEARCH_ERROR = 0x02, | |
46 QQ_GROUP_CMD_REPLY_NOT_MEMBER = 0x0a | |
47 }; | |
48 | |
49 const gchar *qq_group_cmd_get_desc(qq_group_cmd cmd) | |
50 { | |
51 switch (cmd) { | |
52 case QQ_GROUP_CMD_CREATE_GROUP: | |
53 return "QQ_GROUP_CMD_CREATE_GROUP"; | |
54 case QQ_GROUP_CMD_MEMBER_OPT: | |
55 return "QQ_GROUP_CMD_MEMBER_OPT"; | |
56 case QQ_GROUP_CMD_MODIFY_GROUP_INFO: | |
57 return "QQ_GROUP_CMD_MODIFY_GROUP_INFO"; | |
58 case QQ_GROUP_CMD_GET_GROUP_INFO: | |
59 return "QQ_GROUP_CMD_GET_GROUP_INFO"; | |
60 case QQ_GROUP_CMD_ACTIVATE_GROUP: | |
61 return "QQ_GROUP_CMD_ACTIVATE_GROUP"; | |
62 case QQ_GROUP_CMD_SEARCH_GROUP: | |
63 return "QQ_GROUP_CMD_SEARCH_GROUP"; | |
64 case QQ_GROUP_CMD_JOIN_GROUP: | |
65 return "QQ_GROUP_CMD_JOIN_GROUP"; | |
66 case QQ_GROUP_CMD_JOIN_GROUP_AUTH: | |
67 return "QQ_GROUP_CMD_JOIN_GROUP_AUTH"; | |
68 case QQ_GROUP_CMD_EXIT_GROUP: | |
69 return "QQ_GROUP_CMD_EXIT_GROUP"; | |
70 case QQ_GROUP_CMD_SEND_MSG: | |
71 return "QQ_GROUP_CMD_SEND_MSG"; | |
72 case QQ_GROUP_CMD_GET_ONLINE_MEMBER: | |
73 return "QQ_GROUP_CMD_GET_ONLINE_MEMBER"; | |
74 case QQ_GROUP_CMD_GET_MEMBER_INFO: | |
75 return "QQ_GROUP_CMD_GET_MEMBER_INFO"; | |
76 default: | |
77 return "Unknown QQ Group Command"; | |
78 } | |
79 } | |
80 | |
81 /* default process of reply error */ | |
82 static void _qq_process_group_cmd_reply_error_default(guint8 reply, guint8 *cursor, gint len, GaimConnection *gc) | |
83 { | |
84 gchar *msg, *msg_utf8; | |
85 g_return_if_fail(cursor != NULL && len > 0); | |
86 | |
87 msg = g_strndup((gchar *) cursor, len); /* it will append 0x00 */ | |
88 msg_utf8 = qq_to_utf8(msg, QQ_CHARSET_DEFAULT); | |
89 g_free(msg); | |
90 msg = g_strdup_printf(_("Code [0x%02X]: %s"), reply, msg_utf8); | |
91 gaim_notify_error(gc, NULL, _("Group Operation Error"), msg); | |
92 g_free(msg); | |
93 g_free(msg_utf8); | |
94 } | |
95 | |
96 /* default process, dump only */ | |
97 static void _qq_process_group_cmd_reply_default(guint8 *data, guint8 **cursor, gint len, GaimConnection *gc) | |
98 { | |
99 gchar *hex_dump; | |
100 g_return_if_fail(data != NULL && len > 0); | |
101 | |
102 hex_dump = hex_dump_to_str(data, len); | |
103 gaim_debug(GAIM_DEBUG_INFO, "QQ", "Dump unprocessed group cmd reply:\n%s", hex_dump); | |
104 g_free(hex_dump); | |
105 } | |
106 | |
107 /* The lower layer command of send group cmd */ | |
108 void qq_send_group_cmd(GaimConnection *gc, qq_group *group, guint8 *raw_data, gint data_len) | |
109 { | |
110 qq_data *qd; | |
111 group_packet *p; | |
112 | |
113 g_return_if_fail(raw_data != NULL && data_len > 0); | |
114 | |
115 qd = (qq_data *) gc->proto_data; | |
116 | |
117 qq_send_cmd(gc, QQ_CMD_GROUP_CMD, TRUE, 0, TRUE, raw_data, data_len); | |
118 | |
119 p = g_new0(group_packet, 1); | |
120 | |
121 p->send_seq = qd->send_seq; | |
122 if (group == NULL) | |
123 p->internal_group_id = 0; | |
124 else | |
125 p->internal_group_id = group->internal_group_id; | |
126 | |
127 qd->group_packets = g_list_append(qd->group_packets, p); | |
128 } | |
129 | |
130 /* the main entry of group cmd processing, called by qq_recv_core.c */ | |
131 void qq_process_group_cmd_reply(guint8 *buf, gint buf_len, guint16 seq, GaimConnection *gc) | |
132 { | |
133 qq_group *group; | |
134 qq_data *qd; | |
135 gint len, bytes; | |
136 guint32 internal_group_id; | |
137 guint8 *data, *cursor, sub_cmd, reply; | |
138 | |
139 g_return_if_fail(buf != NULL && buf_len != 0); | |
140 | |
141 qd = (qq_data *) gc->proto_data; | |
142 len = buf_len; | |
143 data = g_newa(guint8, len); | |
144 | |
145 if (!qq_group_find_internal_group_id_by_seq(gc, seq, &internal_group_id)) { | |
146 gaim_debug(GAIM_DEBUG_WARNING, "QQ", "We have no record of group cmd, seq [%d]\n", seq); | |
147 return; | |
148 } | |
149 | |
150 if (qq_crypt(DECRYPT, buf, buf_len, qd->session_key, data, &len)) { | |
151 if (len <= 2) { | |
152 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Group cmd reply is too short, only %d bytes\n", len); | |
153 return; | |
154 } | |
155 | |
156 bytes = 0; | |
157 cursor = data; | |
158 bytes += read_packet_b(data, &cursor, len, &sub_cmd); | |
159 bytes += read_packet_b(data, &cursor, len, &reply); | |
160 | |
161 group = qq_group_find_by_id(gc, internal_group_id, QQ_INTERNAL_ID); | |
162 | |
163 if (reply != QQ_GROUP_CMD_REPLY_OK) { | |
164 gaim_debug(GAIM_DEBUG_WARNING, "QQ", | |
165 "Group cmd reply says cmd %s fails\n", qq_group_cmd_get_desc(sub_cmd)); | |
166 | |
167 if (group != NULL) | |
168 qq_set_pending_id(&qd->joining_groups, group->external_group_id, FALSE); | |
169 | |
170 switch (reply) { /* this should be all errors */ | |
171 case QQ_GROUP_CMD_REPLY_NOT_MEMBER: | |
172 if (group != NULL) { | |
173 gaim_debug(GAIM_DEBUG_WARNING, | |
174 "QQ", | |
175 "You are not a member of group \"%s\"\n", group->group_name_utf8); | |
176 group->my_status = QQ_GROUP_MEMBER_STATUS_NOT_MEMBER; | |
177 qq_group_refresh(gc, group); | |
178 } | |
179 break; | |
180 case QQ_GROUP_CMD_REPLY_SEARCH_ERROR: | |
181 if (qd->roomlist != NULL) { | |
182 if (gaim_roomlist_get_in_progress(qd->roomlist)) | |
183 gaim_roomlist_set_in_progress(qd->roomlist, FALSE); | |
184 } | |
185 _qq_process_group_cmd_reply_error_default(reply, cursor, len - bytes, gc); | |
186 break; | |
187 default: | |
188 _qq_process_group_cmd_reply_error_default(reply, cursor, len - bytes, gc); | |
189 } | |
190 return; | |
191 } | |
192 | |
193 /* seems ok so far, so we process the reply according to sub_cmd */ | |
194 switch (sub_cmd) { | |
195 case QQ_GROUP_CMD_GET_GROUP_INFO: | |
196 qq_process_group_cmd_get_group_info(data, &cursor, len, gc); | |
197 if (group != NULL) { | |
198 qq_send_cmd_group_get_members_info(gc, group); | |
199 qq_send_cmd_group_get_online_members(gc, group); | |
200 } | |
201 break; | |
202 case QQ_GROUP_CMD_CREATE_GROUP: | |
203 qq_group_process_create_group_reply(data, &cursor, len, gc); | |
204 break; | |
205 case QQ_GROUP_CMD_MODIFY_GROUP_INFO: | |
206 qq_group_process_modify_info_reply(data, &cursor, len, gc); | |
207 break; | |
208 case QQ_GROUP_CMD_MEMBER_OPT: | |
209 qq_group_process_modify_members_reply(data, &cursor, len, gc); | |
210 break; | |
211 case QQ_GROUP_CMD_ACTIVATE_GROUP: | |
212 qq_group_process_activate_group_reply(data, &cursor, len, gc); | |
213 break; | |
214 case QQ_GROUP_CMD_SEARCH_GROUP: | |
215 qq_process_group_cmd_search_group(data, &cursor, len, gc); | |
216 break; | |
217 case QQ_GROUP_CMD_JOIN_GROUP: | |
218 qq_process_group_cmd_join_group(data, &cursor, len, gc); | |
219 break; | |
220 case QQ_GROUP_CMD_JOIN_GROUP_AUTH: | |
221 qq_process_group_cmd_join_group_auth(data, &cursor, len, gc); | |
222 break; | |
223 case QQ_GROUP_CMD_EXIT_GROUP: | |
224 qq_process_group_cmd_exit_group(data, &cursor, len, gc); | |
225 break; | |
226 case QQ_GROUP_CMD_SEND_MSG: | |
227 qq_process_group_cmd_im(data, &cursor, len, gc); | |
228 break; | |
229 case QQ_GROUP_CMD_GET_ONLINE_MEMBER: | |
230 qq_process_group_cmd_get_online_members(data, &cursor, len, gc); | |
231 if (group != NULL) | |
232 qq_group_conv_refresh_online_member(gc, group); | |
233 break; | |
234 case QQ_GROUP_CMD_GET_MEMBER_INFO: | |
235 qq_process_group_cmd_get_members_info(data, &cursor, len, gc); | |
236 if (group != NULL) | |
237 qq_group_conv_refresh_online_member(gc, group); | |
238 break; | |
239 default: | |
240 gaim_debug(GAIM_DEBUG_WARNING, "QQ", | |
241 "Group cmd %s is processed by default\n", qq_group_cmd_get_desc(sub_cmd)); | |
242 _qq_process_group_cmd_reply_default(data, &cursor, len, gc); | |
243 } | |
244 | |
245 } else { | |
246 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Error decrypt group cmd reply\n"); | |
247 } | |
248 } |