From 65961de041cac297d7d6e3d104d83051ceb64f23 Mon Sep 17 00:00:00 2001 From: Sude Date: Fri, 7 Jun 2019 14:51:05 +0300 Subject: [PATCH] Galaxy: Automatically delete old files when updating or downgrading Determine id of old build and then compare file list to selected build. Automatically delete files that have been removed between the builds. --- include/downloader.h | 1 + src/downloader.cpp | 204 +++++++++++++++++++++++++++++++------------ 2 files changed, 148 insertions(+), 57 deletions(-) diff --git a/include/downloader.h b/include/downloader.h index f754530..a119808 100644 --- a/include/downloader.h +++ b/include/downloader.h @@ -146,6 +146,7 @@ class Downloader int mojoSetupGetFileVector(const gameFile& gf, std::vector& vFiles); std::string getGalaxyInstallDirectory(galaxyAPI *galaxyHandle, const Json::Value& manifest); bool galaxySelectProductIdHelper(const std::string& product_id, std::string& selected_product); + std::vector galaxyGetDepotItemVectorFromJson(const Json::Value& json, const unsigned int& iGalaxyArch = GlobalConstants::ARCH_X64); Website *gogWebsite; API *gogAPI; diff --git a/src/downloader.cpp b/src/downloader.cpp index 5d3c964..62421e3 100644 --- a/src/downloader.cpp +++ b/src/downloader.cpp @@ -3252,29 +3252,9 @@ bool Downloader::galaxySelectProductIdHelper(const std::string& product_id, std: return true; } -void Downloader::galaxyInstallGame(const std::string& product_id, int build_index, const unsigned int& iGalaxyArch) +std::vector Downloader::galaxyGetDepotItemVectorFromJson(const Json::Value& json, const unsigned int& iGalaxyArch) { - std::string id; - if(this->galaxySelectProductIdHelper(product_id, id)) - { - if (!id.empty()) - this->galaxyInstallGameById(id, build_index, iGalaxyArch); - } -} - -void Downloader::galaxyInstallGameById(const std::string& product_id, int build_index, const unsigned int& iGalaxyArch) -{ - if (build_index < 0) - build_index = 0; - - std::string sPlatform; - unsigned int iPlatform = Globals::globalConfig.dlConf.iGalaxyPlatform; - if (iPlatform == GlobalConstants::PLATFORM_LINUX) - sPlatform = "linux"; - else if (iPlatform == GlobalConstants::PLATFORM_MAC) - sPlatform = "osx"; - else - sPlatform = "windows"; + std::string product_id = json["baseProductId"].asString(); std::string sLanguageRegex = "en|eng|english|en[_-]US"; unsigned int iLanguage = Globals::globalConfig.dlConf.iGalaxyLanguage; @@ -3297,41 +3277,6 @@ void Downloader::galaxyInstallGameById(const std::string& product_id, int build_ } } - Json::Value json = gogGalaxy->getProductBuilds(product_id, sPlatform); - - // JSON is empty and platform is Linux. Most likely cause is that Galaxy API doesn't have Linux support - if (json.empty() && iPlatform == GlobalConstants::PLATFORM_LINUX) - { - std::cout << "Galaxy API doesn't have Linux support" << std::endl; - - // Galaxy install hack for Linux - std::cout << "Trying to use installers as repository" << std::endl; - this->galaxyInstallGame_MojoSetupHack(product_id); - - return; - } - - if (json["items"][build_index]["generation"].asInt() != 2) - { - std::cout << "Only generation 2 builds are supported currently" << std::endl; - return; - } - - std::string link = json["items"][build_index]["link"].asString(); - std::string buildHash; - buildHash.assign(link.begin()+link.find_last_of("/")+1, link.end()); - - json = gogGalaxy->getManifestV2(buildHash); - std::string game_title = json["products"][0]["name"].asString(); - std::string install_directory; - - if (Globals::globalConfig.dirConf.bSubDirectories) - { - install_directory = this->getGalaxyInstallDirectory(gogGalaxy, json); - } - - std::string install_path = Globals::globalConfig.dirConf.sDirectory + install_directory; - std::vector items; for (unsigned int i = 0; i < json["depots"].size(); ++i) { @@ -3380,6 +3325,151 @@ void Downloader::galaxyInstallGameById(const std::string& product_id, int build_ } } + return items; +} + +void Downloader::galaxyInstallGame(const std::string& product_id, int build_index, const unsigned int& iGalaxyArch) +{ + std::string id; + if(this->galaxySelectProductIdHelper(product_id, id)) + { + if (!id.empty()) + this->galaxyInstallGameById(id, build_index, iGalaxyArch); + } +} + +void Downloader::galaxyInstallGameById(const std::string& product_id, int build_index, const unsigned int& iGalaxyArch) +{ + if (build_index < 0) + build_index = 0; + + std::string sPlatform; + unsigned int iPlatform = Globals::globalConfig.dlConf.iGalaxyPlatform; + if (iPlatform == GlobalConstants::PLATFORM_LINUX) + sPlatform = "linux"; + else if (iPlatform == GlobalConstants::PLATFORM_MAC) + sPlatform = "osx"; + else + sPlatform = "windows"; + + Json::Value json = gogGalaxy->getProductBuilds(product_id, sPlatform); + + // JSON is empty and platform is Linux. Most likely cause is that Galaxy API doesn't have Linux support + if (json.empty() && iPlatform == GlobalConstants::PLATFORM_LINUX) + { + std::cout << "Galaxy API doesn't have Linux support" << std::endl; + + // Galaxy install hack for Linux + std::cout << "Trying to use installers as repository" << std::endl; + this->galaxyInstallGame_MojoSetupHack(product_id); + + return; + } + + if (json["items"][build_index]["generation"].asInt() != 2) + { + std::cout << "Only generation 2 builds are supported currently" << std::endl; + return; + } + + std::string link = json["items"][build_index]["link"].asString(); + std::string buildHash; + buildHash.assign(link.begin()+link.find_last_of("/")+1, link.end()); + + // Save builds json to another variable for later use + Json::Value json_builds = json; + + json = gogGalaxy->getManifestV2(buildHash); + std::string game_title = json["products"][0]["name"].asString(); + std::string install_directory; + + if (Globals::globalConfig.dirConf.bSubDirectories) + { + install_directory = this->getGalaxyInstallDirectory(gogGalaxy, json); + } + + std::string install_path = Globals::globalConfig.dirConf.sDirectory + install_directory; + + std::vector items = this->galaxyGetDepotItemVectorFromJson(json, iGalaxyArch); + + // Check for differences between previously installed build and new build + std::vector items_old; + + std::string info_path = install_path + "/goggame-" + product_id + ".info"; + std::string old_build_id; + int old_build_index = -1; + if (boost::filesystem::exists(info_path)) + { + std::ifstream info_file_stream(info_path, std::ifstream::binary); + Json::Value info_json; + try { + info_file_stream >> info_json; + old_build_id = info_json["buildId"].asString(); + } + catch (const Json::Exception& exc) + { + std::cout << "Failed to parse " << info_path << std::endl; + std::cout << exc.what() << std::endl; + return; + } + + if (!old_build_id.empty()) + { + for (unsigned int i = 0; i < json_builds["items"].size(); ++i) + { + std::string build_id = json_builds["items"][i]["build_id"].asString(); + if (build_id == old_build_id) + { + old_build_index = i; + break; + } + } + } + } + + // Check for deleted files between builds + if (old_build_index >= 0 && old_build_index != build_index) + { + std::string link = json_builds["items"][old_build_index]["link"].asString(); + std::string buildHash_old; + buildHash_old.assign(link.begin()+link.find_last_of("/")+1, link.end()); + + Json::Value json_old = gogGalaxy->getManifestV2(buildHash_old); + items_old = this->galaxyGetDepotItemVectorFromJson(json_old, iGalaxyArch); + } + + std::vector deleted_filepaths; + if (!items_old.empty()) + { + for (auto old_item: items_old) + { + bool isDeleted = true; + for (auto item: items) + { + if (old_item.path == item.path) + { + isDeleted = false; + break; + } + } + if (isDeleted) + deleted_filepaths.push_back(old_item.path); + } + } + + // Delete old files + if (!deleted_filepaths.empty()) + { + for (auto path : deleted_filepaths) + { + std::string filepath = install_path + "/" + path; + std::cout << "Deleting " << filepath << std::endl; + if (boost::filesystem::exists(filepath)) + if (!boost::filesystem::remove(filepath)) + std::cerr << "Failed to delete " << filepath << std::endl; + } + } + uintmax_t totalSize = 0; for (unsigned int i = 0; i < items.size(); ++i) {