📄 uploads.cpp
字号:
//
// Uploads.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 "Uploads.h"
#include "UploadQueue.h"
#include "UploadQueues.h"
#include "UploadTransfer.h"
#include "UploadTransferHTTP.h"
#include "UploadTransferED2K.h"
#include "Buffer.h"
#include "Transfers.h"
#include "Neighbours.h"
#include "Statistics.h"
#include "Remote.h"
#include "WndMain.h"
#include "WndMedia.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
CUploads Uploads;
//////////////////////////////////////////////////////////////////////
// CUploads construction
CUploads::CUploads()
{
m_nCount = 0;
m_nBandwidth = 0;
m_nTorrentSpeed = 0;
m_bStable = FALSE;
m_nBestSpeed = 0;
}
CUploads::~CUploads()
{
Clear( FALSE );
}
//////////////////////////////////////////////////////////////////////
// CUploads clear
void CUploads::Clear(BOOL bMessage)
{
for ( POSITION pos = GetIterator() ; pos ; )
{
GetNext( pos )->Remove( bMessage );
}
ASSERT( GetCount( NULL, -1 ) == 0 );
}
//////////////////////////////////////////////////////////////////////
// CUploads counting
int CUploads::GetCount(CUploadTransfer* pExcept, int nState) const
{
if ( pExcept == NULL && nState == -1 ) return m_pList.GetCount();
int nCount = 0;
for ( POSITION pos = GetIterator() ; pos ; )
{
CUploadTransfer* pUpload = GetNext( pos );
if ( pUpload != pExcept )
{
switch ( nState )
{
case -1:
nCount++;
break;
case -2:
if ( pUpload->m_nState > upsNull ) nCount++;
break;
default:
if ( pUpload->m_nState == nState ) nCount++;
break;
}
}
}
return nCount;
}
//////////////////////////////////////////////////////////////////////
// CUploads status
void CUploads::SetStable(DWORD nSpeed)
{
m_bStable = TRUE;
m_nBestSpeed = max( m_nBestSpeed, nSpeed );
}
DWORD CUploads::GetBandwidth() const
{
DWORD nTotal = 0;
for ( POSITION pos = GetIterator() ; pos ; )
{
nTotal += GetNext( pos )->GetMeasuredSpeed();
}
return nTotal;
}
//////////////////////////////////////////////////////////////////////
// CUploads per-host limiting
BOOL CUploads::AllowMoreTo(IN_ADDR* pAddress) const
{
int nCount = 0;
for ( POSITION pos = GetIterator() ; pos ; )
{
CUploadTransfer* pUpload = GetNext( pos );
if ( pUpload->m_nState == upsUploading ||
pUpload->m_nState == upsQueued )
{
if ( pUpload->m_pHost.sin_addr.S_un.S_addr == pAddress->S_un.S_addr )
nCount++;
}
}
return ( nCount <= Settings.Uploads.MaxPerHost );
}
BOOL CUploads::EnforcePerHostLimit(CUploadTransfer* pHit, BOOL bRequest)
{
int nCount = 0;
for ( POSITION pos = GetIterator() ; pos ; )
{
CUploadTransfer* pUpload = GetNext( pos );
if ( pUpload->m_nState == upsUploading ||
pUpload->m_nState == upsQueued ||
pUpload->m_nState == upsPreQueue )
{
if ( pUpload->m_pHost.sin_addr.S_un.S_addr == pHit->m_pHost.sin_addr.S_un.S_addr )
nCount++;
}
}
if ( nCount <= Settings.Uploads.MaxPerHost ) return FALSE;
while ( nCount > Settings.Uploads.MaxPerHost )
{
CUploadTransfer* pNewest = NULL;
for ( pos = GetIterator() ; pos ; )
{
CUploadTransfer* pUpload = GetNext( pos );
if ( pUpload->m_nState == upsUploading ||
pUpload->m_nState == upsQueued ||
pUpload->m_nState == upsPreQueue )
{
if ( pUpload != pHit && pUpload->m_pHost.sin_addr.S_un.S_addr == pHit->m_pHost.sin_addr.S_un.S_addr )
{
if ( bRequest && pUpload->m_pBaseFile == pHit->m_pBaseFile )
{
pNewest = pUpload;
break;
}
if ( pNewest == NULL || pUpload->m_tConnected > pNewest->m_tConnected )
pNewest = pUpload;
}
}
}
if ( pNewest == NULL ) break;
if ( bRequest )
{
if ( pNewest->m_pBaseFile == pHit->m_pBaseFile && ! pNewest->m_bLive )
{
UploadQueues.StealPosition( pHit, pNewest );
theApp.Message( MSG_ERROR, IDS_UPLOAD_DROPPED_OLDER,
(LPCTSTR)pNewest->m_sAddress );
pNewest->Close( FALSE );
}
else
{
return FALSE;
}
}
else
{
theApp.Message( MSG_ERROR, IDS_UPLOAD_DROPPED_NEWER, (LPCTSTR)pNewest->m_sAddress );
pNewest->Close( FALSE );
}
nCount--;
}
return FALSE;
}
//////////////////////////////////////////////////////////////////////
// CUploads run
void CUploads::OnRun()
{
CSingleLock pLock( &UploadQueues.m_pSection, TRUE );
int nCountTorrent = 0;
POSITION pos;
m_nCount = 0;
m_nBandwidth = 0;
for ( pos = UploadQueues.GetIterator() ; pos ; )
{
UploadQueues.GetNext( pos )->m_nMeasured = 0;
}
for ( pos = GetIterator() ; pos ; )
{
CUploadTransfer* pTransfer = GetNext( pos );
DWORD nMeasured = pTransfer->GetMeasuredSpeed();
if ( pTransfer->m_nState == upsUploading )
{
m_nCount ++;
if ( pTransfer->m_nProtocol == PROTOCOL_BT ) nCountTorrent ++;
m_nBandwidth += nMeasured;
if ( pTransfer->m_pQueue != NULL && UploadQueues.Check( pTransfer->m_pQueue ) )
pTransfer->m_pQueue->m_nMeasured += nMeasured;
}
}
if ( nCountTorrent > 0 )
{
m_nTorrentSpeed = Settings.Bandwidth.Uploads;
if ( m_nTorrentSpeed == 0 ) m_nTorrentSpeed = 0xFFFFFFFF;
m_nTorrentSpeed = min( m_nTorrentSpeed, Settings.Connection.OutSpeed * 128 );
m_nTorrentSpeed = m_nTorrentSpeed * 4 / 5;
m_nTorrentSpeed = m_nTorrentSpeed / nCountTorrent;
m_nTorrentSpeed = max( m_nTorrentSpeed, Settings.Bandwidth.Request );
}
else
{
m_nTorrentSpeed = 0;
}
}
//////////////////////////////////////////////////////////////////////
// CUploads get connection
BOOL CUploads::OnAccept(CConnection* pConnection, LPCTSTR pszHandshake)
{
CSingleLock pLock( &Transfers.m_pSection );
if ( ! pLock.Lock( 250 ) ) return FALSE;
if ( Settings.Remote.Enable &&
_tcsncmp( pszHandshake, _T("GET /remote/"), 12 ) == 0 )
{
new CRemote( pConnection );
return TRUE;
}
else if ( Settings.Uploads.MaxPerHost > 0 )
{
CUploadTransfer* pUpload = new CUploadTransferHTTP();
for ( POSITION pos = GetIterator() ; pos ; )
{
CUploadTransfer* pTest = GetNext( pos );
if ( pTest->m_pHost.sin_addr.S_un.S_addr ==
pConnection->m_pHost.sin_addr.S_un.S_addr )
{
pTest->m_bLive = FALSE;
}
}
pUpload->AttachTo( pConnection );
return TRUE;
}
return FALSE;
}
//////////////////////////////////////////////////////////////////////
// CUploads rename handler
void CUploads::OnRename(LPCTSTR pszSource, LPCTSTR pszTarget)
{
CSingleLock pLock( &Transfers.m_pSection );
if ( pLock.Lock( 500 ) )
{
for ( POSITION pos = GetIterator() ; pos ; )
{
GetNext( pos )->OnRename( pszSource, pszTarget );
}
pLock.Unlock();
}
CSingleLock pLock2( &theApp.m_pSection );
if ( pLock2.Lock( 500 ) )
{
if ( CMainWnd* pMainWnd = (CMainWnd*)theApp.m_pSafeWnd )
{
CMediaWnd* pMediaWnd = (CMediaWnd*)pMainWnd->m_pWindows.Find(
RUNTIME_CLASS(CMediaWnd) );
if ( pMediaWnd != NULL )
{
pMediaWnd->OnFileDelete( pszSource );
}
}
pLock2.Unlock();
}
}
//////////////////////////////////////////////////////////////////////
// CUploads add and remove
void CUploads::Add(CUploadTransfer* pUpload)
{
POSITION pos = m_pList.Find( pUpload );
ASSERT( pos == NULL );
m_pList.AddHead( pUpload );
}
void CUploads::Remove(CUploadTransfer* pUpload)
{
POSITION pos = m_pList.Find( pUpload );
ASSERT( pos != NULL );
m_pList.RemoveAt( pos );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -