浏览 10757 次
锁定老帖子 主题:MSNP 实现
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-08-31  
MSNP 是Windows/Live Messenger基于的协议, 实现消息通信。 建立于HTTP协议之上。

一下方法分别提供对其操作:
/// File: MsnSharp\Msn\MsnComm.cs
/// 
/// ------------------------------------------------------------
/// Copyright (c) 2004
///   Antonio Cisternino (cisterni.unipi.it),
///   Diego Colombo      (colombod.unipi.it),
///   Giorgio Ennas      (   ennas.unipi.it),
///   Daniele Picciaia   (picciaia.unipi.it)
/// 
/// The use and distribution terms for this software are 
/// contained in the file named license.txt, which can be found 
/// in the root of this distribution.
/// By using this software in any fashion, you are agreeing to 
/// be bound by the terms of this license.
///
/// You must not remove this notice, or any other, from this
/// software.
/// ------------------------------------------------------------

using System;
using System.Net;
using System.Net.Sockets;

using System.Threading;

namespace Msn
{
	//delegate declaration
	public delegate void ReceiveCallback(string info);


	/// <summary>
	/// This class manage communications via socket
	/// </summary>
	internal class MsnComm
	{
		private const int BUFFER_SIZE = 512;

		private TcpClient msnClient;
		private NetworkStream netStream;
		private TcpClient tempClient = null;
		private ReceiveCallback receiveCallback;
		byte[] buffer = new byte[BUFFER_SIZE];
		

		public MsnComm()
		{
		}

		public void Connect(string address,int port)
		{
			msnClient = new TcpClient( address,port );
			netStream = msnClient.GetStream();
		}

		public void Close()
		{
			netStream.Close();
			msnClient.Close();
		}

		/// <summary>
		/// send a Commands and wait for a response (synchronous send)
		/// </summary>
		/// <param name="cmd"></param>
		public void SendReceive(ref Commands cmd)
		{
			Send(cmd);
			cmd = Receive(true);
		}


		/// <summary>
		/// Send a Commands
		/// </summary>
		/// <param name="cmd"></param>
		public void Send(Commands cmd)
		{
			Byte[] packet = null;
			string txtCmd = cmd.ToString();
			packet = StringToByte( txtCmd );
			netStream.Write( packet,0,packet.Length );		
		}


		/// <summary>
		/// Synchronous receive a msn Commands
		/// </summary>
		private Commands Receive(bool getTransactionID)
		{
			Commands cmd = new Commands();
			Byte[] packet = new Byte[BUFFER_SIZE];												
			int dataLen = netStream.Read(packet,0,packet.Length);
			string cmdText = ByteToString(packet,dataLen);

			if (cmdText == null || cmdText.Length == 0)
				return null;
			
			return cmd.FormatCommands(cmdText);
		}

		/// <summary>
		/// Start asynchronous read from serve
		/// </summary>
		/// <param name="callback"></param>
		public void StartAsyncReceive(ReceiveCallback callback)
		{
			receiveCallback = callback;
            if ( msnClient == null ) {
                msnClient = new TcpClient( );
            }
			netStream.BeginRead(buffer,0,buffer.Length,new AsyncCallback(AsyncReceive),netStream);
		}

		private void AsyncReceive(IAsyncResult res)
		{
			NetworkStream myNetworkStream = (NetworkStream)res.AsyncState;
			string myCompleteCommands = "";
			int numberOfBytesRead;

			numberOfBytesRead = myNetworkStream.EndRead(res);
			myCompleteCommands = System.Text.Encoding.ASCII.GetString(buffer, 0, numberOfBytesRead);
			receiveCallback(myCompleteCommands);
    
        
			myNetworkStream.BeginRead(buffer, 0, buffer.Length, 
					new AsyncCallback(AsyncReceive), 
					myNetworkStream);  

		
		}


		/// <summary>
		/// Get a passport ticket via https to passport server (to authenticate user)
		/// </summary>
		/// <param name="passportServer">address of passport server</param>
		/// <param name="ticket">ticket received by server</param>
		/// <returns>passport ticket string to send</returns>
		public string GetPassportTicket(string passportServer,string token,string email,string pwd)
		{
			HttpWebResponse res = null;
			HttpWebRequest req = null;
			string[] PassportURLs = null;
			string ticket = null;


			//open http connection via ssl - connect to 'Nexus' server
			req = (HttpWebRequest) WebRequest.Create(passportServer);
			res = (HttpWebResponse)req.GetResponse();
			if (res.StatusCode.CompareTo(HttpStatusCode.OK)!=0)
				return null;


			//get address of login server
			PassportURLs = res.Headers["PassportURLs"].Split(',');

			foreach(string PassportURL in PassportURLs)
			{
				if (PassportURL.Substring(0,8).CompareTo("DALogin=")!=0)
					continue;
				string passportURL = "https://" + PassportURL.Remove(0,8);

				//connect to login server
				do
				{
					req = (HttpWebRequest) WebRequest.Create(passportURL);
					req.AllowAutoRedirect = false;
					req.Pipelined = false;
					req.KeepAlive = false;
					req.ProtocolVersion = new Version(1,1);
					req.Headers.Add("Authorization", 
						"Passport1.4 OrgVerb=GET,OrgURL=http%3A%2F%2Fmessenger%2Emsn%2Ecom,sign-in=" 
						+ email.Replace("@", "%40") + ",pwd=" + pwd + "," 
						+ token);
					res = (HttpWebResponse)req.GetResponse();
					if (res.StatusCode.CompareTo(HttpStatusCode.Redirect)==0)
						passportURL = res.Headers["Location"];
				}while(res.StatusCode.CompareTo(HttpStatusCode.Redirect)==0);

				

				if (res.StatusCode.CompareTo(HttpStatusCode.Unauthorized)==0)
					//Unauthorized
					return null;


				if (res.StatusCode.CompareTo(HttpStatusCode.OK)==0)
				{
					string[] AuthInfos = res.Headers["Authentication-Info"].Split(',');
					if (AuthInfos == null)
						return null;
					foreach(string AuthInfo in AuthInfos)
					{
						if (AuthInfo.Substring(0,8).CompareTo("from-PP=")!=0)
							continue;
						ticket = AuthInfo.Remove(0,9);
						ticket = ticket.Remove(ticket.Length - 1,1);
						return ticket;
					}
				}


			}

			return ticket;
		}

		//string <--> byte array conversions
		private Byte[] StringToByte(string str)
		{
			return System.Text.Encoding.ASCII.GetBytes(str);

		}

		private string ByteToString(byte[] data,int len)
		{
			return System.Text.Encoding.ASCII.GetString(data,0,len);
		}
	}
}
   发表时间:2007-08-31  
/// File: MsnSharp\Msn\UserProfile.cs
/// 
/// ------------------------------------------------------------
/// Copyright (c) 2004
///   Antonio Cisternino (cisterni.unipi.it),
///   Diego Colombo      (colombod.unipi.it),
///   Giorgio Ennas      (   ennas.unipi.it),
///   Daniele Picciaia   (picciaia.unipi.it)
/// 
/// The use and distribution terms for this software are 
/// contained in the file named license.txt, which can be found 
/// in the root of this distribution.
/// By using this software in any fashion, you are agreeing to 
/// be bound by the terms of this license.
///
/// You must not remove this notice, or any other, from this
/// software.
/// ------------------------------------------------------------

using System;

namespace Msn
{
	/// <summary>
	/// Summary description for UserProfile.
	/// </summary>
	public class UserProfile
	{
		public string account;
		public string password;
		public string nickname;
		
	}
}

0 请登录后投票
   发表时间:2007-08-31  
/// File: MsnSharp\Msn\MsnObject.cs
/// 
/// ------------------------------------------------------------
/// Copyright (c) 2004
///   Antonio Cisternino (cisterni.unipi.it),
///   Diego Colombo      (colombod.unipi.it),
///   Giorgio Ennas      (   ennas.unipi.it),
///   Daniele Picciaia   (picciaia.unipi.it)
/// 
/// The use and distribution terms for this software are 
/// contained in the file named license.txt, which can be found 
/// in the root of this distribution.
/// By using this software in any fashion, you are agreeing to 
/// be bound by the terms of this license.
///
/// You must not remove this notice, or any other, from this
/// software.
/// ------------------------------------------------------------

using System;

namespace Msn
{
	/// <summary>
	/// Summary description for MsnObject.
	/// </summary>
	abstract public class MsnObject
	{
		public UserProfile userProfile;
	}
}

/// File: MsnSharp\Msn\Session.cs
/// 
/// ------------------------------------------------------------
/// Copyright (c) 2004
///   Antonio Cisternino (cisterni.unipi.it),
///   Diego Colombo      (colombod.unipi.it),
///   Giorgio Ennas      (   ennas.unipi.it),
///   Daniele Picciaia   (picciaia.unipi.it)
/// 
/// The use and distribution terms for this software are 
/// contained in the file named license.txt, which can be found 
/// in the root of this distribution.
/// By using this software in any fashion, you are agreeing to 
/// be bound by the terms of this license.
///
/// You must not remove this notice, or any other, from this
/// software.
/// ------------------------------------------------------------

using System;

namespace Msn
{
	public enum SessionEvent
	{
		CommandsArrive = 0
	}
	//delegate declaration
	public delegate void SessionCallback(SessionEvent sessionEvent,string Commands);

	/// <summary>
	/// This classs managet Switchboard session and permit to create/destroy Conversations
	/// </summary>
	public class Session
	{
		private MsnComm communicator = null;
		private bool sessionStarted = false;
		private	Commands cmd = new Commands();
		private SessionCallback callbackMethod = null;
		/// <summary>
		/// Create SwitchboardManager object and initialize interanl objects
		/// </summary>
		public Session()
		{
			communicator = new MsnComm();
		}


		/// <summary>
		/// Set the callback to call whe new Commands arrive
		/// </summary>
		public SessionCallback CallbackMethod
		{
			set
			{
				callbackMethod = value;
			}
		}

		/// <summary>
		/// Start new Switchboard session
		/// </summary>
		/// <param name="address"></param>
		/// <param name="port"></param>
		/// <param name="userAccount"></param>
		/// <param name="authenticationToken"></param>
		/// <returns></returns>
		internal void StartSession(string address,int port,string userAccount,string authenticationToken)
		{

			communicator.Connect(address,port);													//Connect to switchboard server
			communicator.StartAsyncReceive(new ReceiveCallback(SbServerNotifycation));
			cmd.CreateCommands( MsnCommands.Usr,userAccount + " " + authenticationToken + "\r\n");
			communicator.Send(cmd);

			sessionStarted = true;
		}

		/// <summary>
		/// Invite an usert to session
		/// </summary>
		/// <param name="userAccount"></param>
		/// <returns></returns>
		public void InviteUser(string userAccount)
		{
			cmd.CreateCommands( MsnCommands.Cal,userAccount + "\r\n");
			communicator.Send(cmd);
		}

		/// <summary>
		/// Send text Commands
		/// </summary>
		/// <param name="Commands"></param>
		public void SendMessage(string message)
		{
			string msgText;
			//TODO: let user to select font and color
			msgText = "MIME-Version: 1.0\r\nContent-Type: text/plain; charset=UTF-8\r\nX-MMS-IM-Format: FN=Microsoft%20Sans%20Serif; EF=; CO=0; CS=0; PF=22";
			msgText += "\r\n\r\n";
			msgText += message;
			cmd.CreateCommands( MsnCommands.Msg,"N " + msgText.Length + "\r\n" + msgText);
			communicator.Send(cmd);
		}


		public void SendFile(string userAccount)
		{
			string msgText = "MIME-Version: 1.0\r\n";
			msgText += "Content-Type: text/x-msmsgsinvite; charset=UTF-8\r\n\r\n";
			msgText += "Application-Name: File Transfer\r\n";
			msgText += "Application-GUID: {5D3E02AB-6190-11d3-BBBB-00C04F795683}\r\n";
			msgText += "Invitation-Command: INVITE\r\n";
			msgText += "Invitation-Cookie: 85366\r\n";
			msgText += "Application-File: Autoexec.bat\r\n";
			msgText += "Application-FileSize: 187\r\n";
			msgText += "Connectivity: N\r\n";


			cmd.CreateCommands( MsnCommands.Msg,"N " + msgText);
			communicator.SendReceive(ref cmd);

		}


		private void SbServerNotifycation(string msgText)
		{
			if (msgText.IndexOf("JOI") >= 0)
			{

//				msgText = "MIME-Version: 1.0\r\nContent-Type: text/plain\r\n\r\nHello world";
//				cmd.CreateCommands( MsnCommands.Msg,"N " + msgText.Length + "\r\n" + msgText);
//				communicator.SendReceive(ref cmd);

			}

			if (msgText.StartsWith("MSG"))
			{
				if (msgText.IndexOf("\r\nContent-Type: text/plain;")>=0)
				{
					msgText = msgText.Substring(msgText.IndexOf("\r\n\r\n")+4);
					if (callbackMethod != null)
						callbackMethod(SessionEvent.CommandsArrive,msgText);
					}
			}

		}

	}
}

0 请登录后投票
   发表时间:2007-08-31  
/// File: MsnSharp\Msn\Commands.cs
/// 
/// ------------------------------------------------------------
/// Copyright (c) 2004
///   Antonio Cisternino (cisterni.unipi.it),
///   Diego Colombo      (colombod.unipi.it),
///   Giorgio Ennas      (   ennas.unipi.it),
///   Daniele Picciaia   (picciaia.unipi.it)
/// 
/// The use and distribution terms for this software are 
/// contained in the file named license.txt, which can be found 
/// in the root of this distribution.
/// By using this software in any fashion, you are agreeing to 
/// be bound by the terms of this license.
///
/// You must not remove this notice, or any other, from this
/// software.
/// ------------------------------------------------------------

using System;

namespace Msn
{
	/// <summary>
	/// Type of msn Commands
	/// </summary>
	public enum MsnCommands
	{
		Raw = -1,
		//Sent by user
		Ver = 0,
		Cvr,
		UsrI,
		UsrS,
		Syn,
		Chg,
		Xfr,
		Usr,
		Cal,
		Msg,
		Qry,
		Png,
		//Sent by server
		Chl,
		Joy,
		Qng
	}


	/// <summary>
	/// This class rapresent Commands that are sent/received by msn application
	/// </summary>
	public class Commands
	{
		//Array of stirngs containg the commands strings
		internal string[] MsgText = {
										"VER %TrID% MSNP9 MSNP8 CVR0",								//replace %TrID% with current transaction ID
										"CVR %TrID% 0x0410 winnt 5.1 i386 MSNMSGR 6.0.0602 MSMSGS ",
										"USR %TrID% TWN I ",
										"USR %TrID% TWN S ",
										"SYN %TrID% ",
										"CHG %TrID% ",
										"XFR %TrID% ",
										"USR %TrID% ",
										"CAL %TrID% ",
										"MSG %TrID% ",
										"QRY %TrID% ",
										"PNG",

										"CHL %TrID% ",
										"JOI %TrID% ",
										"QNG "
									};


		public MsnCommands msgType;
		public int msgTrID = 0;
		public string msgBody = null;

		/// <summary>
		/// Create Commands with specified type and body 
		/// </summary>
		/// <param name="type"></param>
		/// <param name="body"></param>
	 
		public void CreateCommands(MsnCommands type,string body)
		{
			CreateCommands(type,body,true);
		}

		/// <summary>
		/// Create Commands with specified type, body and optionally update transaction id
		/// </summary>
		/// <param name="type"></param>
		/// <param name="body"></param>
		/// <param name="updateId"></param>
		public void CreateCommands(MsnCommands type,string body,bool updateId)
		{
			if (updateId)
				CreateCommands(type,body,msgTrID++);
			else
				CreateCommands(type,body,msgTrID);
		}

		/// <summary>
		/// Create Commands with specified type, body and transaction id
		/// </summary>
		/// <param name="type"></param>
		/// <param name="msgParams"></param>
		/// <param name="TrID"></param>
		public void CreateCommands(MsnCommands type,string body,int TrID)
		{
			msgType = type;
			msgBody = body;
			msgTrID = TrID;
		}

		/// <summary>
		/// Create Commands from a raw string
		/// </summary>
		/// <param name="rawText"></param>
		public void CreateCommands(string rawText)
		{
			msgType = MsnCommands.Raw;
			msgBody = rawText;
		}

		/// <summary>
		/// Return a string representation of Commands
		/// </summary>
		/// <returns></returns>
		public override string ToString()
		{
			string msgText = null;
			if (msgType != MsnCommands.Raw)
			{
				msgText = MsgText[(int)msgType].Replace("%TrID%",msgTrID.ToString())  ;
				if (msgBody != null)
					msgText += msgBody;
			}
			else
			{
				msgText = msgBody;
			}
			return  msgText;
		}

		/// <summary>
		/// Format Commands from input string
		/// </summary>
		/// <param name="inputString">input string</param>
		/// <returns></returns>
		public Commands FormatCommands(string inputString)
		{
			Commands msg = new Commands();
			msg.msgType = msg.CommandsType( inputString.Substring(0,3)  );
			inputString = inputString.Remove(0,4);
			try
			{
				msg.msgTrID= Convert.ToInt32( inputString.Split(' ')[0]  );
				inputString = inputString.Remove(0, (inputString.Split(' ')[0]).Length + 1);
			}
			catch{}
			msg.msgBody = inputString;
			return msg;
		}

		public  MsnCommands CommandsType(string msgText)
		{
			msgText = msgText.ToUpper();
			int len = MsgText.Length;
			if (len<0)
				return 0;
			int i = 0;
			bool bFound = false;
			while( !bFound && i<len )
			{
				bFound = MsgText[i].Substring(0,3).CompareTo(msgText)==0;
				if (bFound)
					return (MsnCommands) i;
				i++;
			}
			
			return 0;

		}
	}
}

0 请登录后投票
   发表时间:2007-08-31  
/// File: MsnSharp\Msn\Manager.cs
/// 
/// ------------------------------------------------------------
/// Copyright (c) 2004
///   Antonio Cisternino (cisterni.unipi.it),
///   Diego Colombo      (colombod.unipi.it),
///   Giorgio Ennas      (   ennas.unipi.it),
///   Daniele Picciaia   (picciaia.unipi.it)
/// 
/// The use and distribution terms for this software are 
/// contained in the file named license.txt, which can be found 
/// in the root of this distribution.
/// By using this software in any fashion, you are agreeing to 
/// be bound by the terms of this license.
///
/// You must not remove this notice, or any other, from this
/// software.
/// ------------------------------------------------------------

using System;
using System.Security.Cryptography;
using System.Threading;

namespace Msn
{
	//delegate declaration
	public delegate void ManagerCallback(string info);

	/// <summary>
	/// Summary description for Manager.
	/// </summary>
	public class Manager : MsnObject
	{

		//User status
		public enum UserStatus
		{
			OnLine = 0
		}
		//Array containing the state strings
		private string[] MsnState = {
										"NLN"
									};

		//private objects
		private UserStatus status;
		private MsnComm communicator = null;
		private Commands cmd;
		private string[] notificServer = new string[2];
		private int[] notificPort = new int[2];
		private ManagerCallback sessionInvite;
		private bool pingMonitor = false;
		private System.Timers.Timer tmrPing = new System.Timers.Timer(10000);
		private AutoResetEvent waitObj = new AutoResetEvent(false);
		private Session newSession = null;

		//default msn config
		private string passportServer = "https://nexus.passport.com/rdr/pprdr.asp";
		private string dispatchServer = "messenger.hotmail.com";
		private int dispatchPort = 1863;
		private const string  ClientString = "PROD0061VRRZH@4F";
		private const string  ClientCode = "JXQ6J@TUOGYV@N0M";


		/// <summary>
		/// Set async callback to call when recive an invite
		/// </summary>
		public ManagerCallback SessionInvite
		{
			set
			{
				sessionInvite = value;
			}
		}

		
		public Manager()
		{
			communicator = new MsnComm();
			userProfile = new UserProfile();
			cmd = new Commands();
			tmrPing.AutoReset = true;
			tmrPing.Elapsed += new System.Timers.ElapsedEventHandler(tmrPing_Elapsed);
		}

		/// <summary>
		/// Login to messenger system
		/// </summary>
		/// <param name="userAccount">user account(mail address)</param>
		/// <param name="password">password</param>
		public void LogIn(string userAccount,string password)
		{
			//set user profile info
			userProfile.account = userAccount;
			userProfile.password = password;
			
			//connect to Dispatch Server
			communicator.Connect(dispatchServer,dispatchPort);

			//send 'VER' command to verify the client
			//NB until the loging sequence is not completed ALL communication are synchronous
			cmd.CreateCommands(MsnCommands.Ver,"\r\n");
			communicator.SendReceive(ref cmd);
			if (cmd.msgBody == null)
			{
				throw new ApplicationException("Protocol not supported from Dispatch Server");
			}

			//send 'CVR' command, server respond with latest version
			cmd.CreateCommands(MsnCommands.Cvr,userAccount + "\r\n");
			communicator.SendReceive(ref cmd);
		
			//send 'USR' command, server respond with 'XFR' (free NS to use)
			cmd.CreateCommands(MsnCommands.UsrI,userAccount + "\r\n");
			communicator.SendReceive(ref cmd);

			//set Notification server address and port
			if (cmd.msgBody == null)
			{
				communicator.Close();
				throw new ApplicationException("Impossible to obtain Notification Server address");
			}
			cmd.msgBody = cmd.msgBody.Replace("\r\n","");
			string[] msgParams = cmd.msgBody.Replace(" ",":").Split(':');
			notificServer[0] = msgParams[1];
			notificPort[0]	 = Convert.ToInt32( msgParams[2] );
			if (msgParams.Length == 6)
			{
				notificServer[1] = msgParams[4];
				notificPort[1]	 = Convert.ToInt32( msgParams[5] );
			}
			communicator.Close();																					//TODO generate 2 different method : connecttoDispatcher,connecttonotification and call 
																													//the also the second ns ip returned by dispatcher (if ther's no respponse with first)
			//connect to Notification server
			communicator.Connect(notificServer[0],notificPort[0]);

			//send 'VER' command
			cmd.CreateCommands(MsnCommands.Ver,"\r\n",0);
			communicator.SendReceive(ref cmd);
			if (cmd.msgBody == null)
			{
				throw new ApplicationException("Protocol not supported from Notification Server");
			}

			//send 'CVR' command, server respond with latest version
			cmd.CreateCommands(MsnCommands.Cvr,userAccount + "\r\n");
			communicator.SendReceive(ref cmd);
		
			//send 'USR' command, server respond with passport ticket
			cmd.CreateCommands(MsnCommands.UsrI,userAccount + "\r\n");
			communicator.SendReceive(ref cmd);


			//Get passport ticket from passport server (using ssl connection) and send it to server
			string ticket = communicator.GetPassportTicket(passportServer,cmd.msgBody.Split(' ')[2],userAccount,password);
			cmd.CreateCommands(MsnCommands.UsrS,ticket + "\r\n");
			communicator.SendReceive(ref cmd);

			//Start the asyoncronoyus receive to listen from server Commands
			communicator.StartAsyncReceive( new ReceiveCallback(ServerNotication) );
			
			//syncronize list
			cmd.CreateCommands(MsnCommands.Syn,"0\r\n");
			communicator.Send(cmd);

			//Set the status on line
			status = UserStatus.OnLine;
																		//TODO: manage status parameter
			cmd.CreateCommands(MsnCommands.Chg, MsnState[(int)status] + " 268435500 %3Cmsnobj%20Creator%3D%22r2d2_medialab%40hotmail.com%22%20Size%3D%2219712%22%20Type%3D%223%22%20Location%3D%22TFR715.tmp%22%20Friendly%3D%22AAA%3D%22%20SHA1D%3D%22VXRmTeZ3ivxmFNtkgipnm4gY7XE%3D%22%20SHA1C%3D%22h%2FwlPba3obYUbK9FsehrnTaDPP8%3D%22%2F%3E\r\n");
			communicator.Send(cmd);											//send the first asynchronous command


			//Start pinging from client
//			cmd.CreateCommands("PNG\r\n");
//			communicator.Send(cmd);											//send the first asynchronous command

		}

		/// <summary>
		/// Logout from messegner
		/// </summary>
		public void LogOut()
		{

		}


		/// <summary>
		/// Set/Get the user status
		/// </summary>
		public UserStatus Status
		{
			get
			{
				return status;
			}
			set
			{
				status = value;
			}
		}

		/// <summary>
		/// Create new session
		/// </summary>
		/// <returns></returns>
		public Session CreateSession()
		{
			cmd.CreateCommands(MsnCommands.Xfr,"SB\r\n");
			communicator.Send(cmd);

			//wait for server response
			waitObj.WaitOne();


			return newSession;
		}

		/// <summary>
		/// Asynchronous method: Receive server Commands and dispatch it
		/// </summary>
		/// <param name="msgText"></param>
		private void ServerNotication(string msgText)
		{
			if (msgText==null || msgText.Length == 0)
				return;

			lock(this)
			{
				Commands srvMsg = new Commands();
				srvMsg = srvMsg.FormatCommands(msgText);
				Commands response = new Commands();
				switch(srvMsg.msgType)
				{
					case(MsnCommands.Chl): //Challenge Commands
					{
						string hashString = srvMsg.msgBody.Replace("\r\n","") + ClientCode;
						MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
						hashString = ByteArrayToString( md5.ComputeHash(System.Text.Encoding.ASCII.GetBytes(hashString)) );
						response.CreateCommands(MsnCommands.Qry,ClientString + " " + Convert.ToString(hashString.Length) + "\r\n" + hashString);
						communicator.Send(response);
						break;
					}
					case(MsnCommands.Xfr):
					{
			
						//parse response to get switchboard server address and authentication token
						string[] msgParams = msgText.Replace(" ",":").Split(':');
						string sbAddress = msgParams[3];
						int sbPort = Convert.ToInt32( msgParams[4] );
						string sbToken = msgParams[6];

						//create Swtichboard Session manager
						newSession = new Session();
						//start the session
						newSession.StartSession(sbAddress,sbPort,userProfile.account,sbToken);

						waitObj.Set();
						break;
					}

					case(MsnCommands.Qng):
						int intervall = 0;
						tmrPing.Interval = intervall;
						tmrPing.Start();

						break;

					case (MsnCommands.Syn):
						int i = 1;
						break;
				
				}

			}
		}




		/// <summary>
		/// Convert a byte array into a string rapresentation
		/// </summary>
		/// <param name="data"></param>
		/// <returns></returns>
		private string ByteArrayToString(byte[] data)
		{
			string ret = null;
			string temp = data.ToString();
			foreach(byte b in data)
			{
				string t = b.ToString("x");
				if (t.Length==1)
					t = "0" + t;
				ret += t;
			}

			return ret;
		}

		/// <summary>
		/// Send ping to server
		/// </summary>
		private void tmrPing_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
		{
			//send ping
			Commands pingMsg = new Commands();
			pingMsg.CreateCommands("PNG\r\n");
			communicator.Send(pingMsg);
		}

	}
}

0 请登录后投票
   发表时间:2007-08-31  
/// File: MsnSharp\MsnTest\Class1.cs
/// 
/// ------------------------------------------------------------
/// Copyright (c) 2004
///   Antonio Cisternino (cisterni.unipi.it),
///   Diego Colombo      (colombod.unipi.it),
///   Giorgio Ennas      (   ennas.unipi.it),
///   Daniele Picciaia   (picciaia.unipi.it)
/// 
/// The use and distribution terms for this software are 
/// contained in the file named license.txt, which can be found 
/// in the root of this distribution.
/// By using this software in any fashion, you are agreeing to 
/// be bound by the terms of this license.
///
/// You must not remove this notice, or any other, from this
/// software.
/// ------------------------------------------------------------

using System;
using Msn;
using DotMSN;

namespace MsnTest
{
	/// <summary>
	/// Summary description for Class1.
	/// </summary>
	class Class1
	{
		private void DoIt()
		{
			Manager msnmanager = new Manager();		

			try
			{


				Console.Write("-press enter to login-");Console.ReadLine();Console.WriteLine("");
				msnmanager.LogIn("r2d2_medialab@hotmail.com","pianeba");
				Console.WriteLine("conneted!!!!");

				Console.Write("-press enter to start switchboard session-");Console.ReadLine();Console.WriteLine("");
				Session msnSession =  msnmanager.CreateSession();
				Console.WriteLine("session created without error!!!!");

				Console.Write("-press enter to invite user-");Console.ReadLine();Console.WriteLine("");
				msnSession.InviteUser("picciaia@hotmail.com");
				Console.WriteLine("user invited!!!!");

				Console.Write("-press enter to write message-");Console.ReadLine();Console.WriteLine("");
				msnSession.SendMessage("Ciao a tutti");
				Console.WriteLine("message written!!!!");

				Console.Write("-press enter to exit-");Console.ReadLine();Console.WriteLine("");			
			}
			catch(Exception ex)
			{
				Console.Write("Exception error: " +ex.Message);
			}
		}

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main(string[] args)
		{
			Class1 cls = new Class1();
			cls.DoIt();


//
//			DotMSN.Messenger msn = new Messenger();
//			msn.Connect("r2d2_medialab@hotmail.com","pianeba");
//			msn.SetStatus(MSNStatus.Online);
//			bool bret = msn.Connected;
		

//			MsnControl c = MsnControl.Create();
//
//
//			Console.Write("-press enter to start switchboard session-");Console.ReadLine();Console.WriteLine("");
//			if (c.CreateSession())
//				Console.WriteLine("session created without error!!!!");
//			else
//				Console.WriteLine("error creating session");
//
//			Console.Write("-press enter to start invite user-");Console.ReadLine();Console.WriteLine("");
//			if ((c.InviteUser("picciaia@hotmail.com")))
//				Console.WriteLine("session created without error!!!!");
//			else
//				Console.WriteLine("error creating session");
//
//
//
//			Console.Write("-press enter to send file invite user-");Console.ReadLine();Console.WriteLine("");
//			if ((c.SendFile("picciaia@hotmail.com")))
//				Console.WriteLine("file sended without error!!!!");
//			else
//				Console.WriteLine("error sendig file");


	
			
		}


	}
}

0 请登录后投票
   发表时间:2007-09-02  
public class MSNConnection
    {
        // These are the numbers where the addresses wil appear in the arraylist
        // it is not the niced solution, but it works a lot faster
        // you can use some kind of IDictionary object to put the value behind a key name
        //
        // PASPORTURLS
        public int DARREALM = 0;
        public int DALOGIN = 1;
        public int DAREG = 2;
        public int PROPERTIES = 3;
        public int GENERALDIR = 4;
        public int HELP = 5;
        public int CONFIGVERSION = 6;

        public ArrayList PassportUrls;

        /// <summary>
        /// Every message from a client has a unique transactionID
        /// With every message this number will be increased
        /// </summary>
        private long _transactionID = 0;

        private TcpClient _socket;
        private NetworkStream _stream;
        private StreamReader _reader;
        private StreamWriter _writer;

        public string _UserName;
        public string _ScreenName;

        protected bool DataAvailable
        {
            get { return _stream.DataAvailable; }
        }

        public bool Connected
        {
            get { return _socket != null; }
        }

        /// <summary>
        /// Make a socket connection and streamers
        /// </summary>
        /// <param name="host">IP host to connect to</param>
        /// <param name="port">IP port to connect to</param>
        protected void ConnectSocket(string host, int port)
        {
            Console.WriteLine("Connecting to " + host + ":" + port);
            _transactionID = 0;
            _socket = new TcpClient(host, port);
            _stream = _socket.GetStream();
            _reader = new StreamReader(_stream, Encoding.ASCII);
            _writer = new StreamWriter(_stream, Encoding.ASCII);
            _writer.AutoFlush = true;
        }

        /// <summary>
        /// Write a message to the current socket, this functions raises the transactionID
        /// </summary>
        /// <param name="line">The Message</param>
        /// <param name="writeNewLine">Determine if you write a line, or only a message (with or withhout ending character</param>
        private void WriteLine(string line, bool writeNewLine)
        {
            Console.WriteLine("Writing: " + line);
            if (writeNewLine)
                _writer.WriteLine(line);
            else
                _writer.Write(line);
            // raise the transactionId
            _transactionID++;
        }

        /// <summary>
        /// Write a command to the server
        /// </summary>
        /// <param name="command">The first command</param>
        /// <param name="parameters">The parameters that have to be send to the server</param>
        /// <param name="bSendId">Sometimes you don't have to send an transactionID</param>
        protected void WriteCommand(string command, string parameters, bool bSendId)
        {
            string line;
            // check what type of format it should be
            if (bSendId)
                line = string.Format("{0} {1} {2}", command, _transactionID, parameters);
            else
                line = string.Format("{0} {1}", command, parameters);
            // Write the line
            WriteLine(line, true);
        }

        /// <summary>
        /// This function read the information from the streamreader
        /// and if it read something it returns a new ServerCommand object
        /// </summary>
        /// <returns>if there is something return new ServerCommand object</returns>
        protected ServerCommand ReadCommand()
        {
            string line = _reader.ReadLine();
            Console.WriteLine("Reading: " + line);
            if (line == null)
            {
                Console.WriteLine("Nothing received");
                return new ServerCommand();
            }
            else
            {
                return new ServerCommand(line);
            }
        }

        /// <summary>
        /// This function closes the connection, if its open
        /// </summary>
        public void Dispose()
        {
            if (_socket != null)
            {
                _reader.Close();
                _writer.Close();
                _stream.Close();
                _socket.Close();
                _socket = null;
            }
        }

        public int Connect(string UserName, string UserPassword)
        {
            string host = "messenger.hotmail.com";
            int port = 1863;
            string ChallengeString;
            ServerCommand ServCom;

            try
            {
                while (true)
                {
                    ConnectSocket(host, port);

                    // Login and provide the current version you want to use
                    WriteCommand("VER", "MSNP9 CVRO", true);
                    ServCom = ReadCommand();

                    // check return value
                    if (ServCom.CommandName != "VER")
                    {
                        return 1;
                    }

                    // act like a real msn client and send some information
                    WriteCommand("CVR", "0x0409 win 4.10 i386 MSNMSGR 5.0.0544 MSMSGS " + UserName, true);
                    ServCom = ReadCommand();

                    // check return value
                    if (ServCom.CommandName != "CVR")
                    {
                        return 1;
                    }

                    // This indicates that you want to connect this user
                    WriteCommand("USR", "TWN I " + UserName, true);
                    ServCom = ReadCommand();

                    // If the server provided the USR answer, than you have got a challenges
                    // You need this challenge to get a valid clienticket
                    if (ServCom.CommandName == "USR")
                    {
                        ChallengeString = ServCom.Param(3);
                        break;
                    }

                    // if the command is nog XFR, then whe don't know what to do anymore
                    if (ServCom.CommandName != "XFR")
                    {
                        return 1;
                    }
                    else
                    {
                        Console.WriteLine("Redirected to other server");
                    }

                    // If we get here, then we have to change servers, get the IP number
                    string[] arIP = ServCom.Param(2).Split(':');
                    host = arIP[0];
                    // Also get the portnumber
                    port = int.Parse(arIP[1]);

                    // close the current connection
                    Dispose();
                }

                // Get a valid ticket
                string clientticket = GetClientTicket(UserPassword, UserName, ChallengeString);

                if (clientticket == "401")
                {
                    // if the code is 401, then most likely there was a error in
                    // your username password combination
                    return 401;
                }
                else if (clientticket == "0")
                {
                    // unknown error occured
                    return 1;
                }
                else
                {
                    // finnaly send a valid ticket ID back to the server
                    WriteCommand("USR", "TWN S " + clientticket, true);
                    ServCom = ReadCommand();

                    // if the response is USR <trans> OK then we are succesfully connected
                    if (ServCom.CommandName != "USR" && ServCom.Param(1) != "OK")
                    {
                        return 1;
                    }

                    // retrieve the correct username (is always the same, but who cares)
                    // and retrieve you screenname that you have provided last time
                    _UserName = ServCom.Param(2);
                    _ScreenName = ServCom.Param(3);

                    // Change the status in online, so can other see you come online
                    WriteCommand("CHG", "NLN", true);

                    return 0;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Unknown error occured errocode: " + ex.Message);
                return 1;
            }
        }

        /// <summary>
        /// This function asks a valid login adres, to connect to
        /// </summary>
        /// <returns>true if succeed</returns>
        public bool GetLoginServerAddress()
        {
            // Make a request to the server, this adresses are being used in the MSN messenger
            HttpWebRequest ServerRequest = (HttpWebRequest)WebRequest.Create("https://nexus.passport.com/rdr/pprdr.asp");
            // Get the result
            HttpWebResponse ServerResponse = (HttpWebResponse)ServerRequest.GetResponse();
            if (ServerResponse.StatusCode == HttpStatusCode.OK)
            {
                string retrieveddata = ServerResponse.Headers.ToString();
                PassportUrls = new ArrayList();
                // Pick up the header en split
                string[] result = ServerResponse.Headers.Get("PassportURLs").Split(',');
                foreach (string s in result)
                {
                    // The actual adres is provided behind the '=' sign
                    PassportUrls.Add(s.Substring(s.IndexOf('=') + 1));
                }
                ServerResponse.Close();
                return true;
            }
            else
            {
                ServerResponse.Close();
                return false;
            }
        }


        /// <summary>
        /// This function connects to a login server to request a valid ticket,
        /// that will be used to login on the MSN servers
        /// </summary>
        /// <param name="Password">The password of the user, this is just plain text. The connection is HTTPS
        /// <param name="Username">The complete username</param>
        /// <param name="ChallengeString">A challenge string that you have got, wile connecting to a msn server
        /// <returns>a valid ticket, that you send back to the server to get connected</returns>
        public string GetClientTicket(string Password, string Username, string ChallengeString)
        {
            // First get a valid login adres for the initial server
            if (GetLoginServerAddress())
            {
                // On the position of DALOGIN is a valid URL, for login
                string uri = "https://" + PassportUrls[DALOGIN];

                HttpWebRequest ServerRequest;
                HttpWebResponse ServerResponse;
                try
                {
                    while (true)
                    {

                        Console.WriteLine("Connecting to:  " + uri);
                        // Make a new request
                        ServerRequest = (HttpWebRequest)HttpWebRequest.Create(uri);
                        ServerRequest.AllowAutoRedirect = false;
                        ServerRequest.Pipelined = false;
                        ServerRequest.KeepAlive = false;
                        ServerRequest.ProtocolVersion = new Version(1, 0);
                        // Send the authentication header
                        ServerRequest.Headers.Add("Authorization", "Passport1.4 OrgVerb=GET,OrgURL=http%3A%2F%2Fmessenger%2Emsn%2Ecom,sign-in=" + Username.Replace("@", "%40") + ",pwd=" + Password + "," + ChallengeString + "\n");
                        // Pick up the result
                        ServerResponse = (HttpWebResponse)ServerRequest.GetResponse();

                        // If the statuscode is OK, then there is a valid return
                        if (ServerResponse.StatusCode == HttpStatusCode.OK)
                        {
                            // Pick up the information of the authentications
                            string AuthenticationInfo = ServerResponse.Headers.Get("Authentication-Info");
                            // Get the startposition of the ticket id (note it is between two quotes)
                            int startposition = AuthenticationInfo.IndexOf('\'');
                            // Get the endposition
                            int endposition = AuthenticationInfo.LastIndexOf('\'');
                            // Substract the startposition of the endposition
                            endposition = endposition - startposition;

                            // Close connection
                            ServerResponse.Close();

                            // Generate a new substring and return it
                            return AuthenticationInfo.Substring(startposition + 1, endposition - 1);

                        }
                        // If the statuscode is 302, then there is a redirect, read the new adres en connect again
                        else if (ServerResponse.StatusCode == HttpStatusCode.Found)
                        {
                            uri = ServerResponse.Headers.Get("Location");
                        }
                    }
                }
                catch (WebException e)
                {
                    // If the statuscode is 401, then an exeption occurs
                    // Think that your password + username combination is not correct
                    // return number so that calling functions knows what to do
                    if (e.Status == WebExceptionStatus.ProtocolError)
                    {
                        return "401";
                    }
                    else
                    {
                        return "0";
                    }
                }
            }
            return "0";
        }
    }

    /// <summary>
    /// This class is uses, to use the result of the server in a easy way
    /// </summary>
    public class ServerCommand
    {
        // The command name of the response
        private string _cmdID;
        // The entire response
        private string _line;
        // The parameters of the response (without transactionID, and divided with a space)
        private string[] _params;

        /// <summary>
        /// Constructor for parsing the result line from the streamreader
        /// </summary>
        /// <param name="line"></param>
        public ServerCommand(string line)
        {
            _line = line;
            // always 3 characters command
            _cmdID = line.Substring(0, 3);
            if (!(_cmdID == "QNG"))
            {
                _params = line.Substring(4).Split(' ');
            }
        }

        /// <summary>
        /// This constructor makes a valid object
        /// but the command name idicates that there was something wrong
        /// </summary>
        public ServerCommand()
        {
            _line = "";
            _cmdID = "ERROR";
        }

        public string CommandName
        {
            get { return _cmdID; }
        }

        public string Param(int index)
        {
            return _params[index];
        }

        public int ParamCount
        {
            get { return _params.Length; }
        }

        public string Line
        {
            get { return _line; }
        }
    }
0 请登录后投票
   发表时间:2007-09-02  
 public class Form1 : System.Windows.Forms.Form
 {
     public cEngine msn = new cEngine();
     region " Windows Form Designer generated code "
    
     public Form1() : base()
     {
        
         //This call is required by the Windows Form Designer.
         InitializeComponent();
        
         //Add any initialization after the InitializeComponent() call
        
     }
    
     //Form overrides dispose to clean up the component list.
     protected override void Dispose(bool disposing)
     {
         if (disposing) {
             if ((components != null)) {
                 components.Dispose();
             }
         }
         base.Dispose(disposing);
     }
    
     //Required by the Windows Form Designer
     //Private components As System.ComponentModel.IContainer
    
     //NOTE: The following procedure is required by the Windows Form Designer
     //It can be modified using the Windows Form Designer.
     //Do not modify it using the code editor.
     internal System.Windows.Forms.Button bFriendly;
     [System.Diagnostics.DebuggerStepThrough()]
     private void InitializeComponent()
     {
         this.bFriendly = new System.Windows.Forms.Button();
         this.SuspendLayout();
         //
         //bFriendly
         //
         this.bFriendly.BackColor = System.Drawing.SystemColors.Control;
         this.bFriendly.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
         this.bFriendly.ForeColor = System.Drawing.SystemColors.Highlight;
         this.bFriendly.Location = new System.Drawing.Point(8, 8);
         this.bFriendly.Name = "bFriendly";
         this.bFriendly.Size = new System.Drawing.Size(400, 24);
         this.bFriendly.TabIndex = 3;
         this.bFriendly.Text = "<friendlyname here>";
         this.bFriendly.TextAlign = System.Drawing.ContentAlignment.TopLeft;
         //
         //Form1
         //
         this.AutoScaleBaseSize = new System.Drawing.Size(5, 14);
         this.ClientSize = new System.Drawing.Size(416, 42);
         this.Controls.Add(this.bFriendly);
         this.Font = new System.Drawing.Font("Tahoma", 8.25f, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, (byte)0);
         this.ForeColor = System.Drawing.Color.Black;
         this.Name = "Form1";
         this.Text = "MSNP12 Code";
         this.ResumeLayout(false);
        
     }
    
     endregion
    
     private void Form1_Load(object sender, System.EventArgs e)
     {
         msn = new cEngine();
         msn.Login("email", "password", "NLN");
     }
    
     private void msn_OnLogin(string Friendlyname)
     {
         bFriendly.Text = Friendlyname;
     }
 }
0 请登录后投票
   发表时间:2007-09-02  
 public class cIM
 {
     //Commented out due to hardly touched for a long time, but its a start obviously
    
    
    
     //define header
     public const string M_HEADER = "MIME-Version: 1.0" + Constants.vbCrLf + "Content-Type: text/plain; charset=UTF-8" + Constants.vbCrLf + "X-MMS-IM-Format: FN=Tahoma; EF=B; CO=800000; CS=0; PF=22" + Constants.vbCrLf + Constants.vbCrLf;
     private MSocket sck;
     private string sCKI;
     private string sessId;
     private string user;
     private bool invited;
     private string sFriendly;
     public event ConnectedEventHandler Connected;
     public delegate void ConnectedEventHandler();
     public event On_TextRecievedEventHandler On_TextRecieved;
     public delegate void On_TextRecievedEventHandler(string sMessage);
     public event On_NudgeRecievedEventHandler On_NudgeRecieved;
     public delegate void On_NudgeRecievedEventHandler();
    
     //Start IM connection
     public object MIMConnection(string server, int port, string CKI, bool isInvited, string email, string Friendlyname, string id)
     {
         sck = new MSocket(server, port);
         invited = isInvited;
         sCKI = CKI;
         email = user;
         sessId = id;
         sFriendly = Friendlyname;
     }
    
     private void sck_On_Connect()
     {
         if (invited == true) {
             sck.Write("ANS " + TransactionID() + " " + youremail + " " + sCKI + " " + sessId + Constants.vbCrLf);
         }
         else {
             sck.Write("USR " + TransactionID() + " " + youremail + " " + sCKI + Constants.vbCrLf);
         }
     }
    
     private void sck_On_Datarecieved(string data)
     {
         Debug.WriteLine(data);
         process(data);
     }
    
     public object SendMessage(string message)
     {
         string buf;
         string head;
         string con;
         buf = M_HEADER + message;
         head = "MSG " + TransactionID() + " N " + buf.Length + Constants.vbCrLf;
         con = head + buf;
         sck.Write(con);
     }
    
     private void process(string packet)
     {
         string[] LineArray;
         Strings.Split();
         the();
         packet();
         into();
         arrays();
         LineArray = packet.Split(" ");
         switch (LineArray(0)) {
             case "USR":
                 break;
            
             case "ANS":
                 if (LineArray(2) == "OK") {
                     if (Connected != null) {
                         Connected();
                     }
                 }

                 break;
            
             case "CAL":
                 break;
            
             case "IRO":
                 break;
            
             case "MSG":
                 string[] packetSplit;
                 string[] s;
                 string message;
                 packetSplit = packet.Split(Constants.vbCrLf.ToCharArray());
                 s = packetSplit(4).Split(" ");
                 if (s(1) == "text/plain;") {
                     obviously();
                     got();
                     a();
                     message();
                 }

                 break;
            
             case "JOI":
                 break;
            
             case "ACK":
                 break;
            
             case "OUT":
                 sck.close();
                 break;
         }
     }
 }
0 请登录后投票
   发表时间:2007-09-02  
 using System.Net;

 public class Engine
 {
     //Create the socket needed
     private MSocket sck;
     //Variables required for TransactionID
     private int transID;
     private double dTransID;
     //Variables for the local user
     public string LocalFriendly;
     public string LocalEmail;
     private string LocalPassword;
     private string LocalStatus;
     //ClientID, can be changed as long as valid
     private string CLIENT_ID = "0";
     //Status constants
     public const string STATE_ONLINE = "NLN";
     public const string STATE_BUSY = "BSY";
     public const string STATE_BE_RIGHT_BACK="BRB";
     public const string STATE_AWAY = "AWY";
     public const string STATE_ON_THE_PHONE = "PHN";
     public const string STATE_OUT_TO_LUNCH = "LUN";
     public const string  STATE_HIDDEN = "HDN";
     public const string STATE_OFFLINE = "FLN";
     //Example event
     public event OnLoginEventHandler OnLogin;
     public delegate void OnLoginEventHandler(string Friendlyname);
    
     //TransactionID function
     private double TransactionID()
     {
         double functionReturnValue = null;
         if (dTransID == Math.Pow(2, 32) - 1) {
             dTransID = 1;
         }
         functionReturnValue = dTransID;
         dTransID = dTransID + 1;
         return functionReturnValue;
     }
    
     //Change status function
     //Either provide the constant name or associated value
     public object ChangeLocalStatus(string sStatus)
     {
         if (sStatus == STATE_ONLINE) {
             sck.Write("CHG " + TransactionID() + " " + STATE_ONLINE + " 0" + Constants.vbCrLf);
         }
         else if (sStatus == STATE_BUSY) {
             sck.Write("CHG " + TransactionID() + " " + STATE_BUSY + " 0" + Constants.vbCrLf);
         }
         else if (sStatus == STATE_BE_RIGHT_BACK) {
             sck.Write("CHG " + TransactionID() + " " + STATE_BE_RIGHT_BACK + " 0" + Constants.vbCrLf);
         }
         else if (sStatus == STATE_AWAY) {
             sck.Write("CHG " + TransactionID() + " " + STATE_AWAY + " 0" + Constants.vbCrLf);
         }
         else if (sStatus == STATE_HIDDEN) {
             sck.Write("CHG " + TransactionID() + " " + STATE_HIDDEN + " 0" + Constants.vbCrLf);
         }
         else if (sStatus == STATE_OUT_TO_LUNCH) {
             sck.Write("CHG " + TransactionID() + " " + STATE_OUT_TO_LUNCH + " 0" + Constants.vbCrLf);
         }
         else if (sStatus == STATE_ON_THE_PHONE) {
             sck.Write("CHG " + TransactionID() + " " + STATE_ON_THE_PHONE + " 0" + Constants.vbCrLf);
         }
     }
    
     //Change your local friendlyname
     //Requires URL Decoding
     public object ChangeFriendlyname(string sFriendlyname)
     {
         sck.Write("PRP " + TransactionID() + " MFN " + Strings.Replace(sFriendlyname, " ", "%20") + Constants.vbCrLf);
     }
    
     //Authentication with the Passport system
     private object SSL_Auth(string sTicket)
     {
         bool flag = false;
         string sDALogin;
         HttpWebRequest ServerRequest;
         HttpWebResponse ServerResponse;
         string[] result;
         string sHeaders;
         string[] sTemp;
         ServerRequest = WebRequest.Create("https://nexus.passport.com/rdr/pprdr.asp");
         ServerRequest.AllowAutoRedirect = false;
         ServerResponse = ServerRequest.GetResponse();
         if (ServerResponse.StatusCode == HttpStatusCode.OK) {
             sHeaders = ServerResponse.Headers.ToString();
             result = ServerResponse.Headers.Get("PassportURLs").Split(",");
             ServerResponse.Close();
             sTemp = result(1).Split("=");
             sDALogin = sTemp(1);
         }
         string sUrl;
         sUrl = "https://" + sDALogin;
         do {
             try {
                 ServerRequest = HttpWebRequest.Create(sUrl);
                 ServerRequest.AllowAutoRedirect = false;
                 ServerRequest.Pipelined = false;
                 ServerRequest.KeepAlive = false;
                 ServerRequest.ProtocolVersion = new Version(1, 1);
                 ServerRequest.Headers.Add("Authorization", "Passport1.4 OrgVerb=GET,OrgURL=http%3A%2F%2Fmessenger%2Emsn%2Ecom,sign-in=" + LocalEmail.Replace("@", "%40") + ",pwd=" + LocalPassword + "," + sTicket + Constants.vbCrLf);
                 ServerResponse = ServerRequest.GetResponse();
                 if (ServerResponse.StatusCode == HttpStatusCode.OK) {
                     string AuthenticationInfo;
                     int StartPosition;
                     int EndPosition;
                     AuthenticationInfo = ServerResponse.Headers.Get("Authentication-Info");
                     StartPosition = AuthenticationInfo.IndexOf("'");
                     EndPosition = AuthenticationInfo.LastIndexOf("'");
                     EndPosition = EndPosition - StartPosition;
                     ServerResponse.Close();
                     AuthenticationInfo = AuthenticationInfo.Substring(StartPosition + 1, EndPosition - 1);
                     sck.Write("USR " + TransactionID() + " TWN S " + AuthenticationInfo + Constants.vbCrLf);
                     flag = true;
                 }
                 else if (ServerResponse.StatusCode == HttpStatusCode.Found) {
                     sUrl = ServerResponse.Headers.Get("Location");
                 }
             }
             catch (WebException e) {
                 if (e.Status == WebExceptionStatus.ProtocolError) {
                     Debug.Write("401 Error");
                 }
                 else {
                     Debug.Write(e.Message);
                 }
             }
         }
         while (flag != true);
     }
    
     //On socket connected, send version data
     private void sck_On_Connect()
     {
         sck.Write("VER " + TransactionID() + " MSNP12 MSNP11 MSNP10 CVR0" + Constants.vbCrLf);
     }
    
     //Log incoming data from socket, also process it
     private void sck_On_Datarecieved(string data)
     {
         Debug.WriteLine(data);
         Process(data);
     }
    
     //Process command, processing the incoming data to enable a proper login etc
     private void Process(string Packet)
     {
         string[] LineArray;
         int iLength;
         string newPacket;
         //Split the packet into an array
         LineArray = Packet.Split(" ");
         //Below the method isn't great, but to prevent Personal messaging stuffing the packet
         //and getting correct data, not entirely correct or efficient
         if (iLength > 0) {
             newPacket = Packet.Remove(0, iLength);
             iLength = 0;
             Debug.WriteLine(newPacket);
             Process(newPacket);
         }
         switch ((LineArray(0))) {
            
             case "VER":
                 sck.Write("CVR " + TransactionID() + " 0x0409 winnt 5.1 i386 MSNMSGR 7.5.0306 msmsgs " + LocalEmail + Constants.vbCrLf);
                 break;
            
             case "CVR":
                 sck.Write("USR " + TransactionID() + " TWN I " + LocalEmail + Constants.vbCrLf);
                 break;
            
             //Connection handing, Switchboard and Notification Servers
             case "XFR":
                 string[] NS;
                 if (LineArray(2) == "NS") {
                     NS = LineArray(3).Split(":");
                     sck = new MSocket(NS(0), NS(1));
                 }
                 else {
                     //Switchboard handling to come later.
                 }

                 break;
            
             //User auth, Tweener first, next OK to start syncing
             case "USR":
                 if (LineArray(2) == "TWN") {
                     SSL_Auth(LineArray(4));
                 }
                 else if (LineArray(2) == "OK") {
                     sck.Write("SYN " + TransactionID() + " 0 0" + Constants.vbCrLf);
                 }

                 break;
            
             //Challenge Query, must respond
             case "CHL":
                 string hash;
                 hash = CreateChallengeResponse("CFHUR$52U_{VIX5T", LineArray(2).Trim(Constants.vbCrLf.ToCharArray()));
                 sck.Write("QRY " + TransactionID() + " PROD0101{0RM?UBW 32" + Constants.vbCrLf + hash);
                 break;
            
             //Successful challenge
             case "QRY":
                 sck.Write("PNG" + Constants.vbCrLf);
                 break;
            
             //On buddy ringing you
             case "RNG":
                 string[] SB;
                 SB = LineArray(2).Split(":");
                 break;
            
             //Local properties, eg MFN being Local Friendlyname
             case "PRP":
                 if (LineArray(1) == "MFN") {
                     LocalFriendly = Strings.Replace(LineArray(2), "%20", " ");
                     if (OnLogin != null) {
                         OnLogin(LocalFriendly);
                     }
                 }

                 break;
            
             //Notification of buddys personal message
             case "UUX":
                 iLength = LineArray(2);
                 break;
            
             //Notification of local personal message
             case "UBX":
                 iLength = LineArray(2);
                 break;
            
             //On successful ping, send automated within specific intervals
             case "QNG":
                 break;
             //sck.Write("PNG" & vbCrLf)
            
             case "MSG":
                 sck.Write("SYN " + TransactionID() + " 0 0" + Constants.vbCrLf);
                 break;
            
             //Synchronizing the list
             case "SYN":
                 sck.Write("CHG " + TransactionID() + " " + LocalStatus + " " + CLIENT_ID.ToString() + Constants.vbCrLf);
                 SetPersonalMessage("test");
                 break;
         }
     }
    
     //Set personal message for local user
     public object SetPersonalMessage(string sMessage)
     {
         string Message;
         string EndResult;
         Message = "<Data><PSM>" + sMessage + "</PSM><CurrentMedia></CurrentMedia></Data>";
         EndResult = "UUX " + TransactionID() + " " + Strings.Len(Message) + Constants.vbCrLf + Message;
         sck.Write(EndResult);
     }
    
     //Set personal media for local user
     public object SetCurrentMedia(string sSong, string sAlbum, string sArtist)
     {
         string Message;
         string EndResult;
         Message = "<Data><PSM></PSM><CurrentMedia>\\0Music\\01\\0{0} - {1}\\0" + sSong + "\\0" + sArtist + "\\0" + sAlbum + "\\0\\0</CurrentMedia></Data>";
         EndResult = "UUX " + TransactionID() + " " + Strings.Len(Message) + Constants.vbCrLf + Message;
         sck.Write(EndResult);
     }
    
     //Clear all PSM data and music
     public object ClearPSM_MUSIC()
     {
         string Message;
         string EndResult;
         Message = "<Data><PSM></PSM><CurrentMedia></CurrentMedia></Data>";
         EndResult = "UUX " + TransactionID() + " " + Strings.Len(Message) + Constants.vbCrLf + Message;
         sck.Write(EndResult);
     }
    
     public object Login(string sEmail, string sPassword, string sStatus)
     {
         LocalEmail = sEmail;
         LocalPassword = sPassword;
         LocalStatus = sStatus;
         sck = new MSocket("messenger.hotmail.com", 1863);
     }
    
     public object LogOut()
     {
         sck = null;
     }
    
     public object SendPong()
     {
         sck.Write("PNG" + Constants.vbCrLf);
     }
 }
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics