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

📄 localsearch.cpp

📁 p2p软件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		nGroup += 5 + 5 + sizeof(SHA1);
	}
	
	if ( m_pSearch->m_bWantDN )
	{
		nGroup += 8 + pPacket->GetStringLen( pDownload->m_sRemoteName );
	}
	
	if ( m_pSearch->m_bWantURL )
	{
		nGroup += 5;
		
		// if ( m_pSearch->m_bBTH && pDownload->m_pTorrent.IsAvailable() && Network.IsListening() )
		
		if ( m_pSearch->m_bBTH && pDownload->m_pTorrent.IsAvailable() && Network.m_pHost.sin_addr.S_un.S_addr != 0 )
		{
			strURL.Format( _T("btc://%s:%i/%s/%s/"),
				(LPCTSTR)CString( inet_ntoa( Network.m_pHost.sin_addr ) ),
				htons( Network.m_pHost.sin_port ),
				(LPCTSTR)CSHA::HashToString( BTClients.GetGUID() ),
				(LPCTSTR)CSHA::HashToString( &pDownload->m_pBTH ) );
			nGroup += pPacket->GetStringLen( strURL );
		}
	}
	
	pPacket->WritePacket( "H", nGroup, TRUE );
	
	if ( pDownload->m_bTiger && pDownload->m_bSHA1 )
	{
		pPacket->WritePacket( "URN", 3 + sizeof(SHA1) + sizeof(TIGEROOT) );
		pPacket->WriteString( "bp" );
		pPacket->Write( &pDownload->m_pSHA1, sizeof(SHA1) );
		pPacket->Write( &pDownload->m_pTiger, sizeof(TIGEROOT) );
	}
	else if ( pDownload->m_bTiger )
	{
		pPacket->WritePacket( "URN", 4 + sizeof(TIGEROOT) );
		pPacket->WriteString( "ttr" );
		pPacket->Write( &pDownload->m_pTiger, sizeof(TIGEROOT) );
	}
	else if ( pDownload->m_bSHA1 )
	{
		pPacket->WritePacket( "URN", 5 + sizeof(SHA1) );
		pPacket->WriteString( "sha1" );
		pPacket->Write( &pDownload->m_pSHA1, sizeof(SHA1) );
	}
	
	if ( pDownload->m_bED2K )
	{
		pPacket->WritePacket( "URN", 5 + sizeof(MD4) );
		pPacket->WriteString( "ed2k" );
		pPacket->Write( &pDownload->m_pED2K, sizeof(MD4) );
	}
	
	if ( pDownload->m_bBTH )
	{
		pPacket->WritePacket( "URN", 5 + sizeof(SHA1) );
		pPacket->WriteString( "btih" );
		pPacket->Write( &pDownload->m_pBTH, sizeof(SHA1) );
	}
	
	if ( m_pSearch->m_bWantDN )
	{
		if ( pDownload->m_nSize <= 0xFFFFFFFF )
		{
			pPacket->WritePacket( "DN", pPacket->GetStringLen( pDownload->m_sRemoteName ) + 4 );
			pPacket->WriteLongBE( (DWORD)pDownload->m_nSize );
			pPacket->WriteString( pDownload->m_sRemoteName, FALSE );
		}
		else
		{
			pPacket->WritePacket( "SZ", 8 );
			pPacket->WriteInt64( pDownload->m_nSize );
			pPacket->WritePacket( "DN", pPacket->GetStringLen( pDownload->m_sRemoteName ) );
			pPacket->WriteString( pDownload->m_sRemoteName, FALSE );
		}
	}
	
	if ( m_pSearch->m_bWantURL )
	{
		if ( strURL.GetLength() > 0 )
		{
			pPacket->WritePacket( "URL", pPacket->GetStringLen( strURL ) );
			pPacket->WriteString( strURL, FALSE );
		}
		else
		{
			pPacket->WritePacket( "URL", 0 );
		}
	}
	
	QWORD nComplete = pDownload->GetVolumeComplete();
	
	if ( nComplete <= 0xFFFFFFFF )
	{
		pPacket->WritePacket( "PART", 4 );
		pPacket->WriteLongBE( (DWORD)nComplete );
	}
	else
	{
		pPacket->WritePacket( "PART", 8 );
		pPacket->WriteInt64( nComplete );
	}
}

//////////////////////////////////////////////////////////////////////
// CLocalSearch create packet

void CLocalSearch::CreatePacket(int nCount)
{
	ASSERT( m_pPacket == NULL );
	
	if ( m_nProtocol == PROTOCOL_G1 )
		CreatePacketG1( nCount );
	else
		CreatePacketG2();
	
	if ( m_pSchemas.GetCount() ) GetXMLString();
}

void CLocalSearch::CreatePacketG1(int nCount)
{
	m_pPacket = CG1Packet::New( G1_PACKET_HIT, m_nTTL, &m_pGUID );
	
	m_pPacket->WriteByte( nCount );
	m_pPacket->WriteShortLE( htons( Network.m_pHost.sin_port ) );
	m_pPacket->WriteLongLE( Network.m_pHost.sin_addr.S_un.S_addr );

	if ( Uploads.m_bStable )
	{
		m_pPacket->WriteLongLE( Uploads.m_nBestSpeed * 8 / 1024 );
	}
	else
	{
		m_pPacket->WriteLongLE( Settings.Connection.OutSpeed );
	}
}

void CLocalSearch::CreatePacketG2()
{
	CG2Packet* pPacket = CG2Packet::New( G2_PACKET_HIT, TRUE );
	m_pPacket = pPacket;
	
	pPacket->WritePacket( "GU", 16 );
	pPacket->Write( &MyProfile.GUID, sizeof(GGUID) );
	
	if ( TRUE /* Network.IsListening() */ )
	{
		pPacket->WritePacket( "NA", 6 );
		pPacket->WriteLongLE( Network.m_pHost.sin_addr.S_un.S_addr );
		pPacket->WriteShortBE( htons( Network.m_pHost.sin_port ) );
	}
	
	pPacket->WritePacket( "V", 4 );
	pPacket->WriteString( SHAREAZA_VENDOR_A, FALSE );
	
	if ( ! Network.IsStable() || ! Datagrams.IsStable() )
	{
		pPacket->WritePacket( "FW", 0 );
	}
	
	{
		CSingleLock pNetLock( &Network.m_pSection );
		
		if ( pNetLock.Lock( 50 ) )
		{
			for ( POSITION pos = Neighbours.GetIterator() ; pos ; )
			{
				CNeighbour* pNeighbour = Neighbours.GetNext( pos );
				
				if ( pNeighbour->m_nNodeType != ntLeaf &&
					 pNeighbour->m_nProtocol == PROTOCOL_G2 )
				{
					pPacket->WritePacket( "NH", 6 );
					pPacket->WriteLongLE( pNeighbour->m_pHost.sin_addr.S_un.S_addr );
					pPacket->WriteShortBE( htons( pNeighbour->m_pHost.sin_port ) );
				}
			}
		}
	}
	
	if ( ! Uploads.m_bStable ) pPacket->WritePacket( "UNSTA", 0 );
	
	CSingleLock pQueueLock( &UploadQueues.m_pSection );
	int nQueue = 1;
	
	if ( pQueueLock.Lock() )
	{
		for ( POSITION pos = UploadQueues.GetIterator() ; pos ; nQueue++ )
		{
			CUploadQueue* pQueue = UploadQueues.GetNext( pos );
			pPacket->WritePacket( "HG", ( 4 + 7 ) + 2, TRUE );
			pPacket->WritePacket( "SS", 7 );
			pPacket->WriteShortBE( pQueue->GetQueuedCount() + pQueue->GetTransferCount() );
			pPacket->WriteByte( pQueue->GetTransferCount( TRUE ) );
			pPacket->WriteLongBE( pQueue->GetPredictedBandwidth() * 8 / 1024 );
			pPacket->WriteByte( 0 );
			pPacket->WriteByte( nQueue );
		}
		
		pQueueLock.Unlock();
	}
	
	CString strNick = MyProfile.GetNick();
	if ( strNick.GetLength() > 32 ) strNick = strNick.Left( 32 );
	
	if ( strNick.GetLength() )
	{
		int nNick = pPacket->GetStringLen( strNick );
		pPacket->WritePacket( "UPRO", nNick + 6, TRUE );
		pPacket->WritePacket( "NICK", nNick );
		pPacket->WriteString( strNick, FALSE );
	}
	
	if ( Settings.Community.ServeProfile ) pPacket->WritePacket( "BUP", 0 );
	if ( Settings.Community.ServeFiles ) pPacket->WritePacket( "BH", 0 );
	if ( Settings.Community.ChatEnable ) pPacket->WritePacket( "PCH", 0 );
}

//////////////////////////////////////////////////////////////////////
// CLocalSearch meta data

void CLocalSearch::AddMetadata(CSchema* pSchema, CXMLElement* pXML, int nIndex)
{
	ASSERT( pSchema != NULL );
	ASSERT( pXML != NULL );
	ASSERT( pXML->GetParent() == NULL );
	
	CXMLElement* pGroup;
	
	if ( ! m_pSchemas.Lookup( pSchema, (void*&)pGroup ) )
	{
		pGroup = pSchema->Instantiate();
		m_pSchemas.SetAt( pSchema, pGroup );
	}
	
	CString strIndex;
	strIndex.Format( _T("%lu"), nIndex );
	
	pXML->AddAttribute( _T("index"), strIndex );
	pGroup->AddElement( pXML );
}

//////////////////////////////////////////////////////////////////////
// CLocalSearch XML to string

CString CLocalSearch::GetXMLString()
{
	CString strXML;
	
	for ( POSITION pos1 = m_pSchemas.GetStartPosition() ; pos1 ; )
	{
		CXMLElement* pGroup;
		CSchema* pSchema;
		
		m_pSchemas.GetNextAssoc( pos1, (void*&)pSchema, (void*&)pGroup );
		
		strXML += _T("<?xml version=\"1.0\"?>\r\n");
		pGroup->ToString( strXML, TRUE );
		
		for ( POSITION pos2 = pGroup->GetElementIterator() ; pos2 ; )
		{
			CXMLElement* pChild = pGroup->GetNextElement( pos2 );
			pChild->DeleteAttribute( _T("index") );
			pChild->Detach();
		}
		
		delete pGroup;
	}
	
	m_pSchemas.RemoveAll();
	
	return strXML;
}

//////////////////////////////////////////////////////////////////////
// CLocalSearch core trailer

void CLocalSearch::WriteTrailer()
{
	ASSERT( m_pPacket != NULL );
	
	if ( m_nProtocol == PROTOCOL_G1 )
		WriteTrailerG1();
	else
		WriteTrailerG2();
}

void CLocalSearch::WriteTrailerG1()
{
	m_pPacket->WriteString( SHAREAZA_VENDOR_T, FALSE );
	
	BYTE nFlags[2] = { 0, 0 };
	
	nFlags[0] |= G1_QHD_BUSY|G1_QHD_STABLE|G1_QHD_SPEED;
	nFlags[1] |= G1_QHD_PUSH;
	
	if ( ! Network.IsListening() ) nFlags[0] |= G1_QHD_PUSH;
	if ( Uploads.m_bStable ) nFlags[1] |= G1_QHD_STABLE;
	if ( Uploads.m_bStable ) nFlags[1] |= G1_QHD_SPEED;
	if ( ! UploadQueues.IsTransferAvailable() ) nFlags[1] |= G1_QHD_BUSY;
	
	if ( Settings.Community.ServeFiles && Settings.Gnutella1.EnableGGEP )
	{
		nFlags[0] |= G1_QHD_GGEP;
		nFlags[1] |= G1_QHD_GGEP;
	}
	
	CString strXML		= GetXMLString();
	DWORD nCompressed	= 0;
	BYTE* pCompressed	= NULL;
	
	m_pPacket->WriteByte( strXML.IsEmpty() ? 2 : 4 );
	m_pPacket->WriteByte( nFlags[0] );
	m_pPacket->WriteByte( nFlags[1] );
	
	LPSTR pszXML = NULL;
	int nXML = 0;
	
	if ( strXML.GetLength() > 0 )
	{
#ifdef _UNICODE
		nXML = WideCharToMultiByte( CP_ACP, 0, strXML, -1, NULL, 0, NULL, NULL );
		pszXML = new CHAR[ nXML ];
		WideCharToMultiByte( CP_ACP, 0, strXML, -1, pszXML, nXML, NULL, NULL );
		if ( nXML > 0 ) nXML --;
#else
		pszXML = (LPSTR)(LPCSTR)strXML;
		nXML = strlen(pszXML);
#endif
		
		pCompressed = CZLib::Compress( pszXML, nXML, &nCompressed );
		
		if ( nCompressed + 9 < (DWORD)nXML + 11 && pCompressed != NULL )
		{
			m_pPacket->WriteShortLE( (WORD)( nCompressed + 9 + 1 ) );
		}
		else
		{
			m_pPacket->WriteShortLE( nXML + 11 + 1 );
			if ( pCompressed != NULL ) delete [] pCompressed;
			pCompressed = NULL;
		}
	}
	
	m_pPacket->WriteByte( Settings.Community.ChatEnable ? 1 : 0 );
	
	if ( Settings.Community.ServeFiles && Settings.Gnutella1.EnableGGEP )
	{
		m_pPacket->WriteByte( GGEP_MAGIC );
		m_pPacket->WriteByte( GGEP_HDR_LAST | 2 );
		m_pPacket->WriteByte( 'B' );
		m_pPacket->WriteByte( 'H' );
		m_pPacket->WriteByte( GGEP_LEN_LAST );
	}
	
	if ( pCompressed != NULL )
	{
		m_pPacket->Write( "{deflate}", 9 );
		m_pPacket->Write( pCompressed, nCompressed );
		m_pPacket->WriteByte( 0 );
		delete [] pCompressed;
	}
	else if ( pszXML != NULL )
	{
		m_pPacket->Write( "{plaintext}", 11 );
		m_pPacket->Write( pszXML, nXML );
	}
	
#ifdef _UNICODE
	if ( pszXML != NULL ) delete [] pszXML;
#endif
	
	m_pPacket->Write( &MyProfile.GUID, sizeof(GGUID) );
}

void CLocalSearch::WriteTrailerG2()
{
	CG2Packet* pPacket = (CG2Packet*)m_pPacket;
	
	pPacket->WriteByte( 0 );
	pPacket->WriteByte( 0 );
	pPacket->Write( &m_pGUID, sizeof(GGUID) );
}

//////////////////////////////////////////////////////////////////////
// CLocalSearch dispatch packet

void CLocalSearch::DispatchPacket()
{
	ASSERT( m_pPacket != NULL );
	
	if ( m_pNeighbour != NULL )
	{
		if ( m_bWrapped )
		{
			CG2Packet* pG2 = CG2Packet::New( G2_PACKET_HIT_WRAP, (CG1Packet*)m_pPacket );
			m_pPacket->Release();
			m_pPacket = pG2;
		}
		
		m_pNeighbour->Send( m_pPacket, FALSE, TRUE );
	}
	
	if ( m_pEndpoint != NULL )
	{
		Datagrams.Send( m_pEndpoint, (CG2Packet*)m_pPacket, FALSE );
	}
	
	if ( m_pBuffer != NULL )
	{
		m_pPacket->ToBuffer( m_pBuffer );
	}
	
	m_pPacket->Release();
	m_pPacket = NULL;
}

void CLocalSearch::DestroyPacket()
{
	if ( m_pPacket != NULL )
	{
		m_pPacket->Release();
		m_pPacket = NULL;
	}
}

//////////////////////////////////////////////////////////////////////
// CLocalSearch physical and virtual folder tree

void CLocalSearch::WriteVirtualTree()
{
	if ( Library.Lock( 100 ) )
	{
		m_pPacket = AlbumToPacket( Library.GetAlbumRoot() );
		Library.Unlock();
		if ( m_pPacket != NULL ) DispatchPacket();
	}
	
	if ( Library.Lock( 100 ) )
	{
		m_pPacket = FoldersToPacket();
		Library.Unlock();
		if ( m_pPacket != NULL ) DispatchPacket();
	}
}

CG2Packet* CLocalSearch::AlbumToPacket(CAlbumFolder* pFolder)
{
	if ( pFolder == NULL ) return NULL;
	
	if ( pFolder->m_pSchema != NULL && pFolder->m_pSchema->m_bPrivate ) return NULL;
	if ( pFolder->GetSharedCount() == 0 ) return NULL;
	
	CG2Packet* pPacket = CG2Packet::New( "VF", TRUE );
	
	if ( pFolder->m_pSchema != NULL )
	{
		CXMLElement* pXML = pFolder->m_pSchema->Instantiate( TRUE );
		
		if ( pFolder->m_pXML != NULL )
		{
			pXML->AddElement( pFolder->m_pXML->Clone() );
		}
		else
		{
			CXMLElement* pBody = pXML->AddElement( pFolder->m_pSchema->m_sSingular );
			pBody->AddAttribute( pFolder->m_pSchema->GetFirstMemberName(), pFolder->m_sName );
		}
		
		CString strXML = pXML->ToString();
		delete pXML;
		
		pPacket->WritePacket( "MD", pPacket->GetStringLen( strXML ) );
		pPacket->WriteString( strXML, FALSE );
	}
	
	for ( POSITION pos = pFolder->GetFolderIterator() ; pos ; )
	{
		if ( CG2Packet* pChild = AlbumToPacket( pFolder->GetNextFolder( pos ) ) )
		{
			pPacket->WritePacket( pChild );
			pChild->Release();
		}
	}
	
	pPacket->WritePacket( "FILES", pFolder->GetFileCount() * 4 );
	
	for ( pos = pFolder->GetFileIterator() ; pos ; )
	{
		CLibraryFile* pFile = pFolder->GetNextFile( pos );
		pPacket->WriteLongBE( pFile->m_nIndex );
	}
	
	return pPacket;
}

CG2Packet* CLocalSearch::FoldersToPacket()
{
	CG2Packet* pPacket = CG2Packet::New( "PF", TRUE );
	
	for ( POSITION pos = LibraryFolders.GetFolderIterator() ; pos ; )
	{
		if ( CG2Packet* pChild = FolderToPacket( LibraryFolders.GetNextFolder( pos ) ) )
		{
			pPacket->WritePacket( pChild );
			pChild->Release();
		}
	}
	
	return pPacket;
}

CG2Packet* CLocalSearch::FolderToPacket(CLibraryFolder* pFolder)
{
	if ( pFolder == NULL ) return NULL;
	
	if ( pFolder->GetSharedCount() == 0 ) return NULL;
	
	CG2Packet* pPacket = CG2Packet::New( "PF", TRUE );
	
	pPacket->WritePacket( "DN", pPacket->GetStringLen( pFolder->m_sName ) );
	pPacket->WriteString( pFolder->m_sName, FALSE );
	
	for ( POSITION pos = pFolder->GetFolderIterator() ; pos ; )
	{
		if ( CG2Packet* pChild = FolderToPacket( pFolder->GetNextFolder( pos ) ) )
		{
			pPacket->WritePacket( pChild );
			pChild->Release();
		}
	}
	
	pPacket->WritePacket( "FILES", pFolder->GetFileCount() * 4 );
	
	for ( pos = pFolder->GetFileIterator() ; pos ; )
	{
		CLibraryFile* pFile = pFolder->GetNextFile( pos );
		pPacket->WriteLongBE( pFile->m_nIndex );
	}
	
	return pPacket;
}

⌨️ 快捷键说明

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