📄 partfile.cpp
字号:
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 + -