Cache whether a plugin loads a BSA or not

This commit is contained in:
Oliver Hamlet
2015-12-05 10:17:50 +00:00
parent 41b32b2011
commit a4f862a6c3
4 changed files with 45 additions and 32 deletions
+38 -22
View File
@@ -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;
}
}
+2 -1
View File
@@ -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<std::string> masters;
std::set<libespm::FormId> formIDs;
std::string version; //Obtained from description field.
+1 -1
View File
@@ -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();
+4 -8
View File
@@ -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) {