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

📄 chatsession.cpp

📁 著名的下载软件核心Shareaza
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	{
		if ( ! OnText( strLine ) )
		{
			Close();
			return FALSE;
		}
	}
	
	return TRUE;
}

BOOL CChatSession::OnText(const CString& str)
{
	if ( m_pWndPrivate == NULL ) return TRUE;
	
	if ( m_bOld )
	{
		if ( StartsWith( str, _T("\001ACTION ") ) )
		{
			m_pWndPrivate->OnRemoteMessage( TRUE, str.Mid( 8 ) );
		}
		else
		{
			m_pWndPrivate->OnRemoteMessage( FALSE, str );
		}
	}
	else if ( StartsWith( str, _T("MESSAGE ") ) )
	{
		if ( StartsWith( str, _T("MESSAGE \001ACTION ") ) )
		{
			m_pWndPrivate->OnRemoteMessage( TRUE, str.Mid( 16 ) );
		}
		else
		{
			m_pWndPrivate->OnRemoteMessage( FALSE, str.Mid( 8 ) );
		}
	}
	else if ( StartsWith( str, _T("NICK ") ) )
	{
		// New nick is : str.Mid( 5 )
	}
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CChatSession Gnutella2 packet interface

void CChatSession::Send(CG2Packet* pPacket, BOOL bRelease)
{
	ASSERT( m_bG2 );
	ASSERT( pPacket != NULL );
	ASSERT( m_nState >= cssHandshake );
	
	pPacket->ToBuffer( m_pOutput );
	if ( bRelease ) pPacket->Release();
	
	OnWrite();
}

BOOL CChatSession::ReadPackets()
{
	for ( BOOL bSuccess = TRUE ; bSuccess && m_pInput->m_nLength ; )
	{
		BYTE nInput = *( m_pInput->m_pBuffer );
		
		if ( nInput == 0 )
		{
			m_pInput->Remove( 1 );
			continue;
		}
		
		BYTE nLenLen	= ( nInput & 0xC0 ) >> 6;
		BYTE nTypeLen	= ( nInput & 0x38 ) >> 3;
		BYTE nFlags		= ( nInput & 0x07 );
		
		if ( nLenLen == 0 )
		{
			Close();
			return FALSE;
		}
		
		if ( (DWORD)m_pInput->m_nLength < (DWORD)nLenLen + nTypeLen + 2 ) break;
		
		DWORD nLength = 0;
		
		if ( nFlags & G2_FLAG_BIG_ENDIAN )
		{
			BYTE* pLenIn = m_pInput->m_pBuffer + 1;
			
			for ( BYTE nIt = nLenLen ; nIt ; nIt-- )
			{
				nLength <<= 8;
				nLength |= *pLenIn++;
			}
		}
		else
		{
			BYTE* pLenIn	= m_pInput->m_pBuffer + 1;
			BYTE* pLenOut	= (BYTE*)&nLength;
			for ( BYTE nLenCnt = nLenLen ; nLenCnt-- ; ) *pLenOut++ = *pLenIn++;
		}
		
		if ( nLength >= Settings.Gnutella1.MaximumPacket )
		{
			Close();
			return FALSE;
		}
		
		if ( (DWORD)m_pInput->m_nLength < (DWORD)nLength + nLenLen + nTypeLen + 2 ) break;
		
		CG2Packet* pPacket = CG2Packet::New( m_pInput->m_pBuffer );
		
		m_pInput->Remove( nLength + nLenLen + nTypeLen + 2 );
		
		try
		{
			bSuccess = OnPacket( pPacket );
		}
		catch ( CException* pException )
		{
			pException->Delete();
			bSuccess = TRUE;
		}
		
		pPacket->Release();
	}
	
	if ( ! bSuccess ) Close();
	
	return bSuccess;
}

//////////////////////////////////////////////////////////////////////
// CChatSession Gnutella2 packet handlers

BOOL CChatSession::OnPacket(CG2Packet* pPacket)
{
	if ( pPacket->IsType( "CMSG" ) )
	{
		return OnChatMessage( pPacket );
	}
	else if ( pPacket->IsType( G2_PACKET_PROFILE_CHALLENGE ) )
	{
		return OnProfileChallenge( pPacket );
	}
	else if ( pPacket->IsType( G2_PACKET_PROFILE_DELIVERY ) )
	{
		return OnProfileDelivery( pPacket );
	}
	else if ( pPacket->IsType( "CHATREQ" ) )
	{
		return OnChatRequest( pPacket );
	}
	else if ( pPacket->IsType( "CHATANS" ) )
	{
		return OnChatAnswer( pPacket );
	}
	
	return TRUE;
}

BOOL CChatSession::OnProfileChallenge(CG2Packet* pPacket)
{
	if ( ! MyProfile.IsValid() ) return TRUE;
	
	CG2Packet* pProfile = CG2Packet::New( G2_PACKET_PROFILE_DELIVERY, TRUE );
	CString strXML = MyProfile.GetXML( NULL, TRUE )->ToString( TRUE );
	
	pProfile->WritePacket( "XML", pProfile->GetStringLen( strXML ) );
	pProfile->WriteString( strXML, FALSE );
	
	Send( pProfile, TRUE );
	
	return TRUE;
}

BOOL CChatSession::OnProfileDelivery(CG2Packet* pPacket)
{
	if ( ! pPacket->m_bCompound ) return TRUE;
	
	if ( m_pProfile != NULL ) delete m_pProfile;
	m_pProfile = NULL;
	
	CHAR szType[9];
	DWORD nLength;
	
	while ( pPacket->ReadPacket( szType, nLength ) )
	{
		DWORD nOffset = pPacket->m_nPosition + nLength;
		
		if ( strcmp( szType, "XML" ) == 0 )
		{
			CXMLElement* pXML = CXMLElement::FromString( pPacket->ReadString( nLength ), TRUE );
			
			if ( pXML != NULL )
			{
				m_pProfile = new CGProfile();
				
				if ( ! m_pProfile->FromXML( pXML ) || ! m_pProfile->IsValid() )
				{
					delete pXML;
					delete m_pProfile;
					m_pProfile = NULL;
				}
			}
		}
		
		pPacket->m_nPosition = nOffset;
	}
	
	if ( m_pProfile == NULL ) return TRUE;
	
	m_sUserNick = m_pProfile->GetNick();
	
	if ( m_bGUID )
	{
		if ( m_pGUID != m_pProfile->GUID )
		{
			// ERROR: Its someone else !!
			m_pGUID = m_pProfile->GUID;
		}
	}
	else
	{
		m_bGUID = TRUE;
		m_pGUID = m_pProfile->GUID;
	}
	
	if ( m_pWndPrivate != NULL )
	{
		m_pWndPrivate->OnProfileReceived();
		
		CG2Packet* pPacket = CG2Packet::New( "CHATREQ", TRUE );
		pPacket->WritePacket( "USERGUID", 16 );
		pPacket->Write( &m_pGUID, 16 );
		
		Send( pPacket, TRUE );
	}
	
	return TRUE;
}

BOOL CChatSession::OnChatRequest(CG2Packet* pPacket)
{
	if ( ! pPacket->m_bCompound ) return TRUE;
	
	BOOL bGUID = FALSE;
	GGUID pGUID;
	
	CHAR szType[9];
	DWORD nLength;
	
	while ( pPacket->ReadPacket( szType, nLength ) )
	{
		DWORD nOffset = pPacket->m_nPosition + nLength;
		
		if ( strcmp( szType, "USERGUID" ) == 0 && nLength >= 16 )
		{
			pPacket->Read( &pGUID, 16 );
			bGUID = TRUE;
		}
		
		pPacket->m_nPosition = nOffset;
	}
	
	pPacket = CG2Packet::New( "CHATANS", TRUE );
	
	pPacket->WritePacket( "USERGUID", 16 );
	pPacket->Write( &MyProfile.GUID, 16 );
	
	if ( bGUID && pGUID == MyProfile.GUID )
	{
		pPacket->WritePacket( "ACCEPT", 0 );
		PostOpenWindow();
	}
	else
	{
		pPacket->WritePacket( "DENY", 0 );
	}
	
	Send( pPacket, TRUE );
	
	return TRUE;
}

BOOL CChatSession::OnChatAnswer(CG2Packet* pPacket)
{
	if ( ! pPacket->m_bCompound ) return TRUE;
	
	CHAR szType[9];
	DWORD nLength;
	
	while ( pPacket->ReadPacket( szType, nLength ) )
	{
		DWORD nOffset = pPacket->m_nPosition + nLength;
		
		if ( strcmp( szType, "ACCEPT" ) == 0 )
		{
			m_nState = cssActive;
			StatusMessage( 2, IDS_CHAT_PRIVATE_ONLINE, (LPCTSTR)m_sUserNick );
			StatusMessage( 0, 0 );
			return TRUE;
		}
		else if ( strcmp( szType, "DENY" ) == 0 )
		{
			StatusMessage( 1, IDS_CHAT_PRIVATE_REFUSED, (LPCTSTR)m_sUserNick );
		}
		else if ( strcmp( szType, "AWAY" ) == 0 )
		{
			CString strAway = pPacket->ReadString( nLength );
			StatusMessage( 1, IDS_CHAT_PRIVATE_AWAY, (LPCTSTR)m_sUserNick,
				(LPCTSTR)strAway );
		}
		
		pPacket->m_nPosition = nOffset;
	}
	
	Close();
	
	return FALSE;
}

BOOL CChatSession::OnChatMessage(CG2Packet* pPacket)
{
	if ( ! pPacket->m_bCompound ) return TRUE;
	
	BOOL bAction = FALSE;
	CString strBody;
	CHAR szType[9];
	DWORD nLength;
	
	while ( pPacket->ReadPacket( szType, nLength ) )
	{
		DWORD nOffset = pPacket->m_nPosition + nLength;
		
		if ( strcmp( szType, "BODY" ) == 0 )
		{
			strBody = pPacket->ReadString( nLength );
		}
		else if ( strcmp( szType, "ACT" ) == 0 )
		{
			bAction = TRUE;
		}
		
		pPacket->m_nPosition = nOffset;
	}
	
	if ( strBody.IsEmpty() ) return TRUE;
	
	if ( m_pWndPrivate != NULL ) m_pWndPrivate->OnRemoteMessage( bAction, strBody );
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CChatSession message interface

BOOL CChatSession::SendPrivateMessage(BOOL bAction, LPCTSTR pszText)
{
	CSingleLock pLock( &ChatCore.m_pSection, TRUE );
	
	if ( m_nState != cssActive ) return FALSE;
	
	if ( m_bG2 )
	{
		CG2Packet* pPacket = CG2Packet::New( "CMSG", TRUE );
		
		if ( bAction ) pPacket->WritePacket( "ACT", 0 );
		
		pPacket->WritePacket( "BODY", pPacket->GetStringLen( pszText ) );
		pPacket->WriteString( pszText, FALSE );
		
		Send( pPacket, TRUE );
	}
	else
	{
		CString str;
		
		if ( ! m_bOld ) str += _T("MESSAGE ");
		if ( bAction ) str += _T("\001ACTION ");
		str += pszText;
		str += _T("\r\n");
		
		Print( str );
	}

	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CChatSession status message

void CChatSession::StatusMessage(int nFlags, UINT nID, ...)
{
	CString strFormat;
	va_list pArgs;
	
	if ( nID )
		LoadString( strFormat, nID );
	else
		strFormat = _T("-");
	
	va_start( pArgs, nID );
	
	if ( strFormat.Find( _T("%1") ) >= 0 )
	{
		LPTSTR lpszTemp;
		if ( ::FormatMessage( FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER,
			strFormat, 0, 0, (LPTSTR)&lpszTemp, 0, &pArgs ) != 0 && lpszTemp != NULL )
		{
			if ( m_pWndPrivate != NULL ) m_pWndPrivate->OnStatusMessage( nFlags, lpszTemp );
			LocalFree( lpszTemp );
		}
	}
	else
	{
		TCHAR szMessageBuffer[1024];
		_vstprintf( szMessageBuffer, strFormat, pArgs );
		if ( m_pWndPrivate != NULL ) m_pWndPrivate->OnStatusMessage( nFlags, szMessageBuffer );
	}
	
	va_end( pArgs );
}

//////////////////////////////////////////////////////////////////////
// CChatSession chat window interface

void CChatSession::PostOpenWindow()
{
	if ( m_pWndPrivate != NULL || m_pWndPublic != NULL ) return;
	
	if ( CWnd* pWnd = (CWnd*)theApp.SafeMainWnd() )
	{
		pWnd->PostMessage( WM_OPENCHAT, (WPARAM)this );
	}
}

void CChatSession::OnOpenWindow()
{
	ASSERT( m_pWndPrivate == NULL && m_pWndPublic == NULL );
	
	if ( m_bGUID )
	{
		m_pWndPrivate = ChatWindows.FindPrivate( &m_pGUID );
	}
	else
	{
		m_pWndPrivate = ChatWindows.FindPrivate( &m_pHost.sin_addr );
	}
	
	if ( m_pWndPrivate == NULL )
	{
		m_pWndPrivate = new CPrivateChatFrame();
	}
	
	if ( ! m_pWndPrivate->Accept( this ) )
	{
		m_pWndPrivate = new CPrivateChatFrame();
		m_pWndPrivate->Accept( this );
	}
	
	m_pWndPrivate->OnProfileReceived();
	
	StatusMessage( 2, IDS_CHAT_PRIVATE_ONLINE, (LPCTSTR)m_sUserNick );
	StatusMessage( 0, 0 );
	
	PlaySound( _T("RAZA_IncomingChat"), NULL, SND_APPLICATION|SND_ALIAS|SND_ASYNC );
	
	m_nState = cssActive;
	
	// Hack to open it
	
	CWnd* pParent = m_pWndPrivate->GetParent();
	if ( pParent->IsIconic() ) pParent->ShowWindow( SW_SHOWNORMAL );
	pParent->BringWindowToTop();
	pParent->SetForegroundWindow();
}

void CChatSession::OnCloseWindow()
{
	m_pWndPrivate = NULL;
	m_pWndPublic = NULL;
	
	Close();
}

⌨️ 快捷键说明

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