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

📄 uploadclient.cpp

📁 非常出名开源客户端下载的程序emule
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//this file is part of eMule
//Copyright (C)2002 Merkur ( merkur-@users.sourceforge.net / http://www.emule-project.net )
//
//This program 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.
//
//This program 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 this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

#include "StdAfx.h"
#include "zlib/zlib.h"
#include "UpDownClient.h"
#include "opcodes.h"
#include "packets.h"
#include "emule.h"
#include "uploadqueue.h"
#include "otherstructs.h"

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


//	members of CUpDownClient
//	which are mainly used for uploading functions 

CBarShader CUpDownClient::s_UpStatusBar(16);

void CUpDownClient::DrawUpStatusBar(CDC* dc, RECT* rect, bool onlygreyrect, bool  bFlat){ 
	COLORREF crBoth; 
	COLORREF crNeither; 
	COLORREF crClientOnly; 
	COLORREF crSending;
	COLORREF crNextSending;

	if(bFlat) { 
		crBoth = RGB(0, 0, 0);
		crNeither = RGB(224, 224, 224);
		crClientOnly = RGB(0, 220, 255);
		crSending = RGB(0,150,0);
		crNextSending = RGB(255,208,0);
	} else { 
		crBoth = RGB(104, 104, 104);
		crNeither = RGB(224, 224, 224);
		crClientOnly = RGB(0, 220, 255);
		crSending = RGB(0, 150, 0);
		crNextSending = RGB(255,208,0);
	} 

    uint32 filesize = PARTSIZE*(m_nUpPartCount);

	s_UpStatusBar.SetFileSize(filesize); 
	s_UpStatusBar.SetHeight(rect->bottom - rect->top); 
	s_UpStatusBar.SetWidth(rect->right - rect->left); 
	s_UpStatusBar.Fill(crNeither); 
	if (!onlygreyrect && m_abyUpPartStatus) { 
		for (uint32 i = 0;i != m_nUpPartCount;i++)
			if(m_abyUpPartStatus[i])
				s_UpStatusBar.FillRange(PARTSIZE*(i),PARTSIZE*(i+1),crBoth);
	}
	Requested_Block_Struct* block;
	if (!m_BlockRequests_queue.IsEmpty()){
		block = m_BlockRequests_queue.GetHead();
		if(block){
			uint32 start = block->StartOffset/PARTSIZE;
			s_UpStatusBar.FillRange(start*PARTSIZE, (start+1)*PARTSIZE, crNextSending);
		}
	}
	if (!m_DoneBlocks_list.IsEmpty()){
		block = m_DoneBlocks_list.GetTail();
		if(block){
			uint32 start = block->StartOffset/PARTSIZE;
			s_UpStatusBar.FillRange(start*PARTSIZE, (start+1)*PARTSIZE, crNextSending);
		}
	}
	if (!m_DoneBlocks_list.IsEmpty()){
		for(POSITION pos=m_DoneBlocks_list.GetHeadPosition();pos!=0;m_DoneBlocks_list.GetNext(pos)){
			Requested_Block_Struct* block = m_DoneBlocks_list.GetAt(pos);
			s_UpStatusBar.FillRange(block->StartOffset, block->EndOffset, crSending);
		}
	}
   	s_UpStatusBar.Draw(dc, rect->left, rect->top, bFlat); 
} 

void CUpDownClient::SetUploadState(uint8 news){
	m_byUploadState = news;
	theApp.emuledlg->transferwnd.clientlistctrl.RefreshClient(this);
}

uint32 CUpDownClient::GetScore(bool sysvalue, bool isdownloading, bool onlybasevalue){
	//TODO: complete this (friends, uploadspeed, emuleuser etc etc)
	if (!m_pszUsername)
		return 0;

	CKnownFile* currequpfile = theApp.sharedfiles->GetFileByID(requpfileid);
	if(!currequpfile)
		return 0;

	// friend slot
	if (IsFriend() && GetFriendSlot() && !HasLowID())
		return 0x0FFFFFFF;

	if (IsBanned())
		return 0;

	if (sysvalue && HasLowID() && !(socket && socket->IsConnected())){
		return 0;
	}

	// TODO coded by tecxx & herbert, one yet unsolved problem here:
	// sometimes a client asks for 2 files and there is no way to decide, which file the 
	// client finally gets. so it could happen that he is queued first because of a 
	// high prio file, but then asks for something completely different.
	int filepriority = 10; // standard
	if(GetUploadFileID() != NULL){ 
		if(theApp.sharedfiles->GetFileByID(GetUploadFileID()) != NULL){ 
			switch(theApp.sharedfiles->GetFileByID(GetUploadFileID())->GetUpPriority()){ 
				case PR_VERYHIGH:
					filepriority = 18;
					break;
				case PR_HIGH: 
					filepriority = 9; 
					break; 
				case PR_LOW: 
					filepriority = 6; 
					break; 
				case PR_VERYLOW:
					filepriority = 2;
					break;
				case PR_NORMAL: 
					default: 
					filepriority = 7; 
				break; 
			} 
		} 
	} 
	// calculate score, based on waitingtime and other factors
	float fBaseValue;
	if (onlybasevalue)
		fBaseValue = 100;
	else if (!isdownloading)
		fBaseValue = (float)(::GetTickCount()-m_dwWaitTime)/1000;
	else{
		// we dont want one client to download forever
		// the first 15 min downloadtime counts as 15 min waitingtime and you get a 15 min bonus while you are in the first 15 min :)
		// (to avoid 20 sec downloads) after this the score won't raise anymore 
		fBaseValue = (float)(m_dwUploadTime-m_dwWaitTime);
		ASSERT ( m_dwUploadTime-m_dwWaitTime >= 0 ); //oct 28, 02: changed this from "> 0" to ">= 0"
		fBaseValue += (float)(::GetTickCount() - m_dwUploadTime > 900000)? 900000:1800000;
		fBaseValue /= 1000;
	}
	ASSERT(credits != NULL);
	if(theApp.glob_prefs->UseCreditSystem())
		fBaseValue *= credits->GetScoreRatio();
	if (!onlybasevalue)
		fBaseValue *= (float(filepriority)/10.0f); 
	if (!isdownloading && !onlybasevalue){
		if (sysvalue && HasLowID() && !(socket && socket->IsConnected()) ){
			if (!theApp.serverconnect->IsConnected() || theApp.serverconnect->IsLowID() || theApp.listensocket->TooManySockets())
				return 0;
		}
	}
	if( (IsEmuleClient() || this->GetClientSoft() < 10) && m_byEmuleVersion <= 0x19 )
		fBaseValue *= 0.5f;
	return (uint32)fBaseValue;
}

// Checks if it is next requested block from another chunk of the actual file or from another file 
// 
// [Returns] 
//   true : Next requested block is from another different chunk or file than last downloaded block 
//   false: Next requested block is from same chunk that last downloaded block 
bool CUpDownClient::IsDifferentPartBlock()
{ 
	Requested_Block_Struct* lastBlock;
	Requested_Block_Struct* currBlock;
	uint32 lastDone = 0;
	uint32 currRequested = 0;
	
	bool different = false;
	
	try {
		// Check if we have good lists and proceed to check for different chunks
		if (!m_BlockRequests_queue.IsEmpty() && !m_DoneBlocks_list.IsEmpty())
		{
			// Calculate corresponding parts to blocks
			lastBlock = (Requested_Block_Struct*)m_DoneBlocks_list.GetTail();
			lastDone = lastBlock->StartOffset / PARTSIZE;
			currBlock = (Requested_Block_Struct*)m_BlockRequests_queue.GetHead(); 
			currRequested = currBlock->StartOffset / PARTSIZE; 
             
			// Test is we are asking same file and same part
			if ( lastDone != currRequested)
			{ 
				different = true;
				theApp.emuledlg->AddDebugLogLine(false, "%s: Upload session ended due to new chunk.", this->GetUserName());
			}
			if (memcmp(lastBlock->FileID, currBlock->FileID, 16) != 0)
			{ 
				different = true;
				theApp.emuledlg->AddDebugLogLine(false, "%s: Upload session ended due to different file.", this->GetUserName());
			}
		} 
   	}
   	catch(...)
   	{ 
			theApp.emuledlg->AddDebugLogLine(false, "%s: Upload session ended due to error.", this->GetUserName());
      		different = true; 
   	} 
//	theApp.emuledlg->AddDebugLogLine(false, "Debug: User %s, last_done_part (%u) %s (%u) next_requested_part, sent %u Kbs.", GetUserName(), last_done_part, different_part? "!=": "==", next_requested_part, this->GetTransferedUp() / 1024); 

	return different; 
}

bool CUpDownClient::CreateNextBlockPackage(){
	// time critical
	// check if we should kick this client
	// VQB Full Chunk Trans..
	if (theApp.glob_prefs->TransferFullChunks())
	{
		// VQB to provide full chunk transfers (modified by Tarod)
		if ( theApp.uploadqueue->CheckForTimeOver(this) || IsDifferentPartBlock())
		{
			theApp.uploadqueue->RemoveFromUploadQueue(this);
			theApp.uploadqueue->AddClientToQueue(this,true);
			return false;
		}
	}
	else {
		if (theApp.uploadqueue->CheckForTimeOver(this)){
			// back on the waitqueue
			theApp.uploadqueue->RemoveFromUploadQueue(this);
			theApp.uploadqueue->AddClientToQueue(this,true);
			return false;
		}
	}
	if (m_BlockRequests_queue.IsEmpty()){
		return false;
	}
	CFile file;
	byte* filedata = 0;
	char* fullname = 0;
	try{
		while (!m_BlockRequests_queue.IsEmpty()){
			Requested_Block_Struct* currentblock = m_BlockRequests_queue.GetHead();
			CKnownFile* srcfile = theApp.sharedfiles->GetFileByID(currentblock->FileID);
			if (!srcfile)
				throw GetResString(IDS_ERR_REQ_FNF);

			if (srcfile->IsPartFile() && ((CPartFile*)srcfile)->GetStatus() != PS_COMPLETE){
				fullname = nstrdup(((CPartFile*)srcfile)->GetFullName());
				fullname[strlen(fullname)-4] = 0;			
			}
			else{
				fullname = new char[strlen(srcfile->GetPath())+strlen(srcfile->GetFileName())+10];
				sprintf(fullname,"%s\\%s",srcfile->GetPath(),srcfile->GetFileName());
			}
		
			uint32 togo;
			if (currentblock->StartOffset > currentblock->EndOffset){
				togo = currentblock->EndOffset + (srcfile->GetFileSize() - currentblock->StartOffset);
			}
			else{
				togo = currentblock->EndOffset - currentblock->StartOffset;
				if (srcfile->IsPartFile() && !((CPartFile*)srcfile)->IsComplete(currentblock->StartOffset,currentblock->EndOffset-1))
					throw GetResString(IDS_ERR_INCOMPLETEBLOCK);
			}

			if( togo > 184320 )
				throw GetResString(IDS_ERR_LARGEREQBLOCK);
			
			if (!srcfile->IsPartFile()){
				if (!file.Open(fullname,CFile::modeRead|CFile::osSequentialScan|CFile::shareDenyNone))
					throw GetResString(IDS_ERR_OPEN);
				delete[] fullname;
				fullname = 0;
				file.Seek(currentblock->StartOffset,0);
				
				filedata = new byte[togo+500];
				if (uint32 done = file.Read(filedata,togo) != togo){
					file.SeekToBegin();
					file.Read(filedata + done,togo-done);
				}
				file.Close();
			}
			else{
				CPartFile* partfile = (CPartFile*)srcfile;
				delete[] fullname;
				fullname = 0;
				partfile->m_hpartfile.Seek(currentblock->StartOffset,0);
				
				filedata = new byte[togo+500];
				if (uint32 done = partfile->m_hpartfile.Read(filedata,togo) != togo){
					partfile->m_hpartfile.SeekToBegin();
					partfile->m_hpartfile.Read(filedata + done,togo-done);
				}
			}

			SetUploadFileID(currentblock->FileID);

			// check extention to decide whether to compress or not
			CString ext=srcfile->GetFileName();ext.MakeLower();
			int pos=ext.ReverseFind('.');
			if (pos>-1) ext=ext.Mid(pos);
			bool compFlag=(ext!=".zip" && ext!=".rar" && ext!=".ace" && ext!=".ogm" );
			if (ext==".avi" && theApp.glob_prefs->GetDontCompressAvi()) compFlag=false;

			if (m_byDataCompVer == 1 && compFlag )
				CreatePackedPackets(filedata,togo,currentblock);
			else
				CreateStandartPackets(filedata,togo,currentblock);
			
			// file statistic
			srcfile->statistic.AddTransferred(togo);

			m_DoneBlocks_list.AddHead(m_BlockRequests_queue.RemoveHead());
			delete[] filedata;
			filedata = 0;
		}
	}
	catch(CString error){
		OUTPUT_DEBUG_TRACE();
		theApp.emuledlg->AddDebugLogLine(false,GetResString(IDS_ERR_CLIENTERRORED),GetUserName(),error.GetBuffer());
		theApp.uploadqueue->RemoveFromUploadQueue(this);
		this->SetUploadFileID(NULL);
		if (filedata)
			delete filedata;
		if (fullname)
			delete[] fullname;
		return false;
	}
//	theApp.emuledlg->AddDebugLogLine(false,"Debug: Packet done. Size: %i",blockpack->GetLength());
	return true;
}

⌨️ 快捷键说明

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