⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 msntest.cs

📁 c#实现的MSNP协议,可实现模拟MSN的客户端
💻 CS
📖 第 1 页 / 共 2 页
字号:
				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 GetLoginServerAddres()
		{
			// 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 (GetLoginServerAddres())
			{
				// 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; }
			}
		}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -