Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

UploadTransferED2K.cpp

Go to the documentation of this file.
00001 //
00002 // UploadTransferED2K.cpp
00003 //
00004 // Copyright (c) Shareaza Development Team, 2002-2005.
00005 // This file is part of SHAREAZA (www.shareaza.com)
00006 //
00007 // Shareaza is free software; you can redistribute it
00008 // and/or modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2 of
00010 // the License, or (at your option) any later version.
00011 //
00012 // Shareaza is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU General Public License
00018 // along with Shareaza; if not, write to the Free Software
00019 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 //
00021 
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "Settings.h"
00025 #include "Datagrams.h"
00026 #include "UploadFile.h"
00027 #include "UploadQueue.h"
00028 #include "UploadQueues.h"
00029 #include "UploadTransferED2K.h"
00030 #include "Statistics.h"
00031 #include "EDClient.h"
00032 #include "EDPacket.h"
00033 #include "ED2K.h"
00034 
00035 #include "Buffer.h"
00036 #include "Library.h"
00037 #include "Download.h"
00038 #include "Downloads.h"
00039 #include "SharedFile.h"
00040 #include "TransferFile.h"
00041 #include "FragmentedFile.h"
00042 
00043 #ifdef _DEBUG
00044 #undef THIS_FILE
00045 static char THIS_FILE[]=__FILE__;
00046 #define new DEBUG_NEW
00047 #endif
00048 
00049 
00051 // CUploadTransferED2K construction
00052 
00053 CUploadTransferED2K::CUploadTransferED2K(CEDClient* pClient) : CUploadTransfer( PROTOCOL_ED2K )
00054 {
00055         ASSERT( pClient != NULL );
00056         
00057         m_pClient               = pClient;
00058         m_nState                = upsReady;
00059         m_tRequest              = GetTickCount();
00060         
00061         m_sUserAgent    = m_pClient->m_sUserAgent;
00062         m_pHost                 = m_pClient->m_pHost;
00063         m_sAddress              = inet_ntoa( m_pHost.sin_addr );
00064         m_sNick                 = m_pClient->m_sNick;
00065         
00066         m_tRankingSent  = 0;
00067         m_tRankingCheck = 0;
00068         m_tLastRun              = 0;
00069         
00070         m_pClient->m_mOutput.pLimit = &m_nBandwidth;
00071 }
00072 
00073 CUploadTransferED2K::~CUploadTransferED2K()
00074 {
00075         ASSERT( m_pClient == NULL );
00076 }
00077 
00079 // CUploadTransferED2K request
00080 
00081 BOOL CUploadTransferED2K::Request(MD4* pMD4)
00082 {
00083         BOOL bSame = ( m_bED2K && m_pED2K == *pMD4 );
00084         
00085         Cleanup( ! bSame );
00086         
00087         CSingleLock oLock( &Library.m_pSection, TRUE );
00088         if ( CLibraryFile* pFile = LibraryMaps.LookupFileByED2K( pMD4, TRUE, TRUE ) )
00089         {
00090                 // Send comments if necessary
00091                 if ( m_pClient ) m_pClient->SendCommentsPacket( pFile->m_nRating, pFile->m_sComments );
00092 
00093                 RequestComplete( pFile );
00094                 oLock.Unlock();
00095         }
00096         else
00097         {
00098                 oLock.Unlock();
00099                 if ( CDownload* pFile = Downloads.FindByED2K( pMD4, TRUE ) )
00100                 {
00101                         RequestPartial( pFile );
00102                 }
00103                 else
00104                 {
00105                         UploadQueues.Dequeue( this );
00106                         
00107                         theApp.Message( MSG_ERROR, IDS_UPLOAD_FILENOTFOUND, (LPCTSTR)m_sAddress,
00108                                 (LPCTSTR)CED2K::HashToString( pMD4, TRUE ) );   
00109                         
00110                         CEDPacket* pReply = CEDPacket::New( ED2K_C2C_FILENOTFOUND );
00111                         pReply->Write( pMD4, sizeof(MD4) );
00112                         Send( pReply );
00113                         
00114                         Close();
00115                         return FALSE;
00116                 }
00117         }
00118         
00119         if ( UploadQueues.GetPosition( this, FALSE ) < 0 && ! UploadQueues.Enqueue( this ) )
00120         {
00121                 theApp.Message( MSG_ERROR, IDS_UPLOAD_BUSY_QUEUE,
00122                         (LPCTSTR)m_sFileName, (LPCTSTR)m_sAddress, _T("ED2K") );        
00123                 
00124                 CEDPacket* pReply = CEDPacket::New( ED2K_C2C_FILENOTFOUND );
00125                 pReply->Write( pMD4, sizeof(MD4) );
00126                 Send( pReply );
00127                 
00128                 Close();
00129                 return FALSE;
00130         }
00131         
00132         AllocateBaseFile();
00133         
00134         theApp.Message( MSG_SYSTEM, IDS_UPLOAD_FILE,
00135                 (LPCTSTR)m_sFileName, (LPCTSTR)m_sAddress );
00136         
00137         m_nRanking = -1;
00138         return CheckRanking();
00139 }
00140 
00142 // CUploadTransferED2K close
00143 
00144 void CUploadTransferED2K::Close(BOOL bMessage)
00145 {
00146         if ( m_nState == upsNull )
00147         {
00148                 if ( m_pClient != NULL ) m_pClient->OnUploadClose();
00149                 m_pClient = NULL;
00150                 return;
00151         }
00152         
00153         if ( m_pBaseFile != NULL && m_pClient->IsOnline() )
00154         {
00155                 if ( m_nState == upsUploading || m_nState == upsQueued )
00156                 {
00157                         Send( CEDPacket::New( ED2K_C2C_FINISHUPLOAD ) );
00158                 }
00159                 
00160                 CEDPacket* pPacket = CEDPacket::New( ED2K_C2C_FILENOTFOUND );
00161                 pPacket->Write( &m_pED2K, sizeof(MD4) );
00162                 Send( pPacket );
00163         }
00164         
00165         Cleanup();
00166         
00167         ASSERT( m_pClient != NULL );
00168         m_pClient->OnUploadClose();
00169         m_pClient = NULL;
00170         
00171         CUploadTransfer::Close( bMessage );
00172 }
00173 
00175 // CUploadTransferED2K run
00176 
00177 BOOL CUploadTransferED2K::OnRun()
00178 {
00179         return OnRunEx( GetTickCount() );
00180 }
00181 
00182 BOOL CUploadTransferED2K::OnRunEx(DWORD tNow)
00183 {
00184         // Limit per-source packet rate
00185         if ( tNow - m_tLastRun < Settings.eDonkey.SourceThrottle ) return FALSE;
00186         m_tLastRun = tNow;
00187 
00188 
00189         if ( m_nState == upsQueued )
00190         {
00191                 if ( m_pClient->IsOnline() == FALSE && tNow > m_tRequest &&
00192                          tNow - m_tRequest >= Settings.eDonkey.DequeueTime * 1000 )
00193                 {
00194                         theApp.Message( MSG_ERROR, IDS_UPLOAD_QUEUE_TIMEOUT, (LPCTSTR)m_sAddress );
00195                         Close();
00196                         return FALSE;
00197                 }
00198                 else 
00199                 {
00200                         DWORD nCheckThrottle;   // Throttle for how often ED2K clients have queue rank checked
00201                         if ( m_nRanking <= 2 ) nCheckThrottle = 2 * 1000;
00202                         else if ( m_nRanking < 10 ) nCheckThrottle = 15 * 1000;
00203                         else if ( m_nRanking < 50 ) nCheckThrottle = 1 * 60 * 1000;
00204                         else if ( m_nRanking < 200 ) nCheckThrottle = 4 * 60 * 1000;
00205                         else nCheckThrottle = 8 * 60 * 1000;
00206 
00207                         if ( tNow > m_tRankingCheck && tNow - m_tRankingCheck >= nCheckThrottle )       
00208                         {       
00209                                 // Check the queue rank. Start upload or send rank update if required.
00210                                 if ( ! CheckRanking() ) return FALSE;
00211                         }
00212                 }
00213         }
00214         else if ( m_nState == upsUploading )
00215         {
00216                 if ( ! ServeRequests() ) return FALSE;
00217                 
00218                 if ( tNow > m_pClient->m_mOutput.tLast &&
00219                          tNow - m_pClient->m_mOutput.tLast > Settings.Connection.TimeoutTraffic * 3 )
00220                 {
00221                         theApp.Message( MSG_ERROR, IDS_UPLOAD_TRAFFIC_TIMEOUT, (LPCTSTR)m_sAddress );
00222                         Close();
00223                         return FALSE;
00224                 }
00225         }
00226         else if ( m_nState == upsReady || m_nState == upsRequest )
00227         {
00228                 if ( tNow > m_tRequest && tNow - m_tRequest > Settings.Connection.TimeoutHandshake )
00229                 {
00230                         theApp.Message( MSG_ERROR, IDS_UPLOAD_REQUEST_TIMEOUT, (LPCTSTR)m_sAddress );
00231                         Close();
00232                         return FALSE;
00233                 }
00234         }
00235         else if ( m_nState == upsConnecting )
00236         {
00237                 if ( tNow > m_tRequest && tNow - m_tRequest > Settings.Connection.TimeoutConnect + Settings.Connection.TimeoutHandshake + 10000 )
00238                 {
00239                         Close( TRUE );
00240                         return FALSE;
00241                 }
00242         }
00243         
00244         return CUploadTransfer::OnRun();
00245 }
00246 
00248 // CUploadTransferED2K connection establishment
00249 
00250 BOOL CUploadTransferED2K::OnConnected()
00251 {
00252         if ( m_nState != upsConnecting ) return TRUE;
00253         
00254         m_tRequest = GetTickCount();
00255         m_nRanking = -1;
00256         
00257         m_pClient->m_mOutput.pLimit = &m_nBandwidth;
00258         
00259         return CheckRanking();
00260 }
00261 
00263 // CUploadTransferED2K connection lost
00264 
00265 void CUploadTransferED2K::OnDropped(BOOL bError)
00266 {
00267         if ( m_nState == upsQueued )
00268         {
00269                 theApp.Message( MSG_DEFAULT, IDS_UPLOAD_QUEUE_DROP, (LPCTSTR)m_sAddress );
00270                 
00271                 m_tRequest = GetTickCount();
00272                 
00273                 m_oRequested.clear();
00274                 
00275                 m_oServed.clear();
00276         }
00277         else
00278         {
00279                 theApp.Message( MSG_ERROR, IDS_UPLOAD_DROPPED, (LPCTSTR)m_sAddress );
00280                 Close();
00281         }
00282 }
00283 
00285 // CUploadTransferED2K queue drop hook
00286 
00287 void CUploadTransferED2K::OnQueueKick()
00288 {
00289         m_nRanking = -1;
00290         
00291         if ( m_nState == upsRequest || m_nState == upsUploading )
00292         {
00293                 if ( UploadQueues.GetPosition( this, TRUE ) == 0 ) return;
00294                 
00295                 if ( m_pBaseFile != NULL && m_pClient->IsOnline() )
00296                 {
00297                         Send( CEDPacket::New( ED2K_C2C_FINISHUPLOAD ) );
00298                 }
00299                 
00300                 Cleanup( FALSE );
00301         }
00302         else
00303         {
00304                 CheckRanking();
00305         }
00306 }
00307 
00309 // CUploadTransferED2K speed measurement
00310 
00311 DWORD CUploadTransferED2K::GetMeasuredSpeed()
00312 {
00313         if ( m_pClient == NULL ) return 0;
00314         m_pClient->Measure();
00315         return m_pClient->m_mOutput.nMeasure;
00316 }
00317 
00319 // CUploadTransferED2K queue release
00320 
00321 BOOL CUploadTransferED2K::OnQueueRelease(CEDPacket* pPacket)
00322 {
00323         Cleanup();
00324         Close( TRUE );
00325         return FALSE;
00326 }
00327 
00329 // CUploadTransferED2K part request
00330 
00331 BOOL CUploadTransferED2K::OnRequestParts(CEDPacket* pPacket)
00332 {
00333         if ( pPacket->GetRemaining() < sizeof(MD4) + 4 * 3 * 2 )
00334         {
00335                 theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_BAD_PACKET, (LPCTSTR)m_sAddress, pPacket->m_nType );
00336                 Close();
00337                 return FALSE;
00338         }
00339         
00340         MD4 pMD4;
00341         pPacket->Read( &pMD4, sizeof(MD4) );
00342         
00343         if ( pMD4 != m_pED2K )
00344         {
00345                 if ( ! Request( &pMD4 ) ) return FALSE;
00346         }
00347         
00348         if ( m_nState != upsQueued && m_nState != upsRequest && m_nState != upsUploading )
00349         {
00350                 theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_BAD_PACKET, (LPCTSTR)m_sAddress, pPacket->m_nType );
00351                 Close();
00352                 return FALSE;
00353         }
00354         
00355         DWORD nOffset[2][3];
00356         pPacket->Read( nOffset, sizeof(DWORD) * 2 * 3 );
00357         
00358         for ( int nRequest = 0 ; nRequest < 3 ; nRequest++ )
00359         {
00360                 if ( nOffset[1][nRequest] <= m_nFileSize )
00361                 {
00362                         // Valid (or null) request
00363                         if ( nOffset[0][nRequest] < nOffset[1][nRequest] )
00364                         {
00365                                 // Add non-null ranges to the list
00366                                 AddRequest( nOffset[0][nRequest], nOffset[1][nRequest] - nOffset[0][nRequest] );
00367                         }
00368                 }
00369                 else
00370                 {
00371                         // Invalid request- had an impossible range.
00372                         theApp.Message( MSG_ERROR, _T("Invalid file range(s) in request from %s"), (LPCTSTR)m_sAddress );
00373                         // They probably have an incorrent hash associated with a file. Calling close now
00374                         // will send "file not found" to stop them re-asking, then close the connection.
00375                         Close();
00376                         return FALSE;
00377                 }
00378         }
00379         
00380         ServeRequests();
00381         
00382         return TRUE;
00383 }
00384 
00386 // CUploadTransferED2K cleanup
00387 
00388 void CUploadTransferED2K::Cleanup(BOOL bDequeue)
00389 {
00390         if ( bDequeue ) UploadQueues.Dequeue( this );
00391         
00392         if ( m_nState == upsUploading )
00393         {
00394                 ASSERT( m_pBaseFile != NULL );
00395                 if ( m_nLength < SIZE_UNKNOWN ) m_pBaseFile->AddFragment( m_nOffset, m_nPosition );
00396                 
00397                 ASSERT( m_pDiskFile != NULL );
00398                 CloseFile();
00399         }
00400         
00401         ClearRequest();
00402         
00403         m_oRequested.clear();
00404         
00405         m_oServed.clear();
00406         
00407         m_pBaseFile     = NULL;
00408         m_nState        = upsReady;
00409 }
00410 
00412 // CUploadTransferED2K send
00413 
00414 void CUploadTransferED2K::Send(CEDPacket* pPacket, BOOL bRelease)
00415 {
00416         ASSERT( m_nState != upsNull );
00417         ASSERT( m_pClient != NULL );
00418         m_pClient->Send( pPacket, bRelease );
00419 }
00420 
00422 // CUploadTransferED2K request a fragment
00423 
00424 void CUploadTransferED2K::AddRequest(QWORD nOffset, QWORD nLength)
00425 {
00426         ASSERT( m_pBaseFile != NULL );
00427         
00428     FF::SimpleFragment oRequest( nOffset, nOffset + nLength );
00429 
00430     if ( ::std::find( m_oRequested.begin(), m_oRequested.end(), oRequest ) == m_oRequested.end() )
00431     {
00432         m_oRequested.pushBack( oRequest );
00433     }
00434 }
00435 
00437 // CUploadTransferED2K serve requests
00438 
00439 BOOL CUploadTransferED2K::ServeRequests()
00440 {
00441         if ( m_nState != upsUploading && m_nState != upsRequest ) return TRUE;
00442         ASSERT( m_pBaseFile != NULL );
00443         
00444         if ( m_pClient == NULL || m_pClient->m_pOutput == NULL ) return TRUE;
00445         if ( m_pClient->m_pOutput->m_nLength > Settings.eDonkey.FrameSize ) return TRUE;
00446         
00447         if ( m_nLength == SIZE_UNKNOWN )
00448         {
00449                 // Check has just finished
00450                 if ( m_bStopTransfer )
00451                 {
00452                         m_tRotateTime = 0;
00453                         m_bStopTransfer = FALSE;
00454                         
00455                         CUploadQueue* pQueue = m_pQueue;
00456                         if ( pQueue ) pQueue->Dequeue( this );
00457                         pQueue->Enqueue( this, TRUE, FALSE );
00458                         
00459                         int nQpos = UploadQueues.GetPosition( this, TRUE );
00460                         if ( nQpos != 0 )
00461                         {                       
00462                                 if ( m_pBaseFile != NULL && m_pClient->IsOnline() )
00463                                 {
00464                                         Send( CEDPacket::New( ED2K_C2C_FINISHUPLOAD ) );
00465                                 }
00466                                 
00467                                 if ( nQpos > 0 )        // If we aren't uploading any more (the queue wasn't empty)
00468                                 {
00469                                         // Set state to queued, and reset ranking to send a queue ranking packet.
00470                                         m_tRequest = GetTickCount();
00471                                         m_nState = upsQueued;
00472                                         m_nRanking = -1;
00473                                 }
00474 
00475                                 return TRUE;
00476                         }
00477                 }
00478                 if ( ! OpenFile() ) return FALSE;
00479                 if ( ! StartNextRequest() ) return FALSE;
00480         }
00481         
00482         if ( m_nLength != SIZE_UNKNOWN )
00483         {
00484                 if ( DispatchNextChunk() )
00485                 {
00486                         CheckFinishedRequest();
00487                 }
00488                 else
00489                 {
00490                         Cleanup();
00491                         Close();
00492                         return FALSE;
00493                 }
00494         }
00495         return TRUE;
00496 }
00497 
00499 // CUploadTransferED2K file access
00500 
00501 BOOL CUploadTransferED2K::OpenFile()
00502 {
00503         ASSERT( m_nState == upsRequest || m_nState == upsUploading );
00504         ASSERT( m_pBaseFile != NULL );
00505         
00506         if ( m_pDiskFile != NULL ) return TRUE;
00507         m_pDiskFile = TransferFiles.Open( m_sFilePath, FALSE, FALSE );
00508         
00509         if ( m_pDiskFile != NULL )
00510         {
00511                 CQuickLock oLock( Library.m_pSection );
00512                 if ( CLibraryFile* pFile = LibraryMaps.LookupFileByPath( m_sFilePath, TRUE, TRUE ) )
00513                 {
00514                         pFile->m_nUploadsToday++;
00515                         pFile->m_nUploadsTotal++;
00516                 }
00517                 
00518                 return TRUE;
00519         }
00520         
00521         theApp.Message( MSG_ERROR, IDS_UPLOAD_CANTOPEN, (LPCTSTR)m_sFileName, (LPCTSTR)m_sAddress );    
00522         
00523         CEDPacket* pReply = CEDPacket::New( ED2K_C2C_FILENOTFOUND );
00524         pReply->Write( &m_pED2K, sizeof(MD4) );
00525         Send( pReply );
00526         
00527         Cleanup();
00528         Close();
00529         
00530         return FALSE;
00531 }
00532 
00534 // CUploadTransferED2K start the next request
00535 
00536 BOOL CUploadTransferED2K::StartNextRequest()
00537 {
00538         ASSERT( m_nState == upsUploading || m_nState == upsRequest );
00539         ASSERT( m_pDiskFile != NULL );
00540         
00541         while ( !m_oRequested.empty() && m_nLength == SIZE_UNKNOWN )
00542         {
00543         if ( ::std::find( m_oServed.begin(), m_oServed.end(), *m_oRequested.begin() )
00544             == m_oServed.end()
00545             // This should be redundant (Camper)
00546             && m_oRequested.begin()->begin() < m_nFileSize
00547             && m_oRequested.begin()->end() <= m_nFileSize )
00548         {
00549             m_nOffset = m_oRequested.begin()->begin();
00550             m_nLength = m_oRequested.begin()->length();
00551             m_nPosition = 0;
00552         }
00553         m_oRequested.popFront();
00554         }
00555 
00556         if ( m_nLength < SIZE_UNKNOWN )
00557         {
00558                 m_nState        = upsUploading;
00559                 m_tContent      = m_pClient->m_mOutput.tLast = GetTickCount();
00560                 
00561                 theApp.Message( MSG_DEFAULT, IDS_UPLOAD_CONTENT,
00562                         m_nOffset, m_nOffset + m_nLength - 1,
00563                         (LPCTSTR)m_sFileName, (LPCTSTR)m_sAddress,
00564                         (LPCTSTR)m_sUserAgent );
00565                 
00566                 return TRUE;
00567         }
00568         else
00569         {
00570                 Send( CEDPacket::New( ED2K_C2C_FINISHUPLOAD ) );
00571                 Cleanup();
00572                 Close( TRUE );
00573                 return FALSE;
00574         }
00575 }
00576 
00578 // CUploadTransferED2K chunk dispatch
00579 
00580 BOOL CUploadTransferED2K::DispatchNextChunk()
00581 {
00582         ASSERT( m_nState == upsUploading );
00583         if ( !m_pDiskFile ) return FALSE;
00584         ASSERT( m_nLength < SIZE_UNKNOWN );
00585         ASSERT( m_nPosition < m_nLength );
00586         
00587         QWORD nChunk = m_nLength - m_nPosition;
00588         nChunk = min( nChunk, QWORD(Settings.eDonkey.FrameSize) );
00589         
00590 #if 0
00591         // Use packet form
00592         
00593         CEDPacket* pPacket = CEDPacket::New( ED2K_C2C_SENDINGPART );
00594         pPacket->Write( &m_pED2K, sizeof(MD4) );
00595         pPacket->WriteLongLE( m_nOffset + m_nPosition );
00596         pPacket->WriteLongLE( m_nOffset + m_nPosition + nChunk );
00597         
00598         m_pDiskFile->Read( m_nFileBase + m_nOffset + m_nPosition, pPacket->GetWritePointer( nChunk ), nChunk, &nChunk );
00599         // SetFilePointer( hFile, m_nFileBase + m_nOffset + m_nPosition, NULL, FILE_BEGIN );
00600         // ReadFile( hFile, pPacket->WriteGetPointer( nChunk ), nChunk, &nChunk, NULL );
00601         
00602         if ( nChunk == 0 )
00603         {
00604                 pPacket->Release();
00605                 return FALSE;
00606         }
00607         
00608         pPacket->m_nLength = sizeof(MD4) + 8 + nChunk;
00609         
00610         Send( pPacket );
00611         
00612 #else
00613         // Raw write
00614         
00615         CBuffer* pBuffer = m_pClient->m_pOutput;
00616         pBuffer->EnsureBuffer( sizeof(ED2K_PART_HEADER) + (DWORD)nChunk );
00617         
00618         ED2K_PART_HEADER* pHeader = (ED2K_PART_HEADER*)( pBuffer->m_pBuffer + pBuffer->m_nLength );
00619         
00620         if ( ! m_pDiskFile->Read( m_nFileBase + m_nOffset + m_nPosition, &pHeader[1], nChunk, &nChunk ) ) return FALSE;
00621         // SetFilePointer( hFile, m_nFileBase + m_nOffset + m_nPosition, NULL, FILE_BEGIN );
00622         // ReadFile( hFile, &pHeader[1], nChunk, &nChunk, NULL );
00623         if ( nChunk == 0 ) return FALSE;
00624         
00625         pHeader->nProtocol      = ED2K_PROTOCOL_EDONKEY;
00626         pHeader->nType          = ED2K_C2C_SENDINGPART;
00627         pHeader->nLength        = 1 + sizeof(MD4) + 8 + (DWORD)nChunk;
00628         pHeader->pMD4           = m_pED2K;
00629         pHeader->nOffset1       = (DWORD)( m_nOffset + m_nPosition );
00630         pHeader->nOffset2       = (DWORD)( m_nOffset + m_nPosition + nChunk );
00631         
00632         pBuffer->m_nLength += sizeof(ED2K_PART_HEADER) + (DWORD)nChunk;
00633         m_pClient->Send( NULL );
00634         
00635 #endif
00636         
00637         m_nPosition += nChunk;
00638         m_nUploaded += nChunk;
00639         Statistics.Current.Uploads.Volume += ( nChunk / 1024 );
00640         
00641         return TRUE;
00642 }
00643 
00645 // CUploadTransferED2K request
00646 
00647 BOOL CUploadTransferED2K::CheckFinishedRequest()
00648 {
00649         ASSERT( m_nState == upsUploading );
00650         
00651         if ( m_nPosition < m_nLength ) return FALSE;
00652         
00653         theApp.Message( MSG_DEFAULT, IDS_UPLOAD_FINISHED,
00654                 (LPCTSTR)m_sFileName, (LPCTSTR)m_sAddress );
00655         
00656     m_oServed.pushBack( FF::SimpleFragment( m_nOffset, m_nOffset + m_nLength ) );
00657         m_pBaseFile->AddFragment( m_nOffset, m_nLength );
00658         m_nLength = SIZE_UNKNOWN;
00659         
00660         return TRUE;
00661 }
00662 
00664 // CUploadTransferED2K ranking update
00665 
00666 BOOL CUploadTransferED2K::CheckRanking()
00667 {
00668         DWORD tNow = GetTickCount();
00669         int nPosition = UploadQueues.GetPosition( this, TRUE );
00670         
00671         if ( nPosition < 0 )
00672         {       
00673                 // Invalid queue position, or queue deleted. Drop client and exit.
00674                 Cleanup();
00675                 Close( TRUE );
00676                 return FALSE;
00677         }
00678         
00679         // Update 'ranking checked' timer
00680         m_tRankingCheck = tNow;
00681 
00682         // If queue ranking hasn't changed, don't bother sending an update
00683         // Note: if a rank was requested by the remote client, then m_nRanking will be set to -1.
00684         if ( m_nRanking == nPosition ) return TRUE;     
00685 
00686         
00687         if ( nPosition == 0 )
00688         {       
00689                 //Ready to start uploading
00690 
00691                 if ( m_pClient->IsOnline() )
00692                 {
00693                         if ( m_nState != upsUploading )
00694                         {
00695                                 m_nState = upsRequest;
00696                                 Send( CEDPacket::New( ED2K_C2C_STARTUPLOAD ) );
00697                         }
00698                 }
00699                 else
00700                 {
00701                         m_nState = upsConnecting;
00702                         m_pClient->Connect();
00703                 }
00704 
00705                 // Update the 'request sent' timer
00706                 m_tRequest = m_tRankingCheck;
00707 
00708                 // Update the 'ranking sent' variables
00709                 m_nRanking = nPosition;
00710                 m_tRankingSent = tNow;
00711         }
00712         else if ( m_pClient->IsOnline() )
00713         {       
00714                 //Upload is queued
00715 
00716                 // Check if we should send a ranking packet- If we have not sent one in a while, or one was requested
00717                 if ( ( tNow > m_tRankingSent && tNow - m_tRankingSent >= Settings.eDonkey.QueueRankThrottle ) ||
00718                          (  m_nRanking == -1 ) )
00719                          
00720                 {
00721                         // Send a queue rank packet
00722                         CSingleLock pLock( &UploadQueues.m_pSection, TRUE );
00723                         
00724                         if ( UploadQueues.Check( m_pQueue ) )
00725                         {
00726                                 theApp.Message( MSG_DEFAULT, IDS_UPLOAD_QUEUED, (LPCTSTR)m_sFileName,
00727                                         (LPCTSTR)m_sAddress, nPosition, m_pQueue->GetQueuedCount(),
00728                                         (LPCTSTR)m_pQueue->m_sName );
00729                         }
00730                         
00731                         pLock.Unlock();
00732                         
00733                         m_nState = upsQueued;
00734                         
00735                         if ( m_pClient->m_bEmule )
00736                         {       //eMule queue ranking
00737                                 CEDPacket* pPacket = CEDPacket::New( ED2K_C2C_QUEUERANKING, ED2K_PROTOCOL_EMULE );
00738                                 pPacket->WriteShortLE( nPosition );
00739                                 pPacket->WriteShortLE( 0 );
00740                                 pPacket->WriteLongLE( 0 );
00741                                 pPacket->WriteLongLE( 0 );
00742                                 Send( pPacket );
00743                         }
00744                         else
00745                         {       //older eDonkey style
00746                                 CEDPacket* pPacket = CEDPacket::New( ED2K_C2C_QUEUERANK );
00747                                 pPacket->WriteLongLE( nPosition );
00748                                 Send( pPacket );
00749                         }
00750 
00751                         // Update the 'ranking sent' variables
00752                         m_nRanking = nPosition;
00753                         m_tRankingSent = tNow;
00754                 }
00755         }
00756         
00757         return TRUE;
00758 }
00759 
00761 // CUploadTransferED2K reask
00762 
00763 BOOL CUploadTransferED2K::OnReask()
00764 {
00765         if ( m_nState != upsQueued ) return FALSE;
00766         
00767         int nPosition = UploadQueues.GetPosition( this, TRUE );
00768         if ( nPosition < 0 ) return FALSE;
00769         
00770         CEDPacket* pPacket = CEDPacket::New( ED2K_C2C_UDP_REASKACK, ED2K_PROTOCOL_EMULE );
00771         pPacket->WriteShortLE( nPosition );
00772         Datagrams.Send( &m_pClient->m_pHost.sin_addr, m_pClient->m_nUDP, pPacket );
00773         
00774         m_tRequest = GetTickCount();
00775         
00776         return TRUE;
00777 }

Generated on Thu Dec 15 10:39:51 2005 for Shareaza 2.2.1.0 by  doxygen 1.4.2