Galaxy: Refactor CDN priority handling

Make CDN url template handling more generic
Add option to list available CDNs
Change default Galaxy CDN priority to "edgecast,akamai_edgecast_proxy,fastly"
This commit is contained in:
Sude 2024-08-22 13:05:50 +03:00
parent 5b53cce83e
commit e5d2c87676
8 changed files with 108 additions and 68 deletions

View File

@ -36,7 +36,7 @@ struct DownloadConfig
unsigned int iGalaxyCDN;
std::vector<unsigned int> vPlatformPriority;
std::vector<unsigned int> vLanguagePriority;
std::vector<unsigned int> vGalaxyCDNPriority;
std::vector<std::string> vGalaxyCDNPriority;
std::vector<std::string> vTags;
unsigned int iInclude;
unsigned int iGalaxyPlatform;
@ -256,6 +256,7 @@ class Config
#endif
bool bUseFastCheck;
bool bTrustAPIForExtras;
bool bGalaxyListCDNs;
// Cache
bool bUseCache;

View File

@ -124,6 +124,8 @@ 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 galaxyListCDNs(const std::string& product_id, int build_index = -1);
void galaxyListCDNsById(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 galaxyShowLocalCloudSaves(const std::string& product_id, int build_index = -1);

View File

@ -68,7 +68,7 @@ class galaxyAPI
Json::Value getDependenciesJson();
std::vector<galaxyDepotItem> getFilteredDepotItemsVectorFromJson(const Json::Value& depot_json, const std::string& galaxy_language, const std::string& galaxy_arch, const bool& is_dependency = false);
std::string getPathFromDownlinkUrl(const std::string& downlink_url, const std::string& gamename);
std::vector<std::string> cdnUrlTemplatesFromJson(const Json::Value& json, const std::vector<unsigned int>& cdnPriority);
std::vector<std::string> cdnUrlTemplatesFromJson(const Json::Value& json, const std::vector<std::string>& cdnPriority);
protected:
private:
CurlConfig curlConf;

View File

@ -102,22 +102,6 @@ namespace GlobalConstants
{ ARCH_X64, "64", "64-bit", "64|x64|64bit|64-bit" }
};
// Galaxy CDNs
const unsigned int CDN_EDGECAST = 1 << 0;
const unsigned int CDN_HIGHWINDS = 1 << 1;
const unsigned int CDN_GOG = 1 << 2;
const unsigned int CDN_LUMEN = 1 << 3;
const unsigned int CDN_AKAMAI = 1 << 4;
const std::vector<optionsStruct> GALAXY_CDNS =
{
{ CDN_EDGECAST, "edgecast", "Edgecast", "ec|edgecast" },
{ CDN_HIGHWINDS, "high_winds", "Highwinds", "hw|highwinds|high_winds" },
{ CDN_GOG, "gog_cdn", "GOG", "gog|gog_cdn" },
{ CDN_LUMEN, "lumen", "Lumen", "lumen|lumen_cdn" },
{ CDN_AKAMAI, "akamai_edgecast_proxy", "Akamai", "akamai|akamai_cdn|akamai_ec|akamai_edgecast_proxy" }
};
const unsigned int LIST_FORMAT_GAMES = 1 << 0;
const unsigned int LIST_FORMAT_DETAILS_TEXT = 1 << 1;
const unsigned int LIST_FORMAT_DETAILS_JSON = 1 << 2;

View File

@ -125,11 +125,8 @@ int main(int argc, char *argv[])
// Create help text for --galaxy-cdn-priority option
std::string galaxy_cdn_priority_text = "Set priority for used CDNs\n";
for (unsigned int i = 0; i < GlobalConstants::GALAXY_CDNS.size(); ++i)
{
galaxy_cdn_priority_text += GlobalConstants::GALAXY_CDNS[i].str + " = " + GlobalConstants::GALAXY_CDNS[i].regexp + "\n";
}
galaxy_cdn_priority_text += "\n" + priority_help_text;
galaxy_cdn_priority_text += "Use --galaxy-list-cdns to list available CDNs\n";
galaxy_cdn_priority_text += "Set priority by separating values with \",\"";
// Create help text for --check-orphans
std::string orphans_regex_default = ".*\\.(zip|exe|bin|dmg|old|deb|tar\\.gz|pkg|sh|mp4)$"; // Limit to files with these extensions (".old" is for renamed older version files)
@ -155,6 +152,7 @@ int main(int argc, char *argv[])
}
std::string galaxy_product_id_install;
std::string galaxy_product_id_list_cdns;
std::string galaxy_product_id_show_builds;
std::string galaxy_product_id_show_cloud_paths;
std::string galaxy_product_id_show_local_cloud_paths;
@ -313,7 +311,8 @@ int main(int argc, char *argv[])
("galaxy-arch", bpo::value<std::string>(&sGalaxyArch)->default_value("x64"), galaxy_arch_text.c_str())
("galaxy-no-dependencies", bpo::value<bool>(&bNoGalaxyDependencies)->zero_tokens()->default_value(false), "Don't download dependencies during --galaxy-install")
("subdir-galaxy-install", bpo::value<std::string>(&Globals::globalConfig.dirConf.sGalaxyInstallSubdir)->default_value("%install_dir%"), galaxy_install_subdir_text.c_str())
("galaxy-cdn-priority", bpo::value<std::string>(&sGalaxyCDN)->default_value("edgecast,highwinds,akamai,lumen,gog_cdn"), galaxy_cdn_priority_text.c_str())
("galaxy-cdn-priority", bpo::value<std::string>(&sGalaxyCDN)->default_value("edgecast,akamai_edgecast_proxy,fastly"), galaxy_cdn_priority_text.c_str())
("galaxy-list-cdns", bpo::value<std::string>(&galaxy_product_id_list_cdns)->default_value(""), "List available CDNs for 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")
;
options_cli_all.add(options_cli_no_cfg).add(options_cli_cfg).add(options_cli_experimental);
@ -577,7 +576,7 @@ int main(int argc, char *argv[])
if (Globals::globalConfig.dlConf.iGalaxyArch == 0 || Globals::globalConfig.dlConf.iGalaxyArch == Util::getOptionValue("all", GlobalConstants::GALAXY_ARCHS, false))
Globals::globalConfig.dlConf.iGalaxyArch = GlobalConstants::ARCH_X64;
Util::parseOptionString(sGalaxyCDN, Globals::globalConfig.dlConf.vGalaxyCDNPriority, Globals::globalConfig.dlConf.iGalaxyCDN, GlobalConstants::GALAXY_CDNS);
Globals::globalConfig.dlConf.vGalaxyCDNPriority = Util::tokenize(sGalaxyCDN, ",");
unsigned int include_value = 0;
unsigned int exclude_value = 0;
@ -876,6 +875,17 @@ int main(int argc, char *argv[])
}
downloader.galaxyInstallGame(product_id, build_index, Globals::globalConfig.dlConf.iGalaxyArch);
}
else if (!galaxy_product_id_list_cdns.empty())
{
int build_index = -1;
std::vector<std::string> tokens = Util::tokenize(galaxy_product_id_list_cdns, "/");
std::string product_id = tokens[0];
if (tokens.size() == 2)
{
build_index = std::stoi(tokens[1]);
}
downloader.galaxyListCDNs(product_id, build_index);
}
else if (!galaxy_product_cloud_saves.empty()) {
int build_index = -1;
std::vector<std::string> tokens = Util::tokenize(galaxy_product_cloud_saves, "/");

View File

@ -561,24 +561,21 @@ is removed:
.br
> \- _ . ( ) [ ] { }
.TP
\fB\-\-galaxy\-cdn\-priority\fR arg (=edgecast,highwinds,akamai,lumen,gog_cdn)
\fB\-\-galaxy\-cdn\-priority\fR arg (=edgecast,akamai_edgecast_proxy,fastly)
Set priority for used CDNs
.br
Edgecast = ec|edgecast
Use \-\-galaxy\-list\-cdns to list available CDNs
.br
Highwinds = hw|highwinds|high_winds
.br
GOG = gog|gog_cdn
.br
Lumen = lumen|lumen_cdn
.br
Akamai = akamai|akamai_cdn|akamai_ec|ak
.br
amai_edgecast_proxy
.sp 1
Set priority by separating values with ","
.TP
\fB\-\-galaxy\-list-cdns\fR arg
List available CDNs for a game using product id [product_id/build_index] or
gamename regex [gamename/build_id]
.br
Build index is used to select a build and defaults to 0 if not specified.
.br
Example: 12345/2 selects build 2 for product 12345
.br
Combine values by separating with "+"
.SH LANGUAGES
Languages available to select with \fB\-\-language\fR and \fB\-\-galaxy\-language\fR options
.br

View File

@ -4159,6 +4159,69 @@ void Downloader::galaxyInstallGameById(const std::string& product_id, int build_
}
}
void Downloader::galaxyListCDNs(const std::string& product_id, int build_index)
{
std::string id;
if(this->galaxySelectProductIdHelper(product_id, id))
{
if (!id.empty())
this->galaxyListCDNsById(id, build_index);
}
}
void Downloader::galaxyListCDNsById(const std::string& product_id, int build_index)
{
if (build_index < 0)
build_index = 0;
std::string sPlatform;
unsigned int iPlatform = Globals::globalConfig.dlConf.iGalaxyPlatform;
if (iPlatform == GlobalConstants::PLATFORM_LINUX)
sPlatform = "linux";
else if (iPlatform == GlobalConstants::PLATFORM_MAC)
sPlatform = "osx";
else
sPlatform = "windows";
Json::Value json = gogGalaxy->getProductBuilds(product_id, sPlatform);
// JSON is empty and platform is Linux. Most likely cause is that Galaxy API doesn't have Linux support
if (json.empty() && iPlatform == GlobalConstants::PLATFORM_LINUX)
{
std::cout << "Galaxy API doesn't have Linux support" << std::endl;
return;
}
if (json["items"][build_index]["generation"].asInt() != 2)
{
std::cout << "Only generation 2 builds are supported currently" << std::endl;
return;
}
std::string link = json["items"][build_index]["link"].asString();
std::string buildHash;
buildHash.assign(link.begin()+link.find_last_of("/")+1, link.end());
json = gogGalaxy->getSecureLink(product_id, "/");
std::vector<std::string> vEndpointNames;
if (!json.empty())
{
for (unsigned int i = 0; i < json["urls"].size(); ++i)
{
std::string endpoint_name = json["urls"][i]["endpoint_name"].asString();
if (!endpoint_name.empty())
vEndpointNames.push_back(endpoint_name);
}
}
for (auto endpoint : vEndpointNames)
std::cout << endpoint << std::endl;
return;
}
void Downloader::processGalaxyDownloadQueue(const std::string& install_path, Config conf, const unsigned int& tid)
{
std::string msg_prefix = "[Thread #" + std::to_string(tid) + "]";

View File

@ -590,7 +590,7 @@ std::string galaxyAPI::getPathFromDownlinkUrl(const std::string& downlink_url, c
return path;
}
std::vector<std::string> galaxyAPI::cdnUrlTemplatesFromJson(const Json::Value& json, const std::vector<unsigned int>& cdnPriority)
std::vector<std::string> galaxyAPI::cdnUrlTemplatesFromJson(const Json::Value& json, const std::vector<std::string>& cdnPriority)
{
// Handle priority of CDNs
struct urlPriority
@ -606,10 +606,9 @@ std::vector<std::string> galaxyAPI::cdnUrlTemplatesFromJson(const Json::Value& j
std::string endpoint_name = json["urls"][i]["endpoint_name"].asString();
unsigned int score = cdnPriority.size();
unsigned int cdn = Util::getOptionValue(endpoint_name, GlobalConstants::GALAXY_CDNS, false);
for (unsigned int idx = 0; idx < score; ++idx)
{
if (cdn & cdnPriority[idx])
if (endpoint_name == cdnPriority[idx])
{
score = idx;
break;
@ -625,36 +624,20 @@ std::vector<std::string> galaxyAPI::cdnUrlTemplatesFromJson(const Json::Value& j
}
// Build url according to url_format
std::string link_base_url = json["urls"][i]["parameters"]["base_url"].asString();
std::string link_path = json["urls"][i]["parameters"]["path"].asString();
std::string link_token = json["urls"][i]["parameters"]["token"].asString();
std::string url = json["urls"][i]["url_format"].asString();
for (auto cdn_url_template_param : json["urls"][i]["parameters"].getMemberNames())
{
std::string template_to_replace = "{" + cdn_url_template_param + "}";
std::string replacement = json["urls"][i]["parameters"][cdn_url_template_param].asString();
// Add our own template to path
link_path += "{LGOGDOWNLOADER_GALAXY_PATH}";
if (template_to_replace == "{path}")
{
replacement += "{LGOGDOWNLOADER_GALAXY_PATH}";
}
std::string url = json["urls"][i]["url_format"].asString();
while(Util::replaceString(url, "{base_url}", link_base_url));
while(Util::replaceString(url, "{path}", link_path));
while(Util::replaceString(url, "{token}", link_token));
// Highwinds specific
std::string link_hw_l= json["urls"][i]["parameters"]["l"].asString();
std::string link_hw_source = json["urls"][i]["parameters"]["source"].asString();
std::string link_hw_ttl = json["urls"][i]["parameters"]["ttl"].asString();
std::string link_hw_gog_token = json["urls"][i]["parameters"]["gog_token"].asString();
while(Util::replaceString(url, "{l}", link_hw_l));
while(Util::replaceString(url, "{source}", link_hw_source));
while(Util::replaceString(url, "{ttl}", link_hw_ttl));
while(Util::replaceString(url, "{gog_token}", link_hw_gog_token));
// Lumen specific
std::string dirs = json["urls"][i]["parameters"]["dirs"].asString();
std::string expires_at = json["urls"][i]["parameters"]["expires_at"].asString();
while(Util::replaceString(url, "{dirs}", dirs));
while(Util::replaceString(url, "{expires_at}", expires_at));
while(Util::replaceString(url, template_to_replace, replacement));
}
urlPriority cdnurl;
cdnurl.url = url;