📄 queryhit.cpp
字号:
pLastHit->m_bStable = bStable ? TS_TRUE : TS_FALSE;
pLastHit->m_bMeasured = pLastHit->m_bStable;
pLastHit->m_nUpSlots = nGroupState[ pLastHit->m_nGroup ][2];
pLastHit->m_nUpQueue = nGroupState[ pLastHit->m_nGroup ][1];
pLastHit->m_bChat = bPeerChat;
pLastHit->m_bBrowseHost = bBrowseHost;
pLastHit->m_sNick = strNick;
pLastHit->m_bPreview &= pLastHit->m_bPush == TS_FALSE;
if ( pLastHit->m_nUpSlots > 0 )
{
pLastHit->m_bBusy = ( pLastHit->m_nUpSlots <= pLastHit->m_nUpQueue ) ? TS_TRUE : TS_FALSE;
}
pLastHit->Resolve();
if ( pXML ) pLastHit->ParseXML( pXML, nIndex );
}
CheckBogus( pFirstHit );
}
catch ( CException* pException )
{
pException->Delete();
if ( pXML ) delete pXML;
if ( pFirstHit ) pFirstHit->Delete();
return NULL;
}
if ( pXML ) delete pXML;
return pFirstHit;
}
//////////////////////////////////////////////////////////////////////
// CQueryHit from ED2K packet
CQueryHit* CQueryHit::FromPacket(CEDPacket* pPacket, SOCKADDR_IN* pServer, GGUID* pSearchID)
{
CQueryHit* pFirstHit = NULL;
CQueryHit* pLastHit = NULL;
MD4 pHash;
if ( pPacket->m_nType == ED2K_S2C_SEARCHRESULTS ||
pPacket->m_nType == ED2K_S2CG_SEARCHRESULT )
{
DWORD nCount = 1;
if ( pPacket->m_nType == ED2K_S2C_SEARCHRESULTS )
{
if ( pPacket->GetRemaining() < 4 ) return NULL;
nCount = pPacket->ReadLongLE();
}
while ( nCount-- > 0 && pPacket->GetRemaining() >= sizeof(MD4) + 10 )
{
CQueryHit* pHit = new CQueryHit( PROTOCOL_ED2K, pSearchID );
if ( pFirstHit ) pLastHit->m_pNext = pHit;
else pFirstHit = pHit;
pLastHit = pHit;
pHit->m_pVendor = VendorCache.m_pED2K;
if ( ! pHit->ReadEDPacket( pPacket, pServer ) ) break;
pHit->Resolve();
}
}
else if ( pPacket->m_nType == ED2K_S2C_FOUNDSOURCES ||
pPacket->m_nType == ED2K_S2CG_FOUNDSOURCES )
{
if ( pPacket->GetRemaining() < sizeof(MD4) + 1 ) return NULL;
pPacket->Read( &pHash, sizeof(MD4) );
BYTE nCount = pPacket->ReadByte();
while ( nCount-- > 0 && pPacket->GetRemaining() >= 6 )
{
CQueryHit* pHit = new CQueryHit( PROTOCOL_ED2K, pSearchID );
if ( pFirstHit ) pLastHit->m_pNext = pHit;
else pFirstHit = pHit;
pLastHit = pHit;
pHit->m_bED2K = TRUE;
pHit->m_pED2K = pHash;
pHit->m_pVendor = VendorCache.m_pED2K;
pHit->ReadEDAddress( pPacket, pServer );
pHit->Resolve();
}
}
// CheckBogus( pFirstHit );
return pFirstHit;
}
//////////////////////////////////////////////////////////////////////
// CQueryHit bogus checking
BOOL CQueryHit::CheckBogus(CQueryHit* pFirstHit)
{
CString strBase, strTest;
int nBogus = 0;
if ( pFirstHit == NULL ) return TRUE;
for ( CQueryHit* pHit = pFirstHit->m_pNext ; pHit ; pHit = pHit->m_pNext )
{
LPCTSTR pszBase = pFirstHit->m_sName;
LPCTSTR pszTest = pHit->m_sName;
if ( *pszBase == 0 || *pszTest == 0 ) continue;
BOOL bDots = FALSE;
BOOL bDiff = FALSE;
while ( TRUE )
{
while ( *pszBase && ( *pszBase == '!' || *pszBase == '@' || ! _istgraph( *pszBase ) ) ) pszBase++;
while ( *pszTest && ( *pszTest == '!' || *pszTest == '@' || ! _istgraph( *pszTest ) ) ) pszTest++;
if ( ! *pszBase || ! *pszTest ) break;
if ( *pszBase == '.' || *pszTest == '.' )
{
bDots = TRUE;
if ( *pszBase == '.' && *pszTest == '.' )
{
if ( bDiff )
{
bDiff = FALSE;
break;
}
}
else
{
bDiff = FALSE;
break;
}
}
if ( ! bDiff && tolower( *pszBase ) != tolower( *pszTest ) ) bDiff = TRUE;
pszBase++;
pszTest++;
}
if ( bDots && bDiff )
{
if ( ++nBogus >= 2 ) break;
}
}
if ( nBogus < 2 ) return FALSE;
for ( pHit = pFirstHit ; pHit ; pHit = pHit->m_pNext )
{
pHit->m_bBogus = TRUE;
}
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CQueryHit XML metadata reader
CXMLElement* CQueryHit::ReadXML(CG1Packet* pPacket, int nSize)
{
BYTE* pRaw = new BYTE[ nSize ];
pPacket->Read( pRaw, nSize );
CString strXML;
if ( nSize >= 9 && strncmp( (LPCSTR)pRaw, "{deflate}", 9 ) == 0 )
{
BYTE* pText = (BYTE*)CZLib::Decompress( pRaw + 9, nSize - 10, (DWORD*)&nSize );
if ( pText != NULL )
{
LPTSTR pOut = strXML.GetBuffer( nSize );
for ( int nPos = 0 ; nPos < nSize ; nPos++ ) pOut[ nPos ] = (TCHAR)pText[ nPos ];
strXML.ReleaseBuffer( nSize );
delete [] pText;
}
}
else if ( nSize >= 11 && strncmp( (LPCSTR)pRaw, "{plaintext}", 11 ) == 0 )
{
LPCSTR pszRaw = (LPCSTR)pRaw + 11;
if ( strlen( pszRaw ) == (DWORD)nSize - 12 ) strXML = pszRaw;
}
else
{
LPCSTR pszRaw = (LPCSTR)pRaw;
if ( strlen( pszRaw ) == (DWORD)nSize - 1 ) strXML = pszRaw;
}
delete [] pRaw;
CXMLElement* pRoot = NULL;
LPCTSTR pszXML = strXML;
while ( pszXML && *pszXML )
{
CXMLElement* pXML = CXMLElement::FromString( pszXML, TRUE );
if ( ! pXML ) break;
if ( ! pRoot ) pRoot = new CXMLElement( NULL, _T("Metadata") );
pRoot->AddElement( pXML );
pszXML = _tcsstr( pszXML + 1, _T("<?xml") );
}
return pRoot;
}
//////////////////////////////////////////////////////////////////////
// CQueryHit GGEP reader
BOOL CQueryHit::ReadGGEP(CG1Packet* pPacket, BOOL* pbBrowseHost)
{
CGGEPBlock pGGEP;
if ( ! pGGEP.ReadFromPacket( pPacket ) ) return FALSE;
if ( pGGEP.Find( _T("BH") ) ) *pbBrowseHost = TRUE;
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CQueryHit G1 result entry reader
void CQueryHit::ReadG1Packet(CG1Packet* pPacket)
{
CString strData;
m_nIndex = pPacket->ReadLongLE();
m_bSize = TRUE;
m_nSize = pPacket->ReadLongLE();
m_sName = pPacket->ReadString();
strData = pPacket->ReadString();
if ( m_sName.GetLength() > 160 )
{
m_bBogus = TRUE;
}
else
{
int nCurWord = 0, nMaxWord = 0;
for ( LPCTSTR pszName = m_sName ; *pszName ; pszName++ )
{
if ( _istgraph( *pszName ) )
{
nCurWord++;
nMaxWord = max( nMaxWord, nCurWord );
}
else
{
nCurWord = 0;
}
}
if ( nMaxWord > 30 ) m_bBogus = TRUE;
}
LPCTSTR pszData = strData;
LPCTSTR pszEnd = pszData + _tcslen( pszData );
while ( *pszData && pszData < pszEnd )
{
if ( (BYTE)*pszData == GGEP_MAGIC )
{
if ( ! Settings.Gnutella1.EnableGGEP ) break;
CGGEPBlock pGGEP;
pGGEP.ReadFromString( pszData );
if ( CGGEPItem* pItem = pGGEP.Find( _T("H"), 21 ) )
{
if ( pItem->m_pBuffer[0] > 0 && pItem->m_pBuffer[0] < 3 )
{
CopyMemory( &m_pSHA1, &pItem->m_pBuffer[1], 20 );
m_bSHA1 = TRUE;
}
if ( pItem->m_pBuffer[0] == 2 && pItem->m_nLength >= 24 + 20 + 1 )
{
CopyMemory( &m_pTiger, &pItem->m_pBuffer[21], 24 );
m_bTiger = TRUE;
}
}
else if ( CGGEPItem* pItem = pGGEP.Find( _T("u"), 5 + 32 ) )
{
strData = pItem->ToString();
m_bSHA1 |= CSHA::HashFromURN( strData, &m_pSHA1 );
m_bTiger |= CTigerNode::HashFromURN( strData, &m_pTiger );
m_bED2K |= CED2K::HashFromURN( strData, &m_pED2K );
}
break;
}
LPCTSTR pszSep = _tcschr( pszData, 0x1C );
int nLength = pszSep ? pszSep - pszData : _tcslen( pszData );
if ( _tcsncmp( pszData, _T("urn:"), 4 ) == 0 )
{
m_bSHA1 |= CSHA::HashFromURN( pszData, &m_pSHA1 );
m_bTiger |= CTigerNode::HashFromURN( pszData, &m_pTiger );
m_bED2K |= CED2K::HashFromURN( pszData, &m_pED2K );
}
else if ( nLength > 4 )
{
AutoDetectSchema( pszData );
}
if ( pszSep ) pszData = pszSep + 1;
else break;
}
}
//////////////////////////////////////////////////////////////////////
// CQueryHit G1 attributes suffix
void CQueryHit::ParseAttributes(GGUID* pClientID, CVendor* pVendor, BYTE* nFlags, BOOL bChat, BOOL bBrowseHost)
{
m_pClientID = *pClientID;
m_pVendor = pVendor;
m_bChat = bChat;
m_bBrowseHost = bBrowseHost;
if ( nFlags[1] & G1_QHD_PUSH )
m_bPush = ( nFlags[0] & G1_QHD_PUSH ) ? TS_TRUE : TS_FALSE;
if ( nFlags[0] & G1_QHD_BUSY )
m_bBusy = ( nFlags[1] & G1_QHD_BUSY ) ? TS_TRUE : TS_FALSE;
if ( nFlags[0] & G1_QHD_STABLE )
m_bStable = ( nFlags[1] & G1_QHD_STABLE ) ? TS_TRUE : TS_FALSE;
if ( nFlags[0] & G1_QHD_SPEED )
m_bMeasured = ( nFlags[1] & G1_QHD_SPEED ) ? TS_TRUE : TS_FALSE;
}
//////////////////////////////////////////////////////////////////////
// CQueryHit G2 result entry reader
void CQueryHit::ReadG2Packet(CG2Packet* pPacket, DWORD nLength)
{
DWORD nPacket, nEnd = pPacket->m_nPosition + nLength;
CHAR szType[9];
m_bResolveURL = FALSE;
while ( pPacket->m_nPosition < nEnd && pPacket->ReadPacket( szType, nPacket ) )
{
DWORD nSkip = pPacket->m_nPosition + nPacket;
if ( strcmp( szType, "URN" ) == 0 )
{
CString strURN = pPacket->ReadString( nPacket );
if ( strURN.GetLength() + 1 >= (int)nPacket ) AfxThrowUserException();
nPacket -= strURN.GetLength() + 1;
if ( nPacket >= 20 && strURN == _T("sha1") )
{
m_bSHA1 = TRUE;
pPacket->Read( &m_pSHA1, sizeof(SHA1) );
}
else if ( nPacket >= 44 && ( strURN == _T("bp") || strURN == _T("bitprint") ) )
{
m_bSHA1 = TRUE;
pPacket->Read( &m_pSHA1, sizeof(SHA1) );
m_bTiger = TRUE;
pPacket->Read( &m_pTiger, sizeof(TIGEROOT) );
}
else if ( nPacket >= 24 && ( strURN == _T("ttr") || strURN == _T("tree:tiger/") ) )
{
m_bTiger = TRUE;
pPacket->Read( &m_pTiger, sizeof(TIGEROOT) );
}
else if ( nPacket >= 16 && strURN == _T("ed2k") )
{
m_bED2K = TRUE;
pPacket->Read( &m_pED2K, sizeof(MD4) );
}
else if ( nPacket >= 20 && strURN == _T("btih") )
{
m_bBTH = TRUE;
pPacket->Read( &m_pBTH, sizeof(SHA1) );
}
}
else if ( strcmp( szType, "URL" ) == 0 )
{
if ( nPacket == 0 )
{
m_bResolveURL = TRUE;
}
else
{
m_sURL = pPacket->ReadString( nPacket );
}
}
else if ( strcmp( szType, "DN" ) == 0 )
{
if ( m_bSize )
{
m_sName = pPacket->ReadString( nPacket );
}
else if ( nPacket > 4 )
{
m_bSize = TRUE;
m_nSize = pPacket->ReadLongBE();
m_sName = pPacket->ReadString( nPacket - 4 );
}
}
else if ( strcmp( szType, "MD" ) == 0 && nPacket > 0 )
{
CString strXML = pPacket->ReadString( nPacket );
if ( CXMLElement* pXML = CXMLElement::FromString( strXML ) )
{
if ( CXMLAttribute* pURI = pXML->GetAttribute( CXMLAttribute::schemaName ) )
{
m_sSchemaPlural = pXML->GetName();
m_sSchemaURI = pURI->GetValue();
CXMLElement* pChild = pXML->GetFirstElement();
if ( pChild != NULL && m_sSchemaPlural.GetLength() > 0 && m_sSchemaURI.GetLength() > 0 )
{
m_pXML->Delete();
m_pXML = pChild->Detach();
}
}
else if ( CSchema* pSchema = SchemaCache.Guess( pXML->GetName() ) )
{
m_pXML->Delete();
m_sSchemaPlural = pSchema->m_sPlural;
m_sSchemaURI = pSchema->m_sURI;
m_pXML = pXML;
pXML = NULL;
}
pXML->Delete();
}
}
else if ( strcmp( szType, "SZ" ) == 0 )
{
if ( nPacket == 4 )
{
m_bSize = TRUE;
m_nSize = pPacket->ReadLongBE();
}
else if ( nPacket == 8 )
{
m_bSize = TRUE;
m_nSize = pPacket->ReadInt64();
}
}
else if ( strcmp( szType, "G" ) == 0 && nPacket >= 1 )
{
m_nGroup = pPacket->ReadByte();
if ( m_nGroup < 0 ) m_nGroup = 0;
if ( m_nGroup > 7 ) m_nGroup = 7;
}
else if ( strcmp( szType, "ID" ) == 0 && nPacket >= 4 )
{
m_nIndex = pPacket->ReadLongBE();
}
else if ( strcmp( szType, "CSC" ) == 0 && nPacket >= 2 )
{
m_nSources = pPacket->ReadShortBE();
}
else if ( strcmp( szType, "PART" ) == 0 && nPacket >= 4 )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -