mirror of
https://github.com/bloxstraplabs/bloxstrap.git
synced 2025-04-21 10:01:27 -07:00
Refactor arg parser + channel handling
this commit changes way too many things to be stable. be warned of bugs if using this
This commit is contained in:
parent
943acd78e8
commit
765cccf89e
@ -86,7 +86,7 @@ namespace Bloxstrap
|
|||||||
|
|
||||||
_showingExceptionDialog = true;
|
_showingExceptionDialog = true;
|
||||||
|
|
||||||
if (!LaunchSettings.IsQuiet)
|
if (!LaunchSettings.QuietFlag.Active)
|
||||||
Frontend.ShowExceptionDialog(exception);
|
Frontend.ShowExceptionDialog(exception);
|
||||||
|
|
||||||
Terminate(ErrorCode.ERROR_INSTALL_FAILURE);
|
Terminate(ErrorCode.ERROR_INSTALL_FAILURE);
|
||||||
@ -190,7 +190,7 @@ namespace Bloxstrap
|
|||||||
if (Paths.Process != Paths.Application && !File.Exists(Paths.Application))
|
if (Paths.Process != Paths.Application && !File.Exists(Paths.Application))
|
||||||
File.Copy(Paths.Process, Paths.Application);
|
File.Copy(Paths.Process, Paths.Application);
|
||||||
|
|
||||||
Logger.Initialize(LaunchSettings.IsUninstall);
|
Logger.Initialize(LaunchSettings.UninstallFlag.Active);
|
||||||
|
|
||||||
if (!Logger.Initialized && !Logger.NoWriteMode)
|
if (!Logger.Initialized && !Logger.NoWriteMode)
|
||||||
{
|
{
|
||||||
@ -204,7 +204,7 @@ namespace Bloxstrap
|
|||||||
|
|
||||||
// we can only parse them now as settings need
|
// we can only parse them now as settings need
|
||||||
// to be loaded first to know what our channel is
|
// to be loaded first to know what our channel is
|
||||||
LaunchSettings.ParseRoblox();
|
// LaunchSettings.ParseRoblox();
|
||||||
|
|
||||||
if (!Locale.SupportedLocales.ContainsKey(Settings.Prop.Locale))
|
if (!Locale.SupportedLocales.ContainsKey(Settings.Prop.Locale))
|
||||||
{
|
{
|
||||||
@ -214,7 +214,7 @@ namespace Bloxstrap
|
|||||||
|
|
||||||
Locale.Set(Settings.Prop.Locale);
|
Locale.Set(Settings.Prop.Locale);
|
||||||
|
|
||||||
if (!LaunchSettings.IsUninstall)
|
if (!LaunchSettings.UninstallFlag.Active)
|
||||||
Installer.HandleUpgrade();
|
Installer.HandleUpgrade();
|
||||||
|
|
||||||
LaunchHandler.ProcessLaunchArgs();
|
LaunchHandler.ProcessLaunchArgs();
|
||||||
|
@ -27,8 +27,8 @@ namespace Bloxstrap
|
|||||||
private string _playerFileName => _launchMode == LaunchMode.Player ? "RobloxPlayerBeta.exe" : "RobloxStudioBeta.exe";
|
private string _playerFileName => _launchMode == LaunchMode.Player ? "RobloxPlayerBeta.exe" : "RobloxStudioBeta.exe";
|
||||||
private string _playerLocation => Path.Combine(_versionFolder, _playerFileName);
|
private string _playerLocation => Path.Combine(_versionFolder, _playerFileName);
|
||||||
|
|
||||||
private string _launchCommandLine;
|
private string _launchCommandLine = App.LaunchSettings.RobloxLaunchArgs;
|
||||||
private LaunchMode _launchMode;
|
private LaunchMode _launchMode = App.LaunchSettings.RobloxLaunchMode;
|
||||||
private bool _installWebView2;
|
private bool _installWebView2;
|
||||||
|
|
||||||
private string _versionGuid
|
private string _versionGuid
|
||||||
@ -81,10 +81,8 @@ namespace Bloxstrap
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Core
|
#region Core
|
||||||
public Bootstrapper(string launchCommandLine, LaunchMode launchMode, bool installWebView2)
|
public Bootstrapper(bool installWebView2)
|
||||||
{
|
{
|
||||||
_launchCommandLine = launchCommandLine;
|
|
||||||
_launchMode = launchMode;
|
|
||||||
_installWebView2 = installWebView2;
|
_installWebView2 = installWebView2;
|
||||||
|
|
||||||
_packageDirectories = _launchMode == LaunchMode.Player ? PackageMap.Player : PackageMap.Studio;
|
_packageDirectories = _launchMode == LaunchMode.Player ? PackageMap.Player : PackageMap.Studio;
|
||||||
@ -217,7 +215,7 @@ namespace Bloxstrap
|
|||||||
|
|
||||||
await mutex.ReleaseAsync();
|
await mutex.ReleaseAsync();
|
||||||
|
|
||||||
if (!App.LaunchSettings.IsNoLaunch && !_cancelFired)
|
if (!App.LaunchSettings.NoLaunchFlag.Active && !_cancelFired)
|
||||||
await StartRoblox();
|
await StartRoblox();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,32 +223,59 @@ namespace Bloxstrap
|
|||||||
{
|
{
|
||||||
const string LOG_IDENT = "Bootstrapper::CheckLatestVersion";
|
const string LOG_IDENT = "Bootstrapper::CheckLatestVersion";
|
||||||
|
|
||||||
|
// before we do anything, we need to query our channel
|
||||||
|
// if it's set in the launch uri, we need to use it and set the registry key for it
|
||||||
|
// else, check if the registry key for it exists, and use it
|
||||||
|
|
||||||
|
string channel = "production";
|
||||||
|
|
||||||
|
string keyPath = _launchMode == LaunchMode.Player ? "RobloxPlayer" : "RobloxStudio";
|
||||||
|
|
||||||
|
using var key = Registry.CurrentUser.CreateSubKey($"SOFTWARE\\ROBLOX Corporation\\Environments\\{keyPath}\\Channel");
|
||||||
|
|
||||||
|
var match = Regex.Match(App.LaunchSettings.RobloxLaunchArgs, "channel:([a-zA-Z0-9-_]+)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
|
||||||
|
|
||||||
|
if (match.Groups.Count == 2)
|
||||||
|
{
|
||||||
|
channel = match.Groups[1].Value.ToLowerInvariant();
|
||||||
|
}
|
||||||
|
else if (key.GetValue("www.roblox.com") is string value)
|
||||||
|
{
|
||||||
|
channel = value;
|
||||||
|
}
|
||||||
|
|
||||||
ClientVersion clientVersion;
|
ClientVersion clientVersion;
|
||||||
|
|
||||||
string binaryType = _launchMode == LaunchMode.Player ? "WindowsPlayer" : "WindowsStudio64";
|
string binaryType = _launchMode == LaunchMode.Player ? "WindowsPlayer" : "WindowsStudio64";
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
clientVersion = await RobloxDeployment.GetInfo(App.Settings.Prop.Channel, binaryType: binaryType);
|
clientVersion = await RobloxDeployment.GetInfo(channel, binaryType);
|
||||||
}
|
}
|
||||||
catch (HttpResponseException ex)
|
catch (HttpResponseException ex)
|
||||||
{
|
{
|
||||||
if (ex.ResponseMessage.StatusCode is not HttpStatusCode.Unauthorized and not HttpStatusCode.Forbidden and not HttpStatusCode.NotFound)
|
if (ex.ResponseMessage.StatusCode
|
||||||
|
is not HttpStatusCode.Unauthorized
|
||||||
|
and not HttpStatusCode.Forbidden
|
||||||
|
and not HttpStatusCode.NotFound)
|
||||||
throw;
|
throw;
|
||||||
|
|
||||||
App.Logger.WriteLine(LOG_IDENT, $"Reverting enrolled channel to {RobloxDeployment.DefaultChannel} because HTTP {(int)ex.ResponseMessage.StatusCode}");
|
App.Logger.WriteLine(LOG_IDENT, $"Changing channel from {channel} to {RobloxDeployment.DefaultChannel} because HTTP {(int)ex.ResponseMessage.StatusCode}");
|
||||||
App.Settings.Prop.Channel = RobloxDeployment.DefaultChannel;
|
|
||||||
clientVersion = await RobloxDeployment.GetInfo(App.Settings.Prop.Channel, binaryType: binaryType);
|
channel = RobloxDeployment.DefaultChannel;
|
||||||
|
clientVersion = await RobloxDeployment.GetInfo(channel, binaryType);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clientVersion.IsBehindDefaultChannel)
|
if (clientVersion.IsBehindDefaultChannel)
|
||||||
{
|
{
|
||||||
App.Logger.WriteLine(LOG_IDENT, $"Changed Roblox channel from {App.Settings.Prop.Channel} to {RobloxDeployment.DefaultChannel}");
|
App.Logger.WriteLine(LOG_IDENT, $"Changing channel from {channel} to {RobloxDeployment.DefaultChannel} because channel is behind production");
|
||||||
|
|
||||||
App.Settings.Prop.Channel = RobloxDeployment.DefaultChannel;
|
channel = RobloxDeployment.DefaultChannel;
|
||||||
clientVersion = await RobloxDeployment.GetInfo(App.Settings.Prop.Channel, binaryType: binaryType);
|
clientVersion = await RobloxDeployment.GetInfo(channel, binaryType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key.SetValue("www.roblox.com", channel);
|
||||||
|
|
||||||
_latestVersionGuid = clientVersion.VersionGuid;
|
_latestVersionGuid = clientVersion.VersionGuid;
|
||||||
_versionFolder = Path.Combine(Paths.Versions, _latestVersionGuid);
|
_versionFolder = Path.Combine(Paths.Versions, _latestVersionGuid);
|
||||||
_versionPackageManifest = await PackageManifest.Get(_latestVersionGuid);
|
_versionPackageManifest = await PackageManifest.Get(_latestVersionGuid);
|
||||||
@ -262,28 +287,12 @@ namespace Bloxstrap
|
|||||||
|
|
||||||
SetStatus(Strings.Bootstrapper_Status_Starting);
|
SetStatus(Strings.Bootstrapper_Status_Starting);
|
||||||
|
|
||||||
if (_launchMode != LaunchMode.StudioAuth)
|
|
||||||
{
|
|
||||||
_launchCommandLine = _launchCommandLine.Replace("LAUNCHTIMEPLACEHOLDER", DateTimeOffset.Now.ToUnixTimeMilliseconds().ToString());
|
|
||||||
|
|
||||||
|
|
||||||
if (_launchCommandLine.StartsWith("roblox-player:1"))
|
|
||||||
_launchCommandLine += "+channel:";
|
|
||||||
else
|
|
||||||
_launchCommandLine += " -channel ";
|
|
||||||
|
|
||||||
if (App.Settings.Prop.Channel.ToLowerInvariant() == RobloxDeployment.DefaultChannel.ToLowerInvariant())
|
|
||||||
_launchCommandLine += "production";
|
|
||||||
else
|
|
||||||
_launchCommandLine += App.Settings.Prop.Channel.ToLowerInvariant();
|
|
||||||
|
|
||||||
if (App.Settings.Prop.ForceRobloxLanguage)
|
if (App.Settings.Prop.ForceRobloxLanguage)
|
||||||
{
|
{
|
||||||
var match = Regex.Match(_launchCommandLine, "gameLocale:([a-z_]+)");
|
var match = Regex.Match(_launchCommandLine, "gameLocale:([a-z_]+)", RegexOptions.CultureInvariant);
|
||||||
|
|
||||||
if (match.Groups.Count == 2)
|
if (match.Groups.Count == 2)
|
||||||
_launchCommandLine = _launchCommandLine.Replace("robloxLocale:en_us", $"robloxLocale:{match.Groups[1].Value}");
|
_launchCommandLine = _launchCommandLine.Replace("robloxLocale:en_us", $"robloxLocale:{match.Groups[1].Value}", StringComparison.InvariantCultureIgnoreCase);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// whether we should wait for roblox to exit to handle stuff in the background or clean up after roblox closes
|
// whether we should wait for roblox to exit to handle stuff in the background or clean up after roblox closes
|
||||||
@ -479,8 +488,8 @@ namespace Bloxstrap
|
|||||||
// this doesn't go under register, so we check every launch
|
// this doesn't go under register, so we check every launch
|
||||||
// just in case the stock bootstrapper changes it back
|
// just in case the stock bootstrapper changes it back
|
||||||
|
|
||||||
ProtocolHandler.Register("roblox", "Roblox", Paths.Application);
|
ProtocolHandler.Register("roblox", "Roblox", Paths.Application, "-player \"%1\"");
|
||||||
ProtocolHandler.Register("roblox-player", "Roblox", Paths.Application);
|
ProtocolHandler.Register("roblox-player", "Roblox", Paths.Application, "-player \"%1\"");
|
||||||
#if STUDIO_FEATURES
|
#if STUDIO_FEATURES
|
||||||
ProtocolHandler.Register("roblox-studio", "Roblox", Paths.Application);
|
ProtocolHandler.Register("roblox-studio", "Roblox", Paths.Application);
|
||||||
ProtocolHandler.Register("roblox-studio-auth", "Roblox", Paths.Application);
|
ProtocolHandler.Register("roblox-studio-auth", "Roblox", Paths.Application);
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
{
|
{
|
||||||
public enum LaunchMode
|
public enum LaunchMode
|
||||||
{
|
{
|
||||||
|
None,
|
||||||
Player,
|
Player,
|
||||||
Studio,
|
Studio,
|
||||||
StudioAuth
|
StudioAuth
|
||||||
|
@ -61,8 +61,8 @@ namespace Bloxstrap
|
|||||||
// only register player, for the scenario where the user installs bloxstrap, closes it,
|
// only register player, for the scenario where the user installs bloxstrap, closes it,
|
||||||
// and then launches from the website expecting it to work
|
// and then launches from the website expecting it to work
|
||||||
// studio can be implicitly registered when it's first launched manually
|
// studio can be implicitly registered when it's first launched manually
|
||||||
ProtocolHandler.Register("roblox", "Roblox", Paths.Application);
|
ProtocolHandler.Register("roblox", "Roblox", Paths.Application, "-player \"%1\"");
|
||||||
ProtocolHandler.Register("roblox-player", "Roblox", Paths.Application);
|
ProtocolHandler.Register("roblox-player", "Roblox", Paths.Application, "-player \"%1\"");
|
||||||
|
|
||||||
// TODO: implicit installation needs to reregister studio
|
// TODO: implicit installation needs to reregister studio
|
||||||
|
|
||||||
@ -167,17 +167,15 @@ namespace Bloxstrap
|
|||||||
// prompt to shutdown roblox if its currently running
|
// prompt to shutdown roblox if its currently running
|
||||||
if (processes.Any())
|
if (processes.Any())
|
||||||
{
|
{
|
||||||
if (!App.LaunchSettings.IsQuiet)
|
var result = Frontend.ShowMessageBox(
|
||||||
{
|
|
||||||
MessageBoxResult result = Frontend.ShowMessageBox(
|
|
||||||
Strings.Bootstrapper_Uninstall_RobloxRunning,
|
Strings.Bootstrapper_Uninstall_RobloxRunning,
|
||||||
MessageBoxImage.Information,
|
MessageBoxImage.Information,
|
||||||
MessageBoxButton.OKCancel
|
MessageBoxButton.OKCancel,
|
||||||
|
MessageBoxResult.OK
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result != MessageBoxResult.OK)
|
if (result != MessageBoxResult.OK)
|
||||||
App.Terminate(ErrorCode.ERROR_CANCELLED);
|
App.Terminate(ErrorCode.ERROR_CANCELLED);
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -343,7 +341,7 @@ namespace Bloxstrap
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// silently upgrade version if the command line flag is set or if we're launching from an auto update
|
// silently upgrade version if the command line flag is set or if we're launching from an auto update
|
||||||
if (!App.LaunchSettings.IsUpgrade && !isAutoUpgrade)
|
if (!App.LaunchSettings.UpgradeFlag.Active && !isAutoUpgrade)
|
||||||
{
|
{
|
||||||
var result = Frontend.ShowMessageBox(
|
var result = Frontend.ShowMessageBox(
|
||||||
Strings.InstallChecker_VersionDifferentThanInstalled,
|
Strings.InstallChecker_VersionDifferentThanInstalled,
|
||||||
@ -459,6 +457,9 @@ namespace Bloxstrap
|
|||||||
}
|
}
|
||||||
|
|
||||||
Registry.CurrentUser.DeleteSubKeyTree("Software\\Bloxstrap", false);
|
Registry.CurrentUser.DeleteSubKeyTree("Software\\Bloxstrap", false);
|
||||||
|
|
||||||
|
ProtocolHandler.Register("roblox", "Roblox", Paths.Application, "-player \"%1\"");
|
||||||
|
ProtocolHandler.Register("roblox-player", "Roblox", Paths.Application, "-player \"%1\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
App.Settings.Save();
|
App.Settings.Save();
|
||||||
@ -469,7 +470,7 @@ namespace Bloxstrap
|
|||||||
{
|
{
|
||||||
Utilities.ShellExecute($"https://github.com/{App.ProjectRepository}/wiki/Release-notes-for-Bloxstrap-v{currentVer}");
|
Utilities.ShellExecute($"https://github.com/{App.ProjectRepository}/wiki/Release-notes-for-Bloxstrap-v{currentVer}");
|
||||||
}
|
}
|
||||||
else if (!App.LaunchSettings.IsQuiet)
|
else
|
||||||
{
|
{
|
||||||
Frontend.ShowMessageBox(
|
Frontend.ShowMessageBox(
|
||||||
string.Format(Strings.InstallChecker_Updated, currentVer),
|
string.Format(Strings.InstallChecker_Updated, currentVer),
|
||||||
|
@ -32,13 +32,15 @@ namespace Bloxstrap
|
|||||||
{
|
{
|
||||||
// this order is specific
|
// this order is specific
|
||||||
|
|
||||||
if (App.LaunchSettings.IsUninstall)
|
if (App.LaunchSettings.UninstallFlag.Active)
|
||||||
LaunchUninstaller();
|
LaunchUninstaller();
|
||||||
else if (App.LaunchSettings.IsMenuLaunch)
|
else if (App.LaunchSettings.MenuFlag.Active)
|
||||||
LaunchSettings();
|
LaunchSettings();
|
||||||
else if (App.LaunchSettings.IsRobloxLaunch)
|
else if (App.LaunchSettings.WatcherFlag.Active)
|
||||||
|
LaunchWatcher();
|
||||||
|
else if (App.LaunchSettings.RobloxLaunchMode != LaunchMode.None)
|
||||||
LaunchRoblox();
|
LaunchRoblox();
|
||||||
else if (!App.LaunchSettings.IsQuiet)
|
else if (!App.LaunchSettings.QuietFlag.Active)
|
||||||
LaunchMenu();
|
LaunchMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,14 +54,14 @@ namespace Bloxstrap
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (App.LaunchSettings.IsUninstall)
|
if (App.LaunchSettings.UninstallFlag.Active)
|
||||||
{
|
{
|
||||||
Frontend.ShowMessageBox(Strings.Bootstrapper_FirstRunUninstall, MessageBoxImage.Error);
|
Frontend.ShowMessageBox(Strings.Bootstrapper_FirstRunUninstall, MessageBoxImage.Error);
|
||||||
App.Terminate(ErrorCode.ERROR_INVALID_FUNCTION);
|
App.Terminate(ErrorCode.ERROR_INVALID_FUNCTION);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (App.LaunchSettings.IsQuiet)
|
if (App.LaunchSettings.QuietFlag.Active)
|
||||||
{
|
{
|
||||||
var installer = new Installer();
|
var installer = new Installer();
|
||||||
|
|
||||||
@ -99,7 +101,7 @@ namespace Bloxstrap
|
|||||||
bool confirmed = false;
|
bool confirmed = false;
|
||||||
bool keepData = true;
|
bool keepData = true;
|
||||||
|
|
||||||
if (App.LaunchSettings.IsQuiet)
|
if (App.LaunchSettings.QuietFlag.Active)
|
||||||
{
|
{
|
||||||
confirmed = true;
|
confirmed = true;
|
||||||
}
|
}
|
||||||
@ -154,18 +156,18 @@ namespace Bloxstrap
|
|||||||
{
|
{
|
||||||
const string LOG_IDENT = "LaunchHandler::LaunchRoblox";
|
const string LOG_IDENT = "LaunchHandler::LaunchRoblox";
|
||||||
|
|
||||||
bool installWebView2 = false;
|
|
||||||
|
|
||||||
if (!File.Exists(Path.Combine(Paths.System, "mfplat.dll")))
|
if (!File.Exists(Path.Combine(Paths.System, "mfplat.dll")))
|
||||||
{
|
{
|
||||||
Frontend.ShowMessageBox(Strings.Bootstrapper_WMFNotFound, MessageBoxImage.Error);
|
Frontend.ShowMessageBox(Strings.Bootstrapper_WMFNotFound, MessageBoxImage.Error);
|
||||||
|
|
||||||
if (!App.LaunchSettings.IsQuiet)
|
if (!App.LaunchSettings.QuietFlag.Active)
|
||||||
Utilities.ShellExecute("https://support.microsoft.com/en-us/topic/media-feature-pack-list-for-windows-n-editions-c1c6fffa-d052-8338-7a79-a4bb980a700a");
|
Utilities.ShellExecute("https://support.microsoft.com/en-us/topic/media-feature-pack-list-for-windows-n-editions-c1c6fffa-d052-8338-7a79-a4bb980a700a");
|
||||||
|
|
||||||
App.Terminate(ErrorCode.ERROR_FILE_NOT_FOUND);
|
App.Terminate(ErrorCode.ERROR_FILE_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool installWebView2 = false;
|
||||||
{
|
{
|
||||||
using var hklmKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\WOW6432Node\\Microsoft\\EdgeUpdate\\Clients\\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}");
|
using var hklmKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\WOW6432Node\\Microsoft\\EdgeUpdate\\Clients\\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}");
|
||||||
using var hkcuKey = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\EdgeUpdate\\Clients\\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}");
|
using var hkcuKey = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\EdgeUpdate\\Clients\\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}");
|
||||||
@ -193,10 +195,10 @@ namespace Bloxstrap
|
|||||||
|
|
||||||
// start bootstrapper and show the bootstrapper modal if we're not running silently
|
// start bootstrapper and show the bootstrapper modal if we're not running silently
|
||||||
App.Logger.WriteLine(LOG_IDENT, "Initializing bootstrapper");
|
App.Logger.WriteLine(LOG_IDENT, "Initializing bootstrapper");
|
||||||
var bootstrapper = new Bootstrapper(App.LaunchSettings.RobloxLaunchArgs, App.LaunchSettings.RobloxLaunchMode, installWebView2);
|
var bootstrapper = new Bootstrapper(installWebView2);
|
||||||
IBootstrapperDialog? dialog = null;
|
IBootstrapperDialog? dialog = null;
|
||||||
|
|
||||||
if (!App.LaunchSettings.IsQuiet)
|
if (!App.LaunchSettings.QuietFlag.Active)
|
||||||
{
|
{
|
||||||
App.Logger.WriteLine(LOG_IDENT, "Initializing bootstrapper dialog");
|
App.Logger.WriteLine(LOG_IDENT, "Initializing bootstrapper dialog");
|
||||||
dialog = App.Settings.Prop.BootstrapperStyle.GetNew();
|
dialog = App.Settings.Prop.BootstrapperStyle.GetNew();
|
||||||
@ -232,12 +234,17 @@ namespace Bloxstrap
|
|||||||
// this ordering is very important as all wpf windows are shown as modal dialogs, mess it up and you'll end up blocking input to one of them
|
// this ordering is very important as all wpf windows are shown as modal dialogs, mess it up and you'll end up blocking input to one of them
|
||||||
dialog?.ShowBootstrapper();
|
dialog?.ShowBootstrapper();
|
||||||
|
|
||||||
if (!App.LaunchSettings.IsNoLaunch && App.Settings.Prop.EnableActivityTracking)
|
if (!App.LaunchSettings.NoLaunchFlag.Active && App.Settings.Prop.EnableActivityTracking)
|
||||||
App.NotifyIcon?.InitializeContextMenu();
|
App.NotifyIcon?.InitializeContextMenu();
|
||||||
|
|
||||||
App.Logger.WriteLine(LOG_IDENT, "Waiting for bootstrapper task to finish");
|
App.Logger.WriteLine(LOG_IDENT, "Waiting for bootstrapper task to finish");
|
||||||
|
|
||||||
bootstrapperTask.Wait();
|
bootstrapperTask.Wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void LaunchWatcher()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,182 +12,97 @@ namespace Bloxstrap
|
|||||||
{
|
{
|
||||||
public class LaunchSettings
|
public class LaunchSettings
|
||||||
{
|
{
|
||||||
[LaunchFlag(new[] { "-preferences", "-menu", "-settings" })]
|
public LaunchFlag MenuFlag { get; } = new("preferences,menu,settings");
|
||||||
public bool IsMenuLaunch { get; set; } = false;
|
|
||||||
|
|
||||||
[LaunchFlag(new[] { "-player", "-studio" })]
|
public LaunchFlag WatcherFlag { get; } = new("watcher");
|
||||||
public bool IsRobloxLaunch { get; set; } = false;
|
|
||||||
|
|
||||||
[LaunchFlag("-quiet")]
|
public LaunchFlag QuietFlag { get; } = new("quiet");
|
||||||
public bool IsQuiet { get; private set; } = false;
|
|
||||||
|
|
||||||
[LaunchFlag("-uninstall")]
|
public LaunchFlag UninstallFlag { get; } = new("uninstall");
|
||||||
public bool IsUninstall { get; private set; } = false;
|
|
||||||
|
|
||||||
[LaunchFlag("-nolaunch")]
|
public LaunchFlag NoLaunchFlag { get; } = new("nolaunch");
|
||||||
public bool IsNoLaunch { get; private set; } = false;
|
|
||||||
|
|
||||||
[LaunchFlag("-upgrade")]
|
public LaunchFlag UpgradeFlag { get; } = new("upgrade");
|
||||||
public bool IsUpgrade { get; private set; } = false;
|
|
||||||
|
|
||||||
public LaunchMode RobloxLaunchMode { get; private set; } = LaunchMode.Player;
|
public LaunchFlag PlayerFlag { get; } = new("player");
|
||||||
|
|
||||||
public string RobloxLaunchArgs { get; private set; } = "--app";
|
public LaunchFlag StudioFlag { get; } = new("studio");
|
||||||
|
|
||||||
|
public LaunchMode RobloxLaunchMode { get; private set; } = LaunchMode.None;
|
||||||
|
|
||||||
|
public string RobloxLaunchArgs { get; private set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Original launch arguments
|
/// Original launch arguments
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string[] Args { get; private set; }
|
public string[] Args { get; private set; }
|
||||||
|
|
||||||
private Dictionary<string, PropertyInfo>? _flagMap;
|
private Dictionary<string, LaunchFlag> _flagMap = new();
|
||||||
|
|
||||||
private string? _robloxArg;
|
|
||||||
|
|
||||||
// pizzaboxer wanted this
|
|
||||||
private void ParseLaunchFlagProps()
|
|
||||||
{
|
|
||||||
_flagMap = new Dictionary<string, PropertyInfo>();
|
|
||||||
|
|
||||||
foreach (var prop in typeof(LaunchSettings).GetProperties())
|
|
||||||
{
|
|
||||||
var attr = prop.GetCustomAttribute<LaunchFlagAttribute>();
|
|
||||||
|
|
||||||
if (attr == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(attr.Name))
|
|
||||||
{
|
|
||||||
_flagMap[attr.Name] = prop;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach (var name in attr.Names!)
|
|
||||||
_flagMap[name] = prop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ParseFlag(string arg)
|
|
||||||
{
|
|
||||||
const string LOG_IDENT = "LaunchSettings::ParseFlag";
|
|
||||||
|
|
||||||
arg = arg.ToLowerInvariant();
|
|
||||||
|
|
||||||
if (_flagMap!.ContainsKey(arg))
|
|
||||||
{
|
|
||||||
var prop = _flagMap[arg];
|
|
||||||
prop.SetValue(this, true);
|
|
||||||
App.Logger.WriteLine(LOG_IDENT, $"Started with {prop.Name} flag");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// private void ParseRoblox(string arg, ref int i)
|
|
||||||
public void ParseRoblox()
|
|
||||||
{
|
|
||||||
string? arg = _robloxArg;
|
|
||||||
|
|
||||||
if (arg is null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (arg.StartsWith("roblox-player:"))
|
|
||||||
{
|
|
||||||
IsRobloxLaunch = true;
|
|
||||||
|
|
||||||
RobloxLaunchArgs = ProtocolHandler.ParseUri(arg);
|
|
||||||
|
|
||||||
RobloxLaunchMode = LaunchMode.Player;
|
|
||||||
}
|
|
||||||
else if (arg.StartsWith("roblox:"))
|
|
||||||
{
|
|
||||||
IsRobloxLaunch = true;
|
|
||||||
|
|
||||||
RobloxLaunchArgs = $"--app --deeplink {arg}";
|
|
||||||
|
|
||||||
RobloxLaunchMode = LaunchMode.Player;
|
|
||||||
}
|
|
||||||
#if STUDIO_FEATURES
|
|
||||||
else if (arg.StartsWith("roblox-studio:"))
|
|
||||||
{
|
|
||||||
RobloxLaunchArgs = ProtocolHandler.ParseUri(arg);
|
|
||||||
|
|
||||||
if (!RobloxLaunchArgs.Contains("-startEvent"))
|
|
||||||
RobloxLaunchArgs += " -startEvent www.roblox.com/robloxQTStudioStartedEvent";
|
|
||||||
|
|
||||||
RobloxLaunchMode = LaunchMode.Studio;
|
|
||||||
}
|
|
||||||
else if (arg.StartsWith("roblox-studio-auth:"))
|
|
||||||
{
|
|
||||||
RobloxLaunchArgs = HttpUtility.UrlDecode(arg);
|
|
||||||
|
|
||||||
RobloxLaunchMode = LaunchMode.StudioAuth;
|
|
||||||
}
|
|
||||||
else if (arg == "-ide")
|
|
||||||
{
|
|
||||||
RobloxLaunchMode = LaunchMode.Studio;
|
|
||||||
|
|
||||||
if (Args.Length >= 2)
|
|
||||||
{
|
|
||||||
string pathArg = Args[i + 1];
|
|
||||||
|
|
||||||
if (pathArg.StartsWith('-'))
|
|
||||||
return; // likely a launch flag, ignore it.
|
|
||||||
|
|
||||||
i++; // path arg
|
|
||||||
RobloxLaunchArgs = $"-task EditFile -localPlaceFile \"{pathArg}\"";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Parse()
|
|
||||||
{
|
|
||||||
const string LOG_IDENT = "LaunchSettings::Parse";
|
|
||||||
|
|
||||||
App.Logger.WriteLine(LOG_IDENT, "Parsing launch arguments");
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
App.Logger.WriteLine(LOG_IDENT, $"Launch arguments: {string.Join(' ', Args)}");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (Args.Length == 0)
|
|
||||||
{
|
|
||||||
App.Logger.WriteLine(LOG_IDENT, "No launch arguments to parse");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int idx = 0;
|
|
||||||
string firstArg = Args[0];
|
|
||||||
|
|
||||||
// check & handle roblox arg
|
|
||||||
if (!firstArg.StartsWith('-') || firstArg == "-ide")
|
|
||||||
{
|
|
||||||
// ParseRoblox(firstArg, ref idx);
|
|
||||||
_robloxArg = firstArg;
|
|
||||||
idx++; // roblox arg
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if there are any launch flags
|
|
||||||
if (idx > Args.Length - 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
App.Logger.WriteLine(LOG_IDENT, "Parsing launch flags");
|
|
||||||
|
|
||||||
// map out launch flags
|
|
||||||
ParseLaunchFlagProps();
|
|
||||||
|
|
||||||
// parse any launch flags
|
|
||||||
for (int i = idx; i < Args.Length; i++)
|
|
||||||
ParseFlag(Args[i]);
|
|
||||||
|
|
||||||
// cleanup flag map
|
|
||||||
_flagMap!.Clear();
|
|
||||||
_flagMap = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LaunchSettings(string[] args)
|
public LaunchSettings(string[] args)
|
||||||
{
|
{
|
||||||
|
const string LOG_IDENT = "LaunchSettings";
|
||||||
|
|
||||||
Args = args;
|
Args = args;
|
||||||
Parse();
|
|
||||||
|
// build flag map
|
||||||
|
foreach (var prop in this.GetType().GetProperties())
|
||||||
|
{
|
||||||
|
if (prop.PropertyType != typeof(LaunchFlag))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (prop.GetValue(this) is not LaunchFlag flag)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
foreach (string identifier in flag.Identifiers.Split(','))
|
||||||
|
_flagMap.Add(identifier, flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse
|
||||||
|
for (int i = 0; i < Args.Length; i++)
|
||||||
|
{
|
||||||
|
string arg = Args[i];
|
||||||
|
|
||||||
|
if (!arg.StartsWith('-'))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
string identifier = arg[1..];
|
||||||
|
|
||||||
|
if (_flagMap[identifier] is not LaunchFlag flag)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
flag.Active = true;
|
||||||
|
|
||||||
|
if (i < Args.Length - 1 && Args[i+1] is string nextArg && !nextArg.StartsWith('-'))
|
||||||
|
{
|
||||||
|
flag.Data = nextArg;
|
||||||
|
App.Logger.WriteLine(LOG_IDENT, $"Identifier '{identifier}' is active with data");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
App.Logger.WriteLine(LOG_IDENT, $"Identifier '{identifier}' is active");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PlayerFlag.Active)
|
||||||
|
ParsePlayer(PlayerFlag.Data);
|
||||||
|
else if (StudioFlag.Active)
|
||||||
|
ParseStudio(StudioFlag.Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ParsePlayer(string? data)
|
||||||
|
{
|
||||||
|
RobloxLaunchMode = LaunchMode.Player;
|
||||||
|
|
||||||
|
if (!String.IsNullOrEmpty(data))
|
||||||
|
RobloxLaunchArgs = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ParseStudio(string? data)
|
||||||
|
{
|
||||||
|
RobloxLaunchMode = LaunchMode.Studio;
|
||||||
|
|
||||||
|
// TODO: do this later
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Bloxstrap.Models.Attributes
|
|
||||||
{
|
|
||||||
public class LaunchFlagAttribute : Attribute
|
|
||||||
{
|
|
||||||
public string? Name { get; private set; }
|
|
||||||
public string[]? Names { get; private set; }
|
|
||||||
|
|
||||||
public LaunchFlagAttribute(string name)
|
|
||||||
{
|
|
||||||
Name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LaunchFlagAttribute(string[] names)
|
|
||||||
{
|
|
||||||
Names = names;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
22
Bloxstrap/Models/LaunchFlag.cs
Normal file
22
Bloxstrap/Models/LaunchFlag.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Bloxstrap.Models
|
||||||
|
{
|
||||||
|
public class LaunchFlag
|
||||||
|
{
|
||||||
|
public string Identifiers { get; private set; }
|
||||||
|
|
||||||
|
public bool Active = false;
|
||||||
|
|
||||||
|
public string? Data;
|
||||||
|
|
||||||
|
public LaunchFlag(string identifiers)
|
||||||
|
{
|
||||||
|
Identifiers = identifiers;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -16,9 +16,6 @@ namespace Bloxstrap.Models
|
|||||||
public bool ForceRobloxLanguage { get; set; } = false;
|
public bool ForceRobloxLanguage { get; set; } = false;
|
||||||
public bool UseFastFlagManager { get; set; } = true;
|
public bool UseFastFlagManager { get; set; } = true;
|
||||||
|
|
||||||
// channel configuration
|
|
||||||
public string Channel { get; set; } = RobloxDeployment.DefaultChannel;
|
|
||||||
|
|
||||||
// integration configuration
|
// integration configuration
|
||||||
public bool EnableActivityTracking { get; set; } = true;
|
public bool EnableActivityTracking { get; set; } = true;
|
||||||
public bool UseDiscordRichPresence { get; set; } = true;
|
public bool UseDiscordRichPresence { get; set; } = true;
|
||||||
|
@ -21,11 +21,11 @@
|
|||||||
},
|
},
|
||||||
"Bloxstrap (Deeplink)": {
|
"Bloxstrap (Deeplink)": {
|
||||||
"commandName": "Project",
|
"commandName": "Project",
|
||||||
"commandLineArgs": "roblox://experiences/start?placeId=13700835620"
|
"commandLineArgs": "-player \"roblox://experiences/start?placeId=13700835620\""
|
||||||
},
|
},
|
||||||
"Bloxstrap (Studio Launch)": {
|
"Bloxstrap (Studio Launch)": {
|
||||||
"commandName": "Project",
|
"commandName": "Project",
|
||||||
"commandLineArgs": "-ide"
|
"commandLineArgs": "-studio"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -9,69 +9,9 @@ namespace Bloxstrap
|
|||||||
{
|
{
|
||||||
private const string RobloxPlaceKey = "Roblox.Place";
|
private const string RobloxPlaceKey = "Roblox.Place";
|
||||||
|
|
||||||
public static string ParseUri(string protocol)
|
public static void Register(string key, string name, string handler, string handlerParam = "%1")
|
||||||
{
|
{
|
||||||
var args = new Dictionary<string, string>();
|
string handlerArgs = $"\"{handler}\" {handlerParam}";
|
||||||
bool channelArgPresent = false;
|
|
||||||
|
|
||||||
foreach (var parameter in protocol.Split('+'))
|
|
||||||
{
|
|
||||||
if (!parameter.Contains(':'))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var kv = parameter.Split(':');
|
|
||||||
string key = kv[0];
|
|
||||||
string val = kv[1];
|
|
||||||
|
|
||||||
// we'll set this before launching because for some reason roblox just refuses to launch if its like a few minutes old so ???
|
|
||||||
if (key == "launchtime")
|
|
||||||
val = "LAUNCHTIMEPLACEHOLDER";
|
|
||||||
|
|
||||||
if (key == "channel" && !String.IsNullOrEmpty(val))
|
|
||||||
{
|
|
||||||
channelArgPresent = true;
|
|
||||||
EnrollChannel(val);
|
|
||||||
|
|
||||||
// we'll set the arg when launching
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
args.Add(key, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!channelArgPresent)
|
|
||||||
EnrollChannel(RobloxDeployment.DefaultChannel);
|
|
||||||
|
|
||||||
var pairs = args.Select(x => x.Key + ":" + x.Value).ToArray();
|
|
||||||
return String.Join("+", pairs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ChangeChannel(string channel)
|
|
||||||
{
|
|
||||||
if (channel.ToLowerInvariant() == App.Settings.Prop.Channel.ToLowerInvariant())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// don't change if roblox is already running
|
|
||||||
if (Process.GetProcessesByName("RobloxPlayerBeta").Any())
|
|
||||||
{
|
|
||||||
App.Logger.WriteLine("ProtocolHandler::ChangeChannel", $"Ignored channel change from {App.Settings.Prop.Channel} to {channel} because Roblox is already running");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
App.Logger.WriteLine("ProtocolHandler::ChangeChannel", $"Changed Roblox channel from {App.Settings.Prop.Channel} to {channel}");
|
|
||||||
App.Settings.Prop.Channel = channel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void EnrollChannel(string channel)
|
|
||||||
{
|
|
||||||
ChangeChannel(channel);
|
|
||||||
App.State.Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Register(string key, string name, string handler)
|
|
||||||
{
|
|
||||||
string handlerArgs = $"\"{handler}\" %1";
|
|
||||||
|
|
||||||
using var uriKey = Registry.CurrentUser.CreateSubKey($@"Software\Classes\{key}");
|
using var uriKey = Registry.CurrentUser.CreateSubKey($@"Software\Classes\{key}");
|
||||||
using var uriIconKey = uriKey.CreateSubKey("DefaultIcon");
|
using var uriIconKey = uriKey.CreateSubKey("DefaultIcon");
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
namespace Bloxstrap
|
namespace Bloxstrap
|
||||||
{
|
{
|
||||||
// TODO: this is a mess and desperately needs refactoring
|
|
||||||
public static class RobloxDeployment
|
public static class RobloxDeployment
|
||||||
{
|
{
|
||||||
public const string DefaultChannel = "LIVE";
|
public const string DefaultChannel = "production";
|
||||||
|
|
||||||
public static string BaseUrl { get; private set; } = null!;
|
public static string BaseUrl { get; private set; } = null!;
|
||||||
|
|
||||||
@ -88,14 +87,11 @@
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetLocation(string resource, string? channel = null)
|
public static string GetLocation(string resource, string channel = DefaultChannel)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(channel))
|
|
||||||
channel = App.Settings.Prop.Channel;
|
|
||||||
|
|
||||||
string location = BaseUrl;
|
string location = BaseUrl;
|
||||||
|
|
||||||
if (channel.ToLowerInvariant() != DefaultChannel.ToLowerInvariant())
|
if (String.Compare(channel, DefaultChannel, StringComparison.InvariantCultureIgnoreCase) != 0)
|
||||||
{
|
{
|
||||||
string channelName;
|
string channelName;
|
||||||
|
|
||||||
@ -112,11 +108,11 @@
|
|||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<ClientVersion> GetInfo(string channel, bool extraInformation = false, string binaryType = "WindowsPlayer")
|
public static async Task<ClientVersion> GetInfo(string channel, string binaryType = "WindowsPlayer")
|
||||||
{
|
{
|
||||||
const string LOG_IDENT = "RobloxDeployment::GetInfo";
|
const string LOG_IDENT = "RobloxDeployment::GetInfo";
|
||||||
|
|
||||||
App.Logger.WriteLine(LOG_IDENT, $"Getting deploy info for channel {channel} (extraInformation={extraInformation})");
|
App.Logger.WriteLine(LOG_IDENT, $"Getting deploy info for channel {channel}");
|
||||||
|
|
||||||
string cacheKey = $"{channel}-{binaryType}";
|
string cacheKey = $"{channel}-{binaryType}";
|
||||||
ClientVersion clientVersion;
|
ClientVersion clientVersion;
|
||||||
@ -128,7 +124,11 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string path = $"/v2/client-version/{binaryType}/channel/{channel}";
|
string path = $"/v2/client-version/{binaryType}";
|
||||||
|
|
||||||
|
if (String.Compare(channel, DefaultChannel, StringComparison.InvariantCultureIgnoreCase) != 0)
|
||||||
|
path = $"/v2/client-version/{binaryType}/channel/{channel}";
|
||||||
|
|
||||||
HttpResponseMessage deployInfoResponse;
|
HttpResponseMessage deployInfoResponse;
|
||||||
|
|
||||||
try
|
try
|
||||||
@ -173,24 +173,6 @@
|
|||||||
clientVersion.IsBehindDefaultChannel = true;
|
clientVersion.IsBehindDefaultChannel = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// for preferences
|
|
||||||
if (extraInformation && clientVersion.Timestamp is null)
|
|
||||||
{
|
|
||||||
App.Logger.WriteLine(LOG_IDENT, "Getting extra information...");
|
|
||||||
|
|
||||||
string manifestUrl = GetLocation($"/{clientVersion.VersionGuid}-rbxPkgManifest.txt", channel);
|
|
||||||
|
|
||||||
// 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(LOG_IDENT, $"{manifestUrl} - Last-Modified: {lastModified}");
|
|
||||||
clientVersion.Timestamp = DateTime.Parse(lastModified).ToLocalTime();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ClientVersionCache[cacheKey] = clientVersion;
|
ClientVersionCache[cacheKey] = clientVersion;
|
||||||
|
|
||||||
return clientVersion;
|
return clientVersion;
|
||||||
|
@ -114,27 +114,23 @@ namespace Bloxstrap
|
|||||||
public static RobloxFastFlags PCDesktopClient { get; } = GetSettings("PCDesktopClient");
|
public static RobloxFastFlags PCDesktopClient { get; } = GetSettings("PCDesktopClient");
|
||||||
public static RobloxFastFlags PCClientBootstrapper { get; } = GetSettings("PCClientBootstrapper");
|
public static RobloxFastFlags PCClientBootstrapper { get; } = GetSettings("PCClientBootstrapper");
|
||||||
|
|
||||||
public static RobloxFastFlags GetSettings(string applicationName, string? channelName = null, bool shouldCache = true)
|
public static RobloxFastFlags GetSettings(string applicationName, string channelName = RobloxDeployment.DefaultChannel, bool shouldCache = true)
|
||||||
{
|
{
|
||||||
string channelNameLower;
|
channelName = channelName.ToLowerInvariant();
|
||||||
if (!string.IsNullOrEmpty(channelName))
|
|
||||||
channelNameLower = channelName.ToLowerInvariant();
|
|
||||||
else
|
|
||||||
channelNameLower = App.Settings.Prop.Channel.ToLowerInvariant();
|
|
||||||
|
|
||||||
lock (_cache)
|
lock (_cache)
|
||||||
{
|
{
|
||||||
if (_cache.ContainsKey(applicationName) && _cache[applicationName].ContainsKey(channelNameLower))
|
if (_cache.ContainsKey(applicationName) && _cache[applicationName].ContainsKey(channelName))
|
||||||
return _cache[applicationName][channelNameLower];
|
return _cache[applicationName][channelName];
|
||||||
|
|
||||||
var flags = new RobloxFastFlags(applicationName, channelNameLower);
|
var flags = new RobloxFastFlags(applicationName, channelName);
|
||||||
|
|
||||||
if (shouldCache)
|
if (shouldCache)
|
||||||
{
|
{
|
||||||
if (!_cache.ContainsKey(applicationName))
|
if (!_cache.ContainsKey(applicationName))
|
||||||
_cache[applicationName] = new();
|
_cache[applicationName] = new();
|
||||||
|
|
||||||
_cache[applicationName][channelNameLower] = flags;
|
_cache[applicationName][channelName] = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
return flags;
|
return flags;
|
||||||
|
@ -14,10 +14,10 @@ namespace Bloxstrap.UI
|
|||||||
{
|
{
|
||||||
App.Logger.WriteLine("Frontend::ShowMessageBox", message);
|
App.Logger.WriteLine("Frontend::ShowMessageBox", message);
|
||||||
|
|
||||||
if (App.LaunchSettings.IsQuiet)
|
if (App.LaunchSettings.QuietFlag.Active)
|
||||||
return defaultResult;
|
return defaultResult;
|
||||||
|
|
||||||
if (!App.LaunchSettings.IsRobloxLaunch)
|
if (App.LaunchSettings.RobloxLaunchMode != LaunchMode.None)
|
||||||
return ShowFluentMessageBox(message, icon, buttons);
|
return ShowFluentMessageBox(message, icon, buttons);
|
||||||
|
|
||||||
switch (App.Settings.Prop.BootstrapperStyle)
|
switch (App.Settings.Prop.BootstrapperStyle)
|
||||||
|
Loading…
Reference in New Issue
Block a user