From 7abe1b15f1816c5193026443fbbd376a32ff3d47 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Fri, 27 Jan 2017 08:25:55 +0000 Subject: [PATCH] Refactor a few methods from GameSettings to Game --- src/backend/game/game.cpp | 98 ++++++++++++++++++++- src/backend/game/game.h | 8 ++ src/backend/game/game_settings.cpp | 92 ------------------- src/backend/game/game_settings.h | 7 -- src/tests/backend/game/game_settings_test.h | 17 ---- src/tests/backend/game/game_test.h | 15 ++++ 6 files changed, 119 insertions(+), 118 deletions(-) diff --git a/src/backend/game/game.cpp b/src/backend/game/game.cpp index c3c2a0f3..274def4c 100644 --- a/src/backend/game/game.cpp +++ b/src/backend/game/game.cpp @@ -24,6 +24,7 @@ #include "backend/game/game.h" +#include #include #include @@ -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& 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& 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 } diff --git a/src/backend/game/game.h b/src/backend/game/game.h index 3415a66c..529fa7e8 100644 --- a/src/backend/game/game.h +++ b/src/backend/game/game.h @@ -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 GetLoadOrder() const; void SetLoadOrder(const std::vector& 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 loadOrder_; }; diff --git a/src/backend/game/game_settings.cpp b/src/backend/game/game_settings.cpp index 48fb0622..aab59bf3 100644 --- a/src/backend/game/game_settings.cpp +++ b/src/backend/game/game_settings.cpp @@ -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 { diff --git a/src/backend/game/game_settings.h b/src/backend/game/game_settings.h index 78b36b62..01e7802a 100644 --- a/src/backend/game/game_settings.h +++ b/src/backend/game/game_settings.h @@ -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 oldDefaultBranches; GameType type_; diff --git a/src/tests/backend/game/game_settings_test.h b/src/tests/backend/game/game_settings_test.h index abae48c9..8f253af4 100644 --- a/src/tests/backend/game/game_settings_test.h +++ b/src/tests/backend/game/game_settings_test.h @@ -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) { diff --git a/src/tests/backend/game/game_test.h b/src/tests/backend/game/game_test.h index 71f558fc..4395ff14 100644 --- a/src/tests/backend/game/game_test.h +++ b/src/tests/backend/game/game_test.h @@ -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