1
0
Fork 0
forked from suyu/suyu

*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'.
This commit is contained in:
lat9nq 2020-05-27 23:12:56 -04:00
parent ae61e47cba
commit 136c563f76
2 changed files with 32 additions and 8 deletions

View file

@ -6,6 +6,7 @@
#include <array> #include <array>
#include <cstddef> #include <cstddef>
#include <cstring> #include <cstring>
#include <boost/algorithm/string/case_conv.hpp>
#include "common/file_util.h" #include "common/file_util.h"
#include "common/hex_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]); return fmt::format("v{}.{}.{}", bytes[3], bytes[2], bytes[1]);
} }
std::shared_ptr<VfsDirectory> FindSubdirectoryCaseless(const std::shared_ptr<VfsDirectory> 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(u64 title_id) : title_id(title_id) {}
PatchManager::~PatchManager() = default; PatchManager::~PatchManager() = default;
@ -104,7 +123,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 +149,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 +314,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 +359,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 +489,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 +513,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())

View file

@ -29,6 +29,11 @@ enum class TitleVersionFormat : u8 {
std::string FormatTitleVersion(u32 version, std::string FormatTitleVersion(u32 version,
TitleVersionFormat format = TitleVersionFormat::ThreeElements); 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<VfsDirectory> FindSubdirectoryCaseless(const std::shared_ptr<VfsDirectory> dir,
const std::string& name);
// A centralized class to manage patches to games. // A centralized class to manage patches to games.
class PatchManager { class PatchManager {
public: public: