代码改变世界

模拟MSN源码

2007-01-18 12:59  乱世文章  阅读(157)  评论(0编辑  收藏  举报

模拟msn源代码-(与sb服务器通信,聊天session)- -                               

 

// MsnUser.cpp : implementation file
//

#include "stdafx.h"
#include "SimMsnMessenger.h"
#include "MsnUser.h"
#include "MsnLoginClient.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern char  agCurDir[];
/////////////////////////////////////////////////////////////////////////////
// CMsnUser

CMsnUser::CMsnUser()
{
  m_iSendXh=0;
  m_iFree=1;
  m_iCountMsg=0;
}

CMsnUser::~CMsnUser()
{
}


// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CMsnUser, CAsyncSocket)
 //{{AFX_MSG_MAP(CMsnUser)
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif // 0

/////////////////////////////////////////////////////////////////////////////
// CMsnUser member functions

int CMsnUser::SBInit(char *aInServer, char *aInCKI)
{
  if( m_iFree == 0 )
  {
   FileLog( "SBInit  m_iFree=[%d], return -1", m_iFree);
   return -1;
  }
  
  m_iFree=0;

  unsigned int ilLen=strlen(aInServer);
  unsigned int i;
  for( i=2; i < ilLen ; i++ )
  {
   if( aInServer[i]== ':' ) break;
  }
  aInServer[i]=0x00;
  m_strCKI.Format("%s",aInCKI);
  m_Server.Format("%s",aInServer);
  m_iPort = atoi( aInServer+i+1 );
  FileLog( "[UserNo: %d] SBInit Connect(%s:%d) m_iFree=[%d]...",m_iUserNo ,(LPCTSTR)m_Server,m_iPort,m_iFree);
 
  Create(0,SOCK_STREAM,FD_CONNECT);
  Connect((LPCTSTR)m_Server,m_iPort);
  return 0;
}

void CMsnUser::OnConnect(int nErrorCode)
{
 // TODO: Add your specialized code here and/or call the base class
 FileLog("SB: [UserNo: %d] OnConnect(%d)",m_iUserNo , nErrorCode);
 AsyncSelect( FD_READ|FD_CLOSE ); //提请一个“读”的网络事件,准备接收
 char buf[1000];
 memset(buf,0x00,1000);
 m_iSendXh++;
 if( !m_strSessionID.CompareNoCase("XFR")  )
 {
  //主动请求
  //USR 1  tcpip_2005@126.com 17151585.1116982922.3576
  sprintf( buf,"USR %d %s %s/r/n",
   m_iSendXh,(LPCTSTR)m_pLoginClient->m_strMyNickName,
   (LPCTSTR)m_strCKI);

 }
 else
 {
  //被动接受请求
  //ANS 1 tcpip_2005@126.com 989495494.750408580 11742066
  //上面的命令包含了我们的登陆名,我们接收到的CKI杂列和session号.
  sprintf( buf,"ANS %d %s %s %s/r/n",
   m_iSendXh,(LPCTSTR)m_pLoginClient->m_strMyNickName,
   (LPCTSTR)m_strCKI,(LPCTSTR)m_strSessionID);
 }
 int iTem = strlen(buf);
 buf[iTem] = 0x00;
    iTem = Send( (void*)buf, strlen(buf));
 FileLog("Send ret =[%d]", iTem );
 CAsyncSocket::OnConnect(nErrorCode);
}

 
void CMsnUser::OnReceive(int nErrorCode)
{
 // TODO: Add your specialized code here and/or call the base class
 char bufRecv[2048];
 int  iTem;
 int  iLen;
 int  iStart, iEnd;
 char  cTem;
 CString strTem1,strTem2;
 int  i;

 
  iLen = this->Receive( bufRecv, 2047 );

  if( iLen <=0 )
  {
   FileLog("<-Reveive %04d bytes:<span style=/"background-color: #0000FF/">[ERROR!!]</span>",  iLen);
  
   return;
  }

   if (iLen >= 2047 ) iLen = 2047;
  bufRecv[iLen] = 0x00;
  if( iLen < 80 ) FileLog("<-SB : [UserNo: %d] Reveive %04d bytes::<span style=/"background-color: #669999/">[%s]</span>", m_iUserNo , iLen , bufRecv);
  else FileLog("<-SB : [UserNo: %d] Reveive %04d bytes::<span style=/"background-color: #669999/">[<br>%s]</span>", m_iUserNo , iLen , bufRecv);
 
  if(m_pLoginClient != NULL)
  {
   //process the recved Message:
   iStart = iEnd = 0;
   cTem = bufRecv[0];
   strTem1 = CString(bufRecv);
  
   i = 0;
   iTem = strTem1.GetLength();
   for(;iEnd < iTem;)
   {
    iEnd   = strTem1.Find(_T("/r/n"));  //?? CR LF?
    if(iEnd == -1)
    {
     FileLog("Not Find CR LF !  Error!");
     iEnd = strTem1.GetLength();
    }

    strTem2 = strTem1.Mid(0,iEnd);

    m_iBytesForCmd=0;
    DoRecvedStr(strTem2);

    if( m_iBytesForCmd > 0 )
    {
    
     strTem2 = strTem1.Mid(iEnd+2,iEnd+2+m_iBytesForCmd);
     DoMSG(strTem2, m_iBytesForCmd);
     iEnd=iEnd+m_iBytesForCmd;
    }

     iTem = strTem1.GetLength();
    if(iEnd+2 >= iTem)  break;
    strTem1 = strTem1.Mid(iEnd+2,iTem);
    i++;
   }
  
  }
 

 CAsyncSocket::OnReceive(nErrorCode);
}

int CMsnUser::Send(const void* lpBuf, int nBufLen, int nFlags)
{
 // TODO: Add your specialized code here and/or call the base class
    FileLog("->SB : [UserNo: %d] Send %04d bytes::<span style=/"background-color: #CC6600/">[%s]</span>", m_iUserNo , nBufLen , lpBuf);
 
 return CAsyncSocket::Send(lpBuf, nBufLen, nFlags);
}

int CMsnUser::DoRecvedStr(CString strMsg)
{
 FileLog("[UserNo: %d] DoRecvedStr(%s)", m_iUserNo , (LPCTSTR) strMsg);
 CString strCommand;

 char buf[500];
 int  iTem;
 char alTmp0[1000],alTmp1[100],alTmp2[100],alTmp3[100],alTmp4[1000];
 unsigned int i=0;
 
   
 //MSN Messenger命令使用纯ASCII码。对非ASCII码字符使用URL编码。
 //命令的语法是
 //XXX[<SP>TrID<SP>PARAM1<SP>PARAM2…]<CRLF>
 //其中,<SP>是空白字符,<CRLF>是回车换行,
 //XXX是一个3字符的命令串,TrID是一个流水号,PARAMx是参数,
 //[ ]内是可选项。最简单的命令没有流水号和参数。
 //为了方便起见,下面讨论时用" "代表<SP>,"/r/n"代表<CRLF>,
 //"/x??"代表一个值为0x??字节。
 //USR 18 TWN I tcpip_2005@126.com/r/n

 strCommand = strMsg.Mid(0,3);
 if(strCommand == CString("IRO"))
 {
  FileLog("[UserNo: %d] IRO 通话Session已经建立", m_iUserNo);
 
  }
 else if(strCommand == CString("ANS"))
 {
   FileLog("[UserNo: %d] ANS 确认通话Session已经建立!", m_iUserNo);
   WriteMsgFile( "Talk session init OK!", 99 );
  }
 else if(strCommand == CString("USR"))
 {
  //USR 1 OK tcpip_2005@126.com
 
  FileLog("[UserNo: %d] USR 确认通话Session已经建立!", m_iUserNo);
  WriteMsgFile( "Talk session init OK!", 99 );
  memset(alTmp0,0x00,sizeof(alTmp0));
  memset(alTmp1,0x00,sizeof(alTmp1));
  memset(alTmp2,0x00,sizeof(alTmp2));
  memset(alTmp3,0x00,sizeof(alTmp3));
  memset(alTmp4,0x00,sizeof(alTmp4));
  
  sprintf(alTmp0,"%s",(LPCTSTR)strMsg);
  sscanf(alTmp0,"%s %s %s %s",alTmp1,alTmp2,alTmp3,alTmp4);
  FileLog("XFR: %s %s %s %s",alTmp1,alTmp2,alTmp3,alTmp4);
  // CAL 2 tcpip_2005@126.com 
  memset(buf,0x00,sizeof(buf));
  m_iSendXh++;
  sprintf(buf,"CAL %d %s/r/n",m_iSendXh,(LPCTSTR)m_strEmail);
  iTem = strlen(buf);
  buf[iTem] = 0x00;
     Send( (void*)buf, strlen(buf));
  }
 else if(strCommand == CString("BYE"))
 {
   FileLog("[UserNo: %d] BYE SB断开通话Session!", m_iUserNo);
   Close();
   m_hSocket = INVALID_SOCKET;
   m_iFree = 1 ;
   WriteMsgFile( "Bye , Talk session was closed!", 99 );
  }
 else if(strCommand == CString("XFR"))
 {
  //XFR 3 NS 207.46.107.104:1863 0 207.46.104.20:1863%0d%0a
  
  memset(alTmp0,0x00,sizeof(alTmp0));
  memset(alTmp1,0x00,sizeof(alTmp1));
  memset(alTmp2,0x00,sizeof(alTmp2));
  memset(alTmp3,0x00,sizeof(alTmp3));
  memset(alTmp4,0x00,sizeof(alTmp4));
  
  sprintf(alTmp0,"%s",(LPCTSTR)strMsg);
  sscanf(alTmp0,"%s %s %s %s",alTmp1,alTmp2,alTmp3,alTmp4);
  FileLog("XFR: %s %s %s %s",alTmp1,alTmp2,alTmp3,alTmp4);
  
  memset(buf,0x00,sizeof(buf));
  m_iSendXh++;
  iTem = strlen(buf);
  buf[iTem] = 0x0d; buf[iTem+1] = 0x0a; buf[iTem+2] = 0x00;
     Send( (void*)buf, strlen(buf));
 }
 else if(strCommand == CString("MSG"))
 {
  //MSG Hotmail Hotmail 499
 
 
  memset(alTmp0,0x00,sizeof(alTmp0));
  memset(alTmp1,0x00,sizeof(alTmp1));
  memset(alTmp2,0x00,sizeof(alTmp2));
  memset(alTmp3,0x00,sizeof(alTmp3));
  memset(alTmp4,0x00,sizeof(alTmp4));
 
  sprintf(alTmp0,"%s",(LPCTSTR)strMsg);
  int iLen;
  sscanf(alTmp0,"%s %s %s %s",alTmp1,alTmp2,alTmp3 ,alTmp4);
  iLen = atoi( alTmp4 );
  FileLog("MSG : %s %s %s ,Len=%d",alTmp1,alTmp2,alTmp3 ,iLen);
  m_iBytesForCmd = iLen;
   
 }
 else if(strCommand == CString("JOI"))
 {
  //[CAL 2 RINGING 17151585%0d%0a]
  //[JOI tcpip_2005@126.com %e5%b0%8fI%e6%82%a0%e6%82%a0%0d%0a]
 
   FileLog("[UserNo: %d] 通话Session OK!", m_iUserNo);
    WriteMsgFile( "CAL OK!", 99 );
   if( m_strWaitSend.GetLength() > 0 )
   {
    UserInputMsg( (LPCTSTR)m_strWaitSend );
   }
  }
  
 
 
 return 0;
}

int CMsnUser::DoMSG(CString strMsg, int iInMsgLen)
{
 
 FileLog("[UserNo: %d] DoMSG [%d]", m_iUserNo ,iInMsgLen);
 
 WriteMsgFile( (LPCTSTR)strMsg , 0 );
 /*************
  memset(buf,0x00,sizeof(buf));
  m_iSendXh++;
  sprintf(buf,"MSG %d A %d/r/n",m_iSendXh,iInMsgLen);
  iTem = strlen(buf);
  buf[iTem] = 0x00;
     Send( (void*)buf, strlen(buf));

  Send( (LPCTSTR)strMsg,iInMsgLen);
  ***************/
 return 0;
}

void CMsnUser::OnClose(int nErrorCode)
{
 // TODO: Add your specialized code here and/or call the base class
 FileLog("[UserNo: %d] OnClose(%d ) SB断开通话Sessio!", m_iUserNo,nErrorCode);
 m_iFree = 1;
 Close();
 m_hSocket = INVALID_SOCKET;
 WriteMsgFile( "Talk session was closed! Can't send message!", 99 );
 CAsyncSocket::OnClose(nErrorCode);
}

int CMsnUser::WriteMsgFile(const  char *aInMsg, int iIO)
{
 
 char alTmp1[2048];
 int ilBytes=strlen(aInMsg);
 FILE     *fp;
    char    fname1[300];
 int ilIO=iIO;
    memset(alTmp1,0x00,sizeof(alTmp1));
 if( iIO == 0)
 {
  if( strstr(aInMsg,"Typing") != NULL )
  {
    memcpy( alTmp1,"Typing...", 9);
    ilIO=99;
  }
  else
  {
   for( int i=0;i<ilBytes; i ++ )
   {
    if( strncmp(aInMsg+i , "/r/n/r/n",4 ) == 0 )
    memcpy( alTmp1,aInMsg+i +4, ilBytes-i-4);
   }
  }

 }
 else memcpy( alTmp1,aInMsg , ilBytes );

 sprintf(fname1,"%s//html//%d_user_left.htm",agCurDir,m_iUserNo);
    FileLog("[UserNo: %d] %d %s", m_iUserNo,ilIO, fname1);

 if (( fp = fopen(fname1,"a+")) == NULL)  return(-1);

 if( ilIO == 1)  fprintf( fp,"%s say:<br>/n",(LPCTSTR)m_pLoginClient->m_strNick);
 else if( ilIO == 0)  fprintf( fp,"%s say:<br>/n",(LPCTSTR)m_strNickName);
    else fprintf( fp,"Info :  ");
   
 fprintf( fp,"&nbsp;&nbsp;%s<br>/n",alTmp1);
    fclose( fp );

 m_iCountMsg++;

 FileLog("PostMessage(WPARAM, LPARAM lParam DispMainPage)");
 LPARAM lpTmp= m_iUserNo+100;
 AfxGetApp()->m_pMainWnd->PostMessage( WM_MY_MESSAGE, 1, (LPARAM)lpTmp );

 return 0;
}

int CMsnUser::UserInputMsg(const char *aInMsg)
{
 int iInMsgLen=strlen(aInMsg);

 FileLog("[UserNo: %d] UserInputMsg Len=[%d]", m_iUserNo ,iInMsgLen);
 char buf[500],buf1[1000];
 int  iTem,ilLen;


 if( m_iFree == 1 )
 {
  FileLog("[UserNo: %d] session was closed!", m_iUserNo );
  memset(buf1,0x00,sizeof(buf1));
  sprintf(buf1,"Talk session was closed! Can't send message!");
  WriteMsgFile( buf1, 99 );
  m_strWaitSend+=aInMsg;
  
  m_pLoginClient->DoUserXfrSB(m_iUserNo);
  return -1;
 }
 memset(buf1,0x00,sizeof(buf1));
 //sprintf(buf1,"MIME-Version: 1.0/r/nContent-Type: text/plain; charset=UTF-8/r/nX-MMS-IM-Format: FN=%%E5%%AE%%8B%%E4%%BD%%93; EF=; CO=0; CS=86; PF=0/r/n/r/n");
 sprintf(buf1,"MIME-Version: 1.0/r/nContent-Type: text/plain; charset=UTF-8/r/nUser-Agent: Gaim/1.0.3/r/nX-MMS-IM-Format: FN=MS%%2520Sans%%2520Serif; EF=; CO=0; PF=0/r/n/r/n");
 
 
 WriteMsgFile( aInMsg , 1 );
 memset(buf,0x00,sizeof(buf));
 m_iSendXh++;
 sprintf(buf,"MSG %d A %d/r/n",m_iSendXh,iInMsgLen+strlen(buf1));
 iTem = strlen(buf);
 buf[iTem] = 0x00;
 ilLen = Send( (void*)buf, strlen(buf));
 FileLog("[UserNo: %d] Send [%d] ret  [%d]", m_iUserNo ,strlen(buf),ilLen);
 ilLen = Send( (void*)buf1, strlen(buf1));
 FileLog("[UserNo: %d] Send [%d] ret  [%d]", m_iUserNo ,strlen(buf1),ilLen);
 
 ilLen = Send( aInMsg,iInMsgLen);
 FileLog("[UserNo: %d] Send [%d] ret  [%d]", m_iUserNo ,iInMsgLen,ilLen);
 
 return 0;
}