mirror of
https://github.com/Sude-/lgogdownloader.git
synced 2025-02-02 05:52:31 +01:00
Show local cloud save files
This commit is contained in:
parent
c97a828aa7
commit
829d263bc7
@ -117,10 +117,13 @@ class Downloader
|
|||||||
void galaxyInstallGameById(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 galaxyShowBuilds(const std::string& product_id, int build_index = -1);
|
||||||
void galaxyShowCloudSaves(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 galaxyShowBuildsById(const std::string& product_id, int build_index = -1);
|
||||||
void galaxyShowCloudSavesById(const std::string& product_id, int build_index = -1);
|
void galaxyShowCloudSavesById(const std::string& product_id, int build_index = -1);
|
||||||
protected:
|
protected:
|
||||||
private:
|
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);
|
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());
|
CURLcode downloadFile(const std::string& url, const std::string& filepath, const std::string& xml_data = std::string(), const std::string& gamename = std::string());
|
||||||
|
13
main.cpp
13
main.cpp
@ -164,6 +164,7 @@ int main(int argc, char *argv[])
|
|||||||
std::string galaxy_product_id_install;
|
std::string galaxy_product_id_install;
|
||||||
std::string galaxy_product_id_show_builds;
|
std::string galaxy_product_id_show_builds;
|
||||||
std::string galaxy_product_id_show_cloud_paths;
|
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;
|
||||||
std::string tags;
|
std::string tags;
|
||||||
|
|
||||||
@ -288,6 +289,7 @@ int main(int argc, char *argv[])
|
|||||||
("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-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-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-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-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-platform", bpo::value<std::string>(&sGalaxyPlatform)->default_value("w"), galaxy_platform_text.c_str())
|
("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-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())
|
("galaxy-arch", bpo::value<std::string>(&sGalaxyArch)->default_value("x64"), galaxy_arch_text.c_str())
|
||||||
@ -798,6 +800,17 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
downloader.galaxyShowCloudSaves(product_id, build_index);
|
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_id_install.empty())
|
else if (!galaxy_product_id_install.empty())
|
||||||
{
|
{
|
||||||
int build_index = -1;
|
int build_index = -1;
|
||||||
|
@ -4410,13 +4410,23 @@ void Downloader::galaxyShowCloudSaves(const std::string& product_id, int build_i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int Downloader::cloudSaveListByIdForEach(const std::string& product_id, int build_index, const std::function<void(cloudSaveFile &)> &f) {
|
void Downloader::galaxyShowLocalCloudSaves(const std::string& product_id, int build_index)
|
||||||
|
{
|
||||||
|
std::string id;
|
||||||
|
if(this->galaxySelectProductIdHelper(product_id, id))
|
||||||
|
{
|
||||||
|
if (!id.empty())
|
||||||
|
this->galaxyShowLocalCloudSavesById(id, build_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, std::string> Downloader::cloudSaveLocations(const std::string& product_id, int build_index) {
|
||||||
std::string sPlatform;
|
std::string sPlatform;
|
||||||
unsigned int iPlatform = Globals::globalConfig.dlConf.iGalaxyPlatform;
|
unsigned int iPlatform = Globals::globalConfig.dlConf.iGalaxyPlatform;
|
||||||
if (iPlatform == GlobalConstants::PLATFORM_LINUX) {
|
if (iPlatform == GlobalConstants::PLATFORM_LINUX) {
|
||||||
// Linux is not yet supported for cloud saves
|
// Linux is not yet supported for cloud saves
|
||||||
std::cout << "Cloud saves for Linux builds not yet supported" << std::endl;
|
std::cout << "Cloud saves for Linux builds not yet supported" << std::endl;
|
||||||
return -1;
|
return {};
|
||||||
}
|
}
|
||||||
else if (iPlatform == GlobalConstants::PLATFORM_MAC)
|
else if (iPlatform == GlobalConstants::PLATFORM_MAC)
|
||||||
sPlatform = "osx";
|
sPlatform = "osx";
|
||||||
@ -4433,7 +4443,7 @@ int Downloader::cloudSaveListByIdForEach(const std::string& product_id, int buil
|
|||||||
if (json["items"][build_index]["generation"].asInt() != 2)
|
if (json["items"][build_index]["generation"].asInt() != 2)
|
||||||
{
|
{
|
||||||
std::cout << "Only generation 2 builds are supported currently" << std::endl;
|
std::cout << "Only generation 2 builds are supported currently" << std::endl;
|
||||||
return -1;
|
return {};
|
||||||
}
|
}
|
||||||
std::string buildHash;
|
std::string buildHash;
|
||||||
buildHash.assign(link.begin()+link.find_last_of("/")+1, link.end());
|
buildHash.assign(link.begin()+link.find_last_of("/")+1, link.end());
|
||||||
@ -4444,7 +4454,7 @@ int Downloader::cloudSaveListByIdForEach(const std::string& product_id, int buil
|
|||||||
|
|
||||||
if(!gogGalaxy->refreshLogin(clientId, secret, Globals::galaxyConf.getRefreshToken(), false)) {
|
if(!gogGalaxy->refreshLogin(clientId, secret, Globals::galaxyConf.getRefreshToken(), false)) {
|
||||||
std::cout << "Couldn't refresh login" << std::endl;
|
std::cout << "Couldn't refresh login" << std::endl;
|
||||||
return -1;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string install_directory;
|
std::string install_directory;
|
||||||
@ -4469,8 +4479,6 @@ int Downloader::cloudSaveListByIdForEach(const std::string& product_id, int buil
|
|||||||
std::string appdata_local_low_path = Globals::globalConfig.dirConf.sWinePrefix + "drive_c/users/" + username() + "/AppData/LocalLow/";
|
std::string appdata_local_low_path = Globals::globalConfig.dirConf.sWinePrefix + "drive_c/users/" + username() + "/AppData/LocalLow/";
|
||||||
std::string saved_games = Globals::globalConfig.dirConf.sWinePrefix + "drive_c/users/" + username() + "/Save Games/";
|
std::string saved_games = Globals::globalConfig.dirConf.sWinePrefix + "drive_c/users/" + username() + "/Save Games/";
|
||||||
|
|
||||||
std::string url = "https://cloudstorage.gog.com/v1/" + Globals::galaxyConf.getUserId() + "/" + clientId;
|
|
||||||
|
|
||||||
auto cloud_saves_json = gogGalaxy->getCloudPathAsJson(manifest["clientId"].asString())["content"][platform]["cloudStorage"]["locations"];
|
auto cloud_saves_json = gogGalaxy->getCloudPathAsJson(manifest["clientId"].asString())["content"][platform]["cloudStorage"]["locations"];
|
||||||
|
|
||||||
std::map<std::string, std::string> vars {
|
std::map<std::string, std::string> vars {
|
||||||
@ -4489,12 +4497,17 @@ int Downloader::cloudSaveListByIdForEach(const std::string& product_id, int buil
|
|||||||
name_to_location.insert({cloud_save["name"].asString(), std::move(location)});
|
name_to_location.insert({cloud_save["name"].asString(), std::move(location)});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return name_to_location;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Downloader::cloudSaveListByIdForEach(const std::string& product_id, int build_index, const std::function<void(cloudSaveFile &)> &f) {
|
||||||
|
auto name_to_location = this->cloudSaveLocations(product_id, build_index);
|
||||||
if(name_to_location.empty()) {
|
if(name_to_location.empty()) {
|
||||||
std::cout << "No cloud save locations found" << std::endl;
|
std::cout << "No cloud save locations found" << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string url = "https://cloudstorage.gog.com/v1/" + Globals::galaxyConf.getUserId() + "/" + Globals::galaxyConf.getClientId();
|
||||||
auto fileList = gogGalaxy->getResponseJson(url, "application/json");
|
auto fileList = gogGalaxy->getResponseJson(url, "application/json");
|
||||||
|
|
||||||
for(auto &fileJson : fileList) {
|
for(auto &fileJson : fileList) {
|
||||||
@ -4502,8 +4515,6 @@ int Downloader::cloudSaveListByIdForEach(const std::string& product_id, int buil
|
|||||||
auto pos = path.find_first_of('/');
|
auto pos = path.find_first_of('/');
|
||||||
|
|
||||||
auto location = name_to_location[path.substr(0, pos)] + path.substr(pos);
|
auto location = name_to_location[path.substr(0, pos)] + path.substr(pos);
|
||||||
// std::cout << location << std::endl;
|
|
||||||
// std::cout << path <<std::endl;
|
|
||||||
|
|
||||||
auto filesize = fileJson["bytes"].asUInt64();
|
auto filesize = fileJson["bytes"].asUInt64();
|
||||||
|
|
||||||
@ -4517,8 +4528,6 @@ int Downloader::cloudSaveListByIdForEach(const std::string& product_id, int buil
|
|||||||
};
|
};
|
||||||
|
|
||||||
f(csf);
|
f(csf);
|
||||||
|
|
||||||
// iTotalRemainingBytes.fetch_add(filesize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -4588,6 +4597,86 @@ void Downloader::galaxyShowCloudSavesById(const std::string& product_id, int bui
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dirForEachHelper(const boost::filesystem::path &location, std::function<void(boost::filesystem::directory_iterator)> &f) {
|
||||||
|
boost::filesystem::directory_iterator begin { location };
|
||||||
|
boost::filesystem::directory_iterator end;
|
||||||
|
|
||||||
|
for(boost::filesystem::directory_iterator curr_dir { begin }; curr_dir != end; ++curr_dir) {
|
||||||
|
if(boost::filesystem::is_directory(*curr_dir)) {
|
||||||
|
|
||||||
|
dirForEachHelper(*curr_dir, f);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
f(curr_dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dirForEach(const std::string &location, std::function<void(boost::filesystem::directory_iterator)> &&f) {
|
||||||
|
dirForEachHelper(location, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Downloader::galaxyShowLocalCloudSavesById(const std::string& product_id, int build_index) {
|
||||||
|
auto name_to_locations = cloudSaveLocations(product_id, build_index);
|
||||||
|
|
||||||
|
if(name_to_locations.empty()) {
|
||||||
|
std::cout << "Cloud saves not supported for this game" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, cloudSaveFile> path_to_cloudSaveFile;
|
||||||
|
for(auto &name_to_location : name_to_locations) {
|
||||||
|
auto &name = name_to_location.first;
|
||||||
|
auto &location = name_to_location.second;
|
||||||
|
|
||||||
|
if(!boost::filesystem::exists(location) || !boost::filesystem::is_directory(location)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
dirForEach(location, [&](boost::filesystem::directory_iterator file) {
|
||||||
|
cloudSaveFile csf {
|
||||||
|
boost::posix_time::from_time_t(boost::filesystem::last_write_time(*file) - 1),
|
||||||
|
boost::filesystem::file_size(*file),
|
||||||
|
(name / boost::filesystem::relative(*file, location)).string(),
|
||||||
|
file->path().string()
|
||||||
|
};
|
||||||
|
|
||||||
|
path_to_cloudSaveFile.insert(std::make_pair(csf.path, std::move(csf)));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if(path_to_cloudSaveFile.empty()) {
|
||||||
|
std::cout << "No local cloud saves found" << std::endl;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->cloudSaveListByIdForEach(product_id, build_index, [&](cloudSaveFile &csf) {
|
||||||
|
auto it = path_to_cloudSaveFile.find(csf.path);
|
||||||
|
|
||||||
|
//If remote save is not locally stored, skip
|
||||||
|
if(it == std::end(path_to_cloudSaveFile)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cloudSaveFile local_csf { std::move(it->second) };
|
||||||
|
path_to_cloudSaveFile.erase(it);
|
||||||
|
|
||||||
|
std::cout << csf.path << ": ";
|
||||||
|
if(csf.lastModified < local_csf.lastModified) {
|
||||||
|
std::cout << "remote save out of date: it should be synchronized" << std::endl;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::cout << "up to date" << std::endl;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for(auto &path_csf : path_to_cloudSaveFile) {
|
||||||
|
auto &csf = path_csf.second;
|
||||||
|
|
||||||
|
std::cout << csf.path << ": there's only a local copy" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> Downloader::galaxyGetOrphanedFiles(const std::vector<galaxyDepotItem>& items, const std::string& install_path)
|
std::vector<std::string> Downloader::galaxyGetOrphanedFiles(const std::vector<galaxyDepotItem>& items, const std::string& install_path)
|
||||||
{
|
{
|
||||||
std::vector<std::string> orphans;
|
std::vector<std::string> orphans;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user