summaryrefslogtreecommitdiffstats
path: root/src/core/file_sys
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/file_sys')
-rw-r--r--src/core/file_sys/nca_metadata.h6
-rw-r--r--src/core/file_sys/patch_manager.cpp10
-rw-r--r--src/core/file_sys/patch_manager.h9
-rw-r--r--src/core/file_sys/registered_cache.cpp23
-rw-r--r--src/core/file_sys/registered_cache.h3
-rw-r--r--src/core/file_sys/submission_package.cpp11
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;
}