diff --git a/include/config.h b/include/config.h index 252dc1e..85c5e67 100644 --- a/include/config.h +++ b/include/config.h @@ -49,12 +49,6 @@ struct DownloadConfig bool bAutomaticXMLCreation; bool bFreeSpaceCheck; - bool bInstallers; - bool bExtras; - bool bPatches; - bool bLanguagePacks; - bool bDLC; - bool bIgnoreDLCCount; bool bDuplicateHandler; bool bGalaxyDependencies; diff --git a/include/downloader.h b/include/downloader.h index 66e2f0d..c7c1afe 100644 --- a/include/downloader.h +++ b/include/downloader.h @@ -156,6 +156,7 @@ class Downloader template void printProgress(const ThreadSafeQueue& download_queue); static void getGameDetailsThread(Config config, const unsigned int& tid); void printGameDetailsAsText(gameDetails& game); + void printGameFileDetailsAsText(gameFile& gf); static int progressCallback(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow); static size_t writeData(void *ptr, size_t size, size_t nmemb, FILE *stream); diff --git a/include/gamedetails.h b/include/gamedetails.h index 4a47ac9..7637933 100644 --- a/include/gamedetails.h +++ b/include/gamedetails.h @@ -39,9 +39,11 @@ class gameDetails Json::Value getDetailsAsJson(); std::vector getGameFileVector(); std::vector getGameFileVectorFiltered(const unsigned int& iType); + void filterWithType(const unsigned int& iType); virtual ~gameDetails(); protected: void filterListWithPriorities(std::vector& list, const gameSpecificConfig& config); + void filterListWithType(std::vector& list, const unsigned int& iType); private: std::string serialsFilepath; std::string changelogFilepath; diff --git a/include/gamefile.h b/include/gamefile.h index 3c6ddd4..7e95359 100644 --- a/include/gamefile.h +++ b/include/gamefile.h @@ -14,13 +14,6 @@ #include #include -// Game file types -const unsigned int GFTYPE_INSTALLER = 1 << 0; -const unsigned int GFTYPE_EXTRA = 1 << 1; -const unsigned int GFTYPE_PATCH = 1 << 2; -const unsigned int GFTYPE_LANGPACK = 1 << 3; -const unsigned int GFTYPE_DLC = 1 << 4; - class gameFile { public: diff --git a/include/globalconstants.h b/include/globalconstants.h index 6b0f4e0..614c956 100644 --- a/include/globalconstants.h +++ b/include/globalconstants.h @@ -12,7 +12,7 @@ namespace GlobalConstants { - const int GAMEDETAILS_CACHE_VERSION = 4; + const int GAMEDETAILS_CACHE_VERSION = 5; const int ZLIB_WINDOW_SIZE = 15; struct optionsStruct {const unsigned int id; const std::string code; const std::string str; const std::string regexp;}; @@ -132,6 +132,41 @@ namespace GlobalConstants { LIST_FORMAT_TAGS, "tags", "Tags", "t|tags" }, { LIST_FORMAT_TRANSFORMATIONS, "transform", "Transformations", "tr|transform|transformations" } }; + + const unsigned int GFTYPE_BASE_INSTALLER = 1 << 0; + const unsigned int GFTYPE_BASE_EXTRA = 1 << 1; + const unsigned int GFTYPE_BASE_PATCH = 1 << 2; + const unsigned int GFTYPE_BASE_LANGPACK = 1 << 3; + const unsigned int GFTYPE_DLC_INSTALLER = 1 << 4; + const unsigned int GFTYPE_DLC_EXTRA = 1 << 5; + const unsigned int GFTYPE_DLC_PATCH = 1 << 6; + const unsigned int GFTYPE_DLC_LANGPACK = 1 << 7; + const unsigned int GFTYPE_DLC = GFTYPE_DLC_INSTALLER | GFTYPE_DLC_EXTRA | + GFTYPE_DLC_PATCH | GFTYPE_DLC_LANGPACK; + const unsigned int GFTYPE_BASE = GFTYPE_BASE_INSTALLER | GFTYPE_BASE_EXTRA | + GFTYPE_BASE_PATCH | GFTYPE_BASE_LANGPACK; + const unsigned int GFTYPE_INSTALLER = GFTYPE_BASE_INSTALLER | GFTYPE_DLC_INSTALLER; + const unsigned int GFTYPE_EXTRA = GFTYPE_BASE_EXTRA | GFTYPE_DLC_EXTRA; + const unsigned int GFTYPE_PATCH = GFTYPE_BASE_PATCH | GFTYPE_DLC_PATCH; + const unsigned int GFTYPE_LANGPACK = GFTYPE_BASE_LANGPACK | GFTYPE_DLC_LANGPACK; + + const std::vector INCLUDE_OPTIONS = + { + { GFTYPE_BASE_INSTALLER, "bi", "Base game installers", "bi|basegame_installers" }, + { GFTYPE_BASE_EXTRA, "be", "Base game extras", "be|basegame_extras" }, + { GFTYPE_BASE_PATCH, "bp", "Base game patches", "bp|basegame_patches" }, + { GFTYPE_BASE_LANGPACK, "bl", "Base game language packs", "bl|basegame_languagepacks|basegame_langpacks" }, + { GFTYPE_DLC_INSTALLER, "di", "DLC installers", "di|dlc_installers" }, + { GFTYPE_DLC_EXTRA, "de", "DLC extras", "de|dlc_extras" }, + { GFTYPE_DLC_PATCH, "dp", "DLC patches", "dp|dlc_patches" }, + { GFTYPE_DLC_LANGPACK, "dl", "DLC language packs", "dl|dlc_languagepacks|dlc_langpacks" }, + { GFTYPE_DLC, "d", "DLCs", "d|dlc|dlcs" }, + { GFTYPE_BASE, "b", "Basegame", "b|bg|basegame" }, + { GFTYPE_INSTALLER, "i", "All installers", "i|installers" }, + { GFTYPE_EXTRA, "e", "All extras", "e|extras" }, + { GFTYPE_PATCH, "p", "All patches", "p|patches" }, + { GFTYPE_LANGPACK, "l", "All language packs", "l|languagepacks|langpacks" } + }; } #endif // GLOBALCONSTANTS_H_INCLUDED diff --git a/main.cpp b/main.cpp index 6ec5515..d83ad09 100644 --- a/main.cpp +++ b/main.cpp @@ -47,25 +47,6 @@ int main(int argc, char *argv[]) rhash_library_init(); - // Constants for option selection with include/exclude - /* TODO: Add options to give better control for user - For example: option to select base game and DLC installers separately, - this requires some changes to Downloader class to implement */ - const unsigned int OPTION_INSTALLERS = 1 << 0; - const unsigned int OPTION_EXTRAS = 1 << 1; - const unsigned int OPTION_PATCHES = 1 << 2; - const unsigned int OPTION_LANGPACKS = 1 << 3; - const unsigned int OPTION_DLCS = 1 << 4; - - const std::vector INCLUDE_OPTIONS = - { - { OPTION_INSTALLERS, "i", "Installers", "i|installers" }, - { OPTION_EXTRAS, "e", "Extras", "e|extras" }, - { OPTION_PATCHES, "p", "Patches", "p|patches" }, - { OPTION_LANGPACKS, "l", "Language packs", "l|languagepacks|langpacks" }, - { OPTION_DLCS, "d", "DLCs", "d|dlc|dlcs" } - }; - Globals::globalConfig.sVersionString = VERSION_STRING; Globals::globalConfig.sVersionNumber = VERSION_NUMBER; Globals::globalConfig.curlConf.sUserAgent = DEFAULT_USER_AGENT; @@ -156,10 +137,11 @@ int main(int argc, char *argv[]) // Help text for include and exclude options std::string include_options_text; - for (unsigned int i = 0; i < INCLUDE_OPTIONS.size(); ++i) + for (unsigned int i = 0; i < GlobalConstants::INCLUDE_OPTIONS.size(); ++i) { - include_options_text += INCLUDE_OPTIONS[i].str + " = " + INCLUDE_OPTIONS[i].regexp + "\n"; + include_options_text += GlobalConstants::INCLUDE_OPTIONS[i].str + " = " + GlobalConstants::INCLUDE_OPTIONS[i].regexp + "\n"; } + include_options_text += "All = all"; include_options_text += "Separate with \",\" to use multiple values"; // Create help text for --list-format option @@ -576,22 +558,14 @@ int main(int argc, char *argv[]) std::vector vExclude = Util::tokenize(sExcludeOptions, ","); for (std::vector::iterator it = vInclude.begin(); it != vInclude.end(); it++) { - include_value |= Util::getOptionValue(*it, INCLUDE_OPTIONS); + include_value |= Util::getOptionValue(*it, GlobalConstants::INCLUDE_OPTIONS); } for (std::vector::iterator it = vExclude.begin(); it != vExclude.end(); it++) { - exclude_value |= Util::getOptionValue(*it, INCLUDE_OPTIONS); + exclude_value |= Util::getOptionValue(*it, GlobalConstants::INCLUDE_OPTIONS); } Globals::globalConfig.dlConf.iInclude = include_value & ~exclude_value; - // Assign values - // TODO: Use config.iInclude in Downloader class directly and get rid of this value assignment - Globals::globalConfig.dlConf.bInstallers = (Globals::globalConfig.dlConf.iInclude & OPTION_INSTALLERS); - Globals::globalConfig.dlConf.bExtras = (Globals::globalConfig.dlConf.iInclude & OPTION_EXTRAS); - Globals::globalConfig.dlConf.bPatches = (Globals::globalConfig.dlConf.iInclude & OPTION_PATCHES); - Globals::globalConfig.dlConf.bLanguagePacks = (Globals::globalConfig.dlConf.iInclude & OPTION_LANGPACKS); - Globals::globalConfig.dlConf.bDLC = (Globals::globalConfig.dlConf.iInclude & OPTION_DLCS); - Globals::globalConfig.iListFormat = Util::getOptionValue(sListFormat, GlobalConstants::LIST_FORMAT, false); } catch (std::exception& e) diff --git a/man/lgogdownloader.supplemental.groff b/man/lgogdownloader.supplemental.groff index 34921da..05a9851 100644 --- a/man/lgogdownloader.supplemental.groff +++ b/man/lgogdownloader.supplemental.groff @@ -87,16 +87,14 @@ If the file exists lgogdownloader uses it instead of list specified with \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, \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. +Allowed settings are \fBlanguage\fP, \fBplatform\fP, \fBinclude\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 Must be in the following format: .br { "language" : , "platform" : , - "dlc" : , + "include" : , "ignore-dlc-count" : , "subdirectories" : , "directory" : , diff --git a/src/downloader.cpp b/src/downloader.cpp index 5aed242..d66d3f7 100644 --- a/src/downloader.cpp +++ b/src/downloader.cpp @@ -599,17 +599,10 @@ void Downloader::repair() gameSpecificConfig conf; conf.dlConf = Globals::globalConfig.dlConf; conf.dirConf = Globals::globalConfig.dirConf; + Util::getGameSpecificConfig(vGameFiles[i].gamename, &conf); unsigned int type = vGameFiles[i].type; - if (!conf.dlConf.bDLC && (type & GFTYPE_DLC)) - continue; - if (!conf.dlConf.bInstallers && (type & GFTYPE_INSTALLER)) - continue; - if (!conf.dlConf.bExtras && (type & GFTYPE_EXTRA)) - continue; - if (!conf.dlConf.bPatches && (type & GFTYPE_PATCH)) - continue; - if (!conf.dlConf.bLanguagePacks && (type & GFTYPE_LANGPACK)) + if (!(type & conf.dlConf.iInclude)) continue; std::string filepath = vGameFiles[i].getFilepath(); @@ -658,7 +651,7 @@ void Downloader::repair() bool bUseLocalXML = !conf.dlConf.bRemoteXML; // Use local XML data for extras - if (XML.empty() && (type & GFTYPE_EXTRA)) + if (XML.empty() && (type & GlobalConstants::GFTYPE_EXTRA)) bUseLocalXML = true; if (!XML.empty() || bUseLocalXML) @@ -682,6 +675,7 @@ void Downloader::download() gameSpecificConfig conf; conf.dlConf = Globals::globalConfig.dlConf; conf.dirConf = Globals::globalConfig.dirConf; + Util::getGameSpecificConfig(games[i].gamename, &conf); if (conf.dlConf.bSaveSerials && !games[i].serials.empty()) { @@ -695,7 +689,7 @@ void Downloader::download() this->saveChangelog(games[i].changelog, filepath); } - if (conf.dlConf.bDLC && !games[i].dlcs.empty()) + if ((conf.dlConf.iInclude & GlobalConstants::GFTYPE_DLC) && !games[i].dlcs.empty()) { for (unsigned int j = 0; j < games[i].dlcs.size(); ++j) { @@ -1637,11 +1631,7 @@ static int isPresent(std::vector& list, const boost::filesystem::path& void Downloader::checkOrphans() { // Always check everything when checking for orphaned files - Globals::globalConfig.dlConf.bInstallers = true; - Globals::globalConfig.dlConf.bExtras = true; - Globals::globalConfig.dlConf.bPatches = true; - Globals::globalConfig.dlConf.bLanguagePacks = true; - Globals::globalConfig.dlConf.bDLC = true; + Globals::globalConfig.dlConf.iInclude = Util::getOptionValue("all", GlobalConstants::INCLUDE_OPTIONS); Globals::globalConfig.dlConf.iInstallerLanguage = Util::getOptionValue("all", GlobalConstants::LANGUAGES); Globals::globalConfig.dlConf.iInstallerPlatform = Util::getOptionValue("all", GlobalConstants::PLATFORMS); Globals::globalConfig.dlConf.vLanguagePriority.clear(); @@ -1794,15 +1784,7 @@ void Downloader::checkStatus() for (unsigned int i = 0; i < vGameFiles.size(); ++i) { unsigned int type = vGameFiles[i].type; - if (!Globals::globalConfig.dlConf.bDLC && (type & GFTYPE_DLC)) - continue; - if (!Globals::globalConfig.dlConf.bInstallers && (type & GFTYPE_INSTALLER)) - continue; - if (!Globals::globalConfig.dlConf.bExtras && (type & GFTYPE_EXTRA)) - continue; - if (!Globals::globalConfig.dlConf.bPatches && (type & GFTYPE_PATCH)) - continue; - if (!Globals::globalConfig.dlConf.bLanguagePacks && (type & GFTYPE_LANGPACK)) + if (!(type & Globals::globalConfig.dlConf.iInclude)) continue; boost::filesystem::path filepath = vGameFiles[i].getFilepath(); @@ -1856,7 +1838,7 @@ void Downloader::checkStatus() bool bHashOK = true; // assume hash OK // GOG only provides xml data for installers, patches and language packs - if (type & (GFTYPE_INSTALLER | GFTYPE_PATCH | GFTYPE_LANGPACK)) + if (type & (GlobalConstants::GFTYPE_INSTALLER | GlobalConstants::GFTYPE_PATCH | GlobalConstants::GFTYPE_LANGPACK)) remoteHash = this->getRemoteFileHash(vGameFiles[i]); std::string localHash = this->getLocalFileHash(filepath.string(), gamename); @@ -2098,8 +2080,9 @@ std::vector Downloader::getGameDetailsFromJsonNode(Json::Value root gameSpecificConfig conf; conf.dlConf = Globals::globalConfig.dlConf; + conf.dirConf = Globals::globalConfig.dirConf; if (Util::getGameSpecificConfig(game.gamename, &conf) > 0) - std::cerr << game.gamename << " - Language: " << conf.dlConf.iInstallerLanguage << ", Platform: " << conf.dlConf.iInstallerPlatform << ", DLC: " << (conf.dlConf.bDLC ? "true" : "false") << std::endl; + std::cerr << game.gamename << " - Language: " << conf.dlConf.iInstallerLanguage << ", Platform: " << conf.dlConf.iInstallerPlatform << ", Include: " << Util::getOptionNameString(conf.dlConf.iInclude, GlobalConstants::INCLUDE_OPTIONS) << std::endl; for (unsigned int j = 0; j < nodes.size(); ++j) { @@ -2134,15 +2117,27 @@ std::vector Downloader::getGameDetailsFromJsonNode(Json::Value root continue; } - if (nodeName == "extras" && conf.dlConf.bExtras) + if (nodeName == "extras" && + (conf.dlConf.iInclude & GlobalConstants::GFTYPE_EXTRA)) + { game.extras.push_back(fileDetails); - else if (nodeName == "installers" && conf.dlConf.bInstallers) + } + else if (nodeName == "installers" && + (conf.dlConf.iInclude & GlobalConstants::GFTYPE_INSTALLER)) + { game.installers.push_back(fileDetails); - else if (nodeName == "patches" && conf.dlConf.bPatches) + } + else if (nodeName == "patches" && + (conf.dlConf.iInclude & GlobalConstants::GFTYPE_PATCH)) + { game.patches.push_back(fileDetails); - else if (nodeName == "languagepacks" && conf.dlConf.bLanguagePacks) + } + else if (nodeName == "languagepacks" && + (conf.dlConf.iInclude & GlobalConstants::GFTYPE_LANGPACK)) + { game.languagepacks.push_back(fileDetails); - else if (nodeName == "dlcs" && conf.dlConf.bDLC) + } + else if (nodeName == "dlcs" && (conf.dlConf.iInclude & GlobalConstants::GFTYPE_DLC)) { std::vector dlcs = this->getGameDetailsFromJsonNode(fileDetailsNode, recursion_level + 1); game.dlcs.insert(game.dlcs.end(), dlcs.begin(), dlcs.end()); @@ -2153,6 +2148,7 @@ std::vector Downloader::getGameDetailsFromJsonNode(Json::Value root if (!game.extras.empty() || !game.installers.empty() || !game.patches.empty() || !game.languagepacks.empty() || !game.dlcs.empty()) { game.filterWithPriorities(conf); + game.filterWithType(conf.dlConf.iInclude); details.push_back(game); } } @@ -2162,11 +2158,7 @@ std::vector Downloader::getGameDetailsFromJsonNode(Json::Value root void Downloader::updateCache() { // Make sure that all details get cached - Globals::globalConfig.dlConf.bExtras = true; - Globals::globalConfig.dlConf.bInstallers = true; - Globals::globalConfig.dlConf.bPatches = true; - Globals::globalConfig.dlConf.bLanguagePacks = true; - Globals::globalConfig.dlConf.bDLC = true; + Globals::globalConfig.dlConf.iInclude = Util::getOptionValue("all", GlobalConstants::INCLUDE_OPTIONS); Globals::globalConfig.sGameRegex = ".*"; Globals::globalConfig.dlConf.iInstallerLanguage = Util::getOptionValue("all", GlobalConstants::LANGUAGES); Globals::globalConfig.dlConf.iInstallerPlatform = Util::getOptionValue("all", GlobalConstants::PLATFORMS); @@ -2296,11 +2288,7 @@ int Downloader::downloadFileWithId(const std::string& fileid_string, const std:: } DownloadConfig dlConf = Globals::globalConfig.dlConf; - dlConf.bInstallers = true; - dlConf.bExtras = true; - dlConf.bPatches = true; - dlConf.bLanguagePacks = true; - dlConf.bDLC = true; + dlConf.iInclude = Util::getOptionValue("all", GlobalConstants::INCLUDE_OPTIONS); dlConf.bDuplicateHandler = false; // Disable duplicate handler int res = 1; @@ -2956,7 +2944,7 @@ void Downloader::processDownloadQueue(Config conf, const unsigned int& tid) } std::string xml; - if (gf.type & (GFTYPE_INSTALLER | GFTYPE_PATCH) && conf.dlConf.bRemoteXML) + if (gf.type & (GlobalConstants::GFTYPE_INSTALLER | GlobalConstants::GFTYPE_PATCH) && conf.dlConf.bRemoteXML) { std::string xml_url; if (downlinkJson.isMember("checksum")) @@ -3227,7 +3215,7 @@ void Downloader::processDownloadQueue(Config conf, const unsigned int& tid) { if (result == CURLE_OK) { - if ((gf.type & GFTYPE_EXTRA) || (conf.dlConf.bRemoteXML && !bLocalXMLExists && xml.empty())) + if ((gf.type & GlobalConstants::GFTYPE_EXTRA) || (conf.dlConf.bRemoteXML && !bLocalXMLExists && xml.empty())) createXMLQueue.push(gf); } } @@ -3503,31 +3491,31 @@ void Downloader::getGameDetailsThread(Config config, const unsigned int& tid) if (iOptionsOverridden > 0) { std::ostringstream ss; - ss << game_item.name << " - " << iOptionsOverridden << " options overridden with game specific options" << std::endl; + ss << game_item.name << " - " << iOptionsOverridden << " options overridden with game specific options"; if (config.iMsgLevel >= MSGLEVEL_DEBUG) { if (conf.dlConf.bIgnoreDLCCount) - ss << "\tIgnore DLC count" << std::endl; - if (conf.dlConf.bDLC != config.dlConf.bDLC) - ss << "\tDLC: " << (conf.dlConf.bDLC ? "true" : "false") << std::endl; + ss << std::endl << "\tIgnore DLC count"; + if (conf.dlConf.iInclude != config.dlConf.iInclude) + ss << std::endl << "\tInclude: " << Util::getOptionNameString(conf.dlConf.iInclude, GlobalConstants::INCLUDE_OPTIONS); if (conf.dlConf.iInstallerLanguage != config.dlConf.iInstallerLanguage) - ss << "\tLanguage: " << Util::getOptionNameString(conf.dlConf.iInstallerLanguage, GlobalConstants::LANGUAGES) << std::endl; + ss << std::endl << "\tLanguage: " << Util::getOptionNameString(conf.dlConf.iInstallerLanguage, GlobalConstants::LANGUAGES); if (conf.dlConf.vLanguagePriority != config.dlConf.vLanguagePriority) { - ss << "\tLanguage priority:" << std::endl; + ss << std::endl << "\tLanguage priority:"; for (unsigned int j = 0; j < conf.dlConf.vLanguagePriority.size(); ++j) { - ss << "\t " << j << ": " << Util::getOptionNameString(conf.dlConf.vLanguagePriority[j], GlobalConstants::LANGUAGES) << std::endl; + ss << std::endl << "\t " << j << ": " << Util::getOptionNameString(conf.dlConf.vLanguagePriority[j], GlobalConstants::LANGUAGES); } } if (conf.dlConf.iInstallerPlatform != config.dlConf.iInstallerPlatform) - ss << "\tPlatform: " << Util::getOptionNameString(conf.dlConf.iInstallerPlatform, GlobalConstants::PLATFORMS) << std::endl; + ss << std::endl << "\tPlatform: " << Util::getOptionNameString(conf.dlConf.iInstallerPlatform, GlobalConstants::PLATFORMS); if (conf.dlConf.vPlatformPriority != config.dlConf.vPlatformPriority) { - ss << "\tPlatform priority:" << std::endl; + ss << std::endl << "\tPlatform priority:"; for (unsigned int j = 0; j < conf.dlConf.vPlatformPriority.size(); ++j) { - ss << "\t " << j << ": " << Util::getOptionNameString(conf.dlConf.vPlatformPriority[j], GlobalConstants::PLATFORMS) << std::endl; + ss << std::endl << "\t " << j << ": " << Util::getOptionNameString(conf.dlConf.vPlatformPriority[j], GlobalConstants::PLATFORMS); } } } @@ -3548,6 +3536,7 @@ void Downloader::getGameDetailsThread(Config config, const unsigned int& tid) Json::Value product_info = galaxy->getProductInfo(game_item.id); game = galaxy->productInfoJsonToGameDetails(product_info, conf.dlConf); game.filterWithPriorities(conf); + game.filterWithType(conf.dlConf.iInclude); if ((conf.dlConf.bSaveSerials && game.serials.empty()) || (conf.dlConf.bSaveChangelogs && game.changelog.empty()) @@ -3687,7 +3676,7 @@ std::vector Downloader::galaxyGetDepotItemVectorFromJson(const items.insert(std::end(items), std::begin(vec), std::end(vec)); } - if (!Globals::globalConfig.dlConf.bDLC) + if (!(Globals::globalConfig.dlConf.iInclude & GlobalConstants::GFTYPE_DLC)) { std::vector items_no_dlc; for (auto it : items) @@ -4365,11 +4354,7 @@ void Downloader::galaxyShowBuildsById(const std::string& product_id, int build_i std::cout << "Checking for installers that can be used as repository" << std::endl; DownloadConfig dlConf = Globals::globalConfig.dlConf; - dlConf.bInstallers = true; - dlConf.bExtras = false; - dlConf.bLanguagePacks = false; - dlConf.bPatches = false; - dlConf.bDLC = true; + dlConf.iInclude = GlobalConstants::GFTYPE_INSTALLER; dlConf.iInstallerPlatform = dlConf.iGalaxyPlatform; dlConf.iInstallerLanguage = dlConf.iGalaxyLanguage; @@ -5039,10 +5024,7 @@ std::vector Downloader::galaxyGetOrphanedFiles(const std::vector= MSGLEVEL_VERBOSE) - std::cerr << "skipped blacklisted file " << filepath << std::endl; - continue; - } - - std::string languages = Util::getOptionNameString(game.installers[j].language, GlobalConstants::LANGUAGES); - - std::cout << "\tid: " << game.installers[j].id << std::endl - << "\tname: " << game.installers[j].name << std::endl - << "\tpath: " << game.installers[j].path << std::endl - << "\tsize: " << game.installers[j].size << std::endl - << "\tupdated: " << (game.installers[j].updated ? "True" : "False") << std::endl - << "\tlanguage: " << languages << std::endl - << "\tversion: " << game.installers[j].version << std::endl - << std::endl; + this->printGameFileDetailsAsText(gf); } } // List extras - if (Globals::globalConfig.dlConf.bExtras && !game.extras.empty()) + if ((Globals::globalConfig.dlConf.iInclude & GlobalConstants::GFTYPE_BASE_EXTRA) && !game.extras.empty()) { std::cout << "extras: " << std::endl; - for (unsigned int j = 0; j < game.extras.size(); ++j) + for (auto gf : game.extras) { - std::string filepath = game.extras[j].getFilepath(); - if (Globals::globalConfig.blacklist.isBlacklisted(filepath)) - { - if (Globals::globalConfig.iMsgLevel >= MSGLEVEL_VERBOSE) - std::cerr << "skipped blacklisted file " << filepath << std::endl; - continue; - } - - std::cout << "\tid: " << game.extras[j].id << std::endl - << "\tname: " << game.extras[j].name << std::endl - << "\tpath: " << game.extras[j].path << std::endl - << "\tsize: " << game.extras[j].size << std::endl - << std::endl; + this->printGameFileDetailsAsText(gf); } } // List patches - if (Globals::globalConfig.dlConf.bPatches && !game.patches.empty()) + if ((Globals::globalConfig.dlConf.iInclude & GlobalConstants::GFTYPE_BASE_PATCH) && !game.patches.empty()) { std::cout << "patches: " << std::endl; - for (unsigned int j = 0; j < game.patches.size(); ++j) + for (auto gf : game.patches) { - std::string filepath = game.patches[j].getFilepath(); - if (Globals::globalConfig.blacklist.isBlacklisted(filepath)) - { - if (Globals::globalConfig.iMsgLevel >= MSGLEVEL_VERBOSE) - std::cerr << "skipped blacklisted file " << filepath << std::endl; - continue; - } - - std::string languages = Util::getOptionNameString(game.patches[j].language, GlobalConstants::LANGUAGES); - - std::cout << "\tid: " << game.patches[j].id << std::endl - << "\tname: " << game.patches[j].name << std::endl - << "\tpath: " << game.patches[j].path << std::endl - << "\tsize: " << game.patches[j].size << std::endl - << "\tupdated: " << (game.patches[j].updated ? "True" : "False") << std::endl - << "\tlanguage: " << languages << std::endl - << "\tversion: " << game.patches[j].version << std::endl - << std::endl; + this->printGameFileDetailsAsText(gf); } } // List language packs - if (Globals::globalConfig.dlConf.bLanguagePacks && !game.languagepacks.empty()) + if ((Globals::globalConfig.dlConf.iInclude & GlobalConstants::GFTYPE_BASE_LANGPACK) && !game.languagepacks.empty()) { std::cout << "language packs: " << std::endl; - for (unsigned int j = 0; j < game.languagepacks.size(); ++j) + for (auto gf : game.languagepacks) { - std::string filepath = game.languagepacks[j].getFilepath(); - if (Globals::globalConfig.blacklist.isBlacklisted(filepath)) - { - if (Globals::globalConfig.iMsgLevel >= MSGLEVEL_VERBOSE) - std::cerr << "skipped blacklisted file " << filepath << std::endl; - continue; - } - - std::cout << "\tid: " << game.languagepacks[j].id << std::endl - << "\tname: " << game.languagepacks[j].name << std::endl - << "\tpath: " << game.languagepacks[j].path << std::endl - << "\tsize: " << game.languagepacks[j].size << std::endl - << std::endl; + this->printGameFileDetailsAsText(gf); } } - if (Globals::globalConfig.dlConf.bDLC && !game.dlcs.empty()) + if ((Globals::globalConfig.dlConf.iInclude & GlobalConstants::GFTYPE_DLC) && !game.dlcs.empty()) { std::cout << "DLCs: " << std::endl; - for (unsigned int j = 0; j < game.dlcs.size(); ++j) + for (auto dlc : game.dlcs) { - if (!game.dlcs[j].serials.empty()) - { - std::cout << "\tDLC gamename: " << game.dlcs[j].gamename << std::endl - << "\tserials:" << game.dlcs[j].serials << std::endl; - } + std::cout << "DLC gamename: " << dlc.gamename << std::endl + << "product id: " << dlc.product_id << std::endl; - for (unsigned int k = 0; k < game.dlcs[j].installers.size(); ++k) + if (!dlc.serials.empty()) + std::cout << "serials:" << dlc.serials << std::endl; + + if ((Globals::globalConfig.dlConf.iInclude & GlobalConstants::GFTYPE_DLC_INSTALLER) && !dlc.installers.empty()) { - std::string filepath = game.dlcs[j].installers[k].getFilepath(); - if (Globals::globalConfig.blacklist.isBlacklisted(filepath)) + for (auto gf : dlc.installers) { - if (Globals::globalConfig.iMsgLevel >= MSGLEVEL_VERBOSE) - std::cerr << "skipped blacklisted file " << filepath << std::endl; - continue; + this->printGameFileDetailsAsText(gf); } - - std::cout << "\tgamename: " << game.dlcs[j].gamename << std::endl - << "\tproduct id: " << game.dlcs[j].product_id << std::endl - << "\tid: " << game.dlcs[j].installers[k].id << std::endl - << "\tname: " << game.dlcs[j].installers[k].name << std::endl - << "\tpath: " << game.dlcs[j].installers[k].path << std::endl - << "\tsize: " << game.dlcs[j].installers[k].size << std::endl - << "\tupdated: " << (game.dlcs[j].installers[k].updated ? "True" : "False") << std::endl - << "\tversion: " << game.dlcs[j].installers[k].version << std::endl - << std::endl; } - for (unsigned int k = 0; k < game.dlcs[j].patches.size(); ++k) + if ((Globals::globalConfig.dlConf.iInclude & GlobalConstants::GFTYPE_DLC_PATCH) && !dlc.patches.empty()) { - std::string filepath = game.dlcs[j].patches[k].getFilepath(); - if (Globals::globalConfig.blacklist.isBlacklisted(filepath)) { - if (Globals::globalConfig.iMsgLevel >= MSGLEVEL_VERBOSE) - std::cerr << "skipped blacklisted file " << filepath << std::endl; - continue; + for (auto gf : dlc.patches) + { + this->printGameFileDetailsAsText(gf); } - - std::cout << "\tgamename: " << game.dlcs[j].gamename << std::endl - << "\tproduct id: " << game.dlcs[j].product_id << std::endl - << "\tid: " << game.dlcs[j].patches[k].id << std::endl - << "\tname: " << game.dlcs[j].patches[k].name << std::endl - << "\tpath: " << game.dlcs[j].patches[k].path << std::endl - << "\tsize: " << game.dlcs[j].patches[k].size << std::endl - << "\tversion: " << game.dlcs[j].patches[k].version << std::endl - << std::endl; } - for (unsigned int k = 0; k < game.dlcs[j].extras.size(); ++k) + if ((Globals::globalConfig.dlConf.iInclude & GlobalConstants::GFTYPE_DLC_EXTRA) && !dlc.extras.empty()) { - std::string filepath = game.dlcs[j].extras[k].getFilepath(); - if (Globals::globalConfig.blacklist.isBlacklisted(filepath)) { - if (Globals::globalConfig.iMsgLevel >= MSGLEVEL_VERBOSE) - std::cerr << "skipped blacklisted file " << filepath << std::endl; - continue; + for (auto gf : dlc.extras) + { + this->printGameFileDetailsAsText(gf); } - - std::cout << "\tgamename: " << game.dlcs[j].gamename << std::endl - << "\tproduct id: " << game.dlcs[j].product_id << std::endl - << "\tid: " << game.dlcs[j].extras[k].id << std::endl - << "\tname: " << game.dlcs[j].extras[k].name << std::endl - << "\tpath: " << game.dlcs[j].extras[k].path << std::endl - << "\tsize: " << game.dlcs[j].extras[k].size << std::endl - << std::endl; } - for (unsigned int k = 0; k < game.dlcs[j].languagepacks.size(); ++k) + if ((Globals::globalConfig.dlConf.iInclude & GlobalConstants::GFTYPE_DLC_LANGPACK) && !dlc.languagepacks.empty()) { - std::string filepath = game.dlcs[j].languagepacks[k].getFilepath(); - if (Globals::globalConfig.blacklist.isBlacklisted(filepath)) { - if (Globals::globalConfig.iMsgLevel >= MSGLEVEL_VERBOSE) - std::cerr << "skipped blacklisted file " << filepath << std::endl; - continue; + for (auto gf : dlc.languagepacks) + { + this->printGameFileDetailsAsText(gf); } - - std::cout << "\tgamename: " << game.dlcs[j].gamename << std::endl - << "\tproduct id: " << game.dlcs[j].product_id << std::endl - << "\tid: " << game.dlcs[j].languagepacks[k].id << std::endl - << "\tname: " << game.dlcs[j].languagepacks[k].name << std::endl - << "\tpath: " << game.dlcs[j].languagepacks[k].path << std::endl - << "\tsize: " << game.dlcs[j].languagepacks[k].size << std::endl - << std::endl; } } } } + +void Downloader::printGameFileDetailsAsText(gameFile& gf) +{ + std::string filepath = gf.getFilepath(); + if (Globals::globalConfig.blacklist.isBlacklisted(filepath)) + { + if (Globals::globalConfig.iMsgLevel >= MSGLEVEL_VERBOSE) + std::cerr << "skipped blacklisted file " << filepath << std::endl; + return; + } + + std::cout << "\tid: " << gf.id << std::endl + << "\tname: " << gf.name << std::endl + << "\tpath: " << gf.path << std::endl + << "\tsize: " << gf.size << std::endl; + + if (gf.type & GlobalConstants::GFTYPE_INSTALLER) + std::cout << "\tupdated: " << (gf.updated ? "True" : "False") << std::endl; + + if (gf.type & (GlobalConstants::GFTYPE_INSTALLER | GlobalConstants::GFTYPE_PATCH)) + { + std::string languages = Util::getOptionNameString(gf.language, GlobalConstants::LANGUAGES); + std::cout << "\tlanguage: " << languages << std::endl; + } + + if (gf.type & GlobalConstants::GFTYPE_INSTALLER) + std::cout << "\tversion: " << gf.version << std::endl; + + std::cout << std::endl; +} diff --git a/src/galaxyapi.cpp b/src/galaxyapi.cpp index d48bdc7..7ab8b2e 100644 --- a/src/galaxyapi.cpp +++ b/src/galaxyapi.cpp @@ -314,27 +314,27 @@ gameDetails galaxyAPI::productInfoJsonToGameDetails(const Json::Value& json, con if (json.isMember("changelog")) gamedetails.changelog = json["changelog"].asString(); - if (dlConf.bInstallers) + if (dlConf.iInclude & GlobalConstants::GFTYPE_INSTALLER) { - gamedetails.installers = this->fileJsonNodeToGameFileVector(gamedetails.gamename, json["downloads"]["installers"], GFTYPE_INSTALLER, dlConf); + gamedetails.installers = this->fileJsonNodeToGameFileVector(gamedetails.gamename, json["downloads"]["installers"], GlobalConstants::GFTYPE_BASE_INSTALLER, dlConf); } - if (dlConf.bExtras) + if (dlConf.iInclude & GlobalConstants::GFTYPE_EXTRA) { - gamedetails.extras = this->fileJsonNodeToGameFileVector(gamedetails.gamename, json["downloads"]["bonus_content"], GFTYPE_EXTRA, dlConf); + gamedetails.extras = this->fileJsonNodeToGameFileVector(gamedetails.gamename, json["downloads"]["bonus_content"], GlobalConstants::GFTYPE_BASE_EXTRA, dlConf); } - if (dlConf.bPatches) + if (dlConf.iInclude & GlobalConstants::GFTYPE_PATCH) { - gamedetails.patches = this->fileJsonNodeToGameFileVector(gamedetails.gamename, json["downloads"]["patches"], GFTYPE_PATCH, dlConf); + gamedetails.patches = this->fileJsonNodeToGameFileVector(gamedetails.gamename, json["downloads"]["patches"], GlobalConstants::GFTYPE_BASE_PATCH, dlConf); } - if (dlConf.bLanguagePacks) + if (dlConf.iInclude & GlobalConstants::GFTYPE_LANGPACK) { - gamedetails.languagepacks = this->fileJsonNodeToGameFileVector(gamedetails.gamename, json["downloads"]["language_packs"], GFTYPE_LANGPACK, dlConf); + gamedetails.languagepacks = this->fileJsonNodeToGameFileVector(gamedetails.gamename, json["downloads"]["language_packs"], GlobalConstants::GFTYPE_BASE_LANGPACK, dlConf); } - if (dlConf.bDLC) + if (dlConf.iInclude & GlobalConstants::GFTYPE_DLC) { if (json.isMember("expanded_dlcs")) { @@ -352,13 +352,13 @@ gameDetails galaxyAPI::productInfoJsonToGameDetails(const Json::Value& json, con // Add DLC type to all DLC files for (unsigned int j = 0; j < dlc_gamedetails.installers.size(); ++j) - dlc_gamedetails.installers[j].type |= GFTYPE_DLC; + dlc_gamedetails.installers[j].type = GlobalConstants::GFTYPE_DLC_INSTALLER; for (unsigned int j = 0; j < dlc_gamedetails.extras.size(); ++j) - dlc_gamedetails.extras[j].type |= GFTYPE_DLC; + dlc_gamedetails.extras[j].type = GlobalConstants::GFTYPE_DLC_EXTRA; for (unsigned int j = 0; j < dlc_gamedetails.patches.size(); ++j) - dlc_gamedetails.patches[j].type |= GFTYPE_DLC; + dlc_gamedetails.patches[j].type = GlobalConstants::GFTYPE_DLC_PATCH; for (unsigned int j = 0; j < dlc_gamedetails.languagepacks.size(); ++j) - dlc_gamedetails.languagepacks[j].type |= GFTYPE_DLC; + dlc_gamedetails.languagepacks[j].type = GlobalConstants::GFTYPE_DLC_LANGPACK; // Add DLC only if it has any files if (!dlc_gamedetails.installers.empty() || !dlc_gamedetails.extras.empty() || !dlc_gamedetails.patches.empty() || !dlc_gamedetails.languagepacks.empty()) @@ -385,7 +385,7 @@ std::vector galaxyAPI::fileJsonNodeToGameFileVector(const std::string& unsigned int iPlatform = GlobalConstants::PLATFORM_WINDOWS; unsigned int iLanguage = GlobalConstants::LANGUAGE_EN; - if (!(type & GFTYPE_EXTRA)) + if (!(type & GlobalConstants::GFTYPE_EXTRA)) { iPlatform = Util::getOptionValue(infoNode["os"].asString(), GlobalConstants::PLATFORMS); iLanguage = Util::getOptionValue(infoNode["language"].asString(), GlobalConstants::LANGUAGES); @@ -433,7 +433,7 @@ std::vector galaxyAPI::fileJsonNodeToGameFileVector(const std::string& gf.galaxy_downlink_json_url = downlink; gf.version = version; - if (!(type & GFTYPE_EXTRA)) + if (!(type & GlobalConstants::GFTYPE_EXTRA)) { gf.platform = iPlatform; gf.language = iLanguage; @@ -446,7 +446,7 @@ std::vector galaxyAPI::fileJsonNodeToGameFileVector(const std::string& { if (gamefiles[k].path == gf.path) { - if (!(type & GFTYPE_EXTRA)) + if (!(type & GlobalConstants::GFTYPE_EXTRA)) gamefiles[k].language |= gf.language; // Add language code to installer bDuplicate = true; break; diff --git a/src/gamedetails.cpp b/src/gamedetails.cpp index fb8b421..1a16c27 100644 --- a/src/gamedetails.cpp +++ b/src/gamedetails.cpp @@ -214,27 +214,39 @@ std::vector gameDetails::getGameFileVector() // Return vector containing all game files matching download filters std::vector gameDetails::getGameFileVectorFiltered(const unsigned int& iType) { - std::vector vGameFiles = this->getGameFileVector(); + std::vector vGameFiles; - std::remove_if( - vGameFiles.begin(), - vGameFiles.end(), - [iType](gameFile gf) - { - bool bRemove = false; - if (gf.type & iType) - { - // Remove if DLC but DLCs not enabled - if ( !((iType & GFTYPE_DLC) & iType) ) - bRemove = true; - } - else - { - bRemove = true; - } - return bRemove; - } - ); + for (auto gf : this->getGameFileVector()) + { + if (gf.type & iType) + vGameFiles.push_back(gf); + } return vGameFiles; } + +void gameDetails::filterWithType(const unsigned int& iType) +{ + filterListWithType(installers, iType); + filterListWithType(patches, iType); + filterListWithType(extras, iType); + filterListWithType(languagepacks, iType); + for (unsigned int i = 0; i < dlcs.size(); ++i) + { + filterListWithType(dlcs[i].installers, iType); + filterListWithType(dlcs[i].patches, iType); + filterListWithType(dlcs[i].extras, iType); + filterListWithType(dlcs[i].languagepacks, iType); + } +} + +void gameDetails::filterListWithType(std::vector& list, const unsigned int& iType) +{ + for (std::vector::iterator gf = list.begin(); gf != list.end();) + { + if (!(gf->type & iType)) + gf = list.erase(gf); + else + gf++; + } +} diff --git a/src/util.cpp b/src/util.cpp index 316f5cf..dc80f27 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -330,9 +330,19 @@ int Util::getGameSpecificConfig(std::string gamename, gameSpecificConfig* conf, } res++; } + // Warn about deprecated option if (root.isMember("dlc")) { - conf->dlConf.bDLC = root["dlc"].asBool(); + std::cerr << filepath << " contains deprecated option \"dlc\" which will be ignored, use \"include\" instead" << std::endl; + } + if (root.isMember("include")) + { + conf->dlConf.iInclude = 0; + std::vector vInclude = Util::tokenize(root["include"].asString(), ","); + for (std::vector::iterator it = vInclude.begin(); it != vInclude.end(); it++) + { + conf->dlConf.iInclude |= Util::getOptionValue(*it, GlobalConstants::INCLUDE_OPTIONS); + } res++; } if (root.isMember("ignore-dlc-count")) @@ -592,7 +602,8 @@ unsigned int Util::getOptionValue(const std::string& str, const std::vector what; if (str == "all") { - value = (1 << options.size()) - 1; + for (unsigned int i = 0; i < options.size(); ++i) + value |= options[i].id; } else if (boost::regex_search(str, what, expression) && bAllowStringToIntConversion) { @@ -627,7 +638,7 @@ std::string Util::getOptionNameString(const unsigned int& value, const std::vect std::string str; for (unsigned int i = 0; i < options.size(); ++i) { - if (value & options[i].id) + if ((value & options[i].id) == options[i].id) str += (str.empty() ? "" : ", ")+options[i].str; } return str; diff --git a/src/website.cpp b/src/website.cpp index b437e11..3bc6139 100644 --- a/src/website.cpp +++ b/src/website.cpp @@ -188,7 +188,7 @@ std::vector Website::getGames() continue; } - if (Globals::globalConfig.dlConf.bDLC) + if (Globals::globalConfig.dlConf.iInclude & GlobalConstants::GFTYPE_DLC) { int dlcCount = product["dlcCount"].asInt();