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

📄 hostbrowser.cpp

📁 著名的下载软件核心Shareaza
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	else if ( strHeader.CompareNoCase( _T("Content-Type") ) == 0 )
	{
		if ( strValue.CompareNoCase( _T("application/x-gnutella-packets") ) == 0 )
			m_nProtocol = PROTOCOL_G1;
		else if ( strValue.CompareNoCase( _T("application/x-gnutella2") ) == 0 )
			m_nProtocol = PROTOCOL_G2;
		else if ( strValue.CompareNoCase( _T("application/x-shareaza") ) == 0 )
			m_nProtocol = PROTOCOL_G2;
		else if ( strValue.CompareNoCase( _T("text/html") ) == 0 )
			m_nProtocol = 0;
	}
	else if ( strHeader.CompareNoCase( _T("Content-Encoding") ) == 0 )
	{
		m_bDeflate = strValue.CompareNoCase( _T("deflate") ) == 0;
	}
	else if ( strHeader.CompareNoCase( _T("Content-Length") ) == 0 )
	{
		_stscanf( strValue, _T("%lu"), &m_nLength );
	}

	return TRUE;
}

BOOL CHostBrowser::OnHeadersComplete()
{
	if ( m_nProtocol < 0 || m_nLength == 0 )
	{
		theApp.Message( MSG_ERROR, IDS_BROWSE_BAD_RESPONSE, (LPCTSTR)m_sAddress );
		Stop();
		return FALSE;
	}
	
	m_nState		= hbsContent;
	m_nReceived		= 0;
	m_pBuffer		= new CBuffer();
	m_mInput.tLast	= GetTickCount();
	
	if ( m_bDeflate )
	{
		m_pInflate = new z_stream;
		z_streamp pStream = (z_streamp)m_pInflate;
		ZeroMemory( pStream, sizeof(z_stream) );
		
		if ( inflateInit( pStream ) != Z_OK )
		{
			delete pStream;
			m_pInflate = NULL;
			Stop();
			return FALSE;
		}
	}
	
	switch ( m_nProtocol )
	{
	case 0:
		theApp.Message( MSG_DEFAULT, IDS_BROWSE_DOWNLOADING_FROM,
			(LPCTSTR)m_sAddress, _T("HTML") );
		break;
	case PROTOCOL_G1:
		theApp.Message( MSG_DEFAULT, IDS_BROWSE_DOWNLOADING_FROM,
			(LPCTSTR)m_sAddress, _T("Gnutella-1") );
		break;
	case PROTOCOL_G2:
		theApp.Message( MSG_DEFAULT, IDS_BROWSE_DOWNLOADING_FROM,
			(LPCTSTR)m_sAddress, _T("Gnutella-2") );
		break;
	}
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CHostBrowser read content

BOOL CHostBrowser::ReadContent()
{
	if ( m_nReceived < m_nLength )
	{
		DWORD nVolume = min( m_nLength - m_nReceived, m_pInput->m_nLength );
		m_nReceived += nVolume;
		
		if ( m_bDeflate && m_pInflate != NULL )
		{
			z_streamp pStream = (z_streamp)m_pInflate;

			while ( nVolume || m_pBuffer->m_nLength == m_pBuffer->m_nBuffer || pStream->avail_out == 0 )
			{
				m_pBuffer->EnsureBuffer( 1024 );
				
				pStream->next_in	= m_pInput->m_pBuffer;
				pStream->avail_in	= m_pInput->m_nLength;
				pStream->next_out	= m_pBuffer->m_pBuffer + m_pBuffer->m_nLength;
				pStream->avail_out	= m_pBuffer->m_nBuffer - m_pBuffer->m_nLength;
				
				inflate( pStream, Z_SYNC_FLUSH );
				
				m_pInput->Remove( m_pInput->m_nLength - pStream->avail_in );
				nVolume -= ( m_pInput->m_nLength - pStream->avail_in );
				
				DWORD nBlock = ( m_pBuffer->m_nBuffer - m_pBuffer->m_nLength ) - pStream->avail_out;
				m_pBuffer->m_nLength += nBlock;
				if ( ! nBlock ) break;
			}
		}
		else
		{
			m_pBuffer->AddBuffer( m_pInput, nVolume );
		}
	}
	
	switch ( m_nProtocol )
	{
	case 0:
		if ( ! StreamHTML() ) return FALSE;
		break;
	case PROTOCOL_G1:
		if ( ! StreamPacketsG1() ) return FALSE;
		break;
	case PROTOCOL_G2:
		if ( ! StreamPacketsG2() ) return FALSE;
		break;
	}
	
	if ( m_nReceived < m_nLength ) return TRUE;
	
	Stop( TRUE );
	
	if ( m_pProfile->IsValid() && m_pNotify != NULL ) m_pNotify->OnProfileReceived();
	
	theApp.Message( MSG_SYSTEM, IDS_BROWSE_FINISHED, (LPCTSTR)m_sAddress, m_nHits );
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CHostBrowser packet streaming

BOOL CHostBrowser::StreamPacketsG1()
{
	for ( BOOL bSuccess = TRUE ; bSuccess ; )
	{
		GNUTELLAPACKET* pPacket = (GNUTELLAPACKET*)m_pBuffer->m_pBuffer;
		if ( m_pBuffer->m_nLength < sizeof(*pPacket) ) break;
		
		DWORD nLength = sizeof(*pPacket) + pPacket->m_nLength;
		
		if ( pPacket->m_nLength < 0 || nLength >= (DWORD)Settings.Gnutella1.MaximumPacket * 8 )
		{
			theApp.Message( MSG_ERROR, IDS_BROWSE_PACKET_ERROR, (LPCTSTR)m_sAddress );
			Stop();
			return FALSE;
		}
		
		if ( m_pBuffer->m_nLength < nLength ) break;
		
		CG1Packet* pPacketObject = CG1Packet::New( pPacket );
		
		try
		{
			bSuccess = OnPacket( pPacketObject );
		}
		catch ( CException* pException )
		{
			pException->Delete();
		}
		
		pPacketObject->Release();
		
		m_pBuffer->Remove( nLength );
	}
	
	if ( ! bSuccess ) Stop();
	
	return bSuccess;
}

BOOL CHostBrowser::StreamPacketsG2()
{
	CG2Packet* pPacket;

	while ( pPacket = CG2Packet::ReadBuffer( m_pBuffer ) )
	{
		BOOL bSuccess = FALSE;
		
		try
		{
			bSuccess = OnPacket( pPacket );
		}
		catch ( CException* pException )
		{
			pException->Delete();
		}
		
		pPacket->Release();

		if ( ! bSuccess )
		{
			Stop();
			return FALSE;
		}
	}
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CHostBrowser packet interpreter

BOOL CHostBrowser::OnPacket(CG1Packet* pPacket)
{
	if ( pPacket->m_nType != G1_PACKET_HIT || pPacket->m_nLength <= 27 )
		return TRUE;
	
	CQueryHit* pHits = CQueryHit::FromPacket( pPacket );
	
	if ( pHits == NULL )
	{
		theApp.Message( MSG_ERROR, IDS_BROWSE_PACKET_ERROR, (LPCTSTR)m_sAddress );
		return FALSE;
	}
	
	m_bCanPush	= TRUE;
	m_pClientID	= pHits->m_pClientID;
	
	for ( CQueryHit* pCount = pHits ; pCount ; pCount = pCount->m_pNext ) m_nHits++;
	
	Downloads.OnQueryHits( pHits );
	
	if ( ! m_bCanChat && pHits->m_bChat ) m_bCanChat = TRUE;
	
	if ( m_pNotify != NULL )
		m_pNotify->OnBrowseHits( pHits );
	else
		pHits->Delete();
	
	return TRUE;
}

BOOL CHostBrowser::OnPacket(CG2Packet* pPacket)
{
	if ( pPacket->IsType( G2_PACKET_HIT ) )
	{
		CQueryHit* pHits = CQueryHit::FromPacket( pPacket );
		
		if ( pHits == NULL )
		{
			theApp.Message( MSG_ERROR, IDS_BROWSE_PACKET_ERROR, (LPCTSTR)m_sAddress );
			return FALSE;
		}
		
		m_bCanPush	= TRUE;
		m_pClientID	= pHits->m_pClientID;
		
		for ( CQueryHit* pCount = pHits ; pCount ; pCount = pCount->m_pNext )
		{
			m_nHits++;
		}
		
		Downloads.OnQueryHits( pHits );
		
		if ( ! m_bCanChat && pHits->m_bChat )
		{
			m_bCanChat = TRUE;
			if ( m_pNotify && m_pProfile != NULL ) m_pNotify->OnProfileReceived();
		}
		
		if ( m_pNotify != NULL )
			m_pNotify->OnBrowseHits( pHits );
		else
			pHits->Delete();
	}
	else if ( pPacket->IsType( G2_PACKET_PHYSICAL_FOLDER ) )
	{
		if ( m_pNotify != NULL ) m_pNotify->OnPhysicalTree( pPacket );
	}
	else if ( pPacket->IsType( G2_PACKET_VIRTUAL_FOLDER ) )
	{
		if ( m_pNotify != NULL ) m_pNotify->OnVirtualTree( pPacket );
	}
	else if ( pPacket->IsType( G2_PACKET_PROFILE_DELIVERY ) )
	{
		OnProfilePacket( pPacket );
		
		if ( m_pProfile != NULL && m_pNotify != NULL )
		{
			m_pNotify->OnProfileReceived();
		}
	}
	else if ( pPacket->IsType( G2_PACKET_PROFILE_AVATAR ) )
	{
		if ( m_pNotify != NULL ) m_pNotify->OnHeadPacket( pPacket );
	}
	
	return TRUE;
}

void CHostBrowser::OnProfilePacket(CG2Packet* pPacket)
{
	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 )
			{
				if ( m_pProfile == NULL ) m_pProfile = new CGProfile();
				if ( ! m_pProfile->FromXML( pXML ) ) delete pXML;
				if ( m_pProfile != NULL && ! m_pProfile->IsValid() )
				{
					delete m_pProfile;
					m_pProfile = NULL;
				}
			}
		}
		
		pPacket->m_nPosition = nOffset;
	}
}

//////////////////////////////////////////////////////////////////////
// CHostBrowser HTML streaming

BOOL CHostBrowser::StreamHTML()
{
	CString strLine;
	
	CQueryHit* pHits = NULL;
	
	while ( m_pBuffer->ReadLine( strLine ) )
	{
		if ( Settings.General.Debug && ( GetAsyncKeyState( VK_SHIFT ) & 0x8000 ) )
		{
			theApp.Message( MSG_DEBUG, _T("HTML-BROWSE: %s"), (LPCTSTR)strLine );
		}
		
		int nPosHTTP = strLine.Find( _T("http://") );
		
		while ( nPosHTTP >= 0 && strLine.Find( _T("/get/") ) > nPosHTTP )
		{
			CString strURI = strLine.Mid( nPosHTTP ).SpanExcluding( _T("?&\"'<>") );
			CString strName;
			DWORD nSize = 0;
			
			int nPosSize = strLine.Find( _T("<TD NOWRAP>") );
			
			if ( nPosSize >= 0 && nPosSize < nPosHTTP )
			{
				CString strSize = strLine.Mid( nPosSize + 11 ).SpanExcluding( _T("</") );
				float nFloat = 0;
				
				if ( _stscanf( strSize, _T("%f"), &nFloat ) == 1 && nFloat > 0 )
				{
					if ( strSize.Find( _T(" GB") ) >= 0 )
						nFloat *= 1024*1024*1024;
					else if ( strSize.Find( _T(" MB") ) >= 0 )
						nFloat *= 1024*1024;
					else if ( strSize.Find( _T(" KB") ) >= 0 )
						nFloat *= 1024;
					
					nSize = (DWORD)nFloat;
				}
			}
			
			strLine = strLine.Mid( nPosHTTP + strURI.GetLength() );
			
			int nPosName = strLine.Find( _T(">") );
			
			if ( nPosName >= 0 )
			{
				strName = strLine.Mid( nPosName + 1 ).SpanExcluding( _T("<>") );
			}
			
			if ( strName.IsEmpty() && ( nPosName = strURI.ReverseFind( '/' ) ) > 0 )
			{
				strName = URLDecode( strURI.Mid( nPosName + 1 ) );
			}
			
			CQueryHit* pHit = new CQueryHit( PROTOCOL_NULL, NULL );
			
			pHit->m_pAddress	= m_pHost.sin_addr;
			pHit->m_nPort		= htons( m_pHost.sin_port );
			pHit->m_pVendor		= m_pVendor ? m_pVendor : VendorCache.m_pNull;
			pHit->m_bPush		= ( m_tPushed ) ? TS_TRUE : TS_FALSE;
			pHit->m_bBrowseHost	= TRUE;
			pHit->m_nSize		= nSize;
			pHit->m_sName		= strName;
			pHit->m_sURL		= strURI;
			
			if ( m_bCanPush ) pHit->m_pClientID = m_pClientID;
			
			pHit->m_pNext = pHits;
			pHits = pHit;
			
			m_nHits ++;
			
			nPosHTTP = strLine.Find( _T("http://") );
		}
	}
	
	if ( pHits != NULL )
	{
		if ( m_pNotify != NULL )
			m_pNotify->OnBrowseHits( pHits );
		else
			pHits->Delete();
	}
	
	return TRUE;
}

⌨️ 快捷键说明

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