diff --git a/include/api.h b/include/api.h index be4916c..b30f38b 100644 --- a/include/api.h +++ b/include/api.h @@ -33,6 +33,7 @@ class gameDetails { public: std::vector extras; std::vector installers; + std::vector patches; std::string gamename; std::string title; std::string icon; @@ -83,6 +84,7 @@ class API gameDetails getGameDetails(const std::string& game_name, const unsigned int& type = GlobalConstants::PLATFORM_WINDOWS, const unsigned int& lang = GlobalConstants::LANGUAGE_EN); std::string getInstallerLink(const std::string& game_name, const std::string& id); std::string getExtraLink(const std::string& game_name, const std::string& id); + std::string getPatchLink(const std::string& game_name, const std::string& id); std::string getXML(const std::string& game_name, const std::string& id); void clearError(); bool getError() { return this->error; }; diff --git a/include/config.h b/include/config.h index ddfc654..0384920 100644 --- a/include/config.h +++ b/include/config.h @@ -27,6 +27,7 @@ class Config bool bRepair; bool bNoInstallers; bool bNoExtras; + bool bNoPatches; bool bNoUnicode; // don't use Unicode in console output bool bNoColor; // don't use colors bool bVerifyPeer; diff --git a/main.cpp b/main.cpp index 4369121..ef9accf 100644 --- a/main.cpp +++ b/main.cpp @@ -96,6 +96,7 @@ int main(int argc, char *argv[]) ("language", bpo::value(&config.iInstallerLanguage)->default_value(GlobalConstants::LANGUAGE_EN), language_text.c_str()) ("no-installers", bpo::value(&config.bNoInstallers)->zero_tokens()->default_value(false), "Don't download/list/repair installers") ("no-extras", bpo::value(&config.bNoExtras)->zero_tokens()->default_value(false), "Don't download/list/repair extras") + ("no-patches", bpo::value(&config.bNoPatches)->zero_tokens()->default_value(false), "Don't download/list/repair patches") ("no-cover", bpo::value(&config.bNoCover)->zero_tokens()->default_value(false), "Don't download cover images") ("no-remote-xml", bpo::value(&config.bNoRemoteXML)->zero_tokens()->default_value(false), "Don't use remote XML for repair") ("no-unicode", bpo::value(&config.bNoUnicode)->zero_tokens()->default_value(false), "Don't use Unicode in the progress bar") diff --git a/src/api.cpp b/src/api.cpp index 69f2656..edd444e 100644 --- a/src/api.cpp +++ b/src/api.cpp @@ -339,6 +339,54 @@ gameDetails API::getGameDetails(const std::string& game_name, const unsigned int ); } + // Patch details + for (unsigned int i = 0; i < GlobalConstants::LANGUAGES.size(); ++i) + { + if (lang & GlobalConstants::LANGUAGES[i].languageId) + { + unsigned int patch_number = 1; + unsigned int patch_number_file = 1; + std::ostringstream ss; + ss.str(std::string()); + ss << GlobalConstants::LANGUAGES[i].languageCode << patch_number << "patch" << patch_number_file; + std::string patchname = ss.str(); + if (root["game"].isMember(patchname)) // found a patch node + { + Json::Value patchnode = root["game"][patchname]; + while (!patchnode.empty()) + { + patch_number_file = 1; + while(!patchnode.empty()) + { + for ( unsigned int index = 0; index < patchnode.size(); ++index ) + { + Json::Value patch = patchnode[index]; + + game.patches.push_back( + gameFile( false, /* patches don't have "updated" flag */ + patch["id"].isInt() ? std::to_string(patch["id"].asInt()) : patch["id"].asString(), + patchname, + patch["link"].asString(), + patch["size_mb"].asString(), + GlobalConstants::LANGUAGES[i].languageId + ) + ); + } + patch_number_file++; + ss.str(std::string()); + ss << GlobalConstants::LANGUAGES[i].languageCode << patch_number << "patch" << patch_number_file; + patchname = ss.str(); + patchnode = root["game"][patchname]; + } + patch_number++; + ss.str(std::string()); + ss << GlobalConstants::LANGUAGES[i].languageCode << patch_number << "patch" << patch_number_file; + patchname = ss.str(); + patchnode = root["game"][patchname]; + } + } + } + } } else { @@ -434,6 +482,10 @@ std::string API::getExtraLink(const std::string& game_name, const std::string& i return link; } +std::string API::getPatchLink(const std::string& game_name, const std::string& id) +{ + return this->getInstallerLink(game_name, id); +} std::string API::getXML(const std::string& game_name, const std::string& id) { diff --git a/src/downloader.cpp b/src/downloader.cpp index 6c71832..86e76d7 100644 --- a/src/downloader.cpp +++ b/src/downloader.cpp @@ -298,6 +298,19 @@ void Downloader::listGames() << std::endl; } } + // List patches + if (!config.bNoPatches && !config.bUpdateCheck && !games[i].patches.empty()) + { + std::cout << "patches: " << std::endl; + for (unsigned int j = 0; j < games[i].patches.size(); ++j) + { + std::cout << "\tid: " << games[i].patches[j].id << std::endl + << "\tname: " << games[i].patches[j].name << std::endl + << "\tpath: " << games[i].patches[j].path << std::endl + << "\tsize: " << games[i].patches[j].size << std::endl + << std::endl; + } + } } } else @@ -374,6 +387,43 @@ void Downloader::repair() std::cout << std::endl; } } + + // Patches (use remote or local file) + if (!config.bNoPatches) + { + for (unsigned int j = 0; j < games[i].patches.size(); ++j) + { + std::string filepath = Util::makeFilepath(config.sDirectory, games[i].patches[j].path, games[i].gamename); + + // Get XML data + std::string XML = ""; + if (!config.bNoRemoteXML) + { + XML = gogAPI->getXML(games[i].gamename, games[i].patches[j].id); + if (gogAPI->getError()) + { + std::cout << gogAPI->getErrorMessage() << std::endl; + gogAPI->clearError(); + continue; + } + } + + // Repair + if (!XML.empty() || config.bNoRemoteXML) + { + std::string url = gogAPI->getPatchLink(games[i].gamename, games[i].patches[j].id); + if (gogAPI->getError()) + { + std::cout << gogAPI->getErrorMessage() << std::endl; + gogAPI->clearError(); + continue; + } + std::cout << "Repairing file " << filepath << std::endl; + this->repairFile(url, filepath, XML); + std::cout << std::endl; + } + } + } } } @@ -467,6 +517,36 @@ void Downloader::download() } } } + // Download patches + if (!config.bNoPatches) + { + for (unsigned int j = 0; j < games[i].patches.size(); ++j) + { + // Get link + std::string url = gogAPI->getPatchLink(games[i].gamename, games[i].patches[j].id); + if (gogAPI->getError()) + { + std::cout << gogAPI->getErrorMessage() << std::endl; + gogAPI->clearError(); + continue; + } + + std::string filepath = Util::makeFilepath(config.sDirectory, games[i].patches[j].path, games[i].gamename); + + // Download + if (!url.empty()) + { + std::string XML; + if (!config.bNoRemoteXML) + XML = gogAPI->getXML(games[i].gamename, games[i].patches[j].id); + if (!games[i].patches[j].name.empty()) + std::cout << "Dowloading: " << games[i].gamename << " " << games[i].patches[j].name << std::endl; + std::cout << filepath << std::endl; + this->downloadFile(url, filepath, XML); + std::cout << std::endl; + } + } + } } }