mirror of
https://github.com/bloxstraplabs/bloxstrap.git
synced 2025-04-21 10:01:27 -07:00
Merge pull request #1948 from pizzaboxer/bugfix/channel-common-downloading
Add replacing channel name for download + slight RobloxDeployment cleanup
This commit is contained in:
commit
511a4f4708
8
Bloxstrap/Models/ClientFlagSettings.cs
Normal file
8
Bloxstrap/Models/ClientFlagSettings.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace Bloxstrap.Models
|
||||||
|
{
|
||||||
|
public class ClientFlagSettings
|
||||||
|
{
|
||||||
|
[JsonPropertyName("applicationSettings")]
|
||||||
|
public Dictionary<string, string>? ApplicationSettings { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -15,12 +15,12 @@
|
|||||||
{ "https://setup.rbxcdn.com", 0 },
|
{ "https://setup.rbxcdn.com", 0 },
|
||||||
{ "https://setup-ak.rbxcdn.com", 2 },
|
{ "https://setup-ak.rbxcdn.com", 2 },
|
||||||
{ "https://roblox-setup.cachefly.net", 2 },
|
{ "https://roblox-setup.cachefly.net", 2 },
|
||||||
{ "https://s3.amazonaws.com/setup.roblox.com", 4 }
|
{ "https://s3.amazonaws.com/setup.roblox.com", 4 }
|
||||||
};
|
};
|
||||||
|
|
||||||
private static async Task<string?> TestConnection(string url, int priority)
|
private static async Task<string?> TestConnection(string url, int priority)
|
||||||
{
|
{
|
||||||
string LOG_IDENT = $"DeployManager::TestConnection.{url}";
|
string LOG_IDENT = $"RobloxDeployment::TestConnection.{url}";
|
||||||
|
|
||||||
await Task.Delay(priority * 1000);
|
await Task.Delay(priority * 1000);
|
||||||
|
|
||||||
@ -47,7 +47,7 @@
|
|||||||
|
|
||||||
public static async Task<Exception?> InitializeConnectivity()
|
public static async Task<Exception?> InitializeConnectivity()
|
||||||
{
|
{
|
||||||
const string LOG_IDENT = "DeployManager::InitializeConnectivity";
|
const string LOG_IDENT = "RobloxDeployment::InitializeConnectivity";
|
||||||
|
|
||||||
// this function serves double duty as the setup mirror enumerator, and as our connectivity check
|
// this function serves double duty as the setup mirror enumerator, and as our connectivity check
|
||||||
// since we're basically asking four different urls for the exact same thing, if all four fail, then it has to be a user-side problem
|
// since we're basically asking four different urls for the exact same thing, if all four fail, then it has to be a user-side problem
|
||||||
@ -95,7 +95,16 @@
|
|||||||
string location = BaseUrl;
|
string location = BaseUrl;
|
||||||
|
|
||||||
if (channel.ToLowerInvariant() != DefaultChannel.ToLowerInvariant())
|
if (channel.ToLowerInvariant() != DefaultChannel.ToLowerInvariant())
|
||||||
location += $"/channel/{channel.ToLowerInvariant()}";
|
{
|
||||||
|
string channelName;
|
||||||
|
|
||||||
|
if (RobloxFastFlags.GetSettings(nameof(RobloxFastFlags.PCClientBootstrapper), channel).Get<bool>("FFlagReplaceChannelNameForDownload"))
|
||||||
|
channelName = "common";
|
||||||
|
else
|
||||||
|
channelName = channel.ToLowerInvariant();
|
||||||
|
|
||||||
|
location += $"/channel/{channelName}";
|
||||||
|
}
|
||||||
|
|
||||||
location += resource;
|
location += resource;
|
||||||
|
|
||||||
@ -123,7 +132,6 @@
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// TODO - this needs to try both clientsettings and clientsettingscdn
|
|
||||||
deployInfoResponse = await App.HttpClient.GetAsync("https://clientsettingscdn.roblox.com" + path);
|
deployInfoResponse = await App.HttpClient.GetAsync("https://clientsettingscdn.roblox.com" + path);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
144
Bloxstrap/RobloxFastFlags.cs
Normal file
144
Bloxstrap/RobloxFastFlags.cs
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
|
namespace Bloxstrap
|
||||||
|
{
|
||||||
|
public class RobloxFastFlags
|
||||||
|
{
|
||||||
|
private string _applicationName;
|
||||||
|
private string _channelName;
|
||||||
|
|
||||||
|
private bool _initialised = false;
|
||||||
|
private Dictionary<string, string>? _flags;
|
||||||
|
|
||||||
|
private SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1, 1);
|
||||||
|
|
||||||
|
private RobloxFastFlags(string applicationName, string channelName)
|
||||||
|
{
|
||||||
|
_applicationName = applicationName;
|
||||||
|
_channelName = channelName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Fetch()
|
||||||
|
{
|
||||||
|
if (_initialised)
|
||||||
|
return;
|
||||||
|
|
||||||
|
await semaphoreSlim.WaitAsync();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (_initialised)
|
||||||
|
return;
|
||||||
|
|
||||||
|
string logIndent = $"RobloxFastFlags::Fetch.{_applicationName}.{_channelName}";
|
||||||
|
App.Logger.WriteLine(logIndent, "Fetching fast flags");
|
||||||
|
|
||||||
|
string path = $"/v2/settings/application/{_applicationName}";
|
||||||
|
if (_channelName != RobloxDeployment.DefaultChannel.ToLowerInvariant())
|
||||||
|
path += $"/bucket/{_channelName}";
|
||||||
|
|
||||||
|
HttpResponseMessage response;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
response = await App.HttpClient.GetAsync("https://clientsettingscdn.roblox.com" + path);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
App.Logger.WriteLine(logIndent, "Failed to contact clientsettingscdn! Falling back to clientsettings...");
|
||||||
|
App.Logger.WriteException(logIndent, ex);
|
||||||
|
|
||||||
|
response = await App.HttpClient.GetAsync("https://clientsettings.roblox.com" + path);
|
||||||
|
}
|
||||||
|
|
||||||
|
string rawResponse = await response.Content.ReadAsStringAsync();
|
||||||
|
|
||||||
|
if (!response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
App.Logger.WriteLine(logIndent,
|
||||||
|
"Failed to fetch client settings!\r\n" +
|
||||||
|
$"\tStatus code: {response.StatusCode}\r\n" +
|
||||||
|
$"\tResponse: {rawResponse}"
|
||||||
|
);
|
||||||
|
|
||||||
|
throw new HttpResponseException(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
var clientSettings = JsonSerializer.Deserialize<ClientFlagSettings>(rawResponse);
|
||||||
|
|
||||||
|
if (clientSettings == null)
|
||||||
|
throw new Exception("Deserialised client settings is null!");
|
||||||
|
|
||||||
|
if (clientSettings.ApplicationSettings == null)
|
||||||
|
throw new Exception("Deserialised application settings is null!");
|
||||||
|
|
||||||
|
_flags = clientSettings.ApplicationSettings;
|
||||||
|
_initialised = true;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
semaphoreSlim.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<T?> GetAsync<T>(string name)
|
||||||
|
{
|
||||||
|
await Fetch();
|
||||||
|
|
||||||
|
if (!_flags!.ContainsKey(name))
|
||||||
|
return default;
|
||||||
|
|
||||||
|
string value = _flags[name];
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var converter = TypeDescriptor.GetConverter(typeof(T));
|
||||||
|
if (converter == null)
|
||||||
|
return default;
|
||||||
|
|
||||||
|
return (T?)converter.ConvertFromString(value);
|
||||||
|
}
|
||||||
|
catch (NotSupportedException) // boohoo
|
||||||
|
{
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public T? Get<T>(string name)
|
||||||
|
{
|
||||||
|
return GetAsync<T>(name).Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// _cache[applicationName][channelName]
|
||||||
|
private static Dictionary<string, Dictionary<string, RobloxFastFlags>> _cache = new();
|
||||||
|
|
||||||
|
public static RobloxFastFlags PCDesktopClient { get; } = GetSettings("PCDesktopClient");
|
||||||
|
public static RobloxFastFlags PCClientBootstrapper { get; } = GetSettings("PCClientBootstrapper");
|
||||||
|
|
||||||
|
public static RobloxFastFlags GetSettings(string applicationName, string? channelName = null, bool shouldCache = true)
|
||||||
|
{
|
||||||
|
string channelNameLower;
|
||||||
|
if (!string.IsNullOrEmpty(channelName))
|
||||||
|
channelNameLower = channelName.ToLowerInvariant();
|
||||||
|
else
|
||||||
|
channelNameLower = App.Settings.Prop.Channel.ToLowerInvariant();
|
||||||
|
|
||||||
|
lock (_cache)
|
||||||
|
{
|
||||||
|
if (_cache.ContainsKey(applicationName) && _cache[applicationName].ContainsKey(channelNameLower))
|
||||||
|
return _cache[applicationName][channelNameLower];
|
||||||
|
|
||||||
|
var flags = new RobloxFastFlags(applicationName, channelNameLower);
|
||||||
|
|
||||||
|
if (shouldCache)
|
||||||
|
{
|
||||||
|
if (!_cache.ContainsKey(applicationName))
|
||||||
|
_cache[applicationName] = new();
|
||||||
|
|
||||||
|
_cache[applicationName][channelNameLower] = flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user