00001
00023
00024
00025 #include "debug.h"
00026 #include "internal.h"
00027 #include "notify.h"
00028 #include "request.h"
00029
00030 #include "utils.h"
00031 #include "packet_parse.h"
00032 #include "buddy_info.h"
00033 #include "buddy_list.h"
00034 #include "buddy_opt.h"
00035 #include "char_conv.h"
00036 #include "crypt.h"
00037 #include "header_info.h"
00038 #include "send_core.h"
00039 #include "sys_msg.h"
00040 #include "qq.h"
00041
00042 enum {
00043 QQ_MSG_SYS_BEING_ADDED = 0x01,
00044 QQ_MSG_SYS_ADD_CONTACT_REQUEST = 0x02,
00045 QQ_MSG_SYS_ADD_CONTACT_APPROVED = 0x03,
00046 QQ_MSG_SYS_ADD_CONTACT_REJECTED = 0x04,
00047 QQ_MSG_SYS_NEW_VERSION = 0x09,
00048 };
00049
00050
00051 void _qq_sys_msg_log_write(GaimConnection *gc, gchar *msg, gchar *from)
00052 {
00053 GaimLog *log;
00054 GaimAccount *account;
00055
00056 account = gaim_connection_get_account(gc);
00057 g_return_if_fail(gc != NULL && gc->proto_data != NULL);
00058
00059 log = gaim_log_new(GAIM_LOG_IM,
00060 "systemim",
00061 account,
00062 time(NULL)
00063 );
00064 gaim_log_write(log, GAIM_MESSAGE_SYSTEM, from,
00065 time(NULL), msg);
00066 gaim_log_free(log);
00067 }
00068
00069
00070
00071 void _qq_search_before_auth_with_gc_and_uid(gc_and_uid * g)
00072 {
00073 GaimConnection *gc;
00074 guint32 uid;
00075
00076 g_return_if_fail(g != NULL);
00077
00078 gc = g->gc;
00079 uid = g->uid;
00080 g_return_if_fail(gc != 0 && uid != 0);
00081
00082 qq_send_packet_get_info(gc, uid, TRUE);
00083 gaim_request_action
00084 (gc, NULL, _("Do you wanna approve the request?"), "", 2, g, 2,
00085 _("Reject"),
00086 G_CALLBACK(qq_reject_add_request_with_gc_and_uid),
00087 _("Approve"), G_CALLBACK(qq_approve_add_request_with_gc_and_uid));
00088
00089 }
00090
00091
00092 void _qq_search_before_add_with_gc_and_uid(gc_and_uid * g)
00093 {
00094 GaimConnection *gc;
00095 guint32 uid;
00096
00097 g_return_if_fail(g != NULL);
00098
00099 gc = g->gc;
00100 uid = g->uid;
00101 g_return_if_fail(gc != 0 && uid != 0);
00102
00103 qq_send_packet_get_info(gc, uid, TRUE);
00104 gaim_request_action
00105 (gc, NULL, _("Do you wanna add this buddy?"), "", 2, g, 2,
00106 _("Cancel"), NULL, _("Add"), G_CALLBACK(qq_add_buddy_with_gc_and_uid));
00107
00108 }
00109
00110
00111
00112 void _qq_send_packet_ack_msg_sys(GaimConnection * gc, guint8 code, guint32 from, guint16 seq) {
00113 guint8 bar, *ack, *cursor;
00114 gchar *str;
00115 gint ack_len, bytes;
00116
00117 str = g_strdup_printf("%d", from);
00118 bar = 0x1e;
00119 ack_len = 1 + 1 + strlen(str) + 1 + 2;
00120 ack = g_newa(guint8, ack_len);
00121 cursor = ack;
00122 bytes = 0;
00123
00124 bytes += create_packet_b(ack, &cursor, code);
00125 bytes += create_packet_b(ack, &cursor, bar);
00126 bytes += create_packet_data(ack, &cursor, str, strlen(str));
00127 bytes += create_packet_b(ack, &cursor, bar);
00128 bytes += create_packet_w(ack, &cursor, seq);
00129
00130 g_free(str);
00131
00132 if (bytes == ack_len)
00133 qq_send_cmd(gc, QQ_CMD_ACK_SYS_MSG, TRUE, 0, FALSE, ack, ack_len);
00134 else
00135 gaim_debug(GAIM_DEBUG_ERROR, "QQ",
00136 "Fail creating sys msg ACK, expect %d bytes, build %d bytes\n", ack_len, bytes);
00137
00138 }
00139
00140
00141
00142 void _qq_process_msg_sys_being_added(GaimConnection * gc, gchar * from, gchar * to, gchar * msg_utf8) {
00143 gchar *message;
00144 GaimBuddy *b;
00145 guint32 uid;
00146 gc_and_uid *g;
00147
00148 g_return_if_fail(gc != NULL && from != NULL && to != NULL);
00149
00150 uid = strtol(from, NULL, 10);
00151 b = gaim_find_buddy(gc->account, uid_to_gaim_name(uid));
00152 if (b == NULL) {
00153 g = g_new0(gc_and_uid, 1);
00154 g->gc = gc;
00155 g->uid = uid;
00156 message = g_strdup_printf(_("You have been added by %s"), from);
00157 _qq_sys_msg_log_write(gc, message, from);
00158 gaim_request_action(gc, NULL, message,
00159 _("Would like to add him?"), 2, g, 3,
00160 _("Cancel"), NULL, _("Add"),
00161 G_CALLBACK
00162 (qq_add_buddy_with_gc_and_uid),
00163 _("Search"), G_CALLBACK(_qq_search_before_add_with_gc_and_uid));
00164 } else {
00165 message = g_strdup_printf(_("%s has added you [%s]"), from, to);
00166 _qq_sys_msg_log_write(gc, message, from);
00167 gaim_notify_info(gc, NULL, message, NULL);
00168 }
00169
00170 g_free(message);
00171 }
00172
00173
00174
00175 void _qq_process_msg_sys_add_contact_rejected(GaimConnection * gc, gchar * from, gchar * to, gchar * msg_utf8) {
00176 gchar *message, *reason;
00177
00178 g_return_if_fail(gc != NULL && from != NULL && to != NULL);
00179
00180 message = g_strdup_printf(_("User %s rejected your request"), from);
00181 reason = g_strdup_printf(_("Reason: %s"), msg_utf8);
00182 _qq_sys_msg_log_write(gc, message, from);
00183
00184 gaim_notify_info(gc, NULL, message, reason);
00185 g_free(message);
00186 g_free(reason);
00187 }
00188
00189
00190
00191 void _qq_process_msg_sys_add_contact_approved(GaimConnection * gc, gchar * from, gchar * to, gchar * msg_utf8) {
00192 gchar *message;
00193 qq_data *qd;
00194
00195 g_return_if_fail(gc != NULL && from != NULL && to != NULL);
00196
00197 qd = (qq_data *) gc->proto_data;
00198 qq_add_buddy_by_recv_packet(gc, strtol(from, NULL, 10), TRUE, TRUE);
00199
00200 message = g_strdup_printf(_("Use %s has approved your request"), from);
00201 _qq_sys_msg_log_write(gc, message, from);
00202 gaim_notify_info(gc, NULL, message, NULL);
00203
00204 g_free(message);
00205 }
00206
00207
00208
00209 void _qq_process_msg_sys_add_contact_request(GaimConnection * gc, gchar * from, gchar * to, gchar * msg_utf8) {
00210 gchar *message, *reason;
00211 guint32 uid;
00212 gc_and_uid *g, *g2;
00213 GaimBuddy *b;
00214
00215 g_return_if_fail(gc != NULL && from != NULL && to != NULL);
00216
00217 uid = strtol(from, NULL, 10);
00218 g = g_new0(gc_and_uid, 1);
00219 g->gc = gc;
00220 g->uid = uid;
00221
00222 message = g_strdup_printf(_("%s wanna add you [%s] as friends"), from, to);
00223 reason = g_strdup_printf(_("Message: %s"), msg_utf8);
00224 _qq_sys_msg_log_write(gc, message, from);
00225
00226 gaim_request_action
00227 (gc, NULL, message, reason, 2, g, 3,
00228 _("Reject"),
00229 G_CALLBACK(qq_reject_add_request_with_gc_and_uid),
00230 _("Approve"),
00231 G_CALLBACK(qq_approve_add_request_with_gc_and_uid),
00232 _("Search"), G_CALLBACK(_qq_search_before_auth_with_gc_and_uid));
00233
00234 g_free(message);
00235 g_free(reason);
00236
00237 b = gaim_find_buddy(gc->account, uid_to_gaim_name(uid));
00238 if (b == NULL) {
00239 g2 = g_new0(gc_and_uid, 1);
00240 g2->gc = gc;
00241 g2->uid = strtol(from, NULL, 10);
00242 message = g_strdup_printf(_("%s is not in your buddy list"), from);
00243 gaim_request_action(gc, NULL, message,
00244 _("Would you like to add him?"), 2, g2,
00245 3, _("Cancel"), NULL, _("Add"),
00246 G_CALLBACK
00247 (qq_add_buddy_with_gc_and_uid),
00248 _("Search"), G_CALLBACK(_qq_search_before_add_with_gc_and_uid));
00249 g_free(message);
00250 }
00251
00252 }
00253
00254
00255 void qq_process_msg_sys(guint8 * buf, gint buf_len, guint16 seq, GaimConnection * gc) {
00256 qq_data *qd;
00257 gint len;
00258 guint8 *data;
00259 gchar **segments, *code, *from, *to, *msg, *msg_utf8;
00260
00261 g_return_if_fail(gc != NULL && gc->proto_data != NULL);
00262 g_return_if_fail(buf != NULL && buf_len != 0);
00263
00264 qd = (qq_data *) gc->proto_data;
00265 len = buf_len;
00266 data = g_newa(gchar, len);
00267
00268 if (qq_crypt(DECRYPT, buf, buf_len, qd->session_key, data, &len)) {
00269 if (NULL == (segments = split_data(data, len, "\x1f", 4)))
00270 return;
00271 code = segments[0];
00272 from = segments[1];
00273 to = segments[2];
00274 msg = segments[3];
00275
00276 _qq_send_packet_ack_msg_sys(gc, code[0], strtol(from, NULL, 10), seq);
00277
00278 if (strtol(to, NULL, 10) != qd->uid) {
00279 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Recv sys msg to [%s], not me!, discard\n", to);
00280 g_strfreev(segments);
00281 return;
00282 }
00283
00284 msg_utf8 = qq_to_utf8(msg, QQ_CHARSET_DEFAULT);
00285 switch (strtol(code, NULL, 10)) {
00286 case QQ_MSG_SYS_BEING_ADDED:
00287 _qq_process_msg_sys_being_added(gc, from, to, msg_utf8);
00288 break;
00289 case QQ_MSG_SYS_ADD_CONTACT_REQUEST:
00290 _qq_process_msg_sys_add_contact_request(gc, from, to, msg_utf8);
00291 break;
00292 case QQ_MSG_SYS_ADD_CONTACT_APPROVED:
00293 _qq_process_msg_sys_add_contact_approved(gc, from, to, msg_utf8);
00294 break;
00295 case QQ_MSG_SYS_ADD_CONTACT_REJECTED:
00296 _qq_process_msg_sys_add_contact_rejected(gc, from, to, msg_utf8);
00297 break;
00298 case QQ_MSG_SYS_NEW_VERSION:
00299 gaim_debug(GAIM_DEBUG_WARNING, "QQ",
00300 "QQ server says there is newer version than %s\n", qq_get_source_str(QQ_CLIENT));
00301 break;
00302 default:
00303 gaim_debug(GAIM_DEBUG_WARNING, "QQ", "Recv unknown sys msg code: %s\n", code);
00304 }
00305 g_free(msg_utf8);
00306 g_strfreev(segments);
00307
00308 } else
00309 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Error decrypt recv msg sys\n");
00310
00311 }
00312
00313
00314