📄 uploadtransfered2k.cpp
字号:
//
// UploadTransferED2K.cpp
//
// Copyright (c) Shareaza Development Team, 2002-2004.
// This file is part of SHAREAZA (www.shareaza.com)
//
// Shareaza is free software; you can redistribute it
// and/or modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Shareaza is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Shareaza; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
#include "StdAfx.h"
#include "Shareaza.h"
#include "Settings.h"
#include "Datagrams.h"
#include "UploadFile.h"
#include "UploadQueue.h"
#include "UploadQueues.h"
#include "UploadTransferED2K.h"
#include "Statistics.h"
#include "EDClient.h"
#include "EDPacket.h"
#include "ED2K.h"
#include "Buffer.h"
#include "Library.h"
#include "Download.h"
#include "Downloads.h"
#include "SharedFile.h"
#include "TransferFile.h"
#include "FragmentedFile.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// CUploadTransferED2K construction
CUploadTransferED2K::CUploadTransferED2K(CEDClient* pClient) : CUploadTransfer( PROTOCOL_ED2K )
{
ASSERT( pClient != NULL );
m_pClient = pClient;
m_nState = upsReady;
m_tRequest = GetTickCount();
m_sUserAgent = m_pClient->m_sUserAgent;
m_pHost = m_pClient->m_pHost;
m_sAddress = inet_ntoa( m_pHost.sin_addr );
m_sNick = m_pClient->m_sNick;
m_tRanking = 0;
m_pRequested = NULL;
m_pServed = NULL;
m_pClient->m_mOutput.pLimit = &m_nBandwidth;
}
CUploadTransferED2K::~CUploadTransferED2K()
{
ASSERT( m_pClient == NULL );
ASSERT( m_pRequested == NULL );
ASSERT( m_pServed == NULL );
}
//////////////////////////////////////////////////////////////////////
// CUploadTransferED2K request
BOOL CUploadTransferED2K::Request(MD4* pMD4)
{
BOOL bSame = ( m_bED2K && m_pED2K == *pMD4 );
Cleanup( ! bSame );
if ( CLibraryFile* pFile = LibraryMaps.LookupFileByED2K( pMD4, TRUE, TRUE, TRUE ) )
{
RequestComplete( pFile );
Library.Unlock();
}
else if ( CDownload* pFile = Downloads.FindByED2K( pMD4, TRUE ) )
{
RequestPartial( pFile );
}
else
{
UploadQueues.Dequeue( this );
theApp.Message( MSG_ERROR, IDS_UPLOAD_FILENOTFOUND, (LPCTSTR)m_sAddress,
(LPCTSTR)CED2K::HashToString( pMD4, TRUE ) );
CEDPacket* pReply = CEDPacket::New( ED2K_C2C_FILENOTFOUND );
pReply->Write( pMD4, sizeof(MD4) );
Send( pReply );
Close();
return FALSE;
}
if ( UploadQueues.GetPosition( this, FALSE ) < 0 && ! UploadQueues.Enqueue( this ) )
{
theApp.Message( MSG_ERROR, IDS_UPLOAD_BUSY_QUEUE,
(LPCTSTR)m_sFileName, (LPCTSTR)m_sAddress, _T("ED2K") );
CEDPacket* pReply = CEDPacket::New( ED2K_C2C_FILENOTFOUND );
pReply->Write( pMD4, sizeof(MD4) );
Send( pReply );
Close();
return FALSE;
}
AllocateBaseFile();
theApp.Message( MSG_SYSTEM, IDS_UPLOAD_FILE,
(LPCTSTR)m_sFileName, (LPCTSTR)m_sAddress );
m_nRanking = -1;
return SendRanking();
}
//////////////////////////////////////////////////////////////////////
// CUploadTransferED2K close
void CUploadTransferED2K::Close(BOOL bMessage)
{
if ( m_nState == upsNull )
{
if ( m_pClient != NULL ) m_pClient->OnUploadClose();
m_pClient = NULL;
return;
}
if ( m_pBaseFile != NULL && m_pClient->IsOnline() )
{
if ( m_nState == upsUploading || m_nState == upsQueued )
{
Send( CEDPacket::New( ED2K_C2C_FINISHUPLOAD ) );
}
CEDPacket* pPacket = CEDPacket::New( ED2K_C2C_FILENOTFOUND );
pPacket->Write( &m_pED2K, sizeof(MD4) );
Send( pPacket );
}
Cleanup();
ASSERT( m_pClient != NULL );
m_pClient->OnUploadClose();
m_pClient = NULL;
CUploadTransfer::Close( bMessage );
}
//////////////////////////////////////////////////////////////////////
// CUploadTransferED2K run
BOOL CUploadTransferED2K::OnRun()
{
return OnRunEx( GetTickCount() );
}
BOOL CUploadTransferED2K::OnRunEx(DWORD tNow)
{
if ( m_nState == upsQueued )
{
if ( m_pClient->IsOnline() == FALSE && tNow > m_tRequest &&
tNow - m_tRequest >= Settings.eDonkey.DequeueTime * 1000 )
{
theApp.Message( MSG_ERROR, IDS_UPLOAD_QUEUE_TIMEOUT, (LPCTSTR)m_sAddress );
Close();
return FALSE;
}
else if ( tNow > m_tRanking && tNow - m_tRanking >= 5000 )
{
m_tRanking = GetTickCount();
if ( ! SendRanking() ) return FALSE;
}
}
else if ( m_nState == upsUploading )
{
if ( ! ServeRequests() ) return FALSE;
if ( tNow > m_pClient->m_mOutput.tLast &&
tNow - m_pClient->m_mOutput.tLast > Settings.Connection.TimeoutTraffic * 3 )
{
theApp.Message( MSG_ERROR, IDS_UPLOAD_TRAFFIC_TIMEOUT, (LPCTSTR)m_sAddress );
Close();
return FALSE;
}
}
else if ( m_nState == upsReady || m_nState == upsRequest )
{
if ( tNow > m_tRequest && tNow - m_tRequest > Settings.Connection.TimeoutHandshake )
{
theApp.Message( MSG_ERROR, IDS_UPLOAD_REQUEST_TIMEOUT, (LPCTSTR)m_sAddress );
Close();
return FALSE;
}
}
else if ( m_nState == upsConnecting )
{
if ( tNow > m_tRequest && tNow - m_tRequest > Settings.Connection.TimeoutConnect + Settings.Connection.TimeoutHandshake + 10000 )
{
Close( TRUE );
return FALSE;
}
}
return CUploadTransfer::OnRun();
}
//////////////////////////////////////////////////////////////////////
// CUploadTransferED2K connection establishment
BOOL CUploadTransferED2K::OnConnected()
{
if ( m_nState != upsConnecting ) return TRUE;
m_tRequest = GetTickCount();
m_nRanking = -1;
m_pClient->m_mOutput.pLimit = &m_nBandwidth;
return SendRanking();
}
//////////////////////////////////////////////////////////////////////
// CUploadTransferED2K connection lost
void CUploadTransferED2K::OnDropped(BOOL bError)
{
if ( m_nState == upsQueued )
{
theApp.Message( MSG_DEFAULT, IDS_UPLOAD_QUEUE_DROP, (LPCTSTR)m_sAddress );
m_tRequest = GetTickCount();
m_pRequested->DeleteChain();
m_pRequested = NULL;
m_pServed->DeleteChain();
m_pServed = NULL;
}
else
{
theApp.Message( MSG_ERROR, IDS_UPLOAD_DROPPED, (LPCTSTR)m_sAddress );
Close();
}
}
//////////////////////////////////////////////////////////////////////
// CUploadTransferED2K queue drop hook
void CUploadTransferED2K::OnQueueKick()
{
m_nRanking = -1;
if ( m_nState == upsRequest || m_nState == upsUploading )
{
if ( UploadQueues.GetPosition( this, TRUE ) == 0 ) return;
if ( m_pBaseFile != NULL && m_pClient->IsOnline() )
{
Send( CEDPacket::New( ED2K_C2C_FINISHUPLOAD ) );
}
Cleanup( FALSE );
}
else
{
SendRanking();
}
}
//////////////////////////////////////////////////////////////////////
// CUploadTransferED2K speed measurement
DWORD CUploadTransferED2K::GetMeasuredSpeed()
{
if ( m_pClient == NULL ) return 0;
m_pClient->Measure();
return m_pClient->m_mOutput.nMeasure;
}
//////////////////////////////////////////////////////////////////////
// CUploadTransferED2K queue release
BOOL CUploadTransferED2K::OnQueueRelease(CEDPacket* pPacket)
{
Cleanup();
Close( TRUE );
return FALSE;
}
//////////////////////////////////////////////////////////////////////
// CUploadTransferED2K part request
BOOL CUploadTransferED2K::OnRequestParts(CEDPacket* pPacket)
{
if ( pPacket->GetRemaining() < sizeof(MD4) + 4 * 3 * 2 )
{
theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_BAD_PACKET, (LPCTSTR)m_sAddress, pPacket->m_nType );
Close();
return FALSE;
}
MD4 pMD4;
pPacket->Read( &pMD4, sizeof(MD4) );
if ( pMD4 != m_pED2K )
{
if ( ! Request( &pMD4 ) ) return FALSE;
}
if ( m_nState != upsQueued && m_nState != upsRequest && m_nState != upsUploading )
{
theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_BAD_PACKET, (LPCTSTR)m_sAddress, pPacket->m_nType );
Close();
return FALSE;
}
DWORD nOffset[2][3];
pPacket->Read( nOffset, sizeof(DWORD) * 2 * 3 );
for ( int nRequest = 0 ; nRequest < 3 ; nRequest++ )
{
if ( nOffset[0][nRequest] < nOffset[1][nRequest] )
{
AddRequest( nOffset[0][nRequest], nOffset[1][nRequest] - nOffset[0][nRequest] );
}
}
ServeRequests();
return TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -