📄 downloading.cpp
字号:
// state
if(Cmd->GetNode("state").Value == "Verifying")
State = Verifying;
else if(Cmd->GetNode("state").Value == "Corrupted")
State = Failed;
else if(Cmd->GetNode("state").Value == "Completed")
State = Completed;
else if(Cmd->GetNode("state").Value == "Paused")
State = Paused;
else if(Throughput.GetBps() > 0)
State = Downloading;
else
State = Queued;
if(State == Downloading)
LastActiveTime = ::GetTickCount();
Engine->ReleaseDownloads();
// notify UI
Engine->SendCallback(CbcDownloadUpdate,(void*)this);
return true;
}
bool TDownload::ProcessAddSource(TGiftCommand* Cmd)
{
if(Cmd->Name != "ADDSOURCE" || string_to_int(Cmd->Value) != GiftId)
return false;
if(State == Cancelled || State == Completed || State == Failed)
return false;
Engine->LockDownloads();
// add source if it doesn't exist
// find matching source
string SourceId = Cmd->GetNode("url").Value;
LockSources();
TDownload::TSourceIterator sitr = Sources.begin();
while(sitr != Sources.end() && (*sitr)->SourceId != SourceId)
++sitr;
if(sitr == Sources.end()) {
// new source, should always be the case
sitr = Sources.insert(Sources.end(),new TDlSource());
}
// update source
(*sitr)->SourceId = Cmd->GetNode("url").Value;
(*sitr)->GetUser()->SetId(Cmd->GetNode("user").Value);
(*sitr)->Start = string_to_int(Cmd->GetNode("start").Value);
(*sitr)->Size = string_to_int(Cmd->GetNode("total").Value);
(*sitr)->Transmitted = string_to_int(Cmd->GetNode("transmit").Value);
(*sitr)->Network = ProtocolFromUrl((*sitr)->SourceId);
(*sitr)->SetStateStr(Cmd->GetNode("statusgrl").Value);
(*sitr)->ProtoState = Cmd->GetNode("status").Value;
// set download network if it's still empty
if(Network == "")
Network = (*sitr)->Network;
ReleaseSources();
Engine->ReleaseDownloads();
// notify UI
Engine->SendCallback(CbcDownloadAddSource,(void*)this,(void*)(*sitr));
return true;
}
bool TDownload::ProcessDelSource(TGiftCommand* Cmd)
{
if(Cmd->Name != "DELSOURCE" || string_to_int(Cmd->Value) != GiftId)
return false;
Engine->LockDownloads();
// find source
string SourceId = Cmd->GetNode("url").Value;
LockSources();
TDownload::TSourceIterator sitr = Sources.begin();
while(sitr != Sources.end() && (*sitr)->SourceId != SourceId)
++sitr;
if(sitr != Sources.end()) {
ReleaseSources();
Engine->ReleaseDownloads();
// notify UI
Engine->SendCallback(CbcDownloadDelSource,(void*)this,(void*)(*sitr));
Engine->LockDownloads();
LockSources();
delete *sitr;
Sources.erase(sitr);
}
// recalculate state of download
Throughput.SetBps(0);
for(sitr = Sources.begin();sitr != Sources.end(); ++sitr)
Throughput.SetBps(Throughput.GetBps() + (*sitr)->Throughput.GetBps());
if(State == Downloading && Throughput.GetBps() == 0)
State = Queued;
ReleaseSources();
Engine->ReleaseDownloads();
// notify UI
Engine->SendCallback(CbcDownloadUpdate,(void*)this);
return true;
}
// public
bool TDownload::AddSource(const TSearchResult* SearchResult)
{
if(State == Cancelled || State == Completed || State == Failed)
return false;
// hack to not start a new download with gift
if(Cancelling)
return false;
// only allow one source if no hash
if((GetNoOfSources() > 0 && GetHashes()->Size() == 0) ||
!GetHashes()->Equals(SearchResult->GetHashes()))
{
return false;
}
// only allow MaxSources sources
if(GetNoOfSources() >= GetMaxSources() && GetMaxSources() != 0)
return false;
// check for duplicate source
Engine->LockDownloads();
LockSources();
TSourceIterator sitr = Sources.begin();
while(sitr != Sources.end() && (*sitr)->SourceId != SearchResult->SourceId)
++sitr;
if(sitr != Sources.end()) {
ReleaseSources();
Engine->ReleaseDownloads();
return false;
}
ReleaseSources();
Engine->ReleaseDownloads();
// adding the source to the list is done in when giFT sends ADDSOURCE
TDlSource* Source = new TDlSource();
Source->SourceId = SearchResult->SourceId;
Source->GetUser()->SetId(SearchResult->GetUser()->GetId());
LockSources();
Sources.push_back(Source);
ReleaseSources();
// if we don't have meta data for this download get it now
if(MetaData.Empty())
MetaData = SearchResult->MetaData;
if(MimeType == "")
MimeType = SearchResult->MimeType;
// file size can be 0 initially if we created the download from a hash
if(FileSize == 0)
FileSize = SearchResult->FileSize;
TGiftCommand* Cmd = new TGiftCommand("ADDSOURCE");
Cmd->AddNode(TGiftCommand("hash",Hashes->GetFirstHash()->GetGiftHash()));
Cmd->AddNode(TGiftCommand("size",int_to_string(FileSize)));
Cmd->AddNode(TGiftCommand("user",SearchResult->GetUser()->GetId()));
Cmd->AddNode(TGiftCommand("url",SearchResult->SourceId));
Cmd->AddNode(TGiftCommand("save",SaveFileName));
Engine->QueueCommand(Cmd);
return true;
}
bool TDownload::RemoveSource(TDlSource* Source)
{
if(State == Completed || State == Cancelled || State == Failed || State == New)
return false;
// removing the source from the list is done in when giFT sends DELSOURCE
TGiftCommand* Cmd = new TGiftCommand("DELSOURCE",int_to_string(GiftId));
Cmd->AddNode(TGiftCommand("hash",Hashes->GetFirstHash()->GetGiftHash()));
Cmd->AddNode(TGiftCommand("url",Source->SourceId));
Engine->QueueCommand(Cmd);
return true;
}
bool TDownload::FindMoreSources()
{
if(IsFindingMoreSources())
return false;
// HACKHACK: we include Registering here because this may be called from
// Engine::NewDownload()
if(State != Downloading && State != Queued && State != Paused && State != Registering)
return false;
// start search on all networks so we can merge sources
TSearch* Search = Engine->NewSearch(GetHashes(), "", true);
if(!Search)
return false;
Search->SetUData((void*)this);
SourcesSearch = Search;
Search->Start();
// TODO: remove old sources so they don't prevent addition of new ones
// for now just increase the maxiumum
SetMaxSources(GetMaxSources()*2);
// notify UI of state change
Engine->SendCallback(CbcDownloadUpdate,(void*)this);
return true;
}
bool TDownload::KeepAlive()
{
if(IsFindingMoreSources())
return false;
if(State != Queued)
return false;
if(::GetTickCount() < LastActiveTime + KEEP_ALIVE_TIMEOUT)
return false;
// try again earliest in 2 * KEEP_ALIVE_TIMEOUT
LastActiveTime = ::GetTickCount() + KEEP_ALIVE_TIMEOUT;
// try to find new sources
return FindMoreSources();
}
bool TDownload::Pause()
{
if(State == New || State == Completed || State == Cancelled || State == Failed)
return false;
if(State != Paused) {
TGiftCommand* Cmd = new TGiftCommand("TRANSFER",int_to_string(GiftId));
Cmd->AddNode(TGiftCommand("action","pause"));
Engine->QueueCommand(Cmd);
}
return true;
}
bool TDownload::Resume()
{
if(State != Paused)
return false;
TGiftCommand* Cmd = new TGiftCommand("TRANSFER",int_to_string(GiftId));
Cmd->AddNode(TGiftCommand("action","unpause"));
Engine->QueueCommand(Cmd);
return true;
}
bool TDownload::Cancel()
{
if(State == New || State == Completed || State == Cancelled || State == Failed)
return false;
// hack to not add any more sources
Cancelling = true;
/*
// set state now to prevent race condition with addition of new sources
// while download already cancelled
State = Cancelled;
*/
TGiftCommand* Cmd = new TGiftCommand("TRANSFER",int_to_string(GiftId));
Cmd->AddNode(TGiftCommand("action","cancel"));
Engine->QueueCommand(Cmd);
/*
// notify UI
// Note: CbcDownloadUpdate may remove the download!
Engine->SendCallback(CbcDownloadUpdate,(void*)this);
*/
return true;
}
void TDownload::SetMaxSources(unsigned int Max)
{
MaxSources = Max;
// TODO: remove if there are more sources?
}
} // namespace KCeasyEngine
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -