📄 partfile.cpp
字号:
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)));
}
UpdateCompletedInfos(allgaps);
}
// additionally show any file op progress (needed for PS_COMPLETING and PS_WAITINGFORHASH)
if (GetFileOp() != PFOP_NONE)
{
float blockpixel = (float)(rect->right - rect->left)/100.0F;
CRect rcFileOpProgress;
rcFileOpProgress.top = rect->top;
rcFileOpProgress.bottom = rcFileOpProgress.top + PROGRESS_HEIGHT;
rcFileOpProgress.left = rect->left;
if (!bFlat)
{
s_LoadBar.SetWidth(GetFileOpProgress()*blockpixel + 0.5F);
s_LoadBar.Fill(RGB(255,208,0));
s_LoadBar.Draw(dc, rcFileOpProgress.left, rcFileOpProgress.top, false);
}
else
{
rcFileOpProgress.right = rcFileOpProgress.left + (UINT)(GetFileOpProgress()*blockpixel + 0.5F);
dc->FillRect(&rcFileOpProgress, &CBrush(RGB(255,208,0)));
rcFileOpProgress.left = rcFileOpProgress.right;
rcFileOpProgress.right = rect->right;
dc->FillRect(&rcFileOpProgress, &CBrush(RGB(224,224,224)));
}
}
}
void CPartFile::WritePartStatus(CSafeMemFile* file) const
{
UINT parts = GetED2KPartCount();
file->WriteUInt16(parts);
UINT done = 0;
while (done != parts){
uint8 towrite = 0;
for (UINT i = 0; i < 8; i++){
if (IsComplete(done*PARTSIZE, ((done+1)*PARTSIZE)-1))
towrite |= (1<<i);
done++;
if (done == parts)
break;
}
file->WriteUInt8(towrite);
}
}
void CPartFile::WriteCompleteSourcesCount(CSafeMemFile* file) const
{
file->WriteUInt16(m_nCompleteSourcesCount);
}
int CPartFile::GetValidSourcesCount() const
{
int counter = 0;
for (POSITION pos = srclist.GetHeadPosition(); pos != NULL;){
EDownloadState nDLState = srclist.GetNext(pos)->GetDownloadState();
if (nDLState==DS_ONQUEUE || nDLState==DS_DOWNLOADING || nDLState==DS_CONNECTED || nDLState==DS_REMOTEQUEUEFULL)
++counter;
}
return counter;
}
uint16 CPartFile::GetNotCurrentSourcesCount() const
{
UINT counter = 0;
for (POSITION pos = srclist.GetHeadPosition(); pos != NULL;){
EDownloadState nDLState = srclist.GetNext(pos)->GetDownloadState();
if (nDLState!=DS_ONQUEUE && nDLState!=DS_DOWNLOADING)
counter++;
}
return counter;
}
// SLUGFILLER: checkDiskspace
uint32 CPartFile::GetNeededSpace() const
{
if (m_hpartfile.GetLength() > GetFileSize())
return 0; // Shouldn't happen, but just in case
return GetFileSize()-m_hpartfile.GetLength();
}
// SLUGFILLER: checkDiskspace
EPartFileStatus CPartFile::GetStatus(bool ignorepause) const
{
// SLUGFILLER: checkDiskspace
if ((!paused && !insufficient) || status == PS_ERROR || status == PS_COMPLETING || status == PS_COMPLETE || ignorepause)
return status;
else if (paused)
return PS_PAUSED;
else
return PS_INSUFFICIENT;
// SLUGFILLER: checkDiskspace
}
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*/)
{
if (thePrefs.m_iDbgHeap >= 2)
ASSERT_VALID(this);
uint16 nOldTransSourceCount = GetSrcStatisticsValue(DS_DOWNLOADING);
DWORD dwCurTick = ::GetTickCount();
// If buffer size exceeds limit, or if not written within time limit, flush data
if ((m_nTotalBufferData > thePrefs.GetFileBufferSize()) || (dwCurTick > (m_nLastBufferFlushTime + BUFFER_TIME_LIMIT)))
{
// Avoid flushing while copying preview file
if (!m_bPreviewing)
FlushBuffer();
}
datarate = 0;
// calculate datarate, set limit etc.
if(m_icounter < 10)
{
uint32 cur_datarate;
for(POSITION pos = m_downloadingSourceList.GetHeadPosition();pos!=0;)
{
CUpDownClient* cur_src = m_downloadingSourceList.GetNext(pos);
if (thePrefs.m_iDbgHeap >= 2)
ASSERT_VALID( cur_src );
if(cur_src && cur_src->GetDownloadState() == DS_DOWNLOADING)
{
ASSERT( cur_src->socket );
if (cur_src->socket)
{
cur_src->CheckDownloadTimeout();
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);
if (cur_src->IsDownloadingFromPeerCache() && cur_src->m_pPCDownSocket && cur_src->m_pPCDownSocket->IsConnected())
cur_src->m_pPCDownSocket->SetDownloadLimit(limit);
}
}
}
}
}
else
{
// -khaos--+++> Moved this here, otherwise we were setting our permanent variables to 0 every tenth of a second...
memset(m_anStates,0,sizeof(m_anStates));
memset(src_stats,0,sizeof(src_stats));
memset(net_stats,0,sizeof(net_stats));
uint16 nCountForState;
for (POSITION pos = srclist.GetHeadPosition(); pos != NULL;)
{
CUpDownClient* cur_src = srclist.GetNext(pos);
if (thePrefs.m_iDbgHeap >= 2)
ASSERT_VALID( cur_src );
// BEGIN -rewritten- refreshing statistics (no need for temp vars since it is not multithreaded)
nCountForState = cur_src->GetDownloadState();
//special case which is not yet set as downloadstate
if (nCountForState == DS_ONQUEUE)
{
if( cur_src->IsRemoteQueueFull() )
nCountForState = DS_REMOTEQUEUEFULL;
}
if (cur_src->IsBanned())
nCountForState = DS_BANNED;
if (cur_src->GetSourceFrom() >= SF_SERVER && cur_src->GetSourceFrom() <= SF_PASSIVE)
++src_stats[cur_src->GetSourceFrom()];
if (cur_src->GetServerIP() && cur_src->GetServerPort())
{
net_stats[0]++;
if(cur_src->GetKadPort())
net_stats[2]++;
}
if (cur_src->GetKadPort())
net_stats[1]++;
ASSERT( nCountForState < sizeof(m_anStates)/sizeof(m_anStates[0]) );
m_anStates[nCountForState]++;
switch (cur_src->GetDownloadState())
{
case DS_DOWNLOADING:{
ASSERT( cur_src->socket );
if (cur_src->socket)
{
cur_src->CheckDownloadTimeout();
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);
if (cur_src->IsDownloadingFromPeerCache() && cur_src->m_pPCDownSocket && cur_src->m_pPCDownSocket->IsConnected())
cur_src->m_pPCDownSocket->SetDownloadLimit(limit);
}
else{
cur_src->socket->DisableDownloadLimit();
if (cur_src->IsDownloadingFromPeerCache() && cur_src->m_pPCDownSocket && cur_src->m_pPCDownSocket->IsConnected())
cur_src->m_pPCDownSocket->DisableDownloadLimit();
}
}
break;
}
// Do nothing with this client..
case DS_BANNED:
break;
// Check if something has changed with our or their ID state..
case DS_LOWTOLOWIP:
{
// To Mods, please stop instantly removing these sources..
// This causes sources to pop in and out creating extra overhead!
//Make sure this source is still a LowID Client..
if( cur_src->HasLowID() )
{
//Make sure we still cannot callback to this Client..
if( !theApp.DoCallback( cur_src ) )
{
//If we are almost maxed on sources, slowly remove these client to see if we can find a better source.
if( ((dwCurTick - lastpurgetime) > SEC2MS(30)) && (this->GetSourceCount() >= (thePrefs.GetMaxSourcePerFile()*.8 )) )
{
theApp.downloadqueue->RemoveSource( cur_src );
lastpurgetime = dwCurTick;
}
break;
}
}
// This should no longer be a LOWTOLOWIP..
cur_src->SetDownloadState(DS_ONQUEUE);
break;
}
case DS_NONEEDEDPARTS:
{
// To Mods, please stop instantly removing these sources..
// This causes sources to pop in and out creating extra overhead!
if( (dwCurTick - lastpurgetime) > SEC2MS(40) ){
lastpurgetime = dwCurTick;
// we only delete them if reaching the limit
if (GetSourceCount() >= (thePrefs.GetMaxSourcePerFile()*.8 )){
theApp.downloadqueue->RemoveSource( cur_src );
break;
}
}
// doubled reasktime for no needed parts - save connections and traffic
if (cur_src->GetTimeUntilReask() > 0)
break;
cur_src->SwapToAnotherFile(_T("A4AF for NNP file. CPartFile::Process()"), true, false, false, NULL, true, true); // ZZ:DownloadManager
// Recheck this client to see if still NNP.. Set to DS_NONE so that we force a TCP reask next time..
cur_src->SetDownloadState(DS_NONE);
break;
}
case DS_ONQUEUE:
{
// To Mods, please stop instantly removing these sources..
// This causes sources to pop in and out creating extra overhead!
if( cur_src->IsRemoteQueueFull() )
{
if( ((dwCurTick - lastpurgetime) > MIN2MS(1)) && (GetSourceCount() >= (thePrefs.GetMaxSourcePerFile()*.8 )) )
{
theApp.downloadqueue->RemoveSource( cur_src );
lastpurgetime = dwCurTick;
break;
}
}
//Give up to 1 min for UDP to respond.. If we are within one min of TCP reask, do not try..
if (theApp.IsConnected() && cur_src->GetTimeUntilReask() < MIN2MS(2) && cur_src->GetTimeUntilReask() > SEC2MS(1) && ::GetTickCount()-cur_src->getLastTriedToConnectTime() > 20*60*1000) // ZZ:DownloadManager (one resk timestamp for each file)
cur_src->UDPReaskForDownload();
}
case DS_CONNECTING:
case DS_TOOMANYCONNS:
case DS_TOOMANYCONNSKAD:
case DS_NONE:
case DS_WAITCALLBACK:
case DS_WAITCALLBACKKAD:
{
if (theApp.IsConnected() && cur_src->GetTimeUntilReask() == 0 && ::GetTickCount()-cur_src->getLastTriedToConnectTime() > 20*60*1000) // ZZ:DownloadManager (one resk timestamp for each file)
{
if(!cur_src->AskForDownload()) // NOTE: This may *delete* the client!!
break; //I left this break here just as a reminder just in case re rearange things..
}
break;
}
}
}
if( thePrefs.GetMaxSourcePerFileUDP() > GetSourceCount()){
if (theApp.downloadqueue->DoKademliaFileRequest() && (Kademlia::CKademlia::getTotalFile() < KADEMLIATOTALFILE) && (!lastsearchtimeKad || (dwCurTick - lastsearchtimeKad) > KADEMLIAREASKTIME) && Kademlia::CKademlia::isConnected() && theApp.IsConnected() && !stopped){ //Once we can handle lowID users in Kad, we remove the second IsConnected
//Kademlia
theApp.downloadqueue->SetLastKademliaFileRequest();
if (!GetKadFileSearchID())
{
Kademlia::CUInt128 kadFileID;
kadFileID.setValue(GetFileHash());
Kademlia::CSearch* pSearch = Kademlia::CSearchManager::prepareFindFile(Kademlia::CSearch::FILE, true, kadFileID);
if (pSearch)
{
lastsearchtimeKad = dwCurTick;
SetKadFileSearchID(pSearch->getSearchID());
}
else
SetKadFileSearchID(0);
}
}
}
else{
if(GetKadFileSearchID())
{
Kademlia::CSearchManager::stopSearch(GetKadFileSearchID(), true);
}
}
// check if we want new sources from server
if ( !m_bLocalSrcReqQueued && ((!lastsearchtime) || (dwCurTick - lastsearchtime) > SERVERREASKTIME) && theApp.serverconnect->IsConnected()
&& thePrefs.GetMaxSourcePerFileSoft() > GetSourceCount() && !stopped )
{
m_bLocalSrcReqQueued = true;
theApp.downloadqueue->SendLocalSrcRequest(this);
}
count++;
if (count == 3){
count = 0;
UpdateAutoDownPriority();
UpdateDisplayedInfo();
UpdateCompletedInfos();
}
}
if ( GetSrcStatisticsValue(DS_DOWNLOADING) != nOldTransSourceCount ){
if (theApp.emuledlg->transferwnd->downloadlistctrl.curTab == 0)
theApp.emuledlg->transferwnd->downloadlistctrl.ChangeCategory(0);
else
UpdateDisplayedInfo(true);
if (thePrefs.ShowCatTabInfos() )
theApp.emuledlg->transferwnd->UpdateCatTabTitles();
}
return datarate;
}
bool CPartFile::CanAddSource(uint32 userid, uint16 port, uint32 serverip, uint16 serverport, UINT* pdebug_lowiddropped, bool Ed2kID)
{
//The incoming ID could have the userid in the Hyrbid format..
uint32 hybridID = 0;
if( Ed2kID )
hybridID = ntohl(userid);
else
{
hybridID = userid;
userid = ntohl(userid);
}
// MOD Note: Do not change this part - Merkur
if (theApp.serverconnect->IsConnected())
{
if(theApp.serverconnect->IsLowID())
{
if(theApp.serverconnect->GetClientID() == userid && theApp.serverconnect->GetCurrentServer()->GetIP() == serverip && theApp.serverconnect->GetCurrentServer()->GetPort() == serverport )
return false;
if(theApp.serverconnect->GetLocalIP() == userid)
return false;
}
else
{
if(theApp.serverconnect->GetClientID() == userid && thePrefs.GetPort() == port)
return false;
}
}
if (Kademlia::CKademlia::isConnected())
{
ASSERT( Kademlia::CKademlia::getPrefs() != NULL);
if(Kademlia::CKademlia::isFirewalled())
{
//This will change with LowID support is added..
if(Kademlia::CKademlia::getPrefs()->getIPAddress() == hybridID && thePrefs.GetPort() == port)
return false;
}
else
{
if(Kademlia::CKademlia::getIPAddress() == hybridID && thePrefs.GetPort() == port)
return false;
}
}
//This allows *.*.*.0 clients to not be removed..
if ( ((Ed2kID && IsLowID(userid)) || (!Ed2kID && IsLowID(hybridID))) && theApp.IsFirewalled())
{
if (pdebug_lowiddropped)
(*pdebug_lowiddropped)++;
return false;
}
// MOD Note - end
return
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -