📄 downloadwithsources.cpp
字号:
//
// DownloadWithSources.cpp
//
// Copyright (c) Shareaza Development Team, 2002-2004.
// This file is part of SHAREAZA (www.shareaza.com)
//
// Shareaza is free software; you can redistribute it
// and/or modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Shareaza is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Shareaza; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
#include "StdAfx.h"
#include "Shareaza.h"
#include "Settings.h"
#include "Downloads.h"
#include "DownloadWithSources.h"
#include "DownloadSource.h"
#include "Network.h"
#include "Neighbours.h"
#include "Transfer.h"
#include "QueryHit.h"
#include "SourceURL.h"
#include "Schema.h"
#include "SchemaCache.h"
#include "XML.h"
#include "SHA.h"
#include "MD4.h"
#include "TigerTree.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// CDownloadWithSources construction
CDownloadWithSources::CDownloadWithSources()
{
m_pSourceFirst = NULL;
m_pSourceLast = NULL;
m_nSourceCount = 0;
m_pXML = NULL;
}
CDownloadWithSources::~CDownloadWithSources()
{
ClearSources();
if ( m_pXML != NULL ) delete m_pXML;
}
//////////////////////////////////////////////////////////////////////
// CDownloadWithSources list access
int CDownloadWithSources::GetSourceCount(BOOL bNoPush, BOOL bSane) const
{
if ( ! bNoPush && ! bSane ) return m_nSourceCount;
DWORD tNow = GetTickCount();
int nCount = 0;
for ( CDownloadSource* pSource = m_pSourceFirst ; pSource ; pSource = pSource->m_pNext )
{
if ( ! bNoPush || ! pSource->m_bPushOnly )
{
if ( ! bSane ||
pSource->m_tAttempt < tNow ||
pSource->m_tAttempt - tNow <= 900000 )
{
nCount++;
}
}
}
return nCount;
}
BOOL CDownloadWithSources::CheckSource(CDownloadSource* pCheck) const
{
for ( CDownloadSource* pSource = m_pSourceFirst ; pSource ; pSource = pSource->m_pNext )
{
if ( pSource == pCheck ) return TRUE;
}
return FALSE;
}
//////////////////////////////////////////////////////////////////////
// CDownloadWithSources clear
void CDownloadWithSources::ClearSources()
{
for ( CDownloadSource* pSource = GetFirstSource() ; pSource ; )
{
CDownloadSource* pNext = pSource->m_pNext;
delete pSource;
pSource = pNext;
}
m_pSourceFirst = m_pSourceLast = NULL;
m_nSourceCount = 0;
SetModified();
}
//////////////////////////////////////////////////////////////////////
// CDownloadWithSources add a query-hit source
BOOL CDownloadWithSources::AddSourceHit(CQueryHit* pHit, BOOL bForce)
{
BOOL bHash = FALSE;
if ( ! bForce )
{
if ( m_bSHA1 && pHit->m_bSHA1 )
{
if ( m_pSHA1 != pHit->m_pSHA1 ) return FALSE;
bHash = TRUE;
}
else if ( m_bTiger && pHit->m_bTiger )
{
if ( m_pTiger != pHit->m_pTiger ) return FALSE;
bHash = TRUE;
}
if ( m_bED2K && pHit->m_bED2K )
{
if ( m_pED2K != pHit->m_pED2K ) return FALSE;
bHash = TRUE;
}
if ( m_bBTH && pHit->m_bBTH )
{
if ( m_pBTH != pHit->m_pBTH ) return FALSE;
bHash = TRUE;
}
}
if ( ! bHash && ! bForce )
{
if ( Settings.General.HashIntegrity ) return FALSE;
if ( m_sRemoteName.IsEmpty() || pHit->m_sName.IsEmpty() ) return FALSE;
if ( m_nSize == SIZE_UNKNOWN || ! pHit->m_bSize ) return FALSE;
if ( m_nSize != pHit->m_nSize ) return FALSE;
if ( m_sRemoteName.CompareNoCase( pHit->m_sName ) ) return FALSE;
}
if ( ! m_bSHA1 && pHit->m_bSHA1 )
{
m_bSHA1 = TRUE;
m_pSHA1 = pHit->m_pSHA1;
}
if ( ! m_bTiger && pHit->m_bTiger )
{
m_bTiger = TRUE;
m_pTiger = pHit->m_pTiger;
}
if ( ! m_bED2K && pHit->m_bED2K )
{
m_bED2K = TRUE;
m_pED2K = pHit->m_pED2K;
}
if ( m_nSize == SIZE_UNKNOWN && pHit->m_bSize )
{
m_nSize = pHit->m_nSize;
}
if ( m_sRemoteName.IsEmpty() && pHit->m_sName.GetLength() )
{
m_sRemoteName = pHit->m_sName;
}
if ( Settings.Downloads.Metadata && m_pXML == NULL )
{
if ( pHit->m_pXML != NULL && pHit->m_sSchemaPlural.GetLength() )
{
m_pXML = new CXMLElement( NULL, pHit->m_sSchemaPlural );
m_pXML->AddAttribute( _T("xmlns:xsi"), CXMLAttribute::xmlnsInstance );
m_pXML->AddAttribute( CXMLAttribute::schemaName, pHit->m_sSchemaURI );
m_pXML->AddElement( pHit->m_pXML->Clone() );
if ( CSchema* pSchema = SchemaCache.Get( pHit->m_sSchemaURI ) )
{
pSchema->Validate( m_pXML, TRUE );
}
}
}
if ( pHit->m_nProtocol == PROTOCOL_ED2K )
{
Neighbours.FindDonkeySources( &pHit->m_pED2K,
(IN_ADDR*)pHit->m_pClientID.w, (WORD)pHit->m_pClientID.w[1] );
}
// No URL, stop now with success
if ( pHit->m_sURL.IsEmpty() ) return TRUE;
return AddSourceInternal( new CDownloadSource( (CDownload*)this, pHit ) );
}
//////////////////////////////////////////////////////////////////////
// CDownloadWithSources add miscellaneous sources
BOOL CDownloadWithSources::AddSourceED2K(DWORD nClientID, WORD nClientPort, DWORD nServerIP, WORD nServerPort, GGUID* pGUID)
{
return AddSourceInternal( new CDownloadSource( (CDownload*)this, nClientID, nClientPort, nServerIP, nServerPort, pGUID ) );
}
BOOL CDownloadWithSources::AddSourceBT(SHA1* pGUID, IN_ADDR* pAddress, WORD nPort)
{
return AddSourceInternal( new CDownloadSource( (CDownload*)this, pGUID, pAddress, nPort ) );
}
//////////////////////////////////////////////////////////////////////
// CDownloadWithSources add a single URL source
BOOL CDownloadWithSources::AddSourceURL(LPCTSTR pszURL, BOOL bURN, FILETIME* pLastSeen)
{
if ( pszURL == NULL ) return FALSE;
if ( *pszURL == 0 ) return FALSE;
BOOL bHashAuth = FALSE;
CSourceURL pURL;
if ( *pszURL == '@' )
{
bHashAuth = TRUE;
pszURL++;
}
if ( ! pURL.Parse( pszURL ) ) return FALSE;
if ( bURN )
{
if ( pURL.m_pAddress.S_un.S_addr == Network.m_pHost.sin_addr.S_un.S_addr ) return FALSE;
if ( Network.IsFirewalledAddress( &pURL.m_pAddress, TRUE ) ) return FALSE;
}
if ( m_pFailedSources.Find( pszURL ) != NULL ) return FALSE;
if ( pURL.m_bSHA1 && m_bSHA1 )
{
if ( m_pSHA1 != pURL.m_pSHA1 ) return FALSE;
}
if ( m_sRemoteName.IsEmpty() && _tcslen( pszURL ) > 9 )
{
m_sRemoteName = &pszURL[8];
int nPos = m_sRemoteName.ReverseFind( '/' );
if ( nPos >= 0 )
{
m_sRemoteName = m_sRemoteName.Mid( nPos + 1 ).SpanExcluding( _T("?") );
m_sRemoteName = CTransfer::URLDecode( m_sRemoteName );
}
else
{
m_sRemoteName.Empty();
}
if ( m_sRemoteName.IsEmpty() ) m_sRemoteName = _T("default.htm");
}
return AddSourceInternal( new CDownloadSource( (CDownload*)this, pszURL, bURN, bHashAuth, pLastSeen ) );
}
//////////////////////////////////////////////////////////////////////
// CDownloadWithSources add several URL sources
int CDownloadWithSources::AddSourceURLs(LPCTSTR pszURLs, BOOL bURN)
{
CString strURLs( pszURLs );
BOOL bQuote = FALSE;
for ( int nScan = 0 ; nScan < strURLs.GetLength() ; nScan++ )
{
if ( strURLs[ nScan ] == '\"' )
{
bQuote = ! bQuote;
strURLs.SetAt( nScan, ' ' );
}
else if ( strURLs[ nScan ] == ',' && bQuote )
{
strURLs.SetAt( nScan, '`' );
}
}
strURLs += ',';
for ( int nCount = 0 ; ; )
{
int nPos = strURLs.Find( ',' );
if ( nPos < 0 ) break;
CString strURL = strURLs.Left( nPos );
strURLs = strURLs.Mid( nPos + 1 );
strURL.TrimLeft();
FILETIME tSeen = { 0, 0 };
BOOL bSeen = FALSE;
if ( _tcsistr( strURL, _T("://") ) != NULL )
{
nPos = strURL.ReverseFind( ' ' );
if ( nPos > 0 )
{
CString strTime = strURL.Mid( nPos + 1 );
strURL = strURL.Left( nPos );
strURL.TrimRight();
bSeen = TimeFromString( strTime, &tSeen );
}
for ( nScan = 0 ; nScan < strURL.GetLength() ; nScan++ )
{
if ( strURL[ nScan ] == '`' ) strURL.SetAt( nScan, ',' );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -