📄 uploadtransfered2k.cpp
字号:
}
//////////////////////////////////////////////////////////////////////
// CUploadTransferED2K cleanup
void CUploadTransferED2K::Cleanup(BOOL bDequeue)
{
if ( bDequeue ) UploadQueues.Dequeue( this );
if ( m_nState == upsUploading )
{
ASSERT( m_pBaseFile != NULL );
if ( m_nLength < SIZE_UNKNOWN ) m_pBaseFile->AddFragment( m_nOffset, m_nPosition );
ASSERT( m_pDiskFile != NULL );
CloseFile();
}
ClearRequest();
m_pRequested->DeleteChain();
m_pRequested = NULL;
m_pServed->DeleteChain();
m_pServed = NULL;
m_pBaseFile = NULL;
m_nState = upsReady;
}
//////////////////////////////////////////////////////////////////////
// CUploadTransferED2K send
void CUploadTransferED2K::Send(CEDPacket* pPacket, BOOL bRelease)
{
ASSERT( m_nState != upsNull );
ASSERT( m_pClient != NULL );
m_pClient->Send( pPacket, bRelease );
}
//////////////////////////////////////////////////////////////////////
// CUploadTransferED2K request a fragment
void CUploadTransferED2K::AddRequest(QWORD nOffset, QWORD nLength)
{
ASSERT( m_pBaseFile != NULL );
for ( CFileFragment* pFragment = m_pRequested ; pFragment ; pFragment = pFragment->m_pNext )
{
if ( pFragment->m_nOffset == nOffset && pFragment->m_nLength == nLength ) return;
}
m_pRequested = CFileFragment::New( NULL, m_pRequested, nOffset, nLength );
}
//////////////////////////////////////////////////////////////////////
// CUploadTransferED2K serve requests
BOOL CUploadTransferED2K::ServeRequests()
{
if ( m_nState != upsUploading && m_nState != upsRequest ) return TRUE;
ASSERT( m_pBaseFile != NULL );
if ( m_pClient == NULL || m_pClient->m_pOutput == NULL ) return TRUE;
if ( m_pClient->m_pOutput->m_nLength > Settings.eDonkey.FrameSize ) return TRUE;
if ( m_nLength == SIZE_UNKNOWN )
{
if ( ! OpenFile() ) return FALSE;
if ( ! StartNextRequest() ) return FALSE;
}
if ( m_nLength != SIZE_UNKNOWN )
{
if ( DispatchNextChunk() )
{
CheckFinishedRequest();
}
else
{
Cleanup();
Close();
return FALSE;
}
}
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CUploadTransferED2K file access
BOOL CUploadTransferED2K::OpenFile()
{
ASSERT( m_nState == upsRequest || m_nState == upsUploading );
ASSERT( m_pBaseFile != NULL );
if ( m_pDiskFile != NULL ) return TRUE;
m_pDiskFile = TransferFiles.Open( m_sFilePath, FALSE, FALSE );
if ( m_pDiskFile != NULL )
{
if ( CLibraryFile* pFile = LibraryMaps.LookupFileByPath( m_sFilePath, TRUE, TRUE, TRUE ) )
{
pFile->m_nUploadsToday++;
pFile->m_nUploadsTotal++;
Library.Unlock();
}
return TRUE;
}
theApp.Message( MSG_ERROR, IDS_UPLOAD_CANTOPEN, (LPCTSTR)m_sAddress, (LPCTSTR)m_sFileName );
CEDPacket* pReply = CEDPacket::New( ED2K_C2C_FILENOTFOUND );
pReply->Write( &m_pED2K, sizeof(MD4) );
Send( pReply );
Cleanup();
Close();
return FALSE;
}
//////////////////////////////////////////////////////////////////////
// CUploadTransferED2K start the next request
BOOL CUploadTransferED2K::StartNextRequest()
{
ASSERT( m_nState == upsUploading || m_nState == upsRequest );
ASSERT( m_pDiskFile != NULL );
while ( m_pRequested != NULL && m_nLength == SIZE_UNKNOWN )
{
CFileFragment* pFragment = m_pRequested;
m_pRequested = pFragment->m_pNext;
for ( CFileFragment* pOld = m_pServed ; pOld ; pOld = pOld->m_pNext )
{
if ( pOld->m_nOffset == pFragment->m_nOffset && pOld->m_nLength == pFragment->m_nLength ) break;
}
if ( pOld == NULL &&
pFragment->m_nOffset < m_nFileSize &&
pFragment->m_nOffset + pFragment->m_nLength <= m_nFileSize )
{
m_nOffset = pFragment->m_nOffset;
m_nLength = pFragment->m_nLength;
m_nPosition = 0;
}
pFragment->DeleteThis();
}
if ( m_nLength < SIZE_UNKNOWN )
{
m_nState = upsUploading;
m_tContent = m_pClient->m_mOutput.tLast = GetTickCount();
theApp.Message( MSG_DEFAULT, IDS_UPLOAD_CONTENT,
m_nOffset, m_nOffset + m_nLength - 1,
(LPCTSTR)m_sFileName, (LPCTSTR)m_sAddress,
(LPCTSTR)m_sUserAgent );
return TRUE;
}
else
{
Send( CEDPacket::New( ED2K_C2C_FINISHUPLOAD ) );
Cleanup();
Close( TRUE );
return FALSE;
}
}
//////////////////////////////////////////////////////////////////////
// CUploadTransferED2K chunk dispatch
BOOL CUploadTransferED2K::DispatchNextChunk()
{
ASSERT( m_nState == upsUploading );
ASSERT( m_pDiskFile != NULL );
ASSERT( m_nLength < SIZE_UNKNOWN );
ASSERT( m_nPosition < m_nLength );
QWORD nChunk = m_nLength - m_nPosition;
nChunk = min( nChunk, Settings.eDonkey.FrameSize );
#if 0
// Use packet form
CEDPacket* pPacket = CEDPacket::New( ED2K_C2C_SENDINGPART );
pPacket->Write( &m_pED2K, sizeof(MD4) );
pPacket->WriteLongLE( m_nOffset + m_nPosition );
pPacket->WriteLongLE( m_nOffset + m_nPosition + nChunk );
m_pDiskFile->Read( m_nFileBase + m_nOffset + m_nPosition, pPacket->GetWritePointer( nChunk ), nChunk, &nChunk );
// SetFilePointer( hFile, m_nFileBase + m_nOffset + m_nPosition, NULL, FILE_BEGIN );
// ReadFile( hFile, pPacket->WriteGetPointer( nChunk ), nChunk, &nChunk, NULL );
if ( nChunk == 0 )
{
pPacket->Release();
return FALSE;
}
pPacket->m_nLength = sizeof(MD4) + 8 + nChunk;
Send( pPacket );
#else
// Raw write
CBuffer* pBuffer = m_pClient->m_pOutput;
pBuffer->EnsureBuffer( sizeof(ED2K_PART_HEADER) + (DWORD)nChunk );
ED2K_PART_HEADER* pHeader = (ED2K_PART_HEADER*)( pBuffer->m_pBuffer + pBuffer->m_nLength );
if ( ! m_pDiskFile->Read( m_nFileBase + m_nOffset + m_nPosition, &pHeader[1], nChunk, &nChunk ) ) return FALSE;
// SetFilePointer( hFile, m_nFileBase + m_nOffset + m_nPosition, NULL, FILE_BEGIN );
// ReadFile( hFile, &pHeader[1], nChunk, &nChunk, NULL );
if ( nChunk == 0 ) return FALSE;
pHeader->nProtocol = ED2K_PROTOCOL_EDONKEY;
pHeader->nType = ED2K_C2C_SENDINGPART;
pHeader->nLength = 1 + sizeof(MD4) + 8 + (DWORD)nChunk;
pHeader->pMD4 = m_pED2K;
pHeader->nOffset1 = (DWORD)( m_nOffset + m_nPosition );
pHeader->nOffset2 = (DWORD)( m_nOffset + m_nPosition + nChunk );
pBuffer->m_nLength += sizeof(ED2K_PART_HEADER) + (DWORD)nChunk;
m_pClient->Send( NULL );
#endif
m_nPosition += nChunk;
m_nUploaded += nChunk;
Statistics.Current.Uploads.Volume += ( nChunk / 1024 );
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CUploadTransferED2K request
BOOL CUploadTransferED2K::CheckFinishedRequest()
{
ASSERT( m_nState == upsUploading );
if ( m_nPosition < m_nLength ) return FALSE;
theApp.Message( MSG_DEFAULT, IDS_UPLOAD_FINISHED,
(LPCTSTR)m_sFileName, (LPCTSTR)m_sAddress );
m_pServed = CFileFragment::New( NULL, m_pServed, m_nOffset, m_nLength );
m_pBaseFile->AddFragment( m_nOffset, m_nLength );
m_nLength = SIZE_UNKNOWN;
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CUploadTransferED2K ranking update
BOOL CUploadTransferED2K::SendRanking()
{
ASSERT( m_pQueue != NULL );
int nPosition = UploadQueues.GetPosition( this, TRUE );
if ( nPosition < 0 )
{
Cleanup();
Close( TRUE );
return FALSE;
}
if ( m_nRanking == nPosition ) return TRUE;
m_nRanking = nPosition;
if ( nPosition == 0 )
{
m_tRequest = GetTickCount();
if ( m_pClient->IsOnline() )
{
m_nState = upsRequest;
Send( CEDPacket::New( ED2K_C2C_STARTUPLOAD ) );
}
else
{
m_nState = upsConnecting;
m_pClient->Connect();
}
}
else if ( m_pClient->IsOnline() )
{
CSingleLock pLock( &UploadQueues.m_pSection, TRUE );
if ( UploadQueues.Check( m_pQueue ) )
{
theApp.Message( MSG_DEFAULT, IDS_UPLOAD_QUEUED, (LPCTSTR)m_sFileName,
(LPCTSTR)m_sAddress, nPosition, m_pQueue->GetQueuedCount(),
(LPCTSTR)m_pQueue->m_sName );
}
pLock.Unlock();
m_nState = upsQueued;
if ( m_pClient->m_bEmule )
{
CEDPacket* pPacket = CEDPacket::New( ED2K_C2C_QUEUERANKING, ED2K_PROTOCOL_EMULE );
pPacket->WriteShortLE( nPosition );
pPacket->WriteShortLE( 0 );
pPacket->WriteLongLE( 0 );
pPacket->WriteLongLE( 0 );
Send( pPacket );
}
else
{
CEDPacket* pPacket = CEDPacket::New( ED2K_C2C_QUEUERANK );
pPacket->WriteLongLE( nPosition );
Send( pPacket );
}
}
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CUploadTransferED2K reask
BOOL CUploadTransferED2K::OnReask()
{
if ( m_nState != upsQueued ) return FALSE;
int nPosition = UploadQueues.GetPosition( this, TRUE );
if ( nPosition < 0 ) return FALSE;
CEDPacket* pPacket = CEDPacket::New( ED2K_C2C_UDP_REASKACK, ED2K_PROTOCOL_EMULE );
pPacket->WriteShortLE( nPosition );
Datagrams.Send( &m_pClient->m_pHost.sin_addr, m_pClient->m_nUDP, pPacket );
m_tRequest = GetTickCount();
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -