mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Refactor a few methods from GameSettings to Game
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "backend/game/game.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <thread>
|
||||
#include <cmath>
|
||||
|
||||
@@ -36,6 +37,19 @@
|
||||
#include "loot/exception/game_detection_error.h"
|
||||
#include "backend/helpers/helpers.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifndef UNICODE
|
||||
# define UNICODE
|
||||
# endif
|
||||
# ifndef _UNICODE
|
||||
# define _UNICODE
|
||||
# endif
|
||||
# define NOMINMAX
|
||||
# include "windows.h"
|
||||
# include "shlobj.h"
|
||||
# include "shlwapi.h"
|
||||
#endif
|
||||
|
||||
using std::list;
|
||||
using std::string;
|
||||
using std::thread;
|
||||
@@ -55,6 +69,34 @@ Game::Game(const GameSettings& gameSettings) : GameSettings(gameSettings), plugi
|
||||
|
||||
Game::Game(const GameType gameType, const std::string& folder) : GameSettings(gameType, folder), pluginsFullyLoaded_(false) {}
|
||||
|
||||
bool Game::IsInstalled() {
|
||||
try {
|
||||
BOOST_LOG_TRIVIAL(trace) << "Checking if game \"" << Name() << "\" is installed.";
|
||||
if (!GamePath().empty() && fs::exists(GamePath() / "Data" / Master()))
|
||||
return true;
|
||||
|
||||
if (fs::exists(fs::path("..") / "Data" / Master())) {
|
||||
SetGamePath("..");
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
std::string path;
|
||||
std::string key_parent = fs::path(RegistryKey()).parent_path().string();
|
||||
std::string key_name = fs::path(RegistryKey()).filename().string();
|
||||
path = RegKeyStringValue("HKEY_LOCAL_MACHINE", key_parent, key_name);
|
||||
if (!path.empty() && fs::exists(fs::path(path) / "Data" / Master())) {
|
||||
SetGamePath(path);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
} catch (std::exception &e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Error while checking if game \"" << Name() << "\" is installed: " << e.what();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Game::Init(bool createFolder, const boost::filesystem::path& gameLocalAppData) {
|
||||
BOOST_LOG_TRIVIAL(info) << "Initialising filesystem-related data for game: " << Name();
|
||||
|
||||
@@ -129,8 +171,8 @@ void Game::LoadPlugins(const std::vector<std::string>& plugins, bool headersOnly
|
||||
|
||||
// Get the number of threads to use.
|
||||
// hardware_concurrency() may be zero, if so then use only one thread.
|
||||
size_t threadsToUse = std::min((size_t)thread::hardware_concurrency(), sizeMap.size());
|
||||
threadsToUse = std::max(threadsToUse, (size_t)1);
|
||||
size_t threadsToUse = ::std::min((size_t)thread::hardware_concurrency(), sizeMap.size());
|
||||
threadsToUse = ::std::max(threadsToUse, (size_t)1);
|
||||
|
||||
// Divide the plugins up by thread.
|
||||
unsigned int pluginsPerThread = ceil((double)sizeMap.size() / threadsToUse);
|
||||
@@ -240,4 +282,56 @@ void Game::SetLoadOrder(const std::vector<std::string>& loadOrder) const {
|
||||
LoadOrderHandler::SetLoadOrder(loadOrder);
|
||||
loadOrder_ = loadOrder;
|
||||
}
|
||||
|
||||
fs::path Game::MasterlistPath() const {
|
||||
if (FolderName().empty())
|
||||
return "";
|
||||
else
|
||||
return LootPaths::getLootDataPath() / FolderName() / "masterlist.yaml";
|
||||
}
|
||||
|
||||
fs::path Game::UserlistPath() const {
|
||||
if (FolderName().empty())
|
||||
return "";
|
||||
else
|
||||
return LootPaths::getLootDataPath() / FolderName() / "userlist.yaml";
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
std::string Game::RegKeyStringValue(const std::string& keyStr, const std::string& subkey, const std::string& value) {
|
||||
HKEY hKey = NULL;
|
||||
DWORD len = MAX_PATH;
|
||||
std::wstring wstr(MAX_PATH, 0);
|
||||
|
||||
if (keyStr == "HKEY_CLASSES_ROOT")
|
||||
hKey = HKEY_CLASSES_ROOT;
|
||||
else if (keyStr == "HKEY_CURRENT_CONFIG")
|
||||
hKey = HKEY_CURRENT_CONFIG;
|
||||
else if (keyStr == "HKEY_CURRENT_USER")
|
||||
hKey = HKEY_CURRENT_USER;
|
||||
else if (keyStr == "HKEY_LOCAL_MACHINE")
|
||||
hKey = HKEY_LOCAL_MACHINE;
|
||||
else if (keyStr == "HKEY_USERS")
|
||||
hKey = HKEY_USERS;
|
||||
else
|
||||
throw std::invalid_argument("Invalid registry key given.");
|
||||
|
||||
BOOST_LOG_TRIVIAL(trace) << "Getting string for registry key, subkey and value: " << keyStr << " + " << subkey << " + " << value;
|
||||
LONG ret = RegGetValue(hKey,
|
||||
ToWinWide(subkey).c_str(),
|
||||
ToWinWide(value).c_str(),
|
||||
RRF_RT_REG_SZ | KEY_WOW64_32KEY,
|
||||
NULL,
|
||||
&wstr[0],
|
||||
&len);
|
||||
|
||||
if (ret == ERROR_SUCCESS) {
|
||||
BOOST_LOG_TRIVIAL(info) << "Found string: " << wstr.c_str();
|
||||
return FromWinWide(wstr.c_str()); // Passing c_str() cuts off any unused buffer.
|
||||
} else {
|
||||
BOOST_LOG_TRIVIAL(info) << "Failed to get string value.";
|
||||
return "";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ public:
|
||||
Game(const GameSettings& gameSettings);
|
||||
Game(const GameType gameType, const std::string& lootFolder = "");
|
||||
|
||||
bool IsInstalled(); //Sets gamePath if the current value is not valid and a valid path is found.
|
||||
void Init(bool createFolder, const boost::filesystem::path& gameLocalAppData = "");
|
||||
|
||||
void RedatePlugins(); //Change timestamps to match load order (Skyrim only).
|
||||
@@ -55,7 +56,14 @@ public:
|
||||
|
||||
std::vector<std::string> GetLoadOrder() const;
|
||||
void SetLoadOrder(const std::vector<std::string>& loadOrder) const;
|
||||
|
||||
boost::filesystem::path MasterlistPath() const;
|
||||
boost::filesystem::path UserlistPath() const;
|
||||
private:
|
||||
#ifdef _WIN32
|
||||
std::string RegKeyStringValue(const std::string& keyStr, const std::string& subkey, const std::string& value);
|
||||
#endif
|
||||
|
||||
bool pluginsFullyLoaded_;
|
||||
mutable std::vector<std::string> loadOrder_;
|
||||
};
|
||||
|
||||
@@ -31,18 +31,6 @@
|
||||
#include "backend/app/loot_paths.h"
|
||||
#include "backend/helpers/helpers.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifndef UNICODE
|
||||
# define UNICODE
|
||||
# endif
|
||||
# ifndef _UNICODE
|
||||
# define _UNICODE
|
||||
# endif
|
||||
# include "windows.h"
|
||||
# include "shlobj.h"
|
||||
# include "shlwapi.h"
|
||||
#endif
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace loot {
|
||||
@@ -97,34 +85,6 @@ GameSettings::GameSettings(const GameType gameCode, const std::string& folder) :
|
||||
lootFolderName_ = folder;
|
||||
}
|
||||
|
||||
bool GameSettings::IsInstalled() {
|
||||
try {
|
||||
BOOST_LOG_TRIVIAL(trace) << "Checking if game \"" << name_ << "\" is installed.";
|
||||
if (!gamePath_.empty() && fs::exists(gamePath_ / "Data" / masterFile_))
|
||||
return true;
|
||||
|
||||
if (fs::exists(fs::path("..") / "Data" / masterFile_)) {
|
||||
gamePath_ = "..";
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
std::string path;
|
||||
std::string key_parent = fs::path(registryKey_).parent_path().string();
|
||||
std::string key_name = fs::path(registryKey_).filename().string();
|
||||
path = RegKeyStringValue("HKEY_LOCAL_MACHINE", key_parent, key_name);
|
||||
if (!path.empty() && fs::exists(fs::path(path) / "Data" / masterFile_)) {
|
||||
gamePath_ = path;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
} catch (std::exception &e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Error while checking if game \"" << name_ << "\" is installed: " << e.what();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GameSettings::IsRepoBranchOldDefault() const {
|
||||
return oldDefaultBranches.count(repositoryBranch_) == 1;
|
||||
}
|
||||
@@ -185,20 +145,6 @@ fs::path GameSettings::DataPath() const {
|
||||
return gamePath_ / "Data";
|
||||
}
|
||||
|
||||
fs::path GameSettings::MasterlistPath() const {
|
||||
if (lootFolderName_.empty())
|
||||
return "";
|
||||
else
|
||||
return LootPaths::getLootDataPath() / lootFolderName_ / "masterlist.yaml";
|
||||
}
|
||||
|
||||
fs::path GameSettings::UserlistPath() const {
|
||||
if (lootFolderName_.empty())
|
||||
return "";
|
||||
else
|
||||
return LootPaths::getLootDataPath() / lootFolderName_ / "userlist.yaml";
|
||||
}
|
||||
|
||||
std::string GameSettings::GetArchiveFileExtension() const {
|
||||
if (type_ == GameType::fo4)
|
||||
return ".ba2";
|
||||
@@ -241,44 +187,6 @@ GameSettings& GameSettings::SetGamePath(const boost::filesystem::path& path) {
|
||||
gamePath_ = path;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
std::string GameSettings::RegKeyStringValue(const std::string& keyStr, const std::string& subkey, const std::string& value) {
|
||||
HKEY hKey = NULL;
|
||||
DWORD len = MAX_PATH;
|
||||
std::wstring wstr(MAX_PATH, 0);
|
||||
|
||||
if (keyStr == "HKEY_CLASSES_ROOT")
|
||||
hKey = HKEY_CLASSES_ROOT;
|
||||
else if (keyStr == "HKEY_CURRENT_CONFIG")
|
||||
hKey = HKEY_CURRENT_CONFIG;
|
||||
else if (keyStr == "HKEY_CURRENT_USER")
|
||||
hKey = HKEY_CURRENT_USER;
|
||||
else if (keyStr == "HKEY_LOCAL_MACHINE")
|
||||
hKey = HKEY_LOCAL_MACHINE;
|
||||
else if (keyStr == "HKEY_USERS")
|
||||
hKey = HKEY_USERS;
|
||||
else
|
||||
throw std::invalid_argument("Invalid registry key given.");
|
||||
|
||||
BOOST_LOG_TRIVIAL(trace) << "Getting string for registry key, subkey and value: " << keyStr << " + " << subkey << " + " << value;
|
||||
LONG ret = RegGetValue(hKey,
|
||||
ToWinWide(subkey).c_str(),
|
||||
ToWinWide(value).c_str(),
|
||||
RRF_RT_REG_SZ | KEY_WOW64_32KEY,
|
||||
NULL,
|
||||
&wstr[0],
|
||||
&len);
|
||||
|
||||
if (ret == ERROR_SUCCESS) {
|
||||
BOOST_LOG_TRIVIAL(info) << "Found string: " << wstr.c_str();
|
||||
return FromWinWide(wstr.c_str()); // Passing c_str() cuts off any unused buffer.
|
||||
} else {
|
||||
BOOST_LOG_TRIVIAL(info) << "Failed to get string value.";
|
||||
return "";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace YAML {
|
||||
|
||||
@@ -40,7 +40,6 @@ public:
|
||||
GameSettings();
|
||||
GameSettings(const GameType gameType, const std::string& lootFolder = "");
|
||||
|
||||
bool IsInstalled(); //Sets gamePath if the current value is not valid and a valid path is found.
|
||||
bool IsRepoBranchOldDefault() const;
|
||||
|
||||
bool operator == (const GameSettings& rhs) const; //Compares names and folder names.
|
||||
@@ -56,8 +55,6 @@ public:
|
||||
|
||||
boost::filesystem::path GamePath() const;
|
||||
boost::filesystem::path DataPath() const;
|
||||
boost::filesystem::path MasterlistPath() const;
|
||||
boost::filesystem::path UserlistPath() const;
|
||||
|
||||
std::string GetArchiveFileExtension() const;
|
||||
|
||||
@@ -69,10 +66,6 @@ public:
|
||||
GameSettings& SetGamePath(const boost::filesystem::path& path);
|
||||
|
||||
private:
|
||||
#ifdef _WIN32
|
||||
std::string RegKeyStringValue(const std::string& keyStr, const std::string& subkey, const std::string& value);
|
||||
#endif
|
||||
|
||||
static const std::set<std::string> oldDefaultBranches;
|
||||
|
||||
GameType type_;
|
||||
|
||||
@@ -57,8 +57,6 @@ TEST_P(GameSettingsTest, defaultConstructorShouldInitialiseIdToTes4AndAllOtherSe
|
||||
|
||||
EXPECT_EQ("", settings_.GamePath());
|
||||
EXPECT_EQ("", settings_.DataPath());
|
||||
EXPECT_EQ("", settings_.MasterlistPath());
|
||||
EXPECT_EQ("", settings_.UserlistPath());
|
||||
}
|
||||
|
||||
TEST_P(GameSettingsTest, idConstructorShouldInitialiseSettingsToDefaultsForThatGame) {
|
||||
@@ -75,27 +73,12 @@ TEST_P(GameSettingsTest, idConstructorShouldInitialiseSettingsToDefaultsForThatG
|
||||
|
||||
EXPECT_EQ("", settings_.GamePath());
|
||||
EXPECT_EQ("", settings_.DataPath());
|
||||
EXPECT_EQ(LootPaths::getLootDataPath() / "Skyrim" / "masterlist.yaml", settings_.MasterlistPath());
|
||||
EXPECT_EQ(LootPaths::getLootDataPath() / "Skyrim" / "userlist.yaml", settings_.UserlistPath());
|
||||
}
|
||||
|
||||
TEST_P(GameSettingsTest, idConstructorShouldSetGameFolderIfGiven) {
|
||||
settings_ = GameSettings(GameType::tes5, "folder");
|
||||
|
||||
EXPECT_EQ("folder", settings_.FolderName());
|
||||
EXPECT_EQ(LootPaths::getLootDataPath() / "folder" / "masterlist.yaml", settings_.MasterlistPath());
|
||||
EXPECT_EQ(LootPaths::getLootDataPath() / "folder" / "userlist.yaml", settings_.UserlistPath());
|
||||
}
|
||||
|
||||
TEST_P(GameSettingsTest, isInstalledShouldBeFalseIfGamePathIsNotSet) {
|
||||
GameSettings settings_;
|
||||
EXPECT_FALSE(settings_.IsInstalled());
|
||||
}
|
||||
|
||||
TEST_P(GameSettingsTest, isInstalledShouldBeTrueIfGamePathIsValid) {
|
||||
settings_ = GameSettings(GameType::tes5);
|
||||
settings_.SetGamePath(dataPath.parent_path());
|
||||
EXPECT_TRUE(settings_.IsInstalled());
|
||||
}
|
||||
|
||||
TEST_P(GameSettingsTest, isRepoBranchOldDefaultShouldBeTrueIfValueIsMaster) {
|
||||
|
||||
@@ -75,6 +75,8 @@ TEST_P(GameTest, constructingFromGameSettingsShouldUseTheirValues) {
|
||||
EXPECT_EQ(settings.RepoBranch(), game.RepoBranch());
|
||||
|
||||
EXPECT_EQ(settings.GamePath(), game.GamePath());
|
||||
EXPECT_EQ(LootPaths::getLootDataPath() / "folder" / "masterlist.yaml", game.MasterlistPath());
|
||||
EXPECT_EQ(LootPaths::getLootDataPath() / "folder" / "userlist.yaml", game.UserlistPath());
|
||||
}
|
||||
|
||||
TEST_P(GameTest, constructingFromIdAndFolderShouldPassThemToGameSettingsConstructor) {
|
||||
@@ -83,6 +85,19 @@ TEST_P(GameTest, constructingFromIdAndFolderShouldPassThemToGameSettingsConstruc
|
||||
|
||||
EXPECT_EQ(settings.Type(), game.Type());
|
||||
EXPECT_EQ(settings.FolderName(), game.FolderName());
|
||||
EXPECT_EQ(LootPaths::getLootDataPath() / "folder" / "masterlist.yaml", game.MasterlistPath());
|
||||
EXPECT_EQ(LootPaths::getLootDataPath() / "folder" / "userlist.yaml", game.UserlistPath());
|
||||
}
|
||||
|
||||
TEST_P(GameTest, isInstalledShouldBeFalseIfGamePathIsNotSet) {
|
||||
Game game = Game(GetParam());
|
||||
EXPECT_FALSE(game.IsInstalled());
|
||||
}
|
||||
|
||||
TEST_P(GameTest, isInstalledShouldBeTrueIfGamePathIsValid) {
|
||||
Game game = Game(GetParam());
|
||||
game.SetGamePath(dataPath.parent_path());
|
||||
EXPECT_TRUE(game.IsInstalled());
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
Reference in New Issue
Block a user