bloxstrap/Bloxstrap/Helpers/DeployManager.cs
pizzaboxer be938796ae
Add check for working deployment domain (#134)
this is gonna suck to merge into 2.2.0 lmao
2023-04-16 01:58:11 +01:00

161 lines
5.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;
using Bloxstrap.Models;
using DiscordRPC;
namespace Bloxstrap.Helpers
{
public class DeployManager
{
#region Properties
public const string DefaultChannel = "LIVE";
private string _channel = DefaultChannel;
public string Channel
{
get => _channel;
set
{
if (_channel != value)
App.Logger.WriteLine($"[DeployManager::SetChannel] Changed channel to {value}");
_channel = value;
}
}
// a list of roblox delpoyment locations that we check for, in case one of them don't work
private List<string> BaseUrls = new()
{
"https://setup.rbxcdn.com",
"https://setup-ak.rbxcdn.com",
"https://s3.amazonaws.com/setup.roblox.com"
};
private string? _baseUrl = null;
public string BaseUrl
{
get
{
if (String.IsNullOrEmpty(_baseUrl))
{
// check for a working accessible deployment domain
foreach (string attemptedUrl in BaseUrls)
{
App.Logger.WriteLine($"[DeployManager::DefaultBaseUrl.Set] Testing connection to '{attemptedUrl}'...");
try
{
App.HttpClient.GetAsync($"{attemptedUrl}/version").Wait();
App.Logger.WriteLine($"[DeployManager::DefaultBaseUrl.Set] Connection successful!");
_baseUrl = attemptedUrl;
break;
}
catch (Exception ex)
{
App.Logger.WriteLine($"[DeployManager::DefaultBaseUrl.Set] Connection failed!");
App.Logger.WriteLine($"[DeployManager::DefaultBaseUrl.Set] {ex}");
continue;
}
}
if (String.IsNullOrEmpty(_baseUrl))
throw new Exception("Unable to find an accessible Roblox deploy mirror!");
}
if (Channel == DefaultChannel)
return _baseUrl;
else
return $"{_baseUrl}/channel/{Channel.ToLower()}";
}
}
// basically any channel that has had a deploy within the past month with a windowsplayer build
public static readonly List<string> ChannelsAbstracted = new()
{
"LIVE",
"ZNext",
"ZCanary",
"ZIntegration"
};
// why not?
public static readonly List<string> ChannelsAll = new()
{
"LIVE",
"ZAvatarTeam",
"ZAvatarRelease",
"ZCanary",
"ZCanary1",
"ZCanary2",
"ZCanary3",
"ZCanaryApps",
"ZFlag",
"ZIntegration",
"ZIntegration1",
"ZLive",
"ZLive1",
"ZNext",
"ZSocialTeam",
"ZStudioInt1",
"ZStudioInt2"
};
#endregion
public async Task<ClientVersion> GetLastDeploy(bool timestamp = false)
{
App.Logger.WriteLine($"[DeployManager::GetLastDeploy] Getting deploy info for channel {Channel} (timestamp={timestamp})");
HttpResponseMessage deployInfoResponse = await App.HttpClient.GetAsync($"https://clientsettings.roblox.com/v2/client-version/WindowsPlayer/channel/{Channel}");
string rawResponse = await deployInfoResponse.Content.ReadAsStringAsync();
if (!deployInfoResponse.IsSuccessStatusCode)
{
// 400 = Invalid binaryType.
// 404 = Could not find version details for binaryType.
// 500 = Error while fetching version information.
// either way, we throw
App.Logger.WriteLine(
"[DeployManager::GetLastDeploy] Failed to fetch deploy info!\r\n"+
$"\tStatus code: {deployInfoResponse.StatusCode}\r\n"+
$"\tResponse: {rawResponse}"
);
throw new Exception($"Could not get latest deploy for channel {Channel}! (HTTP {deployInfoResponse.StatusCode})");
}
App.Logger.WriteLine($"[DeployManager::GetLastDeploy] Got JSON: {rawResponse}");
ClientVersion clientVersion = JsonSerializer.Deserialize<ClientVersion>(rawResponse)!;
// for preferences
if (timestamp)
{
App.Logger.WriteLine("[DeployManager::GetLastDeploy] Getting timestamp...");
string manifestUrl = $"{BaseUrl}/{clientVersion.VersionGuid}-rbxPkgManifest.txt";
// get an approximate deploy time from rbxpkgmanifest's last modified date
HttpResponseMessage pkgResponse = await App.HttpClient.GetAsync(manifestUrl);
if (pkgResponse.Content.Headers.TryGetValues("last-modified", out var values))
{
string lastModified = values.First();
App.Logger.WriteLine($"[DeployManager::GetLastDeploy] {manifestUrl} - Last-Modified: {lastModified}");
clientVersion.Timestamp = DateTime.Parse(lastModified).ToLocalTime();
}
}
return clientVersion;
}
}
}