mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Refactor load order interaction into a separate class.
The Game class now inherits from the LoadOrderHandler class too.
This commit is contained in:
@@ -88,6 +88,7 @@ set (LOOT_SRC "${CMAKE_SOURCE_DIR}/src/backend/metadata/conditional_metadata.c
|
||||
"${CMAKE_SOURCE_DIR}/src/backend/metadata/tag.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/backend/game.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/backend/game_settings.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/backend/game/load_order_handler.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/backend/metadata_list.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/backend/masterlist.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/backend/plugin.cpp"
|
||||
@@ -111,6 +112,7 @@ set (LOOT_HEADERS "${CMAKE_SOURCE_DIR}/src/backend/metadata/condition_grammar.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/backend/metadata/tag.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/backend/game.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/backend/game_settings.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/backend/game/load_order_handler.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/backend/metadata_list.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/backend/masterlist.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/backend/plugin.h"
|
||||
|
||||
+9
-184
@@ -40,7 +40,7 @@ namespace fs = boost::filesystem;
|
||||
namespace lc = boost::locale;
|
||||
|
||||
namespace loot {
|
||||
Game::Game() : GameSettings(), gh(nullptr) {}
|
||||
Game::Game() {}
|
||||
|
||||
Game::Game(const GameSettings& gameSettings) : Game(gameSettings.Id(), gameSettings.FolderName()) {
|
||||
this->SetDetails(gameSettings.Name(),
|
||||
@@ -51,13 +51,9 @@ namespace loot {
|
||||
gameSettings.RegistryKey());
|
||||
}
|
||||
|
||||
Game::Game(const unsigned int gameCode, const std::string& folder) : GameSettings(gameCode, folder), gh(nullptr) {}
|
||||
Game::Game(const unsigned int gameCode, const std::string& folder) : GameSettings(gameCode, folder) {}
|
||||
|
||||
Game::~Game() {
|
||||
lo_destroy_handle(gh);
|
||||
}
|
||||
|
||||
Game& Game::Init(bool createFolder, const boost::filesystem::path& gameLocalAppData) {
|
||||
void Game::Init(bool createFolder, const boost::filesystem::path& gameLocalAppData) {
|
||||
if (Id() != Game::tes4 && Id() != Game::tes5 && Id() != Game::fo3 && Id() != Game::fonv) {
|
||||
throw error(error::invalid_args, lc::translate("Invalid game ID supplied.").str());
|
||||
}
|
||||
@@ -69,17 +65,13 @@ namespace loot {
|
||||
throw error(error::path_not_found, lc::translate("Game path could not be detected.").str());
|
||||
}
|
||||
|
||||
// Set the path to the game's folder in %LOCALAPPDATA%.
|
||||
_gameLocalDataPath = gameLocalAppData;
|
||||
|
||||
InitLibloHandle();
|
||||
RefreshActivePluginsList();
|
||||
|
||||
if (createFolder) {
|
||||
CreateLOOTGameFolder();
|
||||
}
|
||||
|
||||
return *this;
|
||||
LoadOrderHandler::Init(*this, gameLocalAppData);
|
||||
|
||||
RefreshActivePluginsList();
|
||||
}
|
||||
|
||||
bool Game::operator == (const Game& rhs) const {
|
||||
@@ -94,181 +86,15 @@ namespace loot {
|
||||
return (boost::iequals(Name(), nameOrFolderName) || boost::iequals(FolderName(), nameOrFolderName));
|
||||
}
|
||||
|
||||
void Game::InitLibloHandle() {
|
||||
const char * gameLocalDataPath = nullptr;
|
||||
std::string localAppData = _gameLocalDataPath.string();
|
||||
if (!localAppData.empty())
|
||||
gameLocalDataPath = localAppData.c_str();
|
||||
|
||||
// If the handle has already been initialised, close it and open another.
|
||||
if (gh != nullptr) {
|
||||
lo_destroy_handle(gh);
|
||||
gh = nullptr;
|
||||
}
|
||||
|
||||
int ret;
|
||||
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_BAD_FILENAME && ret != LIBLO_WARN_INVALID_LIST && 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);
|
||||
}
|
||||
|
||||
if (Id() != Game::tes5) {
|
||||
ret = lo_set_game_master(gh, Master().c_str());
|
||||
if (ret != LIBLO_OK && ret != LIBLO_WARN_BAD_FILENAME && ret != LIBLO_WARN_INVALID_LIST && ret != LIBLO_WARN_LO_MISMATCH) {
|
||||
const char * e = nullptr;
|
||||
string err;
|
||||
lo_get_error_message(&e);
|
||||
lo_destroy_handle(gh);
|
||||
gh = nullptr;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Game::RefreshActivePluginsList() {
|
||||
BOOST_LOG_TRIVIAL(debug) << "Refreshing active plugins list for game: " << Name();
|
||||
|
||||
char ** pluginArr;
|
||||
size_t pluginArrSize;
|
||||
unsigned int ret = lo_get_active_plugins(gh, &pluginArr, &pluginArrSize);
|
||||
if (ret != LIBLO_OK && ret != LIBLO_WARN_BAD_FILENAME && ret != LIBLO_WARN_INVALID_LIST && 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 get the active plugins list. Details could not be fetched.";
|
||||
err = lc::translate("libloadorder failed to get the active plugins list. Details could not be fetched.").str();
|
||||
}
|
||||
else {
|
||||
BOOST_LOG_TRIVIAL(error) << "libloadorder failed to get the active plugins list. Details: " << e;
|
||||
err = lc::translate("libloadorder failed to get the active plugins list. Details:").str() + " " + e;
|
||||
}
|
||||
lo_cleanup();
|
||||
throw error(error::liblo_error, err);
|
||||
}
|
||||
|
||||
activePlugins.clear();
|
||||
for (size_t i = 0; i < pluginArrSize; ++i) {
|
||||
activePlugins.insert(boost::locale::to_lower(string(pluginArr[i])));
|
||||
}
|
||||
}
|
||||
|
||||
void Game::GetLoadOrder(std::list<std::string>& loadOrder) const {
|
||||
BOOST_LOG_TRIVIAL(debug) << "Getting load order for game: " << Name();
|
||||
|
||||
char ** pluginArr;
|
||||
size_t pluginArrSize;
|
||||
|
||||
unsigned int ret = lo_get_load_order(gh, &pluginArr, &pluginArrSize);
|
||||
if (ret != LIBLO_OK && ret != LIBLO_WARN_BAD_FILENAME && ret != LIBLO_WARN_INVALID_LIST && 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 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;
|
||||
err = lc::translate("libloadorder failed to get the load order. Details:").str() + " " + e;
|
||||
}
|
||||
lo_cleanup();
|
||||
throw error(error::liblo_error, err);
|
||||
}
|
||||
|
||||
loadOrder.clear();
|
||||
for (size_t i = 0; i < pluginArrSize; ++i) {
|
||||
loadOrder.push_back(string(pluginArr[i]));
|
||||
}
|
||||
}
|
||||
|
||||
void Game::SetLoadOrder(const char * const * const loadOrder, const size_t numPlugins) const {
|
||||
BOOST_LOG_TRIVIAL(debug) << "Setting load order for game: " << Name();
|
||||
|
||||
unsigned int ret = lo_set_load_order(gh, loadOrder, numPlugins);
|
||||
if (ret != LIBLO_OK && ret != LIBLO_WARN_BAD_FILENAME && ret != LIBLO_WARN_INVALID_LIST && 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 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();
|
||||
}
|
||||
else {
|
||||
BOOST_LOG_TRIVIAL(error) << "libloadorder failed to set the load order. Details: " << e;
|
||||
err = lc::translate("libloadorder failed to set the load order. Details:").str() + " " + e;
|
||||
}
|
||||
lo_cleanup();
|
||||
throw error(error::liblo_error, err);
|
||||
}
|
||||
}
|
||||
|
||||
void Game::SetLoadOrder(const std::list<std::string>& loadOrder) const {
|
||||
BOOST_LOG_TRIVIAL(info) << "Setting load order:";
|
||||
size_t pluginArrSize = loadOrder.size();
|
||||
char ** pluginArr = new char*[pluginArrSize];
|
||||
int i = 0;
|
||||
for (const auto &plugin : loadOrder) {
|
||||
BOOST_LOG_TRIVIAL(info) << '\t' << '\t' << plugin;
|
||||
pluginArr[i] = new char[plugin.length() + 1];
|
||||
strcpy(pluginArr[i], plugin.c_str());
|
||||
++i;
|
||||
}
|
||||
|
||||
try {
|
||||
SetLoadOrder(pluginArr, pluginArrSize);
|
||||
}
|
||||
catch (error &/*e*/) {
|
||||
for (size_t i = 0; i < pluginArrSize; i++)
|
||||
delete[] pluginArr[i];
|
||||
delete[] pluginArr;
|
||||
throw;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < pluginArrSize; i++)
|
||||
delete[] pluginArr[i];
|
||||
delete[] pluginArr;
|
||||
activePlugins = GetActivePlugins();
|
||||
}
|
||||
|
||||
void Game::RedatePlugins() {
|
||||
if (Id() != tes5)
|
||||
return;
|
||||
|
||||
list<string> loadorder;
|
||||
GetLoadOrder(loadorder);
|
||||
|
||||
list<string> loadorder = GetLoadOrder();
|
||||
if (!loadorder.empty()) {
|
||||
time_t lastTime;
|
||||
fs::path filepath = DataPath() / *loadorder.begin();
|
||||
@@ -409,8 +235,7 @@ namespace loot {
|
||||
}
|
||||
|
||||
// Get the existing load order.
|
||||
list<string> loadorder;
|
||||
GetLoadOrder(loadorder);
|
||||
list<string> loadorder = GetLoadOrder();
|
||||
BOOST_LOG_TRIVIAL(info) << "Fetched existing load order: ";
|
||||
for (const auto &plugin : loadorder)
|
||||
BOOST_LOG_TRIVIAL(info) << plugin;
|
||||
|
||||
+3
-12
@@ -26,6 +26,7 @@
|
||||
#define __LOOT_GAME__
|
||||
|
||||
#include "game_settings.h"
|
||||
#include "game/load_order_handler.h"
|
||||
#include "plugin.h"
|
||||
#include "metadata_list.h"
|
||||
#include "masterlist.h"
|
||||
@@ -43,24 +44,20 @@
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
namespace loot {
|
||||
class Game : public GameSettings {
|
||||
class Game : public GameSettings, public LoadOrderHandler {
|
||||
public:
|
||||
//Game functions.
|
||||
Game(); //Sets game to LOOT_Game::autodetect, with all other vars being empty.
|
||||
Game(const GameSettings& gameSettings);
|
||||
Game(const unsigned int baseGameCode, const std::string& lootFolder = "");
|
||||
~Game();
|
||||
|
||||
Game& Init(bool createFolder, const boost::filesystem::path& gameLocalAppData = "");
|
||||
void Init(bool createFolder, const boost::filesystem::path& gameLocalAppData = "");
|
||||
|
||||
//Compare names and folder names.
|
||||
bool operator == (const Game& rhs) const;
|
||||
bool operator == (const GameSettings& rhs) const;
|
||||
bool operator == (const std::string& nameOrFolderName) const;
|
||||
|
||||
void GetLoadOrder(std::list<std::string>& loadOrder) const;
|
||||
void SetLoadOrder(const std::list<std::string>& loadOrder) const; //Modifies game load order, even though const.
|
||||
void SetLoadOrder(const char * const * const loadOrder, const size_t numPlugins) const; // For API.
|
||||
void RefreshActivePluginsList();
|
||||
void RedatePlugins(); //Change timestamps to match load order (Skyrim only).
|
||||
|
||||
@@ -77,12 +74,6 @@ namespace loot {
|
||||
Masterlist masterlist;
|
||||
MetadataList userlist;
|
||||
std::unordered_map<std::string, Plugin> plugins; //Map so that plugin data can be edited.
|
||||
private:
|
||||
boost::filesystem::path _gameLocalDataPath; // Path to the game's folder in %LOCALAPPDATA%.
|
||||
|
||||
lo_game_handle gh;
|
||||
|
||||
void InitLibloHandle();
|
||||
};
|
||||
|
||||
std::list<Game> ToGames(const std::list<GameSettings>& settings);
|
||||
|
||||
@@ -0,0 +1,224 @@
|
||||
/* LOOT
|
||||
|
||||
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
|
||||
Fallout: New Vegas.
|
||||
|
||||
Copyright (C) 2012-2015 WrinklyNinja
|
||||
|
||||
This file is part of LOOT.
|
||||
|
||||
LOOT 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.
|
||||
|
||||
LOOT 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 LOOT. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "load_order_handler.h"
|
||||
#include "../error.h"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/locale.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
namespace lc = boost::locale;
|
||||
|
||||
namespace loot {
|
||||
LoadOrderHandler::LoadOrderHandler() : _gh(nullptr) {}
|
||||
|
||||
LoadOrderHandler::~LoadOrderHandler() {
|
||||
lo_destroy_handle(_gh);
|
||||
}
|
||||
|
||||
void LoadOrderHandler::Init(const GameSettings& game, const boost::filesystem::path& gameLocalAppData) {
|
||||
if (game.Id() != GameSettings::tes4
|
||||
&& game.Id() != GameSettings::tes5
|
||||
&& game.Id() != GameSettings::fo3
|
||||
&& game.Id() != GameSettings::fonv) {
|
||||
throw error(error::invalid_args, lc::translate("Unsupported game ID supplied.").str());
|
||||
}
|
||||
|
||||
if (game.GamePath().empty()) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Game path is not initialised.";
|
||||
throw error(error::invalid_args, lc::translate("Game path is not initialised.").str());
|
||||
}
|
||||
|
||||
const char * gameLocalDataPath = nullptr;
|
||||
if (!gameLocalAppData.empty())
|
||||
gameLocalDataPath = gameLocalAppData.string().c_str();
|
||||
|
||||
// If the handle has already been initialised, close it and open another.
|
||||
if (_gh != nullptr) {
|
||||
lo_destroy_handle(_gh);
|
||||
_gh = nullptr;
|
||||
}
|
||||
|
||||
int ret;
|
||||
if (game.Id() == GameSettings::tes4)
|
||||
ret = lo_create_handle(&_gh, LIBLO_GAME_TES4, game.GamePath().string().c_str(), gameLocalDataPath);
|
||||
else if (game.Id() == GameSettings::tes5)
|
||||
ret = lo_create_handle(&_gh, LIBLO_GAME_TES5, game.GamePath().string().c_str(), gameLocalDataPath);
|
||||
else if (game.Id() == GameSettings::fo3)
|
||||
ret = lo_create_handle(&_gh, LIBLO_GAME_FO3, game.GamePath().string().c_str(), gameLocalDataPath);
|
||||
else if (game.Id() == GameSettings::fonv)
|
||||
ret = lo_create_handle(&_gh, LIBLO_GAME_FNV, game.GamePath().string().c_str(), gameLocalDataPath);
|
||||
else
|
||||
ret = LIBLO_ERROR_INVALID_ARGS;
|
||||
|
||||
if (ret != LIBLO_OK && ret != LIBLO_WARN_BAD_FILENAME && ret != LIBLO_WARN_INVALID_LIST && 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);
|
||||
}
|
||||
|
||||
if (game.Id() != GameSettings::tes5) {
|
||||
ret = lo_set_game_master(_gh, game.Master().c_str());
|
||||
if (ret != LIBLO_OK && ret != LIBLO_WARN_BAD_FILENAME && ret != LIBLO_WARN_INVALID_LIST && ret != LIBLO_WARN_LO_MISMATCH) {
|
||||
const char * e = nullptr;
|
||||
string err;
|
||||
lo_get_error_message(&e);
|
||||
lo_destroy_handle(_gh);
|
||||
_gh = nullptr;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::unordered_set<std::string> LoadOrderHandler::GetActivePlugins() const {
|
||||
BOOST_LOG_TRIVIAL(debug) << "Getting active plugins.";
|
||||
|
||||
char ** pluginArr;
|
||||
size_t pluginArrSize;
|
||||
unsigned int ret = lo_get_active_plugins(_gh, &pluginArr, &pluginArrSize);
|
||||
if (ret != LIBLO_OK && ret != LIBLO_WARN_BAD_FILENAME && ret != LIBLO_WARN_INVALID_LIST && 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 get the active plugins list. Details could not be fetched.";
|
||||
err = lc::translate("libloadorder failed to get the active plugins list. Details could not be fetched.").str();
|
||||
}
|
||||
else {
|
||||
BOOST_LOG_TRIVIAL(error) << "libloadorder failed to get the active plugins list. Details: " << e;
|
||||
err = lc::translate("libloadorder failed to get the active plugins list. Details:").str() + " " + e;
|
||||
}
|
||||
lo_cleanup();
|
||||
throw error(error::liblo_error, err);
|
||||
}
|
||||
|
||||
std::unordered_set<std::string> activePlugins;
|
||||
for (size_t i = 0; i < pluginArrSize; ++i) {
|
||||
activePlugins.insert(boost::locale::to_lower(string(pluginArr[i])));
|
||||
}
|
||||
return activePlugins;
|
||||
}
|
||||
|
||||
std::list<std::string> LoadOrderHandler::GetLoadOrder() const {
|
||||
BOOST_LOG_TRIVIAL(debug) << "Getting load order.";
|
||||
|
||||
char ** pluginArr;
|
||||
size_t pluginArrSize;
|
||||
|
||||
unsigned int ret = lo_get_load_order(_gh, &pluginArr, &pluginArrSize);
|
||||
if (ret != LIBLO_OK && ret != LIBLO_WARN_BAD_FILENAME && ret != LIBLO_WARN_INVALID_LIST && 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 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;
|
||||
err = lc::translate("libloadorder failed to get the load order. Details:").str() + " " + e;
|
||||
}
|
||||
lo_cleanup();
|
||||
throw error(error::liblo_error, err);
|
||||
}
|
||||
|
||||
std::list<std::string> loadOrder;
|
||||
for (size_t i = 0; i < pluginArrSize; ++i) {
|
||||
loadOrder.push_back(string(pluginArr[i]));
|
||||
}
|
||||
return loadOrder;
|
||||
}
|
||||
|
||||
void LoadOrderHandler::SetLoadOrder(const char * const * const loadOrder, const size_t numPlugins) const {
|
||||
BOOST_LOG_TRIVIAL(debug) << "Setting load order.";
|
||||
|
||||
unsigned int ret = lo_set_load_order(_gh, loadOrder, numPlugins);
|
||||
if (ret != LIBLO_OK && ret != LIBLO_WARN_BAD_FILENAME && ret != LIBLO_WARN_INVALID_LIST && 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 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();
|
||||
}
|
||||
else {
|
||||
BOOST_LOG_TRIVIAL(error) << "libloadorder failed to set the load order. Details: " << e;
|
||||
err = lc::translate("libloadorder failed to set the load order. Details:").str() + " " + e;
|
||||
}
|
||||
lo_cleanup();
|
||||
throw error(error::liblo_error, err);
|
||||
}
|
||||
}
|
||||
|
||||
void LoadOrderHandler::SetLoadOrder(const std::list<std::string>& loadOrder) const {
|
||||
BOOST_LOG_TRIVIAL(info) << "Setting load order.";
|
||||
size_t pluginArrSize = loadOrder.size();
|
||||
char ** pluginArr = new char*[pluginArrSize];
|
||||
int i = 0;
|
||||
for (const auto &plugin : loadOrder) {
|
||||
BOOST_LOG_TRIVIAL(info) << '\t' << '\t' << plugin;
|
||||
pluginArr[i] = new char[plugin.length() + 1];
|
||||
strcpy(pluginArr[i], plugin.c_str());
|
||||
++i;
|
||||
}
|
||||
|
||||
try {
|
||||
SetLoadOrder(pluginArr, pluginArrSize);
|
||||
}
|
||||
catch (error &/*e*/) {
|
||||
for (size_t i = 0; i < pluginArrSize; i++)
|
||||
delete[] pluginArr[i];
|
||||
delete[] pluginArr;
|
||||
throw;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < pluginArrSize; i++)
|
||||
delete[] pluginArr[i];
|
||||
delete[] pluginArr;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/* LOOT
|
||||
|
||||
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
|
||||
Fallout: New Vegas.
|
||||
|
||||
Copyright (C) 2012-2015 WrinklyNinja
|
||||
|
||||
This file is part of LOOT.
|
||||
|
||||
LOOT 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.
|
||||
|
||||
LOOT 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 LOOT. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __LOOT_LOAD_ORDER_HANDLER__
|
||||
#define __LOOT_LOAD_ORDER_HANDLER__
|
||||
|
||||
#include "../game_settings.h"
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <unordered_set>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include <api/libloadorder.h>
|
||||
|
||||
namespace loot {
|
||||
class LoadOrderHandler {
|
||||
public:
|
||||
LoadOrderHandler();
|
||||
~LoadOrderHandler();
|
||||
|
||||
void Init(const GameSettings& game, const boost::filesystem::path& gameLocalAppData = "");
|
||||
|
||||
std::unordered_set<std::string> GetActivePlugins() const;
|
||||
std::list<std::string> GetLoadOrder() const;
|
||||
|
||||
//These modify game load order, even though const.
|
||||
void SetLoadOrder(const char * const * const loadOrder, const size_t numPlugins) const; // For API.
|
||||
void SetLoadOrder(const std::list<std::string>& loadOrder) const;
|
||||
private:
|
||||
lo_game_handle _gh;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
+1
-2
@@ -636,8 +636,7 @@ namespace loot {
|
||||
|
||||
//Sort plugins into their load order.
|
||||
list<loot::Plugin> installed;
|
||||
list<string> loadOrder;
|
||||
_lootState.CurrentGame().GetLoadOrder(loadOrder);
|
||||
list<string> loadOrder = _lootState.CurrentGame().GetLoadOrder();
|
||||
for (const auto &pluginName : loadOrder) {
|
||||
const auto pos = _lootState.CurrentGame().plugins.find(boost::locale::to_lower(pluginName));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user