@@ -31,6 +31,9 @@ static const std::string UpdateExecutablePatchFile = "default.xexp";
3131static const std::string ISOExtension = " .iso" ;
3232static const std::string OldExtension = " .old" ;
3333static const std::string TempExtension = " .tmp" ;
34+ #ifdef UNLEASHED_RECOMP_IOS
35+ static const std::string InstallValidationFile = " install.validated" ;
36+ #endif
3437
3538static std::string fromU8 (const std::u8string &str)
3639{
@@ -351,6 +354,11 @@ bool Installer::checkGameInstall(const std::filesystem::path &baseDirectory, std
351354 if (!std::filesystem::exists (baseDirectory / GameDirectory / GameExecutableFile))
352355 return false ;
353356
357+ #ifdef UNLEASHED_RECOMP_IOS
358+ if (!std::filesystem::exists (baseDirectory / InstallValidationFile))
359+ return false ;
360+ #endif
361+
354362 return true ;
355363}
356364
@@ -597,6 +605,21 @@ bool Installer::install(Sources &sources, const std::filesystem::path &targetDir
597605 // Install files in reverse order of importance. In case of a process crash or power outage, this will increase the likelihood of the installation
598606 // missing critical files required for the game to run. These files are used as the way to detect if the game is installed.
599607
608+ #ifdef UNLEASHED_RECOMP_IOS
609+ const bool isInstallingGameData = sources.game != nullptr || sources.update != nullptr ;
610+ if (isInstallingGameData)
611+ {
612+ std::error_code ec;
613+ std::filesystem::remove (targetDirectory / InstallValidationFile, ec);
614+ if (ec)
615+ {
616+ journal.lastResult = Journal::Result::FileWriteFailed;
617+ journal.lastErrorMessage = fmt::format (" Failed to remove validation file at {}." , fromPath (targetDirectory / InstallValidationFile));
618+ return false ;
619+ }
620+ }
621+ #endif
622+
600623 // Install the DLC.
601624 if (!sources.dlc .empty ())
602625 {
@@ -668,6 +691,37 @@ bool Installer::install(Sources &sources, const std::filesystem::path &targetDir
668691
669692 // Update the progress with the artificial amount attributed to the patching.
670693 journal.progressCounter += PatcherContribution;
694+
695+ #ifdef UNLEASHED_RECOMP_IOS
696+ Journal validationJournal;
697+ if (!checkInstallIntegrity (targetDirectory, validationJournal, progressCallback))
698+ {
699+ journal.lastResult = validationJournal.lastResult ;
700+ journal.lastPatcherResult = validationJournal.lastPatcherResult ;
701+ journal.lastErrorMessage = validationJournal.lastErrorMessage ;
702+ return false ;
703+ }
704+
705+ std::filesystem::path validationPath = targetDirectory / InstallValidationFile;
706+ std::ofstream validationStream (validationPath, std::ios::binary);
707+ if (!validationStream.is_open ())
708+ {
709+ journal.lastResult = Journal::Result::FileCreationFailed;
710+ journal.lastErrorMessage = fmt::format (" Failed to create file at {}." , fromPath (validationPath));
711+ return false ;
712+ }
713+
714+ validationStream << " ok\n " ;
715+ validationStream.flush ();
716+ if (!validationStream.good ())
717+ {
718+ journal.lastResult = Journal::Result::FileWriteFailed;
719+ journal.lastErrorMessage = fmt::format (" Failed to write file at {}." , fromPath (validationPath));
720+ return false ;
721+ }
722+
723+ journal.createdFiles .push_back (validationPath);
724+ #endif
671725
672726 for (uint32_t i = 0 ; i < 2 ; i++)
673727 {
0 commit comments