From a4f862a6c3b6f99af3f6982dc6f4be8d99499377 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Thu, 5 Nov 2015 21:28:27 +0000 Subject: [PATCH] Cache whether a plugin loads a BSA or not --- src/backend/plugin/plugin.cpp | 60 ++++++++++++++++---------- src/backend/plugin/plugin.h | 3 +- src/gui/handler.cpp | 2 +- src/tests/backend/plugin/test_plugin.h | 12 ++---- 4 files changed, 45 insertions(+), 32 deletions(-) diff --git a/src/backend/plugin/plugin.cpp b/src/backend/plugin/plugin.cpp index b09c0e57..2aa32403 100644 --- a/src/backend/plugin/plugin.cpp +++ b/src/backend/plugin/plugin.cpp @@ -92,12 +92,28 @@ namespace loot { regex(regex7, regex::ECMAScript | regex::icase) }); - Plugin::Plugin() : PluginMetadata(), _isEmpty(true), isMaster(false), crc(0), numOverrideRecords(0) {} + Plugin::Plugin() : + _isEmpty(true), + _loadsBsa(false), + isMaster(false), + crc(0), + numOverrideRecords(0) {} - Plugin::Plugin(const std::string& n) : PluginMetadata(n), _isEmpty(true), isMaster(false), crc(0), numOverrideRecords(0) {} + Plugin::Plugin(const std::string& n) : + PluginMetadata(n), + _isEmpty(true), + _loadsBsa(false), + isMaster(false), + crc(0), + numOverrideRecords(0) {} - Plugin::Plugin(loot::Game& game, const std::string& n, const bool headerOnly) - : PluginMetadata(n), _isEmpty(true), isMaster(false), crc(0), numOverrideRecords(0) { + Plugin::Plugin(Game& game, const std::string& n, const bool headerOnly) : + PluginMetadata(n), + _isEmpty(true), + _loadsBsa(false), + isMaster(false), + crc(0), + numOverrideRecords(0) { try { boost::filesystem::path filepath = game.DataPath() / name; @@ -157,6 +173,22 @@ namespace loot { } } } + + // Get whether the plugin loads a BSA or not. + if (game.Id() == Game::tes5) { + // Skyrim plugins only load BSAs that exactly match their basename. + _loadsBsa = boost::filesystem::exists(game.DataPath() / (name.substr(0, name.length() - 3) + "bsa")); + } + else if (game.Id() != Game::tes4 || boost::iends_with(name, ".esp")) { + //Oblivion .esp files and FO3, FNV plugins can load BSAs which begin with the plugin basename. + string basename = name.substr(0, name.length() - 4); + for (boost::filesystem::directory_iterator it(game.DataPath()); it != boost::filesystem::directory_iterator(); ++it) { + if (it->path().extension().string() == ".bsa" && boost::istarts_with(it->path().filename().string(), basename)) { + _loadsBsa = true; + break; + } + } + } } catch (std::exception& e) { BOOST_LOG_TRIVIAL(error) << "Cannot read plugin file \"" << name << "\". Details: " << e.what(); @@ -296,23 +328,7 @@ namespace loot { return !_dirtyInfo.empty(); } - bool Plugin::LoadsBSA(const Game& game) const { - if (IsRegexPlugin()) - return false; - if (game.Id() == Game::tes5 || game.Id() == Game::fo4) { - // Skyrim plugins only load BSAs that exactly match their basename. - return boost::filesystem::exists(game.DataPath() / (name.substr(0, name.length() - 3) + "bsa")); - } - else { - //Oblivion .esp files and FO3, FNV plugins can load BSAs which begin with the plugin basename. - if (game.Id() != Game::tes4 || boost::iends_with(name, ".esp")) { - string basename = name.substr(0, name.length() - 4); - for (boost::filesystem::directory_iterator it(game.DataPath()); it != boost::filesystem::directory_iterator(); ++it) { - if (it->path().extension().string() == ".bsa" && boost::istarts_with(it->path().filename().string(), basename)) - return true; - } - } - return false; - } + bool Plugin::LoadsBSA() const { + return _loadsBsa; } } diff --git a/src/backend/plugin/plugin.h b/src/backend/plugin/plugin.h index a1c2ed80..b633dea2 100644 --- a/src/backend/plugin/plugin.h +++ b/src/backend/plugin/plugin.h @@ -53,7 +53,7 @@ namespace loot { uint32_t Crc() const; size_t NumOverrideFormIDs() const; - bool LoadsBSA(const Game& game) const; + bool LoadsBSA() const; bool IsActive(const Game& game) const; //Load ordering functions. @@ -65,6 +65,7 @@ namespace loot { static bool IsValid(const std::string& filename, const Game& game); private: bool _isEmpty; // Does the plugin contain any records other than the TES4 header? + bool _loadsBsa; std::vector masters; std::set formIDs; std::string version; //Obtained from description field. diff --git a/src/gui/handler.cpp b/src/gui/handler.cpp index 14c5219d..962f53df 100644 --- a/src/gui/handler.cpp +++ b/src/gui/handler.cpp @@ -743,7 +743,7 @@ namespace loot { pluginNode["isActive"] = plugin.IsActive(_lootState.CurrentGame()); pluginNode["isEmpty"] = plugin.IsEmpty(); pluginNode["isMaster"] = plugin.IsMaster(); - pluginNode["loadsBSA"] = plugin.LoadsBSA(_lootState.CurrentGame()); + pluginNode["loadsBSA"] = plugin.LoadsBSA(); pluginNode["crc"] = IntToHexString(plugin.Crc()); pluginNode["version"] = plugin.Version(); diff --git a/src/tests/backend/plugin/test_plugin.h b/src/tests/backend/plugin/test_plugin.h index 8104c7fc..1c24854d 100644 --- a/src/tests/backend/plugin/test_plugin.h +++ b/src/tests/backend/plugin/test_plugin.h @@ -104,14 +104,10 @@ TEST_F(Plugin, LoadsBSA) { game.SetGamePath(dataPath.parent_path()); ASSERT_NO_THROW(game.Init(false, localPath)); - loot::Plugin plugin("Blank - Different.esm"); - EXPECT_FALSE(plugin.LoadsBSA(game)); - - plugin = loot::Plugin("Blank\\.esm"); - EXPECT_FALSE(plugin.LoadsBSA(game)); - - plugin = loot::Plugin("Blank.esm"); - EXPECT_TRUE(plugin.LoadsBSA(game)); + EXPECT_FALSE(loot::Plugin(game, "Blank - Different.esm", true).LoadsBSA()); + EXPECT_FALSE(loot::Plugin(game, "Blank\\.esm", true).LoadsBSA()); + EXPECT_FALSE(loot::Plugin("Blank.esm").LoadsBSA()); + EXPECT_TRUE(loot::Plugin(game, "Blank.esm", true).LoadsBSA()); } TEST_F(Plugin, IsValid) {