ソースを参照

Merge pull request #4002 from lat9nq/fix-nix-mod-directories

patch_manager: Add support for case-sensitivity on Linux
bunnei 6 年 前
コミット
5242b21524
2 ファイル変更31 行追加8 行削除
  1. 26 8
      src/core/file_sys/patch_manager.cpp
  2. 5 0
      src/core/file_sys/patch_manager.h

+ 26 - 8
src/core/file_sys/patch_manager.cpp

@@ -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())

+ 5 - 0
src/core/file_sys/patch_manager.h

@@ -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,
+                                                       std::string_view name);
+
 // A centralized class to manage patches to games.
 // A centralized class to manage patches to games.
 class PatchManager {
 class PatchManager {
 public:
 public: