diff options
Diffstat (limited to 'src/core/file_sys')
-rw-r--r-- | src/core/file_sys/nca_metadata.h | 6 | ||||
-rw-r--r-- | src/core/file_sys/patch_manager.cpp | 10 | ||||
-rw-r--r-- | src/core/file_sys/patch_manager.h | 9 | ||||
-rw-r--r-- | src/core/file_sys/registered_cache.cpp | 23 | ||||
-rw-r--r-- | src/core/file_sys/registered_cache.h | 3 | ||||
-rw-r--r-- | src/core/file_sys/submission_package.cpp | 11 |
6 files changed, 50 insertions, 12 deletions
diff --git a/src/core/file_sys/nca_metadata.h b/src/core/file_sys/nca_metadata.h index 84d5cd1e0..1f82fff0a 100644 --- a/src/core/file_sys/nca_metadata.h +++ b/src/core/file_sys/nca_metadata.h @@ -35,9 +35,9 @@ enum class ContentRecordType : u8 { Program = 1, Data = 2, Control = 3, - Manual = 4, - Legal = 5, - Patch = 6, + HtmlDocument = 4, + LegalInformation = 5, + DeltaFragment = 6, }; struct ContentRecord { diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index da823c37b..a8f80e2c6 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -493,6 +493,16 @@ std::map<std::string, std::string, std::less<>> PatchManager::GetPatchVersionNam return out; } +std::optional<u32> PatchManager::GetGameVersion() const { + const auto& installed = Core::System::GetInstance().GetContentProvider(); + const auto update_tid = GetUpdateTitleID(title_id); + if (installed.HasEntry(update_tid, ContentRecordType::Program)) { + return installed.GetEntryVersion(update_tid); + } + + return installed.GetEntryVersion(title_id); +} + std::pair<std::unique_ptr<NACP>, VirtualFile> PatchManager::GetControlMetadata() const { const auto& installed = Core::System::GetInstance().GetContentProvider(); diff --git a/src/core/file_sys/patch_manager.h b/src/core/file_sys/patch_manager.h index 769f8c6f0..a363c6577 100644 --- a/src/core/file_sys/patch_manager.h +++ b/src/core/file_sys/patch_manager.h @@ -66,8 +66,13 @@ public: std::map<std::string, std::string, std::less<>> GetPatchVersionNames( VirtualFile update_raw = nullptr) const; - // Given title_id of the program, attempts to get the control data of the update and parse it, - // falling back to the base control data. + // If the game update exists, returns the u32 version field in its Meta-type NCA. If that fails, + // it will fallback to the Meta-type NCA of the base game. If that fails, the result will be + // std::nullopt + std::optional<u32> GetGameVersion() const; + + // Given title_id of the program, attempts to get the control data of the update and parse + // it, falling back to the base control data. std::pair<std::unique_ptr<NACP>, VirtualFile> GetControlMetadata() const; // Version of GetControlMetadata that takes an arbitrary NCA diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp index 58917e094..3725b10f7 100644 --- a/src/core/file_sys/registered_cache.cpp +++ b/src/core/file_sys/registered_cache.cpp @@ -99,7 +99,7 @@ ContentRecordType GetCRTypeFromNCAType(NCAContentType type) { return ContentRecordType::Data; case NCAContentType::Manual: // TODO(DarkLordZach): Peek at NCA contents to differentiate Manual and Legal. - return ContentRecordType::Manual; + return ContentRecordType::HtmlDocument; default: UNREACHABLE_MSG("Invalid NCAContentType={:02X}", static_cast<u8>(type)); } @@ -397,8 +397,8 @@ InstallResult RegisteredCache::InstallEntry(const NSP& nsp, bool overwrite_if_ex }); if (meta_iter == ncas.end()) { - LOG_ERROR(Loader, "The XCI you are attempting to install does not have a metadata NCA and " - "is therefore malformed. Double check your encryption keys."); + LOG_ERROR(Loader, "The file you are attempting to install does not have a metadata NCA and " + "is therefore malformed. Check your encryption keys."); return InstallResult::ErrorMetaFailed; } @@ -415,6 +415,9 @@ InstallResult RegisteredCache::InstallEntry(const NSP& nsp, bool overwrite_if_ex const auto cnmt_file = section0->GetFiles()[0]; const CNMT cnmt(cnmt_file); for (const auto& record : cnmt.GetContentRecords()) { + // Ignore DeltaFragments, they are not useful to us + if (record.type == ContentRecordType::DeltaFragment) + continue; const auto nca = GetNCAFromNSPForID(nsp, record.nca_id); if (nca == nullptr) return InstallResult::ErrorCopyFailed; @@ -645,6 +648,20 @@ ContentProviderUnion::ListEntriesFilterOrigin(std::optional<ContentProviderUnion return out; } +std::optional<ContentProviderUnionSlot> ContentProviderUnion::GetSlotForEntry( + u64 title_id, ContentRecordType type) const { + const auto iter = + std::find_if(providers.begin(), providers.end(), [title_id, type](const auto& provider) { + return provider.second != nullptr && provider.second->HasEntry(title_id, type); + }); + + if (iter == providers.end()) { + return std::nullopt; + } + + return iter->first; +} + ManualContentProvider::~ManualContentProvider() = default; void ManualContentProvider::AddEntry(TitleType title_type, ContentRecordType content_type, diff --git a/src/core/file_sys/registered_cache.h b/src/core/file_sys/registered_cache.h index ec9052653..4398d63e1 100644 --- a/src/core/file_sys/registered_cache.h +++ b/src/core/file_sys/registered_cache.h @@ -199,6 +199,9 @@ public: std::optional<TitleType> title_type = {}, std::optional<ContentRecordType> record_type = {}, std::optional<u64> title_id = {}) const; + std::optional<ContentProviderUnionSlot> GetSlotForEntry(u64 title_id, + ContentRecordType type) const; + private: std::map<ContentProviderUnionSlot, ContentProvider*> providers; }; diff --git a/src/core/file_sys/submission_package.cpp b/src/core/file_sys/submission_package.cpp index d0428a457..8b3b14e25 100644 --- a/src/core/file_sys/submission_package.cpp +++ b/src/core/file_sys/submission_package.cpp @@ -248,10 +248,13 @@ void NSP::ReadNCAs(const std::vector<VirtualFile>& files) { auto next_file = pfs->GetFile(fmt::format("{}.nca", id_string)); if (next_file == nullptr) { - LOG_WARNING(Service_FS, - "NCA with ID {}.nca is listed in content metadata, but cannot " - "be found in PFS. NSP appears to be corrupted.", - id_string); + if (rec.type != ContentRecordType::DeltaFragment) { + LOG_WARNING(Service_FS, + "NCA with ID {}.nca is listed in content metadata, but cannot " + "be found in PFS. NSP appears to be corrupted.", + id_string); + } + continue; } |