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; }
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; } } }
int CDownload::GetClientStatus() const { return IsCompleted() ? -1 : (int)GetEffectiveSourceCount(); }
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; }
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; }