API change: added duplicate handler for installers

API::getGameDetails now has a parameter to enable duplicate handling (default: false)
The duplicate handler applies a language id flag on the original installer so it shows support for multiple languages

Downloader uses duplicate handler by default
Added --no-duplicate-handling option to disable duplicate handler
This commit is contained in:
Sude 2013-11-18 13:19:02 +02:00
parent 1cd79a2292
commit c4585d3d61
5 changed files with 37 additions and 6 deletions

View File

@ -83,7 +83,7 @@ class API
std::string getResponseOAuth(const std::string& url); std::string getResponseOAuth(const std::string& url);
int getUserDetails(); int getUserDetails();
int getGames(); int getGames();
gameDetails getGameDetails(const std::string& game_name, const unsigned int& type = GlobalConstants::PLATFORM_WINDOWS, const unsigned int& lang = GlobalConstants::LANGUAGE_EN); gameDetails getGameDetails(const std::string& game_name, const unsigned int& type = GlobalConstants::PLATFORM_WINDOWS, const unsigned int& lang = GlobalConstants::LANGUAGE_EN, const bool& useDuplicateHandler = false);
std::string getInstallerLink(const std::string& game_name, const std::string& id); 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 getExtraLink(const std::string& game_name, const std::string& id);
std::string getPatchLink(const std::string& game_name, const std::string& id); std::string getPatchLink(const std::string& game_name, const std::string& id);

View File

@ -33,6 +33,7 @@ class Config
bool bVerifyPeer; bool bVerifyPeer;
bool bCheckOrphans; bool bCheckOrphans;
bool bCheckStatus; bool bCheckStatus;
bool bDuplicateHandler;
std::string sGameRegex; std::string sGameRegex;
std::string sDirectory; std::string sDirectory;
std::string sXMLFile; std::string sXMLFile;

View File

@ -78,6 +78,7 @@ int main(int argc, char *argv[])
bool bInsecure = false; bool bInsecure = false;
bool bNoColor = false; bool bNoColor = false;
bool bNoUnicode = false; bool bNoUnicode = false;
bool bNoDuplicateHandler = false;
desc.add_options() desc.add_options()
("help,h", "Print help message") ("help,h", "Print help message")
("login", bpo::value<bool>(&config.bLogin)->zero_tokens()->default_value(false), "Login") ("login", bpo::value<bool>(&config.bLogin)->zero_tokens()->default_value(false), "Login")
@ -102,6 +103,7 @@ int main(int argc, char *argv[])
("no-remote-xml", bpo::value<bool>(&config.bNoRemoteXML)->zero_tokens()->default_value(false), "Don't use remote XML for repair") ("no-remote-xml", bpo::value<bool>(&config.bNoRemoteXML)->zero_tokens()->default_value(false), "Don't use remote XML for repair")
("no-unicode", bpo::value<bool>(&bNoUnicode)->zero_tokens()->default_value(false), "Don't use Unicode in the progress bar") ("no-unicode", bpo::value<bool>(&bNoUnicode)->zero_tokens()->default_value(false), "Don't use Unicode in the progress bar")
("no-color", bpo::value<bool>(&bNoColor)->zero_tokens()->default_value(false), "Don't use coloring in the progress bar") ("no-color", bpo::value<bool>(&bNoColor)->zero_tokens()->default_value(false), "Don't use coloring in the progress bar")
("no-duplicate-handling", bpo::value<bool>(&bNoDuplicateHandler)->zero_tokens()->default_value(false), "Don't use duplicate handler for installers\nDuplicate installers from different languages are handled separately")
("verbose", bpo::value<bool>(&config.bVerbose)->zero_tokens()->default_value(false), "Print lots of information") ("verbose", bpo::value<bool>(&config.bVerbose)->zero_tokens()->default_value(false), "Print lots of information")
("insecure", bpo::value<bool>(&bInsecure)->zero_tokens()->default_value(false), "Don't verify authenticity of SSL certificates") ("insecure", bpo::value<bool>(&bInsecure)->zero_tokens()->default_value(false), "Don't verify authenticity of SSL certificates")
("timeout", bpo::value<long int>(&config.iTimeout)->default_value(10), "Set timeout for connection\nMaximum time in seconds that connection phase is allowed to take") ("timeout", bpo::value<long int>(&config.iTimeout)->default_value(10), "Set timeout for connection\nMaximum time in seconds that connection phase is allowed to take")
@ -150,6 +152,7 @@ int main(int argc, char *argv[])
config.bVerifyPeer = !bInsecure; config.bVerifyPeer = !bInsecure;
config.bColor = !bNoColor; config.bColor = !bNoColor;
config.bUnicode = !bNoUnicode; config.bUnicode = !bNoUnicode;
config.bDuplicateHandler = !bNoDuplicateHandler;
} }
catch (std::exception& e) catch (std::exception& e)
{ {

View File

@ -264,7 +264,7 @@ std::string API::getResponseOAuth(const std::string& url)
return response; return response;
} }
gameDetails API::getGameDetails(const std::string& game_name, const unsigned int& type, const unsigned int& lang) gameDetails API::getGameDetails(const std::string& game_name, const unsigned int& type, const unsigned int& lang, const bool& useDuplicateHandler)
{ {
std::string url; std::string url;
gameDetails game; gameDetails game;
@ -296,6 +296,7 @@ gameDetails API::getGameDetails(const std::string& game_name, const unsigned int
{ {
if (lang & GlobalConstants::LANGUAGES[j].languageId) if (lang & GlobalConstants::LANGUAGES[j].languageId)
{ {
if (root["game"].isMember(installer+GlobalConstants::LANGUAGES[j].languageCode))
installers.push_back(std::make_pair(root["game"][installer+GlobalConstants::LANGUAGES[j].languageCode],GlobalConstants::LANGUAGES[j].languageId)); installers.push_back(std::make_pair(root["game"][installer+GlobalConstants::LANGUAGES[j].languageCode],GlobalConstants::LANGUAGES[j].languageId));
} }
} }
@ -309,6 +310,24 @@ gameDetails API::getGameDetails(const std::string& game_name, const unsigned int
Json::Value installer = installers[i].first[index]; Json::Value installer = installers[i].first[index];
unsigned int language = installers[i].second; unsigned int language = installers[i].second;
// Check for duplicate installers in different languages and add languageId of duplicate installer to the original installer
// https://secure.gog.com/forum/general/introducing_the_beta_release_of_the_new_gogcom_downloader/post1483
if (useDuplicateHandler)
{
bool bDuplicate = false;
for (unsigned int j = 0; j < game.installers.size(); ++j)
{
if (game.installers[j].path == installer["link"].asString())
{
game.installers[j].language |= language;
bDuplicate = true;
break;
}
}
if (bDuplicate)
continue;
}
game.installers.push_back( game.installers.push_back(
gameFile( installer["notificated"].isInt() ? installer["notificated"].asInt() : std::stoi(installer["notificated"].asString()), gameFile( installer["notificated"].isInt() ? installer["notificated"].asInt() : std::stoi(installer["notificated"].asString()),
installer["id"].isInt() ? std::to_string(installer["id"].asInt()) : installer["id"].asString(), installer["id"].isInt() ? std::to_string(installer["id"].asInt()) : installer["id"].asString(),

View File

@ -224,7 +224,7 @@ int Downloader::getGameDetails()
for (unsigned int i = 0; i < gameNamesIds.size(); ++i) for (unsigned int i = 0; i < gameNamesIds.size(); ++i)
{ {
std::cout << "Getting game info " << i+1 << " / " << gameNamesIds.size() << "\r" << std::flush; std::cout << "Getting game info " << i+1 << " / " << gameNamesIds.size() << "\r" << std::flush;
game = gogAPI->getGameDetails(gameNamesIds[i].first, config.iInstallerType, config.iInstallerLanguage); game = gogAPI->getGameDetails(gameNamesIds[i].first, config.iInstallerType, config.iInstallerLanguage, config.bDuplicateHandler);
if (!gogAPI->getError()) if (!gogAPI->getError())
{ {
if (game.extras.empty() && !config.bNoExtras) if (game.extras.empty() && !config.bNoExtras)
@ -278,11 +278,19 @@ void Downloader::listGames()
{ {
if (!config.bUpdateCheck || games[i].installers[j].updated) // Always list updated files if (!config.bUpdateCheck || games[i].installers[j].updated) // Always list updated files
{ {
std::string languages;
for (unsigned int k = 0; k < GlobalConstants::LANGUAGES.size(); k++)
{
if (games[i].installers[j].language & GlobalConstants::LANGUAGES[k].languageId)
languages += (languages.empty() ? "" : ", ")+GlobalConstants::LANGUAGES[k].languageString;
}
std::cout << "\tid: " << games[i].installers[j].id << std::endl std::cout << "\tid: " << games[i].installers[j].id << std::endl
<< "\tname: " << games[i].installers[j].name << std::endl << "\tname: " << games[i].installers[j].name << std::endl
<< "\tpath: " << games[i].installers[j].path << std::endl << "\tpath: " << games[i].installers[j].path << std::endl
<< "\tsize: " << games[i].installers[j].size << std::endl << "\tsize: " << games[i].installers[j].size << std::endl
<< "\tupdated: " << (games[i].installers[j].updated ? "True" : "False") << std::endl << "\tupdated: " << (games[i].installers[j].updated ? "True" : "False") << std::endl
<< "\tlanguage: " << languages << std::endl
<< std::endl; << std::endl;
} }
} }
@ -467,6 +475,8 @@ void Downloader::download()
if (config.bUpdateCheck && !games[i].installers[j].updated) if (config.bUpdateCheck && !games[i].installers[j].updated)
continue; continue;
std::string filepath = Util::makeFilepath(config.sDirectory, games[i].installers[j].path, games[i].gamename);
// Get link // Get link
std::string url = gogAPI->getInstallerLink(games[i].gamename, games[i].installers[j].id); std::string url = gogAPI->getInstallerLink(games[i].gamename, games[i].installers[j].id);
if (gogAPI->getError()) if (gogAPI->getError())
@ -476,8 +486,6 @@ void Downloader::download()
continue; continue;
} }
std::string filepath = Util::makeFilepath(config.sDirectory, games[i].installers[j].path, games[i].gamename);
// Download // Download
if (!url.empty()) if (!url.empty())
{ {