00001
00023
00024
00025 #include "debug.h"
00026 #include "notify.h"
00027
00028 #include "utils.h"
00029 #include "char_conv.h"
00030 #include "crypt.h"
00031 #include "group_conv.h"
00032 #include "group_find.h"
00033 #include "group_hash.h"
00034 #include "group_im.h"
00035 #include "group_info.h"
00036 #include "group_join.h"
00037 #include "group_network.h"
00038 #include "group_opt.h"
00039 #include "group_search.h"
00040 #include "header_info.h"
00041 #include "send_core.h"
00042
00043 enum {
00044 QQ_GROUP_CMD_REPLY_OK = 0x00,
00045 QQ_GROUP_CMD_REPLY_NOT_MEMBER = 0x0a,
00046 };
00047
00048
00049 const gchar *qq_group_cmd_get_desc(qq_group_cmd cmd)
00050 {
00051 switch (cmd) {
00052 case QQ_GROUP_CMD_CREATE_GROUP:
00053 return "QQ_GROUP_CMD_CREATE_GROUP";
00054 case QQ_GROUP_CMD_MEMBER_OPT:
00055 return "QQ_GROUP_CMD_MEMBER_OPT";
00056 case QQ_GROUP_CMD_MODIFY_GROUP_INFO:
00057 return "QQ_GROUP_CMD_MODIFY_GROUP_INFO";
00058 case QQ_GROUP_CMD_GET_GROUP_INFO:
00059 return "QQ_GROUP_CMD_GET_GROUP_INFO";
00060 case QQ_GROUP_CMD_ACTIVATE_GROUP:
00061 return "QQ_GROUP_CMD_ACTIVATE_GROUP";
00062 case QQ_GROUP_CMD_SEARCH_GROUP:
00063 return "QQ_GROUP_CMD_SEARCH_GROUP";
00064 case QQ_GROUP_CMD_JOIN_GROUP:
00065 return "QQ_GROUP_CMD_JOIN_GROUP";
00066 case QQ_GROUP_CMD_JOIN_GROUP_AUTH:
00067 return "QQ_GROUP_CMD_JOIN_GROUP_AUTH";
00068 case QQ_GROUP_CMD_EXIT_GROUP:
00069 return "QQ_GROUP_CMD_EXIT_GROUP";
00070 case QQ_GROUP_CMD_SEND_MSG:
00071 return "QQ_GROUP_CMD_SEND_MSG";
00072 case QQ_GROUP_CMD_GET_ONLINE_MEMBER:
00073 return "QQ_GROUP_CMD_GET_ONLINE_MEMBER";
00074 case QQ_GROUP_CMD_GET_MEMBER_INFO:
00075 return "QQ_GROUP_CMD_GET_MEMBER_INFO";
00076 default:
00077 return "Unknown QQ Group Command";
00078 }
00079 }
00080
00081
00082
00083 void _qq_process_group_cmd_reply_error_default(guint8 reply, guint8 * cursor, gint len, GaimConnection * gc) {
00084 gchar *msg, *msg_utf8;
00085 g_return_if_fail(cursor != NULL && len > 0 && gc != NULL);
00086
00087 msg = g_strndup(cursor, len);
00088 msg_utf8 = qq_to_utf8(msg, QQ_CHARSET_DEFAULT);
00089 g_free(msg);
00090 msg = g_strdup_printf(_("Code [0x%02X]: %s"), reply, msg_utf8);
00091 gaim_notify_error(gc, NULL, _("Group Operation Error"), msg);
00092 g_free(msg);
00093 g_free(msg_utf8);
00094
00095 }
00096
00097
00098
00099 void _qq_process_group_cmd_reply_default(guint8 * data, guint8 ** cursor, gint len, GaimConnection * gc) {
00100 g_return_if_fail(gc != NULL && data != NULL && len > 0);
00101 gaim_debug(GAIM_DEBUG_INFO, "QQ", "Dump unprocessed group cmd reply:\n%s", hex_dump_to_str(data, len));
00102 }
00103
00104
00105
00106 void qq_send_group_cmd(GaimConnection * gc, qq_group * group, guint8 * raw_data, gint data_len) {
00107 qq_data *qd;
00108 group_packet *p;
00109
00110 g_return_if_fail(gc != NULL);
00111 g_return_if_fail(raw_data != NULL && data_len > 0);
00112
00113 qd = (qq_data *) gc->proto_data;
00114 g_return_if_fail(qd != NULL);
00115
00116 qq_send_cmd(gc, QQ_CMD_GROUP_CMD, TRUE, 0, TRUE, raw_data, data_len);
00117
00118 p = g_new0(group_packet, 1);
00119
00120 p->send_seq = qd->send_seq;
00121 if (group == NULL)
00122 p->internal_group_id = 0;
00123 else
00124 p->internal_group_id = group->internal_group_id;
00125
00126 qd->group_packets = g_list_append(qd->group_packets, p);
00127
00128 }
00129
00130
00131
00132 void qq_process_group_cmd_reply(guint8 * buf, gint buf_len, guint16 seq, GaimConnection * gc) {
00133 qq_group *group;
00134 qq_data *qd;
00135 gint len, bytes;
00136 guint32 internal_group_id;
00137 guint8 *data, *cursor, sub_cmd, reply;
00138
00139 g_return_if_fail(gc != NULL && gc->proto_data != NULL);
00140 g_return_if_fail(buf != NULL && buf_len != 0);
00141
00142 qd = (qq_data *) gc->proto_data;
00143 len = buf_len;
00144 data = g_newa(guint8, len);
00145
00146 if (!qq_group_find_internal_group_id_by_seq(gc, seq, &internal_group_id)) {
00147 gaim_debug(GAIM_DEBUG_WARNING, "QQ", "We have no record of group cmd, seq [%d]\n", seq);
00148 return;
00149 }
00150
00151 if (qq_crypt(DECRYPT, buf, buf_len, qd->session_key, data, &len)) {
00152 if (len <= 2) {
00153 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Group cmd reply is too short, only %d bytes\n", len);
00154 return;
00155 }
00156
00157 bytes = 0;
00158 cursor = data;
00159 bytes += read_packet_b(data, &cursor, len, &sub_cmd);
00160 bytes += read_packet_b(data, &cursor, len, &reply);
00161
00162 group = qq_group_find_by_internal_group_id(gc, internal_group_id);
00163
00164 if (reply != QQ_GROUP_CMD_REPLY_OK) {
00165 gaim_debug(GAIM_DEBUG_WARNING, "QQ",
00166 "Group cmd reply says cmd %s fails\n", qq_group_cmd_get_desc(sub_cmd));
00167 switch (reply) {
00168 case QQ_GROUP_CMD_REPLY_NOT_MEMBER:
00169 if (group != NULL) {
00170 gaim_debug(GAIM_DEBUG_WARNING,
00171 "QQ",
00172 "You are not a member of group \"%s\"\n", group->group_name_utf8);
00173 group->my_status = QQ_GROUP_MEMBER_STATUS_NOT_MEMBER;
00174 qq_group_refresh(gc, group);
00175 }
00176 break;
00177 default:
00178 _qq_process_group_cmd_reply_error_default(reply, cursor, len - bytes, gc);
00179 }
00180 return;
00181 }
00182
00183
00184 switch (sub_cmd) {
00185 case QQ_GROUP_CMD_GET_GROUP_INFO:
00186 qq_process_group_cmd_get_group_info(data, &cursor, len, gc);
00187 if (group != NULL) {
00188 qq_send_cmd_group_get_member_info(gc, group);
00189 qq_send_cmd_group_get_online_member(gc, group);
00190 }
00191 break;
00192 case QQ_GROUP_CMD_CREATE_GROUP:
00193 qq_group_process_create_group_reply(data, &cursor, len, gc);
00194 break;
00195 case QQ_GROUP_CMD_MODIFY_GROUP_INFO:
00196 qq_group_process_modify_info_reply(data, &cursor, len, gc);
00197 break;
00198 case QQ_GROUP_CMD_MEMBER_OPT:
00199 qq_group_process_modify_members_reply(data, &cursor, len, gc);
00200 break;
00201 case QQ_GROUP_CMD_ACTIVATE_GROUP:
00202 qq_group_process_activate_group_reply(data, &cursor, len, gc);
00203 break;
00204 case QQ_GROUP_CMD_SEARCH_GROUP:
00205 qq_process_group_cmd_search_group(data, &cursor, len, gc);
00206 break;
00207 case QQ_GROUP_CMD_JOIN_GROUP:
00208 qq_process_group_cmd_join_group(data, &cursor, len, gc);
00209 break;
00210 case QQ_GROUP_CMD_JOIN_GROUP_AUTH:
00211 qq_process_group_cmd_join_group_auth(data, &cursor, len, gc);
00212 break;
00213 case QQ_GROUP_CMD_EXIT_GROUP:
00214 qq_process_group_cmd_exit_group(data, &cursor, len, gc);
00215 break;
00216 case QQ_GROUP_CMD_SEND_MSG:
00217 qq_process_group_cmd_im(data, &cursor, len, gc);
00218 break;
00219 case QQ_GROUP_CMD_GET_ONLINE_MEMBER:
00220 qq_process_group_cmd_get_online_member(data, &cursor, len, gc);
00221 if (group != NULL)
00222 qq_group_conv_refresh_online_member(gc, group);
00223 break;
00224 case QQ_GROUP_CMD_GET_MEMBER_INFO:
00225 qq_process_group_cmd_get_member_info(data, &cursor, len, gc);
00226 if (group != NULL)
00227 qq_group_conv_refresh_online_member(gc, group);
00228 break;
00229 default:
00230 gaim_debug(GAIM_DEBUG_WARNING, "QQ",
00231 "Group cmd %s is processed by default\n", qq_group_cmd_get_desc(sub_cmd));
00232 _qq_process_group_cmd_reply_default(data, &cursor, len, gc);
00233 }
00234
00235 } else
00236 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Error decrypt group cmd reply\n");
00237
00238 }
00239
00240
00241