📄 localsearch.cpp
字号:
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 + -