📄 buddy_opt.c
字号:
/** * @file buddy_opt.c * * purple * * Purple is the legal property of its developers, whose names are too numerous * to list here. Please refer to the COPYRIGHT file distributed with this * source distribution. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include "debug.h"#include "internal.h"#include "notify.h"#include "request.h"#include "buddy_info.h"#include "buddy_list.h"#include "buddy_opt.h"#include "char_conv.h"#include "crypt.h"#include "header_info.h"#include "im.h"#include "keep_alive.h"#include "packet_parse.h"#include "send_core.h"#include "utils.h"#define PURPLE_GROUP_QQ_FORMAT "QQ (%s)"#define PURPLE_GROUP_QQ_UNKNOWN "QQ Unknown"#define PURPLE_GROUP_QQ_BLOCKED "QQ Blocked"#define QQ_REMOVE_BUDDY_REPLY_OK 0x00#define QQ_REMOVE_SELF_REPLY_OK 0x00#define QQ_ADD_BUDDY_AUTH_REPLY_OK 0x30 /* ASCII value of "0" */enum { QQ_MY_AUTH_APPROVE = 0x30, /* ASCII value of "0" */ QQ_MY_AUTH_REJECT = 0x31, /* ASCII value of "1" */ QQ_MY_AUTH_REQUEST = 0x32, /* ASCII value of "2" */};typedef struct _qq_add_buddy_request { guint32 uid; guint16 seq;} qq_add_buddy_request;/* send packet to remove a buddy from my buddy list */static void _qq_send_packet_remove_buddy(PurpleConnection *gc, guint32 uid){ gchar uid_str[11]; g_return_if_fail(uid > 0); g_snprintf(uid_str, sizeof(uid_str), "%d", uid); qq_send_cmd(gc, QQ_CMD_DEL_FRIEND, TRUE, 0, TRUE, (guint8 *) uid_str, strlen(uid_str));}/* try to remove myself from someone's buddy list */static void _qq_send_packet_remove_self_from(PurpleConnection *gc, guint32 uid){ guint8 *raw_data, *cursor; g_return_if_fail(uid > 0); raw_data = g_newa(guint8, 4); cursor = raw_data; create_packet_dw(raw_data, &cursor, uid); qq_send_cmd(gc, QQ_CMD_REMOVE_SELF, TRUE, 0, TRUE, raw_data, 4);}/* try to add a buddy without authentication */static void _qq_send_packet_add_buddy(PurpleConnection *gc, guint32 uid){ qq_data *qd; qq_add_buddy_request *req; gchar uid_str[11]; g_return_if_fail(uid > 0); /* we need to send the ascii code of this uid to qq server */ g_snprintf(uid_str, sizeof(uid_str), "%d", uid); qq_send_cmd(gc, QQ_CMD_ADD_FRIEND_WO_AUTH, TRUE, 0, TRUE, (guint8 *) uid_str, strlen(uid_str)); /* must be set after sending packet to get the correct send_seq */ qd = (qq_data *) gc->proto_data; req = g_new0(qq_add_buddy_request, 1); req->seq = qd->send_seq; req->uid = uid; qd->add_buddy_request = g_list_append(qd->add_buddy_request, req);}/* this buddy needs authentication, text conversion is done at lowest level */static void _qq_send_packet_buddy_auth(PurpleConnection *gc, guint32 uid, const gchar response, const gchar *text){ gchar *text_qq, uid_str[11]; guint8 bar, *cursor, *raw_data; g_return_if_fail(uid != 0); g_snprintf(uid_str, sizeof(uid_str), "%d", uid); bar = 0x1f; raw_data = g_newa(guint8, QQ_MSG_IM_MAX); cursor = raw_data; create_packet_data(raw_data, &cursor, (guint8 *) uid_str, strlen(uid_str)); create_packet_b(raw_data, &cursor, bar); create_packet_b(raw_data, &cursor, response); if (text != NULL) { text_qq = utf8_to_qq(text, QQ_CHARSET_DEFAULT); create_packet_b(raw_data, &cursor, bar); create_packet_data(raw_data, &cursor, (guint8 *) text_qq, strlen(text_qq)); g_free(text_qq); } qq_send_cmd(gc, QQ_CMD_BUDDY_AUTH, TRUE, 0, TRUE, raw_data, cursor - raw_data);}static void _qq_send_packet_add_buddy_auth_with_gc_and_uid(gc_and_uid *g, const gchar *text){ PurpleConnection *gc; guint32 uid; g_return_if_fail(g != NULL); gc = g->gc; uid = g->uid; g_return_if_fail(uid != 0); _qq_send_packet_buddy_auth(gc, uid, QQ_MY_AUTH_REQUEST, text); g_free(g);}/* the real packet to reject and request is sent from here */static void _qq_reject_add_request_real(gc_and_uid *g, const gchar *reason){ gint uid; PurpleConnection *gc; g_return_if_fail(g != NULL); gc = g->gc; uid = g->uid; g_return_if_fail(uid != 0); _qq_send_packet_buddy_auth(gc, uid, QQ_MY_AUTH_REJECT, reason); g_free(g);}/* we approve other's request of adding me as friend */void qq_approve_add_request_with_gc_and_uid(gc_and_uid *g){ gint uid; PurpleConnection *gc; g_return_if_fail(g != NULL); gc = g->gc; uid = g->uid; g_return_if_fail(uid != 0); _qq_send_packet_buddy_auth(gc, uid, QQ_MY_AUTH_APPROVE, NULL); g_free(g);}void qq_do_nothing_with_gc_and_uid(gc_and_uid *g, const gchar *msg){ g_free(g);}/* we reject other's request of adding me as friend */void qq_reject_add_request_with_gc_and_uid(gc_and_uid *g){ gint uid; gchar *msg1, *msg2; PurpleConnection *gc; gc_and_uid *g2; gchar *nombre; g_return_if_fail(g != NULL); gc = g->gc; uid = g->uid; g_return_if_fail(uid != 0); g_free(g); g2 = g_new0(gc_and_uid, 1); g2->gc = gc; g2->uid = uid; msg1 = g_strdup_printf(_("You rejected %d's request"), uid); msg2 = g_strdup(_("Input your reason:")); nombre = uid_to_purple_name(uid); purple_request_input(gc, _("Reject request"), msg1, msg2, _("Sorry, you are not my type..."), TRUE, FALSE, NULL, _("Reject"), G_CALLBACK(_qq_reject_add_request_real), _("Cancel"), NULL, purple_connection_get_account(gc), nombre, NULL, g2); g_free(nombre);}void qq_add_buddy_with_gc_and_uid(gc_and_uid *g){ gint uid; PurpleConnection *gc; g_return_if_fail(g != NULL); gc = g->gc; uid = g->uid; g_return_if_fail(uid != 0); _qq_send_packet_add_buddy(gc, uid); g_free(g);}void qq_block_buddy_with_gc_and_uid(gc_and_uid *g){ guint32 uid; PurpleConnection *gc; PurpleBuddy buddy; PurpleGroup group; g_return_if_fail(g != NULL); gc = g->gc; uid = g->uid; g_return_if_fail(uid > 0); buddy.name = uid_to_purple_name(uid); group.name = PURPLE_GROUP_QQ_BLOCKED; qq_remove_buddy(gc, &buddy, &group); _qq_send_packet_remove_self_from(gc, uid);}/* process reply to add_buddy_auth request */void qq_process_add_buddy_auth_reply(guint8 *buf, gint buf_len, PurpleConnection *gc){ qq_data *qd; gint len; guint8 *data, *cursor, reply; gchar **segments, *msg_utf8; g_return_if_fail(buf != NULL && buf_len != 0); qd = (qq_data *) gc->proto_data; len = buf_len; data = g_newa(guint8, len); cursor = data; if (qq_crypt(DECRYPT, buf, buf_len, qd->session_key, data, &len)) { read_packet_b(data, &cursor, len, &reply); if (reply != QQ_ADD_BUDDY_AUTH_REPLY_OK) { purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Add buddy with auth request fails\n"); if (NULL == (segments = split_data(data, len, "\x1f", 2))) return; msg_utf8 = qq_to_utf8(segments[1], QQ_CHARSET_DEFAULT); purple_notify_error(gc, NULL, _("Add buddy with auth request fails"), msg_utf8); g_free(msg_utf8); } else { purple_debug(PURPLE_DEBUG_INFO, "QQ", "Add buddy with auth request OK\n"); } } else { purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Error decrypt add buddy with auth reply\n"); }}/* process the server reply for my request to remove a buddy */void qq_process_remove_buddy_reply(guint8 *buf, gint buf_len, PurpleConnection *gc){ qq_data *qd; gint len; guint8 *data, *cursor, reply; g_return_if_fail(buf != NULL && buf_len != 0); qd = (qq_data *) gc->proto_data;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -