mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Updated notes in README. Tidied up code a bit, improvements to sorting algorithm.
This commit is contained in:
+8
-13
@@ -3,18 +3,13 @@
|
||||
# If you don't know YAML, just think of a normal ini file, but replace the
|
||||
# equals signs with colons followed by a space. No tabs allowed.
|
||||
|
||||
bEnableNetworking: true
|
||||
bUseOnlineCache: true
|
||||
bGetMetadataUpdates: true
|
||||
bPromptMetadataSubmit: true
|
||||
bAlwaysSubmitMetadata: true
|
||||
bGetMetadataUpdates: true
|
||||
|
||||
sOnlineCacheURL: "http://better-oblivion-sorting-software.googlecode.com/svn/data/boss-nehrim/masterlist.txt"
|
||||
sMetadataURL: "http://better-oblivion-sorting-software.googlecode.com/svn/data/boss-nehrim/masterlist.txt"
|
||||
sVersionCheckerURL: "http://better-oblivion-sorting-software.googlecode.com/svn/data/boss-nehrim/masterlist.txt"
|
||||
sMetadataURL: "http://better-oblivion-sorting-software.googlecode.com/svn/data/boss-nehrim/masterlist.txt"
|
||||
|
||||
sGame: auto # auto, oblivion, skyrim, fallout3, falloutnv
|
||||
sLastGame: auto # auto, oblivion, skyrim, fallout3, falloutnv
|
||||
iDebugVerbosity: 0 # 0, 1, 2, 3. Logging takes place if > 0.
|
||||
bDoTrialRun: false
|
||||
sLanguage: eng # An ISO 639-3 language string.
|
||||
sGame: auto # auto, oblivion, skyrim, fallout3, falloutnv
|
||||
sLastGame: auto # auto, oblivion, skyrim, fallout3, falloutnv
|
||||
iDebugVerbosity: 0 # 0, 1, 2, 3. Logging takes place if > 0.
|
||||
bDoTrialRun: false
|
||||
sLanguage: eng # An ISO 639-3 language string.
|
||||
|
||||
|
||||
@@ -34,10 +34,6 @@ namespace boss {
|
||||
const unsigned int VERSION_MAJOR = 3;
|
||||
const unsigned int VERSION_MINOR = 0;
|
||||
const unsigned int VERSION_PATCH = 0;
|
||||
|
||||
// Temporary hack.
|
||||
const char * const libespm_options_path = "../../libespm/opts/input";
|
||||
const char * const libespm_game = "Skyrim";
|
||||
|
||||
}
|
||||
|
||||
|
||||
+137
-23
@@ -24,6 +24,7 @@
|
||||
#include "metadata.h"
|
||||
#include "helpers.h"
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <src/fileFormat.h>
|
||||
|
||||
#include <iostream>
|
||||
@@ -32,6 +33,54 @@ using namespace std;
|
||||
|
||||
namespace boss {
|
||||
|
||||
FormID::FormID() : id(0) {}
|
||||
|
||||
FormID::FormID(const std::string& sourcePlugin, const uint32_t objectID) : plugin(sourcePlugin), id(objectID) {}
|
||||
|
||||
FormID::FormID(const std::vector<std::string>& sourcePlugins, const uint32_t formID) {
|
||||
int index = formID >> 24;
|
||||
id = formID & ~((uint32_t)index << 24);
|
||||
|
||||
if (index >= sourcePlugins.size()) {
|
||||
cout << hex << formID << dec << " in " << sourcePlugins.back() << " has a higher modIndex than expected." << endl;
|
||||
index = sourcePlugins.size() - 1;
|
||||
}
|
||||
|
||||
plugin = sourcePlugins[index];
|
||||
}
|
||||
|
||||
bool FormID::operator == (const FormID& rhs) const {
|
||||
|
||||
}
|
||||
|
||||
bool FormID::operator != (const FormID& rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
bool FormID::operator < (const FormID& rhs) const {
|
||||
return (id < rhs.Id() || plugin < rhs.Plugin());
|
||||
}
|
||||
|
||||
bool FormID::operator > (const FormID& rhs) const {
|
||||
return !(*this == rhs || *this < rhs);
|
||||
}
|
||||
|
||||
bool FormID::operator <= (const FormID& rhs) const {
|
||||
return (*this == rhs || *this < rhs);
|
||||
}
|
||||
|
||||
bool FormID::operator >= (const FormID& rhs) const {
|
||||
return !(*this < rhs);
|
||||
}
|
||||
|
||||
std::string FormID::Plugin() const {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
uint32_t FormID::Id() const {
|
||||
return id;
|
||||
}
|
||||
|
||||
ConditionalData::ConditionalData() {}
|
||||
|
||||
ConditionalData::ConditionalData(const string& c) : condition(c) {}
|
||||
@@ -81,6 +130,10 @@ namespace boss {
|
||||
File::File(const std::string& n, const std::string& d, const std::string& c)
|
||||
: display(d), ConditionalData(c, n) {}
|
||||
|
||||
bool File::operator < (const File& rhs) const {
|
||||
return Name() < rhs.Name();
|
||||
}
|
||||
|
||||
std::string File::Name() const {
|
||||
return Data();
|
||||
}
|
||||
@@ -115,6 +168,10 @@ namespace boss {
|
||||
Data(data);
|
||||
}
|
||||
|
||||
bool Tag::operator < (const Tag& rhs) const {
|
||||
return Name() < rhs.Name();
|
||||
}
|
||||
|
||||
bool Tag::IsAddition() const {
|
||||
return addTag;
|
||||
}
|
||||
@@ -130,20 +187,20 @@ namespace boss {
|
||||
return Data();
|
||||
}
|
||||
|
||||
Plugin::Plugin() : enabled(true), priority(0), crc(0), isMaster(false) {}
|
||||
Plugin::Plugin(const std::string& n) : name(n), enabled(true), priority(0), crc(0), isMaster(false) {}
|
||||
Plugin::Plugin() : enabled(true), priority(0), isMaster(false) {}
|
||||
Plugin::Plugin(const std::string& n) : name(n), enabled(true), priority(0), isMaster(false) {}
|
||||
|
||||
Plugin::Plugin(const std::string& n, const std::string& path)
|
||||
: name(n), enabled(true), priority(0) {
|
||||
|
||||
// Get data from file contents using libespm. Assumes libespm has already been initialised.
|
||||
boost::filesystem::path filepath = boost::filesystem::path(path) / n;
|
||||
|
||||
ifstream input(filepath.string().c_str(), ios::binary);
|
||||
espm::file File;
|
||||
espm::readFile(input, File);
|
||||
input.close();
|
||||
|
||||
crc = GetCrc32(filepath);
|
||||
|
||||
isMaster = espm::isMaster(File);
|
||||
vector<char*> rawMasters = espm::getMasters(File);
|
||||
for (size_t i=0,max=rawMasters.size(); i < max; ++i) {
|
||||
@@ -151,8 +208,11 @@ namespace boss {
|
||||
}
|
||||
|
||||
vector<espm::item> records = espm::getRecords(File);
|
||||
vector<string> plugins = masters;
|
||||
plugins.push_back(name);
|
||||
for (vector<espm::item>::const_iterator it = records.begin(),endIt = records.end(); it != endIt; ++it){
|
||||
formIDs.insert(*reinterpret_cast<uint32_t*>(it->record.recID));
|
||||
uint32_t id = *reinterpret_cast<uint32_t*>(it->record.recID);
|
||||
formIDs.insert(FormID(plugins, id));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,7 +236,7 @@ namespace boss {
|
||||
return requirements;
|
||||
}
|
||||
|
||||
std::set<File, file_comp> Plugin::Incs() const {
|
||||
std::set<File> Plugin::Incs() const {
|
||||
return incompatibilities;
|
||||
}
|
||||
|
||||
@@ -208,7 +268,7 @@ namespace boss {
|
||||
requirements = r;
|
||||
}
|
||||
|
||||
void Plugin::Incs(const std::set<File, file_comp>& i) {
|
||||
void Plugin::Incs(const std::set<File>& i) {
|
||||
incompatibilities = i;
|
||||
}
|
||||
|
||||
@@ -235,7 +295,7 @@ namespace boss {
|
||||
++it;
|
||||
}
|
||||
|
||||
for (set<File, file_comp>::iterator it = incompatibilities.begin(); it != incompatibilities.end();) {
|
||||
for (set<File>::iterator it = incompatibilities.begin(); it != incompatibilities.end();) {
|
||||
if (!it->EvalCondition(game))
|
||||
incompatibilities.erase(it++);
|
||||
else
|
||||
@@ -265,36 +325,90 @@ namespace boss {
|
||||
return boost::iends_with(name, "\\.esm") || boost::iends_with(name, "\\.esp");
|
||||
}
|
||||
|
||||
bool Plugin::operator == (Plugin rhs) {
|
||||
return name == rhs.Name();
|
||||
bool Plugin::operator == (const Plugin& rhs) const {
|
||||
return boost::iequals(name, rhs.Name());
|
||||
}
|
||||
|
||||
bool Plugin::operator != (const Plugin& rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
bool Plugin::operator < (const Plugin& rhs) const {
|
||||
|
||||
/* If this plugin is a master and the other isn't, this plugin should load first.
|
||||
* If this plugin is a master of the other plugin, this plugin should load first.
|
||||
* If this plugin conflicts with the other plugin, then the plugin which contains the most records overall should load first.
|
||||
*/
|
||||
|
||||
if (IsMaster() && !rhs.IsMaster())
|
||||
return true;
|
||||
|
||||
if (!IsMaster() && rhs.IsMaster())
|
||||
return false;
|
||||
|
||||
if (rhs.IsChildOf(*this))
|
||||
return true;
|
||||
|
||||
if (IsChildOf(rhs)) // Should probably also check for cyclic masters.
|
||||
return false;
|
||||
|
||||
if (!OverlapFormIDs(rhs).empty() && formIDs.size() != rhs.FormIDs().size())
|
||||
return formIDs.size() > rhs.FormIDs().size();
|
||||
|
||||
//return false;
|
||||
return name < rhs.Name();
|
||||
}
|
||||
|
||||
bool Plugin::operator > (const Plugin& rhs) const {
|
||||
return !(*this == rhs || *this < rhs);
|
||||
}
|
||||
|
||||
bool Plugin::operator <= (const Plugin& rhs) const {
|
||||
return (*this == rhs || *this < rhs);
|
||||
}
|
||||
|
||||
bool Plugin::operator >= (const Plugin& rhs) const {
|
||||
return !(*this < rhs);
|
||||
}
|
||||
|
||||
std::set<uint32_t> Plugin::FormIDs() const {
|
||||
std::set<FormID> Plugin::FormIDs() const {
|
||||
return formIDs;
|
||||
}
|
||||
|
||||
std::set<uint32_t> Plugin::OverrideFormIDs() const {
|
||||
int modIndex = masters.size() << 24;
|
||||
|
||||
set<uint32_t> fidSubset;
|
||||
|
||||
for (set<uint32_t>::const_iterator it = formIDs.begin(), endIt=formIDs.end(); it != endIt; ++it) {
|
||||
if (*it < modIndex)
|
||||
std::set<FormID> Plugin::OverrideFormIDs() const {
|
||||
set<FormID> fidSubset;
|
||||
for (set<FormID>::const_iterator it = formIDs.begin(), endIt=formIDs.end(); it != endIt; ++it) {
|
||||
if (boost::iequals(it->Plugin(), name))
|
||||
fidSubset.insert(*it);
|
||||
}
|
||||
|
||||
return fidSubset;
|
||||
}
|
||||
|
||||
std::set<FormID> Plugin::OverlapFormIDs(const Plugin& plugin) const {
|
||||
std::set<FormID> otherFormIDs = plugin.FormIDs();
|
||||
std::set<FormID> overlap;
|
||||
for (std::set<FormID>::const_iterator it=formIDs.begin(), endIt=formIDs.end(); it != endIt; ++it) {
|
||||
if (otherFormIDs.find(*it) != otherFormIDs.end())
|
||||
overlap.insert(*it);
|
||||
}
|
||||
|
||||
return overlap;
|
||||
}
|
||||
|
||||
std::vector<std::string> Plugin::Masters() const {
|
||||
return masters;
|
||||
}
|
||||
|
||||
uint32_t Plugin::Crc() const {
|
||||
return crc;
|
||||
}
|
||||
|
||||
bool Plugin::IsMaster() const {
|
||||
return isMaster;
|
||||
}
|
||||
|
||||
//Checks if the object plugin is explicitly dependent on the given plugin.
|
||||
bool Plugin::IsChildOf(const Plugin& plugin) const {
|
||||
for (vector<string>::const_iterator it=masters.begin(), endIt=masters.end(); it != endIt; ++it) {
|
||||
if (boost::iequals(*it, plugin.Name()))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+45
-53
@@ -31,10 +31,31 @@
|
||||
#include <list>
|
||||
#include <set>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
namespace boss {
|
||||
|
||||
//A FormID is a 32 bit unsigned integer of the form xxYYYYYY in hex. The xx is the position in the masters list of the plugin that the FormID is from, and the YYYYYY is the rest of the FormID. Here the xx bit is stored as the corresponding filename to allow comparison between FormIDs from different plugins.
|
||||
class FormID {
|
||||
public:
|
||||
FormID();
|
||||
FormID(const std::string& pluginName, const uint32_t objectID);
|
||||
|
||||
//The masters here also includes the plugin that they are masters of as the last element.
|
||||
FormID(const std::vector<std::string>& masters, const uint32_t formID);
|
||||
|
||||
bool operator == (const FormID& rhs) const;
|
||||
bool operator != (const FormID& rhs) const;
|
||||
bool operator < (const FormID& rhs) const;
|
||||
bool operator > (const FormID& rhs) const;
|
||||
bool operator <= (const FormID& rhs) const;
|
||||
bool operator >= (const FormID& rhs) const;
|
||||
|
||||
std::string Plugin() const;
|
||||
uint32_t Id() const;
|
||||
private:
|
||||
std::string plugin;
|
||||
uint32_t id;
|
||||
};
|
||||
|
||||
class ConditionalData {
|
||||
public:
|
||||
ConditionalData();
|
||||
@@ -75,6 +96,8 @@ namespace boss {
|
||||
File(const std::string& name, const std::string& display,
|
||||
const std::string& condition);
|
||||
|
||||
bool operator < (const File& rhs) const;
|
||||
|
||||
std::string Name() const;
|
||||
std::string DisplayName() const;
|
||||
private:
|
||||
@@ -87,6 +110,8 @@ namespace boss {
|
||||
Tag(const std::string& tag);
|
||||
Tag(const std::string& tag, const std::string& condition);
|
||||
|
||||
bool operator < (const Tag& rhs) const;
|
||||
|
||||
bool IsAddition() const;
|
||||
std::string Name() const;
|
||||
std::string PrefixedName() const; //Name with '-' in front if suggested for removal.
|
||||
@@ -94,18 +119,6 @@ namespace boss {
|
||||
bool addTag;
|
||||
};
|
||||
|
||||
struct file_comp {
|
||||
bool operator() (const File& lhs, const File& rhs) const {
|
||||
return lhs.Name() < rhs.Name();
|
||||
}
|
||||
};
|
||||
|
||||
struct tag_comp {
|
||||
bool operator() (const Tag& lhs, const Tag& rhs) const {
|
||||
return lhs.Name() < rhs.Name();
|
||||
}
|
||||
};
|
||||
|
||||
class Plugin {
|
||||
public:
|
||||
Plugin();
|
||||
@@ -117,7 +130,7 @@ namespace boss {
|
||||
int Priority() const;
|
||||
std::list<File> LoadAfter() const;
|
||||
std::list<File> Reqs() const;
|
||||
std::set<File, file_comp> Incs() const;
|
||||
std::set<File> Incs() const;
|
||||
std::list<Message> Messages() const;
|
||||
std::list<Tag> Tags() const;
|
||||
|
||||
@@ -126,7 +139,7 @@ namespace boss {
|
||||
void Priority(const int priority);
|
||||
void LoadAfter(const std::list<File>& after);
|
||||
void Reqs(const std::list<File>& reqs);
|
||||
void Incs(const std::set<File, file_comp>& incs);
|
||||
void Incs(const std::set<File>& incs);
|
||||
void Messages(const std::list<Message>& messages);
|
||||
void Tags(const std::list<Tag>& tags);
|
||||
|
||||
@@ -134,57 +147,36 @@ namespace boss {
|
||||
bool HasNameOnly() const;
|
||||
bool IsRegexPlugin() const;
|
||||
|
||||
bool operator == (Plugin rhs);
|
||||
//Compare name strings.
|
||||
bool operator == (const Plugin& rhs) const;
|
||||
bool operator != (const Plugin& rhs) const;
|
||||
|
||||
//Compare load order positions.
|
||||
bool operator < (const Plugin& rhs) const;
|
||||
bool operator > (const Plugin& rhs) const;
|
||||
bool operator <= (const Plugin& rhs) const;
|
||||
bool operator >= (const Plugin& rhs) const;
|
||||
|
||||
std::set<uint32_t> FormIDs() const;
|
||||
std::set<uint32_t> OverrideFormIDs() const;
|
||||
std::set<FormID> FormIDs() const;
|
||||
std::set<FormID> OverrideFormIDs() const;
|
||||
std::set<FormID> OverlapFormIDs(const Plugin& plugin) const;
|
||||
std::vector<std::string> Masters() const;
|
||||
uint32_t Crc() const;
|
||||
bool IsMaster() const;
|
||||
bool IsMaster() const; //Checks master bit flag.
|
||||
bool IsChildOf(const Plugin& plugin) const; //Checks masters for given plugin.
|
||||
private:
|
||||
std::string name;
|
||||
bool enabled; //Default to true.
|
||||
int priority; //Default to 0 : >0 is higher, <0 is lower priorities.
|
||||
std::list<File> loadAfter;
|
||||
std::list<File> requirements;
|
||||
std::set<File, file_comp> incompatibilities;
|
||||
std::set<File> incompatibilities;
|
||||
std::list<Message> messages;
|
||||
std::list<Tag> tags;
|
||||
|
||||
std::vector<std::string> masters;
|
||||
std::set<uint32_t> formIDs;
|
||||
uint32_t crc;
|
||||
std::set<FormID> formIDs;
|
||||
bool isMaster;
|
||||
};
|
||||
|
||||
inline bool isMasterOf(const Plugin& servant, const Plugin& master) {
|
||||
std::vector<std::string> masters = servant.Masters();
|
||||
for (int i = 0; i < masters.size(); ++i) {
|
||||
if (masters[i] == master.Name())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
struct plugin_comp {
|
||||
bool operator() (const Plugin& lhs, const Plugin& rhs) const {
|
||||
if (lhs.IsMaster() && !rhs.IsMaster())
|
||||
return true;
|
||||
else if (!lhs.IsMaster() && rhs.IsMaster())
|
||||
return false;
|
||||
else if (isMasterOf(rhs, lhs))
|
||||
return true;
|
||||
else if (isMasterOf(lhs, rhs)) // Should probably also check for cyclic masters.
|
||||
return false;
|
||||
else if (lhs.OverrideFormIDs().size() > rhs.OverrideFormIDs().size())
|
||||
return true;
|
||||
else if (lhs.OverrideFormIDs().size() < rhs.OverrideFormIDs().size())
|
||||
return false;
|
||||
else
|
||||
return lhs.Name() < rhs.Name();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -189,7 +189,7 @@ namespace YAML {
|
||||
if (node["req"])
|
||||
rhs.Reqs(node["req"].as< std::list<boss::File> >());
|
||||
if (node["inc"])
|
||||
rhs.Incs(node["inc"].as< std::set<boss::File, boss::file_comp> >());
|
||||
rhs.Incs(node["inc"].as< std::set<boss::File> >());
|
||||
if (node["msg"])
|
||||
rhs.Messages(node["msg"].as< std::list<boss::Message> >());
|
||||
if (node["tag"])
|
||||
|
||||
+82
-35
@@ -1,3 +1,25 @@
|
||||
/* BOSS
|
||||
|
||||
A plugin load order optimiser for games that use the esp/esm plugin system.
|
||||
|
||||
Copyright (C) 2012 WrinklyNinja
|
||||
|
||||
This file is part of BOSS.
|
||||
|
||||
BOSS is free software: you can redistribute
|
||||
it and/or modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
BOSS is distributed in the hope that it will
|
||||
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with BOSS. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <yaml-cpp/yaml.h>
|
||||
#include "metadata.h"
|
||||
@@ -11,25 +33,24 @@
|
||||
#include <stdint.h>
|
||||
#include <ctime>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
#include <src/commonSupport.h>
|
||||
#include <src/fileFormat.h>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
using namespace std;
|
||||
|
||||
//It would be neater if this could be done by just skipping bits of the output...
|
||||
void minimisePluginList(set<boss::Plugin, boss::plugin_comp>& plugins) {
|
||||
set<boss::Plugin, boss::plugin_comp> out;
|
||||
for (set<boss::Plugin, boss::plugin_comp>::iterator it=plugins.begin(), endIt=plugins.end(); it != endIt; ++it) {
|
||||
boss::Plugin p(it->Name());
|
||||
p.Tags(it->Tags());
|
||||
out.insert(p);
|
||||
}
|
||||
plugins.swap(out);
|
||||
}
|
||||
// Temporary hack.
|
||||
const char * const libespm_options_path = "libespm.cfg";
|
||||
const char * const libespm_game = "Skyrim";
|
||||
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
@@ -78,51 +99,77 @@ int main(int argc, char *argv[]) {
|
||||
out2 << yout2.c_str();
|
||||
out2.close();
|
||||
*/
|
||||
cout << "Testing plugin reading." << endl;
|
||||
cout << "Setting up libespm and BOSS..." << endl;
|
||||
|
||||
|
||||
// Set up libesm.
|
||||
common::options::setGame(libespm_game);
|
||||
ifstream input(libespm_options_path);
|
||||
common::readOptions(input);
|
||||
input.close();
|
||||
|
||||
//Set up BOSS vars.
|
||||
boss::Game game(boss::GAME_TES5);
|
||||
|
||||
cout << "Reading plugins in Data folder..." << endl;
|
||||
time_t start, end;
|
||||
start = time(NULL);
|
||||
|
||||
// Set up libesm.
|
||||
common::options::setGame(boss::libespm_game);
|
||||
ifstream input(boss::libespm_options_path);
|
||||
common::readOptions(input);
|
||||
input.close();
|
||||
|
||||
// Get a list of the plugins.
|
||||
list<boss::Plugin> plugins;
|
||||
for (fs::directory_iterator it(argv[1]); it != fs::directory_iterator(); ++it) {
|
||||
for (fs::directory_iterator it(game.DataPath()); it != fs::directory_iterator(); ++it) {
|
||||
if (fs::is_regular_file(it->status()) && (it->path().extension().string() == ".esp" || it->path().extension().string() == ".esm")) {
|
||||
|
||||
string filename = it->path().filename().string();
|
||||
if (filename == "Skyrim.esm"
|
||||
|| filename == "Tamriel Compendium.esp"
|
||||
|| filename == "Tamriel Compendium - Skill Books.esp")
|
||||
continue; // Libespm crashes with these plugins.
|
||||
|
||||
if (it->path().filename().string() == "Skyrim.esm")
|
||||
continue; // Libespm crashes with v1.9 Skyrim.esm.
|
||||
|
||||
cout << "Found plugin: " << it->path().string() << endl;
|
||||
boss::Plugin plugin(it->path().filename().string(),it->path().parent_path().string());
|
||||
plugins.push_back(plugin);
|
||||
cout << "Reading plugin: " << filename << endl;
|
||||
boss::Plugin plugin(filename, it->path().parent_path().string());
|
||||
plugins.push_back(plugin);
|
||||
}
|
||||
}
|
||||
|
||||
cout << "Finished looking for plugins." << endl;
|
||||
|
||||
plugins.sort(boss::plugin_comp());
|
||||
|
||||
|
||||
end = time(NULL);
|
||||
cout << "Time taken to read plugins: " << (end - start) << " seconds." << endl;
|
||||
start = time(NULL);
|
||||
|
||||
for (list<boss::Plugin>::iterator it=plugins.begin(), endIt = plugins.end(); it != endIt; ++it) {
|
||||
cout << it->Name() << endl
|
||||
<< '\t' << "Number of records: " << it->FormIDs().size() << endl
|
||||
<< '\t' << "Is Master: " << it->IsMaster() << endl
|
||||
<< '\t' << "Masters:" << endl;
|
||||
|
||||
vector<std::string> masters = it->Masters();
|
||||
for(int i = 0; i < masters.size(); ++i)
|
||||
cout << '\t' << '\t' << i << ": " << masters[i] << endl;
|
||||
|
||||
cout << '\t' << "Number of Records: " << it->FormIDs().size() << endl;
|
||||
|
||||
cout << '\t' << "Number of Override Records: " << it->OverrideFormIDs().size() << endl;
|
||||
|
||||
cout << '\t' << "Conflicts with:" << endl;
|
||||
for (list<boss::Plugin>::iterator jt=plugins.begin(), endJt = plugins.end(); jt != endJt; ++jt) {
|
||||
if (*jt != *it && !jt->IsChildOf(*it)) {
|
||||
size_t overlap = jt->OverlapFormIDs(*it).size();
|
||||
if (overlap > 0)
|
||||
cout << '\t' << '\t' << jt->Name() << " (" << overlap << " records)" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end = time(NULL);
|
||||
cout << "Time taken to print plugins' details: " << (end - start) << " seconds." << endl;
|
||||
start = time(NULL);
|
||||
|
||||
cout << "Sorting plugins..." << endl;
|
||||
|
||||
plugins.sort();
|
||||
|
||||
end = time(NULL);
|
||||
cout << "Time taken to sort plugins: " << (end - start) << " seconds." << endl;
|
||||
|
||||
|
||||
for (list<boss::Plugin>::iterator it=plugins.begin(), endIt = plugins.end(); it != endIt; ++it)
|
||||
cout << it->Name() << endl;
|
||||
|
||||
cout << "Tester finished." << endl;
|
||||
start = time(NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user