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 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());
|
||||
|
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_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 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-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-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-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())
|
||||
@ -798,6 +800,17 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
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())
|
||||
{
|
||||
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;
|
||||
unsigned int iPlatform = Globals::globalConfig.dlConf.iGalaxyPlatform;
|
||||
if (iPlatform == GlobalConstants::PLATFORM_LINUX) {
|
||||
// Linux is not yet supported for cloud saves
|
||||
std::cout << "Cloud saves for Linux builds not yet supported" << std::endl;
|
||||
return -1;
|
||||
return {};
|
||||
}
|
||||
else if (iPlatform == GlobalConstants::PLATFORM_MAC)
|
||||
sPlatform = "osx";
|
||||
@ -4433,7 +4443,7 @@ int Downloader::cloudSaveListByIdForEach(const std::string& product_id, int buil
|
||||
if (json["items"][build_index]["generation"].asInt() != 2)
|
||||
{
|
||||
std::cout << "Only generation 2 builds are supported currently" << std::endl;
|
||||
return -1;
|
||||
return {};
|
||||
}
|
||||
std::string buildHash;
|
||||
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)) {
|
||||
std::cout << "Couldn't refresh login" << std::endl;
|
||||
return -1;
|
||||
return {};
|
||||
}
|
||||
|
||||
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 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"];
|
||||
|
||||
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)});
|
||||
}
|
||||
|
||||
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()) {
|
||||
std::cout << "No cloud save locations found" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
std::string url = "https://cloudstorage.gog.com/v1/" + Globals::galaxyConf.getUserId() + "/" + Globals::galaxyConf.getClientId();
|
||||
auto fileList = gogGalaxy->getResponseJson(url, "application/json");
|
||||
|
||||
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 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();
|
||||
|
||||
@ -4517,8 +4528,6 @@ int Downloader::cloudSaveListByIdForEach(const std::string& product_id, int buil
|
||||
};
|
||||
|
||||
f(csf);
|
||||
|
||||
// iTotalRemainingBytes.fetch_add(filesize);
|
||||
}
|
||||
|
||||
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> orphans;
|
||||
|
Loading…
x
Reference in New Issue
Block a user