📄 downloadqueue.cpp
字号:
{
if (thePrefs.GetDebugServerUDPLevel() > 0 && thePrefs.GetDebugServerSourcesLevel() > 0)
Debug(_T("Rotating file list\n"));
// move the last 35 files to the head
if (filelist.GetCount() >= MAX_REQUESTS_PER_SERVER){
for (int i = 0; i != MAX_REQUESTS_PER_SERVER; i++){
filelist.AddHead( filelist.RemoveTail() );
}
}
// and next server
cur_udpserver = theApp.serverlist->GetNextServer(cur_udpserver);
m_cRequestsSentToServer = 0;
if (cur_udpserver == NULL){
lastudpsearchtime = ::GetTickCount();
lastfile = NULL;
return false; // finished (processed all file & all servers)
}
m_iSearchedServers++;
lastfile = NULL;
}
return true;
}
void CDownloadQueue::StopUDPRequests(){
cur_udpserver = 0;
lastudpsearchtime = ::GetTickCount();
lastfile = 0;
}
// SLUGFILLER: checkDiskspace
bool CDownloadQueue::CompareParts(POSITION pos1, POSITION pos2){
CPartFile* file1 = filelist.GetAt(pos1);
CPartFile* file2 = filelist.GetAt(pos2);
return CPartFile::RightFileHasHigherPrio(file1, file2);
}
void CDownloadQueue::SwapParts(POSITION pos1, POSITION pos2){
CPartFile* file1 = filelist.GetAt(pos1);
CPartFile* file2 = filelist.GetAt(pos2);
filelist.SetAt(pos1, file2);
filelist.SetAt(pos2, file1);
}
void CDownloadQueue::HeapSort(uint16 first, uint16 last){
uint16 r;
POSITION pos1 = filelist.FindIndex(first);
for ( r = first; !(r & 0x8000) && (r<<1) < last; ){
uint16 r2 = (r<<1)+1;
POSITION pos2 = filelist.FindIndex(r2);
if (r2 != last){
POSITION pos3 = pos2;
filelist.GetNext(pos3);
if (!CompareParts(pos2, pos3)){
pos2 = pos3;
r2++;
}
}
if (!CompareParts(pos1, pos2)) {
SwapParts(pos1, pos2);
r = r2;
pos1 = pos2;
}
else
break;
}
}
void CDownloadQueue::SortByPriority(){
uint16 n = filelist.GetCount();
if (!n)
return;
uint16 i;
for ( i = n/2; i--; )
HeapSort(i, n-1);
for ( i = n; --i; ){
SwapParts(filelist.FindIndex(0), filelist.FindIndex(i));
HeapSort(0, i-1);
}
}
void CDownloadQueue::CheckDiskspaceTimed()
{
if ((!lastcheckdiskspacetime) || (::GetTickCount() - lastcheckdiskspacetime) > DISKSPACERECHECKTIME)
CheckDiskspace();
}
void CDownloadQueue::CheckDiskspace(bool bNotEnoughSpaceLeft)
{
lastcheckdiskspacetime = ::GetTickCount();
// sorting the list could be done here, but I prefer to "see" that function call in the calling functions.
//SortByPriority();
// If disabled, resume any previously paused files
if (!thePrefs.IsCheckDiskspaceEnabled())
{
if (!bNotEnoughSpaceLeft) // avoid worse case, if we already had 'disk full'
{
for( POSITION pos1 = filelist.GetHeadPosition(); pos1 != NULL; )
{
CPartFile* cur_file = filelist.GetNext(pos1);
switch(cur_file->GetStatus())
{
case PS_PAUSED:
case PS_ERROR:
case PS_COMPLETING:
case PS_COMPLETE:
continue;
}
cur_file->ResumeFileInsufficient();
}
}
return;
}
// 'bNotEnoughSpaceLeft' - avoid worse case, if we already had 'disk full'
uint64 nTotalAvailableSpace = bNotEnoughSpaceLeft ? 0 : GetFreeDiskSpaceX(thePrefs.GetTempDir());
if (thePrefs.GetMinFreeDiskSpace() == 0)
{
for( POSITION pos1 = filelist.GetHeadPosition(); pos1 != NULL; )
{
CPartFile* cur_file = filelist.GetNext(pos1);
switch(cur_file->GetStatus())
{
case PS_PAUSED:
case PS_ERROR:
case PS_COMPLETING:
case PS_COMPLETE:
continue;
}
// Pause the file only if it would grow in size and would exceed the currently available free space
uint32 nSpaceToGo = cur_file->GetNeededSpace();
if (nSpaceToGo <= nTotalAvailableSpace)
{
nTotalAvailableSpace -= nSpaceToGo;
cur_file->ResumeFileInsufficient();
}
else
cur_file->PauseFile(true/*bInsufficient*/);
}
}
else
{
for( POSITION pos1 = filelist.GetHeadPosition(); pos1 != NULL; )
{
CPartFile* cur_file = filelist.GetNext(pos1);
switch(cur_file->GetStatus())
{
case PS_PAUSED:
case PS_ERROR:
case PS_COMPLETING:
case PS_COMPLETE:
continue;
}
if (nTotalAvailableSpace < thePrefs.GetMinFreeDiskSpace())
{
if (cur_file->IsNormalFile())
{
// Normal files: pause the file only if it would still grow
uint32 nSpaceToGrow = cur_file->GetNeededSpace();
if (nSpaceToGrow)
cur_file->PauseFile(true/*bInsufficient*/);
}
else
{
// Compressed/sparse files: always pause the file
cur_file->PauseFile(true/*bInsufficient*/);
}
}
else
{
// doesn't work this way. resuming the file without checking if there is a chance to successfully
// flush any available buffered file data will pause the file right after it was resumed and disturb
// the StopPausedFile function.
//cur_file->ResumeFileInsufficient();
}
}
}
}
// SLUGFILLER: checkDiskspace
void CDownloadQueue::GetDownloadStats(SDownloadStats& results)
{
memset(&results, 0, sizeof results);
for (POSITION pos = filelist.GetHeadPosition(); pos != 0; )
{
const CPartFile* cur_file = filelist.GetNext(pos);
results.a[0] += cur_file->GetSourceCount();
results.a[1] += cur_file->GetTransferingSrcCount();
results.a[2] += cur_file->GetSrcStatisticsValue(DS_ONQUEUE);
results.a[3] += cur_file->GetSrcStatisticsValue(DS_REMOTEQUEUEFULL);
results.a[4] += cur_file->GetSrcStatisticsValue(DS_NONEEDEDPARTS);
results.a[5] += cur_file->GetSrcStatisticsValue(DS_CONNECTED);
results.a[6] += cur_file->GetSrcStatisticsValue(DS_REQHASHSET);
results.a[7] += cur_file->GetSrcStatisticsValue(DS_CONNECTING);
results.a[8] += cur_file->GetSrcStatisticsValue(DS_WAITCALLBACK);
results.a[8] += cur_file->GetSrcStatisticsValue(DS_WAITCALLBACKKAD);
results.a[9] += cur_file->GetSrcStatisticsValue(DS_TOOMANYCONNS);
results.a[9] += cur_file->GetSrcStatisticsValue(DS_TOOMANYCONNSKAD);
results.a[10] += cur_file->GetSrcStatisticsValue(DS_LOWTOLOWIP);
results.a[11] += cur_file->GetSrcStatisticsValue(DS_NONE);
results.a[12] += cur_file->GetSrcStatisticsValue(DS_ERROR);
results.a[13] += cur_file->GetSrcStatisticsValue(DS_BANNED);
results.a[14] += cur_file->src_stats[3];
results.a[15] += cur_file->GetSrcA4AFCount();
results.a[16] += cur_file->src_stats[0];
results.a[17] += cur_file->src_stats[1];
results.a[18] += cur_file->src_stats[2];
results.a[19] += cur_file->net_stats[0];
results.a[20] += cur_file->net_stats[1];
results.a[21] += cur_file->net_stats[2];
}
}
CUpDownClient* CDownloadQueue::GetDownloadClientByIP(uint32 dwIP){
for (POSITION pos = filelist.GetHeadPosition();pos != 0;){
CPartFile* cur_file = filelist.GetNext(pos);
for (POSITION pos2 = cur_file->srclist.GetHeadPosition();pos2 != 0; ){
CUpDownClient* cur_client = cur_file->srclist.GetNext(pos2);
if (dwIP == cur_client->GetIP()){
return cur_client;
}
}
}
return NULL;
}
CUpDownClient* CDownloadQueue::GetDownloadClientByIP_UDP(uint32 dwIP, uint16 nUDPPort){
for (POSITION pos = filelist.GetHeadPosition();pos != 0;){
CPartFile* cur_file = filelist.GetNext(pos);
for (POSITION pos2 = cur_file->srclist.GetHeadPosition();pos2 != 0;){
CUpDownClient* cur_client = cur_file->srclist.GetNext(pos2);
if (dwIP == cur_client->GetIP() && nUDPPort == cur_client->GetUDPPort()){
return cur_client;
}
}
}
return NULL;
}
bool CDownloadQueue::IsInList(const CUpDownClient* client) const
{
for (POSITION pos = filelist.GetHeadPosition();pos != 0;){
CPartFile* cur_file = filelist.GetNext(pos);
for (POSITION pos2 = cur_file->srclist.GetHeadPosition();pos2 != 0;){
if (cur_file->srclist.GetNext(pos2) == client)
return true;
}
}
return false;
}
void CDownloadQueue::ResetCatParts(int cat)
{
CPartFile* cur_file;
for (POSITION pos = filelist.GetHeadPosition(); pos != 0; ){
cur_file = filelist.GetNext(pos);
if (cur_file->GetCategory()==cat)
cur_file->SetCategory(0);
else if (cur_file->GetCategory() > cat)
cur_file->SetCategory(cur_file->GetCategory() - 1, false);
}
}
void CDownloadQueue::SetCatPrio(int cat, uint8 newprio)
{
for (POSITION pos = filelist.GetHeadPosition(); pos != 0; ){
CPartFile* cur_file = filelist.GetNext(pos);
if (cat==0 || cur_file->GetCategory()==cat)
if (newprio==PR_AUTO) {
cur_file->SetAutoDownPriority(true);
cur_file->SetDownPriority(PR_HIGH, false);
}
else {
cur_file->SetAutoDownPriority(false);
cur_file->SetDownPriority(newprio, false);
}
}
theApp.downloadqueue->SortByPriority();
theApp.downloadqueue->CheckDiskspaceTimed();
}
// ZZ:DownloadManager -->
void CDownloadQueue::RemoveAutoPrioInCat(int cat, uint8 newprio){
CPartFile* cur_file;
for (POSITION pos = filelist.GetHeadPosition();pos != 0;filelist.GetNext(pos)){
cur_file = filelist.GetAt(pos);
if (cur_file->IsAutoDownPriority() && (cat==0 || cur_file->GetCategory()==cat)) {
cur_file->SetAutoDownPriority(false);
cur_file->SetDownPriority(newprio, false);
}
}
theApp.downloadqueue->SortByPriority();
theApp.downloadqueue->CheckDiskspaceTimed(); // SLUGFILLER: checkDiskspace
}
// <-- ZZ:DownloadManager
void CDownloadQueue::SetCatStatus(int cat, int newstatus)
{
bool reset = false;
bool resort = false;
POSITION pos= filelist.GetHeadPosition();
while (pos != 0)
{
CPartFile* cur_file = filelist.GetAt(pos);
if (!cur_file)
continue;
if (cat==-1 ||
(cat==-2 && cur_file->GetCategory()==0) ||
(cat==0 && cur_file->CheckShowItemInGivenCat(cat)) ||
(cat>0 && cat==cur_file->GetCategory()))
{
switch (newstatus){
case MP_CANCEL:
cur_file->DeleteFile();
reset = true;
break;
case MP_PAUSE:
cur_file->PauseFile(false, false);
resort = true;
break;
case MP_STOP:
cur_file->StopFile(false, false);
resort = true;
break;
case MP_RESUME:
if (cur_file->CanResumeFile()){
if (cur_file->GetStatus() == PS_INSUFFICIENT)
cur_file->ResumeFileInsufficient();
else {
cur_file->ResumeFile(false);
resort = true;
}
}
break;
}
}
filelist.GetNext(pos);
if (reset)
{
reset = false;
pos = filelist.GetHeadPosition();
}
}
if(resort) {
theApp.downloadqueue->SortByPriority();
theApp.downloadqueue->CheckDiskspace(); // SLUGFILLER: checkDiskspace
}
}
void CDownloadQueue::MoveCat(uint8 from, uint8 to)
{
if (from < to)
--to;
POSITION pos= filelist.GetHeadPosition();
while (pos != 0)
{
CPartFile* cur_file = filelist.GetAt(pos);
if (!cur_file)
continue;
uint8 mycat = cur_file->GetCategory();
if ((mycat>=min(from,to) && mycat<=max(from,to)))
{
//if ((from<to && (mycat<from || mycat>to)) || (from>to && (mycat>from || mycat<to)) ) continue; //not affected
if (mycat == from)
cur_file->SetCategory(to);
else{
if (from < to)
cur_file->SetCategory(mycat - 1);
else
cur_file->SetCategory(mycat + 1);
}
}
filelist.GetNext(pos);
}
}
UINT CDownloadQueue::GetDownloadingFileCount() const
{
UINT result = 0;
for (POSITION pos = filelist.GetHeadPosition();pos != 0;){
UINT uStatus = filelist.GetNext(pos)->GetStatus();
if (uStatus == PS_READY || uStatus == PS_EMPTY)
result++;
}
return result;
}
uint16 CDownloadQueue::GetPausedFileCount(){
uint16 result = 0;
for (POSITION pos = filelist.GetHeadPosition();pos != 0;){
CPartFile* cur_file = filelist.GetNext(pos);
if (cur_file->GetStatus() == PS_PAUSED)
result++;
}
return result;
}
void CDownloadQueue::DisableAllA4AFAuto(void)
{
for (POSITION pos = filelist.GetHeadPosition(); pos != NULL; )
filelist.GetNext(pos)->SetA4AFAuto(false);
}
// HoaX_69: BEGIN AutoCat function
void CDownloadQueue::SetAutoCat(CPartFile* newfile){
if(thePrefs.GetCatCount()>1){
for (int ix=1;ix<thePrefs.GetCatCount();ix++){
int curPos = 0;
CString catExt = thePrefs.GetCategory(ix)->autocat;
catExt.MakeLower();
// No need to compare agains an empty AutoCat array
if( catExt.IsEmpty())
continue;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -