diff --git a/Sources/Plasma/FeatureLib/pfPatcher/pfPatcher.cpp b/Sources/Plasma/FeatureLib/pfPatcher/pfPatcher.cpp index d4705e62..07dff2f5 100644 --- a/Sources/Plasma/FeatureLib/pfPatcher/pfPatcher.cpp +++ b/Sources/Plasma/FeatureLib/pfPatcher/pfPatcher.cpp @@ -89,6 +89,10 @@ struct pfPatcherWorker : public hsThread // Any file kFlagZipped = 1<<3, + + // Begin internal flags + kLastManifestFlag = 1<<4, + kSelfPatch = 1<<5, }; std::deque fRequests; @@ -103,6 +107,7 @@ struct pfPatcherWorker : public hsThread pfPatcher::FileDownloadFunc fFileDownloaded; pfPatcher::GameCodeDiscoverFunc fGameCodeDiscovered; pfPatcher::ProgressTickFunc fProgressTick; + pfPatcher::FileDownloadFunc fSelfPatch; pfPatcher* fParent; volatile bool fStarted; @@ -199,6 +204,7 @@ public: void Begin() { fDLStartTime = hsTimer::GetSysSeconds(); } plFileName GetFileName() const { return fFilename; } + bool IsSelfPatch() const { return hsCheckBits(fFlags, pfPatcherWorker::kSelfPatch); } void Unlink() const { plFileSystem::Unlink(fFilename); } }; @@ -306,6 +312,8 @@ static void IFileThingDownloadCB(ENetError result, void* param, const plFileName if (IS_NET_SUCCESS(result)) { PatcherLogGreen("\tDownloaded File '%s'", stream->GetFileName().AsString().c_str()); patcher->WhitelistFile(stream->GetFileName(), true); + if (patcher->fSelfPatch && stream->IsSelfPatch()) + patcher->fSelfPatch(stream->GetFileName()); patcher->IssueRequest(); } else { PatcherLogRed("\tDownloaded Failed: File '%s'", stream->GetFileName().AsString().c_str()); @@ -454,7 +462,7 @@ hsError pfPatcherWorker::Run() void pfPatcherWorker::ProcessFile() { do { - const NetCliFileManifestEntry& entry = fQueuedFiles.front(); + NetCliFileManifestEntry& entry = fQueuedFiles.front(); // eap sucks plFileName clName = plString::FromWchar(entry.clientName); @@ -478,6 +486,15 @@ void pfPatcherWorker::ProcessFile() 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"); @@ -562,6 +579,11 @@ void pfPatcher::OnProgressTick(ProgressTickFunc cb) fWorker->fProgressTick = cb; } +void pfPatcher::OnSelfPatch(FileDownloadFunc cb) +{ + fWorker->fSelfPatch = cb; +} + // =================================================== void pfPatcher::RequestGameCode() diff --git a/Sources/Plasma/FeatureLib/pfPatcher/pfPatcher.h b/Sources/Plasma/FeatureLib/pfPatcher/pfPatcher.h index 6610b722..dee1b77b 100644 --- a/Sources/Plasma/FeatureLib/pfPatcher/pfPatcher.h +++ b/Sources/Plasma/FeatureLib/pfPatcher/pfPatcher.h @@ -112,6 +112,9 @@ public: */ void OnProgressTick(ProgressTickFunc cb); + /** This is called when the current application has been updated. */ + void OnSelfPatch(FileDownloadFunc cb); + void RequestGameCode(); void RequestManifest(const plString& mfs); void RequestManifest(const std::vector& mfs);