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

📄 downloading.cpp

📁 Last change: 2008-02-03 This is the source code of KCeasy。
💻 CPP
📖 第 1 页 / 共 2 页
字号:

    // 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 + -