Refactor a few methods from GameSettings to Game

This commit is contained in:
Oliver Hamlet
2017-02-06 18:01:55 +00:00
parent e91ba5584a
commit 7abe1b15f1
6 changed files with 119 additions and 118 deletions
+96 -2
View File
@@ -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
}
+8
View File
@@ -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_;
};
-92
View File
@@ -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 {
-7
View File
@@ -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) {
+15
View File
@@ -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