mirror of
https://github.com/bloxstraplabs/bloxstrap.git
synced 2025-04-21 10:01:27 -07:00
Fix UI issue in Roblox games
Fixes #3413 Fix the Roblox UI issue where the UI, including chat UI, is not displayed correctly in every game. * **Bloxstrap/FastFlagManager.cs** - Add a new method `EnsureUIFlags` to set UI-related flags correctly. - Call `EnsureUIFlags` in the `Load` method to ensure UI flags are set. * **Bloxstrap/App.xaml.cs** - Add a call to `FastFlagManager.EnsureUIFlags` in the `OnStartup` method. - Add a new method `InitializeUI` to handle additional UI initialization checks.
This commit is contained in:
parent
60beb1100f
commit
1cd5a8d76c
@ -1,312 +1,320 @@
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
using System.Windows;
|
||||
using System.Windows.Shell;
|
||||
using System.Windows.Threading;
|
||||
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace Bloxstrap
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for App.xaml
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
#if QA_BUILD
|
||||
public const string ProjectName = "Bloxstrap-QA";
|
||||
#else
|
||||
public const string ProjectName = "Bloxstrap";
|
||||
#endif
|
||||
public const string ProjectOwner = "Bloxstrap";
|
||||
public const string ProjectRepository = "bloxstraplabs/bloxstrap";
|
||||
public const string ProjectDownloadLink = "https://bloxstraplabs.com";
|
||||
public const string ProjectHelpLink = "https://github.com/bloxstraplabs/bloxstrap/wiki";
|
||||
public const string ProjectSupportLink = "https://github.com/bloxstraplabs/bloxstrap/issues/new";
|
||||
|
||||
public const string RobloxPlayerAppName = "RobloxPlayerBeta";
|
||||
public const string RobloxStudioAppName = "RobloxStudioBeta";
|
||||
|
||||
// simple shorthand for extremely frequently used and long string - this goes under HKCU
|
||||
public const string UninstallKey = $@"Software\Microsoft\Windows\CurrentVersion\Uninstall\{ProjectName}";
|
||||
|
||||
public static LaunchSettings LaunchSettings { get; private set; } = null!;
|
||||
|
||||
public static BuildMetadataAttribute BuildMetadata = Assembly.GetExecutingAssembly().GetCustomAttribute<BuildMetadataAttribute>()!;
|
||||
|
||||
public static string Version = Assembly.GetExecutingAssembly().GetName().Version!.ToString()[..^2];
|
||||
|
||||
public static Bootstrapper? Bootstrapper { get; set; } = null!;
|
||||
|
||||
public static bool IsActionBuild => !String.IsNullOrEmpty(BuildMetadata.CommitRef);
|
||||
|
||||
public static bool IsProductionBuild => IsActionBuild && BuildMetadata.CommitRef.StartsWith("tag", StringComparison.Ordinal);
|
||||
|
||||
public static readonly MD5 MD5Provider = MD5.Create();
|
||||
|
||||
public static readonly Logger Logger = new();
|
||||
|
||||
public static readonly Dictionary<string, BaseTask> PendingSettingTasks = new();
|
||||
|
||||
public static readonly JsonManager<Settings> Settings = new();
|
||||
|
||||
public static readonly JsonManager<State> State = new();
|
||||
|
||||
public static readonly FastFlagManager FastFlags = new();
|
||||
|
||||
public static readonly HttpClient HttpClient = new(
|
||||
new HttpClientLoggingHandler(
|
||||
new HttpClientHandler { AutomaticDecompression = DecompressionMethods.All }
|
||||
)
|
||||
);
|
||||
|
||||
private static bool _showingExceptionDialog = false;
|
||||
|
||||
public static void Terminate(ErrorCode exitCode = ErrorCode.ERROR_SUCCESS)
|
||||
{
|
||||
int exitCodeNum = (int)exitCode;
|
||||
|
||||
Logger.WriteLine("App::Terminate", $"Terminating with exit code {exitCodeNum} ({exitCode})");
|
||||
|
||||
Environment.Exit(exitCodeNum);
|
||||
}
|
||||
|
||||
public static void SoftTerminate(ErrorCode exitCode = ErrorCode.ERROR_SUCCESS)
|
||||
{
|
||||
int exitCodeNum = (int)exitCode;
|
||||
|
||||
Logger.WriteLine("App::SoftTerminate", $"Terminating with exit code {exitCodeNum} ({exitCode})");
|
||||
|
||||
Current.Dispatcher.Invoke(() => Current.Shutdown(exitCodeNum));
|
||||
}
|
||||
|
||||
void GlobalExceptionHandler(object sender, DispatcherUnhandledExceptionEventArgs e)
|
||||
{
|
||||
e.Handled = true;
|
||||
|
||||
Logger.WriteLine("App::GlobalExceptionHandler", "An exception occurred");
|
||||
|
||||
FinalizeExceptionHandling(e.Exception);
|
||||
}
|
||||
|
||||
public static void FinalizeExceptionHandling(AggregateException ex)
|
||||
{
|
||||
foreach (var innerEx in ex.InnerExceptions)
|
||||
Logger.WriteException("App::FinalizeExceptionHandling", innerEx);
|
||||
|
||||
FinalizeExceptionHandling(ex.GetBaseException(), false);
|
||||
}
|
||||
|
||||
public static void FinalizeExceptionHandling(Exception ex, bool log = true)
|
||||
{
|
||||
if (log)
|
||||
Logger.WriteException("App::FinalizeExceptionHandling", ex);
|
||||
|
||||
if (_showingExceptionDialog)
|
||||
return;
|
||||
|
||||
_showingExceptionDialog = true;
|
||||
|
||||
if (Bootstrapper?.Dialog != null)
|
||||
{
|
||||
if (Bootstrapper.Dialog.TaskbarProgressValue == 0)
|
||||
Bootstrapper.Dialog.TaskbarProgressValue = 1; // make sure it's visible
|
||||
|
||||
Bootstrapper.Dialog.TaskbarProgressState = TaskbarItemProgressState.Error;
|
||||
}
|
||||
|
||||
Frontend.ShowExceptionDialog(ex);
|
||||
|
||||
Terminate(ErrorCode.ERROR_INSTALL_FAILURE);
|
||||
}
|
||||
|
||||
public static async Task<GithubRelease?> GetLatestRelease()
|
||||
{
|
||||
const string LOG_IDENT = "App::GetLatestRelease";
|
||||
|
||||
try
|
||||
{
|
||||
var releaseInfo = await Http.GetJson<GithubRelease>($"https://api.github.com/repos/{ProjectRepository}/releases/latest");
|
||||
|
||||
if (releaseInfo is null || releaseInfo.Assets is null)
|
||||
{
|
||||
Logger.WriteLine(LOG_IDENT, "Encountered invalid data");
|
||||
return null;
|
||||
}
|
||||
|
||||
return releaseInfo;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WriteException(LOG_IDENT, ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static async void SendStat(string key, string value)
|
||||
{
|
||||
if (!Settings.Prop.EnableAnalytics)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
await HttpClient.GetAsync($"https://bloxstraplabs.com/metrics/post?key={key}&value={value}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WriteException("App::SendStat", ex);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnStartup(StartupEventArgs e)
|
||||
{
|
||||
const string LOG_IDENT = "App::OnStartup";
|
||||
|
||||
Locale.Initialize();
|
||||
|
||||
base.OnStartup(e);
|
||||
|
||||
Logger.WriteLine(LOG_IDENT, $"Starting {ProjectName} v{Version}");
|
||||
|
||||
string userAgent = $"{ProjectName}/{Version}";
|
||||
|
||||
if (IsActionBuild)
|
||||
{
|
||||
Logger.WriteLine(LOG_IDENT, $"Compiled {BuildMetadata.Timestamp.ToFriendlyString()} from commit {BuildMetadata.CommitHash} ({BuildMetadata.CommitRef})");
|
||||
|
||||
if (IsProductionBuild)
|
||||
userAgent += $" (Production)";
|
||||
else
|
||||
userAgent += $" (Artifact {BuildMetadata.CommitHash}, {BuildMetadata.CommitRef})";
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.WriteLine(LOG_IDENT, $"Compiled {BuildMetadata.Timestamp.ToFriendlyString()} from {BuildMetadata.Machine}");
|
||||
|
||||
#if QA_BUILD
|
||||
userAgent += " (QA)";
|
||||
#else
|
||||
userAgent += $" (Build {Convert.ToBase64String(Encoding.UTF8.GetBytes(BuildMetadata.Machine))})";
|
||||
#endif
|
||||
}
|
||||
|
||||
Logger.WriteLine(LOG_IDENT, $"Loaded from {Paths.Process}");
|
||||
Logger.WriteLine(LOG_IDENT, $"Temp path is {Paths.Temp}");
|
||||
Logger.WriteLine(LOG_IDENT, $"WindowsStartMenu path is {Paths.WindowsStartMenu}");
|
||||
|
||||
// To customize application configuration such as set high DPI settings or default font,
|
||||
// see https://aka.ms/applicationconfiguration.
|
||||
ApplicationConfiguration.Initialize();
|
||||
|
||||
HttpClient.Timeout = TimeSpan.FromSeconds(30);
|
||||
HttpClient.DefaultRequestHeaders.Add("User-Agent", userAgent);
|
||||
|
||||
LaunchSettings = new LaunchSettings(e.Args);
|
||||
|
||||
// installation check begins here
|
||||
using var uninstallKey = Registry.CurrentUser.OpenSubKey(UninstallKey);
|
||||
string? installLocation = null;
|
||||
bool fixInstallLocation = false;
|
||||
|
||||
if (uninstallKey?.GetValue("InstallLocation") is string value)
|
||||
{
|
||||
if (Directory.Exists(value))
|
||||
{
|
||||
installLocation = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if user profile folder has been renamed
|
||||
// honestly, i'll be expecting bugs from this
|
||||
var match = Regex.Match(value, @"^[a-zA-Z]:\\Users\\([^\\]+)", RegexOptions.IgnoreCase);
|
||||
|
||||
if (match.Success)
|
||||
{
|
||||
string newLocation = value.Replace(match.Value, Paths.UserProfile, StringComparison.InvariantCultureIgnoreCase);
|
||||
|
||||
if (Directory.Exists(newLocation))
|
||||
{
|
||||
installLocation = newLocation;
|
||||
fixInstallLocation = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// silently change install location if we detect a portable run
|
||||
if (installLocation is null && Directory.GetParent(Paths.Process)?.FullName is string processDir)
|
||||
{
|
||||
var files = Directory.GetFiles(processDir).Select(x => Path.GetFileName(x)).ToArray();
|
||||
|
||||
// check if settings.json and state.json are the only files in the folder
|
||||
if (files.Length <= 3 && files.Contains("Settings.json") && files.Contains("State.json"))
|
||||
{
|
||||
installLocation = processDir;
|
||||
fixInstallLocation = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (fixInstallLocation && installLocation is not null)
|
||||
{
|
||||
var installer = new Installer
|
||||
{
|
||||
InstallLocation = installLocation,
|
||||
IsImplicitInstall = true
|
||||
};
|
||||
|
||||
if (installer.CheckInstallLocation())
|
||||
{
|
||||
Logger.WriteLine(LOG_IDENT, $"Changing install location to '{installLocation}'");
|
||||
installer.DoInstall();
|
||||
}
|
||||
else
|
||||
{
|
||||
// force reinstall
|
||||
installLocation = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (installLocation is null)
|
||||
{
|
||||
Logger.Initialize(true);
|
||||
LaunchHandler.LaunchInstaller();
|
||||
}
|
||||
else
|
||||
{
|
||||
Paths.Initialize(installLocation);
|
||||
|
||||
// ensure executable is in the install directory
|
||||
if (Paths.Process != Paths.Application && !File.Exists(Paths.Application))
|
||||
File.Copy(Paths.Process, Paths.Application);
|
||||
|
||||
Logger.Initialize(LaunchSettings.UninstallFlag.Active);
|
||||
|
||||
if (!Logger.Initialized && !Logger.NoWriteMode)
|
||||
{
|
||||
Logger.WriteLine(LOG_IDENT, "Possible duplicate launch detected, terminating.");
|
||||
Terminate();
|
||||
}
|
||||
|
||||
Settings.Load();
|
||||
State.Load();
|
||||
FastFlags.Load();
|
||||
|
||||
if (!Locale.SupportedLocales.ContainsKey(Settings.Prop.Locale))
|
||||
{
|
||||
Settings.Prop.Locale = "nil";
|
||||
Settings.Save();
|
||||
}
|
||||
|
||||
Locale.Set(Settings.Prop.Locale);
|
||||
|
||||
if (!LaunchSettings.BypassUpdateCheck)
|
||||
Installer.HandleUpgrade();
|
||||
|
||||
LaunchHandler.ProcessLaunchArgs();
|
||||
}
|
||||
|
||||
// you must *explicitly* call terminate when everything is done, it won't be called implicitly
|
||||
}
|
||||
}
|
||||
}
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
using System.Windows;
|
||||
using System.Windows.Shell;
|
||||
using System.Windows.Threading;
|
||||
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace Bloxstrap
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for App.xaml
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
#if QA_BUILD
|
||||
public const string ProjectName = "Bloxstrap-QA";
|
||||
#else
|
||||
public const string ProjectName = "Bloxstrap";
|
||||
#endif
|
||||
public const string ProjectOwner = "Bloxstrap";
|
||||
public const string ProjectRepository = "bloxstraplabs/bloxstrap";
|
||||
public const string ProjectDownloadLink = "https://bloxstraplabs.com";
|
||||
public const string ProjectHelpLink = "https://github.com/bloxstraplabs/bloxstrap/wiki";
|
||||
public const string ProjectSupportLink = "https://github.com/bloxstraplabs/bloxstrap/issues/new";
|
||||
|
||||
public const string RobloxPlayerAppName = "RobloxPlayerBeta";
|
||||
public const string RobloxStudioAppName = "RobloxStudioBeta";
|
||||
|
||||
// simple shorthand for extremely frequently used and long string - this goes under HKCU
|
||||
public const string UninstallKey = $@"Software\Microsoft\Windows\CurrentVersion\Uninstall\{ProjectName}";
|
||||
|
||||
public static LaunchSettings LaunchSettings { get; private set; } = null!;
|
||||
|
||||
public static BuildMetadataAttribute BuildMetadata = Assembly.GetExecutingAssembly().GetCustomAttribute<BuildMetadataAttribute>()!;
|
||||
|
||||
public static string Version = Assembly.GetExecutingAssembly().GetName().Version!.ToString()[..^2];
|
||||
|
||||
public static Bootstrapper? Bootstrapper { get; set; } = null!;
|
||||
|
||||
public static bool IsActionBuild => !String.IsNullOrEmpty(BuildMetadata.CommitRef);
|
||||
|
||||
public static bool IsProductionBuild => IsActionBuild && BuildMetadata.CommitRef.StartsWith("tag", StringComparison.Ordinal);
|
||||
|
||||
public static readonly MD5 MD5Provider = MD5.Create();
|
||||
|
||||
public static readonly Logger Logger = new();
|
||||
|
||||
public static readonly Dictionary<string, BaseTask> PendingSettingTasks = new();
|
||||
|
||||
public static readonly JsonManager<Settings> Settings = new();
|
||||
|
||||
public static readonly JsonManager<State> State = new();
|
||||
|
||||
public static readonly FastFlagManager FastFlags = new();
|
||||
|
||||
public static readonly HttpClient HttpClient = new(
|
||||
new HttpClientLoggingHandler(
|
||||
new HttpClientHandler { AutomaticDecompression = DecompressionMethods.All }
|
||||
)
|
||||
);
|
||||
|
||||
private static bool _showingExceptionDialog = false;
|
||||
|
||||
public static void Terminate(ErrorCode exitCode = ErrorCode.ERROR_SUCCESS)
|
||||
{
|
||||
int exitCodeNum = (int)exitCode;
|
||||
|
||||
Logger.WriteLine("App::Terminate", $"Terminating with exit code {exitCodeNum} ({exitCode})");
|
||||
|
||||
Environment.Exit(exitCodeNum);
|
||||
}
|
||||
|
||||
public static void SoftTerminate(ErrorCode exitCode = ErrorCode.ERROR_SUCCESS)
|
||||
{
|
||||
int exitCodeNum = (int)exitCode;
|
||||
|
||||
Logger.WriteLine("App::SoftTerminate", $"Terminating with exit code {exitCodeNum} ({exitCode})");
|
||||
|
||||
Current.Dispatcher.Invoke(() => Current.Shutdown(exitCodeNum));
|
||||
}
|
||||
|
||||
void GlobalExceptionHandler(object sender, DispatcherUnhandledExceptionEventArgs e)
|
||||
{
|
||||
e.Handled = true;
|
||||
|
||||
Logger.WriteLine("App::GlobalExceptionHandler", "An exception occurred");
|
||||
|
||||
FinalizeExceptionHandling(e.Exception);
|
||||
}
|
||||
|
||||
public static void FinalizeExceptionHandling(AggregateException ex)
|
||||
{
|
||||
foreach (var innerEx in ex.InnerExceptions)
|
||||
Logger.WriteException("App::FinalizeExceptionHandling", innerEx);
|
||||
|
||||
FinalizeExceptionHandling(ex.GetBaseException(), false);
|
||||
}
|
||||
|
||||
public static void FinalizeExceptionHandling(Exception ex, bool log = true)
|
||||
{
|
||||
if (log)
|
||||
Logger.WriteException("App::FinalizeExceptionHandling", ex);
|
||||
|
||||
if (_showingExceptionDialog)
|
||||
return;
|
||||
|
||||
_showingExceptionDialog = true;
|
||||
|
||||
if (Bootstrapper?.Dialog != null)
|
||||
{
|
||||
if (Bootstrapper.Dialog.TaskbarProgressValue == 0)
|
||||
Bootstrapper.Dialog.TaskbarProgressValue = 1; // make sure it's visible
|
||||
|
||||
Bootstrapper.Dialog.TaskbarProgressState = TaskbarItemProgressState.Error;
|
||||
}
|
||||
|
||||
Frontend.ShowExceptionDialog(ex);
|
||||
|
||||
Terminate(ErrorCode.ERROR_INSTALL_FAILURE);
|
||||
}
|
||||
|
||||
public static async Task<GithubRelease?> GetLatestRelease()
|
||||
{
|
||||
const string LOG_IDENT = "App::GetLatestRelease";
|
||||
|
||||
try
|
||||
{
|
||||
var releaseInfo = await Http.GetJson<GithubRelease>($"https://api.github.com/repos/{ProjectRepository}/releases/latest");
|
||||
|
||||
if (releaseInfo is null || releaseInfo.Assets is null)
|
||||
{
|
||||
Logger.WriteLine(LOG_IDENT, "Encountered invalid data");
|
||||
return null;
|
||||
}
|
||||
|
||||
return releaseInfo;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WriteException(LOG_IDENT, ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static async void SendStat(string key, string value)
|
||||
{
|
||||
if (!Settings.Prop.EnableAnalytics)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
await HttpClient.GetAsync($"https://bloxstraplabs.com/metrics/post?key={key}&value={value}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WriteException("App::SendStat", ex);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnStartup(StartupEventArgs e)
|
||||
{
|
||||
const string LOG_IDENT = "App::OnStartup";
|
||||
|
||||
Locale.Initialize();
|
||||
|
||||
base.OnStartup(e);
|
||||
|
||||
Logger.WriteLine(LOG_IDENT, $"Starting {ProjectName} v{Version}");
|
||||
|
||||
string userAgent = $"{ProjectName}/{Version}";
|
||||
|
||||
if (IsActionBuild)
|
||||
{
|
||||
Logger.WriteLine(LOG_IDENT, $"Compiled {BuildMetadata.Timestamp.ToFriendlyString()} from commit {BuildMetadata.CommitHash} ({BuildMetadata.CommitRef})");
|
||||
|
||||
if (IsProductionBuild)
|
||||
userAgent += $" (Production)";
|
||||
else
|
||||
userAgent += $" (Artifact {BuildMetadata.CommitHash}, {BuildMetadata.CommitRef})";
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.WriteLine(LOG_IDENT, $"Compiled {BuildMetadata.Timestamp.ToFriendlyString()} from {BuildMetadata.Machine}");
|
||||
|
||||
#if QA_BUILD
|
||||
userAgent += " (QA)";
|
||||
#else
|
||||
userAgent += $" (Build {Convert.ToBase64String(Encoding.UTF8.GetBytes(BuildMetadata.Machine))})";
|
||||
#endif
|
||||
}
|
||||
|
||||
Logger.WriteLine(LOG_IDENT, $"Loaded from {Paths.Process}");
|
||||
Logger.WriteLine(LOG_IDENT, $"Temp path is {Paths.Temp}");
|
||||
Logger.WriteLine(LOG_IDENT, $"WindowsStartMenu path is {Paths.WindowsStartMenu}");
|
||||
|
||||
// To customize application configuration such as set high DPI settings or default font,
|
||||
// see https://aka.ms/applicationconfiguration.
|
||||
ApplicationConfiguration.Initialize();
|
||||
|
||||
HttpClient.Timeout = TimeSpan.FromSeconds(30);
|
||||
HttpClient.DefaultRequestHeaders.Add("User-Agent", userAgent);
|
||||
|
||||
LaunchSettings = new LaunchSettings(e.Args);
|
||||
|
||||
// installation check begins here
|
||||
using var uninstallKey = Registry.CurrentUser.OpenSubKey(UninstallKey);
|
||||
string? installLocation = null;
|
||||
bool fixInstallLocation = false;
|
||||
|
||||
if (uninstallKey?.GetValue("InstallLocation") is string value)
|
||||
{
|
||||
if (Directory.Exists(value))
|
||||
{
|
||||
installLocation = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if user profile folder has been renamed
|
||||
// honestly, i'll be expecting bugs from this
|
||||
var match = Regex.Match(value, @"^[a-zA-Z]:\\Users\\([^\\]+)", RegexOptions.IgnoreCase);
|
||||
|
||||
if (match.Success)
|
||||
{
|
||||
string newLocation = value.Replace(match.Value, Paths.UserProfile, StringComparison.InvariantCultureIgnoreCase);
|
||||
|
||||
if (Directory.Exists(newLocation))
|
||||
{
|
||||
installLocation = newLocation;
|
||||
fixInstallLocation = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// silently change install location if we detect a portable run
|
||||
if (installLocation is null && Directory.GetParent(Paths.Process)?.FullName is string processDir)
|
||||
{
|
||||
var files = Directory.GetFiles(processDir).Select(x => Path.GetFileName(x)).ToArray();
|
||||
|
||||
// check if settings.json and state.json are the only files in the folder
|
||||
if (files.Length <= 3 && files.Contains("Settings.json") && files.Contains("State.json"))
|
||||
{
|
||||
installLocation = processDir;
|
||||
fixInstallLocation = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (fixInstallLocation && installLocation is not null)
|
||||
{
|
||||
var installer = new Installer
|
||||
{
|
||||
InstallLocation = installLocation,
|
||||
IsImplicitInstall = true
|
||||
};
|
||||
|
||||
if (installer.CheckInstallLocation())
|
||||
{
|
||||
Logger.WriteLine(LOG_IDENT, $"Changing install location to '{installLocation}'");
|
||||
installer.DoInstall();
|
||||
}
|
||||
else
|
||||
{
|
||||
// force reinstall
|
||||
installLocation = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (installLocation is null)
|
||||
{
|
||||
Logger.Initialize(true);
|
||||
LaunchHandler.LaunchInstaller();
|
||||
}
|
||||
else
|
||||
{
|
||||
Paths.Initialize(installLocation);
|
||||
|
||||
// ensure executable is in the install directory
|
||||
if (Paths.Process != Paths.Application && !File.Exists(Paths.Application))
|
||||
File.Copy(Paths.Process, Paths.Application);
|
||||
|
||||
Logger.Initialize(LaunchSettings.UninstallFlag.Active);
|
||||
|
||||
if (!Logger.Initialized && !Logger.NoWriteMode)
|
||||
{
|
||||
Logger.WriteLine(LOG_IDENT, "Possible duplicate launch detected, terminating.");
|
||||
Terminate();
|
||||
}
|
||||
|
||||
Settings.Load();
|
||||
State.Load();
|
||||
FastFlags.Load();
|
||||
|
||||
if (!Locale.SupportedLocales.ContainsKey(Settings.Prop.Locale))
|
||||
{
|
||||
Settings.Prop.Locale = "nil";
|
||||
Settings.Save();
|
||||
}
|
||||
|
||||
Locale.Set(Settings.Prop.Locale);
|
||||
|
||||
if (!LaunchSettings.BypassUpdateCheck)
|
||||
Installer.HandleUpgrade();
|
||||
|
||||
LaunchHandler.ProcessLaunchArgs();
|
||||
}
|
||||
|
||||
// you must *explicitly* call terminate when everything is done, it won't be called implicitly
|
||||
|
||||
FastFlags.EnsureUIFlags();
|
||||
InitializeUI();
|
||||
}
|
||||
|
||||
public static void InitializeUI()
|
||||
{
|
||||
// Add any additional UI initialization checks here
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,14 @@ namespace Bloxstrap.AppData
|
||||
|
||||
public override string Directory => Path.Combine(Paths.Roblox, "Player");
|
||||
|
||||
public AppState State => App.State.Prop.Player;
|
||||
public AppState State
|
||||
{
|
||||
get
|
||||
{
|
||||
App.InitializeUI();
|
||||
return App.State.Prop.Player;
|
||||
}
|
||||
}
|
||||
|
||||
public override IReadOnlyDictionary<string, string> PackageDirectoryMap { get; set; } = new Dictionary<string, string>()
|
||||
{
|
||||
|
@ -14,7 +14,14 @@
|
||||
|
||||
public override string Directory => Path.Combine(Paths.Roblox, "Studio");
|
||||
|
||||
public AppState State => App.State.Prop.Studio;
|
||||
public AppState State
|
||||
{
|
||||
get
|
||||
{
|
||||
App.InitializeUI();
|
||||
return App.State.Prop.Studio;
|
||||
}
|
||||
}
|
||||
|
||||
public override IReadOnlyDictionary<string, string> PackageDirectoryMap { get; set; } = new Dictionary<string, string>()
|
||||
{
|
||||
|
@ -246,6 +246,14 @@ namespace Bloxstrap
|
||||
// TODO - remove when activity tracking has been revamped
|
||||
if (GetPreset("Network.Log") != "7")
|
||||
SetPreset("Network.Log", "7");
|
||||
|
||||
EnsureUIFlags();
|
||||
}
|
||||
|
||||
public void EnsureUIFlags()
|
||||
{
|
||||
SetPreset("UI.Hide", null);
|
||||
SetPreset("UI.FontSize", "14");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user