mirror of
https://github.com/bloxstraplabs/bloxstrap.git
synced 2025-06-23 23:00:23 -07:00
Compare commits
6 Commits
a5d4b1e85f
...
e7fc640664
Author | SHA1 | Date | |
---|---|---|---|
|
e7fc640664 | ||
|
33243bfd0a | ||
|
2acd0162fb | ||
|
f23d2bce88 | ||
|
e983814176 | ||
|
4795bf8b66 |
@ -58,6 +58,7 @@ namespace Bloxstrap
|
||||
private double _taskbarProgressIncrement;
|
||||
private double _taskbarProgressMaximum;
|
||||
private long _totalDownloadedBytes = 0;
|
||||
private bool _packageExtractionSuccess = true;
|
||||
|
||||
private bool _mustUpgrade => String.IsNullOrEmpty(AppData.State.VersionGuid) || !File.Exists(AppData.ExecutablePath);
|
||||
private bool _noConnection = false;
|
||||
@ -78,7 +79,15 @@ namespace Bloxstrap
|
||||
|
||||
// https://github.com/icsharpcode/SharpZipLib/blob/master/src/ICSharpCode.SharpZipLib/Zip/FastZip.cs/#L669-L680
|
||||
// exceptions don't get thrown if we define events without actually binding to the failure events. probably a bug. ¯\_(ツ)_/¯
|
||||
_fastZipEvents.FileFailure += (_, e) => throw e.Exception;
|
||||
_fastZipEvents.FileFailure += (_, e) =>
|
||||
{
|
||||
// only give a pass to font files (no idea whats wrong with them)
|
||||
if (!e.Name.EndsWith(".ttf"))
|
||||
throw e.Exception;
|
||||
|
||||
App.Logger.WriteLine("FastZipEvents::OnFileFailure", $"Failed to extract {e.Name}");
|
||||
_packageExtractionSuccess = false;
|
||||
};
|
||||
_fastZipEvents.DirectoryFailure += (_, e) => throw e.Exception;
|
||||
_fastZipEvents.ProcessFile += (_, e) => e.ContinueRunning = !_cancelTokenSource.IsCancellationRequested;
|
||||
|
||||
@ -223,6 +232,8 @@ namespace Bloxstrap
|
||||
}
|
||||
}
|
||||
|
||||
bool allModificationsApplied = true;
|
||||
|
||||
if (!_noConnection)
|
||||
{
|
||||
if (AppData.State.VersionGuid != _latestVersionGuid || _mustUpgrade)
|
||||
@ -233,7 +244,7 @@ namespace Bloxstrap
|
||||
|
||||
// we require deployment details for applying modifications for a worst case scenario,
|
||||
// where we'd need to restore files from a package that isn't present on disk and needs to be redownloaded
|
||||
await ApplyModifications();
|
||||
allModificationsApplied = await ApplyModifications();
|
||||
}
|
||||
|
||||
// check registry entries for every launch, just in case the stock bootstrapper changes it back
|
||||
@ -247,7 +258,15 @@ namespace Bloxstrap
|
||||
await mutex.ReleaseAsync();
|
||||
|
||||
if (!App.LaunchSettings.NoLaunchFlag.Active && !_cancelTokenSource.IsCancellationRequested)
|
||||
{
|
||||
// show some balloon tips
|
||||
if (!_packageExtractionSuccess)
|
||||
Frontend.ShowBalloonTip(Strings.Bootstrapper_ExtractionFailed_Title, Strings.Bootstrapper_ExtractionFailed_Message, ToolTipIcon.Warning);
|
||||
else if (!allModificationsApplied)
|
||||
Frontend.ShowBalloonTip(Strings.Bootstrapper_ModificationsFailed_Title, Strings.Bootstrapper_ModificationsFailed_Message, ToolTipIcon.Warning);
|
||||
|
||||
StartRoblox();
|
||||
}
|
||||
|
||||
await mutex.ReleaseAsync();
|
||||
|
||||
@ -643,7 +662,28 @@ namespace Bloxstrap
|
||||
#endregion
|
||||
|
||||
#region Roblox Install
|
||||
private void CleanupVersionsFolder()
|
||||
private static bool TryDeleteRobloxInDirectory(string dir)
|
||||
{
|
||||
string clientPath = Path.Combine(dir, "RobloxPlayerBeta.exe");
|
||||
if (!File.Exists(dir))
|
||||
{
|
||||
clientPath = Path.Combine(dir, "RobloxStudioBeta.exe");
|
||||
if (!File.Exists(dir))
|
||||
return true; // ok???
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
File.Delete(clientPath);
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void CleanupVersionsFolder()
|
||||
{
|
||||
const string LOG_IDENT = "Bootstrapper::CleanupVersionsFolder";
|
||||
|
||||
@ -653,6 +693,13 @@ namespace Bloxstrap
|
||||
|
||||
if (dirName != App.State.Prop.Player.VersionGuid && dirName != App.State.Prop.Studio.VersionGuid)
|
||||
{
|
||||
Filesystem.AssertReadOnlyDirectory(dir);
|
||||
|
||||
// check if it's still being used first
|
||||
// we dont want to accidentally delete the files of a running roblox instance
|
||||
if (!TryDeleteRobloxInDirectory(dir))
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
Directory.Delete(dir, true);
|
||||
@ -921,10 +968,12 @@ namespace Bloxstrap
|
||||
_isInstalling = false;
|
||||
}
|
||||
|
||||
private async Task ApplyModifications()
|
||||
private async Task<bool> ApplyModifications()
|
||||
{
|
||||
const string LOG_IDENT = "Bootstrapper::ApplyModifications";
|
||||
|
||||
bool success = true;
|
||||
|
||||
SetStatus(Strings.Bootstrapper_Status_ApplyingModifications);
|
||||
|
||||
// handle file mods
|
||||
@ -1000,7 +1049,7 @@ namespace Bloxstrap
|
||||
foreach (string file in Directory.GetFiles(Paths.Modifications, "*.*", SearchOption.AllDirectories))
|
||||
{
|
||||
if (_cancelTokenSource.IsCancellationRequested)
|
||||
return;
|
||||
return true;
|
||||
|
||||
// get relative directory path
|
||||
string relativeFile = file.Substring(Paths.Modifications.Length + 1);
|
||||
@ -1032,10 +1081,18 @@ namespace Bloxstrap
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(fileVersionFolder)!);
|
||||
|
||||
Filesystem.AssertReadOnly(fileVersionFolder);
|
||||
File.Copy(fileModFolder, fileVersionFolder, true);
|
||||
Filesystem.AssertReadOnly(fileVersionFolder);
|
||||
|
||||
App.Logger.WriteLine(LOG_IDENT, $"{relativeFile} has been copied to the version folder");
|
||||
try
|
||||
{
|
||||
File.Copy(fileModFolder, fileVersionFolder, true);
|
||||
Filesystem.AssertReadOnly(fileVersionFolder);
|
||||
App.Logger.WriteLine(LOG_IDENT, $"{relativeFile} has been copied to the version folder");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
App.Logger.WriteLine(LOG_IDENT, $"Failed to apply modification ({relativeFile})");
|
||||
App.Logger.WriteException(LOG_IDENT, ex);
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
// the manifest is primarily here to keep track of what files have been
|
||||
@ -1082,7 +1139,7 @@ namespace Bloxstrap
|
||||
if (package is not null)
|
||||
{
|
||||
if (_cancelTokenSource.IsCancellationRequested)
|
||||
return;
|
||||
return true;
|
||||
|
||||
await DownloadPackage(package);
|
||||
ExtractPackage(package, entry.Value);
|
||||
@ -1093,6 +1150,11 @@ namespace Bloxstrap
|
||||
App.State.Save();
|
||||
|
||||
App.Logger.WriteLine(LOG_IDENT, $"Finished checking file mods");
|
||||
|
||||
if (!success)
|
||||
App.Logger.WriteLine(LOG_IDENT, "Failed to apply all modifications");
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
private async Task DownloadPackage(Package package)
|
||||
|
@ -1,4 +1,4 @@
|
||||
using Microsoft.Win32;
|
||||
using Windows.UI.ViewManagement;
|
||||
|
||||
namespace Bloxstrap.Extensions
|
||||
{
|
||||
@ -9,9 +9,9 @@ namespace Bloxstrap.Extensions
|
||||
if (dialogTheme != Theme.Default)
|
||||
return dialogTheme;
|
||||
|
||||
using var key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize");
|
||||
|
||||
if (key?.GetValue("AppsUseLightTheme") is int value && value == 0)
|
||||
var settings = new UISettings();
|
||||
var background = settings.GetColorValue(UIColorType.Background);
|
||||
if (((5 * background.G) + (2 * background.R) + background.B) < (8 * 128))
|
||||
return Theme.Dark;
|
||||
|
||||
return Theme.Light;
|
||||
|
36
Bloxstrap/Resources/Strings.Designer.cs
generated
36
Bloxstrap/Resources/Strings.Designer.cs
generated
@ -178,6 +178,24 @@ namespace Bloxstrap.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Some content may be missing. Force a Roblox reinstallation in settings to fix this..
|
||||
/// </summary>
|
||||
public static string Bootstrapper_ExtractionFailed_Message {
|
||||
get {
|
||||
return ResourceManager.GetString("Bootstrapper.ExtractionFailed.Message", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Failed to extract all files.
|
||||
/// </summary>
|
||||
public static string Bootstrapper_ExtractionFailed_Title {
|
||||
get {
|
||||
return ResourceManager.GetString("Bootstrapper.ExtractionFailed.Title", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Bloxstrap tried to upgrade Roblox but can't because Roblox's files are still in use.
|
||||
///
|
||||
@ -207,6 +225,24 @@ namespace Bloxstrap.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Not all modifications will be present in the current launch..
|
||||
/// </summary>
|
||||
public static string Bootstrapper_ModificationsFailed_Message {
|
||||
get {
|
||||
return ResourceManager.GetString("Bootstrapper.ModificationsFailed.Message", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Failed to apply all modifications.
|
||||
/// </summary>
|
||||
public static string Bootstrapper_ModificationsFailed_Title {
|
||||
get {
|
||||
return ResourceManager.GetString("Bootstrapper.ModificationsFailed.Title", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Bloxstrap does not have enough disk space to download and install Roblox. Please free up some disk space and try again..
|
||||
/// </summary>
|
||||
|
@ -1270,4 +1270,16 @@ Please close any applications that may be using Roblox's files, and relaunch.</v
|
||||
<data name="App.OSDeprecation.Win7_81" xml:space="preserve">
|
||||
<value>Roblox no longer supports Windows 7 or 8.1. To continue playing Roblox, please upgrade to Windows 10 or newer.</value>
|
||||
</data>
|
||||
<data name="Bootstrapper.ExtractionFailed.Title" xml:space="preserve">
|
||||
<value>Failed to extract all files</value>
|
||||
</data>
|
||||
<data name="Bootstrapper.ExtractionFailed.Message" xml:space="preserve">
|
||||
<value>Some content may be missing. Force a Roblox reinstallation in settings to fix this.</value>
|
||||
</data>
|
||||
<data name="Bootstrapper.ModificationsFailed.Title" xml:space="preserve">
|
||||
<value>Failed to apply all modifications</value>
|
||||
</data>
|
||||
<data name="Bootstrapper.ModificationsFailed.Message" xml:space="preserve">
|
||||
<value>Not all modifications will be present in the current launch.</value>
|
||||
</data>
|
||||
</root>
|
@ -4,16 +4,20 @@ using Wpf.Ui.Appearance;
|
||||
using Wpf.Ui.Controls;
|
||||
using Wpf.Ui.Mvvm.Contracts;
|
||||
using Wpf.Ui.Mvvm.Services;
|
||||
using Windows.UI.ViewManagement;
|
||||
|
||||
namespace Bloxstrap.UI.Elements.Base
|
||||
{
|
||||
public abstract class WpfUiWindow : UiWindow
|
||||
{
|
||||
private readonly IThemeService _themeService = new ThemeService();
|
||||
private UISettings _settings;
|
||||
|
||||
public WpfUiWindow()
|
||||
{
|
||||
ApplyTheme();
|
||||
_settings = new UISettings();
|
||||
_settings.ColorValuesChanged += ColorValuesChanged;
|
||||
}
|
||||
|
||||
public void ApplyTheme()
|
||||
@ -37,5 +41,13 @@ namespace Bloxstrap.UI.Elements.Base
|
||||
|
||||
base.OnSourceInitialized(e);
|
||||
}
|
||||
|
||||
private async void ColorValuesChanged(UISettings sender, object args)
|
||||
{
|
||||
await Dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
ApplyTheme();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
Height="420"
|
||||
Background="{ui:ThemeResource ApplicationBackgroundBrush}"
|
||||
ExtendsContentIntoTitleBar="True"
|
||||
WindowBackdropType="Mica"
|
||||
WindowStartupLocation="CenterScreen">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
|
@ -18,6 +18,7 @@
|
||||
ResizeMode="NoResize"
|
||||
Background="{ui:ThemeResource ApplicationBackgroundBrush}"
|
||||
ExtendsContentIntoTitleBar="True"
|
||||
WindowBackdropType="Mica"
|
||||
WindowStartupLocation="CenterScreen">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
|
@ -16,6 +16,7 @@
|
||||
ResizeMode="NoResize"
|
||||
Background="{ui:ThemeResource ApplicationBackgroundBrush}"
|
||||
ExtendsContentIntoTitleBar="True"
|
||||
WindowBackdropType="Mica"
|
||||
WindowStartupLocation="CenterScreen">
|
||||
<ui:UiWindow.Resources>
|
||||
<converters:RangeConverter x:Key="ValidationConverter" From="0" />
|
||||
|
@ -15,6 +15,7 @@
|
||||
Title="{x:Static resources:Strings.Dialog_Connectivity_Title}"
|
||||
Background="{ui:ThemeResource ApplicationBackgroundBrush}"
|
||||
ExtendsContentIntoTitleBar="True"
|
||||
WindowBackdropType="Mica"
|
||||
WindowStartupLocation="CenterScreen">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
|
@ -16,6 +16,7 @@
|
||||
SizeToContent="Height"
|
||||
Background="{ui:ThemeResource ApplicationBackgroundBrush}"
|
||||
ExtendsContentIntoTitleBar="True"
|
||||
WindowBackdropType="Mica"
|
||||
WindowStartupLocation="CenterScreen">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
|
@ -18,6 +18,7 @@
|
||||
ResizeMode="NoResize"
|
||||
Background="{ui:ThemeResource ApplicationBackgroundBrush}"
|
||||
ExtendsContentIntoTitleBar="True"
|
||||
WindowBackdropType="Mica"
|
||||
WindowStartupLocation="CenterScreen">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
|
@ -16,6 +16,7 @@
|
||||
ResizeMode="NoResize"
|
||||
Background="{ui:ThemeResource ApplicationBackgroundBrush}"
|
||||
ExtendsContentIntoTitleBar="True"
|
||||
WindowBackdropType="Mica"
|
||||
WindowStartupLocation="CenterScreen">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
|
@ -17,6 +17,7 @@
|
||||
ResizeMode="NoResize"
|
||||
Background="{ui:ThemeResource ApplicationBackgroundBrush}"
|
||||
ExtendsContentIntoTitleBar="True"
|
||||
WindowBackdropType="Mica"
|
||||
WindowStartupLocation="CenterScreen">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
|
@ -19,6 +19,7 @@
|
||||
ResizeMode="NoResize"
|
||||
Background="{ui:ThemeResource ApplicationBackgroundBrush}"
|
||||
ExtendsContentIntoTitleBar="True"
|
||||
WindowBackdropType="Mica"
|
||||
WindowStartupLocation="CenterScreen">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
|
@ -83,5 +83,17 @@ namespace Bloxstrap.UI
|
||||
return messagebox.Result;
|
||||
}));
|
||||
}
|
||||
|
||||
public static void ShowBalloonTip(string title, string message, System.Windows.Forms.ToolTipIcon icon = System.Windows.Forms.ToolTipIcon.None, int timeout = 5)
|
||||
{
|
||||
var notifyIcon = new System.Windows.Forms.NotifyIcon
|
||||
{
|
||||
Icon = Properties.Resources.IconBloxstrap,
|
||||
Text = App.ProjectName,
|
||||
Visible = true
|
||||
};
|
||||
|
||||
notifyIcon.ShowBalloonTip(timeout, title, message, icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,5 +31,15 @@ namespace Bloxstrap.Utility
|
||||
fileInfo.IsReadOnly = false;
|
||||
App.Logger.WriteLine("Filesystem::AssertReadOnly", $"The following file was set as read-only: {filePath}");
|
||||
}
|
||||
|
||||
internal static void AssertReadOnlyDirectory(string directoryPath)
|
||||
{
|
||||
var directory = new DirectoryInfo(directoryPath) { Attributes = FileAttributes.Normal };
|
||||
|
||||
foreach (var info in directory.GetFileSystemInfos("*", SearchOption.AllDirectories))
|
||||
info.Attributes = FileAttributes.Normal;
|
||||
|
||||
App.Logger.WriteLine("Filesystem::AssertReadOnlyDirectory", $"The following directory was set as read-only: {directoryPath}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user