⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uploadtransfered2k.cpp

📁 著名的下载软件核心Shareaza
💻 CPP
📖 第 1 页 / 共 2 页
字号:
}

//////////////////////////////////////////////////////////////////////
// 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 + -