锁定老帖子 主题:MSNP 实现
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-08-31
一下方法分别提供对其操作: /// 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); } } } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间: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; } } |
|
返回顶楼 | |
发表时间: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); } } } } } |
|
返回顶楼 | |
发表时间: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; } } } |
|
返回顶楼 | |
发表时间: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); } } } |
|
返回顶楼 | |
发表时间: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"); } } } |
|
返回顶楼 | |
发表时间: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; } } } |
|
返回顶楼 | |
发表时间: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; } } |
|
返回顶楼 | |
发表时间: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; } } } |
|
返回顶楼 | |
发表时间: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); } } |
|
返回顶楼 | |