diff --git a/include/gamedetails.h b/include/gamedetails.h index 4ef052a..f0af033 100644 --- a/include/gamedetails.h +++ b/include/gamedetails.h @@ -4,6 +4,7 @@ #include "globalconstants.h" #include "gamefile.h" #include "config.h" +#include "util.h" #include #include @@ -23,7 +24,7 @@ class gameDetails std::string icon; std::string serials; void filterWithPriorities(const Config& config); - void makeFilepaths(const Config& config); + void makeFilepaths(const gameSpecificDirectoryConfig& config); std::string getSerialsFilepath(); Json::Value getDetailsAsJson(); virtual ~gameDetails(); diff --git a/include/util.h b/include/util.h index d8d2813..c289288 100644 --- a/include/util.h +++ b/include/util.h @@ -20,12 +20,25 @@ #include #include +struct gameSpecificDirectoryConfig +{ + bool bSubDirectories; + std::string sDirectory; + std::string sGameSubdir; + std::string sInstallersSubdir; + std::string sExtrasSubdir; + std::string sPatchesSubdir; + std::string sLanguagePackSubdir; + std::string sDLCSubdir; +}; + struct gameSpecificConfig { unsigned int iInstallerPlatform; unsigned int iInstallerLanguage; bool bDLC; bool bIgnoreDLCCount; + gameSpecificDirectoryConfig dirConf; }; namespace Util diff --git a/man/lgogdownloader.supplemental.groff b/man/lgogdownloader.supplemental.groff index 22423a0..e0eed30 100644 --- a/man/lgogdownloader.supplemental.groff +++ b/man/lgogdownloader.supplemental.groff @@ -70,17 +70,25 @@ It doesn't have to exist, but if it does exist, it must be readable to lgogdownl \fI$XDG_CONFIG_HOME/lgogdownloader/gamespecific/gamename.conf\fP JSON formatted file. Sets game specific settings for \fBgamename\fP. .br -Allowed settings are \fBlanguage\fP, \fBplatform\fP, \fBdlc\fP and \fBignore-dlc-count\fP. +Allowed settings are \fBlanguage\fP, \fBplatform\fP, \fBdlc\fP, \fBignore-dlc-count\fP \fBsubdirectories\fP, \fBdirectory\fP, \fBsubdir-game\fP, \fBsubdir-installers\fP, \fBsubdir-extras\fP, \fBsubdir-patches\fP, \fBsubdir-language-packs\fP and \fBsubdir-dlc\fP. .br The \fBdlc\fP option is limited to disabling DLC for specific game. It can't enable DLC listing/downloading if \fB--no-dlc\fP option is used. .br Must be in the following format: .br { - "language" : , - "platform" : , + "language" : , + "platform" : , "dlc" : , - "ignore-dlc-count" : + "ignore-dlc-count" : , + "subdirectories" : , + "directory" : , + "subdir-game" : , + "subdir-installers" : , + "subdir-extras" : , + "subdir-patches" : , + "subdir-language-packs" : , + "subdir-dlc" : .br } diff --git a/src/downloader.cpp b/src/downloader.cpp index 25289d5..319bde1 100644 --- a/src/downloader.cpp +++ b/src/downloader.cpp @@ -211,6 +211,16 @@ void Downloader::getGameList() */ int Downloader::getGameDetails() { + // Set default game specific directory options to values from config + gameSpecificDirectoryConfig dirConfDefault; + dirConfDefault.sDirectory = config.sDirectory; + dirConfDefault.bSubDirectories = config.bSubDirectories; + dirConfDefault.sGameSubdir = config.sGameSubdir; + dirConfDefault.sInstallersSubdir = config.sInstallersSubdir; + dirConfDefault.sExtrasSubdir = config.sExtrasSubdir; + dirConfDefault.sLanguagePackSubdir = config.sLanguagePackSubdir; + dirConfDefault.sDLCSubdir = config.sDLCSubdir; + if (config.bUseCache && !config.bUpdateCache) { // GameRegex filter alias for all games @@ -223,7 +233,12 @@ int Downloader::getGameDetails() if (result == 0) { for (unsigned int i = 0; i < this->games.size(); ++i) - this->games[i].makeFilepaths(config); + { + gameSpecificConfig conf; + conf.dirConf = dirConfDefault; + Util::getGameSpecificConfig(games[i].gamename, &conf); + this->games[i].makeFilepaths(conf.dirConf); + } return 0; } else @@ -254,10 +269,12 @@ int Downloader::getGameDetails() conf.bIgnoreDLCCount = false; conf.iInstallerLanguage = config.iInstallerLanguage; conf.iInstallerPlatform = config.iInstallerPlatform; + conf.dirConf = dirConfDefault; if (!config.bUpdateCache) // Disable game specific config files for cache update { - if (Util::getGameSpecificConfig(gameItems[i].name, &conf) > 0) - std::cout << std::endl << gameItems[i].name << " - Language: " << conf.iInstallerLanguage << ", Platform: " << conf.iInstallerPlatform << ", DLC: " << (conf.bDLC ? "true" : "false") << ", Ignore DLC count: " << (conf.bIgnoreDLCCount ? "true" : "false") << std::endl; + int iOptionsOverridden = Util::getGameSpecificConfig(gameItems[i].name, &conf); + if (iOptionsOverridden > 0) + std::cout << std::endl << gameItems[i].name << " - " << iOptionsOverridden << " options overridden with game specific options" << std::endl; } game = gogAPI->getGameDetails(gameItems[i].name, conf.iInstallerPlatform, conf.iInstallerLanguage, config.bDuplicateHandler); @@ -346,7 +363,7 @@ int Downloader::getGameDetails() } } - game.makeFilepaths(config); + game.makeFilepaths(conf.dirConf); if (!config.bUpdateCheck) games.push_back(game); diff --git a/src/gamedetails.cpp b/src/gamedetails.cpp index 5e57777..0224910 100644 --- a/src/gamedetails.cpp +++ b/src/gamedetails.cpp @@ -1,5 +1,4 @@ #include "gamedetails.h" -#include "util.h" gameDetails::gameDetails() { @@ -66,7 +65,7 @@ void gameDetails::filterListWithPriorities(std::vector& list, const Co } } -void gameDetails::makeFilepaths(const Config& config) +void gameDetails::makeFilepaths(const gameSpecificDirectoryConfig& config) { std::string filepath; std::string directory = config.sDirectory + "/" + config.sGameSubdir + "/"; diff --git a/src/util.cpp b/src/util.cpp index fcfb93e..c82f1a7 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -240,12 +240,36 @@ int Util::getGameSpecificConfig(std::string gamename, gameSpecificConfig* conf, { if (root.isMember("language")) { - conf->iInstallerLanguage = root["language"].asUInt(); + unsigned int language = 0; + if (root["language"].isInt()) + language = root["language"].asUInt(); + else + { + std::vector tokens = Util::tokenize(root["language"].asString(), "+"); + for (std::vector::iterator it = tokens.begin(); it != tokens.end(); it++) + { + language |= Util::getOptionValue(*it, GlobalConstants::LANGUAGES); + } + } + + conf->iInstallerLanguage = language; res++; } if (root.isMember("platform")) { - conf->iInstallerPlatform = root["platform"].asUInt(); + unsigned int platform = 0; + if (root["platform"].isInt()) + platform = root["platform"].asUInt(); + else + { + std::vector tokens = Util::tokenize(root["platform"].asString(), "+"); + for (std::vector::iterator it = tokens.begin(); it != tokens.end(); it++) + { + platform |= Util::getOptionValue(*it, GlobalConstants::PLATFORMS); + } + } + + conf->iInstallerPlatform = platform; res++; } if (root.isMember("dlc")) @@ -258,10 +282,50 @@ int Util::getGameSpecificConfig(std::string gamename, gameSpecificConfig* conf, conf->bIgnoreDLCCount = root["ignore-dlc-count"].asBool(); res++; } + if (root.isMember("subdirectories")) + { + conf->dirConf.bSubDirectories = root["subdirectories"].asBool(); + res++; + } + if (root.isMember("directory")) + { + conf->dirConf.sDirectory = root["directory"].asString(); + res++; + } + if (root.isMember("subdir-game")) + { + conf->dirConf.sGameSubdir = root["subdir-game"].asString(); + res++; + } + if (root.isMember("subdir-installers")) + { + conf->dirConf.sInstallersSubdir = root["subdir-installers"].asString(); + res++; + } + if (root.isMember("subdir-extras")) + { + conf->dirConf.sExtrasSubdir = root["subdir-extras"].asString(); + res++; + } + if (root.isMember("subdir-patches")) + { + conf->dirConf.sPatchesSubdir = root["subdir-patches"].asString(); + res++; + } + if (root.isMember("subdir-language-packs")) + { + conf->dirConf.sLanguagePackSubdir = root["subdir-language-packs"].asString(); + res++; + } + if (root.isMember("subdir-dlc")) + { + conf->dirConf.sDLCSubdir = root["subdir-dlc"].asString(); + res++; + } } else { - std::cout << "Failed to parse game specific config" << std::endl; + std::cout << "Failed to parse game specific config " << filepath << std::endl; std::cout << jsonparser->getFormattedErrorMessages() << std::endl; } delete jsonparser;