From 765cccf89e5f670eb8d4740edac30b22a752c0ba Mon Sep 17 00:00:00 2001 From: pizzaboxer Date: Mon, 19 Aug 2024 15:37:56 +0100 Subject: [PATCH] Refactor arg parser + channel handling this commit changes way too many things to be stable. be warned of bugs if using this --- Bloxstrap/App.xaml.cs | 8 +- Bloxstrap/Bootstrapper.cs | 81 +++--- Bloxstrap/Enums/LaunchMode.cs | 1 + Bloxstrap/Installer.cs | 29 +-- Bloxstrap/LaunchHandler.cs | 31 ++- Bloxstrap/LaunchSettings.cs | 233 ++++++------------ .../Models/Attributes/LaunchFlagAttribute.cs | 24 -- Bloxstrap/Models/LaunchFlag.cs | 22 ++ Bloxstrap/Models/Settings.cs | 3 - Bloxstrap/Properties/launchSettings.json | 4 +- Bloxstrap/ProtocolHandler.cs | 64 +---- Bloxstrap/RobloxDeployment.cs | 38 +-- Bloxstrap/RobloxFastFlags.cs | 16 +- Bloxstrap/UI/Frontend.cs | 4 +- 14 files changed, 202 insertions(+), 356 deletions(-) delete mode 100644 Bloxstrap/Models/Attributes/LaunchFlagAttribute.cs create mode 100644 Bloxstrap/Models/LaunchFlag.cs diff --git a/Bloxstrap/App.xaml.cs b/Bloxstrap/App.xaml.cs index a1d3d83..db72422 100644 --- a/Bloxstrap/App.xaml.cs +++ b/Bloxstrap/App.xaml.cs @@ -86,7 +86,7 @@ namespace Bloxstrap _showingExceptionDialog = true; - if (!LaunchSettings.IsQuiet) + if (!LaunchSettings.QuietFlag.Active) Frontend.ShowExceptionDialog(exception); Terminate(ErrorCode.ERROR_INSTALL_FAILURE); @@ -190,7 +190,7 @@ namespace Bloxstrap if (Paths.Process != Paths.Application && !File.Exists(Paths.Application)) File.Copy(Paths.Process, Paths.Application); - Logger.Initialize(LaunchSettings.IsUninstall); + Logger.Initialize(LaunchSettings.UninstallFlag.Active); if (!Logger.Initialized && !Logger.NoWriteMode) { @@ -204,7 +204,7 @@ namespace Bloxstrap // we can only parse them now as settings need // to be loaded first to know what our channel is - LaunchSettings.ParseRoblox(); + // LaunchSettings.ParseRoblox(); if (!Locale.SupportedLocales.ContainsKey(Settings.Prop.Locale)) { @@ -214,7 +214,7 @@ namespace Bloxstrap Locale.Set(Settings.Prop.Locale); - if (!LaunchSettings.IsUninstall) + if (!LaunchSettings.UninstallFlag.Active) Installer.HandleUpgrade(); LaunchHandler.ProcessLaunchArgs(); diff --git a/Bloxstrap/Bootstrapper.cs b/Bloxstrap/Bootstrapper.cs index 86bbfd7..280d577 100644 --- a/Bloxstrap/Bootstrapper.cs +++ b/Bloxstrap/Bootstrapper.cs @@ -27,8 +27,8 @@ namespace Bloxstrap private string _playerFileName => _launchMode == LaunchMode.Player ? "RobloxPlayerBeta.exe" : "RobloxStudioBeta.exe"; private string _playerLocation => Path.Combine(_versionFolder, _playerFileName); - private string _launchCommandLine; - private LaunchMode _launchMode; + private string _launchCommandLine = App.LaunchSettings.RobloxLaunchArgs; + private LaunchMode _launchMode = App.LaunchSettings.RobloxLaunchMode; private bool _installWebView2; private string _versionGuid @@ -81,10 +81,8 @@ namespace Bloxstrap #endregion #region Core - public Bootstrapper(string launchCommandLine, LaunchMode launchMode, bool installWebView2) + public Bootstrapper(bool installWebView2) { - _launchCommandLine = launchCommandLine; - _launchMode = launchMode; _installWebView2 = installWebView2; _packageDirectories = _launchMode == LaunchMode.Player ? PackageMap.Player : PackageMap.Studio; @@ -217,7 +215,7 @@ namespace Bloxstrap await mutex.ReleaseAsync(); - if (!App.LaunchSettings.IsNoLaunch && !_cancelFired) + if (!App.LaunchSettings.NoLaunchFlag.Active && !_cancelFired) await StartRoblox(); } @@ -225,32 +223,59 @@ namespace Bloxstrap { 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; string binaryType = _launchMode == LaunchMode.Player ? "WindowsPlayer" : "WindowsStudio64"; try { - clientVersion = await RobloxDeployment.GetInfo(App.Settings.Prop.Channel, binaryType: binaryType); + clientVersion = await RobloxDeployment.GetInfo(channel, binaryType); } 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; - App.Logger.WriteLine(LOG_IDENT, $"Reverting enrolled 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); + App.Logger.WriteLine(LOG_IDENT, $"Changing channel from {channel} to {RobloxDeployment.DefaultChannel} because HTTP {(int)ex.ResponseMessage.StatusCode}"); + + channel = RobloxDeployment.DefaultChannel; + clientVersion = await RobloxDeployment.GetInfo(channel, binaryType); } 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; - clientVersion = await RobloxDeployment.GetInfo(App.Settings.Prop.Channel, binaryType: binaryType); + channel = RobloxDeployment.DefaultChannel; + clientVersion = await RobloxDeployment.GetInfo(channel, binaryType); } + key.SetValue("www.roblox.com", channel); + _latestVersionGuid = clientVersion.VersionGuid; _versionFolder = Path.Combine(Paths.Versions, _latestVersionGuid); _versionPackageManifest = await PackageManifest.Get(_latestVersionGuid); @@ -262,28 +287,12 @@ namespace Bloxstrap SetStatus(Strings.Bootstrapper_Status_Starting); - if (_launchMode != LaunchMode.StudioAuth) + if (App.Settings.Prop.ForceRobloxLanguage) { - _launchCommandLine = _launchCommandLine.Replace("LAUNCHTIMEPLACEHOLDER", DateTimeOffset.Now.ToUnixTimeMilliseconds().ToString()); + var match = Regex.Match(_launchCommandLine, "gameLocale:([a-z_]+)", RegexOptions.CultureInvariant); - - 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) - { - var match = Regex.Match(_launchCommandLine, "gameLocale:([a-z_]+)"); - - if (match.Groups.Count == 2) - _launchCommandLine = _launchCommandLine.Replace("robloxLocale:en_us", $"robloxLocale:{match.Groups[1].Value}"); - } + if (match.Groups.Count == 2) + _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 @@ -479,8 +488,8 @@ namespace Bloxstrap // this doesn't go under register, so we check every launch // just in case the stock bootstrapper changes it back - ProtocolHandler.Register("roblox", "Roblox", Paths.Application); - ProtocolHandler.Register("roblox-player", "Roblox", Paths.Application); + ProtocolHandler.Register("roblox", "Roblox", Paths.Application, "-player \"%1\""); + ProtocolHandler.Register("roblox-player", "Roblox", Paths.Application, "-player \"%1\""); #if STUDIO_FEATURES ProtocolHandler.Register("roblox-studio", "Roblox", Paths.Application); ProtocolHandler.Register("roblox-studio-auth", "Roblox", Paths.Application); diff --git a/Bloxstrap/Enums/LaunchMode.cs b/Bloxstrap/Enums/LaunchMode.cs index d1a34e9..c045d4f 100644 --- a/Bloxstrap/Enums/LaunchMode.cs +++ b/Bloxstrap/Enums/LaunchMode.cs @@ -2,6 +2,7 @@ { public enum LaunchMode { + None, Player, Studio, StudioAuth diff --git a/Bloxstrap/Installer.cs b/Bloxstrap/Installer.cs index b07634c..ccb458c 100644 --- a/Bloxstrap/Installer.cs +++ b/Bloxstrap/Installer.cs @@ -61,8 +61,8 @@ namespace Bloxstrap // only register player, for the scenario where the user installs bloxstrap, closes it, // and then launches from the website expecting it to work // studio can be implicitly registered when it's first launched manually - ProtocolHandler.Register("roblox", "Roblox", Paths.Application); - ProtocolHandler.Register("roblox-player", "Roblox", Paths.Application); + ProtocolHandler.Register("roblox", "Roblox", Paths.Application, "-player \"%1\""); + ProtocolHandler.Register("roblox-player", "Roblox", Paths.Application, "-player \"%1\""); // TODO: implicit installation needs to reregister studio @@ -167,17 +167,15 @@ namespace Bloxstrap // prompt to shutdown roblox if its currently running if (processes.Any()) { - if (!App.LaunchSettings.IsQuiet) - { - MessageBoxResult result = Frontend.ShowMessageBox( - Strings.Bootstrapper_Uninstall_RobloxRunning, - MessageBoxImage.Information, - MessageBoxButton.OKCancel - ); + var result = Frontend.ShowMessageBox( + Strings.Bootstrapper_Uninstall_RobloxRunning, + MessageBoxImage.Information, + MessageBoxButton.OKCancel, + MessageBoxResult.OK + ); - if (result != MessageBoxResult.OK) - App.Terminate(ErrorCode.ERROR_CANCELLED); - } + if (result != MessageBoxResult.OK) + App.Terminate(ErrorCode.ERROR_CANCELLED); try { @@ -343,7 +341,7 @@ namespace Bloxstrap return; // 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( Strings.InstallChecker_VersionDifferentThanInstalled, @@ -459,6 +457,9 @@ namespace Bloxstrap } 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(); @@ -469,7 +470,7 @@ namespace Bloxstrap { Utilities.ShellExecute($"https://github.com/{App.ProjectRepository}/wiki/Release-notes-for-Bloxstrap-v{currentVer}"); } - else if (!App.LaunchSettings.IsQuiet) + else { Frontend.ShowMessageBox( string.Format(Strings.InstallChecker_Updated, currentVer), diff --git a/Bloxstrap/LaunchHandler.cs b/Bloxstrap/LaunchHandler.cs index aead956..58ef421 100644 --- a/Bloxstrap/LaunchHandler.cs +++ b/Bloxstrap/LaunchHandler.cs @@ -32,13 +32,15 @@ namespace Bloxstrap { // this order is specific - if (App.LaunchSettings.IsUninstall) + if (App.LaunchSettings.UninstallFlag.Active) LaunchUninstaller(); - else if (App.LaunchSettings.IsMenuLaunch) + else if (App.LaunchSettings.MenuFlag.Active) LaunchSettings(); - else if (App.LaunchSettings.IsRobloxLaunch) + else if (App.LaunchSettings.WatcherFlag.Active) + LaunchWatcher(); + else if (App.LaunchSettings.RobloxLaunchMode != LaunchMode.None) LaunchRoblox(); - else if (!App.LaunchSettings.IsQuiet) + else if (!App.LaunchSettings.QuietFlag.Active) LaunchMenu(); } @@ -52,14 +54,14 @@ namespace Bloxstrap return; } - if (App.LaunchSettings.IsUninstall) + if (App.LaunchSettings.UninstallFlag.Active) { Frontend.ShowMessageBox(Strings.Bootstrapper_FirstRunUninstall, MessageBoxImage.Error); App.Terminate(ErrorCode.ERROR_INVALID_FUNCTION); return; } - if (App.LaunchSettings.IsQuiet) + if (App.LaunchSettings.QuietFlag.Active) { var installer = new Installer(); @@ -99,7 +101,7 @@ namespace Bloxstrap bool confirmed = false; bool keepData = true; - if (App.LaunchSettings.IsQuiet) + if (App.LaunchSettings.QuietFlag.Active) { confirmed = true; } @@ -154,18 +156,18 @@ namespace Bloxstrap { const string LOG_IDENT = "LaunchHandler::LaunchRoblox"; - bool installWebView2 = false; if (!File.Exists(Path.Combine(Paths.System, "mfplat.dll"))) { 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"); 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 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 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; - if (!App.LaunchSettings.IsQuiet) + if (!App.LaunchSettings.QuietFlag.Active) { App.Logger.WriteLine(LOG_IDENT, "Initializing bootstrapper dialog"); 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 dialog?.ShowBootstrapper(); - if (!App.LaunchSettings.IsNoLaunch && App.Settings.Prop.EnableActivityTracking) + if (!App.LaunchSettings.NoLaunchFlag.Active && App.Settings.Prop.EnableActivityTracking) App.NotifyIcon?.InitializeContextMenu(); App.Logger.WriteLine(LOG_IDENT, "Waiting for bootstrapper task to finish"); bootstrapperTask.Wait(); } + + public static void LaunchWatcher() + { + + } } } diff --git a/Bloxstrap/LaunchSettings.cs b/Bloxstrap/LaunchSettings.cs index e2062d0..a217d09 100644 --- a/Bloxstrap/LaunchSettings.cs +++ b/Bloxstrap/LaunchSettings.cs @@ -12,182 +12,97 @@ namespace Bloxstrap { public class LaunchSettings { - [LaunchFlag(new[] { "-preferences", "-menu", "-settings" })] - public bool IsMenuLaunch { get; set; } = false; + public LaunchFlag MenuFlag { get; } = new("preferences,menu,settings"); - [LaunchFlag(new[] { "-player", "-studio" })] - public bool IsRobloxLaunch { get; set; } = false; + public LaunchFlag WatcherFlag { get; } = new("watcher"); - [LaunchFlag("-quiet")] - public bool IsQuiet { get; private set; } = false; + public LaunchFlag QuietFlag { get; } = new("quiet"); - [LaunchFlag("-uninstall")] - public bool IsUninstall { get; private set; } = false; + public LaunchFlag UninstallFlag { get; } = new("uninstall"); - [LaunchFlag("-nolaunch")] - public bool IsNoLaunch { get; private set; } = false; + public LaunchFlag NoLaunchFlag { get; } = new("nolaunch"); - [LaunchFlag("-upgrade")] - public bool IsUpgrade { get; private set; } = false; + public LaunchFlag UpgradeFlag { get; } = new("upgrade"); + + public LaunchFlag PlayerFlag { get; } = new("player"); + + public LaunchFlag StudioFlag { get; } = new("studio"); - public LaunchMode RobloxLaunchMode { get; private set; } = LaunchMode.Player; + public LaunchMode RobloxLaunchMode { get; private set; } = LaunchMode.None; - public string RobloxLaunchArgs { get; private set; } = "--app"; + public string RobloxLaunchArgs { get; private set; } = ""; /// /// Original launch arguments /// public string[] Args { get; private set; } - private Dictionary? _flagMap; - - private string? _robloxArg; - - // pizzaboxer wanted this - private void ParseLaunchFlagProps() - { - _flagMap = new Dictionary(); - - foreach (var prop in typeof(LaunchSettings).GetProperties()) - { - var attr = prop.GetCustomAttribute(); - - 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; - } + private Dictionary _flagMap = new(); public LaunchSettings(string[] args) { + const string LOG_IDENT = "LaunchSettings"; + 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 } } } diff --git a/Bloxstrap/Models/Attributes/LaunchFlagAttribute.cs b/Bloxstrap/Models/Attributes/LaunchFlagAttribute.cs deleted file mode 100644 index 60c3886..0000000 --- a/Bloxstrap/Models/Attributes/LaunchFlagAttribute.cs +++ /dev/null @@ -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; - } - } -} diff --git a/Bloxstrap/Models/LaunchFlag.cs b/Bloxstrap/Models/LaunchFlag.cs new file mode 100644 index 0000000..ead3886 --- /dev/null +++ b/Bloxstrap/Models/LaunchFlag.cs @@ -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; + } + } +} diff --git a/Bloxstrap/Models/Settings.cs b/Bloxstrap/Models/Settings.cs index 584f88f..11ce9c3 100644 --- a/Bloxstrap/Models/Settings.cs +++ b/Bloxstrap/Models/Settings.cs @@ -16,9 +16,6 @@ namespace Bloxstrap.Models public bool ForceRobloxLanguage { get; set; } = false; public bool UseFastFlagManager { get; set; } = true; - // channel configuration - public string Channel { get; set; } = RobloxDeployment.DefaultChannel; - // integration configuration public bool EnableActivityTracking { get; set; } = true; public bool UseDiscordRichPresence { get; set; } = true; diff --git a/Bloxstrap/Properties/launchSettings.json b/Bloxstrap/Properties/launchSettings.json index 7dc753d..e3f8ff7 100644 --- a/Bloxstrap/Properties/launchSettings.json +++ b/Bloxstrap/Properties/launchSettings.json @@ -21,11 +21,11 @@ }, "Bloxstrap (Deeplink)": { "commandName": "Project", - "commandLineArgs": "roblox://experiences/start?placeId=13700835620" + "commandLineArgs": "-player \"roblox://experiences/start?placeId=13700835620\"" }, "Bloxstrap (Studio Launch)": { "commandName": "Project", - "commandLineArgs": "-ide" + "commandLineArgs": "-studio" } } } \ No newline at end of file diff --git a/Bloxstrap/ProtocolHandler.cs b/Bloxstrap/ProtocolHandler.cs index 6338c77..ff57e2c 100644 --- a/Bloxstrap/ProtocolHandler.cs +++ b/Bloxstrap/ProtocolHandler.cs @@ -9,69 +9,9 @@ namespace Bloxstrap { 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(); - 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"; + string handlerArgs = $"\"{handler}\" {handlerParam}"; using var uriKey = Registry.CurrentUser.CreateSubKey($@"Software\Classes\{key}"); using var uriIconKey = uriKey.CreateSubKey("DefaultIcon"); diff --git a/Bloxstrap/RobloxDeployment.cs b/Bloxstrap/RobloxDeployment.cs index 6c97d4e..b350eea 100644 --- a/Bloxstrap/RobloxDeployment.cs +++ b/Bloxstrap/RobloxDeployment.cs @@ -1,9 +1,8 @@ namespace Bloxstrap { - // TODO: this is a mess and desperately needs refactoring public static class RobloxDeployment { - public const string DefaultChannel = "LIVE"; + public const string DefaultChannel = "production"; public static string BaseUrl { get; private set; } = null!; @@ -88,14 +87,11 @@ 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; - if (channel.ToLowerInvariant() != DefaultChannel.ToLowerInvariant()) + if (String.Compare(channel, DefaultChannel, StringComparison.InvariantCultureIgnoreCase) != 0) { string channelName; @@ -112,11 +108,11 @@ return location; } - public static async Task GetInfo(string channel, bool extraInformation = false, string binaryType = "WindowsPlayer") + public static async Task GetInfo(string channel, string binaryType = "WindowsPlayer") { 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}"; ClientVersion clientVersion; @@ -128,7 +124,11 @@ } 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; try @@ -173,24 +173,6 @@ 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; return clientVersion; diff --git a/Bloxstrap/RobloxFastFlags.cs b/Bloxstrap/RobloxFastFlags.cs index 6121861..04e45da 100644 --- a/Bloxstrap/RobloxFastFlags.cs +++ b/Bloxstrap/RobloxFastFlags.cs @@ -114,27 +114,23 @@ namespace Bloxstrap 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) + public static RobloxFastFlags GetSettings(string applicationName, string channelName = RobloxDeployment.DefaultChannel, bool shouldCache = true) { - string channelNameLower; - if (!string.IsNullOrEmpty(channelName)) - channelNameLower = channelName.ToLowerInvariant(); - else - channelNameLower = App.Settings.Prop.Channel.ToLowerInvariant(); + channelName = channelName.ToLowerInvariant(); lock (_cache) { - if (_cache.ContainsKey(applicationName) && _cache[applicationName].ContainsKey(channelNameLower)) - return _cache[applicationName][channelNameLower]; + if (_cache.ContainsKey(applicationName) && _cache[applicationName].ContainsKey(channelName)) + return _cache[applicationName][channelName]; - var flags = new RobloxFastFlags(applicationName, channelNameLower); + var flags = new RobloxFastFlags(applicationName, channelName); if (shouldCache) { if (!_cache.ContainsKey(applicationName)) _cache[applicationName] = new(); - _cache[applicationName][channelNameLower] = flags; + _cache[applicationName][channelName] = flags; } return flags; diff --git a/Bloxstrap/UI/Frontend.cs b/Bloxstrap/UI/Frontend.cs index 509a323..af21245 100644 --- a/Bloxstrap/UI/Frontend.cs +++ b/Bloxstrap/UI/Frontend.cs @@ -14,10 +14,10 @@ namespace Bloxstrap.UI { App.Logger.WriteLine("Frontend::ShowMessageBox", message); - if (App.LaunchSettings.IsQuiet) + if (App.LaunchSettings.QuietFlag.Active) return defaultResult; - if (!App.LaunchSettings.IsRobloxLaunch) + if (App.LaunchSettings.RobloxLaunchMode != LaunchMode.None) return ShowFluentMessageBox(message, icon, buttons); switch (App.Settings.Prop.BootstrapperStyle)