void pfPatcherWorker::ProcessFile() { do { NetCliFileManifestEntry& entry = fQueuedFiles.front(); // eap sucks plFileName clName = plString::FromWchar(entry.clientName); plString dlName = plString::FromWchar(entry.downloadName); // Check to see if ours matches plFileInfo mine(clName); if (mine.FileSize() == entry.fileSize) { plMD5Checksum cliMD5(clName); plMD5Checksum srvMD5; srvMD5.SetFromHexString(plString::FromWchar(entry.md5, 32).c_str()); if (cliMD5 == srvMD5) { WhitelistFile(clName, false); fQueuedFiles.pop_front(); continue; } } // It's different... but do we want it? if (fFileDownloadDesired) { if (!fFileDownloadDesired(clName)) { PatcherLogRed("\tDeclined '%S'", entry.clientName); fQueuedFiles.pop_front(); continue; } } // If you got here, they're different and we want it. PatcherLogYellow("\tEnqueuing '%S'", entry.clientName); plFileSystem::CreateDir(plFileName(clName).StripFileName()); // If someone registered for SelfPatch notifications, then we should probably // let them handle the gruntwork... Otherwise, go nuts! if (fSelfPatch) { if (clName == plFileSystem::GetCurrentAppPath().GetFileName()) { clName += ".tmp"; // don't overwrite myself! entry.flags |= kSelfPatch; } } pfPatcherStream* s = new pfPatcherStream(this, dlName, entry); s->Open(clName, "wb"); hsTempMutexLock lock(fRequestMut); fRequests.push_back(Request(dlName, Request::kFile, s)); fQueuedFiles.pop_front(); if (!fRequestActive) IssueRequest(); } while (!fQueuedFiles.empty()); }
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; }