C#代码转Delphi,还是MSN登录问题。(倾嚷相送)(99分)

  • 主题发起人 lovellybaby
  • 开始时间
L

lovellybaby

Unregistered / Unconfirmed
GUEST, unregistred user!
以下是MSN登陆代码,代码不难,但我不知道在Delphi中则么自定义Request头.
-----------------------------------------------------------------------
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Net.Sockets;
using System.Net;
using System.IO;
using System.Text;
using System.Web;

namespace MSNTestNamespace
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class MSNTest : System.Windows.Forms.Form
{
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Button btnConnect;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label lblUsername;
private System.Windows.Forms.TextBox txtPassword;
private System.Windows.Forms.TextBox txtUsername;
private System.Windows.Forms.Label lblScreenName;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;

public MSNTest()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();

//
// TODO: Add any constructor code after InitializeComponent call
//
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.panel1 = new System.Windows.Forms.Panel();
this.btnConnect = new System.Windows.Forms.Button();
this.label2 = new System.Windows.Forms.Label();
this.lblUsername = new System.Windows.Forms.Label();
this.txtPassword = new System.Windows.Forms.TextBox();
this.txtUsername = new System.Windows.Forms.TextBox();
this.lblScreenName = new System.Windows.Forms.Label();
this.panel1.SuspendLayout();
this.SuspendLayout();
//
// panel1
//
this.panel1.BackColor = System.Drawing.SystemColors.InactiveBorder;
this.panel1.Controls.Add(this.label2);
this.panel1.Controls.Add(this.lblUsername);
this.panel1.Controls.Add(this.txtPassword);
this.panel1.Controls.Add(this.txtUsername);
this.panel1.Location = new System.Drawing.Point(8, 16);
this.panel1.Name = &quot;panel1&quot;;
this.panel1.Size = new System.Drawing.Size(192, 144);
this.panel1.TabIndex = 5;
//
// btnConnect
//
this.btnConnect.Location = new System.Drawing.Point(204, 232);
this.btnConnect.Name = &quot;btnConnect&quot;;
this.btnConnect.TabIndex = 0;
this.btnConnect.Text = &quot;Connect Me&quot;;
this.btnConnect.Click += new System.EventHandler(this.button1_Click);
//
// label2
//
this.label2.Font = new System.Drawing.Font(&quot;Microsoft Sans Serif&quot;, 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
this.label2.Location = new System.Drawing.Point(6, 64);
this.label2.Name = &quot;label2&quot;;
this.label2.TabIndex = 8;
this.label2.Text = &quot;Password&quot;;
//
// lblUsername
//
this.lblUsername.Font = new System.Drawing.Font(&quot;Microsoft Sans Serif&quot;, 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
this.lblUsername.Location = new System.Drawing.Point(6, 8);
this.lblUsername.Name = &quot;lblUsername&quot;;
this.lblUsername.TabIndex = 7;
this.lblUsername.Text = &quot;Username&quot;;
//
// txtPassword
//
this.txtPassword.Location = new System.Drawing.Point(8, 88);
this.txtPassword.Name = &quot;txtPassword&quot;;
this.txtPassword.PasswordChar = '*';
this.txtPassword.Size = new System.Drawing.Size(168, 20);
this.txtPassword.TabIndex = 6;
this.txtPassword.Text = &quot;&quot;;
//
// txtUsername
//
this.txtUsername.Location = new System.Drawing.Point(8, 32);
this.txtUsername.Name = &quot;txtUsername&quot;;
this.txtUsername.Size = new System.Drawing.Size(168, 20);
this.txtUsername.TabIndex = 5;
this.txtUsername.Text = &quot;&quot;;
//
// lblScreenName
//
this.lblScreenName.Location = new System.Drawing.Point(8, 168);
this.lblScreenName.Name = &quot;lblScreenName&quot;;
this.lblScreenName.Size = new System.Drawing.Size(272, 48);
this.lblScreenName.TabIndex = 6;
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.lblScreenName);
this.Controls.Add(this.panel1);
this.Controls.Add(this.btnConnect);
this.Name = &quot;Form1&quot;;
this.Text = &quot;MSN Test MSNP9&quot;;
this.panel1.ResumeLayout(false);
this.ResumeLayout(false);

}
#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new MSNTest());
}

private void button1_Click(object sender, System.EventArgs e)
{

MSNConnection MSN = new MSNConnection();
string username = txtUsername.Text;
string password = txtPassword.Text;
if (username != &quot;&quot; && password != &quot;&quot;)
{
lblScreenName.Text = &quot;Connecting please wait&quot;;
lblScreenName.Update();
int result = MSN.Connect(username, password);
lblScreenName.Text = &quot;&quot;;
lblScreenName.Update();
if (result == 0)
{
MessageBox.Show(&quot;Connected as '&quot; + MSN._UserName + &quot;'&quot;, &quot;MSN Test&quot;,MessageBoxButtons.OK, MessageBoxIcon.Information);
lblScreenName.Text = &quot;Your screenname: &quot; + MSN._ScreenName.Replace(&quot;%20&quot;, &quot; &quot;);
}
else if (result == 401)
{
MessageBox.Show(&quot;Invalid credentials, please try again&quot;, &quot;MSN Test&quot;,MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
MessageBox.Show(&quot;Unknow error occured while connecting&quot;, &quot;MSN Test&quot;,MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
else
{
MessageBox.Show(&quot;Invalid credentials, please try again&quot;, &quot;MSN Test&quot;,MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}

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=&quot;host&quot;>IP host to connect to</param>
/// <param name=&quot;port&quot;>IP port to connect to</param>
protected void ConnectSocket(string host, int port)
{
Console.WriteLine(&quot;Connecting to &quot; + host + &quot;:&quot; + 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=&quot;line&quot;>The Message</param>
/// <param name=&quot;writeNewLine&quot;>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(&quot;Writing: &quot; + line);
if (writeNewLine)
_writer.WriteLine(line);
else
_writer.Write(line);
// raise the transactionId
_transactionID++;
}

/// <summary>
/// Write a command to the server
/// </summary>
/// <param name=&quot;command&quot;>The first command</param>
/// <param name=&quot;parameters&quot;>The parameters that have to be send to the server</param>
/// <param name=&quot;bSendId&quot;>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(&quot;{0} {1} {2}&quot;, command, _transactionID, parameters);
else
line = string.Format(&quot;{0} {1}&quot;, 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(&quot;Reading: &quot; + line);
if (line == null)
{
Console.WriteLine(&quot;Nothing received&quot;);
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 = &quot;messenger.hotmail.com&quot;;
int port = 1863;
string ChallengeString;
ServerCommand ServCom;

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

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

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

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

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

// This indicates that you want to connect this user
WriteCommand(&quot;USR&quot;, &quot;TWN I &quot; + 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 == &quot;USR&quot;)
{
ChallengeString = ServCom.Param(3);
break;
}

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

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

// if the response is USR <trans> OK then we are succesfully connected
if (ServCom.CommandName != &quot;USR&quot; && ServCom.Param(1) != &quot;OK&quot;)
{
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(&quot;CHG&quot;, &quot;NLN&quot;, true);

return 0;
}
}
catch (Exception ex)
{
Console.WriteLine(&quot;Unknown error occured errocode: &quot; + 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(&quot;https://nexus.passport.com/rdr/pprdr.asp&quot;);
// 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(&quot;PassportURLs&quot;).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=&quot;Password&quot;>The password of the user, this is just plain text. The connection is HTTPS
/// <param name=&quot;Username&quot;>The complete username</param>
/// <param name=&quot;ChallengeString&quot;>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 = &quot;https://&quot; + PassportUrls[DALOGIN];

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

Console.WriteLine(&quot;Connecting to: &quot; + 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(&quot;Authorization&quot;, &quot;Passport1.4 OrgVerb=GET,OrgURL=http%3A%2F%2Fmessenger%2Emsn%2Ecom,sign-in=&quot; + Username.Replace(&quot;@&quot;, &quot;%40&quot;) + &quot;,pwd=&quot; + Password + &quot;,&quot; + ChallengeString + &quot;/n&quot;);
// 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(&quot;Authentication-Info&quot;);
// 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(&quot;Location&quot;);
}
}
}
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 &quot;401&quot;;
}
else
{
return &quot;0&quot;;
}
}
}
return &quot;0&quot;;
}
}

/// <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=&quot;line&quot;></param>
public ServerCommand(string line)
{
_line = line;
// always 3 characters command
_cmdID = line.Substring(0, 3);
if (!(_cmdID == &quot;QNG&quot;))
{
_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 = &quot;&quot;;
_cmdID = &quot;ERROR&quot;;
}

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; }
}
}
}
------------------------------------------------------------------
 
兄弟,我已把代码给你汇过去了。给分吧!
 
接受答案了.
 

Similar threads

顶部