mirror of
https://github.com/Sude-/lgogdownloader.git
synced 2025-02-02 05:52:31 +01:00
Replace --update-check option and remove --game aliases
Replace --update-check option with --updated and --notifications options --updated restricts downloader to operate only on games that have update flag set in account page --notifications shows the number of new forum replies, updates games, unread chat messages and pending friend requests --clear-update-flags clears update notification flags for all games Remove aliases for --game option "free" could no longer be used as originally intended and "all" was unnecessary because leaving regex empty has the same effect
This commit is contained in:
parent
9dc5d4124c
commit
8e9c094929
@ -213,11 +213,12 @@ class Config
|
|||||||
|
|
||||||
bool bDownload;
|
bool bDownload;
|
||||||
bool bRepair;
|
bool bRepair;
|
||||||
bool bUpdateCheck;
|
bool bUpdated;
|
||||||
bool bList;
|
bool bList;
|
||||||
bool bListDetails;
|
bool bListDetails;
|
||||||
bool bCheckStatus;
|
bool bCheckStatus;
|
||||||
bool bShowWishlist;
|
bool bShowWishlist;
|
||||||
|
bool bNotifications;
|
||||||
|
|
||||||
bool bVerbose;
|
bool bVerbose;
|
||||||
bool bUnicode; // use Unicode in console output
|
bool bUnicode; // use Unicode in console output
|
||||||
|
@ -91,7 +91,8 @@ class Downloader
|
|||||||
int init();
|
int init();
|
||||||
int login();
|
int login();
|
||||||
int listGames();
|
int listGames();
|
||||||
void updateCheck();
|
void checkNotifications();
|
||||||
|
void clearUpdateNotifications();
|
||||||
void repair();
|
void repair();
|
||||||
void download();
|
void download();
|
||||||
void checkOrphans();
|
void checkOrphans();
|
||||||
|
@ -53,10 +53,12 @@ class galaxyAPI
|
|||||||
Json::Value getManifestV2(std::string manifest_hash);
|
Json::Value getManifestV2(std::string manifest_hash);
|
||||||
Json::Value getSecureLink(const std::string& product_id, const std::string& path);
|
Json::Value getSecureLink(const std::string& product_id, const std::string& path);
|
||||||
std::string getResponse(const std::string& url, const bool& zlib_decompress = false);
|
std::string getResponse(const std::string& url, const bool& zlib_decompress = false);
|
||||||
|
Json::Value getResponseJson(const std::string& url, const bool& zlib_decompress = false);
|
||||||
std::string hashToGalaxyPath(const std::string& hash);
|
std::string hashToGalaxyPath(const std::string& hash);
|
||||||
std::vector<galaxyDepotItem> getDepotItemsVector(const std::string& hash);
|
std::vector<galaxyDepotItem> getDepotItemsVector(const std::string& hash);
|
||||||
Json::Value getProductInfo(const std::string& product_id);
|
Json::Value getProductInfo(const std::string& product_id);
|
||||||
gameDetails productInfoJsonToGameDetails(const Json::Value& json, const DownloadConfig& dlConf);
|
gameDetails productInfoJsonToGameDetails(const Json::Value& json, const DownloadConfig& dlConf);
|
||||||
|
Json::Value getUserData();
|
||||||
protected:
|
protected:
|
||||||
private:
|
private:
|
||||||
CurlConfig curlConf;
|
CurlConfig curlConf;
|
||||||
|
@ -22,7 +22,6 @@ class Website
|
|||||||
std::string getResponse(const std::string& url);
|
std::string getResponse(const std::string& url);
|
||||||
Json::Value getGameDetailsJSON(const std::string& gameid);
|
Json::Value getGameDetailsJSON(const std::string& gameid);
|
||||||
std::vector<gameItem> getGames();
|
std::vector<gameItem> getGames();
|
||||||
std::vector<gameItem> getFreeGames();
|
|
||||||
std::vector<wishlistItem> getWishlistItems();
|
std::vector<wishlistItem> getWishlistItems();
|
||||||
bool IsLoggedIn();
|
bool IsLoggedIn();
|
||||||
virtual ~Website();
|
virtual ~Website();
|
||||||
@ -30,7 +29,6 @@ class Website
|
|||||||
private:
|
private:
|
||||||
static size_t writeMemoryCallback(char *ptr, size_t size, size_t nmemb, void *userp);
|
static size_t writeMemoryCallback(char *ptr, size_t size, size_t nmemb, void *userp);
|
||||||
CURL* curlhandle;
|
CURL* curlhandle;
|
||||||
Config config;
|
|
||||||
bool IsloggedInSimple();
|
bool IsloggedInSimple();
|
||||||
bool IsLoggedInComplex(const std::string& email);
|
bool IsLoggedInComplex(const std::string& email);
|
||||||
int retries;
|
int retries;
|
||||||
|
13
main.cpp
13
main.cpp
@ -133,6 +133,7 @@ int main(int argc, char *argv[])
|
|||||||
bpo::options_description options_cli_cfg;
|
bpo::options_description options_cli_cfg;
|
||||||
bpo::options_description options_cfg_only;
|
bpo::options_description options_cfg_only;
|
||||||
bpo::options_description options_cfg_all("Configuration");
|
bpo::options_description options_cfg_all("Configuration");
|
||||||
|
bool bClearUpdateNotifications = false;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
bool bInsecure = false;
|
bool bInsecure = false;
|
||||||
@ -160,9 +161,11 @@ int main(int argc, char *argv[])
|
|||||||
("list-details", bpo::value<bool>(&Globals::globalConfig.bListDetails)->zero_tokens()->default_value(false), "List games with detailed info")
|
("list-details", bpo::value<bool>(&Globals::globalConfig.bListDetails)->zero_tokens()->default_value(false), "List games with detailed info")
|
||||||
("download", bpo::value<bool>(&Globals::globalConfig.bDownload)->zero_tokens()->default_value(false), "Download")
|
("download", bpo::value<bool>(&Globals::globalConfig.bDownload)->zero_tokens()->default_value(false), "Download")
|
||||||
("repair", bpo::value<bool>(&Globals::globalConfig.bRepair)->zero_tokens()->default_value(false), "Repair downloaded files\nUse --repair --download to redownload files when filesizes don't match (possibly different version). Redownload will rename the old file (appends .old to filename)")
|
("repair", bpo::value<bool>(&Globals::globalConfig.bRepair)->zero_tokens()->default_value(false), "Repair downloaded files\nUse --repair --download to redownload files when filesizes don't match (possibly different version). Redownload will rename the old file (appends .old to filename)")
|
||||||
("game", bpo::value<std::string>(&Globals::globalConfig.sGameRegex)->default_value(""), "Set regular expression filter\nfor download/list/repair (Perl syntax)\nAliases: \"all\", \"free\"\nAlias \"free\" doesn't work with cached details")
|
("game", bpo::value<std::string>(&Globals::globalConfig.sGameRegex)->default_value(""), "Set regular expression filter\nfor download/list/repair (Perl syntax)")
|
||||||
("create-xml", bpo::value<std::string>(&Globals::globalConfig.sXMLFile)->implicit_value("automatic"), "Create GOG XML for file\n\"automatic\" to enable automatic XML creation")
|
("create-xml", bpo::value<std::string>(&Globals::globalConfig.sXMLFile)->implicit_value("automatic"), "Create GOG XML for file\n\"automatic\" to enable automatic XML creation")
|
||||||
("update-check", bpo::value<bool>(&Globals::globalConfig.bUpdateCheck)->zero_tokens()->default_value(false), "Check for update notifications")
|
("notifications", bpo::value<bool>(&Globals::globalConfig.bNotifications)->zero_tokens()->default_value(false), "Check notifications")
|
||||||
|
("updated", bpo::value<bool>(&Globals::globalConfig.bUpdated)->zero_tokens()->default_value(false), "List/download only games with update flag set")
|
||||||
|
("clear-update-flags", bpo::value<bool>(&bClearUpdateNotifications)->zero_tokens()->default_value(false), "Clear update notification flags")
|
||||||
("check-orphans", bpo::value<std::string>(&Globals::globalConfig.sOrphanRegex)->implicit_value(""), check_orphans_text.c_str())
|
("check-orphans", bpo::value<std::string>(&Globals::globalConfig.sOrphanRegex)->implicit_value(""), check_orphans_text.c_str())
|
||||||
("status", bpo::value<bool>(&Globals::globalConfig.bCheckStatus)->zero_tokens()->default_value(false), "Show status of files\n\nOutput format:\nstatuscode gamename filename filesize filehash\n\nStatus codes:\nOK - File is OK\nND - File is not downloaded\nMD5 - MD5 mismatch, different version\nFS - File size mismatch, incomplete download")
|
("status", bpo::value<bool>(&Globals::globalConfig.bCheckStatus)->zero_tokens()->default_value(false), "Show status of files\n\nOutput format:\nstatuscode gamename filename filesize filehash\n\nStatus codes:\nOK - File is OK\nND - File is not downloaded\nMD5 - MD5 mismatch, different version\nFS - File size mismatch, incomplete download")
|
||||||
("save-config", bpo::value<bool>(&Globals::globalConfig.bSaveConfig)->zero_tokens()->default_value(false), "Create config file with current settings")
|
("save-config", bpo::value<bool>(&Globals::globalConfig.bSaveConfig)->zero_tokens()->default_value(false), "Create config file with current settings")
|
||||||
@ -721,8 +724,10 @@ int main(int argc, char *argv[])
|
|||||||
downloader.showWishlist();
|
downloader.showWishlist();
|
||||||
else if (Globals::globalConfig.bUpdateCache)
|
else if (Globals::globalConfig.bUpdateCache)
|
||||||
downloader.updateCache();
|
downloader.updateCache();
|
||||||
else if (Globals::globalConfig.bUpdateCheck) // Update check has priority over download and list
|
else if (Globals::globalConfig.bNotifications)
|
||||||
downloader.updateCheck();
|
downloader.checkNotifications();
|
||||||
|
else if (bClearUpdateNotifications)
|
||||||
|
downloader.clearUpdateNotifications();
|
||||||
else if (!vFileIdStrings.empty())
|
else if (!vFileIdStrings.empty())
|
||||||
{
|
{
|
||||||
for (std::vector<std::string>::iterator it = vFileIdStrings.begin(); it != vFileIdStrings.end(); it++)
|
for (std::vector<std::string>::iterator it = vFileIdStrings.begin(); it != vFileIdStrings.end(); it++)
|
||||||
|
@ -354,38 +354,62 @@ int Downloader::login()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Downloader::updateCheck()
|
void Downloader::checkNotifications()
|
||||||
{
|
{
|
||||||
std::cout << "New forum replies: " << gogAPI->user.notifications_forum << std::endl;
|
Json::Value userData = gogGalaxy->getUserData();
|
||||||
std::cout << "New private messages: " << gogAPI->user.notifications_messages << std::endl;
|
|
||||||
std::cout << "Updated games: " << gogAPI->user.notifications_games << std::endl;
|
|
||||||
|
|
||||||
if (gogAPI->user.notifications_games)
|
if (userData.empty())
|
||||||
{
|
{
|
||||||
Globals::globalConfig.sGameRegex = ".*"; // Always check all games
|
std::cout << "Empty JSON response" << std::endl;
|
||||||
if (Globals::globalConfig.bList || Globals::globalConfig.bListDetails || Globals::globalConfig.bDownload)
|
return;
|
||||||
{
|
|
||||||
if (Globals::globalConfig.bList)
|
|
||||||
Globals::globalConfig.bListDetails = true; // Always list details
|
|
||||||
this->getGameList();
|
|
||||||
if (Globals::globalConfig.bDownload)
|
|
||||||
this->download();
|
|
||||||
else
|
|
||||||
this->listGames();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!userData.isMember("updates"))
|
||||||
|
{
|
||||||
|
std::cout << "Invalid JSON response" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "New forum replies: " << userData["updates"]["messages"].asInt() << std::endl;
|
||||||
|
std::cout << "Updated games: " << userData["updates"]["products"].asInt() << std::endl;
|
||||||
|
std::cout << "Unread chat messages: " << userData["updates"]["unreadChatMessages"].asInt() << std::endl;
|
||||||
|
std::cout << "Pending friend requests: " << userData["updates"]["pendingFriendRequests"].asInt() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Downloader::clearUpdateNotifications()
|
||||||
|
{
|
||||||
|
Json::Value userData = gogGalaxy->getUserData();
|
||||||
|
if (userData.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!userData.isMember("updates"))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userData["updates"]["products"].asInt() < 1)
|
||||||
|
{
|
||||||
|
std::cout << "No updates" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Globals::globalConfig.bUpdated = true;
|
||||||
|
this->getGameList();
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < gameItems.size(); ++i)
|
||||||
|
{
|
||||||
|
// Getting game details should remove the update flag
|
||||||
|
std::cerr << "\033[KClearing update flags " << i+1 << " / " << gameItems.size() << "\r" << std::flush;
|
||||||
|
Json::Value details = gogWebsite->getGameDetailsJSON(gameItems[i].id);
|
||||||
|
}
|
||||||
|
std::cerr << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Downloader::getGameList()
|
void Downloader::getGameList()
|
||||||
{
|
{
|
||||||
if (Globals::globalConfig.sGameRegex == "free")
|
gameItems = gogWebsite->getGames();
|
||||||
{
|
|
||||||
gameItems = gogWebsite->getFreeGames();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gameItems = gogWebsite->getGames();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get detailed info about the games
|
/* Get detailed info about the games
|
||||||
@ -399,12 +423,6 @@ int Downloader::getGameDetails()
|
|||||||
|
|
||||||
if (Globals::globalConfig.bUseCache && !Globals::globalConfig.bUpdateCache)
|
if (Globals::globalConfig.bUseCache && !Globals::globalConfig.bUpdateCache)
|
||||||
{
|
{
|
||||||
// GameRegex filter alias for all games
|
|
||||||
if (Globals::globalConfig.sGameRegex == "all")
|
|
||||||
Globals::globalConfig.sGameRegex = ".*";
|
|
||||||
else if (Globals::globalConfig.sGameRegex == "free")
|
|
||||||
std::cerr << "Warning: regex alias \"free\" doesn't work with cached details" << std::endl;
|
|
||||||
|
|
||||||
int result = this->loadGameDetailsCache();
|
int result = this->loadGameDetailsCache();
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
{
|
{
|
||||||
@ -531,35 +549,32 @@ int Downloader::listGames()
|
|||||||
std::cout << "serials:" << std::endl << games[i].serials << std::endl;
|
std::cout << "serials:" << std::endl << games[i].serials << std::endl;
|
||||||
|
|
||||||
// List installers
|
// List installers
|
||||||
if (Globals::globalConfig.dlConf.bInstallers)
|
if (Globals::globalConfig.dlConf.bInstallers && !games[i].installers.empty())
|
||||||
{
|
{
|
||||||
std::cout << "installers: " << std::endl;
|
std::cout << "installers: " << std::endl;
|
||||||
for (unsigned int j = 0; j < games[i].installers.size(); ++j)
|
for (unsigned int j = 0; j < games[i].installers.size(); ++j)
|
||||||
{
|
{
|
||||||
if (!Globals::globalConfig.bUpdateCheck || games[i].installers[j].updated) // Always list updated files
|
std::string filepath = games[i].installers[j].getFilepath();
|
||||||
|
if (Globals::globalConfig.blacklist.isBlacklisted(filepath))
|
||||||
{
|
{
|
||||||
std::string filepath = games[i].installers[j].getFilepath();
|
if (Globals::globalConfig.bVerbose)
|
||||||
if (Globals::globalConfig.blacklist.isBlacklisted(filepath))
|
std::cerr << "skipped blacklisted file " << filepath << std::endl;
|
||||||
{
|
continue;
|
||||||
if (Globals::globalConfig.bVerbose)
|
|
||||||
std::cerr << "skipped blacklisted file " << filepath << std::endl;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string languages = Util::getOptionNameString(games[i].installers[j].language, GlobalConstants::LANGUAGES);
|
|
||||||
|
|
||||||
std::cout << "\tid: " << games[i].installers[j].id << std::endl
|
|
||||||
<< "\tname: " << games[i].installers[j].name << std::endl
|
|
||||||
<< "\tpath: " << games[i].installers[j].path << std::endl
|
|
||||||
<< "\tsize: " << games[i].installers[j].size << std::endl
|
|
||||||
<< "\tupdated: " << (games[i].installers[j].updated ? "True" : "False") << std::endl
|
|
||||||
<< "\tlanguage: " << languages << std::endl
|
|
||||||
<< std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string languages = Util::getOptionNameString(games[i].installers[j].language, GlobalConstants::LANGUAGES);
|
||||||
|
|
||||||
|
std::cout << "\tid: " << games[i].installers[j].id << std::endl
|
||||||
|
<< "\tname: " << games[i].installers[j].name << std::endl
|
||||||
|
<< "\tpath: " << games[i].installers[j].path << std::endl
|
||||||
|
<< "\tsize: " << games[i].installers[j].size << std::endl
|
||||||
|
<< "\tupdated: " << (games[i].installers[j].updated ? "True" : "False") << std::endl
|
||||||
|
<< "\tlanguage: " << languages << std::endl
|
||||||
|
<< std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// List extras
|
// List extras
|
||||||
if (Globals::globalConfig.dlConf.bExtras && !Globals::globalConfig.bUpdateCheck && !games[i].extras.empty())
|
if (Globals::globalConfig.dlConf.bExtras && !games[i].extras.empty())
|
||||||
{
|
{
|
||||||
std::cout << "extras: " << std::endl;
|
std::cout << "extras: " << std::endl;
|
||||||
for (unsigned int j = 0; j < games[i].extras.size(); ++j)
|
for (unsigned int j = 0; j < games[i].extras.size(); ++j)
|
||||||
@ -580,7 +595,7 @@ int Downloader::listGames()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// List patches
|
// List patches
|
||||||
if (Globals::globalConfig.dlConf.bPatches && !Globals::globalConfig.bUpdateCheck && !games[i].patches.empty())
|
if (Globals::globalConfig.dlConf.bPatches && !games[i].patches.empty())
|
||||||
{
|
{
|
||||||
std::cout << "patches: " << std::endl;
|
std::cout << "patches: " << std::endl;
|
||||||
for (unsigned int j = 0; j < games[i].patches.size(); ++j)
|
for (unsigned int j = 0; j < games[i].patches.size(); ++j)
|
||||||
@ -605,7 +620,7 @@ int Downloader::listGames()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// List language packs
|
// List language packs
|
||||||
if (Globals::globalConfig.dlConf.bLanguagePacks && !Globals::globalConfig.bUpdateCheck && !games[i].languagepacks.empty())
|
if (Globals::globalConfig.dlConf.bLanguagePacks && !games[i].languagepacks.empty())
|
||||||
{
|
{
|
||||||
std::cout << "language packs: " << std::endl;
|
std::cout << "language packs: " << std::endl;
|
||||||
for (unsigned int j = 0; j < games[i].languagepacks.size(); ++j)
|
for (unsigned int j = 0; j < games[i].languagepacks.size(); ++j)
|
||||||
@ -782,19 +797,11 @@ void Downloader::repair()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Json::Value downlinkJson;
|
Json::Value downlinkJson = gogGalaxy->getResponseJson(vGameFiles[i].galaxy_downlink_json_url);
|
||||||
std::string response = gogGalaxy->getResponse(vGameFiles[i].galaxy_downlink_json_url);
|
|
||||||
|
|
||||||
if (response.empty())
|
if (downlinkJson.empty())
|
||||||
{
|
{
|
||||||
std::cerr << "Found nothing in " << vGameFiles[i].galaxy_downlink_json_url << ", skipping file" << std::endl;
|
std::cerr << "Empty JSON response, skipping file" << std::endl;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
std::istringstream iss(response);
|
|
||||||
iss >> downlinkJson;
|
|
||||||
} catch (const Json::Exception& exc) {
|
|
||||||
std::cerr << "Could not parse JSON response, skipping file" << std::endl;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2653,20 +2660,11 @@ void Downloader::processDownloadQueue(Config conf, const unsigned int& tid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get downlink JSON from Galaxy API
|
// Get downlink JSON from Galaxy API
|
||||||
Json::Value downlinkJson;
|
Json::Value downlinkJson = galaxy->getResponseJson(gf.galaxy_downlink_json_url);
|
||||||
std::string response = galaxy->getResponse(gf.galaxy_downlink_json_url);
|
|
||||||
|
|
||||||
if (response.empty())
|
if (downlinkJson.empty())
|
||||||
{
|
{
|
||||||
msgQueue.push(Message("Found nothing in " + gf.galaxy_downlink_json_url + ", skipping file", MSGTYPE_WARNING, msg_prefix));
|
msgQueue.push(Message("Empty JSON response, skipping file", MSGTYPE_WARNING, msg_prefix));
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
std::istringstream iss(response);
|
|
||||||
iss >> downlinkJson;
|
|
||||||
} catch (const Json::Exception& exc) {
|
|
||||||
msgQueue.push(Message("Could not parse JSON response, skipping file", MSGTYPE_WARNING, msg_prefix));
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3226,20 +3224,7 @@ void Downloader::getGameDetailsThread(Config config, const unsigned int& tid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
game.makeFilepaths(conf.dirConf);
|
game.makeFilepaths(conf.dirConf);
|
||||||
|
gameDetailsQueue.push(game);
|
||||||
if (!config.bUpdateCheck)
|
|
||||||
gameDetailsQueue.push(game);
|
|
||||||
else
|
|
||||||
{ // Update check, only add games that have updated files
|
|
||||||
for (unsigned int j = 0; j < game.installers.size(); ++j)
|
|
||||||
{
|
|
||||||
if (game.installers[j].updated)
|
|
||||||
{
|
|
||||||
gameDetailsQueue.push(game);
|
|
||||||
break; // add the game only once
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vDownloadInfo[tid].setStatus(DLSTATUS_FINISHED);
|
vDownloadInfo[tid].setStatus(DLSTATUS_FINISHED);
|
||||||
@ -4458,23 +4443,11 @@ void Downloader::processGalaxyDownloadQueue_MojoSetupHack(Config conf, const uns
|
|||||||
|
|
||||||
int Downloader::mojoSetupGetFileVector(const gameFile& gf, std::vector<zipFileEntry>& vFiles)
|
int Downloader::mojoSetupGetFileVector(const gameFile& gf, std::vector<zipFileEntry>& vFiles)
|
||||||
{
|
{
|
||||||
Json::Value downlinkJson;
|
Json::Value downlinkJson = gogGalaxy->getResponseJson(gf.galaxy_downlink_json_url);
|
||||||
std::string response = gogGalaxy->getResponse(gf.galaxy_downlink_json_url);
|
|
||||||
|
|
||||||
if (response.empty())
|
if (downlinkJson.empty())
|
||||||
{
|
{
|
||||||
std::cerr << "Found nothing in " << gf.galaxy_downlink_json_url << std::endl;
|
std::cerr << "Empty JSON response" << std::endl;
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
std::istringstream iss(response);
|
|
||||||
iss >> downlinkJson;
|
|
||||||
}
|
|
||||||
catch (const Json::Exception& exc)
|
|
||||||
{
|
|
||||||
std::cerr << "Could not parse JSON response" << std::endl;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,18 +77,12 @@ bool galaxyAPI::refreshLogin()
|
|||||||
+ "&grant_type=refresh_token"
|
+ "&grant_type=refresh_token"
|
||||||
+ "&refresh_token=" + Globals::galaxyConf.getRefreshToken();
|
+ "&refresh_token=" + Globals::galaxyConf.getRefreshToken();
|
||||||
|
|
||||||
std::string json = this->getResponse(refresh_url);
|
Json::Value token_json = this->getResponseJson(refresh_url);
|
||||||
if (json.empty())
|
|
||||||
|
if (token_json.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Json::Value token_json;
|
Globals::galaxyConf.setJSON(token_json);
|
||||||
std::istringstream json_stream(json);
|
|
||||||
try {
|
|
||||||
json_stream >> token_json;
|
|
||||||
Globals::galaxyConf.setJSON(token_json);
|
|
||||||
} catch (const Json::Exception& exc) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -143,10 +137,9 @@ std::string galaxyAPI::getResponse(const std::string& url, const bool& zlib_deco
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
Json::Value galaxyAPI::getProductBuilds(const std::string& product_id, const std::string& platform, const std::string& generation)
|
Json::Value galaxyAPI::getResponseJson(const std::string& url, const bool& zlib_decompress)
|
||||||
{
|
{
|
||||||
std::string url = "https://content-system.gog.com/products/" + product_id + "/os/" + platform + "/builds?generation=" + generation;
|
std::istringstream response(this->getResponse(url, zlib_decompress));
|
||||||
std::istringstream response(this->getResponse(url));
|
|
||||||
Json::Value json;
|
Json::Value json;
|
||||||
|
|
||||||
if (!response.str().empty())
|
if (!response.str().empty())
|
||||||
@ -164,6 +157,13 @@ Json::Value galaxyAPI::getProductBuilds(const std::string& product_id, const std
|
|||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Json::Value galaxyAPI::getProductBuilds(const std::string& product_id, const std::string& platform, const std::string& generation)
|
||||||
|
{
|
||||||
|
std::string url = "https://content-system.gog.com/products/" + product_id + "/os/" + platform + "/builds?generation=" + generation;
|
||||||
|
|
||||||
|
return this->getResponseJson(url);
|
||||||
|
}
|
||||||
|
|
||||||
Json::Value galaxyAPI::getManifestV1(const std::string& product_id, const std::string& build_id, const std::string& manifest_id, const std::string& platform)
|
Json::Value galaxyAPI::getManifestV1(const std::string& product_id, const std::string& build_id, const std::string& manifest_id, const std::string& platform)
|
||||||
{
|
{
|
||||||
std::string url = "https://cdn.gog.com/content-system/v1/manifests/" + product_id + "/" + platform + "/" + build_id + "/" + manifest_id + ".json";
|
std::string url = "https://cdn.gog.com/content-system/v1/manifests/" + product_id + "/" + platform + "/" + build_id + "/" + manifest_id + ".json";
|
||||||
@ -173,12 +173,7 @@ Json::Value galaxyAPI::getManifestV1(const std::string& product_id, const std::s
|
|||||||
|
|
||||||
Json::Value galaxyAPI::getManifestV1(const std::string& manifest_url)
|
Json::Value galaxyAPI::getManifestV1(const std::string& manifest_url)
|
||||||
{
|
{
|
||||||
std::istringstream response(this->getResponse(manifest_url));
|
return this->getResponseJson(manifest_url);
|
||||||
Json::Value json;
|
|
||||||
|
|
||||||
response >> json;
|
|
||||||
|
|
||||||
return json;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Json::Value galaxyAPI::getManifestV2(std::string manifest_hash)
|
Json::Value galaxyAPI::getManifestV2(std::string manifest_hash)
|
||||||
@ -187,23 +182,15 @@ Json::Value galaxyAPI::getManifestV2(std::string manifest_hash)
|
|||||||
manifest_hash = this->hashToGalaxyPath(manifest_hash);
|
manifest_hash = this->hashToGalaxyPath(manifest_hash);
|
||||||
|
|
||||||
std::string url = "https://cdn.gog.com/content-system/v2/meta/" + manifest_hash;
|
std::string url = "https://cdn.gog.com/content-system/v2/meta/" + manifest_hash;
|
||||||
std::istringstream response(this->getResponse(url, true));
|
|
||||||
Json::Value json;
|
|
||||||
|
|
||||||
response >> json;
|
return this->getResponseJson(url, true);
|
||||||
|
|
||||||
return json;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Json::Value galaxyAPI::getSecureLink(const std::string& product_id, const std::string& path)
|
Json::Value galaxyAPI::getSecureLink(const std::string& product_id, const std::string& path)
|
||||||
{
|
{
|
||||||
std::string url = "https://content-system.gog.com/products/" + product_id + "/secure_link?generation=2&path=" + path + "&_version=2";
|
std::string url = "https://content-system.gog.com/products/" + product_id + "/secure_link?generation=2&path=" + path + "&_version=2";
|
||||||
std::istringstream response(this->getResponse(url));
|
|
||||||
Json::Value json;
|
|
||||||
|
|
||||||
response >>json;
|
return this->getResponseJson(url);
|
||||||
|
|
||||||
return json;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string galaxyAPI::hashToGalaxyPath(const std::string& hash)
|
std::string galaxyAPI::hashToGalaxyPath(const std::string& hash)
|
||||||
@ -262,12 +249,8 @@ std::vector<galaxyDepotItem> galaxyAPI::getDepotItemsVector(const std::string& h
|
|||||||
Json::Value galaxyAPI::getProductInfo(const std::string& product_id)
|
Json::Value galaxyAPI::getProductInfo(const std::string& product_id)
|
||||||
{
|
{
|
||||||
std::string url = "https://api.gog.com/products/" + product_id + "?expand=downloads,expanded_dlcs,description,screenshots,videos,related_products,changelog&locale=en-US";
|
std::string url = "https://api.gog.com/products/" + product_id + "?expand=downloads,expanded_dlcs,description,screenshots,videos,related_products,changelog&locale=en-US";
|
||||||
std::istringstream response(this->getResponse(url));
|
|
||||||
Json::Value json;
|
|
||||||
|
|
||||||
response >> json;
|
return this->getResponseJson(url);
|
||||||
|
|
||||||
return json;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gameDetails galaxyAPI::productInfoJsonToGameDetails(const Json::Value& json, const DownloadConfig& dlConf)
|
gameDetails galaxyAPI::productInfoJsonToGameDetails(const Json::Value& json, const DownloadConfig& dlConf)
|
||||||
@ -379,17 +362,10 @@ std::vector<gameFile> galaxyAPI::fileJsonNodeToGameFileVector(const std::string&
|
|||||||
Json::Value fileNode = infoNode["files"][j];
|
Json::Value fileNode = infoNode["files"][j];
|
||||||
std::string downlink = fileNode["downlink"].asString();
|
std::string downlink = fileNode["downlink"].asString();
|
||||||
|
|
||||||
std::string downlinkResponse = this->getResponse(downlink);
|
Json::Value downlinkJson = this->getResponseJson(downlink);
|
||||||
|
if (downlinkJson.empty())
|
||||||
if (downlinkResponse.empty())
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Json::Value downlinkJson;
|
|
||||||
Json::CharReaderBuilder builder;
|
|
||||||
std::istringstream downlink_stream(downlinkResponse);
|
|
||||||
std::string errs;
|
|
||||||
Json::parseFromStream(builder, downlink_stream, &downlinkJson, &errs);
|
|
||||||
|
|
||||||
std::string downlink_url = downlinkJson["downlink"].asString();
|
std::string downlink_url = downlinkJson["downlink"].asString();
|
||||||
std::string downlink_url_unescaped = (std::string)curl_easy_unescape(curlhandle, downlink_url.c_str(), downlink_url.size(), NULL);
|
std::string downlink_url_unescaped = (std::string)curl_easy_unescape(curlhandle, downlink_url.c_str(), downlink_url.size(), NULL);
|
||||||
std::string path;
|
std::string path;
|
||||||
@ -460,3 +436,10 @@ std::vector<gameFile> galaxyAPI::fileJsonNodeToGameFileVector(const std::string&
|
|||||||
|
|
||||||
return gamefiles;
|
return gamefiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Json::Value galaxyAPI::getUserData()
|
||||||
|
{
|
||||||
|
std::string url = "https://embed.gog.com/userData.json";
|
||||||
|
|
||||||
|
return this->getResponseJson(url);
|
||||||
|
}
|
||||||
|
@ -124,10 +124,11 @@ std::vector<gameItem> Website::getGames()
|
|||||||
Json::Value root;
|
Json::Value root;
|
||||||
int i = 1;
|
int i = 1;
|
||||||
bool bAllPagesParsed = false;
|
bool bAllPagesParsed = false;
|
||||||
|
int iUpdated = Globals::globalConfig.bUpdated ? 1 : 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
std::string response = this->getResponse("https://www.gog.com/account/getFilteredProducts?hasHiddenProducts=false&hiddenFlag=0&isUpdated=0&mediaType=1&sortBy=title&system=&page=" + std::to_string(i));
|
std::string response = this->getResponse("https://www.gog.com/account/getFilteredProducts?hasHiddenProducts=false&hiddenFlag=0&isUpdated=" + std::to_string(iUpdated) + "&mediaType=1&sortBy=title&system=&page=" + std::to_string(i));
|
||||||
std::istringstream json_stream(response);
|
std::istringstream json_stream(response);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -151,7 +152,7 @@ std::vector<gameItem> Website::getGames()
|
|||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
std::cerr << "DEBUG INFO (Website::getGames)" << std::endl << root << std::endl;
|
std::cerr << "DEBUG INFO (Website::getGames)" << std::endl << root << std::endl;
|
||||||
#endif
|
#endif
|
||||||
if (root["page"].asInt() == root["totalPages"].asInt())
|
if (root["page"].asInt() == root["totalPages"].asInt() || root["totalPages"].asInt() == 0)
|
||||||
bAllPagesParsed = true;
|
bAllPagesParsed = true;
|
||||||
if (root["products"].isArray())
|
if (root["products"].isArray())
|
||||||
{
|
{
|
||||||
@ -203,10 +204,6 @@ std::vector<gameItem> Website::getGames()
|
|||||||
// Filter the game list
|
// Filter the game list
|
||||||
if (!Globals::globalConfig.sGameRegex.empty())
|
if (!Globals::globalConfig.sGameRegex.empty())
|
||||||
{
|
{
|
||||||
// GameRegex filter aliases
|
|
||||||
if (Globals::globalConfig.sGameRegex == "all")
|
|
||||||
Globals::globalConfig.sGameRegex = ".*";
|
|
||||||
|
|
||||||
boost::regex expression(Globals::globalConfig.sGameRegex);
|
boost::regex expression(Globals::globalConfig.sGameRegex);
|
||||||
boost::match_results<std::string::const_iterator> what;
|
boost::match_results<std::string::const_iterator> what;
|
||||||
if (!boost::regex_search(game.name, what, expression)) // Check if name matches the specified regex
|
if (!boost::regex_search(game.name, what, expression)) // Check if name matches the specified regex
|
||||||
@ -272,41 +269,6 @@ std::vector<gameItem> Website::getGames()
|
|||||||
return games;
|
return games;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get list of free games
|
|
||||||
std::vector<gameItem> Website::getFreeGames()
|
|
||||||
{
|
|
||||||
Json::Value root;
|
|
||||||
std::vector<gameItem> games;
|
|
||||||
std::string json = this->getResponse("https://www.gog.com/games/ajax/filtered?mediaType=game&page=1&price=free&sort=title");
|
|
||||||
std::istringstream json_stream(json);
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Parse JSON
|
|
||||||
json_stream >> root;
|
|
||||||
} catch (const Json::Exception& exc) {
|
|
||||||
#ifdef DEBUG
|
|
||||||
std::cerr << "DEBUG INFO (Website::getFreeGames)" << std::endl << json << std::endl;
|
|
||||||
#endif
|
|
||||||
std::cout << exc.what();
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
std::cerr << "DEBUG INFO (Website::getFreeGames)" << std::endl << root << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Json::Value products = root["products"];
|
|
||||||
for (unsigned int i = 0; i < products.size(); ++i)
|
|
||||||
{
|
|
||||||
gameItem game;
|
|
||||||
game.name = products[i]["slug"].asString();
|
|
||||||
game.id = products[i]["id"].isInt() ? std::to_string(products[i]["id"].asInt()) : products[i]["id"].asString();
|
|
||||||
games.push_back(game);
|
|
||||||
}
|
|
||||||
|
|
||||||
return games;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Login to GOG website
|
// Login to GOG website
|
||||||
int Website::Login(const std::string& email, const std::string& password)
|
int Website::Login(const std::string& email, const std::string& password)
|
||||||
{
|
{
|
||||||
|
@ -64,7 +64,7 @@ struct tm ZipUtil::date_time_to_tm(uint64_t date, uint64_t time)
|
|||||||
uint64_t dos_time_base_year = 1980;
|
uint64_t dos_time_base_year = 1980;
|
||||||
|
|
||||||
struct tm timeinfo;
|
struct tm timeinfo;
|
||||||
timeinfo.tm_year = (uint16_t)(((date & 0xFE00) >> 9) - local_time_base_year + dos_time_base_year);
|
timeinfo.tm_year = (uint16_t)(((date & 0xFE00) >> 9) - local_time_base_year + dos_time_base_year);
|
||||||
timeinfo.tm_mon = (uint16_t)(((date & 0x1E0) >> 5) - 1);
|
timeinfo.tm_mon = (uint16_t)(((date & 0x1E0) >> 5) - 1);
|
||||||
timeinfo.tm_mday = (uint16_t)(date & 0x1F);
|
timeinfo.tm_mday = (uint16_t)(date & 0x1F);
|
||||||
timeinfo.tm_hour = (uint16_t)((time & 0xF800) >> 11);
|
timeinfo.tm_hour = (uint16_t)((time & 0xF800) >> 11);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user