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)