mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Updated to use libloadorder 6.0.1.
Also fixed ghosted plugins not being recognised - closes #312.
This commit is contained in:
+35
-140
@@ -283,9 +283,9 @@ namespace loot {
|
||||
// Game member functions
|
||||
//----------------------
|
||||
|
||||
Game::Game() : id(Game::autodetect) {}
|
||||
Game::Game() : id(Game::autodetect), gh(nullptr) {}
|
||||
|
||||
Game::Game(const unsigned int gameCode, const std::string& folder) : id(gameCode) {
|
||||
Game::Game(const unsigned int gameCode, const std::string& folder) : id(gameCode), gh(nullptr) {
|
||||
if (Id() == Game::tes4) {
|
||||
_name = "TES IV: Oblivion";
|
||||
registryKey = "Software\\Bethesda Softworks\\Oblivion\\Installed Path";
|
||||
@@ -327,6 +327,10 @@ namespace loot {
|
||||
lootFolderName = folder;
|
||||
}
|
||||
|
||||
Game::~Game() {
|
||||
lo_destroy_handle(gh);
|
||||
}
|
||||
|
||||
Game& Game::SetDetails(const std::string& name, const std::string& masterFile,
|
||||
const std::string& repositoryURL, const std::string& repositoryBranch, const std::string& path, const std::string& registry) {
|
||||
BOOST_LOG_TRIVIAL(info) << "Setting new details for game: " << _name;
|
||||
@@ -384,6 +388,7 @@ namespace loot {
|
||||
// Set the path to the game's folder in %LOCALAPPDATA%.
|
||||
_gameLocalDataPath = gameLocalAppData;
|
||||
|
||||
InitLibloHandle();
|
||||
RefreshActivePluginsList();
|
||||
|
||||
if (createFolder) {
|
||||
@@ -465,18 +470,12 @@ namespace loot {
|
||||
return g_path_local / lootFolderName / "userlist.yaml";
|
||||
}
|
||||
|
||||
void Game::RefreshActivePluginsList() {
|
||||
BOOST_LOG_TRIVIAL(debug) << "Refreshing active plugins list for game: " << _name;
|
||||
|
||||
lo_game_handle gh = nullptr;
|
||||
char ** pluginArr;
|
||||
size_t pluginArrSize;
|
||||
int ret;
|
||||
|
||||
void Game::InitLibloHandle() {
|
||||
const char * gameLocalDataPath = nullptr;
|
||||
if (!_gameLocalDataPath.empty())
|
||||
gameLocalDataPath = _gameLocalDataPath.string().c_str();
|
||||
|
||||
int ret;
|
||||
if (Id() == Game::tes4)
|
||||
ret = lo_create_handle(&gh, LIBLO_GAME_TES4, gamePath.string().c_str(), gameLocalDataPath);
|
||||
else if (Id() == Game::tes5)
|
||||
@@ -504,25 +503,31 @@ namespace loot {
|
||||
throw error(error::liblo_error, err);
|
||||
}
|
||||
|
||||
ret = lo_set_game_master(gh, _masterFile.c_str());
|
||||
|
||||
if (ret != LIBLO_OK) {
|
||||
const char * e = nullptr;
|
||||
string err;
|
||||
lo_get_error_message(&e);
|
||||
lo_destroy_handle(gh);
|
||||
if (e == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "libloadorder failed to initialise game master file support. Details could not be fetched.";
|
||||
err = lc::translate("libloadorder failed to initialise game master file support. Details could not be fetched.").str();
|
||||
if (id != Game::tes5) {
|
||||
if (lo_set_game_master(gh, _masterFile.c_str()) != LIBLO_OK) {
|
||||
const char * e = nullptr;
|
||||
string err;
|
||||
lo_get_error_message(&e);
|
||||
lo_destroy_handle(gh);
|
||||
if (e == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "libloadorder failed to initialise game master file support. Details could not be fetched.";
|
||||
err = lc::translate("libloadorder failed to initialise game master file support. Details could not be fetched.").str();
|
||||
}
|
||||
else {
|
||||
BOOST_LOG_TRIVIAL(error) << "libloadorder failed to initialise game master file support. Details: " << e;
|
||||
err = lc::translate("libloadorder failed to initialise game master file support. Details:").str() + " " + e;
|
||||
}
|
||||
lo_cleanup();
|
||||
throw error(error::liblo_error, err);
|
||||
}
|
||||
else {
|
||||
BOOST_LOG_TRIVIAL(error) << "libloadorder failed to initialise game master file support. Details: " << e;
|
||||
err = lc::translate("libloadorder failed to initialise game master file support. Details:").str() + " " + e;
|
||||
}
|
||||
lo_cleanup();
|
||||
throw error(error::liblo_error, err);
|
||||
}
|
||||
}
|
||||
|
||||
void Game::RefreshActivePluginsList() {
|
||||
BOOST_LOG_TRIVIAL(debug) << "Refreshing active plugins list for game: " << _name;
|
||||
|
||||
char ** pluginArr;
|
||||
size_t pluginArrSize;
|
||||
if (lo_get_active_plugins(gh, &pluginArr, &pluginArrSize) != LIBLO_OK) {
|
||||
const char * e = nullptr;
|
||||
string err;
|
||||
@@ -544,8 +549,6 @@ namespace loot {
|
||||
for (size_t i = 0; i < pluginArrSize; ++i) {
|
||||
activePlugins.insert(boost::locale::to_lower(string(pluginArr[i])));
|
||||
}
|
||||
|
||||
lo_destroy_handle(gh);
|
||||
}
|
||||
|
||||
bool Game::IsActive(const std::string& plugin) const {
|
||||
@@ -555,70 +558,17 @@ namespace loot {
|
||||
void Game::GetLoadOrder(std::list<std::string>& loadOrder) const {
|
||||
BOOST_LOG_TRIVIAL(debug) << "Getting load order for game: " << _name;
|
||||
|
||||
lo_game_handle gh = nullptr;
|
||||
char ** pluginArr;
|
||||
size_t pluginArrSize;
|
||||
|
||||
int ret;
|
||||
|
||||
const char * gameLocalDataPath = nullptr;
|
||||
if (!_gameLocalDataPath.empty())
|
||||
gameLocalDataPath = _gameLocalDataPath.string().c_str();
|
||||
|
||||
if (Id() == Game::tes4)
|
||||
ret = lo_create_handle(&gh, LIBLO_GAME_TES4, gamePath.string().c_str(), gameLocalDataPath);
|
||||
else if (Id() == Game::tes5)
|
||||
ret = lo_create_handle(&gh, LIBLO_GAME_TES5, gamePath.string().c_str(), gameLocalDataPath);
|
||||
else if (Id() == Game::fo3)
|
||||
ret = lo_create_handle(&gh, LIBLO_GAME_FO3, gamePath.string().c_str(), gameLocalDataPath);
|
||||
else if (Id() == Game::fonv)
|
||||
ret = lo_create_handle(&gh, LIBLO_GAME_FNV, gamePath.string().c_str(), gameLocalDataPath);
|
||||
else
|
||||
ret = LIBLO_ERROR_INVALID_ARGS;
|
||||
|
||||
if (ret != LIBLO_OK && ret != LIBLO_WARN_LO_MISMATCH) {
|
||||
const char * e = nullptr;
|
||||
string err;
|
||||
lo_get_error_message(&e);
|
||||
if (e == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "libloadorder failed to create a game handle. Details could not be fetched.";
|
||||
err = lc::translate("libloadorder failed to create a game handle. Details could not be fetched.").str();
|
||||
}
|
||||
else {
|
||||
BOOST_LOG_TRIVIAL(error) << "libloadorder failed to create a game handle. Details: " << e;
|
||||
err = lc::translate("libloadorder failed to create a game handle. Details:").str() + " " + e;
|
||||
}
|
||||
lo_cleanup();
|
||||
throw error(error::liblo_error, err);
|
||||
}
|
||||
|
||||
ret = lo_set_game_master(gh, _masterFile.c_str());
|
||||
|
||||
if (ret != LIBLO_OK) {
|
||||
const char * e = nullptr;
|
||||
string err;
|
||||
lo_get_error_message(&e);
|
||||
lo_destroy_handle(gh);
|
||||
if (e == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "libloadorder failed to initialise game master file support. Details could not be fetched.";
|
||||
err = lc::translate("libloadorder failed to initialise game master file support. Details could not be fetched.").str();
|
||||
}
|
||||
else {
|
||||
BOOST_LOG_TRIVIAL(error) << "libloadorder failed to initialise game master file support. Details: " << e;
|
||||
err = lc::translate("libloadorder failed to initialise game master file support. Details:").str() + " " + e;
|
||||
}
|
||||
lo_cleanup();
|
||||
throw error(error::liblo_error, err);
|
||||
}
|
||||
|
||||
if (lo_get_load_order(gh, &pluginArr, &pluginArrSize) != LIBLO_OK) {
|
||||
const char * e = nullptr;
|
||||
string err;
|
||||
lo_get_error_message(&e);
|
||||
lo_destroy_handle(gh);
|
||||
if (e == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "libloadorder failed to set the load order. Details could not be fetched.";
|
||||
err = lc::translate("libloadorder failed to set the load order. Details could not be fetched.").str();
|
||||
BOOST_LOG_TRIVIAL(error) << "libloadorder failed to get the load order. Details could not be fetched.";
|
||||
err = lc::translate("libloadorder failed to get the load order. Details could not be fetched.").str();
|
||||
}
|
||||
else {
|
||||
BOOST_LOG_TRIVIAL(error) << "libloadorder failed to get the load order. Details: " << e;
|
||||
@@ -632,65 +582,11 @@ namespace loot {
|
||||
for (size_t i = 0; i < pluginArrSize; ++i) {
|
||||
loadOrder.push_back(string(pluginArr[i]));
|
||||
}
|
||||
|
||||
lo_destroy_handle(gh);
|
||||
}
|
||||
|
||||
void Game::SetLoadOrder(const char * const * const loadOrder, const size_t numPlugins) const {
|
||||
BOOST_LOG_TRIVIAL(debug) << "Setting load order for game: " << _name;
|
||||
|
||||
lo_game_handle gh = nullptr;
|
||||
int ret;
|
||||
|
||||
const char * gameLocalDataPath = nullptr;
|
||||
if (!_gameLocalDataPath.empty())
|
||||
gameLocalDataPath = _gameLocalDataPath.string().c_str();
|
||||
|
||||
if (Id() == Game::tes4)
|
||||
ret = lo_create_handle(&gh, LIBLO_GAME_TES4, gamePath.string().c_str(), gameLocalDataPath);
|
||||
else if (Id() == Game::tes5)
|
||||
ret = lo_create_handle(&gh, LIBLO_GAME_TES5, gamePath.string().c_str(), gameLocalDataPath);
|
||||
else if (Id() == Game::fo3)
|
||||
ret = lo_create_handle(&gh, LIBLO_GAME_FO3, gamePath.string().c_str(), gameLocalDataPath);
|
||||
else if (Id() == Game::fonv)
|
||||
ret = lo_create_handle(&gh, LIBLO_GAME_FNV, gamePath.string().c_str(), gameLocalDataPath);
|
||||
else
|
||||
ret = LIBLO_ERROR_INVALID_ARGS;
|
||||
|
||||
if (ret != LIBLO_OK && ret != LIBLO_WARN_LO_MISMATCH) {
|
||||
const char * e = nullptr;
|
||||
string err;
|
||||
lo_get_error_message(&e);
|
||||
if (e == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "libloadorder failed to create a game handle. Details could not be fetched.";
|
||||
err = lc::translate("libloadorder failed to create a game handle. Details could not be fetched.").str();
|
||||
}
|
||||
else {
|
||||
BOOST_LOG_TRIVIAL(error) << "libloadorder failed to create a game handle. Details: " << e;
|
||||
err = lc::translate("libloadorder failed to create a game handle. Details:").str() + " " + e;
|
||||
}
|
||||
lo_cleanup();
|
||||
throw error(error::liblo_error, err);
|
||||
}
|
||||
|
||||
ret = lo_set_game_master(gh, _masterFile.c_str());
|
||||
if (ret != LIBLO_OK) {
|
||||
const char * e = nullptr;
|
||||
string err;
|
||||
lo_get_error_message(&e);
|
||||
lo_destroy_handle(gh);
|
||||
if (e == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "libloadorder failed to initialise game master file support. Details could not be fetched.";
|
||||
err = lc::translate("libloadorder failed to initialise game master file support. Details could not be fetched.").str();
|
||||
}
|
||||
else {
|
||||
BOOST_LOG_TRIVIAL(error) << "libloadorder failed to initialise game master file support. Details: " << e;
|
||||
err = lc::translate("libloadorder failed to initialise game master file support. Details:").str() + " " + e;
|
||||
}
|
||||
lo_cleanup();
|
||||
throw error(error::liblo_error, err);
|
||||
}
|
||||
|
||||
if (lo_set_load_order(gh, loadOrder, numPlugins) != LIBLO_OK) {
|
||||
const char * e = nullptr;
|
||||
string err;
|
||||
@@ -707,8 +603,6 @@ namespace loot {
|
||||
lo_cleanup();
|
||||
throw error(error::liblo_error, err);
|
||||
}
|
||||
|
||||
lo_destroy_handle(gh);
|
||||
}
|
||||
|
||||
void Game::SetLoadOrder(const std::list<std::string>& loadOrder) const {
|
||||
@@ -792,7 +686,8 @@ namespace loot {
|
||||
BOOST_LOG_TRIVIAL(info) << "Found plugin: " << pluginPair.first;
|
||||
|
||||
//Insert the lowercased name as a key for case-insensitive matching.
|
||||
auto plugin = plugins.insert(pair<string, Plugin>(boost::locale::to_lower(pluginPair.first), Plugin(pluginPair.first)));
|
||||
Plugin temp(pluginPair.first);
|
||||
auto plugin = plugins.insert(pair<string, Plugin>(boost::locale::to_lower(temp.Name()), temp));
|
||||
|
||||
if (pluginPair.second > meanFileSize) {
|
||||
BOOST_LOG_TRIVIAL(trace) << "Creating individual loading thread for: " << pluginPair.first;
|
||||
|
||||
@@ -104,6 +104,7 @@ namespace loot {
|
||||
//Game functions.
|
||||
Game(); //Sets game to LOOT_Game::autodetect, with all other vars being empty.
|
||||
Game(const unsigned int baseGameCode, const std::string& lootFolder = "");
|
||||
~Game();
|
||||
|
||||
Game& SetDetails(const std::string& name, const std::string& masterFile,
|
||||
const std::string& repositoryURL, const std::string& repositoryBranch,
|
||||
@@ -174,8 +175,12 @@ namespace loot {
|
||||
|
||||
std::unordered_set<std::string> activePlugins; //Holds lowercased strings.
|
||||
|
||||
lo_game_handle gh;
|
||||
|
||||
//Creates directory in LOOT folder for LOOT's game-specific files.
|
||||
void CreateLOOTGameFolder();
|
||||
|
||||
void InitLibloHandle();
|
||||
};
|
||||
|
||||
std::vector<Game> GetGames(YAML::Node& settings);
|
||||
|
||||
Reference in New Issue
Block a user