📄 queryhit.cpp
字号:
{
m_nPartial = pPacket->ReadLongBE();
}
else if ( strcmp( szType, "COM" ) == 0 )
{
CString strXML = pPacket->ReadString( nPacket );
if ( CXMLElement* pComment = CXMLElement::FromString( strXML ) )
{
m_nRating = -1;
_stscanf( pComment->GetAttributeValue( _T("rating") ), _T("%i"), &m_nRating );
m_nRating = max( 0, min( 6, m_nRating + 1 ) );
m_sComments = pComment->GetValue();
Replace( m_sComments, _T("{n}"), _T("\r\n") );
delete pComment;
}
}
else if ( strcmp( szType, "PVU" ) == 0 )
{
if ( nPacket == 0 )
{
m_bPreview = TRUE;
}
else
{
m_bPreview = TRUE;
m_sPreview = pPacket->ReadString( nPacket );
}
}
else if ( strcmp( szType, "BOGUS" ) == 0 )
{
m_bBogus = TRUE;
}
else if ( strcmp( szType, "COLLECT" ) == 0 )
{
m_bCollection = TRUE;
}
pPacket->m_nPosition = nSkip;
}
if ( ! m_bSHA1 && ! m_bTiger && ! m_bED2K && ! m_bBTH ) AfxThrowUserException();
}
//////////////////////////////////////////////////////////////////////
// CQueryHit ED2K result entry reader
BOOL CQueryHit::ReadEDPacket(CEDPacket* pPacket, SOCKADDR_IN* pServer)
{
m_bED2K = TRUE;
pPacket->Read( &m_pED2K, sizeof(MD4) );
ReadEDAddress( pPacket, pServer );
DWORD nTags = pPacket->ReadLongLE();
while ( nTags-- > 0 )
{
if ( pPacket->GetRemaining() < 1 ) return FALSE;
CEDTag pTag;
if ( ! pTag.Read( pPacket ) ) return FALSE;
if ( pTag.m_nKey == ED2K_FT_FILENAME && pTag.m_nType == ED2K_TAG_STRING )
{
m_sName = pTag.m_sValue;
}
else if ( pTag.m_nKey == ED2K_FT_FILESIZE && pTag.m_nType == ED2K_TAG_INT )
{
m_bSize = TRUE;
m_nSize = pTag.m_nValue;
}
else if ( pTag.m_nKey == ED2K_FT_SOURCES && pTag.m_nType == ED2K_TAG_INT )
{
m_nSources = pTag.m_nValue;
if ( m_nSources == 0 )
m_bResolveURL = FALSE;
else
m_nSources--;
}
}
return TRUE;
}
void CQueryHit::ReadEDAddress(CEDPacket* pPacket, SOCKADDR_IN* pServer)
{
DWORD nAddress = m_pAddress.S_un.S_addr = pPacket->ReadLongLE();
m_nPort = pPacket->ReadShortLE();
m_pClientID.w[0] = pServer->sin_addr.S_un.S_addr;
m_pClientID.w[1] = htons( pServer->sin_port );
m_pClientID.w[2] = nAddress;
m_pClientID.w[3] = m_nPort;
if ( nAddress == 0 )
{
m_bResolveURL = FALSE;
m_bPush = TS_UNKNOWN;
}
else if ( CEDPacket::IsLowID( nAddress ) || Network.IsFirewalledAddress( &nAddress ) || ! m_nPort )
{
m_bPush = TS_TRUE;
}
else
{
m_bPush = TS_FALSE;
}
}
//////////////////////////////////////////////////////////////////////
// CQueryHit resolve
void CQueryHit::Resolve()
{
if ( m_bPreview && m_bSHA1 && m_sPreview.IsEmpty() )
{
m_sPreview.Format( _T("http://%s:%i/gnutella/preview/v1?%s"),
(LPCTSTR)CString( inet_ntoa( m_pAddress ) ), m_nPort,
(LPCTSTR)CSHA::HashToString( &m_pSHA1, TRUE ) );
}
if ( m_sURL.GetLength() )
{
m_nSources ++;
return;
}
else if ( ! m_bResolveURL )
return;
m_nSources++;
if ( m_nProtocol == PROTOCOL_ED2K )
{
if ( m_bPush == TS_TRUE )
{
m_sURL.Format( _T("ed2kftp://%lu@%s:%i/%s/%I64i/"),
m_pClientID.w[2],
(LPCTSTR)CString( inet_ntoa( (IN_ADDR&)m_pClientID.w[0] ) ),
m_pClientID.w[1],
(LPCTSTR)CED2K::HashToString( &m_pED2K ), m_nSize );
}
else
{
m_sURL.Format( _T("ed2kftp://%s:%i/%s/%I64i/"),
(LPCTSTR)CString( inet_ntoa( m_pAddress ) ), m_nPort,
(LPCTSTR)CED2K::HashToString( &m_pED2K ), m_nSize );
}
return;
}
if ( m_nIndex == 0 || m_bTiger || m_bED2K || Settings.Downloads.RequestHash )
{
if ( m_bSHA1 )
{
m_sURL.Format( _T("http://%s:%i/uri-res/N2R?%s"),
(LPCTSTR)CString( inet_ntoa( m_pAddress ) ), m_nPort,
(LPCTSTR)CSHA::HashToString( &m_pSHA1, TRUE ) );
return;
}
else if ( m_bTiger )
{
m_sURL.Format( _T("http://%s:%i/uri-res/N2R?%s"),
(LPCTSTR)CString( inet_ntoa( m_pAddress ) ), m_nPort,
(LPCTSTR)CTigerNode::HashToString( &m_pTiger, TRUE ) );
return;
}
else if ( m_bED2K )
{
m_sURL.Format( _T("http://%s:%i/uri-res/N2R?%s"),
(LPCTSTR)CString( inet_ntoa( m_pAddress ) ), m_nPort,
(LPCTSTR)CED2K::HashToString( &m_pED2K, TRUE ) );
return;
}
}
if ( Settings.Downloads.RequestURLENC )
{
m_sURL.Format( _T("http://%s:%i/get/%lu/%s"),
(LPCTSTR)CString( inet_ntoa( m_pAddress ) ), m_nPort, m_nIndex,
(LPCTSTR)CTransfer::URLEncode( m_sName ) );
}
else
{
m_sURL.Format( _T("http://%s:%i/get/%lu/%s"),
(LPCTSTR)CString( inet_ntoa( m_pAddress ) ), m_nPort, m_nIndex,
(LPCTSTR)m_sName );
}
}
//////////////////////////////////////////////////////////////////////
// CQueryHit XML metadata suffix
BOOL CQueryHit::ParseXML(CXMLElement* pMetaData, DWORD nRealIndex)
{
CString strRealIndex;
strRealIndex.Format( _T("%i"), nRealIndex );
for ( POSITION pos1 = pMetaData->GetElementIterator() ; pos1 && ! m_pXML ; )
{
CXMLElement* pXML = pMetaData->GetNextElement( pos1 );
for ( POSITION pos2 = pXML->GetElementIterator() ; pos2 ; )
{
CXMLElement* pHit = pXML->GetNextElement( pos2 );
CXMLAttribute* pIndex = pHit->GetAttribute( _T("index") );
if ( pIndex != NULL && pIndex->GetValue() == strRealIndex )
{
m_sSchemaPlural = pXML->GetName();
m_sSchemaURI = pXML->GetAttributeValue( CXMLAttribute::schemaName, _T("") );
if ( m_sSchemaPlural.GetLength() > 0 && m_sSchemaURI.GetLength() > 0 )
{
if ( m_pXML ) delete m_pXML;
m_pXML = pHit->Detach();
pIndex->Delete();
}
break;
}
}
}
return m_pXML != NULL;
}
//////////////////////////////////////////////////////////////////////
// CQueryHit schema auto-detect
BOOL CQueryHit::AutoDetectSchema(LPCTSTR pszInfo)
{
if ( m_pXML ) return TRUE;
if ( _tcsstr( pszInfo, _T(" Kbps") ) != NULL && _tcsstr( pszInfo, _T(" kHz ") ) != NULL )
{
if ( AutoDetectAudio( pszInfo ) ) return TRUE;
}
return FALSE;
}
BOOL CQueryHit::AutoDetectAudio(LPCTSTR pszInfo)
{
int nBitrate = 0;
int nFrequency = 0;
int nMinutes = 0;
int nSeconds = 0;
BOOL bVariable = FALSE;
if ( _stscanf( pszInfo, _T("%i Kbps %i kHz %i:%i"), &nBitrate, &nFrequency,
&nMinutes, &nSeconds ) != 4 )
{
bVariable = TRUE;
if ( _stscanf( pszInfo, _T("%i Kbps(VBR) %i kHz %i:%i"), &nBitrate, &nFrequency,
&nMinutes, &nSeconds ) != 4 ) return FALSE;
}
m_sSchemaURI = CSchema::uriAudio;
m_pXML = new CXMLElement( NULL, _T("audio") );
CString strValue;
strValue.Format( _T("%lu"), nMinutes * 60 + nSeconds );
m_pXML->AddAttribute( _T("seconds"), strValue );
strValue.Format( bVariable ? _T("%lu~") : _T("%lu"), nBitrate );
m_pXML->AddAttribute( _T("bitrate"), strValue );
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CQueryHit copy and delete helpers
void CQueryHit::Copy(CQueryHit* pOther)
{
if ( m_pXML ) delete m_pXML;
m_pSearchID = pOther->m_pSearchID;
m_pClientID = pOther->m_pClientID;
m_pAddress = pOther->m_pAddress;
m_nPort = pOther->m_nPort;
m_nSpeed = pOther->m_nSpeed;
m_sSpeed = pOther->m_sSpeed;
m_pVendor = pOther->m_pVendor;
m_bPush = pOther->m_bPush;
m_bBusy = pOther->m_bBusy;
m_bStable = pOther->m_bStable;
m_bMeasured = pOther->m_bMeasured;
m_bChat = pOther->m_bChat;
m_bBrowseHost = pOther->m_bBrowseHost;
m_bSHA1 = pOther->m_bSHA1;
m_bTiger = pOther->m_bTiger;
m_bED2K = pOther->m_bED2K;
m_sURL = pOther->m_sURL;
m_sName = pOther->m_sName;
m_nIndex = pOther->m_nIndex;
m_bSize = pOther->m_bSize;
m_nSize = pOther->m_nSize;
m_sSchemaURI = pOther->m_sSchemaURI;
m_sSchemaPlural = pOther->m_sSchemaPlural;
m_pXML = pOther->m_pXML;
m_bMatched = pOther->m_bMatched;
m_bBogus = pOther->m_bBogus;
m_bFiltered = pOther->m_bFiltered;
m_bDownload = pOther->m_bDownload;
if ( m_bSHA1 ) m_pSHA1 = pOther->m_pSHA1;
if ( m_bTiger ) m_pTiger = pOther->m_pTiger;
if ( m_bED2K ) m_pED2K = pOther->m_pED2K;
pOther->m_pXML = NULL;
}
void CQueryHit::Delete()
{
for ( CQueryHit* pHit = this ; pHit ; )
{
CQueryHit* pNext = pHit->m_pNext;
delete pHit;
pHit = pNext;
}
}
//////////////////////////////////////////////////////////////////////
// CQueryHit rating
int CQueryHit::GetRating()
{
int nRating = 0;
if ( m_bPush != TS_TRUE ) nRating += 4;
if ( m_bBusy != TS_TRUE ) nRating += 2;
if ( m_bStable == TS_TRUE ) nRating ++;
return nRating;
}
//////////////////////////////////////////////////////////////////////
// CQueryHit serialize
void CQueryHit::Serialize(CArchive& ar, int nVersion)
{
if ( ar.IsStoring() )
{
ar.Write( &m_pSearchID, sizeof(GGUID) );
ar << m_nProtocol;
ar.Write( &m_pClientID, sizeof(GGUID) );
ar.Write( &m_pAddress, sizeof(IN_ADDR) );
ar << m_nPort;
ar << m_nSpeed;
ar << m_sSpeed;
ar << m_pVendor->m_sCode;
ar << m_bPush;
ar << m_bBusy;
ar << m_bStable;
ar << m_bMeasured;
ar << m_nUpSlots;
ar << m_nUpQueue;
ar << m_bChat;
ar << m_bBrowseHost;
ar << m_bSHA1;
if ( m_bSHA1 ) ar.Write( &m_pSHA1, sizeof(SHA1) );
ar << m_bTiger;
if ( m_bTiger ) ar.Write( &m_pTiger, sizeof(TIGEROOT) );
ar << m_bED2K;
if ( m_bED2K ) ar.Write( &m_pED2K, sizeof(MD4) );
ar << m_sURL;
ar << m_sName;
ar << m_nIndex;
ar << m_bSize;
ar << m_nSize;
ar << m_nSources;
ar << m_nPartial;
ar << m_bPreview;
ar << m_sPreview;
ar << m_bCollection;
if ( m_pXML == NULL ) m_sSchemaURI.Empty();
ar << m_sSchemaURI;
ar << m_sSchemaPlural;
if ( m_sSchemaURI.GetLength() ) m_pXML->Serialize( ar );
ar << m_nRating;
ar << m_sComments;
ar << m_bMatched;
ar << m_bBogus;
ar << m_bDownload;
}
else
{
ar.Read( &m_pSearchID, sizeof(GGUID) );
if ( nVersion >= 9 ) ar >> m_nProtocol;
ar.Read( &m_pClientID, sizeof(GGUID) );
ar.Read( &m_pAddress, sizeof(IN_ADDR) );
ar >> m_nPort;
ar >> m_nSpeed;
ar >> m_sSpeed;
ar >> m_sSchemaURI;
m_pVendor = VendorCache.Lookup( m_sSchemaURI );
ar >> m_bPush;
ar >> m_bBusy;
ar >> m_bStable;
ar >> m_bMeasured;
ar >> m_nUpSlots;
ar >> m_nUpQueue;
ar >> m_bChat;
ar >> m_bBrowseHost;
ar >> m_bSHA1;
if ( m_bSHA1 ) ar.Read( &m_pSHA1, sizeof(SHA1) );
ar >> m_bTiger;
if ( m_bTiger ) ar.Read( &m_pTiger, sizeof(TIGEROOT) );
ar >> m_bED2K;
if ( m_bED2K ) ar.Read( &m_pED2K, sizeof(MD4) );
ar >> m_sURL;
ar >> m_sName;
ar >> m_nIndex;
ar >> m_bSize;
if ( nVersion >= 10 )
{
ar >> m_nSize;
}
else
{
DWORD nSize;
ar >> nSize;
m_nSize = nSize;
}
ar >> m_nSources;
ar >> m_nPartial;
ar >> m_bPreview;
ar >> m_sPreview;
if ( nVersion >= 11 ) ar >> m_bCollection;
ar >> m_sSchemaURI;
ar >> m_sSchemaPlural;
if ( m_sSchemaURI.GetLength() )
{
m_pXML = new CXMLElement();
m_pXML->Serialize( ar );
}
ar >> m_nRating;
ar >> m_sComments;
ar >> m_bMatched;
ar >> m_bBogus;
ar >> m_bDownload;
if ( m_nSources == 0 && m_sURL.GetLength() ) m_nSources = 1;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -