📄 downloadsource.cpp
字号:
CFileFragment* pNew = CFileFragment::New( NULL, m_pPastFragment );
pNew->Serialize( ar, FALSE );
if ( m_pPastFragment != NULL ) m_pPastFragment->m_pPrevious = pNew;
m_pPastFragment = pNew;
}
}
ResolveURL();
}
}
//////////////////////////////////////////////////////////////////////
// CDownloadSource create transfer
CDownloadTransfer* CDownloadSource::CreateTransfer()
{
ASSERT( m_pTransfer == NULL );
if ( m_nProtocol == PROTOCOL_HTTP )
{
return ( m_pTransfer = new CDownloadTransferHTTP( this ) );
}
else if ( m_nProtocol == PROTOCOL_ED2K )
{
return ( m_pTransfer = new CDownloadTransferED2K( this ) );
}
else if ( m_nProtocol == PROTOCOL_BT )
{
return ( m_pTransfer = new CDownloadTransferBT( this, NULL ) );
}
else
{
return NULL;
}
}
//////////////////////////////////////////////////////////////////////
// CDownloadSource remove
void CDownloadSource::Remove(BOOL bCloseTransfer, BOOL bBan)
{
if ( m_pTransfer != NULL )
{
if ( bCloseTransfer )
{
m_pTransfer->Close( TS_TRUE );
ASSERT( m_pTransfer == NULL );
}
else
{
m_pTransfer->m_pSource = NULL;
m_pTransfer = NULL;
}
}
m_pDownload->RemoveSource( this, bBan );
}
//////////////////////////////////////////////////////////////////////
// CDownloadSource failure handler
void CDownloadSource::OnFailure(BOOL bNondestructive)
{
if ( m_pTransfer != NULL )
{
m_pTransfer->m_pSource = NULL;
m_pTransfer = NULL;
}
DWORD nDelay = Settings.Downloads.RetryDelay * (DWORD)pow( 2, m_nFailures );
if ( m_nFailures < 20 )
{
if ( nDelay > 3600000 ) nDelay = 3600000;
}
else
{
if ( nDelay > 86400000 ) nDelay = 86400000;
}
nDelay += GetTickCount();
int nMaxFailures = ( m_bReadContent ? 40 : 3 );
if ( nMaxFailures < 20 && m_pDownload->GetSourceCount() > 20 ) nMaxFailures = 0;
m_pDownload->SetModified();
if ( bNondestructive || ( ++m_nFailures < nMaxFailures ) )
{
m_tAttempt = max( m_tAttempt, nDelay );
}
else
{
if ( Settings.Downloads.NeverDrop )
{
m_tAttempt = nDelay;
}
else
{
m_pDownload->RemoveSource( this, TRUE );
}
}
}
//////////////////////////////////////////////////////////////////////
// CDownloadSource resume handler
void CDownloadSource::OnResume()
{
m_tAttempt = 0;
}
//////////////////////////////////////////////////////////////////////
// CDownloadSource status
void CDownloadSource::SetValid()
{
m_bReadContent = TRUE;
m_nFailures = 0;
m_pDownload->SetModified();
}
void CDownloadSource::SetLastSeen()
{
SYSTEMTIME pTime;
GetSystemTime( &pTime );
SystemTimeToFileTime( &pTime, &m_tLastSeen );
m_pDownload->SetModified();
}
void CDownloadSource::SetGnutella(int nGnutella)
{
m_nGnutella |= nGnutella;
m_pDownload->SetModified();
}
//////////////////////////////////////////////////////////////////////
// CDownloadSource hash check and learn
BOOL CDownloadSource::CheckHash(const SHA1* pSHA1)
{
if ( m_pDownload->m_bSHA1 && ! m_bHashAuth )
{
if ( m_pDownload->m_pSHA1 != *pSHA1 ) return FALSE;
}
else
{
if ( m_pDownload->m_pTorrent.IsAvailable() ) return TRUE;
m_pDownload->m_bSHA1 = TRUE;
m_pDownload->m_pSHA1 = *pSHA1;
}
m_bSHA1 = TRUE;
m_pDownload->SetModified();
return TRUE;
}
BOOL CDownloadSource::CheckHash(const TIGEROOT* pTiger)
{
if ( m_pDownload->m_bTiger && ! m_bHashAuth )
{
if ( m_pDownload->m_pTiger != *pTiger ) return FALSE;
}
else
{
if ( m_pDownload->m_pTorrent.IsAvailable() ) return TRUE;
m_pDownload->m_bTiger = TRUE;
m_pDownload->m_pTiger = *pTiger;
}
m_bTiger = TRUE;
m_pDownload->SetModified();
return TRUE;
}
BOOL CDownloadSource::CheckHash(const MD4* pED2K)
{
if ( m_pDownload->m_bED2K && ! m_bHashAuth )
{
if ( memcmp( &m_pDownload->m_pED2K, pED2K, sizeof(MD4) ) ) return FALSE;
}
else
{
if ( m_pDownload->m_pTorrent.IsAvailable() ) return TRUE;
m_pDownload->m_bED2K = TRUE;
m_pDownload->m_pED2K = *pED2K;
}
m_bED2K = TRUE;
m_pDownload->SetModified();
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CDownloadSource push request
BOOL CDownloadSource::PushRequest()
{
if ( m_nProtocol == PROTOCOL_BT )
{
return FALSE;
}
else if ( m_nProtocol == PROTOCOL_ED2K )
{
if ( m_nServerPort == 0 ) return FALSE;
if ( EDClients.IsFull() ) return TRUE;
CEDClient* pClient = EDClients.Connect( m_pAddress.S_un.S_addr, m_nPort,
&m_pServerAddress, m_nServerPort, m_bGUID ? &m_pGUID : NULL );
if ( pClient != NULL && pClient->m_bConnected )
{
pClient->SeekNewDownload();
return TRUE;
}
if ( Neighbours.PushDonkey( m_pAddress.S_un.S_addr, &m_pServerAddress, m_nServerPort ) )
{
theApp.Message( MSG_DEFAULT, IDS_DOWNLOAD_PUSH_SENT, (LPCTSTR)m_pDownload->m_sRemoteName );
m_tAttempt = GetTickCount() + Settings.Downloads.PushTimeout;
return TRUE;
}
}
else
{
if ( ! m_bGUID ) return FALSE;
if ( Network.SendPush( &m_pGUID, m_nIndex ) )
{
theApp.Message( MSG_DEFAULT, IDS_DOWNLOAD_PUSH_SENT, (LPCTSTR)m_pDownload->m_sRemoteName );
m_tAttempt = GetTickCount() + Settings.Downloads.PushTimeout;
return TRUE;
}
}
return FALSE;
}
BOOL CDownloadSource::CheckPush(GGUID* pClientID)
{
return m_bGUID && ( m_pGUID == *pClientID );
}
BOOL CDownloadSource::CheckDonkey(CEDClient* pClient)
{
if ( m_nProtocol != PROTOCOL_ED2K ) return FALSE;
if ( m_bGUID && pClient->m_bGUID ) return m_pGUID == pClient->m_pGUID;
if ( m_bPushOnly )
{
return m_pServerAddress.S_un.S_addr == pClient->m_pServer.sin_addr.S_un.S_addr &&
m_pAddress.S_un.S_addr == pClient->m_nClientID;
}
else
{
return m_pAddress.S_un.S_addr == pClient->m_pHost.sin_addr.S_un.S_addr;
}
}
//////////////////////////////////////////////////////////////////////
// CDownloadSource past fragments
void CDownloadSource::AddFragment(QWORD nOffset, QWORD nLength, BOOL bMerge)
{
m_bReadContent = TRUE;
CFileFragment::AddMerge( &m_pPastFragment, nOffset, nLength );
m_pDownload->SetModified();
}
//////////////////////////////////////////////////////////////////////
// CDownloadSource available ranges
void CDownloadSource::SetAvailableRanges(LPCTSTR pszRanges)
{
if ( m_pAvailable != NULL )
{
m_pAvailable->DeleteChain();
m_pAvailable = NULL;
}
if ( ! pszRanges || ! *pszRanges ) return;
if ( _tcsnicmp( pszRanges, _T("bytes"), 5 ) ) return;
CFileFragment* pPrevious = NULL;
CString strRanges( pszRanges + 6 );
for ( strRanges += ',' ; strRanges.GetLength() ; )
{
CString strRange = strRanges.SpanExcluding( _T(", \t") );
strRanges = strRanges.Mid( strRange.GetLength() + 1 );
strRange.TrimLeft();
strRange.TrimRight();
if ( strRange.Find( '-' ) < 0 ) continue;
QWORD nFirst = 0, nLast = 0;
if ( _stscanf( strRange, _T("%I64i-%I64i"), &nFirst, &nLast ) == 2 && nLast > nFirst )
{
CFileFragment* pFragment = CFileFragment::New( pPrevious, NULL, nFirst, nLast + 1 - nFirst );
if ( ! m_pAvailable ) m_pAvailable = pFragment;
if ( pPrevious ) pPrevious->m_pNext = pFragment;
pPrevious = pFragment;
}
}
m_pDownload->SetModified();
}
//////////////////////////////////////////////////////////////////////
// CDownloadSource range intersection test
BOOL CDownloadSource::HasUsefulRanges() const
{
if ( m_pAvailable == NULL ) return m_pDownload->IsRangeUseful( 0, m_pDownload->m_nSize );
for ( CFileFragment* pFragment = m_pAvailable ; pFragment ; pFragment = pFragment->m_pNext )
{
if ( m_pDownload->IsRangeUseful( pFragment->m_nOffset, pFragment->m_nLength ) ) return TRUE;
}
return FALSE;
}
//////////////////////////////////////////////////////////////////////
// CDownloadSource range intersection
BOOL CDownloadSource::TouchedRange(QWORD nOffset, QWORD nLength) const
{
if ( m_pTransfer != NULL && m_pTransfer->m_nState == dtsDownloading )
{
if ( m_pTransfer->m_nOffset + m_pTransfer->m_nLength > nOffset &&
m_pTransfer->m_nOffset < nOffset + nLength )
{
return TRUE;
}
}
for ( CFileFragment* pFragment = m_pPastFragment ; pFragment ;
pFragment = pFragment->m_pNext )
{
if ( pFragment->m_nOffset >= nOffset + nLength ) continue;
if ( pFragment->m_nOffset + pFragment->m_nLength <= nOffset ) continue;
return TRUE;
}
return FALSE;
}
//////////////////////////////////////////////////////////////////////
// CDownloadSource colour
int CDownloadSource::GetColour()
{
if ( m_nColour >= 0 ) return m_nColour;
m_nColour = m_pDownload->GetSourceColour();
return m_nColour;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -