From 584fef3988823de7f4f42cddaec095411a47a1a9 Mon Sep 17 00:00:00 2001 From: Sude Date: Fri, 6 Aug 2021 11:23:02 +0300 Subject: [PATCH] Use duplicate handler for extras Makes downloader use duplicate handler for extras This should help to avoid a race condition mentioned in issue #200 (Crashes when downloading "secure") because the downloader no longer tries to download the same file from multiple threads --- include/galaxyapi.h | 6 +---- src/galaxyapi.cpp | 55 +++++++++++++++------------------------------ 2 files changed, 19 insertions(+), 42 deletions(-) diff --git a/include/galaxyapi.h b/include/galaxyapi.h index dcb677b..858b639 100644 --- a/include/galaxyapi.h +++ b/include/galaxyapi.h @@ -69,11 +69,7 @@ class galaxyAPI CurlConfig curlConf; static size_t writeMemoryCallback(char *ptr, size_t size, size_t nmemb, void *userp); CURL* curlhandle; - std::vector installerJsonNodeToGameFileVector(const std::string& gamename, const Json::Value& json, const DownloadConfig& dlConf); - std::vector patchJsonNodeToGameFileVector(const std::string& gamename, const Json::Value& json, const DownloadConfig& dlConf); - std::vector languagepackJsonNodeToGameFileVector(const std::string& gamename, const Json::Value& json, const DownloadConfig& dlConf); - std::vector extraJsonNodeToGameFileVector(const std::string& gamename, const Json::Value& json); - std::vector fileJsonNodeToGameFileVector(const std::string& gamename, const Json::Value& json, const unsigned int& type = GFTYPE_INSTALLER, const unsigned int& platform = (GlobalConstants::PLATFORM_WINDOWS | GlobalConstants::PLATFORM_LINUX), const unsigned int& lang = GlobalConstants::LANGUAGE_EN, const bool& useDuplicateHandler = false); + std::vector fileJsonNodeToGameFileVector(const std::string& gamename, const Json::Value& json, const unsigned int& type, const DownloadConfig& dlConf); }; #endif // GALAXYAPI_H diff --git a/src/galaxyapi.cpp b/src/galaxyapi.cpp index e0e5921..0a0d119 100644 --- a/src/galaxyapi.cpp +++ b/src/galaxyapi.cpp @@ -257,22 +257,22 @@ gameDetails galaxyAPI::productInfoJsonToGameDetails(const Json::Value& json, con if (dlConf.bInstallers) { - gamedetails.installers = this->installerJsonNodeToGameFileVector(gamedetails.gamename, json["downloads"]["installers"], dlConf); + gamedetails.installers = this->fileJsonNodeToGameFileVector(gamedetails.gamename, json["downloads"]["installers"], GFTYPE_INSTALLER, dlConf); } if (dlConf.bExtras) { - gamedetails.extras = this->extraJsonNodeToGameFileVector(gamedetails.gamename, json["downloads"]["bonus_content"]); + gamedetails.extras = this->fileJsonNodeToGameFileVector(gamedetails.gamename, json["downloads"]["bonus_content"], GFTYPE_EXTRA, dlConf); } if (dlConf.bPatches) { - gamedetails.patches = this->patchJsonNodeToGameFileVector(gamedetails.gamename, json["downloads"]["patches"], dlConf); + gamedetails.patches = this->fileJsonNodeToGameFileVector(gamedetails.gamename, json["downloads"]["patches"], GFTYPE_PATCH, dlConf); } if (dlConf.bLanguagePacks) { - gamedetails.languagepacks = this->languagepackJsonNodeToGameFileVector(gamedetails.gamename, json["downloads"]["language_packs"], dlConf); + gamedetails.languagepacks = this->fileJsonNodeToGameFileVector(gamedetails.gamename, json["downloads"]["language_packs"], GFTYPE_LANGPACK, dlConf); } if (dlConf.bDLC) @@ -303,27 +303,7 @@ gameDetails galaxyAPI::productInfoJsonToGameDetails(const Json::Value& json, con return gamedetails; } -std::vector galaxyAPI::installerJsonNodeToGameFileVector(const std::string& gamename, const Json::Value& json, const DownloadConfig& dlConf) -{ - return this->fileJsonNodeToGameFileVector(gamename, json, GFTYPE_INSTALLER, dlConf.iInstallerPlatform, dlConf.iInstallerLanguage, dlConf.bDuplicateHandler); -} - -std::vector galaxyAPI::patchJsonNodeToGameFileVector(const std::string& gamename, const Json::Value& json, const DownloadConfig& dlConf) -{ - return this->fileJsonNodeToGameFileVector(gamename, json, GFTYPE_PATCH, dlConf.iInstallerPlatform, dlConf.iInstallerLanguage, dlConf.bDuplicateHandler); -} - -std::vector galaxyAPI::languagepackJsonNodeToGameFileVector(const std::string& gamename, const Json::Value& json, const DownloadConfig& dlConf) -{ - return this->fileJsonNodeToGameFileVector(gamename, json, GFTYPE_LANGPACK, dlConf.iInstallerPlatform, dlConf.iInstallerLanguage, dlConf.bDuplicateHandler); -} - -std::vector galaxyAPI::extraJsonNodeToGameFileVector(const std::string& gamename, const Json::Value& json) -{ - return this->fileJsonNodeToGameFileVector(gamename, json, GFTYPE_EXTRA); -} - -std::vector galaxyAPI::fileJsonNodeToGameFileVector(const std::string& gamename, const Json::Value& json, const unsigned int& type, const unsigned int& platform, const unsigned int& lang, const bool& useDuplicateHandler) +std::vector galaxyAPI::fileJsonNodeToGameFileVector(const std::string& gamename, const Json::Value& json, const unsigned int& type, const DownloadConfig& dlConf) { std::vector gamefiles; unsigned int iInfoNodes = json.size(); @@ -343,10 +323,10 @@ std::vector galaxyAPI::fileJsonNodeToGameFileVector(const std::string& iPlatform = Util::getOptionValue(infoNode["os"].asString(), GlobalConstants::PLATFORMS); iLanguage = Util::getOptionValue(infoNode["language"].asString(), GlobalConstants::LANGUAGES); - if (!(iPlatform & platform)) + if (!(iPlatform & dlConf.iInstallerPlatform)) continue; - if (!(iLanguage & lang)) + if (!(iLanguage & dlConf.iInstallerLanguage)) continue; } @@ -377,22 +357,23 @@ std::vector galaxyAPI::fileJsonNodeToGameFileVector(const std::string& { gf.platform = iPlatform; gf.language = iLanguage; + } - if (useDuplicateHandler) + if (dlConf.bDuplicateHandler) + { + bool bDuplicate = false; + for (unsigned int k = 0; k < gamefiles.size(); ++k) { - bool bDuplicate = false; - for (unsigned int k = 0; k < gamefiles.size(); ++k) + if (gamefiles[k].path == gf.path) { - if (gamefiles[k].path == gf.path) - { + if (!(type & GFTYPE_EXTRA)) gamefiles[k].language |= gf.language; // Add language code to installer - bDuplicate = true; - break; - } + bDuplicate = true; + break; } - if (bDuplicate) - continue; } + if (bDuplicate) + continue; } gamefiles.push_back(gf);