Show cloud save paths

This commit is contained in:
loki-47-6F-64 2022-07-31 14:11:32 +02:00
parent 8e046e977d
commit c4f604aec0
6 changed files with 126 additions and 14 deletions

View File

@ -19,6 +19,7 @@ struct DirectoryConfig
{
bool bSubDirectories;
std::string sDirectory;
std::string sWinePrefix;
std::string sGameSubdir;
std::string sInstallersSubdir;
std::string sExtrasSubdir;

View File

@ -113,6 +113,7 @@ 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 galaxyShowBuildsById(const std::string& product_id, int build_index = -1);
void galaxyShowCloudSavesById(const std::string& product_id, int build_index = -1);
protected:

View File

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

View File

@ -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;
@ -223,6 +235,7 @@ int main(int argc, char *argv[])
// Commandline options (config file)
options_cli_cfg.add_options()
("directory", bpo::value<std::string>(&Globals::globalConfig.dirConf.sDirectory)->default_value("."), "Set download directory")
("wine-prefix", bpo::value<std::string>(&Globals::globalConfig.dirConf.sWinePrefix)->default_value("."), "Set wineprefix directory")
("limit-rate", bpo::value<curl_off_t>(&Globals::globalConfig.curlConf.iDownloadRate)->default_value(0), "Limit download rate to value in kB\n0 = unlimited")
("xml-directory", bpo::value<std::string>(&Globals::globalConfig.sXMLDirectory), "Set directory for GOG XML files")
("chunk-size", bpo::value<size_t>(&Globals::globalConfig.iChunkSize)->default_value(10), "Chunk size (in MB) when creating XML")
@ -580,15 +593,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())
@ -788,7 +794,7 @@ int main(int argc, char *argv[])
{
build_index = std::stoi(tokens[1]);
}
downloader.galaxyShowCloudSavesById(product_id, build_index);
downloader.galaxyShowCloudSaves(product_id, build_index);
}
else if (!galaxy_product_id_install.empty())
{

View File

@ -50,6 +50,11 @@ ThreadSafeQueue<zipFileEntry> dlQueueGalaxy_MojoSetupHack;
std::mutex mtx_create_directories; // Mutex for creating directories in Downloader::processDownloadQueue
std::atomic<unsigned long long> iTotalRemainingBytes(0);
std::string username() {
auto user = std::getenv("USER");
return user ? user : std::string();
}
Downloader::Downloader()
{
if (Globals::globalConfig.bLogin)
@ -4096,13 +4101,54 @@ void Downloader::galaxyShowBuildsById(const std::string& product_id, int build_i
return;
}
std::string parseLocationHelper(const std::string &location, const std::map<std::string, std::string> &var) {
char search_arg[2] {'?', '>'};
auto it = std::search(std::begin(location), std::end(location), std::begin(search_arg), std::end(search_arg));
if(it == std::end(location)) {
return location;
}
std::string var_name { std::begin(location) + 2, it };
auto relative_path = it + 2;
auto var_value = var.find(var_name);
if(var_value == std::end(var)) {
return location;
}
std::string parsedLocation;
parsedLocation.insert(std::end(parsedLocation), std::begin(var_value->second), std::end(var_value->second));
parsedLocation.insert(std::end(parsedLocation), relative_path, std::end(location));
return parsedLocation;
}
std::string parseLocation(const std::string &location, const std::map<std::string, std::string> &var) {
auto parsedLocation = parseLocationHelper(location, var);
Util::replaceAllString(parsedLocation, "\\", "/");
return parsedLocation;
}
void Downloader::galaxyShowCloudSaves(const std::string& product_id, int build_index)
{
std::string id;
if(this->galaxySelectProductIdHelper(product_id, id))
{
if (!id.empty())
this->galaxyShowCloudSavesById(id, build_index);
}
}
void Downloader::galaxyShowCloudSavesById(const std::string& product_id, int build_index)
{
std::string sPlatform;
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
std::cout << "Cloud saves for Linux builds not yet supported" << std::endl;
return;
}
else if (iPlatform == GlobalConstants::PLATFORM_MAC)
sPlatform = "osx";
else
@ -4157,11 +4203,12 @@ void Downloader::galaxyShowCloudSavesById(const std::string& product_id, int bui
std::string link = json["items"][build_index]["link"].asString();
Json::Value manifest;
if (json["items"][build_index]["generation"].asInt() == 2)
{
std::string buildHash;
buildHash.assign(link.begin()+link.find_last_of("/")+1, link.end());
json = gogGalaxy->getManifestV2(buildHash);
manifest = gogGalaxy->getManifestV2(buildHash);
}
else
{
@ -4169,7 +4216,18 @@ void Downloader::galaxyShowCloudSavesById(const std::string& product_id, int bui
return;
}
json = gogGalaxy->getCloudPathAsJson(json["clientId"].asString());
std::string install_directory;
if (Globals::globalConfig.dirConf.bSubDirectories)
{
install_directory = this->getGalaxyInstallDirectory(gogGalaxy, json);
}
std::string install_path = Globals::globalConfig.dirConf.sDirectory + install_directory;
std::string document_path = Globals::globalConfig.dirConf.sWinePrefix + "drive_c/users/" + username() + "/Documents/";
std::string appdata_roaming = Globals::globalConfig.dirConf.sWinePrefix + "drive_c/users/" + username() + "/AppData/Roaming/";
std::string appdata_local_path = Globals::globalConfig.dirConf.sWinePrefix + "drive_c/users/" + username() + "/AppData/Local/";
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 platform;
switch(iPlatform) {
@ -4180,8 +4238,37 @@ void Downloader::galaxyShowCloudSavesById(const std::string& product_id, int bui
platform = "Windows";
}
json = gogGalaxy->getCloudPathAsJson(manifest["clientId"].asString());
json = json["content"][platform]["cloudStorage"]["locations"];
Json::StyledStreamWriter().write(std::cout, json);
struct cloud_save_t {
std::string name;
std::string location;
};
std::map<std::string, std::string> vars {
{ "INSTALL", std::move(install_path) },
{ "DOCUMENTS", std::move(document_path) },
{ "APPLICATION_DATA_ROAMING", std::move(appdata_roaming)},
{ "APPLICATION_DATA_LOCAL", std::move(appdata_local_path) },
{ "APPLICATION_DATA_LOCAL_LOW", std::move(appdata_local_low_path) },
{ "SAVED_GAMES", std::move(saved_games) },
};
std::vector<cloud_save_t> cloud_saves;
for(auto &cloud_save : json) {
std::string location = parseLocation(cloud_save["location"].asString(), vars);
std::string name = cloud_save["name"].asString();
cloud_saves.emplace_back(cloud_save_t { std::move(name), std::move(location) });
}
if(cloud_saves.empty()) {
std::cout << "No cloud save locations found" << std::endl;
}
for(auto &cloud_save : cloud_saves) {
std::cout << cloud_save.name << "::" << cloud_save.location << std::endl;
}
return;
}

View File

@ -391,6 +391,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;