|
|
@ -10,6 +10,7 @@ |
|
|
#include "common/file_util.h"
|
|
|
#include "common/file_util.h"
|
|
|
#include "common/hex_util.h"
|
|
|
#include "common/hex_util.h"
|
|
|
#include "common/logging/log.h"
|
|
|
#include "common/logging/log.h"
|
|
|
|
|
|
#include "common/string_util.h"
|
|
|
#include "core/core.h"
|
|
|
#include "core/core.h"
|
|
|
#include "core/file_sys/content_archive.h"
|
|
|
#include "core/file_sys/content_archive.h"
|
|
|
#include "core/file_sys/control_metadata.h"
|
|
|
#include "core/file_sys/control_metadata.h"
|
|
|
@ -48,6 +49,23 @@ std::string FormatTitleVersion(u32 version, TitleVersionFormat format) { |
|
|
return fmt::format("v{}.{}.{}", bytes[3], bytes[2], bytes[1]); |
|
|
return fmt::format("v{}.{}.{}", bytes[3], bytes[2], bytes[1]); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<VfsDirectory> FindSubdirectoryCaseless(const std::shared_ptr<VfsDirectory> dir, |
|
|
|
|
|
std::string_view name) { |
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
|
|
return dir->GetSubdirectory(name); |
|
|
|
|
|
#else
|
|
|
|
|
|
const auto subdirs = dir->GetSubdirectories(); |
|
|
|
|
|
for (const auto& subdir : subdirs) { |
|
|
|
|
|
std::string dir_name = Common::ToLower(subdir->GetName()); |
|
|
|
|
|
if (dir_name == name) { |
|
|
|
|
|
return subdir; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return nullptr; |
|
|
|
|
|
#endif
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
PatchManager::PatchManager(u64 title_id) : title_id(title_id) {} |
|
|
PatchManager::PatchManager(u64 title_id) : title_id(title_id) {} |
|
|
|
|
|
|
|
|
PatchManager::~PatchManager() = default; |
|
|
PatchManager::~PatchManager() = default; |
|
|
@ -104,7 +122,7 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const { |
|
|
if (std::find(disabled.begin(), disabled.end(), subdir->GetName()) != disabled.end()) |
|
|
if (std::find(disabled.begin(), disabled.end(), subdir->GetName()) != disabled.end()) |
|
|
continue; |
|
|
continue; |
|
|
|
|
|
|
|
|
auto exefs_dir = subdir->GetSubdirectory("exefs"); |
|
|
|
|
|
|
|
|
auto exefs_dir = FindSubdirectoryCaseless(subdir, "exefs"); |
|
|
if (exefs_dir != nullptr) |
|
|
if (exefs_dir != nullptr) |
|
|
layers.push_back(std::move(exefs_dir)); |
|
|
layers.push_back(std::move(exefs_dir)); |
|
|
} |
|
|
} |
|
|
@ -130,7 +148,7 @@ std::vector<VirtualFile> PatchManager::CollectPatches(const std::vector<VirtualD |
|
|
if (std::find(disabled.cbegin(), disabled.cend(), subdir->GetName()) != disabled.cend()) |
|
|
if (std::find(disabled.cbegin(), disabled.cend(), subdir->GetName()) != disabled.cend()) |
|
|
continue; |
|
|
continue; |
|
|
|
|
|
|
|
|
auto exefs_dir = subdir->GetSubdirectory("exefs"); |
|
|
|
|
|
|
|
|
auto exefs_dir = FindSubdirectoryCaseless(subdir, "exefs"); |
|
|
if (exefs_dir != nullptr) { |
|
|
if (exefs_dir != nullptr) { |
|
|
for (const auto& file : exefs_dir->GetFiles()) { |
|
|
for (const auto& file : exefs_dir->GetFiles()) { |
|
|
if (file->GetExtension() == "ips") { |
|
|
if (file->GetExtension() == "ips") { |
|
|
@ -295,7 +313,7 @@ std::vector<Core::Memory::CheatEntry> PatchManager::CreateCheatList( |
|
|
continue; |
|
|
continue; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
auto cheats_dir = subdir->GetSubdirectory("cheats"); |
|
|
|
|
|
|
|
|
auto cheats_dir = FindSubdirectoryCaseless(subdir, "cheats"); |
|
|
if (cheats_dir != nullptr) { |
|
|
if (cheats_dir != nullptr) { |
|
|
auto res = ReadCheatFileFromFolder(system, title_id, build_id_, cheats_dir, true); |
|
|
auto res = ReadCheatFileFromFolder(system, title_id, build_id_, cheats_dir, true); |
|
|
if (res.has_value()) { |
|
|
if (res.has_value()) { |
|
|
@ -340,11 +358,11 @@ static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType t |
|
|
continue; |
|
|
continue; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
auto romfs_dir = subdir->GetSubdirectory("romfs"); |
|
|
|
|
|
|
|
|
auto romfs_dir = FindSubdirectoryCaseless(subdir, "romfs"); |
|
|
if (romfs_dir != nullptr) |
|
|
if (romfs_dir != nullptr) |
|
|
layers.push_back(std::move(romfs_dir)); |
|
|
layers.push_back(std::move(romfs_dir)); |
|
|
|
|
|
|
|
|
auto ext_dir = subdir->GetSubdirectory("romfs_ext"); |
|
|
|
|
|
|
|
|
auto ext_dir = FindSubdirectoryCaseless(subdir, "romfs_ext"); |
|
|
if (ext_dir != nullptr) |
|
|
if (ext_dir != nullptr) |
|
|
layers_ext.push_back(std::move(ext_dir)); |
|
|
layers_ext.push_back(std::move(ext_dir)); |
|
|
} |
|
|
} |
|
|
@ -470,7 +488,7 @@ std::map<std::string, std::string, std::less<>> PatchManager::GetPatchVersionNam |
|
|
for (const auto& mod : mod_dir->GetSubdirectories()) { |
|
|
for (const auto& mod : mod_dir->GetSubdirectories()) { |
|
|
std::string types; |
|
|
std::string types; |
|
|
|
|
|
|
|
|
const auto exefs_dir = mod->GetSubdirectory("exefs"); |
|
|
|
|
|
|
|
|
const auto exefs_dir = FindSubdirectoryCaseless(mod, "exefs"); |
|
|
if (IsDirValidAndNonEmpty(exefs_dir)) { |
|
|
if (IsDirValidAndNonEmpty(exefs_dir)) { |
|
|
bool ips = false; |
|
|
bool ips = false; |
|
|
bool ipswitch = false; |
|
|
bool ipswitch = false; |
|
|
@ -494,9 +512,9 @@ std::map<std::string, std::string, std::less<>> PatchManager::GetPatchVersionNam |
|
|
if (layeredfs) |
|
|
if (layeredfs) |
|
|
AppendCommaIfNotEmpty(types, "LayeredExeFS"); |
|
|
AppendCommaIfNotEmpty(types, "LayeredExeFS"); |
|
|
} |
|
|
} |
|
|
if (IsDirValidAndNonEmpty(mod->GetSubdirectory("romfs"))) |
|
|
|
|
|
|
|
|
if (IsDirValidAndNonEmpty(FindSubdirectoryCaseless(mod, "romfs"))) |
|
|
AppendCommaIfNotEmpty(types, "LayeredFS"); |
|
|
AppendCommaIfNotEmpty(types, "LayeredFS"); |
|
|
if (IsDirValidAndNonEmpty(mod->GetSubdirectory("cheats"))) |
|
|
|
|
|
|
|
|
if (IsDirValidAndNonEmpty(FindSubdirectoryCaseless(mod, "cheats"))) |
|
|
AppendCommaIfNotEmpty(types, "Cheats"); |
|
|
AppendCommaIfNotEmpty(types, "Cheats"); |
|
|
|
|
|
|
|
|
if (types.empty()) |
|
|
if (types.empty()) |
|
|
|