diff libpurple/protocols/msn/msn.c @ 20516:5bc492d82ff4

explicit merge of '46d8a45835e685c9dd812f5c6c0df074388bec8a' and 'fa439470adac87fe2027a307e96c857766b06d12'
author Richard Laager <rlaager@wiktel.com>
date Sun, 16 Sep 2007 18:05:55 +0000
parents e5b827037534 7aaebdb013c9
children 8a4748cbf844
line wrap: on
line diff
--- a/libpurple/protocols/msn/msn.c	Mon Sep 10 23:13:42 2007 +0000
+++ b/libpurple/protocols/msn/msn.c	Sun Sep 16 18:05:55 2007 +0000
@@ -37,7 +37,7 @@
 #include "cmds.h"
 #include "core.h"
 #include "prpl.h"
-#include "msn-utils.h"
+#include "msnutils.h"
 #include "version.h"
 
 #include "switchboard.h"
@@ -151,7 +151,7 @@
 	return PURPLE_CMD_RET_OK;
 }
 
-static void
+void
 msn_act_id(PurpleConnection *gc, const char *entry)
 {
 	MsnCmdProc *cmdproc;
@@ -175,9 +175,12 @@
 		return;
 	}
 
-	msn_cmdproc_send(cmdproc, "REA", "%s %s",
-					 purple_account_get_username(account),
-					 alias);
+	if (*alias == '\0') {
+		alias = purple_url_encode(purple_account_get_username(account));
+	}
+
+	msn_cmdproc_send(cmdproc, "PRP", "MFN %s", alias);
+
 }
 
 static void
@@ -414,6 +417,28 @@
 	return user && user->mobile;
 }
 
+void
+msn_send_privacy(PurpleConnection *gc)
+{
+       PurpleAccount *account;
+        MsnSession *session;
+        MsnCmdProc *cmdproc;
+
+        account = purple_connection_get_account(gc);
+        session = gc->proto_data;
+        cmdproc = session->notification->cmdproc;
+
+        if (account->perm_deny == PURPLE_PRIVACY_ALLOW_ALL ||
+                account->perm_deny == PURPLE_PRIVACY_DENY_USERS)
+        {
+                msn_cmdproc_send(cmdproc, "BLP", "%s", "AL");
+        }
+        else
+        {
+                msn_cmdproc_send(cmdproc, "BLP", "%s", "BL");
+        }
+}
+
 static void
 initiate_chat_cb(PurpleBlistNode *node, gpointer data)
 {
@@ -460,6 +485,7 @@
 	session = gc->proto_data;
 
 	xfer = purple_xfer_new(gc->account, PURPLE_XFER_SEND, who);
+
 	if (xfer)
 	{
 		slplink = msn_session_get_slplink(session, who);
@@ -511,20 +537,27 @@
 	return "msn";
 }
 
+/*
+ * Set the User status text
+ * Add the PSM String Using "Name - PSM String" format
+ */
 static char *
 msn_status_text(PurpleBuddy *buddy)
 {
 	PurplePresence *presence;
 	PurpleStatus *status;
+	const char *msg, *cmedia;
 
 	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));
-	}
+	msg = purple_status_get_attr_string(status, "message");
+	cmedia = purple_status_get_attr_string(status, "currentmedia");
 
+	if (cmedia)
+		return g_markup_escape_text(cmedia, -1);
+	else if (msg)
+		return g_markup_escape_text(msg, -1);
 	return NULL;
 }
 
@@ -540,8 +573,41 @@
 	
 	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)));
+		const char *psm, *currentmedia, *name;
+		char *tmp;
+
+		psm = purple_status_get_attr_string(status, "message");
+		currentmedia = purple_status_get_attr_string(status, "currentmedia");
+
+		if (!purple_presence_is_available(presence)) {
+			name = purple_status_get_name(status);
+		} else {
+			name = NULL;
+		}
+
+		if (name != NULL && *name) {
+			char *tmp2 = g_markup_escape_text(name, -1);
+
+			if (psm != NULL && *psm) {
+				tmp = g_markup_escape_text(psm, -1);
+				purple_notify_user_info_add_pair(user_info, tmp2, tmp);
+				g_free(tmp);
+			} else {
+				purple_notify_user_info_add_pair(user_info, _("Status"), tmp2);
+			}
+
+			g_free(tmp2);
+		} else {
+			tmp = g_markup_escape_text(psm, -1);
+			purple_notify_user_info_add_pair(user_info, _("Status"), tmp);
+			g_free(tmp);
+		}
+
+		if (currentmedia) {
+			tmp = g_markup_escape_text(currentmedia, -1);
+			purple_notify_user_info_add_pair(user_info, _("Current media"), tmp);
+			g_free(tmp);
+		}
 	}
 	
 	if (full && user)
@@ -566,29 +632,48 @@
 {
 	PurpleStatusType *status;
 	GList *types = NULL;
-
+#if 0
 	status = purple_status_type_new_full(PURPLE_STATUS_AVAILABLE,
 			NULL, NULL, FALSE, TRUE, FALSE);
+#endif
+	status = purple_status_type_new_with_attrs(
+				PURPLE_STATUS_AVAILABLE, NULL, NULL, TRUE, TRUE, FALSE,
+				"message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+				"currentmedia", _("Current media"), purple_value_new(PURPLE_TYPE_STRING),
+				NULL);
 	types = g_list_append(types, status);
 
-	status = purple_status_type_new_full(PURPLE_STATUS_AWAY,
-			NULL, NULL, FALSE, TRUE, FALSE);
+	status = purple_status_type_new_with_attrs(
+			PURPLE_STATUS_AWAY, NULL, NULL, TRUE, TRUE, FALSE,
+			"message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+			"currentmedia", _("Current media"), purple_value_new(PURPLE_TYPE_STRING),
+			NULL);
 	types = g_list_append(types, status);
 
-	status = purple_status_type_new_full(PURPLE_STATUS_AWAY,
-			"brb", _("Be Right Back"), FALSE, TRUE, FALSE);
+	status = purple_status_type_new_with_attrs(
+			PURPLE_STATUS_AWAY, "brb", _("Be Right Back"), TRUE, TRUE, FALSE,
+			"message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+			"currentmedia", _("Current media"), purple_value_new(PURPLE_TYPE_STRING),
+			NULL);
 	types = g_list_append(types, status);
 
-	status = purple_status_type_new_full(PURPLE_STATUS_UNAVAILABLE,
-			"busy", _("Busy"), FALSE, TRUE, FALSE);
+	status = purple_status_type_new_with_attrs(
+			PURPLE_STATUS_UNAVAILABLE, "busy", _("Busy"), TRUE, TRUE, FALSE,
+			"message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+			"currentmedia", _("Current media"), purple_value_new(PURPLE_TYPE_STRING),
+			NULL);
 	types = g_list_append(types, status);
-
-	status = purple_status_type_new_full(PURPLE_STATUS_UNAVAILABLE,
-			"phone", _("On the Phone"), FALSE, TRUE, FALSE);
+	status = purple_status_type_new_with_attrs(
+			PURPLE_STATUS_UNAVAILABLE, "phone", _("On the Phone"), TRUE, TRUE, FALSE,
+			"message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+			"currentmedia", _("Current media"), purple_value_new(PURPLE_TYPE_STRING),
+			NULL);
 	types = g_list_append(types, status);
-
-	status = purple_status_type_new_full(PURPLE_STATUS_AWAY,
-			"lunch", _("Out to Lunch"), FALSE, TRUE, FALSE);
+	status = purple_status_type_new_with_attrs(
+			PURPLE_STATUS_AWAY, "lunch", _("Out to Lunch"), TRUE, TRUE, FALSE,
+			"message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+			"currentmedia", _("Current media"), purple_value_new(PURPLE_TYPE_STRING),
+			NULL);
 	types = g_list_append(types, status);
 
 	status = purple_status_type_new_full(PURPLE_STATUS_INVISIBLE,
@@ -598,11 +683,11 @@
 	status = purple_status_type_new_full(PURPLE_STATUS_OFFLINE,
 			NULL, NULL, FALSE, TRUE, FALSE);
 	types = g_list_append(types, status);
-	
+
 	status = purple_status_type_new_full(PURPLE_STATUS_MOBILE,
 			"mobile", NULL, FALSE, FALSE, TRUE);
 	types = g_list_append(types, status);
-	
+
 	return types;
 }
 
@@ -785,6 +870,7 @@
 	char *msgformat;
 	char *msgtext;
 
+	purple_debug_info("MSNP14","send IM {%s} to %s\n",message,who);
 	account = purple_connection_get_account(gc);
 
 	if (buddy) {
@@ -798,62 +884,91 @@
 	}
 
 	msn_import_html(message, &msgformat, &msgtext);
+	if(msn_user_is_online(account, who)||
+		msn_user_is_yahoo(account, who)){
+		/*User online,then send Online Instant Message*/
 
-	if (strlen(msgtext) + strlen(msgformat) + strlen(VERSION) > 1564)
-	{
+		if (strlen(msgtext) + strlen(msgformat) + strlen(VERSION) > 1564)
+		{
+			g_free(msgformat);
+			g_free(msgtext);
+
+			return -E2BIG;
+		}
+
+		msg = msn_message_new_plain(msgtext);
+		msg->remote_user = g_strdup(who);
+		msn_message_set_attr(msg, "X-MMS-IM-Format", msgformat);
+
 		g_free(msgformat);
 		g_free(msgtext);
 
-		return -E2BIG;
-	}
+		purple_debug_info("MSNP14","prepare to send online Message\n");
+		if (g_ascii_strcasecmp(who, purple_account_get_username(account)))
+		{
+			MsnSession *session;
+			MsnSwitchBoard *swboard;
 
-	msg = msn_message_new_plain(msgtext);
-	msn_message_set_attr(msg, "X-MMS-IM-Format", msgformat);
-
-	g_free(msgformat);
-	g_free(msgtext);
+			session = gc->proto_data;
+			if(msn_user_is_yahoo(account,who)){
+				/*we send the online and offline Message to Yahoo User via UBM*/
+				purple_debug_info("MSNP14","send to Yahoo User\n");
+				uum_send_msg(session,msg);
+			}else{
+				purple_debug_info("MSNP14","send via switchboard\n");
+				swboard = msn_session_get_swboard(session, who, MSN_SB_FLAG_IM);
+				msn_switchboard_send_msg(swboard, msg, TRUE);
+			}
+		}
+		else
+		{
+			char *body_str, *body_enc, *pre, *post;
+			const char *format;
+			MsnIMData *imdata = g_new0(MsnIMData, 1);
+			/*
+			 * In MSN, you can't send messages to yourself, so
+			 * we'll fake like we received it ;)
+			 */
+			body_str = msn_message_to_string(msg);
+			body_enc = g_markup_escape_text(body_str, -1);
+			g_free(body_str);
 
-	if (g_ascii_strcasecmp(who, purple_account_get_username(account)))
-	{
-		MsnSession *session;
-		MsnSwitchBoard *swboard;
+			format = msn_message_get_attr(msg, "X-MMS-IM-Format");
+			msn_parse_format(format, &pre, &post);
+			body_str = g_strdup_printf("%s%s%s", pre ? pre :  "",
+									   body_enc ? body_enc : "", post ? post : "");
+			g_free(body_enc);
+			g_free(pre);
+			g_free(post);
+
+			serv_got_typing_stopped(gc, who);
+			imdata->gc = gc;
+			imdata->who = who;
+			imdata->msg = body_str;
+			imdata->flags = flags;
+			imdata->when = time(NULL);
+			g_idle_add(msn_send_me_im, imdata);
+		}
 
+		msn_message_destroy(msg);
+	}else	{
+		/*send Offline Instant Message,only to MSN Passport User*/
+		MsnSession *session;
+		MsnOim *oim;
+		char *friendname;
+
+		purple_debug_info("MSNP14","prepare to send offline Message\n");
 		session = gc->proto_data;
-		swboard = msn_session_get_swboard(session, who, MSN_SB_FLAG_IM);
+		/* XXX/khc: hack */
+		if (!session->oim)
+			session->oim = msn_oim_new(session);
 
-		msn_switchboard_send_msg(swboard, msg, TRUE);
+		oim = session->oim;
+		friendname = msn_encode_mime(account->username);
+		msn_oim_prep_send_msg_info(oim, purple_account_get_username(account),
+								   friendname, who,	message);
+		msn_oim_send_msg(oim);
 	}
-	else
-	{
-		char *body_str, *body_enc, *pre, *post;
-		const char *format;
-		MsnIMData *imdata = g_new0(MsnIMData, 1);
-		/*
-		 * In MSN, you can't send messages to yourself, so
-		 * we'll fake like we received it ;)
-		 */
-		body_str = msn_message_to_string(msg);
-		body_enc = g_markup_escape_text(body_str, -1);
-		g_free(body_str);
-
-		format = msn_message_get_attr(msg, "X-MMS-IM-Format");
-		msn_parse_format(format, &pre, &post);
-		body_str = g_strdup_printf("%s%s%s", pre ? pre :  "",
-								   body_enc ? body_enc : "", post ? post : "");
-		g_free(body_enc);
-		g_free(pre);
-		g_free(post);
-
-		serv_got_typing_stopped(gc, who);
-		imdata->gc = gc;
-		imdata->who = who;
-		imdata->msg = body_str;
-		imdata->flags = flags;
-		imdata->when = time(NULL);
-		g_idle_add(msn_send_me_im, imdata);
-	}
-
-	msn_message_destroy(msg);
 
 	return 1;
 }
@@ -992,6 +1107,7 @@
 	userlist = session->userlist;
 	who = msn_normalize(gc->account, buddy->name);
 
+	purple_debug_info("MSN","Add user:%s to group:%s\n", who, group->name);
 	if (!session->logged_in)
 	{
 #if 0
@@ -1025,8 +1141,7 @@
 	/* XXX - Would group ever be NULL here?  I don't think so...
 	 * shx: Yes it should; MSN handles non-grouped buddies, and this is only
 	 * internal. */
-	msn_userlist_add_buddy(userlist, who, MSN_LIST_FL,
-						   group ? group->name : NULL);
+	msn_userlist_add_buddy(userlist, who, group ? group->name : NULL);
 }
 
 static void
@@ -1042,7 +1157,7 @@
 		return;
 
 	/* XXX - Does buddy->name need to be msn_normalize'd here?  --KingAnt */
-	msn_userlist_rem_buddy(userlist, buddy->name, MSN_LIST_FL, group->name);
+	msn_userlist_rem_buddy(userlist, buddy->name);
 }
 
 static void
@@ -1059,10 +1174,18 @@
 	if (!session->logged_in)
 		return;
 
-	if (user != NULL && user->list_op & MSN_LIST_BL_OP)
-		msn_userlist_rem_buddy(userlist, who, MSN_LIST_BL, NULL);
+	if (user != NULL && user->list_op & MSN_LIST_BL_OP) {
+		msn_userlist_rem_buddy_from_list(userlist, who, MSN_LIST_BL);
 
-	msn_userlist_add_buddy(userlist, who, MSN_LIST_AL, NULL);
+		/* delete contact from Block list and add it to Allow in the callback */
+		msn_del_contact_from_list(session->contact, NULL, who, MSN_LIST_BL);
+	} else {
+		/* just add the contact to Allow list */
+		msn_add_contact_to_list(session->contact, NULL, who, MSN_LIST_AL);
+	}
+
+
+	msn_userlist_add_buddy_to_list(userlist, who, MSN_LIST_AL);
 }
 
 static void
@@ -1079,10 +1202,17 @@
 	if (!session->logged_in)
 		return;
 
-	if (user != NULL && user->list_op & MSN_LIST_AL_OP)
-		msn_userlist_rem_buddy(userlist, who, MSN_LIST_AL, NULL);
+	if (user != NULL && user->list_op & MSN_LIST_AL_OP) {
+		msn_userlist_rem_buddy_from_list(userlist, who, MSN_LIST_AL);
 
-	msn_userlist_add_buddy(userlist, who, MSN_LIST_BL, NULL);
+		/* delete contact from Allow list and add it to Block in the callback */
+		msn_del_contact_from_list(session->contact, NULL, who, MSN_LIST_AL);
+	} else {
+		/* just add the contact to Block list */
+		msn_add_contact_to_list(session->contact, NULL, who, MSN_LIST_BL);
+	}
+
+	msn_userlist_add_buddy_to_list(userlist, who, MSN_LIST_BL);
 }
 
 static void
@@ -1100,10 +1230,12 @@
 
 	user = msn_userlist_find_user(userlist, who);
 
-	msn_userlist_rem_buddy(userlist, who, MSN_LIST_AL, NULL);
+	msn_userlist_rem_buddy_from_list(userlist, who, MSN_LIST_AL);
+
+	msn_del_contact_from_list(session->contact, NULL, who, MSN_LIST_AL);
 
 	if (user != NULL && user->list_op & MSN_LIST_RL_OP)
-		msn_userlist_add_buddy(userlist, who, MSN_LIST_BL, NULL);
+		msn_userlist_add_buddy_to_list(userlist, who, MSN_LIST_BL);
 }
 
 static void
@@ -1121,32 +1253,18 @@
 
 	user = msn_userlist_find_user(userlist, who);
 
-	msn_userlist_rem_buddy(userlist, who, MSN_LIST_BL, NULL);
+	msn_userlist_rem_buddy_from_list(userlist, who, MSN_LIST_BL);
+
+	msn_del_contact_from_list(session->contact, NULL, who, MSN_LIST_BL);
 
 	if (user != NULL && user->list_op & MSN_LIST_RL_OP)
-		msn_userlist_add_buddy(userlist, who, MSN_LIST_AL, NULL);
+		msn_userlist_add_buddy_to_list(userlist, who, MSN_LIST_AL);
 }
 
 static void
 msn_set_permit_deny(PurpleConnection *gc)
 {
-	PurpleAccount *account;
-	MsnSession *session;
-	MsnCmdProc *cmdproc;
-
-	account = purple_connection_get_account(gc);
-	session = gc->proto_data;
-	cmdproc = session->notification->cmdproc;
-
-	if (account->perm_deny == PURPLE_PRIVACY_ALLOW_ALL ||
-		account->perm_deny == PURPLE_PRIVACY_DENY_USERS)
-	{
-		msn_cmdproc_send(cmdproc, "BLP", "%s", "AL");
-	}
-	else
-	{
-		msn_cmdproc_send(cmdproc, "BLP", "%s", "BL");
-	}
+	msn_send_privacy(gc);
 }
 
 static void
@@ -1283,24 +1401,20 @@
 				 PurpleGroup *group, GList *moved_buddies)
 {
 	MsnSession *session;
-	MsnCmdProc *cmdproc;
-	int old_gid;
-	const char *enc_new_group_name;
 
 	session = gc->proto_data;
-	cmdproc = session->notification->cmdproc;
-	enc_new_group_name = purple_url_encode(group->name);
-
-	old_gid = msn_userlist_find_group_id(session->userlist, old_name);
-
-	if (old_gid >= 0)
+	
+	g_return_if_fail(session != NULL);
+	g_return_if_fail(session->userlist != NULL);
+	
+	if (msn_userlist_find_group_with_name(session->userlist, old_name) != NULL)
 	{
-		msn_cmdproc_send(cmdproc, "REG", "%d %s 0", old_gid,
-						 enc_new_group_name);
+		msn_contact_rename_group(session, old_name, group->name);
 	}
 	else
 	{
-		msn_cmdproc_send(cmdproc, "ADG", "%s 0", enc_new_group_name);
+		/* not found */
+		msn_add_group(session, NULL, group->name);
 	}
 }
 
@@ -1360,15 +1474,20 @@
 {
 	MsnSession *session;
 	MsnCmdProc *cmdproc;
-	int group_id;
 
 	session = gc->proto_data;
 	cmdproc = session->notification->cmdproc;
 
-	if ((group_id = msn_userlist_find_group_id(session->userlist, group->name)) >= 0)
+	purple_debug_info("MSN", "Remove group %s\n", group->name);
+	/*we can't delete the default group*/
+	if(!strcmp(group->name, MSN_INDIVIDUALS_GROUP_NAME)||
+		!strcmp(group->name, MSN_NON_IM_GROUP_NAME))
 	{
-		msn_cmdproc_send(cmdproc, "RMG", "%d", group_id);
+		purple_debug_info("MSN", "This group can't be removed, returning.\n");
+		return ;
 	}
+	
+	msn_del_group(session, group->name);
 }
 
 /**
@@ -1418,12 +1537,11 @@
 {
 	char *p, *q;
 
-	if ((p = strstr(url_text, " contactparams:photopreauthurl=\"")) != NULL)
+	if ((p = strstr(url_text, PHOTO_URL)) != NULL)
 	{
-		p += strlen(" contactparams:photopreauthurl=\"");
+		p += strlen(PHOTO_URL);
 	}
-
-	if (p && (strncmp(p, "http://", 8) == 0) && ((q = strchr(p, '"')) != NULL))
+	if (p && (strncmp(p, "http://",strlen("http://")) == 0) && ((q = strchr(p, '"')) != NULL))
 			return g_strndup(p, q - p);
 
 	return NULL;
@@ -1488,7 +1606,7 @@
 	MsnGetInfoStepTwoData *info2_data = NULL;
 #endif
 
-	purple_debug_info("msn", "In msn_got_info\n");
+	purple_debug_info("msn", "In msn_got_info,url_text:{%s}\n",url_text);
 
 	/* Make sure the connection is still valid */
 	if (g_list_find(purple_connections_get_all(), info_data->gc) == NULL)
@@ -1872,6 +1990,7 @@
 #if PHOTO_SUPPORT
 	/* Find the URL to the photo; must be before the marshalling [Bug 994207] */
 	photo_url_text = msn_get_photo_url(url_text);
+	purple_debug_info("MSNP14","photo url:{%s}\n",photo_url_text);
 
 	/* Marshall the existing state */
 	info2_data = g_malloc0(sizeof(MsnGetInfoStepTwoData));
@@ -2096,7 +2215,7 @@
 	msn_add_deny,			/* add_deny */
 	msn_rem_permit,			/* rem_permit */
 	msn_rem_deny,			/* rem_deny */
-	msn_set_permit_deny,		/* set_permit_deny */
+	msn_set_permit_deny,	/* set_permit_deny */
 	NULL,					/* join_chat */
 	NULL,					/* reject chat invite */
 	NULL,					/* get_chat_name */
@@ -2152,10 +2271,11 @@
 	"MSN",                                            /**< name           */
 	VERSION,                                          /**< version        */
 	                                                  /**  summary        */
-	N_("MSN Protocol Plugin"),
+	N_("Windows Live Messenger Protocol Plugin"),
 	                                                  /**  description    */
-	N_("MSN Protocol Plugin"),
-	"Christian Hammond <chipx86@gnupdate.org>",       /**< author         */
+	N_("Windows Live Messenger Protocol Plugin"),
+	"Christian Hammond <chipx86@gnupdate.org>, "
+	"MaYuan <mayuan2006@gmail.com>",				  /**< author         */
 	PURPLE_WEBSITE,                                     /**< homepage       */
 
 	msn_load,                                         /**< load           */
@@ -2180,11 +2300,11 @@
 	PurpleAccountOption *option;
 
 	option = purple_account_option_string_new(_("Server"), "server",
-											MSN_SERVER);
+											WLM_SERVER);
 	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
 											   option);
 
-	option = purple_account_option_int_new(_("Port"), "port", 1863);
+	option = purple_account_option_int_new(_("Port"), "port", WLM_PORT);
 	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
 											   option);