game_list: Fix version display on non-NAND titles
This commit is contained in:
		| @@ -82,15 +82,31 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, | |||||||
|     return romfs; |     return romfs; | ||||||
| } | } | ||||||
|  |  | ||||||
| std::map<PatchType, u32> PatchManager::GetPatchVersionNames() const { | std::map<PatchType, std::string> PatchManager::GetPatchVersionNames() const { | ||||||
|     std::map<PatchType, u32> out; |     std::map<PatchType, std::string> out; | ||||||
|     const auto installed = Service::FileSystem::GetUnionContents(); |     const auto installed = Service::FileSystem::GetUnionContents(); | ||||||
|  |  | ||||||
|     const auto update_tid = GetUpdateTitleID(title_id); |     const auto update_tid = GetUpdateTitleID(title_id); | ||||||
|     const auto update_version = installed->GetEntryVersion(update_tid); |     const auto update_control = installed->GetEntry(title_id, ContentRecordType::Control); | ||||||
|     if (update_version != boost::none && |     if (update_control != nullptr) { | ||||||
|         installed->HasEntry(update_tid, ContentRecordType::Program)) { |         do { | ||||||
|         out[PatchType::Update] = update_version.get(); |             const auto romfs = | ||||||
|  |                 PatchRomFS(update_control->GetRomFS(), update_control->GetBaseIVFCOffset(), | ||||||
|  |                            FileSys::ContentRecordType::Control); | ||||||
|  |             if (romfs == nullptr) | ||||||
|  |                 break; | ||||||
|  |  | ||||||
|  |             const auto control_dir = FileSys::ExtractRomFS(romfs); | ||||||
|  |             if (control_dir == nullptr) | ||||||
|  |                 break; | ||||||
|  |  | ||||||
|  |             const auto nacp_file = control_dir->GetFile("control.nacp"); | ||||||
|  |             if (nacp_file == nullptr) | ||||||
|  |                 break; | ||||||
|  |  | ||||||
|  |             FileSys::NACP nacp(nacp_file); | ||||||
|  |             out[PatchType::Update] = nacp.GetVersionString(); | ||||||
|  |         } while (false); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return out; |     return out; | ||||||
|   | |||||||
| @@ -45,7 +45,7 @@ public: | |||||||
|  |  | ||||||
|     // Returns a vector of pairs between patch names and patch versions. |     // Returns a vector of pairs between patch names and patch versions. | ||||||
|     // i.e. Update v80 will return {Update, 80} |     // i.e. Update v80 will return {Update, 80} | ||||||
|     std::map<PatchType, u32> GetPatchVersionNames() const; |     std::map<PatchType, std::string> GetPatchVersionNames() const; | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     u64 title_id; |     u64 title_id; | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ | |||||||
| #include "core/file_sys/card_image.h" | #include "core/file_sys/card_image.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" | ||||||
|  | #include "core/file_sys/patch_manager.h" | ||||||
| #include "core/file_sys/romfs.h" | #include "core/file_sys/romfs.h" | ||||||
| #include "core/hle/kernel/process.h" | #include "core/hle/kernel/process.h" | ||||||
| #include "core/loader/nca.h" | #include "core/loader/nca.h" | ||||||
| @@ -20,10 +21,18 @@ AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file) | |||||||
|       nca_loader(std::make_unique<AppLoader_NCA>(xci->GetProgramNCAFile())) { |       nca_loader(std::make_unique<AppLoader_NCA>(xci->GetProgramNCAFile())) { | ||||||
|     if (xci->GetStatus() != ResultStatus::Success) |     if (xci->GetStatus() != ResultStatus::Success) | ||||||
|         return; |         return; | ||||||
|  |  | ||||||
|     const auto control_nca = xci->GetNCAByType(FileSys::NCAContentType::Control); |     const auto control_nca = xci->GetNCAByType(FileSys::NCAContentType::Control); | ||||||
|  |  | ||||||
|     if (control_nca == nullptr || control_nca->GetStatus() != ResultStatus::Success) |     if (control_nca == nullptr || control_nca->GetStatus() != ResultStatus::Success) | ||||||
|         return; |         return; | ||||||
|     const auto romfs = FileSys::ExtractRomFS(control_nca->GetRomFS()); |  | ||||||
|  |     auto romfs_raw = control_nca->GetRomFS(); | ||||||
|  |     FileSys::PatchManager patch{xci->GetNCAByType(FileSys::NCAContentType::Program)->GetTitleId()}; | ||||||
|  |     romfs_raw = patch.PatchRomFS(romfs_raw, control_nca->GetBaseIVFCOffset(), | ||||||
|  |                                  FileSys::ContentRecordType::Control); | ||||||
|  |  | ||||||
|  |     const auto romfs = FileSys::ExtractRomFS(romfs_raw); | ||||||
|     if (romfs == nullptr) |     if (romfs == nullptr) | ||||||
|         return; |         return; | ||||||
|     for (const auto& language : FileSys::LANGUAGE_NAMES) { |     for (const auto& language : FileSys::LANGUAGE_NAMES) { | ||||||
|   | |||||||
| @@ -457,23 +457,17 @@ static QString FormatGameName(const std::string& physical_name) { | |||||||
| } | } | ||||||
|  |  | ||||||
| static QString FormatPatchNameVersions(const FileSys::PatchManager& patch_manager, | static QString FormatPatchNameVersions(const FileSys::PatchManager& patch_manager, | ||||||
|                                        std::string update_version_override = "", |  | ||||||
|                                        bool updatable = true) { |                                        bool updatable = true) { | ||||||
|     QString out; |     QString out; | ||||||
|     for (const auto& kv : patch_manager.GetPatchVersionNames()) { |     for (const auto& kv : patch_manager.GetPatchVersionNames()) { | ||||||
|         if (!updatable && kv.first == FileSys::PatchType::Update) |         if (!updatable && kv.first == FileSys::PatchType::Update) | ||||||
|             continue; |             continue; | ||||||
|  |  | ||||||
|         if (kv.second == 0) { |         if (kv.second.empty()) { | ||||||
|             out.append(fmt::format("{}\n", FileSys::FormatPatchTypeName(kv.first)).c_str()); |             out.append(fmt::format("{}\n", FileSys::FormatPatchTypeName(kv.first)).c_str()); | ||||||
|         } else { |         } else { | ||||||
|             auto version_data = FileSys::FormatTitleVersion(kv.second); |             out.append(fmt::format("{} ({})\n", FileSys::FormatPatchTypeName(kv.first), kv.second) | ||||||
|             if (kv.first == FileSys::PatchType::Update && !update_version_override.empty()) |                            .c_str()); | ||||||
|                 version_data = update_version_override; |  | ||||||
|  |  | ||||||
|             out.append( |  | ||||||
|                 fmt::format("{} ({})\n", FileSys::FormatPatchTypeName(kv.first), version_data) |  | ||||||
|                     .c_str()); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -491,8 +485,7 @@ void GameList::RefreshGameDirectory() { | |||||||
|  |  | ||||||
| static void GetMetadataFromControlNCA(const FileSys::PatchManager& patch_manager, | static void GetMetadataFromControlNCA(const FileSys::PatchManager& patch_manager, | ||||||
|                                       const std::shared_ptr<FileSys::NCA>& nca, |                                       const std::shared_ptr<FileSys::NCA>& nca, | ||||||
|                                       std::vector<u8>& icon, std::string& name, |                                       std::vector<u8>& icon, std::string& name) { | ||||||
|                                       std::string& version) { |  | ||||||
|     const auto romfs = patch_manager.PatchRomFS(nca->GetRomFS(), nca->GetBaseIVFCOffset(), |     const auto romfs = patch_manager.PatchRomFS(nca->GetRomFS(), nca->GetBaseIVFCOffset(), | ||||||
|                                                 FileSys::ContentRecordType::Control); |                                                 FileSys::ContentRecordType::Control); | ||||||
|     if (romfs == nullptr) |     if (romfs == nullptr) | ||||||
| @@ -507,7 +500,6 @@ static void GetMetadataFromControlNCA(const FileSys::PatchManager& patch_manager | |||||||
|         return; |         return; | ||||||
|     FileSys::NACP nacp(nacp_file); |     FileSys::NACP nacp(nacp_file); | ||||||
|     name = nacp.GetApplicationName(); |     name = nacp.GetApplicationName(); | ||||||
|     version = nacp.GetVersionString(); |  | ||||||
|  |  | ||||||
|     FileSys::VirtualFile icon_file = nullptr; |     FileSys::VirtualFile icon_file = nullptr; | ||||||
|     for (const auto& language : FileSys::LANGUAGE_NAMES) { |     for (const auto& language : FileSys::LANGUAGE_NAMES) { | ||||||
| @@ -527,7 +519,8 @@ GameListWorker::GameListWorker( | |||||||
|  |  | ||||||
| GameListWorker::~GameListWorker() = default; | GameListWorker::~GameListWorker() = default; | ||||||
|  |  | ||||||
| void GameListWorker::AddInstalledTitlesToGameList(std::shared_ptr<FileSys::RegisteredCache> cache) { | void GameListWorker::AddInstalledTitlesToGameList() { | ||||||
|  |     const auto cache = Service::FileSystem::GetUnionContents(); | ||||||
|     const auto installed_games = cache->ListEntriesFilter(FileSys::TitleType::Application, |     const auto installed_games = cache->ListEntriesFilter(FileSys::TitleType::Application, | ||||||
|                                                           FileSys::ContentRecordType::Program); |                                                           FileSys::ContentRecordType::Program); | ||||||
|  |  | ||||||
| @@ -539,20 +532,28 @@ void GameListWorker::AddInstalledTitlesToGameList(std::shared_ptr<FileSys::Regis | |||||||
|  |  | ||||||
|         std::vector<u8> icon; |         std::vector<u8> icon; | ||||||
|         std::string name; |         std::string name; | ||||||
|         std::string version = ""; |  | ||||||
|         u64 program_id = 0; |         u64 program_id = 0; | ||||||
|         loader->ReadProgramId(program_id); |         loader->ReadProgramId(program_id); | ||||||
|  |  | ||||||
|         const FileSys::PatchManager patch{program_id}; |         const FileSys::PatchManager patch{program_id}; | ||||||
|         const auto& control = cache->GetEntry(game.title_id, FileSys::ContentRecordType::Control); |         const auto& control = cache->GetEntry(game.title_id, FileSys::ContentRecordType::Control); | ||||||
|         if (control != nullptr) |         if (control != nullptr) | ||||||
|             GetMetadataFromControlNCA(patch, control, icon, name, version); |             GetMetadataFromControlNCA(patch, control, icon, name); | ||||||
|  |  | ||||||
|  |         auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id); | ||||||
|  |  | ||||||
|  |         // The game list uses this as compatibility number for untested games | ||||||
|  |         QString compatibility("99"); | ||||||
|  |         if (it != compatibility_list.end()) | ||||||
|  |             compatibility = it->second.first; | ||||||
|  |  | ||||||
|         emit EntryReady({ |         emit EntryReady({ | ||||||
|             new GameListItemPath( |             new GameListItemPath( | ||||||
|                 FormatGameName(file->GetFullPath()), icon, QString::fromStdString(name), |                 FormatGameName(file->GetFullPath()), icon, QString::fromStdString(name), | ||||||
|                 QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType())), |                 QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType())), | ||||||
|                 program_id), |                 program_id), | ||||||
|             new GameListItem(FormatPatchNameVersions(patch, version)), |             new GameListItemCompat(compatibility), | ||||||
|  |             new GameListItem(FormatPatchNameVersions(patch)), | ||||||
|             new GameListItem( |             new GameListItem( | ||||||
|                 QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))), |                 QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))), | ||||||
|             new GameListItemSize(file->GetSize()), |             new GameListItemSize(file->GetSize()), | ||||||
| @@ -620,14 +621,12 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign | |||||||
|  |  | ||||||
|             const FileSys::PatchManager patch{program_id}; |             const FileSys::PatchManager patch{program_id}; | ||||||
|  |  | ||||||
|             std::string version = ""; |  | ||||||
|  |  | ||||||
|             if (res1 != Loader::ResultStatus::Success && res3 != Loader::ResultStatus::Success && |             if (res1 != Loader::ResultStatus::Success && res3 != Loader::ResultStatus::Success && | ||||||
|                 res2 == Loader::ResultStatus::Success) { |                 res2 == Loader::ResultStatus::Success) { | ||||||
|                 // Use from metadata pool. |                 // Use from metadata pool. | ||||||
|                 if (nca_control_map.find(program_id) != nca_control_map.end()) { |                 if (nca_control_map.find(program_id) != nca_control_map.end()) { | ||||||
|                     const auto nca = nca_control_map[program_id]; |                     const auto nca = nca_control_map[program_id]; | ||||||
|                     GetMetadataFromControlNCA(patch, nca, icon, name, version); |                     GetMetadataFromControlNCA(patch, nca, icon, name); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |  | ||||||
| @@ -644,9 +643,7 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign | |||||||
|                     QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType())), |                     QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType())), | ||||||
|                     program_id), |                     program_id), | ||||||
|                 new GameListItemCompat(compatibility), |                 new GameListItemCompat(compatibility), | ||||||
|                 new GameListItem(FormatPatchNameVersions(program_id, loader->IsRomFSUpdatable())), |                 new GameListItem(FormatPatchNameVersions(patch, loader->IsRomFSUpdatable())), | ||||||
|                 new GameListItem( |  | ||||||
|                     FormatPatchNameVersions(patch, version, loader->IsRomFSUpdatable())), |  | ||||||
|                 new GameListItem( |                 new GameListItem( | ||||||
|                     QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))), |                     QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))), | ||||||
|                 new GameListItemSize(FileUtil::GetSize(physical_name)), |                 new GameListItemSize(FileUtil::GetSize(physical_name)), | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Zach Hilman
					Zach Hilman