Ejemplo n.º 1
0
CString CDownload::GetDownloadSources() const
{
	const int nTotalSources = GetSourceCount();
	const int nSources = GetEffectiveSourceCount();

	CString strText;
	if ( IsCompleted() )
	{
		if ( m_bVerify == TRI_TRUE )
			LoadString( strText, IDS_STATUS_VERIFIED );
		else if ( m_bVerify == TRI_FALSE )
			LoadString( strText, IDS_STATUS_UNVERIFIED );
	}
	else if ( nTotalSources == 0 )
	{
		LoadString( strText, IDS_STATUS_NOSOURCES );
	}
	else if ( nSources == nTotalSources )
	{
		CString strSource;
		LoadSourcesString( strSource, nSources );
		strText.Format( L"(%i %s)", nSources, (LPCTSTR)strSource );
	}
	else
	{
		CString strSource;
		LoadSourcesString( strSource, nTotalSources, true );
		strText.Format( L"(%i/%i %s)", nSources, nTotalSources, (LPCTSTR)strSource );
	}
	return strText;
}
Ejemplo n.º 2
0
void CDownload::OnRun()
{
	// Set the currently downloading state
	// (Used to optimize display in Ctrl/Wnd functions)
	m_bDownloading = false;

	const DWORD tNow = GetTickCount();

	if ( ! IsPaused() )
	{
		if ( GetFileError() != ERROR_SUCCESS )
		{
			// File or disk errors
			Pause( FALSE );
		}
		else if ( IsMoving() )
		{
			if ( ! IsCompleted() && ! IsTasking() )
				OnDownloaded();
		}
		else if ( IsTrying() || IsSeeding() )
		{
			// This download is trying to download
			if ( HasHash() )		// Workaround for direct downloads stuck "verifying"
				OpenDownload();

			// Dead Download Check: if download appears dead, give up and allow another to start.
			// Incomplete, and trying for at least 3 hours:
			if ( ! IsCompleted() && tNow > GetStartTimer() + ( 3 * 60 * 60 * 1000 ) )
			{
				const DWORD tHoursToTry = min( ( GetEffectiveSourceCount() + 49u ) / 50u, 9lu ) + Settings.Downloads.StarveGiveUp;

				// No new data for 5-14 hours
				if ( tNow > m_tReceived + ( tHoursToTry * 60 * 60 * 1000 ) )
				{
					if ( IsTorrent() )
					{
						// Are there other torrents that should start?
						if ( Downloads.GetTryingCount( TRUE ) >= Settings.BitTorrent.DownloadTorrents )
						{
							StopTrying();		// Give up for now, try again later
							return;
						}
					}
					else	// Regular download
					{
						// Are there other downloads that should try?
						if ( Downloads.GetTryingCount() >= ( Settings.Downloads.MaxFiles + Settings.Downloads.MaxFileSearches ) )
						{
							StopTrying();		// Give up for now, try again later
							return;
						}
					}
				}
			}
			// End Dead Download Check

			// Run the download
			RunTorrent( tNow );
			RunSearch( tNow );
			RunValidation();

			if ( IsSeeding() )
			{
				// Mark as collapsed to get correct heights when dragging files
				if ( ! Settings.General.DebugBTSources && m_bExpanded )
					m_bExpanded = FALSE;
			}
			else // if ( ! IsMoving() )
			{
				if ( IsComplete() && IsFileOpen() )
				{
					if ( IsFullyVerified() )
						OnDownloaded();
				}
				else if ( CheckTorrentRatio() )
				{
					if ( ! Network.IsConnected() )
					{
						StopTrying();
						return;
					}

					StartTransfersIfNeeded( tNow );
				}
			}

			// Calculate current downloading state
			if ( HasActiveTransfers() )
				m_bDownloading = true;

			// Mutate regular download to torrent download
			if ( Settings.BitTorrent.EnablePromote && m_oBTH && ! IsTorrent() )
			{
				m_pTorrent.Clear();
				m_pTorrent.m_oMD5	= m_oMD5;
				m_pTorrent.m_oBTH	= m_oBTH;
				m_pTorrent.m_oSHA1	= m_oSHA1;
				m_pTorrent.m_oED2K	= m_oED2K;
				m_pTorrent.m_oTiger	= m_oTiger;
				m_pTorrent.m_sName	= m_sName;
				m_pTorrent.m_nSize	= m_nSize;
				SetTorrent();
			}
		}
		else if ( ! IsCompleted() && m_bVerify != TRI_TRUE )
		{
			// This is pending download
		//	// If this download isn't trying to download, see if it can try
		//	if ( IsDownloading() )
		//		SetStartTimer();	// This download was probably started by a push/etc

			if ( Network.IsConnected() )
			{
				// Have extra regular downloads 'trying' so when a new slot is ready,
				// a download has sources and is ready to go.
				if ( Downloads.GetTryingCount() < ( Settings.Downloads.MaxFiles + Settings.Downloads.MaxFileSearches ) )
				{
					if ( ! IsTorrent() ||
						Downloads.GetTryingCount( true ) < Settings.BitTorrent.DownloadTorrents )
					{
						// Torrents only try when 'ready to go'. (Reduce tracker load)
						Resume();
					}
				}
			}
		//	else
		//		ASSERT( ! IsTrying() );
		}
	}

	// Don't save Downloads with many sources too often, since it's slow
	if ( tNow >= m_tSaved + ( GetCount() > 20 ? 5 * Settings.Downloads.SaveInterval : Settings.Downloads.SaveInterval ) )
	{
		if ( IsModified() )
		{
			FlushFile();
			if ( Save() )
				m_tSaved = tNow;
		}
	}
}
Ejemplo n.º 3
0
int CDownload::GetClientStatus() const
{
	return IsCompleted() ? -1 : (int)GetEffectiveSourceCount();
}
Ejemplo n.º 4
0
CString CDownload::GetDownloadStatus() const
{
	CString strText;

	if ( m_bClearing )	// Briefly marked for removal
	{
		LoadString( strText, IDS_STATUS_CLEARING );
	}
	else if ( IsPaused() )
	{
		if ( GetFileError() == ERROR_SUCCESS || IsSeeding() )
			LoadString( strText, IDS_STATUS_PAUSED );
		else
			LoadString( strText, IsMoving() ? IDS_STATUS_CANTMOVE : IDS_STATUS_FILEERROR );
	}
	else if ( IsCompleted() )
	{
		if ( IsSeeding() )
			LoadString( strText, m_bTorrentTrackerError ? IDS_STATUS_TRACKERDOWN : IDS_STATUS_SEEDING );
		else
			LoadString( strText, IDS_STATUS_COMPLETED );
	}
	else if ( IsMoving() )
	{
		LoadString( strText, IDS_STATUS_MOVING );
	}
	else if ( IsStarted() && GetProgress() == 100.0f )
	{
		LoadString( strText, IDS_STATUS_VERIFYING );
	}
	else if ( ! IsTrying() )
	{
		LoadString( strText, IDS_STATUS_QUEUED );
	}
	else if ( IsDownloading() )
	{
		const DWORD nTime = GetTimeRemaining();

		if ( nTime == 0xFFFFFFFF )
			LoadString( strText, IDS_STATUS_ACTIVE );	// IDS_STATUS_DOWNLOADING
		else if ( nTime == 0 )
			LoadString( strText, IDS_STATUS_DOWNLOADING );
		else if ( nTime > 86400 )
			strText.Format( L"%u:%.2u:%.2u:%.2u", nTime / 86400, ( nTime / 3600 ) % 24, ( nTime / 60 ) % 60, nTime % 60 );
		else
			strText.Format( L"%u:%.2u:%.2u", nTime / 3600, ( nTime / 60 ) % 60, nTime % 60 );
	}
	else if ( GetEffectiveSourceCount() > 0 )
	{
		LoadString( strText, IDS_STATUS_PENDING );
	}
	else if ( IsTorrent() )
	{
		if ( GetTaskType() == dtaskAllocate )
			LoadString( strText, IDS_STATUS_CREATING );
		else if ( m_bTorrentTrackerError )
			LoadString( strText, IDS_STATUS_TRACKERDOWN );
		else
			LoadString( strText, IDS_STATUS_TORRENT );
	}
	else // Inactive
	{
		LoadString( strText, IDS_STATUS_QUEUED );
	}

	return strText;
}
Ejemplo n.º 5
0
BOOL CDownloadWithSources::AddSourceInternal(CDownloadSource* pSource)
{
	if ( ! pSource )
		return FALSE;	// Out of memory

	if ( GetEffectiveSourceCount() > Settings.Downloads.SourcesWanted )
	{
		delete pSource;
		return FALSE;	// Too many sources
	}

	// Check/Reject if source is invalid
	if ( ! pSource->m_bPushOnly )
	{
		// Reject invalid IPs (Sometimes ed2k sends invalid 0.x.x.x sources)
		if ( pSource->m_pAddress.S_un.S_un_b.s_b1 == 0 || pSource->m_nPort == 0 )
		{
			delete pSource;
			return FALSE;
		}

		// Reject if source is the local IP/port
		if ( Network.IsSelfIP( pSource->m_pAddress ) )
		{
			if ( Settings.Connection.IgnoreOwnIP ||
				( pSource->m_nServerPort == 0 &&
				Settings.Connection.InPort == pSource->m_nPort ) )
			{
				delete pSource;
				return FALSE;
			}
		}
	}
	else if ( pSource->m_nProtocol == PROTOCOL_ED2K )
	{
		// Reject invalid server IPs (Sometimes ed2k sends invalid 0.x.x.x sources)
		if ( pSource->m_pServerAddress.S_un.S_un_b.s_b1 == 0 )
		{
			delete pSource;
			return FALSE;
		}
	}

	CQuickLock pLock( Transfers.m_pSection );

	if ( pSource->m_nRedirectionCount == 0 )	// Don't check for existing sources if source is a redirection
	{
		bool bDeleteSource = false;
		bool bHTTPSource = pSource->IsHTTPSource();
		bool bNeedHTTPSource = ! bHTTPSource &&
			Settings.Gnutella2.Enabled &&
			VendorCache.IsExtended( pSource->m_sServer );

		// Remove unneeded sources
		for ( POSITION posSource = GetIterator() ; posSource ; )
		{
			CDownloadSource* pExisting = GetNext( posSource );

			ASSERT( pSource != pExisting );
			if ( pExisting->Equals( pSource ) ) 	// IPs and ports are equal
			{
				bool bExistingHTTPSource = pExisting->IsHTTPSource();

				if ( bNeedHTTPSource && bExistingHTTPSource )
					bNeedHTTPSource = false;

				if ( ( pExisting->m_nProtocol == pSource->m_nProtocol ) ||
					 ( bExistingHTTPSource && bHTTPSource ) )
				{
					bDeleteSource = true;			// Same protocol
				}
				else if ( ! pExisting->IsIdle() )
				{
					// Already downloading so we can remove new non-HTTP source
					if ( bExistingHTTPSource && ! bHTTPSource )
						bDeleteSource = true;
				}
				else // We are not downloading
				{
					// ...So we can replace non-HTTP source with a new one
					if ( ! bExistingHTTPSource && bHTTPSource )
					{
						// Set connection delay the same as for the old source
						pSource->m_tAttempt = pExisting->m_tAttempt;
						pExisting->Remove( TRUE, FALSE );
					}
				}
			}
		}

		if ( bDeleteSource )
		{
			delete pSource;

			SetModified();

			return FALSE;
		}

		// Make additional G2 source from the existing non-HTTP PeerProject source
		if ( bNeedHTTPSource )
		{
			CString strURL = GetURL( pSource->m_pAddress, pSource->m_nPort );
			if ( ! strURL.IsEmpty() )
			{
				if ( CDownloadSource* pG2Source = new CDownloadSource( (CDownload*)this, strURL ) )
				{
					pG2Source->m_sServer = pSource->m_sServer;		// Copy user-agent
					pG2Source->m_tAttempt = pSource->m_tAttempt;	// Set the same connection delay
					pG2Source->m_nProtocol = PROTOCOL_HTTP;

					AddSourceInternal( pG2Source );
				}
			}
		}
	}

	InternalAdd( pSource );

	SetModified();

	return TRUE;
}