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

📄 downloadwithtiger.cpp

📁 著名的下载软件核心Shareaza
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// DownloadWithTiger.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 "Downloads.h"
#include "DownloadWithTiger.h"
#include "FragmentedFile.h"

#include "Neighbours.h"
#include "Transfers.h"
#include "Library.h"
#include "SharedFile.h"
#include "BTInfo.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


//////////////////////////////////////////////////////////////////////
// CDownloadWithTiger construction

CDownloadWithTiger::CDownloadWithTiger()
{
	m_pTigerBlock		= NULL;
	m_nTigerBlock		= 0;
	m_nTigerSuccess		= 0;
	
	m_pHashsetBlock		= NULL;
	m_nHashsetBlock		= 0;
	m_nHashsetSuccess	= 0;
	
	m_nVerifyCookie		= 0;
	m_nVerifyHash		= HASH_NULL;
	m_nVerifyBlock		= 0xFFFFFFFF;
}

CDownloadWithTiger::~CDownloadWithTiger()
{
	if ( m_pHashsetBlock != NULL ) delete [] m_pHashsetBlock;
	if ( m_pTigerBlock != NULL ) delete [] m_pTigerBlock;
}

//////////////////////////////////////////////////////////////////////
// CDownloadWithTiger informational access

DWORD CDownloadWithTiger::GetValidationCookie() const
{
	return m_nVerifyCookie;
}

QWORD CDownloadWithTiger::GetVerifyLength(int nHash) const
{
	if ( nHash == HASH_NULL )
	{
		if ( m_pTorrentBlock != NULL ) return m_nTorrentSize;
		else if ( m_pTigerBlock != NULL ) return m_nTigerSize;
		else if ( m_pHashsetBlock != NULL ) return ED2K_PART_SIZE;
	}
	else if ( nHash == HASH_TIGERTREE && m_pTigerBlock != NULL )
	{
		return m_nTigerSize;
	}
	else if ( nHash == HASH_ED2K && m_pHashsetBlock != NULL )
	{
		return ED2K_PART_SIZE;
	}
	else if ( nHash == HASH_TORRENT && m_pTorrentBlock != NULL )
	{
		return m_nTorrentSize;
	}
	
	return 0;
}

BOOL CDownloadWithTiger::GetNextVerifyRange(QWORD& nOffset, QWORD& nLength, BOOL& bSuccess, int nHash) const
{
	if ( nOffset >= m_nSize ) return FALSE;
	if ( m_pTigerBlock == NULL && m_pHashsetBlock == NULL && m_pTorrentBlock == NULL ) return FALSE;
	
	if ( nHash == HASH_NULL )
	{
		if ( m_pTorrentBlock != NULL ) nHash = HASH_TORRENT;
		else if ( m_pTigerBlock != NULL ) nHash = HASH_TIGERTREE;
		else if ( m_pHashsetBlock != NULL ) nHash = HASH_ED2K;
	}
	
	QWORD nBlockCount, nBlockSize;
	BYTE* pBlockPtr;
	
	switch ( nHash )
	{
	case HASH_TIGERTREE:
		if ( m_pTigerBlock == NULL ) return FALSE;
		pBlockPtr	= m_pTigerBlock;
		nBlockCount	= m_nTigerBlock;
		nBlockSize	= m_nTigerSize;
		break;
	case HASH_ED2K:
		if ( m_pHashsetBlock == NULL ) return FALSE;
		pBlockPtr	= m_pHashsetBlock;
		nBlockCount	= m_nHashsetBlock;
		nBlockSize	= ED2K_PART_SIZE;
		break;
	case HASH_TORRENT:
		if ( m_pTorrentBlock == NULL ) return FALSE;
		pBlockPtr	= m_pTorrentBlock;
		nBlockCount	= m_nTorrentBlock;
		nBlockSize	= m_nTorrentSize;
		break;
	default:
		return FALSE;
	}
	
	if ( nBlockSize == 0 ) return FALSE;
	
	for ( QWORD nBlock = nOffset / nBlockSize ; nBlock < nBlockCount ; nBlock++ )
	{
		QWORD nThis = nBlock * nBlockSize;
		
		if ( nThis >= nOffset && pBlockPtr[ nBlock ] )
		{
			TRISTATE nBase	= pBlockPtr[ nBlock ];
			bSuccess		= nBase == TS_TRUE;
			nOffset			= nThis;
			nLength			= 0;
			
			for ( ; nBlock < nBlockCount ; nBlock++ )
			{
				if ( nBase != pBlockPtr[ nBlock ] ) break;
				nLength += nBlockSize;
			}
			
			return TRUE;
		}
	}
	
	return FALSE;
}

BOOL CDownloadWithTiger::IsFullyVerified()
{
	if ( m_nTorrentBlock > 0 && m_nTorrentSuccess >= m_nTorrentBlock ) return TRUE;
	if ( m_nTigerBlock > 0 && m_nTigerSuccess >= m_nTigerBlock ) return TRUE;
	if ( m_nHashsetBlock > 0 && m_nHashsetSuccess >= m_nHashsetBlock ) return TRUE;
	return FALSE;
}

//////////////////////////////////////////////////////////////////////
// CDownloadWithTiger tiger-tree access

BOOL CDownloadWithTiger::NeedTigerTree() const
{
	return ( m_nSize < SIZE_UNKNOWN && m_pTigerTree.IsAvailable() == FALSE );
}

BOOL CDownloadWithTiger::SetTigerTree(BYTE* pTiger, DWORD nTiger)
{
	if ( m_nSize == SIZE_UNKNOWN ) return FALSE;
	if ( m_pTigerTree.IsAvailable() ) return TRUE;
	
	if ( ! m_pTigerTree.FromBytes( pTiger, nTiger,
			Settings.Library.TigerHeight, m_nSize ) )
	{
		theApp.Message( MSG_ERROR, IDS_DOWNLOAD_TIGER_CORRUPT,
			(LPCTSTR)GetDisplayName() );
		return FALSE;
	}
	
	TIGEROOT pRoot;
	m_pTigerTree.GetRoot( &pRoot );
	
	if ( m_bTiger && m_pTiger != pRoot )
	{
		m_pTigerTree.Clear();
		theApp.Message( MSG_ERROR, IDS_DOWNLOAD_TIGER_MISMATCH,
			(LPCTSTR)GetDisplayName() );
		return FALSE;
	}
	else if ( ! m_bTiger )
	{
		m_bTiger = TRUE;
		m_pTiger = pRoot;
	}
	
	m_nTigerSize	= m_pTigerTree.GetBlockLength();
	m_nTigerBlock	= m_pTigerTree.GetBlockCount();
	m_pTigerBlock	= new BYTE[ m_nTigerBlock ];
	
	ZeroMemory( m_pTigerBlock, sizeof(BYTE) * m_nTigerBlock );
	
	SetModified();
	
	theApp.Message( MSG_DEFAULT, IDS_DOWNLOAD_TIGER_READY,
		(LPCTSTR)GetDisplayName(), m_pTigerTree.GetHeight(),
		(LPCTSTR)Settings.SmartVolume( m_nTigerSize, FALSE ) );
	
	return TRUE;
}

CTigerTree* CDownloadWithTiger::GetTigerTree()
{
	return m_pTigerTree.IsAvailable() ? &m_pTigerTree : NULL;
}

//////////////////////////////////////////////////////////////////////
// CDownloadWithTiger eDonkey2000 hashset access

BOOL CDownloadWithTiger::NeedHashset() const
{
	return ( m_nSize < SIZE_UNKNOWN && m_pHashset.IsAvailable() == FALSE );
}

BOOL CDownloadWithTiger::SetHashset(BYTE* pSource, DWORD nSource)
{
	if ( m_nSize == SIZE_UNKNOWN ) return FALSE;
	if ( m_pHashset.IsAvailable() ) return TRUE;
	
	if ( nSource == 0 && m_bED2K )
	{
		m_pHashset.FromRoot( &m_pED2K );
	}
	else if ( m_pHashset.FromBytes( pSource, nSource, m_nSize ) )
	{
		MD4 pRoot;
		m_pHashset.GetRoot( &pRoot );
		
		if ( m_bED2K && m_pED2K != pRoot )
		{
			m_pHashset.Clear();
			theApp.Message( MSG_ERROR, IDS_DOWNLOAD_HASHSET_CORRUPT,
				(LPCTSTR)GetDisplayName() );
			return FALSE;
		}
		else if ( ! m_bED2K )
		{
			m_bED2K = TRUE;
			m_pED2K = pRoot;
		}
	}
	else
	{
		theApp.Message( MSG_ERROR, IDS_DOWNLOAD_HASHSET_CORRUPT,
			(LPCTSTR)GetDisplayName() );
		return FALSE;
	}
	
	m_nHashsetBlock	= m_pHashset.GetBlockCount();
	m_pHashsetBlock	= new BYTE[ m_nHashsetBlock ];
	
	ZeroMemory( m_pHashsetBlock, sizeof(BYTE) * m_nHashsetBlock );
	
	SetModified();
	
	theApp.Message( MSG_DEFAULT, IDS_DOWNLOAD_HASHSET_READY,
		(LPCTSTR)GetDisplayName(),
		(LPCTSTR)Settings.SmartVolume( ED2K_PART_SIZE, FALSE ) );
	
	Neighbours.SendDonkeyDownload( reinterpret_cast<CDownload*>( this ) );
	
	return TRUE;
}

CED2K* CDownloadWithTiger::GetHashset()
{
	return m_pHashset.IsAvailable() ? &m_pHashset : NULL;
}

//////////////////////////////////////////////////////////////////////
// CDownloadWithTiger test if the file can finish

BOOL CDownloadWithTiger::ValidationCanFinish() const
{
	BOOL bAvailable = FALSE;
	
	if ( m_pTorrentBlock != NULL )
	{
		if ( m_nTorrentSuccess >= m_nTorrentBlock ) return TRUE;
		bAvailable = TRUE;
	}
	
	if ( m_pTigerBlock != NULL && Settings.Downloads.VerifyTiger )
	{
		if ( m_nTigerSuccess >= m_nTigerBlock ) return TRUE;
		bAvailable = TRUE;
	}
	
	if ( m_pHashsetBlock != NULL && Settings.Downloads.VerifyED2K )
	{
		if ( m_nHashsetSuccess >= m_nHashsetBlock ) return TRUE;
		bAvailable = TRUE;
	}
	
	return ! bAvailable;
}

//////////////////////////////////////////////////////////////////////
// CDownloadWithTiger run validation

void CDownloadWithTiger::RunValidation(BOOL bSeeding)
{
	if ( m_pTigerBlock == NULL && m_pHashsetBlock == NULL && m_pTorrentBlock == NULL ) return;
	if ( m_sLocalName.IsEmpty() ) return;
	
	if ( ! bSeeding )
	{
		if ( m_pFile == NULL || ! OpenFile() ) return;
	}
	
	if ( m_nVerifyHash > HASH_NULL && m_nVerifyBlock < 0xFFFFFFFF )
	{
		Downloads.m_nValidation ++;
		ContinueValidation();
	}
	else
	{
		if ( FindNewValidationBlock( HASH_TORRENT ) ||
			 FindNewValidationBlock( HASH_TIGERTREE ) ||
			 FindNewValidationBlock( HASH_ED2K ) )
		{
			Downloads.m_nValidation ++;
			ContinueValidation();
		}
	}
}

//////////////////////////////////////////////////////////////////////
// CDownloadWithTiger validation setup

BOOL CDownloadWithTiger::FindNewValidationBlock(int nHash)
{
	if ( nHash == HASH_TIGERTREE && ! Settings.Downloads.VerifyTiger ) return FALSE;
	if ( nHash == HASH_ED2K && ! Settings.Downloads.VerifyED2K ) return FALSE;
	
	DWORD nBlockCount;
	QWORD nBlockSize;
	BYTE* pBlockPtr;
	
	switch ( nHash )
	{
	case HASH_TIGERTREE:
		if ( m_pTigerBlock == NULL ) return FALSE;
		pBlockPtr	= m_pTigerBlock;
		nBlockCount	= m_nTigerBlock;
		nBlockSize	= m_nTigerSize;
		break;
	case HASH_ED2K:
		if ( m_pHashsetBlock == NULL ) return FALSE;
		pBlockPtr	= m_pHashsetBlock;
		nBlockCount	= m_nHashsetBlock;
		nBlockSize	= ED2K_PART_SIZE;
		break;
	case HASH_TORRENT:
		if ( m_pTorrentBlock == NULL ) return FALSE;
		pBlockPtr	= m_pTorrentBlock;
		nBlockCount	= m_nTorrentBlock;
		nBlockSize	= m_nTorrentSize;
		break;
	default:
		return FALSE;
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -