📄 msn.c
字号:
/** * @file msn.c The MSN protocol plugin * * 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 */#define PHOTO_SUPPORT 1#include <glib.h>#include "msn.h"#include "accountopt.h"#include "msg.h"#include "page.h"#include "pluginpref.h"#include "prefs.h"#include "session.h"#include "state.h"#include "util.h"#include "cmds.h"#include "core.h"#include "prpl.h"#include "msn-utils.h"#include "version.h"#include "switchboard.h"#include "notification.h"#include "sync.h"#include "slplink.h"#if PHOTO_SUPPORT#include "imgstore.h"#endiftypedef struct{ PurpleConnection *gc; const char *passport;} MsnMobileData;typedef struct{ PurpleConnection *gc; char *name;} MsnGetInfoData;typedef struct{ MsnGetInfoData *info_data; char *stripped; char *url_buffer; PurpleNotifyUserInfo *user_info; char *photo_url_text;} MsnGetInfoStepTwoData;typedef struct{ PurpleConnection *gc; const char *who; char *msg; PurpleMessageFlags flags; time_t when;} MsnIMData;static const char *msn_normalize(const PurpleAccount *account, const char *str){ static char buf[BUF_LEN]; char *tmp; g_return_val_if_fail(str != NULL, NULL); g_snprintf(buf, sizeof(buf), "%s%s", str, (strchr(str, '@') ? "" : "@hotmail.com")); tmp = g_utf8_strdown(buf, -1); strncpy(buf, tmp, sizeof(buf)); g_free(tmp); return buf;}static PurpleCmdRetmsn_cmd_nudge(PurpleConversation *conv, const gchar *cmd, gchar **args, gchar **error, void *data){ PurpleAccount *account = purple_conversation_get_account(conv); PurpleConnection *gc = purple_account_get_connection(account); MsnMessage *msg; MsnSession *session; MsnSwitchBoard *swboard; msg = msn_message_new_nudge(); session = gc->proto_data; swboard = msn_session_get_swboard(session, purple_conversation_get_name(conv), MSN_SB_FLAG_IM); if (swboard == NULL) return PURPLE_CMD_RET_FAILED; msn_switchboard_send_msg(swboard, msg, TRUE); purple_conversation_write(conv, NULL, _("You have just sent a Nudge!"), PURPLE_MESSAGE_SYSTEM, time(NULL)); return PURPLE_CMD_RET_OK;}static voidmsn_act_id(PurpleConnection *gc, const char *entry){ MsnCmdProc *cmdproc; MsnSession *session; PurpleAccount *account; const char *alias; session = gc->proto_data; cmdproc = session->notification->cmdproc; account = purple_connection_get_account(gc); if(entry && strlen(entry)) alias = purple_url_encode(entry); else alias = ""; if (strlen(alias) > BUDDY_ALIAS_MAXLEN) { purple_notify_error(gc, NULL, _("Your new MSN friendly name is too long."), NULL); return; } msn_cmdproc_send(cmdproc, "REA", "%s %s", purple_account_get_username(account), alias);}static voidmsn_set_prp(PurpleConnection *gc, const char *type, const char *entry){ MsnCmdProc *cmdproc; MsnSession *session; session = gc->proto_data; cmdproc = session->notification->cmdproc; if (entry == NULL || *entry == '\0') { msn_cmdproc_send(cmdproc, "PRP", "%s", type); } else { msn_cmdproc_send(cmdproc, "PRP", "%s %s", type, purple_url_encode(entry)); }}static voidmsn_set_home_phone_cb(PurpleConnection *gc, const char *entry){ msn_set_prp(gc, "PHH", entry);}static voidmsn_set_work_phone_cb(PurpleConnection *gc, const char *entry){ msn_set_prp(gc, "PHW", entry);}static voidmsn_set_mobile_phone_cb(PurpleConnection *gc, const char *entry){ msn_set_prp(gc, "PHM", entry);}static voidenable_msn_pages_cb(PurpleConnection *gc){ msn_set_prp(gc, "MOB", "Y");}static voiddisable_msn_pages_cb(PurpleConnection *gc){ msn_set_prp(gc, "MOB", "N");}static voidsend_to_mobile(PurpleConnection *gc, const char *who, const char *entry){ MsnTransaction *trans; MsnSession *session; MsnCmdProc *cmdproc; MsnPage *page; char *payload; size_t payload_len; session = gc->proto_data; cmdproc = session->notification->cmdproc; page = msn_page_new(); msn_page_set_body(page, entry); payload = msn_page_gen_payload(page, &payload_len); trans = msn_transaction_new(cmdproc, "PGD", "%s 1 %d", who, payload_len); msn_transaction_set_payload(trans, payload, payload_len); msn_page_destroy(page); msn_cmdproc_send_trans(cmdproc, trans);}static voidsend_to_mobile_cb(MsnMobileData *data, const char *entry){ send_to_mobile(data->gc, data->passport, entry); g_free(data);}static voidclose_mobile_page_cb(MsnMobileData *data, const char *entry){ g_free(data);}/* -- */static voidmsn_show_set_friendly_name(PurplePluginAction *action){ PurpleConnection *gc; gc = (PurpleConnection *) action->context; purple_request_input(gc, NULL, _("Set your friendly name."), _("This is the name that other MSN buddies will " "see you as."), purple_connection_get_display_name(gc), FALSE, FALSE, NULL, _("OK"), G_CALLBACK(msn_act_id), _("Cancel"), NULL, purple_connection_get_account(gc), NULL, NULL, gc);}static voidmsn_show_set_home_phone(PurplePluginAction *action){ PurpleConnection *gc; MsnSession *session; gc = (PurpleConnection *) action->context; session = gc->proto_data; purple_request_input(gc, NULL, _("Set your home phone number."), NULL, msn_user_get_home_phone(session->user), FALSE, FALSE, NULL, _("OK"), G_CALLBACK(msn_set_home_phone_cb), _("Cancel"), NULL, purple_connection_get_account(gc), NULL, NULL, gc);}static voidmsn_show_set_work_phone(PurplePluginAction *action){ PurpleConnection *gc; MsnSession *session; gc = (PurpleConnection *) action->context; session = gc->proto_data; purple_request_input(gc, NULL, _("Set your work phone number."), NULL, msn_user_get_work_phone(session->user), FALSE, FALSE, NULL, _("OK"), G_CALLBACK(msn_set_work_phone_cb), _("Cancel"), NULL, purple_connection_get_account(gc), NULL, NULL, gc);}static voidmsn_show_set_mobile_phone(PurplePluginAction *action){ PurpleConnection *gc; MsnSession *session; gc = (PurpleConnection *) action->context; session = gc->proto_data; purple_request_input(gc, NULL, _("Set your mobile phone number."), NULL, msn_user_get_mobile_phone(session->user), FALSE, FALSE, NULL, _("OK"), G_CALLBACK(msn_set_mobile_phone_cb), _("Cancel"), NULL, purple_connection_get_account(gc), NULL, NULL, gc);}static voidmsn_show_set_mobile_pages(PurplePluginAction *action){ PurpleConnection *gc; gc = (PurpleConnection *) action->context; purple_request_action(gc, NULL, _("Allow MSN Mobile pages?"), _("Do you want to allow or disallow people on " "your buddy list to send you MSN Mobile pages " "to your cell phone or other mobile device?"), -1, purple_connection_get_account(gc), NULL, NULL, gc, 3, _("Allow"), G_CALLBACK(enable_msn_pages_cb), _("Disallow"), G_CALLBACK(disable_msn_pages_cb), _("Cancel"), NULL);}static voidmsn_show_hotmail_inbox(PurplePluginAction *action){ PurpleConnection *gc; MsnSession *session; gc = (PurpleConnection *) action->context; session = gc->proto_data; if (session->passport_info.file == NULL) { purple_notify_error(gc, NULL, _("This Hotmail account may not be active."), NULL); return; } purple_notify_uri(gc, session->passport_info.file);}static voidshow_send_to_mobile_cb(PurpleBlistNode *node, gpointer ignored){ PurpleBuddy *buddy; PurpleConnection *gc; MsnSession *session; MsnMobileData *data; g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); buddy = (PurpleBuddy *) node; gc = purple_account_get_connection(buddy->account); session = gc->proto_data; data = g_new0(MsnMobileData, 1); data->gc = gc; data->passport = buddy->name; purple_request_input(gc, NULL, _("Send a mobile message."), NULL, NULL, TRUE, FALSE, NULL, _("Page"), G_CALLBACK(send_to_mobile_cb), _("Close"), G_CALLBACK(close_mobile_page_cb), purple_connection_get_account(gc), purple_buddy_get_name(buddy), NULL, data);}static gbooleanmsn_offline_message(const PurpleBuddy *buddy) { MsnUser *user; if (buddy == NULL) return FALSE; user = buddy->proto_data; return user && user->mobile;}static voidinitiate_chat_cb(PurpleBlistNode *node, gpointer data){ PurpleBuddy *buddy; PurpleConnection *gc; MsnSession *session; MsnSwitchBoard *swboard; g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); buddy = (PurpleBuddy *) node; gc = purple_account_get_connection(buddy->account); session = gc->proto_data; swboard = msn_switchboard_new(session); msn_switchboard_request(swboard); msn_switchboard_request_add_user(swboard, buddy->name); /* TODO: This might move somewhere else, after USR might be */ swboard->chat_id = session->conv_seq++; swboard->conv = serv_got_joined_chat(gc, swboard->chat_id, "MSN Chat"); swboard->flag = MSN_SB_FLAG_IM; purple_conv_chat_add_user(PURPLE_CONV_CHAT(swboard->conv), purple_account_get_username(buddy->account), NULL, PURPLE_CBFLAGS_NONE, TRUE);}static voidt_msn_xfer_init(PurpleXfer *xfer){ MsnSlpLink *slplink = xfer->data; msn_slplink_request_ft(slplink, xfer);}static PurpleXfer*msn_new_xfer(PurpleConnection *gc, const char *who){ MsnSession *session; MsnSlpLink *slplink; PurpleXfer *xfer; session = gc->proto_data; xfer = purple_xfer_new(gc->account, PURPLE_XFER_SEND, who); if (xfer) { slplink = msn_session_get_slplink(session, who); xfer->data = slplink; purple_xfer_set_init_fnc(xfer, t_msn_xfer_init); } return xfer;}static voidmsn_send_file(PurpleConnection *gc, const char *who, const char *file){ PurpleXfer *xfer = msn_new_xfer(gc, who); if (file) purple_xfer_request_accepted(xfer, file); else purple_xfer_request(xfer);}static gbooleanmsn_can_receive_file(PurpleConnection *gc, const char *who){ PurpleAccount *account; char *normal; gboolean ret; account = purple_connection_get_account(gc); normal = g_strdup(msn_normalize(account, purple_account_get_username(account))); ret = strcmp(normal, msn_normalize(account, who)); g_free(normal); return ret;}/************************************************************************** * Protocol Plugin ops **************************************************************************/static const char *msn_list_icon(PurpleAccount *a, PurpleBuddy *b){ return "msn";}static char *msn_status_text(PurpleBuddy *buddy){ PurplePresence *presence; PurpleStatus *status; presence = purple_buddy_get_presence(buddy); status = purple_presence_get_active_status(presence); if (!purple_presence_is_available(presence) && !purple_presence_is_idle(presence)) { return g_strdup(purple_status_get_name(status)); } return NULL;}static voidmsn_tooltip_text(PurpleBuddy *buddy, PurpleNotifyUserInfo *user_info, gboolean full){ MsnUser *user; PurplePresence *presence = purple_buddy_get_presence(buddy); PurpleStatus *status = purple_presence_get_active_status(presence); user = buddy->proto_data; if (purple_presence_is_online(presence)) { purple_notify_user_info_add_pair(user_info, _("Status"), (purple_presence_is_idle(presence) ? _("Idle") : purple_status_get_name(status))); } if (full && user) { purple_notify_user_info_add_pair(user_info, _("Has you"), ((user->list_op & (1 << MSN_LIST_RL)) ? _("Yes") : _("No"))); } /* XXX: This is being shown in non-full tooltips because the * XXX: blocked icon overlay isn't always accurate for MSN. * XXX: This can die as soon as purple_privacy_check() knows that * XXX: this prpl always honors both the allow and deny lists. */ if (user) { purple_notify_user_info_add_pair(user_info, _("Blocked"), ((user->list_op & (1 << MSN_LIST_BL)) ? _("Yes") : _("No"))); }}static GList *msn_status_types(PurpleAccount *account){ PurpleStatusType *status; GList *types = NULL; status = purple_status_type_new_full(PURPLE_STATUS_AVAILABLE, NULL, NULL, FALSE, TRUE, FALSE); types = g_list_append(types, status); status = purple_status_type_new_full(PURPLE_STATUS_AWAY, NULL, NULL, FALSE, TRUE, FALSE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -