system: per-content-type root overrides in ContentManager
This commit is contained in:
parent
9181630ece
commit
8130e534bc
2 changed files with 30 additions and 1 deletions
|
|
@ -183,6 +183,14 @@ class ContentManager {
|
||||||
// and writes a .header file for XAM enumeration.
|
// and writes a .header file for XAM enumeration.
|
||||||
X_RESULT InstallContent(const std::filesystem::path& package_path);
|
X_RESULT InstallContent(const std::filesystem::path& package_path);
|
||||||
|
|
||||||
|
// Redirects all content of `content_type` to `root` with a flattened
|
||||||
|
// single-title layout instead of the shared content tree:
|
||||||
|
// root/{xuid}/{package}/ data
|
||||||
|
// root/{xuid}/Headers/{package}.header enumeration header
|
||||||
|
// The xuid level is kept so per-profile content stays isolated. Set before
|
||||||
|
// the title enumerates or opens content of this type; no data is migrated.
|
||||||
|
void SetContentTypeRoot(XContentType content_type, std::filesystem::path root);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::filesystem::path ResolvePackageRoot(uint64_t xuid, XContentType content_type,
|
std::filesystem::path ResolvePackageRoot(uint64_t xuid, XContentType content_type,
|
||||||
uint32_t title_id = -1);
|
uint32_t title_id = -1);
|
||||||
|
|
@ -199,6 +207,9 @@ class ContentManager {
|
||||||
|
|
||||||
KernelState* kernel_state_;
|
KernelState* kernel_state_;
|
||||||
std::filesystem::path root_path_;
|
std::filesystem::path root_path_;
|
||||||
|
// Per-content-type root overrides (SetContentTypeRoot), keyed by the raw
|
||||||
|
// XContentType value.
|
||||||
|
std::unordered_map<uint32_t, std::filesystem::path> content_type_roots_;
|
||||||
|
|
||||||
// TODO(benvanik): remove use of global lock, it's bad here!
|
// TODO(benvanik): remove use of global lock, it's bad here!
|
||||||
rex::thread::global_critical_region global_critical_region_;
|
rex::thread::global_critical_region global_critical_region_;
|
||||||
|
|
|
||||||
|
|
@ -85,12 +85,23 @@ ContentManager::ContentManager(KernelState* kernel_state, const std::filesystem:
|
||||||
|
|
||||||
ContentManager::~ContentManager() = default;
|
ContentManager::~ContentManager() = default;
|
||||||
|
|
||||||
|
void ContentManager::SetContentTypeRoot(XContentType content_type, std::filesystem::path root) {
|
||||||
|
content_type_roots_[uint32_t(content_type)] = std::move(root);
|
||||||
|
}
|
||||||
|
|
||||||
std::filesystem::path ContentManager::ResolvePackageRoot(uint64_t xuid, XContentType content_type,
|
std::filesystem::path ContentManager::ResolvePackageRoot(uint64_t xuid, XContentType content_type,
|
||||||
uint32_t title_id) {
|
uint32_t title_id) {
|
||||||
if (title_id == kCurrentlyRunningTitleId) {
|
if (title_id == kCurrentlyRunningTitleId) {
|
||||||
title_id = kernel_state_->title_id();
|
title_id = kernel_state_->title_id();
|
||||||
}
|
}
|
||||||
auto xuid_str = fmt::format("{:016X}", xuid);
|
auto xuid_str = fmt::format("{:016X}", xuid);
|
||||||
|
|
||||||
|
// Overridden types use a flattened single-title layout: root/xuid/
|
||||||
|
auto override_it = content_type_roots_.find(uint32_t(content_type));
|
||||||
|
if (override_it != content_type_roots_.end()) {
|
||||||
|
return override_it->second / xuid_str;
|
||||||
|
}
|
||||||
|
|
||||||
auto title_id_str = fmt::format("{:08X}", title_id);
|
auto title_id_str = fmt::format("{:08X}", title_id);
|
||||||
auto content_type_str = fmt::format("{:08X}", uint32_t(content_type));
|
auto content_type_str = fmt::format("{:08X}", uint32_t(content_type));
|
||||||
|
|
||||||
|
|
@ -126,9 +137,16 @@ std::filesystem::path ContentManager::ResolvePackageHeaderPath(const std::string
|
||||||
}
|
}
|
||||||
|
|
||||||
auto xuid_str = fmt::format("{:016X}", xuid);
|
auto xuid_str = fmt::format("{:016X}", xuid);
|
||||||
|
std::string final_name = std::string(file_name) + ".header";
|
||||||
|
|
||||||
|
// Overridden types keep headers beside their data: root/xuid/Headers/
|
||||||
|
auto override_it = content_type_roots_.find(uint32_t(content_type));
|
||||||
|
if (override_it != content_type_roots_.end()) {
|
||||||
|
return override_it->second / xuid_str / kGameContentHeaderDirName / final_name;
|
||||||
|
}
|
||||||
|
|
||||||
auto title_id_str = fmt::format("{:08X}", title_id);
|
auto title_id_str = fmt::format("{:08X}", title_id);
|
||||||
auto content_type_str = fmt::format("{:08X}", uint32_t(content_type));
|
auto content_type_str = fmt::format("{:08X}", uint32_t(content_type));
|
||||||
std::string final_name = std::string(file_name) + ".header";
|
|
||||||
|
|
||||||
// Header root path:
|
// Header root path:
|
||||||
// content_root/xuid/title_id/Headers/content_type/filename.header
|
// content_root/xuid/title_id/Headers/content_type/filename.header
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue