From c9ec48ea96d9d0dfd3e8fbbc87d89ca57ff5fc24 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Tue, 15 Apr 2025 15:10:41 +0200 Subject: [PATCH] Qt/System: Clear games in games.yml that are inside the old vfs path during game list refresh --- rpcs3/Emu/System.cpp | 7 ++++ rpcs3/Emu/System.h | 1 + rpcs3/Emu/games_config.cpp | 60 ++++++++++++++++++++++++++++--- rpcs3/Emu/games_config.h | 3 ++ rpcs3/rpcs3qt/game_list_frame.cpp | 3 ++ 5 files changed, 70 insertions(+), 4 deletions(-) diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 77f98c4798..1a8e7012d9 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -4139,6 +4139,13 @@ game_boot_result Emulator::AddGameToYml(const std::string& path) return game_boot_result::invalid_file_or_folder; } +void Emulator::UpdateGamesPath(const std::string& path, bool save_on_disk) +{ + m_games_config.set_save_on_dirty(save_on_disk); + [[maybe_unused]] const games_config::result res = m_games_config.update_vfs_path(path); + m_games_config.set_save_on_dirty(true); +} + u32 Emulator::RemoveGames(const std::vector& title_id_list, bool save_on_disk) { if (title_id_list.empty()) diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index 4306fe9658..97755c6f13 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -454,6 +454,7 @@ public: u32 AddGamesFromDir(const std::string& path); game_boot_result AddGame(const std::string& path); game_boot_result AddGameToYml(const std::string& path); + void UpdateGamesPath(const std::string& path, bool save_on_disk = true); u32 RemoveGames(const std::vector& title_id_list, bool save_on_disk = true); game_boot_result RemoveGameFromYml(const std::string& title_id); diff --git a/rpcs3/Emu/games_config.cpp b/rpcs3/Emu/games_config.cpp index cfa43f6e15..ef209aaaf7 100644 --- a/rpcs3/Emu/games_config.cpp +++ b/rpcs3/Emu/games_config.cpp @@ -118,20 +118,64 @@ games_config::result games_config::remove_game(const std::string& key) return result::success; } +games_config::result games_config::update_vfs_path(const std::string& path) +{ + std::lock_guard lock(m_mutex); + + if (m_vfs_path != path) + { + cfg_log.notice("Changing VFS path in games.yml from '%s' to '%s'", m_vfs_path, path); + + // Remove games in old vfs path + if (!m_vfs_path.empty()) + { + for (auto it = m_games.begin(); it != m_games.end();) + { + if (it->second.starts_with(m_vfs_path)) + { + cfg_log.notice("Removing game from games.yml due to outdated vfs games path: '%s' (old vfs path: '%s')", it->second, m_vfs_path); + it = m_games.erase(it); + continue; + } + + it++; + } + } + + m_vfs_path = path; + m_dirty = true; + + if (m_save_on_dirty && !save_nl()) + { + return result::failure; + } + } + + return result::success; +} + bool games_config::save_nl() { YAML::Emitter out; - out << m_games; + out << YAML::BeginMap; + out << vfs_path_key << m_vfs_path; + for (const auto& [key, value] : m_games) + { + out << key << value; + } + out << YAML::EndMap; - fs::pending_file temp(fs::get_config_dir(true) + "games.yml"); + const std::string path = fs::get_config_dir(true) + "games.yml"; + fs::pending_file temp(path); if (temp.file && temp.file.write(out.c_str(), out.size()) >= out.size() && temp.commit()) { + cfg_log.notice("Saved games.yml to '%s'", path); m_dirty = false; return true; } - cfg_log.error("Failed to save games.yml: %s", fs::g_tls_error); + cfg_log.error("Failed to save games.yml to '%s': %s", path, fs::g_tls_error); return false; } @@ -145,6 +189,7 @@ void games_config::load() { std::lock_guard lock(m_mutex); + m_vfs_path.clear(); m_games.clear(); const std::string path = fs::get_config_dir(true) + "games.yml"; @@ -186,7 +231,14 @@ void games_config::load() { if (!entry.first.Scalar().empty() && entry.second.IsScalar() && !entry.second.Scalar().empty()) { - m_games.emplace(entry.first.Scalar(), entry.second.Scalar()); + if (entry.first.Scalar() == vfs_path_key) + { + m_vfs_path = entry.second.Scalar(); + } + else + { + m_games.emplace(entry.first.Scalar(), entry.second.Scalar()); + } } } } diff --git a/rpcs3/Emu/games_config.h b/rpcs3/Emu/games_config.h index c0e8bfb870..4f3bc85967 100644 --- a/rpcs3/Emu/games_config.h +++ b/rpcs3/Emu/games_config.h @@ -25,12 +25,15 @@ public: result add_game(const std::string& key, const std::string& path); result add_external_hdd_game(const std::string& key, std::string& path); result remove_game(const std::string& key); + result update_vfs_path(const std::string& path); bool save(); private: bool save_nl(); void load(); + const std::string vfs_path_key = "VFS_PATH"; + std::string m_vfs_path; std::map m_games; mutable shared_mutex m_mutex; diff --git a/rpcs3/rpcs3qt/game_list_frame.cpp b/rpcs3/rpcs3qt/game_list_frame.cpp index 4399137600..cb789e1af0 100644 --- a/rpcs3/rpcs3qt/game_list_frame.cpp +++ b/rpcs3/rpcs3qt/game_list_frame.cpp @@ -419,6 +419,9 @@ void game_list_frame::Refresh(const bool from_drive, const std::vector serials_to_remove = serials_to_remove_from_yml; // Initialize the list with the specified serials (if any)