From 136c563f76f68f83fc30984097b459f80becdef4 Mon Sep 17 00:00:00 2001 From: lat9nq Date: Wed, 27 May 2020 23:12:56 -0400 Subject: [PATCH 1/3] *nix systems can read any-case patch directories Changes many patch_manager functions to use a case-less variant of GetSubdirectory. Fixes patches not showing up on *nix systems when patch directories are named with odd cases, i.e. `exeFS'. --- src/core/file_sys/patch_manager.cpp | 35 ++++++++++++++++++++++------- src/core/file_sys/patch_manager.h | 5 +++++ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index b93aa69354..3d1965abb4 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "common/file_util.h" #include "common/hex_util.h" @@ -48,6 +49,24 @@ std::string FormatTitleVersion(u32 version, TitleVersionFormat format) { return fmt::format("v{}.{}.{}", bytes[3], bytes[2], bytes[1]); } +std::shared_ptr FindSubdirectoryCaseless(const std::shared_ptr dir, + const std::string& name) { +#ifdef _WIN32 + return dir->GetSubdirectory(name); +#else + const auto subdirs = dir->GetSubdirectories(); + for (const auto& subdir : subdirs) { + std::string dir_name = subdir->GetName(); + boost::algorithm::to_lower(dir_name); + if (dir_name == name) { + return subdir; + } + } + + return nullptr; +#endif +} + PatchManager::PatchManager(u64 title_id) : title_id(title_id) {} PatchManager::~PatchManager() = default; @@ -104,7 +123,7 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const { if (std::find(disabled.begin(), disabled.end(), subdir->GetName()) != disabled.end()) continue; - auto exefs_dir = subdir->GetSubdirectory("exefs"); + auto exefs_dir = FindSubdirectoryCaseless(subdir, "exefs"); if (exefs_dir != nullptr) layers.push_back(std::move(exefs_dir)); } @@ -130,7 +149,7 @@ std::vector PatchManager::CollectPatches(const std::vectorGetName()) != disabled.cend()) continue; - auto exefs_dir = subdir->GetSubdirectory("exefs"); + auto exefs_dir = FindSubdirectoryCaseless(subdir, "exefs"); if (exefs_dir != nullptr) { for (const auto& file : exefs_dir->GetFiles()) { if (file->GetExtension() == "ips") { @@ -295,7 +314,7 @@ std::vector PatchManager::CreateCheatList( continue; } - auto cheats_dir = subdir->GetSubdirectory("cheats"); + auto cheats_dir = FindSubdirectoryCaseless(subdir, "cheats"); if (cheats_dir != nullptr) { auto res = ReadCheatFileFromFolder(system, title_id, build_id_, cheats_dir, true); if (res.has_value()) { @@ -340,11 +359,11 @@ static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType t continue; } - auto romfs_dir = subdir->GetSubdirectory("romfs"); + auto romfs_dir = FindSubdirectoryCaseless(subdir, "romfs"); if (romfs_dir != nullptr) 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) layers_ext.push_back(std::move(ext_dir)); } @@ -470,7 +489,7 @@ std::map> PatchManager::GetPatchVersionNam for (const auto& mod : mod_dir->GetSubdirectories()) { std::string types; - const auto exefs_dir = mod->GetSubdirectory("exefs"); + const auto exefs_dir = FindSubdirectoryCaseless(mod, "exefs"); if (IsDirValidAndNonEmpty(exefs_dir)) { bool ips = false; bool ipswitch = false; @@ -494,9 +513,9 @@ std::map> PatchManager::GetPatchVersionNam if (layeredfs) AppendCommaIfNotEmpty(types, "LayeredExeFS"); } - if (IsDirValidAndNonEmpty(mod->GetSubdirectory("romfs"))) + if (IsDirValidAndNonEmpty(FindSubdirectoryCaseless(mod, "romfs"))) AppendCommaIfNotEmpty(types, "LayeredFS"); - if (IsDirValidAndNonEmpty(mod->GetSubdirectory("cheats"))) + if (IsDirValidAndNonEmpty(FindSubdirectoryCaseless(mod, "cheats"))) AppendCommaIfNotEmpty(types, "Cheats"); if (types.empty()) diff --git a/src/core/file_sys/patch_manager.h b/src/core/file_sys/patch_manager.h index ec6db524d8..a1fb6694df 100644 --- a/src/core/file_sys/patch_manager.h +++ b/src/core/file_sys/patch_manager.h @@ -29,6 +29,11 @@ enum class TitleVersionFormat : u8 { std::string FormatTitleVersion(u32 version, TitleVersionFormat format = TitleVersionFormat::ThreeElements); +// Returns a directory with name matching name case-insensitive. Returns nullptr if directory +// doesn't have a directory with name. +std::shared_ptr FindSubdirectoryCaseless(const std::shared_ptr dir, + const std::string& name); + // A centralized class to manage patches to games. class PatchManager { public: From 326403518de42860778e9ac102ae04eb85ee1e85 Mon Sep 17 00:00:00 2001 From: lat9nq Date: Thu, 28 May 2020 13:30:22 -0400 Subject: [PATCH 2/3] Address requested changes --- src/core/file_sys/patch_manager.cpp | 6 +++--- src/core/file_sys/patch_manager.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index 3d1965abb4..1002b688c3 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -6,11 +6,11 @@ #include #include #include -#include #include "common/file_util.h" #include "common/hex_util.h" #include "common/logging/log.h" +#include "common/string_util.h" #include "core/core.h" #include "core/file_sys/content_archive.h" #include "core/file_sys/control_metadata.h" @@ -50,14 +50,14 @@ std::string FormatTitleVersion(u32 version, TitleVersionFormat format) { } std::shared_ptr FindSubdirectoryCaseless(const std::shared_ptr dir, - const std::string& name) { + 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 = subdir->GetName(); - boost::algorithm::to_lower(dir_name); + dir_name = Common::ToLower(dir_name); if (dir_name == name) { return subdir; } diff --git a/src/core/file_sys/patch_manager.h b/src/core/file_sys/patch_manager.h index a1fb6694df..f4cb918ddd 100644 --- a/src/core/file_sys/patch_manager.h +++ b/src/core/file_sys/patch_manager.h @@ -32,7 +32,7 @@ std::string FormatTitleVersion(u32 version, // Returns a directory with name matching name case-insensitive. Returns nullptr if directory // doesn't have a directory with name. std::shared_ptr FindSubdirectoryCaseless(const std::shared_ptr dir, - const std::string& name); + std::string_view name); // A centralized class to manage patches to games. class PatchManager { From f57cbd9f247ac43dbc9e599cc8523c9b8d93ad48 Mon Sep 17 00:00:00 2001 From: lat9nq Date: Thu, 28 May 2020 13:33:50 -0400 Subject: [PATCH 3/3] Make copying directory string more concise --- src/core/file_sys/patch_manager.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index 1002b688c3..c47ff863ec 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -56,8 +56,7 @@ std::shared_ptr FindSubdirectoryCaseless(const std::shared_ptrGetSubdirectories(); for (const auto& subdir : subdirs) { - std::string dir_name = subdir->GetName(); - dir_name = Common::ToLower(dir_name); + std::string dir_name = Common::ToLower(subdir->GetName()); if (dir_name == name) { return subdir; }