From 5bfb00bb31376f12c0ed5fe0f124d4dcc66bb2dd Mon Sep 17 00:00:00 2001 From: Sude Date: Mon, 25 Apr 2016 18:14:04 +0300 Subject: [PATCH] Changed gameFile format and gamedetails cache format gameFile now contains gamename and file type info Game details cache format has been changed to match gameFile changes Cache also has a new "gamedetails-cache-version" field that can be used to detect cache format changes --- include/gamefile.h | 9 +++- include/globalconstants.h | 2 + src/api.cpp | 107 +++++++++++++++++++++----------------- src/downloader.cpp | 45 +++++++++++----- src/gamefile.cpp | 19 +++---- 5 files changed, 108 insertions(+), 74 deletions(-) diff --git a/include/gamefile.h b/include/gamefile.h index e5e59e1..80a37ef 100644 --- a/include/gamefile.h +++ b/include/gamefile.h @@ -13,18 +13,25 @@ #include #include +// 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; + class gameFile { public: gameFile(); - gameFile(const int& t_updated, const std::string& t_id, const std::string& t_name, const std::string& t_path, const std::string& t_size, const unsigned int& t_language = GlobalConstants::LANGUAGE_EN, const unsigned int& t_platform = GlobalConstants::PLATFORM_WINDOWS, const int& t_silent = 0); int updated; + std::string gamename; std::string id; std::string name; std::string path; std::string size; unsigned int platform; unsigned int language; + unsigned int type; int score; int silent; void setFilepath(const std::string& path); diff --git a/include/globalconstants.h b/include/globalconstants.h index 2ae0f96..935ac2f 100644 --- a/include/globalconstants.h +++ b/include/globalconstants.h @@ -12,6 +12,8 @@ namespace GlobalConstants { + const int GAMEDETAILS_CACHE_VERSION = 1; + struct optionsStruct {const unsigned int id; const std::string code; const std::string str; const std::string regexp;}; const std::string PROTOCOL_PREFIX = "gogdownloader://"; diff --git a/src/api.cpp b/src/api.cpp index 13ca1ba..0ada213 100644 --- a/src/api.cpp +++ b/src/api.cpp @@ -349,17 +349,19 @@ gameDetails API::getGameDetails(const std::string& game_name, const unsigned int continue; } - game.installers.push_back( - 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["name"].asString(), - installer["link"].asString(), - installer["size"].asString(), - language, - installers[i].platform, - installer["silent"].isInt() ? installer["silent"].asInt() : std::stoi(installer["silent"].asString()) - ) - ); + gameFile gf; + gf.type = GFTYPE_INSTALLER; + gf.gamename = game.gamename; + gf.updated = installer["notificated"].isInt() ? installer["notificated"].asInt() : std::stoi(installer["notificated"].asString()); + gf.id = installer["id"].isInt() ? std::to_string(installer["id"].asInt()) : installer["id"].asString(); + gf.name = installer["name"].asString(); + gf.path = installer["link"].asString(); + gf.size = installer["size"].asString(); + gf.language = language; + gf.platform = installers[i].platform; + gf.silent = installer["silent"].isInt() ? installer["silent"].asInt() : std::stoi(installer["silent"].asString()); + + game.installers.push_back(gf); } } @@ -369,14 +371,16 @@ gameDetails API::getGameDetails(const std::string& game_name, const unsigned int { Json::Value extra = extras[index]; - game.extras.push_back( - gameFile( false, /* extras don't have "updated" flag */ - extra["id"].isInt() ? std::to_string(extra["id"].asInt()) : extra["id"].asString(), - extra["name"].asString(), - extra["link"].asString(), - extra["size_mb"].asString() - ) - ); + gameFile gf; + gf.type = GFTYPE_EXTRA; + gf.gamename = game.gamename; + gf.updated = false; // extras don't have "updated" flag + gf.id = extra["id"].isInt() ? std::to_string(extra["id"].asInt()) : extra["id"].asString(); + gf.name = extra["name"].asString(); + gf.path = extra["link"].asString(); + gf.size = extra["size_mb"].asString(); + + game.extras.push_back(gf); } // Patch details @@ -434,16 +438,18 @@ gameDetails API::getGameDetails(const std::string& game_name, const unsigned int continue; } - game.patches.push_back( - gameFile( patch["notificated"].isInt() ? patch["notificated"].asInt() : std::stoi(patch["notificated"].asString()), - patch["id"].isInt() ? std::to_string(patch["id"].asInt()) : patch["id"].asString(), - patch["name"].asString(), - patch["link"].asString(), - patch["size"].asString(), - GlobalConstants::LANGUAGES[i].id, - patches[j].platform - ) - ); + gameFile gf; + gf.type = GFTYPE_PATCH; + gf.gamename = game.gamename; + gf.updated = patch["notificated"].isInt() ? patch["notificated"].asInt() : std::stoi(patch["notificated"].asString()); + gf.id = patch["id"].isInt() ? std::to_string(patch["id"].asInt()) : patch["id"].asString(); + gf.name = patch["name"].asString(); + gf.path = patch["link"].asString(); + gf.size = patch["size"].asString(); + gf.language = GlobalConstants::LANGUAGES[i].id; + gf.platform = patches[j].platform; + + game.patches.push_back(gf); } } else // Patch is a single file @@ -465,16 +471,18 @@ gameDetails API::getGameDetails(const std::string& game_name, const unsigned int continue; } - game.patches.push_back( - gameFile( patchnode["notificated"].isInt() ? patchnode["notificated"].asInt() : std::stoi(patchnode["notificated"].asString()), - patchnode["id"].isInt() ? std::to_string(patchnode["id"].asInt()) : patchnode["id"].asString(), - patchnode["name"].asString(), - patchnode["link"].asString(), - patchnode["size"].asString(), - GlobalConstants::LANGUAGES[i].id, - patches[j].platform - ) - ); + gameFile gf; + gf.type = GFTYPE_PATCH; + gf.gamename = game.gamename; + gf.updated = patchnode["notificated"].isInt() ? patchnode["notificated"].asInt() : std::stoi(patchnode["notificated"].asString()); + gf.id = patchnode["id"].isInt() ? std::to_string(patchnode["id"].asInt()) : patchnode["id"].asString(); + gf.name = patchnode["name"].asString(); + gf.path = patchnode["link"].asString(); + gf.size = patchnode["size"].asString(); + gf.language = GlobalConstants::LANGUAGES[i].id; + gf.platform = patches[j].platform; + + game.patches.push_back(gf); } } } @@ -500,15 +508,18 @@ gameDetails API::getGameDetails(const std::string& game_name, const unsigned int for (unsigned int j = 0; j < langpacknames.size(); ++j) { Json::Value langpack = root["game"][langpacknames[j]]; - game.languagepacks.push_back( - gameFile( false, /* language packs don't have "updated" flag */ - langpack["id"].isInt() ? std::to_string(langpack["id"].asInt()) : langpack["id"].asString(), - langpack["name"].asString(), - langpack["link"].asString(), - langpack["size"].asString(), - GlobalConstants::LANGUAGES[i].id - ) - ); + + gameFile gf; + gf.type = GFTYPE_LANGPACK; + gf.gamename = game.gamename; + gf.updated = false; // language packs don't have "updated" flag + gf.id = langpack["id"].isInt() ? std::to_string(langpack["id"].asInt()) : langpack["id"].asString(); + gf.name = langpack["name"].asString(); + gf.path = langpack["link"].asString(); + gf.size = langpack["size"].asString(); + gf.language = GlobalConstants::LANGUAGES[i].id; + + game.languagepacks.push_back(gf); } } } diff --git a/src/downloader.cpp b/src/downloader.cpp index 2761263..630fc40 100644 --- a/src/downloader.cpp +++ b/src/downloader.cpp @@ -256,6 +256,11 @@ int Downloader::getGameDetails() std::cerr << "Cache is too old." << std::endl; std::cerr << "Update cache with --update-cache or use bigger --cache-valid" << std::endl; } + else if (result == 5) + { + std::cerr << "Cache version doesn't match current version." << std::endl; + std::cerr << "Update cache with --update-cache" << std::endl; + } return 1; } } @@ -2056,14 +2061,15 @@ std::vector Downloader::getExtrasFromJSON(const Json::Value& json, con continue; } - extras.push_back( - gameFile ( false, - id, - name, - path, - std::string() - ) - ); + gameFile gf; + gf.type = GFTYPE_EXTRA; + gf.gamename = gamename; + gf.updated = false; + gf.id = id; + gf.name = name; + gf.path = path; + + extras.push_back(gf); } return extras; @@ -2609,6 +2615,7 @@ std::string Downloader::getRemoteFileHash(const std::string& gamename, const std returns 2 if JSON parsing failed returns 3 if cache is too old returns 4 if JSON doesn't contain "games" node + returns 5 if cache version doesn't match */ int Downloader::loadGameDetailsCache() { @@ -2641,14 +2648,25 @@ int Downloader::loadGameDetailsCache() } } - if (root.isMember("games")) + int iCacheVersion = 0; + if (root.isMember("gamedetails-cache-version")) + iCacheVersion = root["gamedetails-cache-version"].asInt(); + + if (iCacheVersion != GlobalConstants::GAMEDETAILS_CACHE_VERSION) { - this->games = getGameDetailsFromJsonNode(root["games"]); - res = 0; + res = 5; } else { - res = 4; + if (root.isMember("games")) + { + this->games = getGameDetailsFromJsonNode(root["games"]); + res = 0; + } + else + { + res = 4; + } } } else @@ -2681,6 +2699,7 @@ int Downloader::saveGameDetailsCache() Json::Value json; + json["gamedetails-cache-version"] = GlobalConstants::GAMEDETAILS_CACHE_VERSION; json["version-string"] = config.sVersionString; json["version-number"] = config.sVersionNumber; json["date"] = bptime::to_iso_string(bptime::second_clock::local_time()); @@ -2764,6 +2783,8 @@ std::vector Downloader::getGameDetailsFromJsonNode(Json::Value root fileDetails.platform = fileDetailsNode["platform"].asUInt(); fileDetails.language = fileDetailsNode["language"].asUInt(); fileDetails.silent = fileDetailsNode["silent"].asInt(); + fileDetails.gamename = fileDetailsNode["gamename"].asString(); + fileDetails.type = fileDetailsNode["type"].asUInt(); if (nodeName != "extras" && !(fileDetails.platform & conf.iInstallerPlatform)) continue; diff --git a/src/gamefile.cpp b/src/gamefile.cpp index 9b85995..d78623e 100644 --- a/src/gamefile.cpp +++ b/src/gamefile.cpp @@ -6,21 +6,12 @@ #include "gamefile.h" -gameFile::gameFile(const int& t_updated, const std::string& t_id, const std::string& t_name, const std::string& t_path, const std::string& t_size, const unsigned int& t_language, const unsigned int& t_platform, const int& t_silent) -{ - this->updated = t_updated; - this->id = t_id; - this->name = t_name; - this->path = t_path; - this->size = t_size; - this->platform = t_platform; - this->language = t_language; - this->silent = t_silent; -} - gameFile::gameFile() { - //ctor + this->platform = GlobalConstants::PLATFORM_WINDOWS; + this->language = GlobalConstants::LANGUAGE_EN; + this->silent = 0; + this->type = 0; } gameFile::~gameFile() @@ -50,6 +41,8 @@ Json::Value gameFile::getAsJson() json["platform"] = this->platform; json["language"] = this->language; json["silent"] = this->silent; + json["gamename"] = this->gamename; + json["type"] = this->type; return json; }