mirror of
https://github.com/Sude-/lgogdownloader.git
synced 2024-11-20 03:39:17 +01:00
Merge branch 'cloud-save' of https://github.com/loki-47-6F-64/lgogdownloader
This commit is contained in:
commit
6ae6ab2469
@ -19,6 +19,7 @@ struct DirectoryConfig
|
||||
{
|
||||
bool bSubDirectories;
|
||||
std::string sDirectory;
|
||||
std::string sWinePrefix;
|
||||
std::string sGameSubdir;
|
||||
std::string sInstallersSubdir;
|
||||
std::string sExtrasSubdir;
|
||||
@ -102,6 +103,16 @@ class GalaxyConfig
|
||||
return this->token_json;
|
||||
}
|
||||
|
||||
std::string getUserId() {
|
||||
std::unique_lock<std::mutex> lock(m);
|
||||
|
||||
if(this->token_json.isMember("user_id")) {
|
||||
return this->token_json["user_id"].asString();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void setJSON(Json::Value json)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m);
|
||||
@ -131,16 +142,34 @@ class GalaxyConfig
|
||||
return this->filepath;
|
||||
}
|
||||
|
||||
void resetClient() {
|
||||
std::lock_guard<std::mutex> lock(m);
|
||||
if(token_json.isMember("client_id")) {
|
||||
token_json["client_id"] = default_client_id;
|
||||
}
|
||||
if(token_json.isMember("client_secret")) {
|
||||
token_json["client_secret"] = default_client_secret;
|
||||
}
|
||||
}
|
||||
|
||||
std::string getClientId()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m);
|
||||
return this->client_id;
|
||||
std::lock_guard<std::mutex> lock(m);
|
||||
if(token_json.isMember("client_id")) {
|
||||
return token_json["client_id"].asString();
|
||||
}
|
||||
|
||||
return default_client_id;
|
||||
}
|
||||
|
||||
std::string getClientSecret()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m);
|
||||
return this->client_secret;
|
||||
std::lock_guard<std::mutex> lock(m);
|
||||
if(token_json.isMember("client_secret")) {
|
||||
return token_json["client_secret"].asString();
|
||||
}
|
||||
|
||||
return default_client_secret;
|
||||
}
|
||||
|
||||
std::string getRedirectUri()
|
||||
@ -154,8 +183,6 @@ class GalaxyConfig
|
||||
GalaxyConfig(const GalaxyConfig& other)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(other.m);
|
||||
client_id = other.client_id;
|
||||
client_secret = other.client_secret;
|
||||
redirect_uri = other.redirect_uri;
|
||||
filepath = other.filepath;
|
||||
token_json = other.token_json;
|
||||
@ -169,8 +196,6 @@ class GalaxyConfig
|
||||
std::unique_lock<std::mutex> lock1(m, std::defer_lock);
|
||||
std::unique_lock<std::mutex> lock2(other.m, std::defer_lock);
|
||||
std::lock(lock1, lock2);
|
||||
client_id = other.client_id;
|
||||
client_secret = other.client_secret;
|
||||
redirect_uri = other.redirect_uri;
|
||||
filepath = other.filepath;
|
||||
token_json = other.token_json;
|
||||
@ -178,8 +203,9 @@ class GalaxyConfig
|
||||
}
|
||||
protected:
|
||||
private:
|
||||
std::string client_id = "46899977096215655";
|
||||
std::string client_secret = "9d85c43b1482497dbbce61f6e4aa173a433796eeae2ca8c5f6129f2dc4de46d9";
|
||||
const std::string default_client_id = "46899977096215655";
|
||||
const std::string default_client_secret = "9d85c43b1482497dbbce61f6e4aa173a433796eeae2ca8c5f6129f2dc4de46d9";
|
||||
|
||||
std::string redirect_uri = "https://embed.gog.com/on_login_success?origin=client";
|
||||
std::string filepath;
|
||||
Json::Value token_json;
|
||||
@ -281,6 +307,12 @@ class Config
|
||||
Blacklist blacklist;
|
||||
Blacklist ignorelist;
|
||||
Blacklist gamehasdlc;
|
||||
|
||||
// Cloud save options
|
||||
std::vector<std::string> cloudWhiteList;
|
||||
std::vector<std::string> cloudBlackList;
|
||||
bool bCloudForce;
|
||||
|
||||
std::string sGameHasDLCList;
|
||||
|
||||
// Integers
|
||||
|
@ -32,9 +32,11 @@
|
||||
#include <curl/curl.h>
|
||||
#include <json/json.h>
|
||||
#include <ctime>
|
||||
#include <functional>
|
||||
#include <fstream>
|
||||
#include <deque>
|
||||
|
||||
class cloudSaveFile;
|
||||
class Timer
|
||||
{
|
||||
public:
|
||||
@ -99,6 +101,14 @@ class Downloader
|
||||
void clearUpdateNotifications();
|
||||
void repair();
|
||||
void download();
|
||||
|
||||
void downloadCloudSaves(const std::string& product_id, int build_index = -1);
|
||||
void downloadCloudSavesById(const std::string& product_id, int build_index = -1);
|
||||
void uploadCloudSaves(const std::string& product_id, int build_index = -1);
|
||||
void uploadCloudSavesById(const std::string& product_id, int build_index = -1);
|
||||
void deleteCloudSaves(const std::string& product_id, int build_index = -1);
|
||||
void deleteCloudSavesById(const std::string& product_id, int build_index = -1);
|
||||
|
||||
void checkOrphans();
|
||||
void checkStatus();
|
||||
void updateCache();
|
||||
@ -113,9 +123,16 @@ class Downloader
|
||||
void galaxyInstallGame(const std::string& product_id, int build_index = -1, const unsigned int& iGalaxyArch = GlobalConstants::ARCH_X64);
|
||||
void galaxyInstallGameById(const std::string& product_id, int build_index = -1, const unsigned int& iGalaxyArch = GlobalConstants::ARCH_X64);
|
||||
void galaxyShowBuilds(const std::string& product_id, int build_index = -1);
|
||||
void galaxyShowCloudSaves(const std::string& product_id, int build_index = -1);
|
||||
void galaxyShowLocalCloudSaves(const std::string& product_id, int build_index = -1);
|
||||
void galaxyShowLocalCloudSavesById(const std::string& product_id, int build_index = -1);
|
||||
void galaxyShowBuildsById(const std::string& product_id, int build_index = -1);
|
||||
void galaxyShowCloudSavesById(const std::string& product_id, int build_index = -1);
|
||||
protected:
|
||||
private:
|
||||
std::map<std::string, std::string> cloudSaveLocations(const std::string& product_id, int build_index);
|
||||
int cloudSaveListByIdForEach(const std::string& product_id, int build_index, const std::function<void(cloudSaveFile &)> &f);
|
||||
|
||||
CURLcode downloadFile(const std::string& url, const std::string& filepath, const std::string& xml_data = std::string(), const std::string& gamename = std::string());
|
||||
int repairFile(const std::string& url, const std::string& filepath, const std::string& xml_data = std::string(), const std::string& gamename = std::string());
|
||||
int getGameDetails();
|
||||
@ -133,6 +150,8 @@ class Downloader
|
||||
static std::string getChangelogFromJSON(const Json::Value& json);
|
||||
void saveChangelog(const std::string& changelog, const std::string& filepath);
|
||||
static void processDownloadQueue(Config conf, const unsigned int& tid);
|
||||
static void processCloudSaveDownloadQueue(Config conf, const unsigned int& tid);
|
||||
static void processCloudSaveUploadQueue(Config conf, const unsigned int& tid);
|
||||
static int progressCallbackForThread(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow);
|
||||
template <typename T> void printProgress(const ThreadSafeQueue<T>& download_queue);
|
||||
static void getGameDetailsThread(Config config, const unsigned int& tid);
|
||||
|
@ -46,16 +46,20 @@ class galaxyAPI
|
||||
galaxyAPI(CurlConfig& conf);
|
||||
virtual ~galaxyAPI();
|
||||
int init();
|
||||
|
||||
bool isTokenExpired();
|
||||
bool refreshLogin();
|
||||
bool refreshLogin(const std::string &clientId, const std::string &clientSecret, const std::string &refreshToken, bool newSession);
|
||||
|
||||
Json::Value getProductBuilds(const std::string& product_id, const std::string& platform = "windows", const std::string& generation = "2");
|
||||
Json::Value getManifestV1(const std::string& product_id, const std::string& build_id, const std::string& manifest_id = "repository", const std::string& platform = "windows");
|
||||
Json::Value getManifestV1(const std::string& manifest_url);
|
||||
Json::Value getManifestV2(std::string manifest_hash, const bool& is_dependency = false);
|
||||
Json::Value getCloudPathAsJson(const std::string &clientId);
|
||||
Json::Value getSecureLink(const std::string& product_id, const std::string& path);
|
||||
Json::Value getDependencyLink(const std::string& path);
|
||||
std::string getResponse(const std::string& url);
|
||||
Json::Value getResponseJson(const std::string& url);
|
||||
std::string getResponse(const std::string& url, const char *encoding = nullptr);
|
||||
Json::Value getResponseJson(const std::string& url, const char *encoding = nullptr);
|
||||
std::string hashToGalaxyPath(const std::string& hash);
|
||||
std::vector<galaxyDepotItem> getDepotItemsVector(const std::string& hash, const bool& is_dependency = false);
|
||||
Json::Value getProductInfo(const std::string& product_id);
|
||||
|
@ -66,6 +66,7 @@ namespace Util
|
||||
int createXML(std::string filepath, uintmax_t chunk_size, std::string xml_dir = std::string());
|
||||
int getGameSpecificConfig(std::string gamename, gameSpecificConfig* conf, std::string directory = std::string());
|
||||
int replaceString(std::string& str, const std::string& to_replace, const std::string& replace_with);
|
||||
int replaceAllString(std::string& str, const std::string& to_replace, const std::string& replace_with);
|
||||
void filepathReplaceReservedStrings(std::string& str, const std::string& gamename, const unsigned int& platformId = 0, const std::string& dlcname = "");
|
||||
void setFilePermissions(const boost::filesystem::path& path, const boost::filesystem::perms& permissions);
|
||||
int getTerminalWidth();
|
||||
@ -90,6 +91,7 @@ namespace Util
|
||||
CURLcode CurlHandleGetResponse(CURL* curlhandle, std::string& response, int max_retries = -1);
|
||||
curl_off_t CurlWriteMemoryCallback(char *ptr, curl_off_t size, curl_off_t nmemb, void *userp);
|
||||
curl_off_t CurlWriteChunkMemoryCallback(void *contents, curl_off_t size, curl_off_t nmemb, void *userp);
|
||||
curl_off_t CurlReadChunkMemoryCallback(void *contents, curl_off_t size, curl_off_t nmemb, ChunkMemoryStruct *userp);
|
||||
|
||||
template<typename ... Args> std::string formattedString(const std::string& format, Args ... args)
|
||||
{
|
||||
|
91
main.cpp
91
main.cpp
@ -24,6 +24,18 @@ template<typename T> void set_vm_value(std::map<std::string, bpo::variable_value
|
||||
vm[option].value() = boost::any(value);
|
||||
}
|
||||
|
||||
void ensure_trailing_slash(std::string &path, const char *default_ = nullptr) {
|
||||
if (!path.empty())
|
||||
{
|
||||
if (path.at(path.length()-1)!='/')
|
||||
path += "/";
|
||||
}
|
||||
else
|
||||
{
|
||||
path = default_; // Directory wasn't specified, use current directory
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct sigaction act;
|
||||
@ -151,6 +163,11 @@ int main(int argc, char *argv[])
|
||||
|
||||
std::string galaxy_product_id_install;
|
||||
std::string galaxy_product_id_show_builds;
|
||||
std::string galaxy_product_id_show_cloud_paths;
|
||||
std::string galaxy_product_id_show_local_cloud_paths;
|
||||
std::string galaxy_product_cloud_saves;
|
||||
std::string galaxy_product_cloud_saves_delete;
|
||||
std::string galaxy_upload_product_cloud_saves;
|
||||
std::string tags;
|
||||
|
||||
std::vector<std::string> vFileIdStrings;
|
||||
@ -213,6 +230,11 @@ int main(int argc, char *argv[])
|
||||
("cacert", bpo::value<std::string>(&Globals::globalConfig.curlConf.sCACertPath)->default_value(""), "Path to CA certificate bundle in PEM format")
|
||||
("respect-umask", bpo::value<bool>(&Globals::globalConfig.bRespectUmask)->zero_tokens()->default_value(false), "Do not adjust permissions of sensitive files")
|
||||
("user-agent", bpo::value<std::string>(&Globals::globalConfig.curlConf.sUserAgent)->default_value(DEFAULT_USER_AGENT), "Set user agent")
|
||||
|
||||
("wine-prefix", bpo::value<std::string>(&Globals::globalConfig.dirConf.sWinePrefix)->default_value("."), "Set wineprefix directory")
|
||||
("cloud-whitelist", bpo::value<std::vector<std::string>>(&Globals::globalConfig.cloudWhiteList)->multitoken(), "Include this list of cloud saves, by default all cloud saves are included\n Example: --cloud-whitelist saves/AutoSave-0 saves/AutoSave-1/screenshot.png")
|
||||
("cloud-blacklist", bpo::value<std::vector<std::string>>(&Globals::globalConfig.cloudBlackList)->multitoken(), "Exclude this list of cloud saves\n Example: --cloud-blacklist saves/AutoSave-0 saves/AutoSave-1/screenshot.png")
|
||||
("cloud-force", bpo::value<bool>(&Globals::globalConfig.bCloudForce)->zero_tokens()->default_value(false), "Download or Upload cloud saves even if they're up-to-date\nDelete remote cloud saves even if no saves are whitelisted")
|
||||
#ifdef USE_QT_GUI_LOGIN
|
||||
("enable-login-gui", bpo::value<bool>(&Globals::globalConfig.bEnableLoginGUI)->zero_tokens()->default_value(false), "Enable login GUI when encountering reCAPTCHA on login form")
|
||||
#endif
|
||||
@ -271,6 +293,11 @@ int main(int argc, char *argv[])
|
||||
options_cli_experimental.add_options()
|
||||
("galaxy-install", bpo::value<std::string>(&galaxy_product_id_install)->default_value(""), "Install game using product id [product_id/build_index] or gamename regex [gamename/build_id]\nBuild index is used to select a build and defaults to 0 if not specified.\n\nExample: 12345/2 selects build 2 for product 12345")
|
||||
("galaxy-show-builds", bpo::value<std::string>(&galaxy_product_id_show_builds)->default_value(""), "Show game builds using product id [product_id/build_index] or gamename regex [gamename/build_id]\nBuild index is used to select a build and defaults to 0 if not specified.\n\nExample: 12345/2 selects build 2 for product 12345")
|
||||
("galaxy-download-cloud-saves", bpo::value<std::string>(&galaxy_product_cloud_saves)->default_value(""), "Download cloud saves using product-id [product_id/build_index] or gamename regex [gamename/build_id]\nBuild index is used to select a build and defaults to 0 if not specified.\n\nExample: 12345/2 selects build 2 for product 12345")
|
||||
("galaxy-upload-cloud-saves", bpo::value<std::string>(&galaxy_upload_product_cloud_saves)->default_value(""), "Upload cloud saves using product-id [product_id/build_index] or gamename regex [gamename/build_id]\nBuild index is used to select a build and defaults to 0 if not specified.\n\nExample: 12345/2 selects build 2 for product 12345")
|
||||
("galaxy-show-cloud-saves", bpo::value<std::string>(&galaxy_product_id_show_cloud_paths)->default_value(""), "Show game cloud-saves using product id [product_id/build_index] or gamename regex [gamename/build_id]\nBuild index is used to select a build and defaults to 0 if not specified.\n\nExample: 12345/2 selects build 2 for product 12345")
|
||||
("galaxy-show-local-cloud-saves", bpo::value<std::string>(&galaxy_product_id_show_local_cloud_paths)->default_value(""), "Show local cloud-saves using product id [product_id/build_index] or gamename regex [gamename/build_id]\nBuild index is used to select a build and defaults to 0 if not specified.\n\nExample: 12345/2 selects build 2 for product 12345")
|
||||
("galaxy-delete-cloud-saves", bpo::value<std::string>(&galaxy_product_cloud_saves_delete)->default_value(""), "Delete cloud-saves using product id [product_id/build_index] or gamename regex [gamename/build_id]\nBuild index is used to select a build and defaults to 0 if not specified.\n\nExample: 12345/2 selects build 2 for product 12345")
|
||||
("galaxy-platform", bpo::value<std::string>(&sGalaxyPlatform)->default_value("w"), galaxy_platform_text.c_str())
|
||||
("galaxy-language", bpo::value<std::string>(&sGalaxyLanguage)->default_value("en"), galaxy_language_text.c_str())
|
||||
("galaxy-arch", bpo::value<std::string>(&sGalaxyArch)->default_value("x64"), galaxy_arch_text.c_str())
|
||||
@ -578,15 +605,8 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
// Make sure that directory has trailing slash
|
||||
if (!Globals::globalConfig.dirConf.sDirectory.empty())
|
||||
{
|
||||
if (Globals::globalConfig.dirConf.sDirectory.at(Globals::globalConfig.dirConf.sDirectory.length()-1)!='/')
|
||||
Globals::globalConfig.dirConf.sDirectory += "/";
|
||||
}
|
||||
else
|
||||
{
|
||||
Globals::globalConfig.dirConf.sDirectory = "./"; // Directory wasn't specified, use current directory
|
||||
}
|
||||
ensure_trailing_slash(Globals::globalConfig.dirConf.sDirectory, "./");
|
||||
ensure_trailing_slash(Globals::globalConfig.dirConf.sWinePrefix, "./");
|
||||
|
||||
// CA certificate bundle
|
||||
if (Globals::globalConfig.curlConf.sCACertPath.empty())
|
||||
@ -777,6 +797,39 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
downloader.galaxyShowBuilds(product_id, build_index);
|
||||
}
|
||||
else if (!galaxy_product_id_show_cloud_paths.empty())
|
||||
{
|
||||
int build_index = -1;
|
||||
std::vector<std::string> tokens = Util::tokenize(galaxy_product_id_show_cloud_paths, "/");
|
||||
std::string product_id = tokens[0];
|
||||
if (tokens.size() == 2)
|
||||
{
|
||||
build_index = std::stoi(tokens[1]);
|
||||
}
|
||||
downloader.galaxyShowCloudSaves(product_id, build_index);
|
||||
}
|
||||
else if (!galaxy_product_id_show_local_cloud_paths.empty())
|
||||
{
|
||||
int build_index = -1;
|
||||
std::vector<std::string> tokens = Util::tokenize(galaxy_product_id_show_local_cloud_paths, "/");
|
||||
std::string product_id = tokens[0];
|
||||
if (tokens.size() == 2)
|
||||
{
|
||||
build_index = std::stoi(tokens[1]);
|
||||
}
|
||||
downloader.galaxyShowLocalCloudSaves(product_id, build_index);
|
||||
}
|
||||
else if (!galaxy_product_cloud_saves_delete.empty())
|
||||
{
|
||||
int build_index = -1;
|
||||
std::vector<std::string> tokens = Util::tokenize(galaxy_product_cloud_saves_delete, "/");
|
||||
std::string product_id = tokens[0];
|
||||
if (tokens.size() == 2)
|
||||
{
|
||||
build_index = std::stoi(tokens[1]);
|
||||
}
|
||||
downloader.deleteCloudSaves(product_id, build_index);
|
||||
}
|
||||
else if (!galaxy_product_id_install.empty())
|
||||
{
|
||||
int build_index = -1;
|
||||
@ -788,6 +841,26 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
downloader.galaxyInstallGame(product_id, build_index, Globals::globalConfig.dlConf.iGalaxyArch);
|
||||
}
|
||||
else if (!galaxy_product_cloud_saves.empty()) {
|
||||
int build_index = -1;
|
||||
std::vector<std::string> tokens = Util::tokenize(galaxy_product_cloud_saves, "/");
|
||||
std::string product_id = tokens[0];
|
||||
if (tokens.size() == 2)
|
||||
{
|
||||
build_index = std::stoi(tokens[1]);
|
||||
}
|
||||
downloader.downloadCloudSaves(product_id, build_index);
|
||||
}
|
||||
else if (!galaxy_upload_product_cloud_saves.empty()) {
|
||||
int build_index = -1;
|
||||
std::vector<std::string> tokens = Util::tokenize(galaxy_upload_product_cloud_saves, "/");
|
||||
std::string product_id = tokens[0];
|
||||
if (tokens.size() == 2)
|
||||
{
|
||||
build_index = std::stoi(tokens[1]);
|
||||
}
|
||||
downloader.uploadCloudSaves(product_id, build_index);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!Globals::globalConfig.bLogin)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -53,23 +53,33 @@ int galaxyAPI::init()
|
||||
return res;
|
||||
}
|
||||
|
||||
bool galaxyAPI::refreshLogin()
|
||||
bool galaxyAPI::refreshLogin(const std::string &clientId, const std::string &clientSecret, const std::string &refreshToken, bool newSession)
|
||||
{
|
||||
std::string refresh_url = "https://auth.gog.com/token?client_id=" + Globals::galaxyConf.getClientId()
|
||||
+ "&client_secret=" + Globals::galaxyConf.getClientSecret()
|
||||
std::string refresh_url = "https://auth.gog.com/token?client_id=" + clientId
|
||||
+ "&client_secret=" + clientSecret
|
||||
+ "&grant_type=refresh_token"
|
||||
+ "&refresh_token=" + Globals::galaxyConf.getRefreshToken();
|
||||
+ "&refresh_token=" + refreshToken
|
||||
+ (newSession ? "" : "&without_new_session=1");
|
||||
|
||||
// std::cout << refresh_url << std::endl;
|
||||
Json::Value token_json = this->getResponseJson(refresh_url);
|
||||
|
||||
if (token_json.empty())
|
||||
return false;
|
||||
|
||||
token_json["client_id"] = clientId;
|
||||
token_json["client_secret"] = clientSecret;
|
||||
|
||||
Globals::galaxyConf.setJSON(token_json);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool galaxyAPI::refreshLogin()
|
||||
{
|
||||
return refreshLogin(Globals::galaxyConf.getClientId(), Globals::galaxyConf.getClientSecret(), Globals::galaxyConf.getRefreshToken(), true);
|
||||
}
|
||||
|
||||
bool galaxyAPI::isTokenExpired()
|
||||
{
|
||||
bool res = false;
|
||||
@ -80,7 +90,7 @@ bool galaxyAPI::isTokenExpired()
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string galaxyAPI::getResponse(const std::string& url)
|
||||
std::string galaxyAPI::getResponse(const std::string& url, const char *encoding)
|
||||
{
|
||||
struct curl_slist *header = NULL;
|
||||
|
||||
@ -92,13 +102,26 @@ std::string galaxyAPI::getResponse(const std::string& url)
|
||||
std::string bearer = "Authorization: Bearer " + access_token;
|
||||
header = curl_slist_append(header, bearer.c_str());
|
||||
}
|
||||
|
||||
if(encoding) {
|
||||
auto accept = "Accept: " + std::string(encoding);
|
||||
header = curl_slist_append(header, accept.c_str());
|
||||
}
|
||||
|
||||
curl_easy_setopt(curlhandle, CURLOPT_HTTPHEADER, header);
|
||||
curl_easy_setopt(curlhandle, CURLOPT_URL, url.c_str());
|
||||
curl_easy_setopt(curlhandle, CURLOPT_ACCEPT_ENCODING, "");
|
||||
|
||||
int max_retries = std::min(3, Globals::globalConfig.iRetries);
|
||||
std::string response;
|
||||
Util::CurlHandleGetResponse(curlhandle, response, max_retries);
|
||||
auto res = Util::CurlHandleGetResponse(curlhandle, response, max_retries);
|
||||
|
||||
if(res) {
|
||||
long int response_code = 0;
|
||||
curl_easy_getinfo(curlhandle, CURLINFO_RESPONSE_CODE, &response_code);
|
||||
|
||||
std::cout << "Response code for " << url << " is [" << response_code << ']' << std::endl;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curlhandle, CURLOPT_ACCEPT_ENCODING, NULL);
|
||||
curl_easy_setopt(curlhandle, CURLOPT_HTTPHEADER, NULL);
|
||||
@ -107,9 +130,9 @@ std::string galaxyAPI::getResponse(const std::string& url)
|
||||
return response;
|
||||
}
|
||||
|
||||
Json::Value galaxyAPI::getResponseJson(const std::string& url)
|
||||
Json::Value galaxyAPI::getResponseJson(const std::string& url, const char *encoding)
|
||||
{
|
||||
std::istringstream response(this->getResponse(url));
|
||||
std::istringstream response(this->getResponse(url, encoding));
|
||||
Json::Value json;
|
||||
|
||||
if (!response.str().empty())
|
||||
@ -149,8 +172,13 @@ Json::Value galaxyAPI::getResponseJson(const std::string& url)
|
||||
catch(const Json::Exception& exc)
|
||||
{
|
||||
// Failed to parse json
|
||||
|
||||
std::cout << "Failed to parse json: " << exc.what();
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::cout << "Failed to parse json: " << exc.what();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -190,6 +218,12 @@ Json::Value galaxyAPI::getManifestV2(std::string manifest_hash, const bool& is_d
|
||||
return this->getResponseJson(url);
|
||||
}
|
||||
|
||||
Json::Value galaxyAPI::getCloudPathAsJson(const std::string &clientId) {
|
||||
std::string url = "https://remote-config.gog.com/components/galaxy_client/clients/" + clientId + "?component_version=2.0.51";
|
||||
|
||||
return this->getResponseJson(url);
|
||||
}
|
||||
|
||||
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";
|
||||
|
34
src/util.cpp
34
src/util.cpp
@ -8,6 +8,9 @@
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
#include <boost/iostreams/filter/gzip.hpp>
|
||||
#include <boost/iostreams/filtering_streambuf.hpp>
|
||||
#include <boost/iostreams/copy.hpp>
|
||||
#include <tinyxml2.h>
|
||||
#include <json/json.h>
|
||||
#include <fstream>
|
||||
@ -391,6 +394,22 @@ int Util::replaceString(std::string& str, const std::string& to_replace, const s
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Util::replaceAllString(std::string& str, const std::string& to_replace, const std::string& replace_with) {
|
||||
size_t pos = str.find(to_replace);
|
||||
if (pos == std::string::npos)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
do {
|
||||
str.replace(str.begin()+pos, str.begin()+pos+to_replace.length(), replace_with);
|
||||
|
||||
pos = str.find(to_replace, pos + to_replace.length());
|
||||
} while(pos != std::string::npos);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Util::filepathReplaceReservedStrings(std::string& str, const std::string& gamename, const unsigned int& platformId, const std::string& dlcname)
|
||||
{
|
||||
std::string platform;
|
||||
@ -749,7 +768,6 @@ void Util::CurlHandleSetDefaultOptions(CURL* curlhandle, const CurlConfig& conf)
|
||||
curl_easy_setopt(curlhandle, CURLOPT_USERAGENT, conf.sUserAgent.c_str());
|
||||
curl_easy_setopt(curlhandle, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_easy_setopt(curlhandle, CURLOPT_NOPROGRESS, 1);
|
||||
curl_easy_setopt(curlhandle, CURLOPT_FAILONERROR, true);
|
||||
curl_easy_setopt(curlhandle, CURLOPT_NOSIGNAL, 1);
|
||||
curl_easy_setopt(curlhandle, CURLOPT_CONNECTTIMEOUT, conf.iTimeout);
|
||||
curl_easy_setopt(curlhandle, CURLOPT_FAILONERROR, true);
|
||||
@ -823,8 +841,9 @@ CURLcode Util::CurlHandleGetResponse(CURL* curlhandle, std::string& response, in
|
||||
// Retry on CURLE_HTTP_RETURNED_ERROR if response code is not "404 Not Found"
|
||||
case CURLE_HTTP_RETURNED_ERROR:
|
||||
curl_easy_getinfo(curlhandle, CURLINFO_RESPONSE_CODE, &response_code);
|
||||
if (response_code == 404)
|
||||
if (response_code == 404 || response_code == 403) {
|
||||
bShouldRetry = false;
|
||||
}
|
||||
else
|
||||
bShouldRetry = true;
|
||||
break;
|
||||
@ -865,3 +884,14 @@ curl_off_t Util::CurlWriteChunkMemoryCallback(void *contents, curl_off_t size, c
|
||||
|
||||
return realsize;
|
||||
}
|
||||
|
||||
curl_off_t Util::CurlReadChunkMemoryCallback(void *contents, curl_off_t size, curl_off_t nmemb, ChunkMemoryStruct *mem) {
|
||||
curl_off_t realsize = std::min(size * nmemb, mem->size);
|
||||
|
||||
std::copy(mem->memory, mem->memory + realsize, (char*)contents);
|
||||
|
||||
mem->size -= realsize;
|
||||
mem->memory += realsize;
|
||||
|
||||
return realsize;
|
||||
}
|
||||
|
@ -264,6 +264,9 @@ std::vector<gameItem> Website::getGames()
|
||||
// Login to GOG website
|
||||
int Website::Login(const std::string& email, const std::string& password)
|
||||
{
|
||||
// Reset client id and client secret to ensure we can log-in
|
||||
Globals::galaxyConf.resetClient();
|
||||
|
||||
int res = 0;
|
||||
std::string postdata;
|
||||
std::ostringstream memory;
|
||||
|
Loading…
Reference in New Issue
Block a user