예제 #1
0
static void ManifestDownloaded(
    ENetError                     result, 
    void*                         param, 
    const wchar_t                 group[], 
    const NetCliFileManifestEntry manifest[], 
    uint32_t                        entryCount)
{
    plResPatcher* patcher = (plResPatcher*)param;
    char* name = hsWStringToString(group);
    if (IS_NET_SUCCESS(result))
        PatcherLog(kInfo, "    Downloaded manifest %s", name);
    else {
        PatcherLog(kError, "    Failed to download manifest %s", name);
        patcher->Finish(false);
        delete[] name;
        return;
    }

    for (uint32_t i = 0; i < entryCount; ++i)
    {
        const NetCliFileManifestEntry mfs = manifest[i];
        char* fileName = hsWStringToString(mfs.clientName);

        // See if the files are the same
        // 1. Check file size before we do time consuming md5 operations
        // 2. Do wasteful md5. We should consider implementing a CRC instead.
        if (plFileUtils::GetFileSize(fileName) == mfs.fileSize)
        {
            plMD5Checksum cliMD5(fileName);
            plMD5Checksum srvMD5;
            char* eapSucksString = hsWStringToString(mfs.md5);
            srvMD5.SetFromHexString(eapSucksString);
            delete[] eapSucksString;

            if (cliMD5 == srvMD5)
            {
                delete[] fileName;
                continue;
            } else
                PatcherLog(kInfo, "    Enqueueing %s: MD5 Checksums Differ", fileName);
        } else
            PatcherLog(kInfo, "    Enqueueing %s: File Sizes Differ", fileName);

        // If we're still here, then we need to update the file.
        float size = mfs.zipSize ? (float)mfs.zipSize : (float)mfs.fileSize;
        patcher->GetProgress()->SetLength(size + patcher->GetProgress()->GetMax());
        patcher->RequestFile(mfs.downloadName, mfs.clientName);
    }

    patcher->IssueRequest();
    delete[] name;
}
예제 #2
0
static void FileDownloaded(
    ENetError           result,
    void*               param,
    const plFileName &  filename,
    hsStream*           writer)
{
    plResPatcher* patcher = (plResPatcher*)param;
    plFileName file = filename;
    if (((plResDownloadStream*)writer)->IsZipped())
        file = file.StripFileExt(); // Kill off .gz
    writer->Close();

    switch (result)
    {
        case kNetSuccess:
        {
            PatcherLog(kStatus, "    Download Complete: %s", file.AsString().c_str());
            
            // If this is a PRP, then we need to add it to the ResManager
            plFileName clientPath = static_cast<plResDownloadStream*>(writer)->GetFileName();
            if (clientPath.GetFileExt().CompareI("prp") == 0)
            {
                plResManager* clientResMgr = static_cast<plResManager*>(hsgResMgr::ResMgr());
                clientResMgr->AddSinglePage(clientPath);
            }

            // Continue down the warpath
            patcher->IssueRequest();
            delete writer;
            return;
        }
        case kNetErrFileNotFound:
            PatcherLog(kError, "    Download Failed: %s not found", file.AsString().c_str());
            break;
        default:
            char* error = hsWStringToString(NetErrorToString(result));
            PatcherLog(kError, "    Download Failed: %s", error);
            delete[] error;
            break;
    }

    // Failure case
    static_cast<plResDownloadStream*>(writer)->Unlink();
    patcher->Finish(false);
    delete writer;
}
예제 #3
0
void plResPatcher::Start()
{
    hsAssert(!fPatching, "Too many calls to plResPatcher::Start");
    fPatching = true;
    PatcherLog(kHeader, "--- Patch Started (%i requests) ---", fRequests.size());
    fProgress = plProgressMgr::GetInstance()->RegisterOperation(0.0, "Checking for updates...",
        plProgressMgr::kUpdateText, false, true);
    IssueRequest();
}
예제 #4
0
void plResPatcher::IssueRequest()
{
    if (!fPatching) return;
    if (fRequests.empty())
        // Wheee!
        Finish();
    else {
        Request req = fRequests.front();
        fRequests.pop();

        std::wstring title;
        if (req.fType == kManifest)
        {
            char* eapSucksString = hsWStringToString(req.fFile.c_str());
            PatcherLog(kMajorStatus, "    Downloading manifest... %s", eapSucksString);
            xtl::format(title, L"Checking %s for updates...", req.fFile.c_str());
            NetCliFileManifestRequest(ManifestDownloaded, this, req.fFile.c_str());
            delete[] eapSucksString;
        } else if (req.fType == kFile) {
            char* eapSucksString = hsWStringToString(req.fFriendlyName.c_str());
            PatcherLog(kMajorStatus, "    Downloading file... %s", eapSucksString);
            xtl::format(title, L"Downloading... %s", plFileUtils::GetFileName(req.fFriendlyName.c_str()));

            // If this is a PRP, we need to unload it from the ResManager
            if (stricmp(plFileUtils::GetFileExt(eapSucksString), "prp") == 0)
                ((plResManager*)hsgResMgr::ResMgr())->RemoveSinglePage(eapSucksString);

            plFileUtils::EnsureFilePathExists(req.fFriendlyName.c_str());
            plResDownloadStream* stream = new plResDownloadStream(fProgress, req.fFile.c_str());
            if(stream->Open(eapSucksString, "wb"))
                NetCliFileDownloadRequest(req.fFile.c_str(), stream, FileDownloaded, this);
            else {
                PatcherLog(kError, "    Unable to create file %s", eapSucksString);
                Finish(false);
            }
            delete[] eapSucksString;
        }

        char* hack = hsWStringToString(title.c_str());
        fProgress->SetTitle(hack);
        delete[] hack;
    }
}
예제 #5
0
static void FileDownloaded(
    ENetError       result,
    void*           param,
    const wchar_t   filename[],
    hsStream*       writer) 
{
    plResPatcher* patcher = (plResPatcher*)param;
    char* name = hsWStringToString(filename);
    if (((plResDownloadStream*)writer)->IsZipped())
        plFileUtils::StripExt(name); // Kill off .gz
    writer->Close();

    switch (result)
    {
        case kNetSuccess:
            PatcherLog(kStatus, "    Download Complete: %s", name);
            
            // If this is a PRP, then we need to add it to the ResManager
            if (stricmp(plFileUtils::GetFileExt(name), "prp") == 0)
                ((plResManager*)hsgResMgr::ResMgr())->AddSinglePage(name);

            // Continue down the warpath
            patcher->IssueRequest();
            delete[] name;
            delete writer;
            return;
        case kNetErrFileNotFound:
            PatcherLog(kError, "    Download Failed: %s not found", name);
            break;
        default:
            char* error = hsWStringToString(NetErrorToString(result));
            PatcherLog(kError, "    Download Failed: %s", error);
            delete[] error;
            break;
    }

    // Failure case
    ((plResDownloadStream*)writer)->Unlink();
    patcher->Finish(false);
    delete[] name;
    delete writer;
}
예제 #6
0
void plResPatcher::Finish(bool success)
{
    while (fRequests.size())
        fRequests.pop();

    fPatching = false;
    if (success)
        PatcherLog(kHeader, "--- Patch Completed Successfully ---");
    else
    {
        PatcherLog(kHeader, "--- Patch Killed by Error ---");
        if (fProgress)
            fProgress->SetAborting();
    }
    delete fProgress; fProgress = nil;

    plResPatcherMsg* pMsg = new plResPatcherMsg(success, sLastError);
    delete[] sLastError; sLastError = nil;
    pMsg->Send(); // whoosh... off it goes
}
예제 #7
0
void plResPatcher::IssueRequest()
{
    if (!fPatching) return;
    if (fRequests.empty())
        // Wheee!
        Finish();
    else {
        Request req = fRequests.front();
        fRequests.pop();

        plString title;
        if (req.fType == kManifest)
        {
            PatcherLog(kMajorStatus, "    Downloading manifest... %s", req.fFile.AsString().c_str());
            title = plString::Format("Checking %s for updates...", req.fFile.AsString().c_str());
            NetCliFileManifestRequest(ManifestDownloaded, this, req.fFile.AsString().ToWchar());
        } else if (req.fType == kFile) {
            PatcherLog(kMajorStatus, "    Downloading file... %s", req.fFriendlyName.AsString().c_str());
            title = plString::Format("Downloading... %s", req.fFriendlyName.GetFileName().c_str());

            // If this is a PRP, we need to unload it from the ResManager

            if (req.fFriendlyName.GetFileExt().CompareI("prp") == 0)
                ((plResManager*)hsgResMgr::ResMgr())->RemoveSinglePage(req.fFriendlyName);

            plFileSystem::CreateDir(req.fFriendlyName.StripFileName(), true);
            plResDownloadStream* stream = new plResDownloadStream(fProgress, req.fFile);
            if (stream->Open(req.fFriendlyName, "wb"))
                NetCliFileDownloadRequest(req.fFile, stream, FileDownloaded, this);
            else {
                PatcherLog(kError, "    Unable to create file %s", req.fFriendlyName.AsString().c_str());
                Finish(false);
            }
        }

        fProgress->SetTitle(title.c_str());
    }
}