00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "Settings.h"
00025 #include "Network.h"
00026 #include "BTPacket.h"
00027 #include "BTClient.h"
00028 #include "BTClients.h"
00029 #include "Download.h"
00030 #include "DownloadTask.h"
00031 #include "DownloadSource.h"
00032 #include "DownloadWithTorrent.h"
00033 #include "DownloadTransferBT.h"
00034 #include "UploadTransferBT.h"
00035 #include "BTTrackerRequest.h"
00036 #include "FragmentedFile.h"
00037 #include "Buffer.h"
00038 #include "SHA.h"
00039 #include "LibraryFolders.h"
00040 #include "GProfile.h"
00041 #include "Uploads.h"
00042 #include "UploadTransfer.h"
00043
00044 #ifdef _DEBUG
00045 #undef THIS_FILE
00046 static char THIS_FILE[]=__FILE__;
00047 #define new DEBUG_NEW
00048 #endif
00049
00050
00052
00053
00054 CDownloadWithTorrent::CDownloadWithTorrent()
00055 {
00056 m_bTorrentRequested = FALSE;
00057 m_bTorrentStarted = FALSE;
00058 m_tTorrentTracker = 0;
00059 m_nTorrentUploaded = 0;
00060 m_nTorrentDownloaded = 0;
00061 m_bTorrentEndgame = FALSE;
00062 m_bTorrentTrackerError = FALSE;
00063 m_nTorrentTrackerErrors = 0;
00064
00065 m_pTorrentBlock = NULL;
00066 m_nTorrentBlock = 0;
00067 m_nTorrentSize = 0;
00068 m_nTorrentSuccess = 0;
00069 m_bSeeding = FALSE;
00070
00071 m_tTorrentChoke = 0;
00072 m_tTorrentSources = 0;
00073 ZeroMemory(m_pPeerID.n, 20);
00074
00075
00076 m_sKey = _T("");
00077 srand( GetTickCount() );
00078 for ( int nChar = 1 ; nChar < 6 ; nChar++ )
00079 {
00080 m_sKey += GenerateCharacter();
00081 }
00082
00083 m_nStartTorrentDownloads= dtAlways;
00084 }
00085
00086 CDownloadWithTorrent::~CDownloadWithTorrent()
00087 {
00088 if ( m_bTorrentRequested ) CBTTrackerRequest::SendStopped( this );
00089 CloseTorrentUploads();
00090 if ( m_pTorrentBlock != NULL ) delete [] m_pTorrentBlock;
00091 }
00092
00094
00095
00096 void CDownloadWithTorrent::Serialize(CArchive& ar, int nVersion)
00097 {
00098 CDownloadWithFile::Serialize( ar, nVersion );
00099
00100 if ( nVersion < 22 ) return;
00101
00102 m_pTorrent.Serialize( ar );
00103
00104 if ( ar.IsLoading() && m_pTorrent.IsAvailable() )
00105 {
00106 m_bBTH = TRUE;
00107 m_bBTHTrusted = TRUE;
00108 m_pBTH = m_pTorrent.m_pInfoSHA1;
00109 }
00110
00111 if ( nVersion >= 23 && m_pTorrent.IsAvailable() )
00112 {
00113 if ( ar.IsStoring() )
00114 {
00115 ar << m_nTorrentSuccess;
00116 ar.Write( m_pTorrentBlock, sizeof(BYTE) * m_nTorrentBlock );
00117 }
00118 else
00119 {
00120 m_nTorrentSize = m_pTorrent.m_nBlockSize;
00121 m_nTorrentBlock = m_pTorrent.m_nBlockCount;
00122
00123 ar >> m_nTorrentSuccess;
00124 m_pTorrentBlock = new BYTE[ m_nTorrentBlock ];
00125 ar.Read( m_pTorrentBlock, sizeof(BYTE) * m_nTorrentBlock );
00126 }
00127 }
00128 }
00129
00131
00132
00133 BOOL CDownloadWithTorrent::SetTorrent(CBTInfo* pTorrent)
00134 {
00135 if ( pTorrent == NULL ) return FALSE;
00136 if ( m_pTorrent.IsAvailable() ) return FALSE;
00137 if ( ! pTorrent->IsAvailable() ) return FALSE;
00138
00139 m_pTorrent.Copy( pTorrent );
00140
00141 m_bBTH = TRUE;
00142 m_pBTH = m_pTorrent.m_pInfoSHA1;
00143
00144 m_nTorrentSize = m_pTorrent.m_nBlockSize;
00145 m_nTorrentBlock = m_pTorrent.m_nBlockCount;
00146 m_pTorrentBlock = new BYTE[ m_nTorrentBlock ];
00147
00148 ZeroMemory( m_pTorrentBlock, sizeof(BYTE) * m_nTorrentBlock );
00149 SetModified();
00150
00151 CreateDirectory( Settings.Downloads.TorrentPath, NULL );
00152 LibraryFolders.AddFolder( Settings.Downloads.TorrentPath, FALSE );
00153 pTorrent->SaveTorrentFile( Settings.Downloads.TorrentPath );
00154
00155 if ( ! Settings.BitTorrent.AdvancedInterfaceSet )
00156 {
00157
00158 Settings.BitTorrent.AdvancedInterfaceSet = TRUE;
00159 Settings.BitTorrent.AdvancedInterface = TRUE;
00160 }
00161
00162 return TRUE;
00163 }
00164
00166
00167
00168 BOOL CDownloadWithTorrent::RunTorrent(DWORD tNow)
00169 {
00170 if ( ! m_pTorrent.IsAvailable() ) return TRUE;
00171 if ( m_bDiskFull ) return FALSE;
00172
00173 if ( tNow > m_tTorrentChoke && tNow - m_tTorrentChoke >= 10000 ) ChokeTorrent( tNow );
00174
00175 if ( m_pFile != NULL && m_pFile->IsOpen() == FALSE )
00176 {
00177 BOOL bCreated = ( m_sLocalName.IsEmpty() ||
00178 GetFileAttributes( m_sLocalName ) == 0xFFFFFFFF );
00179
00180 if ( ! PrepareFile() ) return FALSE;
00181
00182 ASSERT( m_pTask == NULL );
00183 if ( bCreated ) m_pTask = new CDownloadTask( (CDownload*)this, CDownloadTask::dtaskAllocate );
00184 }
00185
00186 if ( m_pTask != NULL ) return FALSE;
00187
00188 BOOL bLive = ( ! IsPaused() ) && ( IsTrying() ) && ( Network.IsConnected() );
00189
00190 if ( bLive && ! m_bTorrentStarted )
00191 {
00192 if ( ! m_bTorrentRequested || tNow > m_tTorrentTracker )
00193 {
00194 theApp.Message( MSG_DEFAULT, _T("Sending initial announce for %s"), m_pTorrent.m_sName );
00195
00196 GenerateTorrentDownloadID();
00197
00198 m_bTorrentRequested = TRUE;
00199 m_bTorrentStarted = FALSE;
00200 m_tTorrentTracker = tNow + Settings.BitTorrent.DefaultTrackerPeriod;
00201 m_nTorrentUploaded = 0;
00202 m_nTorrentDownloaded = 0;
00203
00204 if ( GetSourceCount(TRUE, TRUE) < Settings.BitTorrent.DownloadConnections + 10 )
00205 CBTTrackerRequest::SendStarted( this, Settings.BitTorrent.DownloadConnections + 10 );
00206 else
00207 CBTTrackerRequest::SendStarted( this );
00208 }
00209 }
00210 else if ( ! bLive && m_bTorrentRequested )
00211 {
00212 theApp.Message( MSG_DEFAULT, _T("Sending final announce for %s"), m_pTorrent.m_sName );
00213
00214 CBTTrackerRequest::SendStopped( this );
00215
00216 m_bTorrentRequested = m_bTorrentStarted = FALSE;
00217 m_tTorrentTracker = 0;
00218
00219 }
00220
00221 if ( m_bTorrentStarted && tNow > m_tTorrentTracker )
00222 {
00223
00224 theApp.Message( MSG_DEFAULT, _T("Performing tracker update for %s"), m_pTorrent.m_sName );
00225
00226 int nSources = GetBTSourceCount();
00227 int nSourcesWanted = (int)( Settings.BitTorrent.DownloadConnections * 1.5 );
00228 nSourcesWanted = max( nSourcesWanted, Settings.Downloads.SourcesWanted / 10 );
00229 m_tTorrentTracker = tNow + Settings.BitTorrent.DefaultTrackerPeriod;
00230 if ( IsMoving() )
00231 {
00232
00233 if ( ( ! IsCompleted() ) || ( Settings.Connection.FirewallStatus == CONNECTION_OPEN ) || ( nSources > (nSourcesWanted / 2) ) || ( Uploads.GetTorrentUploadCount() >= Settings.BitTorrent.UploadCount ) )
00234 CBTTrackerRequest::SendUpdate( this, 0 );
00235 else
00236 CBTTrackerRequest::SendUpdate( this, 10 );
00237 }
00238 else if ( ( GetTransferCount( dtsCountTorrentAndActive ) ) > ( Settings.BitTorrent.DownloadConnections ) )
00239 {
00240 if ( nSources > nSourcesWanted )
00241 CBTTrackerRequest::SendUpdate( this, 0 );
00242 else
00243 CBTTrackerRequest::SendUpdate( this, 10 );
00244 }
00245 else
00246 {
00247 if ( nSources > nSourcesWanted )
00248 CBTTrackerRequest::SendUpdate( this, 5 );
00249 else
00250 CBTTrackerRequest::SendUpdate( this );
00251 }
00252
00253 }
00254
00255 return TRUE;
00256 }
00257
00259
00260
00261 BOOL CDownloadWithTorrent::GenerateTorrentDownloadID()
00262 {
00263 theApp.Message( MSG_DEBUG, _T("Creating BitTorrent Peer ID") );
00264
00265 int nByte;
00266
00267
00268 for ( nByte = 0 ; nByte < 20 ; nByte++ )
00269 {
00270 if ( m_pPeerID.n[ nByte ] != 0 )
00271 {
00272 theApp.Message( MSG_DEBUG, _T("Attempted to re-create an in-use Peer ID") );
00273 return FALSE;
00274 }
00275 }
00276
00277
00278 if ( Settings.BitTorrent.StandardPeerID )
00279 {
00280
00281 m_pPeerID.n[ 0 ] = '-';
00282 m_pPeerID.n[ 1 ] = BT_ID1;
00283 m_pPeerID.n[ 2 ] = BT_ID2;
00284 m_pPeerID.n[ 3 ] = (BYTE)theApp.m_nVersion[0] + '0';
00285 m_pPeerID.n[ 4 ] = (BYTE)theApp.m_nVersion[1] + '0';
00286 m_pPeerID.n[ 5 ] = (BYTE)theApp.m_nVersion[2] + '0';
00287 m_pPeerID.n[ 6 ] = (BYTE)theApp.m_nVersion[3] + '0';
00288 m_pPeerID.n[ 7 ] = '-';
00289
00290
00291 srand( GetTickCount() );
00292 for ( nByte = 8 ; nByte < 16 ; nByte++ )
00293 {
00294 m_pPeerID.n[ nByte ] += rand();
00295 }
00296 for ( nByte = 16 ; nByte < 20 ; nByte++ )
00297 {
00298 m_pPeerID.n[ nByte ] = m_pPeerID.n[ nByte % 16 ]
00299 ^ m_pPeerID.n[ 15 - ( nByte % 16 ) ];
00300 }
00301 }
00302 else
00303 {
00304
00305 for ( nByte = 0 ; nByte < 20 ; nByte++ )
00306 {
00307 m_pPeerID.n[ nByte ] += rand();
00308 }
00309 }
00310
00311 return TRUE;
00312 }
00313
00315
00316
00317 void CDownloadWithTorrent::OnTrackerEvent(BOOL bSuccess, LPCTSTR pszReason)
00318 {
00319 if ( bSuccess )
00320 {
00321
00322 m_bTorrentTrackerError = FALSE;
00323 m_sTorrentTrackerError.Empty();
00324 m_nTorrentTrackerErrors = 0;
00325 }
00326 else
00327 {
00328
00329
00330 m_bTorrentTrackerError = TRUE;
00331 m_sTorrentTrackerError.Empty();
00332 m_nTorrentTrackerErrors ++;
00333
00334 if ( pszReason != NULL )
00335 {
00336
00337 m_sTorrentTrackerError = pszReason;
00338 m_tTorrentTracker = GetTickCount() + 60 * 60 * 1000;
00339 }
00340 else if ( m_bTorrentTrackerError )
00341 {
00342
00343
00344
00345
00346 if ( m_nTorrentTrackerErrors <= Settings.BitTorrent.MaxTrackerRetry )
00347 {
00348
00349 DWORD tRetryTime;
00350 if ( m_nTorrentTrackerErrors <= 3 )
00351 tRetryTime = m_nTorrentTrackerErrors * 10 * 1000;
00352 else if ( m_nTorrentTrackerErrors <= 6 )
00353 tRetryTime = m_nTorrentTrackerErrors * 1 * 60 * 1000;
00354 else if ( m_nTorrentTrackerErrors <= 15 )
00355 tRetryTime = m_nTorrentTrackerErrors * 2 * 60 * 1000;
00356 else
00357 tRetryTime = 30 * 60 * 1000;
00358 m_tTorrentTracker = GetTickCount() + tRetryTime;
00359
00360
00361 CString strErrorMessage;
00362 LoadString( strErrorMessage, IDS_BT_TRACKER_RETRY );
00363 m_sTorrentTrackerError.Format( strErrorMessage, m_nTorrentTrackerErrors, Settings.BitTorrent.MaxTrackerRetry );
00364 }
00365 else
00366 {
00367
00368 m_tTorrentTracker = GetTickCount() + 30 * 60 * 1000;
00369 LoadString( m_sTorrentTrackerError, IDS_BT_TRACKER_DOWN );
00370 }
00371 }
00372 }
00373 }
00374
00376
00377
00378 CDownloadTransferBT* CDownloadWithTorrent::CreateTorrentTransfer(CBTClient* pClient)
00379 {
00380 if ( IsMoving() || IsPaused() ) return NULL;
00381
00382 CDownloadSource* pSource = NULL;
00383
00384 for ( pSource = GetFirstSource() ; pSource ; pSource = pSource->m_pNext )
00385 {
00386 if ( pSource->m_nProtocol == PROTOCOL_BT &&
00387 memcmp( &pSource->m_pGUID, &pClient->m_pGUID, 16 ) == 0 ) break;
00388 }
00389
00390 if ( pSource == NULL )
00391 {
00392 pSource = new CDownloadSource( (CDownload*)this, &pClient->m_pGUID,
00393 &pClient->m_pHost.sin_addr, htons( pClient->m_pHost.sin_port ) );
00394 pSource->m_bPushOnly = TRUE;
00395
00396 if ( ! AddSourceInternal( pSource ) ) return NULL;
00397 }
00398
00399 if ( pSource->m_pTransfer != NULL )
00400 {
00401
00402 return NULL;
00403 }
00404
00405 pSource->m_pTransfer = new CDownloadTransferBT( pSource, pClient );
00406
00407 return (CDownloadTransferBT*)pSource->m_pTransfer;
00408 }
00409
00410 void CDownloadWithTorrent::OnFinishedTorrentBlock(DWORD nBlock)
00411 {
00412 for ( CDownloadTransferBT* pTransfer = (CDownloadTransferBT*)GetFirstTransfer() ; pTransfer ; pTransfer = (CDownloadTransferBT*)pTransfer->m_pDlNext )
00413 {
00414 if ( pTransfer->m_nProtocol == PROTOCOL_BT )
00415 {
00416 pTransfer->SendFinishedBlock( nBlock );
00417 }
00418 }
00419 }
00420
00422
00423
00424 CBTPacket* CDownloadWithTorrent::CreateBitfieldPacket()
00425 {
00426 ASSERT( m_pTorrent.IsAvailable() );
00427
00428 CBTPacket* pPacket = CBTPacket::New( BT_PACKET_BITFIELD );
00429 int nCount = 0;
00430
00431 for ( QWORD nBlock = 0 ; nBlock < m_nTorrentBlock ; )
00432 {
00433 BYTE nByte = 0;
00434
00435 for ( int nBit = 7 ; nBit >= 0 && nBlock < m_nTorrentBlock ; nBit--, nBlock++ )
00436 {
00437 if ( m_pTorrentBlock[ nBlock ] )
00438 {
00439 nByte |= ( 1 << nBit );
00440 nCount++;
00441 }
00442 }
00443
00444 pPacket->WriteByte( nByte );
00445 }
00446
00447 if ( nCount > 0 ) return pPacket;
00448 pPacket->Release();
00449
00450 return NULL;
00451 }
00452
00454
00455
00456 void CDownloadWithTorrent::AddUpload(CUploadTransferBT* pUpload)
00457 {
00458 if ( m_pTorrentUploads.Find( pUpload ) == NULL )
00459 m_pTorrentUploads.AddTail( pUpload );
00460 }
00461
00462 void CDownloadWithTorrent::RemoveUpload(CUploadTransferBT* pUpload)
00463 {
00464 if ( POSITION pos = m_pTorrentUploads.Find( pUpload ) )
00465 m_pTorrentUploads.RemoveAt( pos );
00466 }
00467
00468 void CDownloadWithTorrent::CloseTorrentUploads()
00469 {
00470 for ( POSITION pos = m_pTorrentUploads.GetHeadPosition() ; pos ; )
00471 {
00472 CUploadTransferBT* pUpload = (CUploadTransferBT*)m_pTorrentUploads.GetNext( pos );
00473 pUpload->Close();
00474 }
00475 }
00476
00478
00479
00480 void CDownloadWithTorrent::ChokeTorrent(DWORD tNow)
00481 {
00482 BOOL bChooseRandom = TRUE;
00483 int nTotalRandom = 0;
00484 CPtrList pSelected;
00485
00486 if ( ! tNow ) tNow = GetTickCount();
00487 if ( tNow > m_tTorrentChoke && tNow - m_tTorrentChoke < 2000 ) return;
00488 m_tTorrentChoke = tNow;
00489
00490
00491 if ( ( IsCompleted() ) && ( Settings.Connection.FirewallStatus == CONNECTION_FIREWALLED ) )
00492 {
00493
00494 if ( m_pTorrentUploads.GetCount() < max( Settings.BitTorrent.UploadCount * 2, 5 ) )
00495 {
00496 if ( CanStartTransfers( tNow ) )
00497 {
00498 theApp.Message( MSG_DEBUG, _T("Attempting to push-start a BitTorrent upload") );
00499 StartNewTransfer( tNow );
00500 }
00501 }
00502 }
00503
00504
00505 for ( POSITION pos = m_pTorrentUploads.GetHeadPosition() ; pos ; )
00506 {
00507 CUploadTransferBT* pTransfer = (CUploadTransferBT*)m_pTorrentUploads.GetNext( pos );
00508 if ( pTransfer->m_nProtocol != PROTOCOL_BT ) continue;
00509
00510 if ( pTransfer->m_nRandomUnchoke == 2 )
00511 {
00512 if ( tNow - pTransfer->m_tRandomUnchoke >= Settings.BitTorrent.RandomPeriod )
00513 {
00514 pTransfer->m_nRandomUnchoke = 1;
00515 }
00516 else
00517 {
00518 bChooseRandom = FALSE;
00519 }
00520 }
00521
00522 if ( pTransfer->m_bInterested )
00523 nTotalRandom += ( pTransfer->m_nRandomUnchoke == 0 ) ? 3 : 1;
00524 }
00525
00526 if ( bChooseRandom && nTotalRandom > 0 )
00527 {
00528 nTotalRandom = rand() % nTotalRandom;
00529
00530 for ( POSITION pos = m_pTorrentUploads.GetHeadPosition() ; pos ; )
00531 {
00532 CUploadTransferBT* pTransfer = (CUploadTransferBT*)m_pTorrentUploads.GetNext( pos );
00533 if ( pTransfer->m_nProtocol != PROTOCOL_BT ) continue;
00534 if ( pTransfer->m_bInterested == FALSE ) continue;
00535
00536 int nWeight = ( pTransfer->m_nRandomUnchoke == 0 ) ? 3 : 1;
00537
00538 if ( nTotalRandom < nWeight )
00539 {
00540 pTransfer->m_nRandomUnchoke = 2;
00541 pTransfer->m_tRandomUnchoke = tNow;
00542 pSelected.AddTail( pTransfer );
00543 break;
00544 }
00545 else
00546 {
00547 nTotalRandom -= nWeight;
00548 }
00549 }
00550 }
00551
00552 while ( pSelected.GetCount() < Settings.BitTorrent.UploadCount )
00553 {
00554 CUploadTransferBT* pBest = NULL;
00555 DWORD nBest = 0;
00556
00557 for ( POSITION pos = m_pTorrentUploads.GetHeadPosition() ; pos ; )
00558 {
00559 CUploadTransferBT* pTransfer = (CUploadTransferBT*)m_pTorrentUploads.GetNext( pos );
00560
00561 if ( pTransfer->m_nProtocol == PROTOCOL_BT &&
00562 pTransfer->m_bInterested &&
00563 pSelected.Find( pTransfer->m_pClient ) == NULL &&
00564 pTransfer->GetAverageSpeed() >= nBest )
00565 {
00566 pBest = pTransfer;
00567 nBest = pTransfer->GetAverageSpeed();
00568 }
00569 }
00570
00571 if ( pBest == NULL ) break;
00572 pSelected.AddTail( pBest->m_pClient );
00573 }
00574
00575 while ( pSelected.GetCount() < Settings.BitTorrent.UploadCount )
00576 {
00577 CDownloadTransferBT* pBest = NULL;
00578 DWORD nBest = 0;
00579
00580 for ( CDownloadTransferBT* pTransfer = (CDownloadTransferBT*)GetFirstTransfer()
00581 ; pTransfer ; pTransfer = (CDownloadTransferBT*)pTransfer->m_pDlNext )
00582 {
00583 if ( pTransfer->m_nProtocol == PROTOCOL_BT &&
00584 pSelected.Find( pTransfer->m_pClient ) == NULL &&
00585 pTransfer->m_nState == dtsDownloading &&
00586 pTransfer->m_pClient->m_pUpload->m_bInterested &&
00587 pTransfer->GetAverageSpeed() >= nBest )
00588 {
00589 pBest = pTransfer;
00590 nBest = pTransfer->GetAverageSpeed();
00591 }
00592 }
00593
00594 if ( pBest == NULL ) break;
00595 pSelected.AddTail( pBest->m_pClient );
00596 }
00597
00598 for ( POSITION pos = m_pTorrentUploads.GetHeadPosition() ; pos ; )
00599 {
00600 CUploadTransferBT* pTransfer = (CUploadTransferBT*)m_pTorrentUploads.GetNext( pos );
00601 if ( pTransfer->m_nProtocol != PROTOCOL_BT ) continue;
00602
00603 pTransfer->SetChoke( pTransfer->m_bInterested == TRUE &&
00604 pSelected.Find( pTransfer->m_pClient ) == NULL );
00605 }
00606 }
00607
00609
00610
00611 BOOL CDownloadWithTorrent::FindMoreSources()
00612 {
00613 if ( m_pFile != NULL && m_bTorrentRequested )
00614 {
00615 ASSERT( m_pTorrent.IsAvailable() );
00616
00617 if ( GetTickCount() - m_tTorrentSources > 15000 )
00618 {
00619 m_tTorrentTracker = GetTickCount() + Settings.BitTorrent.DefaultTrackerPeriod;
00620 m_tTorrentSources = GetTickCount();
00621 CBTTrackerRequest::SendUpdate( this, min ( ( Settings.BitTorrent.DownloadConnections * 2 ), 100 ) );
00622 return TRUE;
00623 }
00624 }
00625
00626 return FALSE;
00627 }
00628
00630
00631
00632 BOOL CDownloadWithTorrent::SeedTorrent(LPCTSTR pszTarget)
00633 {
00634 CDownload* pDownload = reinterpret_cast<CDownload*>(this);
00635
00636 if ( IsMoving() || IsCompleted() ) return FALSE;
00637 if ( m_sLocalName == pszTarget ) return FALSE;
00638
00639 ASSERT( m_pFile != NULL );
00640 if ( m_pFile == NULL ) return FALSE;
00641 ASSERT( m_pFile->IsOpen() == FALSE );
00642 if ( m_pFile->IsOpen() ) return FALSE;
00643 delete m_pFile;
00644 m_pFile = NULL;
00645
00646 GenerateTorrentDownloadID();
00647
00648 pDownload->m_bSeeding = TRUE;
00649 pDownload->m_bComplete = TRUE;
00650 pDownload->m_tCompleted = GetTickCount();
00651
00652 memset( m_pTorrentBlock, TS_TRUE, m_nTorrentBlock );
00653 m_nTorrentSuccess = m_nTorrentBlock;
00654
00655 if ( m_sLocalName.GetLength() > 0 )
00656 {
00657 ASSERT( FALSE );
00658 ::DeleteFile( m_sLocalName );
00659 ::DeleteFile( m_sLocalName + _T(".sd") );
00660 }
00661
00662 m_sLocalName = pszTarget;
00663 SetModified();
00664
00665 m_tTorrentTracker = GetTickCount() + ( 60 * 1000 );
00666 m_bTorrentRequested = TRUE;
00667 m_bTorrentStarted = FALSE;
00668 m_nTorrentUploaded = 0;
00669 m_nTorrentDownloaded = 0;
00670
00671 if ( ( Settings.Connection.FirewallStatus == CONNECTION_FIREWALLED ) && ( GetSourceCount() < 40 ) )
00672 CBTTrackerRequest::SendStarted( this );
00673 else
00674 CBTTrackerRequest::SendStarted( this, 0 );
00675
00676 return TRUE;
00677 }
00678
00680
00681
00682 void CDownloadWithTorrent::CloseTorrent()
00683 {
00684 if ( m_bTorrentRequested ) CBTTrackerRequest::SendStopped( this );
00685 m_bTorrentRequested = FALSE;
00686 m_bTorrentStarted = FALSE;
00687 CloseTorrentUploads();
00688
00689 }
00690
00691
00693
00694
00695 float CDownloadWithTorrent::GetRatio() const
00696 {
00697 if ( m_nTorrentUploaded == 0 || m_nTorrentDownloaded == 0 ) return 0;
00698 return (float)m_nTorrentUploaded / (float)m_nTorrentDownloaded;
00699 }
00700
00702
00703
00704 BOOL CDownloadWithTorrent::CheckTorrentRatio() const
00705 {
00706 if ( ! m_bBTH ) return TRUE;
00707
00708 if ( m_nStartTorrentDownloads == dtAlways ) return TRUE;
00709
00710 if ( m_nStartTorrentDownloads == dtWhenRatio )
00711 {
00712 if ( m_nTorrentUploaded > m_nTorrentDownloaded ) return TRUE;
00713 if ( GetVolumeComplete() < 5 * 1024 * 1024 ) return TRUE;
00714 }
00715
00716 return FALSE;
00717 }
00718
00720
00721
00722 BOOL CDownloadWithTorrent::UploadExists(in_addr* pIP) const
00723 {
00724 for ( POSITION pos = m_pTorrentUploads.GetHeadPosition() ; pos ; )
00725 {
00726 CUploadTransferBT* pTransfer = (CUploadTransferBT*)m_pTorrentUploads.GetNext( pos );
00727
00728 if ( ( pTransfer->m_nProtocol == PROTOCOL_BT ) &&
00729 ( pTransfer->m_nState != upsNull ) &&
00730 ( pTransfer->m_pHost.sin_addr.S_un.S_addr == pIP->S_un.S_addr ) )
00731 return TRUE;
00732 }
00733 return FALSE;
00734 }
00735
00736 BOOL CDownloadWithTorrent::UploadExists(SHA1* pGUID) const
00737 {
00738 for ( POSITION pos = m_pTorrentUploads.GetHeadPosition() ; pos ; )
00739 {
00740 CUploadTransferBT* pTransfer = (CUploadTransferBT*)m_pTorrentUploads.GetNext( pos );
00741
00742 if ( ( pTransfer->m_nProtocol == PROTOCOL_BT ) &&
00743 ( pTransfer->m_nState != upsNull ) &&
00744 ( memcmp( pGUID, &pTransfer->m_pClient->m_pGUID, 16 ) == 0 ) )
00745 return TRUE;
00746 }
00747 return FALSE;
00748 }