patch_manager: Add support for packed updates
Will prefer any installed update over the packed version.
This commit is contained in:
		| @@ -184,8 +184,8 @@ static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType t | |||||||
|     romfs = std::move(packed); |     romfs = std::move(packed); | ||||||
| } | } | ||||||
|  |  | ||||||
| VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, | VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, ContentRecordType type, | ||||||
|                                      ContentRecordType type) const { |                                      VirtualFile update_raw) const { | ||||||
|     LOG_INFO(Loader, "Patching RomFS for title_id={:016X}, type={:02X}", title_id, |     LOG_INFO(Loader, "Patching RomFS for title_id={:016X}, type={:02X}", title_id, | ||||||
|              static_cast<u8>(type)); |              static_cast<u8>(type)); | ||||||
|  |  | ||||||
| @@ -205,6 +205,13 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, | |||||||
|                      FormatTitleVersion(installed->GetEntryVersion(update_tid).get_value_or(0))); |                      FormatTitleVersion(installed->GetEntryVersion(update_tid).get_value_or(0))); | ||||||
|             romfs = new_nca->GetRomFS(); |             romfs = new_nca->GetRomFS(); | ||||||
|         } |         } | ||||||
|  |     } else if (update_raw != nullptr) { | ||||||
|  |         const auto new_nca = std::make_shared<NCA>(update, romfs, ivfc_offset); | ||||||
|  |         if (new_nca->GetStatus() == Loader::ResultStatus::Success && | ||||||
|  |             new_nca->GetRomFS() != nullptr) { | ||||||
|  |             LOG_INFO(Loader, "    RomFS: Update (XCI) applied successfully"); | ||||||
|  |             romfs = new_nca->GetRomFS(); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // LayeredFS |     // LayeredFS | ||||||
| @@ -224,7 +231,7 @@ static bool IsDirValidAndNonEmpty(const VirtualDir& dir) { | |||||||
|     return dir != nullptr && (!dir->GetFiles().empty() || !dir->GetSubdirectories().empty()); |     return dir != nullptr && (!dir->GetFiles().empty() || !dir->GetSubdirectories().empty()); | ||||||
| } | } | ||||||
|  |  | ||||||
| std::map<std::string, std::string, std::less<>> PatchManager::GetPatchVersionNames() const { | std::map<PatchType, std::string> PatchManager::GetPatchVersionNames(VirtualFile update_raw) const { | ||||||
|     std::map<std::string, std::string, std::less<>> out; |     std::map<std::string, std::string, std::less<>> out; | ||||||
|     const auto installed = Service::FileSystem::GetUnionContents(); |     const auto installed = Service::FileSystem::GetUnionContents(); | ||||||
|  |  | ||||||
| @@ -245,6 +252,8 @@ std::map<std::string, std::string, std::less<>> PatchManager::GetPatchVersionNam | |||||||
|                     "Update", |                     "Update", | ||||||
|                     FormatTitleVersion(meta_ver.get(), TitleVersionFormat::ThreeElements)); |                     FormatTitleVersion(meta_ver.get(), TitleVersionFormat::ThreeElements)); | ||||||
|             } |             } | ||||||
|  |         } else if (update_raw != nullptr) { | ||||||
|  |             out[PatchType::Update] = "XCI"; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -46,7 +46,8 @@ public: | |||||||
|     // - Game Updates |     // - Game Updates | ||||||
|     // - LayeredFS |     // - LayeredFS | ||||||
|     VirtualFile PatchRomFS(VirtualFile base, u64 ivfc_offset, |     VirtualFile PatchRomFS(VirtualFile base, u64 ivfc_offset, | ||||||
|                            ContentRecordType type = ContentRecordType::Program) const; |                            ContentRecordType type = ContentRecordType::Program, | ||||||
|  |                            VirtualFile update_raw = nullptr) const; | ||||||
|  |  | ||||||
|     // Returns a vector of pairs between patch names and patch versions. |     // Returns a vector of pairs between patch names and patch versions. | ||||||
|     // i.e. Update 3.2.2 will return {"Update", "3.2.2"} |     // i.e. Update 3.2.2 will return {"Update", "3.2.2"} | ||||||
|   | |||||||
| @@ -24,6 +24,7 @@ RomFSFactory::RomFSFactory(Loader::AppLoader& app_loader) { | |||||||
|         LOG_ERROR(Service_FS, "Unable to read RomFS!"); |         LOG_ERROR(Service_FS, "Unable to read RomFS!"); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     app_loader.ReadUpdateRaw(update_raw); | ||||||
|     updatable = app_loader.IsRomFSUpdatable(); |     updatable = app_loader.IsRomFSUpdatable(); | ||||||
|     ivfc_offset = app_loader.ReadRomFSIVFCOffset(); |     ivfc_offset = app_loader.ReadRomFSIVFCOffset(); | ||||||
| } | } | ||||||
| @@ -35,7 +36,8 @@ ResultVal<VirtualFile> RomFSFactory::OpenCurrentProcess() { | |||||||
|         return MakeResult<VirtualFile>(file); |         return MakeResult<VirtualFile>(file); | ||||||
|  |  | ||||||
|     const PatchManager patch_manager(Core::CurrentProcess()->GetTitleID()); |     const PatchManager patch_manager(Core::CurrentProcess()->GetTitleID()); | ||||||
|     return MakeResult<VirtualFile>(patch_manager.PatchRomFS(file, ivfc_offset)); |     return MakeResult<VirtualFile>( | ||||||
|  |         patch_manager.PatchRomFS(file, ivfc_offset, ContentRecordType::Program, update_raw)); | ||||||
| } | } | ||||||
|  |  | ||||||
| ResultVal<VirtualFile> RomFSFactory::Open(u64 title_id, StorageId storage, ContentRecordType type) { | ResultVal<VirtualFile> RomFSFactory::Open(u64 title_id, StorageId storage, ContentRecordType type) { | ||||||
|   | |||||||
| @@ -37,6 +37,7 @@ public: | |||||||
|  |  | ||||||
| private: | private: | ||||||
|     VirtualFile file; |     VirtualFile file; | ||||||
|  |     VirtualFile update_raw; | ||||||
|     bool updatable; |     bool updatable; | ||||||
|     u64 ivfc_offset; |     u64 ivfc_offset; | ||||||
| }; | }; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user