⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 downloadsource.cpp

📁 著名的下载软件核心Shareaza
💻 CPP
📖 第 1 页 / 共 2 页
字号:
				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 + -