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
This commit is contained in:
Sude 2016-04-25 18:14:04 +03:00
parent 2538825fb2
commit 5bfb00bb31
5 changed files with 108 additions and 74 deletions

View File

@ -13,18 +13,25 @@
#include <vector>
#include <json/json.h>
// 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);

View File

@ -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://";

View File

@ -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);
}
}
}

View File

@ -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<gameFile> 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<gameDetails> 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;

View File

@ -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;
}