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

📄 partfile.cpp

📁 非常出名开源客户端下载的程序emule
💻 CPP
📖 第 1 页 / 共 5 页
字号:

	s_ChunkBar.SetFileSize(this->GetFileSize()); 
	s_ChunkBar.SetHeight(rect->bottom - rect->top); 
	s_ChunkBar.SetWidth(rect->right - rect->left); 
	s_ChunkBar.Fill(crMissing); 
	COLORREF color;
	if (!onlygreyrect && !m_SrcpartFrequency.IsEmpty()) { 
		for (int i = 0;i != GetPartCount();i++)
			if(m_SrcpartFrequency[i] > 0 ){
				color = RGB(0, (210-(22*(m_SrcpartFrequency[i]-1)) <  0)? 0:210-(22*(m_SrcpartFrequency[i]-1)), 255);
				s_ChunkBar.FillRange(PARTSIZE*(i),PARTSIZE*(i+1),color);
			}
	}
   	s_ChunkBar.Draw(dc, rect->left, rect->top, bFlat); 
} 

void CPartFile::DrawStatusBar(CDC* dc, RECT* rect, bool bFlat){ 
	COLORREF crProgress;
	COLORREF crHave;
	COLORREF crPending;
	COLORREF crMissing = RGB(255, 0, 0);

	if(bFlat) {
		crProgress = RGB(0, 150, 0);
		crHave = RGB(0, 0, 0);
		crPending = RGB(255,208,0);
	} else {
		crProgress = RGB(0, 224, 0);
		crHave = RGB(104, 104, 104);
		crPending = RGB(255, 208, 0);
	}

	s_ChunkBar.SetHeight(rect->bottom - rect->top);
	s_ChunkBar.SetWidth(rect->right - rect->left);
	s_ChunkBar.SetFileSize(m_nFileSize);
	s_ChunkBar.Fill(crHave);

	uint32 allgaps = 0;

	if(status == PS_COMPLETE || status == PS_COMPLETING) {
		s_ChunkBar.FillRange(0, m_nFileSize, crProgress);
		s_ChunkBar.Draw(dc, rect->left, rect->top, bFlat);
		percentcompleted = 100;
		completedsize = m_nFileSize;
		return;
	}

	// red gaps
	for (POSITION pos = gaplist.GetHeadPosition();pos !=  0;gaplist.GetNext(pos)){
		Gap_Struct* cur_gap = gaplist.GetAt(pos);
		allgaps += cur_gap->end - cur_gap->start;
		bool gapdone = false;
		uint32 gapstart = cur_gap->start;
		uint32 gapend = cur_gap->end;
		for (uint32 i = 0; i != GetPartCount(); i++){
			if (gapstart >= i*PARTSIZE && gapstart <=  (i+1)*PARTSIZE){ // is in this part?
				if (gapend <= (i+1)*PARTSIZE)
					gapdone = true;
				else{
					gapend = (i+1)*PARTSIZE; // and next part
				}
				// paint
				COLORREF color;
				if (m_SrcpartFrequency.GetCount() >= (INT_PTR)i && m_SrcpartFrequency[i])  // frequency?
					color = RGB(0,
					(210-(22*(m_SrcpartFrequency[i]-1)) <  0)? 0:210-(22*(m_SrcpartFrequency[i]-1))
					,255);
				else
					color = crMissing;

				s_ChunkBar.FillRange(gapstart, gapend + 1,  color);

				if (gapdone) // finished?
					break;
				else{
					gapstart = gapend;
					gapend = cur_gap->end;
				}
			}
		}
	}

	// yellow pending parts
	for (POSITION pos = requestedblocks_list.GetHeadPosition();pos !=  0;requestedblocks_list.GetNext(pos))
	{
		Requested_Block_Struct* block =  requestedblocks_list.GetAt(pos);
		s_ChunkBar.FillRange((block->StartOffset + block->transferred), block->EndOffset,  crPending);
	}

	s_ChunkBar.Draw(dc, rect->left, rect->top, bFlat);

	// green progress
	float blockpixel = (float)(rect->right - rect->left)/((float)m_nFileSize);
	RECT gaprect;
	gaprect.top = rect->top;
	gaprect.bottom = gaprect.top + PROGRESS_HEIGHT; // Barry - was 4
	gaprect.left = rect->left;

	if(!bFlat) {
		s_LoadBar.SetWidth((uint32)((float)((float)((m_nFileSize-((allgaps==0)?1:allgaps) )-1))*blockpixel + .5f));
		s_LoadBar.Fill(crProgress);
		s_LoadBar.Draw(dc, gaprect.left, gaprect.top, false);
	} else {
		gaprect.right = rect->left+  (uint32)((float)((float)((m_nFileSize-((allgaps==0)?1:allgaps))-1))*blockpixel +  .5f);
		dc->FillRect(&gaprect, &CBrush(crProgress));
		//draw gray progress only if flat
		gaprect.left = gaprect.right;
		gaprect.right = rect->right;
		dc->FillRect(&gaprect, &CBrush(RGB(224,224,224)));
	}

	if (gaplist.GetCount() || requestedblocks_list.GetCount()){
		percentcompleted = ((1.0f-(float)allgaps/m_nFileSize)) * 100;
		completedsize = m_nFileSize - allgaps - 1;
	}
	else{
		percentcompleted = 100;
		completedsize = m_nFileSize;
	}

}

void CPartFile::WritePartStatus(CFile* file){
	uint16 parts = GetPartCount();
	file->Write(&parts,2);
	uint16 done = 0;
	while (done != parts){
		uint8 towrite = 0;
		for (uint32 i = 0;i != 8;i++){
			if (IsComplete(done*PARTSIZE,((done+1)*PARTSIZE)-1))
				towrite |= (1<<i);
			done++;
			if (done == parts)
				break;
		}
		file->Write(&towrite,1);
	}
}

int CPartFile::GetValidSourcesCount() {
	int counter=0;
	POSITION pos1,pos2;
	for (int sl=0;sl<SOURCESSLOTS;sl++) if (!srclists[sl].IsEmpty())
	for (pos1 = srclists[sl].GetHeadPosition();( pos2 = pos1 ) != NULL;){
		srclists[sl].GetNext(pos1);
		CUpDownClient* cur_src = srclists[sl].GetAt(pos2);
		if (cur_src->GetDownloadState()!=DS_ONQUEUE && cur_src->GetDownloadState()!=DS_DOWNLOADING &&
			cur_src->GetDownloadState()!=DS_NONEEDEDPARTS) counter++;
	}
	return counter;
}

uint16 CPartFile::GetNotCurrentSourcesCount(){
		uint16 counter=0;

		POSITION pos1,pos2;
		for (int sl=0;sl<SOURCESSLOTS;sl++) if (!srclists[sl].IsEmpty())
		for (pos1 = srclists[sl].GetHeadPosition();( pos2 = pos1 ) != NULL;){
			srclists[sl].GetNext(pos1);
			CUpDownClient* cur_src = srclists[sl].GetAt(pos2);
			if (cur_src->GetDownloadState()!=DS_ONQUEUE && cur_src->GetDownloadState()!=DS_DOWNLOADING) counter++;
		}
		return counter;
}

uint8 CPartFile::GetStatus(bool ignorepause){
	if ((!paused) || status == PS_ERROR || ignorepause)
		return status;
	else
		return PS_PAUSED;
}
void CPartFile::AddDownloadingSource(CUpDownClient* client){
	POSITION pos = m_downloadingSourceList.Find(client); // to be sure
	if(pos == NULL){
		m_downloadingSourceList.AddTail(client);
	}
}

void CPartFile::RemoveDownloadingSource(CUpDownClient* client){
	POSITION pos = m_downloadingSourceList.Find(client); // to be sure
	if(pos != NULL){
		m_downloadingSourceList.RemoveAt(pos);
	}
}

uint32 CPartFile::Process(uint32 reducedownload, uint8 m_icounter/*in percent*/)
{
	uint16 tempTS=0;
	DWORD dwCurTick = ::GetTickCount();

	// If buffer size exceeds limit, or if not written within time limit, flush data
	if ((m_nTotalBufferData > theApp.glob_prefs->GetFileBufferSize()) || (dwCurTick > (m_nLastBufferFlushTime + BUFFER_TIME_LIMIT))){
		// Avoid flushing while copying preview file
		if (!m_bPreviewing)
			FlushBuffer();
	}

	datarate = 0;

	if(m_icounter < 10){
		for(POSITION pos = m_downloadingSourceList.GetHeadPosition();pos!=0;){
			CUpDownClient* cur_src = m_downloadingSourceList.GetNext(pos);
			if(cur_src){
				tempTS++;
				uint32 cur_datarate = cur_src->CalculateDownloadRate();
				datarate+=cur_datarate;
				if(reducedownload){
					uint32 limit = reducedownload*cur_datarate/1000;
					if(limit<1000 && reducedownload == 200)
						limit +=1000;
					else if(limit<1)
						limit = 1;
					cur_src->socket->SetDownloadLimit(limit);
				}
			}
		}
	}
	else{
		POSITION pos1, pos2;
		for (uint32 sl = 0; sl < SOURCESSLOTS; sl++){
			if (!srclists[sl].IsEmpty()){
				for (pos1 = srclists[sl].GetHeadPosition();( pos2 = pos1 ) != NULL;){
					srclists[sl].GetNext(pos1);
					CUpDownClient* cur_src = srclists[sl].GetAt(pos2);

					switch (cur_src->GetDownloadState()){
						case DS_DOWNLOADING:{
							tempTS++;
							uint32 cur_datarate = cur_src->CalculateDownloadRate();
							datarate += cur_datarate;
							if (reducedownload && cur_src->GetDownloadState() == DS_DOWNLOADING){
								uint32 limit = reducedownload*cur_datarate/1000; //(uint32)(((float)reducedownload/100)*cur_datarate)/10;		
								if (limit < 1000 && reducedownload == 200)
									limit += 1000;
								else if (limit < 1)
									limit = 1;
								cur_src->socket->SetDownloadLimit(limit);
							}
							else
								cur_src->socket->DisableDownloadLimit();
							break;
						}
						case DS_BANNED:
						case DS_ERROR:
							break;
						case DS_CONNECTED:
							if(cur_src->socket){
								if( !cur_src->socket->IsConnected() ){
									cur_src->SetDownloadState(DS_NONE);
									break;
								}
							}
							else{
								cur_src->SetDownloadState(DS_NONE);
							}
						case DS_LOWTOLOWIP:	// if we now have a high ip we can ask
							if( ((dwCurTick - lastpurgetime) > 30000) && (this->GetSourceCount() >= (theApp.glob_prefs->GetMaxSourcePerFile()*.8 )) ){
								theApp.downloadqueue->RemoveSource( cur_src );
								lastpurgetime = dwCurTick;
								break;
							}
							if (theApp.serverconnect->IsLowID())
								break;
						case DS_NONEEDEDPARTS:{ 
							if( ((dwCurTick - lastpurgetime) > 40000) && (this->GetSourceCount() >= (theApp.glob_prefs->GetMaxSourcePerFile()*.8 )) )
								if( !cur_src->SwapToAnotherFile( cur_src ) ){
									theApp.downloadqueue->RemoveSource( cur_src );
									lastpurgetime = dwCurTick;
									break; //Johnny-B - nothing more to do here (good eye!)
								}
							// doubled reasktime for no needed parts - save connections and traffic
							if (!((!cur_src->GetLastAskedTime()) || (dwCurTick - cur_src->GetLastAskedTime()) > FILEREASKTIME*2))
								break; 
						}
						case DS_ONQUEUE:{
							if( cur_src->IsRemoteQueueFull() )
								if( ((dwCurTick - lastpurgetime) > 60000) && (this->GetSourceCount() >= (theApp.glob_prefs->GetMaxSourcePerFile()*.8 )) ){
									theApp.downloadqueue->RemoveSource( cur_src );
									lastpurgetime = dwCurTick;
									break; //Johnny-B - nothing more to do here (good eye!)
								}
							if (theApp.serverconnect->IsConnected() && ((!cur_src->GetLastAskedTime()) || (dwCurTick - cur_src->GetLastAskedTime()) > FILEREASKTIME-20000))
								cur_src->UDPReaskForDownload();
						}
						case DS_CONNECTING:
						case DS_TOOMANYCONNS:
						case DS_NONE:
						case DS_WAITCALLBACK:
							if (theApp.serverconnect->IsConnected() && ((!cur_src->GetLastAskedTime()) || (dwCurTick - cur_src->GetLastAskedTime()) > FILEREASKTIME))
								cur_src->AskForDownload();
							break;
					}
				}
			}
		}
		transferingsrc= tempTS;

		// swap No needed partfiles if possible
		if (((!m_LastNoNeededCheck) || (dwCurTick - m_LastNoNeededCheck) > 10000))
		{
			m_LastNoNeededCheck = dwCurTick;
			POSITION pos1, pos2;
			for (int sl = 0; sl < SOURCESSLOTS; sl++)
				if (!srclists[sl].IsEmpty())
					for (pos1 = srclists[sl].GetHeadPosition();( pos2 = pos1 ) != NULL;)
					{
						srclists[sl].GetNext(pos1);
						CUpDownClient* cur_src = srclists[sl].GetAt(pos2);
						if (cur_src->GetDownloadState() == DS_NONEEDEDPARTS)
							cur_src->SwapToAnotherFile(false);
					}
		}

		// check if we want new sources from server
		//uint16 test = theApp.glob_prefs->GetMaxSourcePerFileSoft();
		if (( (!lastsearchtime) || (dwCurTick - lastsearchtime) > SERVERREASKTIME) && theApp.serverconnect->IsConnected()
			&& theApp.glob_prefs->GetMaxSourcePerFileSoft() > GetSourceCount() && !stopped )
		{
			//local server
			lastsearchtime = dwCurTick;
			Packet* packet = new Packet(OP_GETSOURCES,16);
			memcpy(packet->pBuffer,m_abyFileHash,16);
			theApp.uploadqueue->AddUpDataOverheadServer(packet->size);
			theApp.serverconnect->SendPacket(packet,true);
			theApp.emuledlg->AddDebugLogLine( false, "Send:Source Request Server File(%s)", GetFileName() );
		}

		count++;
		if (count == 3){
			count = 0;
			UpdateAutoDownPriority();
			UpdateDisplayedInfo();
			if(m_bPercentUpdated == false)
				UpdateCompletedInfos();
			m_bPercentUpdated = false;
		}
	}
	// calculate datarate, set limit etc.

	return datarate;
}

void CPartFile::AddSources(CMemFile* sources,uint32 serverip, uint16 serverport){

	if (stopped) return;

	uint8 count;
	uint8 debug_lowiddropped = 0;
	uint8 debug_possiblesources = 0;
	sources->Read(&count,1);
	for (int i = 0;i != count;i++){
		uint32 userid;
		sources->Read(&userid,4);
		uint16 port;
		sources->Read(&port,2);
		// check first if we are this source

		// MOD Note: Do not change this part - Merkur
		if (theApp.serverconnect->GetClientID() < 16777216 && theApp.serverconnect->IsConnected()){
			if ((theApp.serverconnect->GetClientID() == userid) && inet_addr(theApp.serverconnect->GetCurrentServer()->GetFullIP()) == serverip)
				continue;
		}
		else if (theApp.serverconnect->GetClientID() == userid)
			continue;
		else if (userid < 16777216 && !theApp.serverconnect->IsLocalServer(serverip,serverport)){
			debug_lowiddropped++;
			continue;
		}
		// MOD Note - end

		if( theApp.glob_prefs->GetMaxSourcePerFile() > this->GetSourceCount() ){
			debug_possiblesources++;
			CUpDownClient* newsource = new CUpDownClient(port,userid,serverip,serverport,this);
			theApp.downloadqueue->CheckAndAddSource(this,newsource);
		}
	}
	theApp.emuledlg->AddDebugLogLine(false,"RCV: %i sources from server, %i low id dropped, %i possible sources File(%s)",count,debug_lowiddropped,debug_possiblesources, GetFileName());
}

void CPartFile::NewSrcPartsInfo(){
	// Cache part count
	uint16 partcount = GetPartCount();

	// Increase size if necessary
	if(m_SrcpartFrequency.GetSize() < partcount){
		m_SrcpartFrequency.SetSize(partcount);
	}
	// Reset part counters
	for(int i = 0; i < partcount; i++){
		m_SrcpartFrequency[i] = 0;
	}
	CUpDownClient* cur_src;
	
	for(int sl=0; sl<SOURCESSLOTS; ++sl) {
		if (!srclists[sl].IsEmpty()) {
			for (POSITION pos = srclists[sl].GetHeadPosition(); pos != 0; ){
				cur_src = srclists[sl].GetNext(pos);
				for (int i = 0; i != partcount; i++){
					if (cur_src->IsPartAvailable(i))
						m_SrcpartFrequency[i] +=1;
				}
			}
		}
	}
	//theApp.emuledlg->transferwnd.downloadlistctrl.UpdateItem(this);
	UpdateDisplayedInfo(true);
}

bool CPartFile::GetNextRequestedBlock(CUpDownClient* sender,Requested_Block_Struct** newblocks,uint16* count){
	uint16 requestedCount = *count;
	uint16 newblockcount = 0;
	uint8* partsav = sender->GetPartStatus();
	*count = 0;
	uint16 randomness;
	CList<int,int> liGoodParts;
	CList<int,int> liPossibleParts;

⌨️ 快捷键说明

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