Improve include/exclude options

DLC files can now be included/excluded separately
Bumped game details cache version number

Game specific config file changes:
- "dlc" option is deprecated and will be ignored
- "include" option is added
This commit is contained in:
Sude 2023-05-17 18:03:31 +03:00
parent 06c033eda1
commit ed1a61e2b3
12 changed files with 219 additions and 289 deletions

View File

@ -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;

View File

@ -156,6 +156,7 @@ class Downloader
template <typename T> void printProgress(const ThreadSafeQueue<T>& 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);

View File

@ -39,9 +39,11 @@ class gameDetails
Json::Value getDetailsAsJson();
std::vector<gameFile> getGameFileVector();
std::vector<gameFile> getGameFileVectorFiltered(const unsigned int& iType);
void filterWithType(const unsigned int& iType);
virtual ~gameDetails();
protected:
void filterListWithPriorities(std::vector<gameFile>& list, const gameSpecificConfig& config);
void filterListWithType(std::vector<gameFile>& list, const unsigned int& iType);
private:
std::string serialsFilepath;
std::string changelogFilepath;

View File

@ -14,13 +14,6 @@
#include <vector>
#include <json/json.h>
// 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:

View File

@ -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<GlobalConstants::optionsStruct> 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

View File

@ -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<GlobalConstants::optionsStruct> 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<std::string> vExclude = Util::tokenize(sExcludeOptions, ",");
for (std::vector<std::string>::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<std::string>::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)

View File

@ -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" : <string>,
"platform" : <string>,
"dlc" : <bool>,
"include" : <string>,
"ignore-dlc-count" : <bool>,
"subdirectories" : <bool>,
"directory" : <string>,

View File

@ -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<gameFile>& 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<gameDetails> 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<gameDetails> 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<gameDetails> dlcs = this->getGameDetailsFromJsonNode(fileDetailsNode, recursion_level + 1);
game.dlcs.insert(game.dlcs.end(), dlcs.begin(), dlcs.end());
@ -2153,6 +2148,7 @@ std::vector<gameDetails> 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<gameDetails> 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<galaxyDepotItem> 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<galaxyDepotItem> 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<std::string> Downloader::galaxyGetOrphanedFiles(const std::vector<ga
void Downloader::galaxyInstallGame_MojoSetupHack(const std::string& product_id)
{
DownloadConfig dlConf = Globals::globalConfig.dlConf;
dlConf.bInstallers = true;
dlConf.bExtras = false;
dlConf.bLanguagePacks = false;
dlConf.bPatches = false;
dlConf.iInclude |= GlobalConstants::GFTYPE_BASE_INSTALLER;
dlConf.iInstallerPlatform = dlConf.iGalaxyPlatform;
dlConf.iInstallerLanguage = dlConf.iGalaxyLanguage;
@ -6191,182 +6173,110 @@ void Downloader::printGameDetailsAsText(gameDetails& game)
std::cout << "serials:" << std::endl << game.serials << std::endl;
// List installers
if (Globals::globalConfig.dlConf.bInstallers && !game.installers.empty())
if ((Globals::globalConfig.dlConf.iInclude & GlobalConstants::GFTYPE_BASE_INSTALLER) && !game.installers.empty())
{
std::cout << "installers: " << std::endl;
for (unsigned int j = 0; j < game.installers.size(); ++j)
for (auto gf : game.installers)
{
std::string filepath = game.installers[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.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)
{
std::string filepath = game.dlcs[j].installers[k].getFilepath();
if (Globals::globalConfig.blacklist.isBlacklisted(filepath))
{
if (Globals::globalConfig.iMsgLevel >= MSGLEVEL_VERBOSE)
std::cerr << "skipped blacklisted file " << filepath << std::endl;
continue;
}
if (!dlc.serials.empty())
std::cout << "serials:" << dlc.serials << std::endl;
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_INSTALLER) && !dlc.installers.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;
}
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)
for (auto gf : dlc.installers)
{
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;
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_PATCH) && !dlc.patches.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.patches)
{
this->printGameFileDetailsAsText(gf);
}
}
if ((Globals::globalConfig.dlConf.iInclude & GlobalConstants::GFTYPE_DLC_EXTRA) && !dlc.extras.empty())
{
for (auto gf : dlc.extras)
{
this->printGameFileDetailsAsText(gf);
}
}
if ((Globals::globalConfig.dlConf.iInclude & GlobalConstants::GFTYPE_DLC_LANGPACK) && !dlc.languagepacks.empty())
{
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;
}

View File

@ -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<gameFile> 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<gameFile> 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<gameFile> 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;

View File

@ -214,27 +214,39 @@ std::vector<gameFile> gameDetails::getGameFileVector()
// Return vector containing all game files matching download filters
std::vector<gameFile> gameDetails::getGameFileVectorFiltered(const unsigned int& iType)
{
std::vector<gameFile> vGameFiles = this->getGameFileVector();
std::vector<gameFile> vGameFiles;
std::remove_if(
vGameFiles.begin(),
vGameFiles.end(),
[iType](gameFile gf)
for (auto gf : this->getGameFileVector())
{
bool bRemove = false;
if (gf.type & iType)
{
// Remove if DLC but DLCs not enabled
if ( !((iType & GFTYPE_DLC) & iType) )
bRemove = true;
vGameFiles.push_back(gf);
}
else
{
bRemove = true;
}
return bRemove;
}
);
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<gameFile>& list, const unsigned int& iType)
{
for (std::vector<gameFile>::iterator gf = list.begin(); gf != list.end();)
{
if (!(gf->type & iType))
gf = list.erase(gf);
else
gf++;
}
}

View File

@ -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<std::string> vInclude = Util::tokenize(root["include"].asString(), ",");
for (std::vector<std::string>::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<Glob
boost::match_results<std::string::const_iterator> 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;

View File

@ -188,7 +188,7 @@ std::vector<gameItem> Website::getGames()
continue;
}
if (Globals::globalConfig.dlConf.bDLC)
if (Globals::globalConfig.dlConf.iInclude & GlobalConstants::GFTYPE_DLC)
{
int dlcCount = product["dlcCount"].asInt();