This commit is contained in:
pizzaboxer 2024-04-13 07:42:38 +01:00
commit bd2d8e58f6
No known key found for this signature in database
GPG Key ID: 59D4A1DBAD0F2BA8
34 changed files with 751 additions and 268 deletions

View File

@ -7,9 +7,10 @@ body:
value: |
### **Preliminary instructions**
- Before opening an issue, please [check the Wiki first](https://github.com/pizzaboxer/bloxstrap/wiki/) to see if your problem has been addressed there.
- **[Read this if Roblox is crashing or not launching](https://github.com/pizzaboxer/bloxstrap/wiki/Roblox-crashes-or-does-not-launch).** Only open an issue for it if this does not address your problem.
- If it isn't, please confirm which pages that you read that were relevant to your issue.
- If your problem is with Roblox itself (i.e. it crashes or doesn't launch), [check to see if it happens without Bloxstrap](https://github.com/pizzaboxer/bloxstrap/wiki/Roblox-crashes-or-does-not-launch).
- Please only open an issue if your problem happens only with Bloxstrap, and state clearly that this is the case, as anything else is out of my control.
- If you are getting a Bloxstrap Exception error, please attach a copy of the provided log file. There is a button on the dialog that locates it for you.
- If your problem is with Roblox itself, [check to see if it happens without Bloxstrap](https://github.com/pizzaboxer/bloxstrap/wiki/Roblox-crashes-or-does-not-launch). Please only open an issue if your problem only happens with Bloxstrap, as anything else is out of my control.
- If more clarification on the issue is needed, and you don't respond after a month, then your issue will be closed as stale.
- type: checkboxes
id: terms

View File

@ -14,7 +14,7 @@ jobs:
with:
submodules: true
- uses: actions/setup-dotnet@v3
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '6.0.x'
@ -28,7 +28,7 @@ jobs:
run: dotnet publish -p:PublishSingleFile=true -p:CommitHash=${{ github.sha }} -p:CommitRef=${{ github.ref_type }}/${{ github.ref_name }} -r win-x64 -c ${{ matrix.configuration }} --self-contained false .\Bloxstrap\Bloxstrap.csproj
- name: Upload Artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Bloxstrap (${{ matrix.configuration }})
path: |
@ -41,7 +41,7 @@ jobs:
steps:
- name: Download x64 release artifact
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: Bloxstrap (Release)
path: x64
@ -51,7 +51,7 @@ jobs:
mv x64/Bloxstrap.exe Bloxstrap-${{ github.ref_name }}.exe
- name: Release
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@v2
with:
draft: true
files: |

View File

@ -27,12 +27,7 @@ namespace Bloxstrap
public static bool IsSetupComplete { get; set; } = true;
public static bool IsFirstRun { get; set; } = true;
public static bool IsQuiet { get; private set; } = false;
public static bool IsUninstall { get; private set; } = false;
public static bool IsNoLaunch { get; private set; } = false;
public static bool IsUpgrade { get; private set; } = false;
public static bool IsMenuLaunch { get; private set; } = false;
public static string[] LaunchArgs { get; private set; } = null!;
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];
@ -96,13 +91,22 @@ namespace Bloxstrap
_showingExceptionDialog = true;
if (!IsQuiet)
if (!LaunchSettings.IsQuiet)
Frontend.ShowExceptionDialog(exception);
Terminate(ErrorCode.ERROR_INSTALL_FAILURE);
#endif
}
private void StartupFinished()
{
const string LOG_IDENT = "App::StartupFinished";
Logger.WriteLine(LOG_IDENT, "Successfully reached end of main thread. Terminating...");
Terminate();
}
protected override void OnStartup(StartupEventArgs e)
{
const string LOG_IDENT = "App::OnStartup";
@ -122,48 +126,11 @@ namespace Bloxstrap
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
LaunchArgs = e.Args;
#if DEBUG
Logger.WriteLine(LOG_IDENT, $"Arguments: {string.Join(' ', LaunchArgs)}");
#endif
LaunchSettings = new LaunchSettings(e.Args);
HttpClient.Timeout = TimeSpan.FromSeconds(30);
HttpClient.DefaultRequestHeaders.Add("User-Agent", ProjectRepository);
if (LaunchArgs.Length > 0)
{
if (Array.IndexOf(LaunchArgs, "-preferences") != -1 || Array.IndexOf(LaunchArgs, "-menu") != -1)
{
Logger.WriteLine(LOG_IDENT, "Started with IsMenuLaunch flag");
IsMenuLaunch = true;
}
if (Array.IndexOf(LaunchArgs, "-quiet") != -1)
{
Logger.WriteLine(LOG_IDENT, "Started with IsQuiet flag");
IsQuiet = true;
}
if (Array.IndexOf(LaunchArgs, "-uninstall") != -1)
{
Logger.WriteLine(LOG_IDENT, "Started with IsUninstall flag");
IsUninstall = true;
}
if (Array.IndexOf(LaunchArgs, "-nolaunch") != -1)
{
Logger.WriteLine(LOG_IDENT, "Started with IsNoLaunch flag");
IsNoLaunch = true;
}
if (Array.IndexOf(LaunchArgs, "-upgrade") != -1)
{
Logger.WriteLine(LOG_IDENT, "Bloxstrap started with IsUpgrade flag");
IsUpgrade = true;
}
}
using (var checker = new InstallChecker())
{
checker.Check();
@ -175,7 +142,7 @@ namespace Bloxstrap
// just in case the user decides to cancel the install
if (!IsFirstRun)
{
Logger.Initialize(IsUninstall);
Logger.Initialize(LaunchSettings.IsUninstall);
if (!Logger.Initialized)
{
@ -188,18 +155,15 @@ namespace Bloxstrap
FastFlags.Load();
}
if (!IsUninstall && !IsMenuLaunch)
if (!LaunchSettings.IsUninstall && !LaunchSettings.IsMenuLaunch)
NotifyIcon = new();
#if !DEBUG
if (!IsUninstall && !IsFirstRun)
if (!LaunchSettings.IsUninstall && !IsFirstRun)
InstallChecker.CheckUpgrade();
#endif
string commandLine = "";
LaunchMode? launchMode = null;
if (IsMenuLaunch)
if (LaunchSettings.IsMenuLaunch)
{
Process? menuProcess = Process.GetProcesses().Where(x => x.MainWindowTitle == $"{ProjectName} Menu").FirstOrDefault();
@ -211,7 +175,7 @@ namespace Bloxstrap
}
else
{
if (Process.GetProcessesByName(ProjectName).Length > 1 && !IsQuiet)
if (Process.GetProcessesByName(ProjectName).Length > 1 && !LaunchSettings.IsQuiet)
Frontend.ShowMessageBox(
Bloxstrap.Resources.Strings.Menu_AlreadyRunning,
MessageBoxImage.Information
@ -219,74 +183,20 @@ namespace Bloxstrap
Frontend.ShowMenu();
}
}
else if (LaunchArgs.Length > 0)
{
if (LaunchArgs[0].StartsWith("roblox-player:"))
{
commandLine = ProtocolHandler.ParseUri(LaunchArgs[0]);
launchMode = LaunchMode.Player;
}
else if (LaunchArgs[0].StartsWith("roblox:"))
{
if (Settings.Prop.UseDisableAppPatch)
Frontend.ShowMessageBox(
Bloxstrap.Resources.Strings.Bootstrapper_DeeplinkTempEnabled,
MessageBoxImage.Information
);
commandLine = $"--app --deeplink {LaunchArgs[0]}";
launchMode = LaunchMode.Player;
}
else if (LaunchArgs[0].StartsWith("roblox-studio:"))
{
commandLine = ProtocolHandler.ParseUri(LaunchArgs[0]);
if (!commandLine.Contains("-startEvent"))
commandLine += " -startEvent www.roblox.com/robloxQTStudioStartedEvent";
launchMode = LaunchMode.Studio;
}
else if (LaunchArgs[0].StartsWith("roblox-studio-auth:"))
{
commandLine = HttpUtility.UrlDecode(LaunchArgs[0]);
launchMode = LaunchMode.StudioAuth;
}
else if (LaunchArgs[0] == "-ide")
{
launchMode = LaunchMode.Studio;
if (LaunchArgs.Length >= 2)
commandLine = $"-task EditFile -localPlaceFile \"{LaunchArgs[1]}\"";
}
else
{
commandLine = "--app";
launchMode = LaunchMode.Player;
}
}
else
{
commandLine = "--app";
launchMode = LaunchMode.Player;
StartupFinished();
return;
}
if (launchMode != null)
{
if (!IsFirstRun)
ShouldSaveConfigs = true;
// start bootstrapper and show the bootstrapper modal if we're not running silently
Logger.WriteLine(LOG_IDENT, "Initializing bootstrapper");
Bootstrapper bootstrapper = new(commandLine, (LaunchMode)launchMode);
Bootstrapper bootstrapper = new(LaunchSettings.RobloxLaunchArgs, LaunchSettings.RobloxLaunchMode);
IBootstrapperDialog? dialog = null;
if (!IsQuiet)
if (!LaunchSettings.IsQuiet)
{
Logger.WriteLine(LOG_IDENT, "Initializing bootstrapper dialog");
dialog = Settings.Prop.BootstrapperStyle.GetNew();
@ -300,7 +210,7 @@ namespace Bloxstrap
Mutex? singletonMutex = null;
if (Settings.Prop.MultiInstanceLaunching && launchMode == LaunchMode.Player)
if (Settings.Prop.MultiInstanceLaunching && LaunchSettings.RobloxLaunchMode == LaunchMode.Player)
{
Logger.WriteLine(LOG_IDENT, "Creating singleton mutex");
@ -344,7 +254,7 @@ 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 (!IsNoLaunch && Settings.Prop.EnableActivityTracking)
if (!LaunchSettings.IsNoLaunch && Settings.Prop.EnableActivityTracking)
NotifyIcon?.InitializeContextMenu();
Logger.WriteLine(LOG_IDENT, "Waiting for bootstrapper task to finish");
@ -360,11 +270,8 @@ namespace Bloxstrap
while (Process.GetProcessesByName("RobloxPlayerBeta").Any())
Thread.Sleep(5000);
}
}
Logger.WriteLine(LOG_IDENT, "Successfully reached end of main thread. Terminating...");
Terminate();
StartupFinished();
}
}
}

View File

@ -7,8 +7,8 @@
<UseWPF>true</UseWPF>
<UseWindowsForms>True</UseWindowsForms>
<ApplicationIcon>Bloxstrap.ico</ApplicationIcon>
<Version>2.5.3</Version>
<FileVersion>2.5.3.0</FileVersion>
<Version>2.6.0</Version>
<FileVersion>2.6.0.0</FileVersion>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
@ -40,7 +40,7 @@
<ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
<PackageReference Include="DiscordRichPresence" Version="1.2.1.24" />
<PackageReference Include="Markdig" Version="0.33.0" />
<PackageReference Include="Markdig" Version="0.35.0" />
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.18-beta">
<!--<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>-->
<PrivateAssets>all</PrivateAssets>

View File

@ -99,10 +99,6 @@ namespace Bloxstrap
message = message.Replace("{product}", productName);
// yea idk
if (App.Settings.Prop.BootstrapperStyle == BootstrapperStyle.ByfronDialog)
message = message.Replace("...", "");
if (Dialog is not null)
Dialog.Message = message;
}
@ -127,7 +123,7 @@ namespace Bloxstrap
App.Logger.WriteLine(LOG_IDENT, "Running bootstrapper");
if (App.IsUninstall)
if (App.LaunchSettings.IsUninstall)
{
Uninstall();
return;
@ -230,9 +226,9 @@ namespace Bloxstrap
await mutex.ReleaseAsync();
if (App.IsFirstRun && App.IsNoLaunch)
if (App.IsFirstRun && App.LaunchSettings.IsNoLaunch)
Dialog?.ShowSuccess(Resources.Strings.Bootstrapper_SuccessfullyInstalled);
else if (!App.IsNoLaunch && !_cancelFired)
else if (!App.LaunchSettings.IsNoLaunch && !_cancelFired)
await StartRoblox();
}
@ -306,7 +302,7 @@ namespace Bloxstrap
MessageBoxImage.Error
);
if (!App.IsQuiet)
if (!App.LaunchSettings.IsQuiet)
Utilities.ShellExecute("https://support.microsoft.com/en-us/topic/media-feature-pack-list-for-windows-n-editions-c1c6fffa-d052-8338-7a79-a4bb980a700a");
Dialog?.CloseBootstrapper();
@ -659,7 +655,7 @@ namespace Bloxstrap
FileName = downloadLocation,
};
foreach (string arg in App.LaunchArgs)
foreach (string arg in App.LaunchSettings.Args)
startInfo.ArgumentList.Add(arg);
App.Settings.Save();
@ -703,13 +699,13 @@ namespace Bloxstrap
{
foreach (Process process in Process.GetProcessesByName(App.RobloxPlayerAppName))
{
process.CloseMainWindow();
process.Kill();
process.Close();
}
foreach (Process process in Process.GetProcessesByName(App.RobloxStudioAppName))
{
process.CloseMainWindow();
process.Kill();
process.Close();
}
}

View File

@ -7,6 +7,8 @@
LegacyDialog2011,
ProgressDialog,
FluentDialog,
ByfronDialog
ByfronDialog,
ProgressFluentDialog,
ProgressFluentAeroDialog
}
}

View File

@ -3,5 +3,16 @@
static class BootstrapperStyleEx
{
public static IBootstrapperDialog GetNew(this BootstrapperStyle bootstrapperStyle) => Frontend.GetBootstrapperDialog(bootstrapperStyle);
public static IReadOnlyCollection<BootstrapperStyle> Selections => new BootstrapperStyle[]
{
BootstrapperStyle.FluentDialog,
BootstrapperStyle.ProgressFluentDialog,
BootstrapperStyle.ProgressFluentAeroDialog,
BootstrapperStyle.ByfronDialog,
BootstrapperStyle.LegacyDialog2011,
BootstrapperStyle.LegacyDialog2008,
BootstrapperStyle.VistaDialog
};
}
}

View File

@ -124,7 +124,7 @@ namespace Bloxstrap
App.BaseDirectory = Path.Combine(Paths.LocalAppData, App.ProjectName);
App.Logger.Initialize(true);
if (App.IsQuiet)
if (App.LaunchSettings.IsQuiet)
return;
App.IsSetupComplete = false;
@ -159,7 +159,7 @@ namespace Bloxstrap
MessageBoxResult result;
// silently upgrade version if the command line flag is set or if we're launching from an auto update
if (App.IsUpgrade || isAutoUpgrade)
if (App.LaunchSettings.IsUpgrade || isAutoUpgrade)
{
result = MessageBoxResult.Yes;
}
@ -238,7 +238,7 @@ namespace Bloxstrap
(_, _) => Utilities.ShellExecute($"https://github.com/{App.ProjectRepository}/releases/tag/v{currentVersionInfo.ProductVersion}")
);
}
else if (!App.IsQuiet)
else if (!App.LaunchSettings.IsQuiet)
{
Frontend.ShowMessageBox(
string.Format(Resources.Strings.InstallChecker_Updated, currentVersionInfo.ProductVersion),

View File

@ -60,7 +60,7 @@
int delay = 1000;
if (App.Settings.Prop.OhHeyYouFoundMe)
if (App.Settings.Prop.PowerTools)
delay = 250;
string logDirectory = Path.Combine(Paths.LocalAppData, "Roblox\\logs");

View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Bloxstrap
{
public class InterProcessLock : IDisposable
{
public Mutex Mutex { get; private set; }
public bool IsAcquired { get; private set; }
public InterProcessLock(string name, TimeSpan timeout)
{
Mutex = new Mutex(false, "Bloxstrap-" + name);
IsAcquired = Mutex.WaitOne(timeout);
}
public void Dispose()
{
if (IsAcquired)
{
Mutex.ReleaseMutex();
IsAcquired = false;
}
}
}
}

181
Bloxstrap/LaunchSettings.cs Normal file
View File

@ -0,0 +1,181 @@
using Bloxstrap.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Windows;
namespace Bloxstrap
{
public class LaunchSettings
{
[LaunchFlag(new[] { "-preferences", "-menu" })]
public bool IsMenuLaunch { get; private set; } = false;
[LaunchFlag("-quiet")]
public bool IsQuiet { get; private set; } = false;
[LaunchFlag("-uninstall")]
public bool IsUninstall { get; private set; } = false;
[LaunchFlag("-nolaunch")]
public bool IsNoLaunch { get; private set; } = false;
[LaunchFlag("-upgrade")]
public bool IsUpgrade { get; private set; } = false;
public LaunchMode RobloxLaunchMode { get; private set; } = LaunchMode.Player;
public string RobloxLaunchArgs { get; private set; } = "--app";
/// <summary>
/// Original launch arguments
/// </summary>
public string[] Args { get; private set; }
private Dictionary<string, PropertyInfo>? _flagMap;
// pizzaboxer wanted this
private void ParseLaunchFlagProps()
{
_flagMap = new Dictionary<string, PropertyInfo>();
foreach (var prop in typeof(LaunchSettings).GetProperties())
{
var attr = prop.GetCustomAttribute<LaunchFlagAttribute>();
if (attr == null)
continue;
if (!string.IsNullOrEmpty(attr.Name))
{
_flagMap[attr.Name] = prop;
}
else
{
foreach (var name in attr.Names!)
_flagMap[name] = prop;
}
}
}
private void ParseFlag(string arg)
{
const string LOG_IDENT = "LaunchSettings::ParseFlag";
arg = arg.ToLowerInvariant();
if (_flagMap!.ContainsKey(arg))
{
var prop = _flagMap[arg];
prop.SetValue(this, true);
App.Logger.WriteLine(LOG_IDENT, $"Started with {prop.Name} flag");
}
}
private void ParseRoblox(string arg, ref int i)
{
if (arg.StartsWith("roblox-player:"))
{
RobloxLaunchArgs = ProtocolHandler.ParseUri(arg);
RobloxLaunchMode = LaunchMode.Player;
}
else if (arg.StartsWith("roblox:"))
{
if (App.Settings.Prop.UseDisableAppPatch)
Frontend.ShowMessageBox(
Resources.Strings.Bootstrapper_DeeplinkTempEnabled,
MessageBoxImage.Information
);
RobloxLaunchArgs = $"--app --deeplink {arg}";
RobloxLaunchMode = LaunchMode.Player;
}
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}\"";
}
}
}
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);
idx++; // roblox arg
}
// check if there are any launch flags
if (idx > Args.Length - 1)
return;
App.Logger.WriteLine(LOG_IDENT, "Parsing launch flags");
// map out launch flags
ParseLaunchFlagProps();
// parse any launch flags
for (int i = idx; i < Args.Length; i++)
ParseFlag(Args[i]);
// cleanup flag map
_flagMap!.Clear();
_flagMap = null;
}
public LaunchSettings(string[] args)
{
Args = args;
Parse();
}
}
}

View File

@ -0,0 +1,24 @@
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;
}
}
}

View File

@ -13,7 +13,10 @@ namespace Bloxstrap.Models
public bool CheckForUpdates { get; set; } = true;
public bool CreateDesktopIcon { get; set; } = true;
public bool MultiInstanceLaunching { get; set; } = false;
public bool OhHeyYouFoundMe { get; set; } = false;
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
[JsonPropertyName("OhHeyYouFoundMeAgain")]
public bool PowerTools { get; set; } = false;
// channel configuration
public string Channel { get; set; } = RobloxDeployment.DefaultChannel;

View File

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project>
<PropertyGroup>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<PublishDir>bin\Release\net6.0-windows\publish\win-x86\</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol>
<_TargetId>Folder</_TargetId>
<TargetFramework>net6.0-windows</TargetFramework>
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
<SelfContained>false</SelfContained>
<PublishSingleFile>true</PublishSingleFile>
<PublishReadyToRun>false</PublishReadyToRun>
</PropertyGroup>
</Project>

View File

@ -243,6 +243,24 @@ namespace Bloxstrap.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Style preview - Click the X button at the top right to close.
/// </summary>
public static string Bootstrapper_StylePreview_ImageCancel {
get {
return ResourceManager.GetString("Bootstrapper.StylePreview.ImageCancel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Style preview - Click Cancel to close.
/// </summary>
public static string Bootstrapper_StylePreview_TextCancel {
get {
return ResourceManager.GetString("Bootstrapper.StylePreview.TextCancel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Bloxstrap has successfully installed.
/// </summary>
@ -828,6 +846,24 @@ namespace Bloxstrap.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Fluent Progress (Aero).
/// </summary>
public static string Enums_BootstrapperStyle_ProgressFluentAeroDialog {
get {
return ResourceManager.GetString("Enums.BootstrapperStyle.ProgressFluentAeroDialog", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Fluent Progress.
/// </summary>
public static string Enums_BootstrapperStyle_ProgressFluentDialog {
get {
return ResourceManager.GetString("Enums.BootstrapperStyle.ProgressFluentDialog", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Vista (2008 - 2011).
/// </summary>
@ -1426,7 +1462,7 @@ namespace Bloxstrap.Resources {
}
/// <summary>
/// Looks up a localized string similar to Bloxstrap is currently running, likely as a background Roblox process. Please note that not all your changes will immediately apply until you close all currently open Roblox instances.&quot;.
/// Looks up a localized string similar to Bloxstrap is currently running, likely as a background Roblox process. Please note that not all your changes will immediately apply until you close all currently open Roblox instances..
/// </summary>
public static string Menu_AlreadyRunning {
get {

View File

@ -180,6 +180,14 @@ Your ReShade configuration files will still be saved, and you can locate them by
<data name="Bootstrapper.Status.WaitingOtherInstances" xml:space="preserve">
<value>Waiting for other instances...</value>
</data>
<data name="Bootstrapper.StylePreview.ImageCancel" xml:space="preserve">
<value>Style preview - Click the X button at the top right to close</value>
<comment>Text for style previews that use an X button. Currently only applies to Byfron</comment>
</data>
<data name="Bootstrapper.StylePreview.TextCancel" xml:space="preserve">
<value>Style preview - Click Cancel to close</value>
<comment>Text for style previews that use text button that says "Cancel"</comment>
</data>
<data name="Bootstrapper.SuccessfullyInstalled" xml:space="preserve">
<value>Bloxstrap has successfully installed</value>
</data>
@ -375,6 +383,12 @@ Your ReShade configuration files will still be saved, and you can locate them by
<data name="Enums.BootstrapperStyle.ProgressDialog" xml:space="preserve">
<value>Progress (~2014)</value>
</data>
<data name="Enums.BootstrapperStyle.ProgressFluentAeroDialog" xml:space="preserve">
<value>Fluent Progress (Aero)</value>
</data>
<data name="Enums.BootstrapperStyle.ProgressFluentDialog" xml:space="preserve">
<value>Fluent Progress</value>
</data>
<data name="Enums.BootstrapperStyle.VistaDialog" xml:space="preserve">
<value>Vista (2008 - 2011)</value>
</data>
@ -577,7 +591,7 @@ Would you like to upgrade your currently installed version?</value>
<value>All files</value>
</data>
<data name="Menu.AlreadyRunning" xml:space="preserve">
<value>Bloxstrap is currently running, likely as a background Roblox process. Please note that not all your changes will immediately apply until you close all currently open Roblox instances."</value>
<value>Bloxstrap is currently running, likely as a background Roblox process. Please note that not all your changes will immediately apply until you close all currently open Roblox instances.</value>
</data>
<data name="Menu.Appearance.Bootstrapper.Description" xml:space="preserve">
<value>You can make it look different, retro, or even just like Roblox.</value>

View File

@ -14,7 +14,7 @@
Closing="Window_Closing">
<Border CornerRadius="10" BorderBrush="#33393B3D" Background="{Binding Background}" BorderThickness="{Binding DialogBorder}">
<Grid>
<Image Source="{Binding ByfronLogoLocation}" Width="114" Height="108" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="17,13,0,0" />
<Image Source="{Binding ByfronLogoLocation}" RenderOptions.BitmapScalingMode="HighQuality" Width="114" Height="108" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="17,13,0,0" />
<Button Margin="15" VerticalAlignment="Top" HorizontalAlignment="Right" Width="20" Height="20" BorderThickness="0" Padding="1" Background="Transparent" BorderBrush="Transparent" Visibility="{Binding CancelButtonVisibility, Mode=OneWay}" Command="{Binding CancelInstallCommand}">
<Path Fill="{Binding IconColor}" Stretch="Fill">
<Path.Data>

View File

@ -26,7 +26,11 @@ namespace Bloxstrap.UI.Elements.Bootstrapper
get => _viewModel.Message;
set
{
_viewModel.Message = value;
string message = value;
if (message.EndsWith("..."))
message = message[..^3];
_viewModel.Message = message;
_viewModel.OnPropertyChanged(nameof(_viewModel.Message));
}
}

View File

@ -30,11 +30,7 @@
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border Grid.Column="0" Margin="0,12,0,0" Width="48" Height="48" VerticalAlignment="Top">
<Border.Background>
<ImageBrush ImageSource="{Binding Icon, Mode=OneWay}" RenderOptions.BitmapScalingMode="HighQuality" />
</Border.Background>
</Border>
<Image Grid.Column="0" Margin="0,12,0,0" Width="48" Height="48" VerticalAlignment="Top" Source="{Binding Icon, Mode=OneWay}" RenderOptions.BitmapScalingMode="HighQuality" />
<StackPanel Grid.Column="1">
<TextBlock Margin="16,8,0,0" FontSize="20" Text="{Binding Message, Mode=OneWay}" Foreground="{DynamicResource TextFillColorPrimaryBrush}" />
<ProgressBar Margin="16,16,0,16" IsIndeterminate="{Binding ProgressIndeterminate, Mode=OneWay}" Maximum="{Binding ProgressMaximum, Mode=OneWay}" Value="{Binding ProgressValue, Mode=OneWay}" />

View File

@ -0,0 +1,80 @@
<base:WpfUiWindow
x:Class="Bloxstrap.UI.Elements.Bootstrapper.ProgressFluentDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:base="clr-namespace:Bloxstrap.UI.Elements.Base"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:vms="clr-namespace:Bloxstrap.UI.ViewModels.Bootstrapper"
Width="500"
Height="280"
MinHeight="0"
d:DataContext="{d:DesignInstance vms:ProgressFluentDialogViewModel,
IsDesignTimeCreatable=True}"
AllowsTransparency="True"
Background="{ui:ThemeResource ApplicationBackgroundBrush}"
Closing="UiWindow_Closing"
ExtendsContentIntoTitleBar="True"
ResizeMode="NoResize"
WindowBackdropType="{Binding Path=WindowBackdropType, Mode=OneTime}"
WindowStartupLocation="CenterScreen"
WindowStyle="None"
mc:Ignorable="d">
<!-- Background is for Aero theme only -->
<Grid Background="{Binding Path=BackgroundColourBrush, Mode=OneTime}">
<!-- Allow for drag -->
<ui:TitleBar
VerticalAlignment="Top"
CanMaximize="False"
ShowClose="False"
ShowMaximize="False"
ShowMinimize="False" />
<Grid Margin="32,16">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image
Grid.Row="0"
Width="80"
Height="80"
Margin="0,30,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Top"
RenderOptions.BitmapScalingMode="HighQuality"
Source="{Binding Icon, Mode=OneWay}" />
<TextBlock
Grid.Row="1"
Margin="0,0,0,8"
HorizontalAlignment="Center"
FontSize="18"
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
Text="{Binding Message, Mode=OneWay}" />
<ProgressBar
Grid.Row="2"
Margin="0,0,0,16"
IsIndeterminate="{Binding ProgressIndeterminate, Mode=OneWay}"
Maximum="{Binding ProgressMaximum, Mode=OneWay}"
Value="{Binding ProgressValue, Mode=OneWay}" />
<Button
Grid.Row="3"
Width="120"
Padding="4"
HorizontalAlignment="Center"
Command="{Binding CancelInstallCommand}"
Content="{x:Static resources:Strings.Common_Cancel}"
FontSize="14"
IsEnabled="{Binding CancelEnabled, Mode=OneWay}" />
</Grid>
</Grid>
</base:WpfUiWindow>

View File

@ -0,0 +1,117 @@
using Bloxstrap.UI.Elements.Bootstrapper.Base;
using Bloxstrap.UI.ViewModels.Bootstrapper;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace Bloxstrap.UI.Elements.Bootstrapper
{
/// <summary>
/// Interaction logic for ProgressFluentDialog.xaml
/// </summary>
public partial class ProgressFluentDialog : IBootstrapperDialog
{
private readonly ProgressFluentDialogViewModel _viewModel;
public Bloxstrap.Bootstrapper? Bootstrapper { get; set; }
private bool _isClosing;
#region UI Elements
public string Message
{
get => _viewModel.Message;
set
{
_viewModel.Message = value;
_viewModel.OnPropertyChanged(nameof(_viewModel.Message));
}
}
public ProgressBarStyle ProgressStyle
{
get => _viewModel.ProgressIndeterminate ? ProgressBarStyle.Marquee : ProgressBarStyle.Continuous;
set
{
_viewModel.ProgressIndeterminate = (value == ProgressBarStyle.Marquee);
_viewModel.OnPropertyChanged(nameof(_viewModel.ProgressIndeterminate));
}
}
public int ProgressMaximum
{
get => _viewModel.ProgressMaximum;
set
{
_viewModel.ProgressMaximum = value;
_viewModel.OnPropertyChanged(nameof(_viewModel.ProgressMaximum));
}
}
public int ProgressValue
{
get => _viewModel.ProgressValue;
set
{
_viewModel.ProgressValue = value;
_viewModel.OnPropertyChanged(nameof(_viewModel.ProgressValue));
}
}
public bool CancelEnabled
{
get => _viewModel.CancelEnabled;
set
{
_viewModel.CancelEnabled = value;
_viewModel.OnPropertyChanged(nameof(_viewModel.CancelButtonVisibility));
_viewModel.OnPropertyChanged(nameof(_viewModel.CancelEnabled));
}
}
#endregion
public ProgressFluentDialog(bool aero)
{
InitializeComponent();
ApplyTheme();
_viewModel = new ProgressFluentDialogViewModel(this, aero);
DataContext = _viewModel;
Title = App.Settings.Prop.BootstrapperTitle;
Icon = App.Settings.Prop.BootstrapperIcon.GetIcon().GetImageSource();
}
private void UiWindow_Closing(object sender, CancelEventArgs e)
{
if (!_isClosing)
Bootstrapper?.CancelInstall();
}
#region IBootstrapperDialog Methods
public void ShowBootstrapper() => this.ShowDialog();
public void CloseBootstrapper()
{
_isClosing = true;
Dispatcher.BeginInvoke(this.Close);
}
public void ShowSuccess(string message, Action? callback) => BaseFunctions.ShowSuccess(message, callback);
#endregion
}
}

View File

@ -30,7 +30,7 @@
<ColumnDefinition Width="20" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="pack://application:,,,/Bloxstrap.ico" />
<Image Grid.Column="0" Source="pack://application:,,,/Bloxstrap.ico" RenderOptions.BitmapScalingMode="HighQuality" />
<TextBlock x:Name="VersionTextBlock" Foreground="{DynamicResource TextFillColorSecondaryBrush}" Grid.Column="1" VerticalAlignment="Center" Margin="6,0,0,0" Text="Bloxstrap v2.4.1" />
</Grid>
</MenuItem.Header>

View File

@ -39,7 +39,7 @@ namespace Bloxstrap.UI.Elements.ContextMenu
if (_activityWatcher is not null)
{
if (App.Settings.Prop.OhHeyYouFoundMe)
if (App.Settings.Prop.PowerTools)
LogTracerMenuItem.Visibility = Visibility.Visible;
_activityWatcher.OnGameJoin += ActivityWatcher_OnGameJoin;
@ -136,7 +136,7 @@ namespace Bloxstrap.UI.Elements.ContextMenu
return;
using Process process = Process.GetProcessById((int)_processId!);
process.CloseMainWindow();
process.Kill();
process.Close();
}
}

View File

@ -6,17 +6,19 @@ using System.Windows;
using Markdig.Syntax;
using Markdig.Syntax.Inlines;
using Markdig;
using System.Windows.Media;
namespace Bloxstrap.UI.Elements.Controls
{
/// <summary>
/// TextBlock with markdown support. <br/>
/// Only supports text and urls.
/// TextBlock with markdown support.
/// </summary>
[ContentProperty("MarkdownText")]
[Localizability(LocalizationCategory.Text)]
class MarkdownTextBlock : TextBlock
{
private static MarkdownPipeline _markdownPipeline;
public static readonly DependencyProperty MarkdownTextProperty =
DependencyProperty.Register(nameof(MarkdownText), typeof(string), typeof(MarkdownTextBlock),
new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender, OnTextMarkdownChanged));
@ -24,10 +26,73 @@ namespace Bloxstrap.UI.Elements.Controls
[Localizability(LocalizationCategory.Text)]
public string MarkdownText
{
get => Inlines.ToString() ?? "";
get => (string)GetValue(MarkdownTextProperty);
set => SetValue(MarkdownTextProperty, value);
}
private static System.Windows.Documents.Inline? GetWpfInlineFromMarkdownInline(Markdig.Syntax.Inlines.Inline? inline)
{
if (inline is LiteralInline literalInline)
{
return new Run(literalInline.ToString());
}
else if (inline is EmphasisInline emphasisInline)
{
switch (emphasisInline.DelimiterChar)
{
case '*':
case '_':
{
if (emphasisInline.DelimiterCount == 1) // 1 = italic
{
var childInline = new Italic(GetWpfInlineFromMarkdownInline(emphasisInline.FirstChild));
return childInline;
}
else // 2 = bold
{
var childInline = new Bold(GetWpfInlineFromMarkdownInline(emphasisInline.FirstChild));
return childInline;
}
}
case '=': // marked
{
var childInline = new Span(GetWpfInlineFromMarkdownInline(emphasisInline.FirstChild));
childInline.Background = new SolidColorBrush(Color.FromArgb(50, 255, 255, 255)); // TODO: better colour?
return childInline;
}
}
}
else if (inline is LinkInline linkInline)
{
string? url = linkInline.Url;
var textInline = linkInline.FirstChild;
if (string.IsNullOrEmpty(url))
{
return GetWpfInlineFromMarkdownInline(textInline);
}
var childInline = GetWpfInlineFromMarkdownInline(textInline);
return new Hyperlink(childInline)
{
Command = GlobalViewModel.OpenWebpageCommand,
CommandParameter = url
};
}
return null;
}
private void AddMarkdownInline(Markdig.Syntax.Inlines.Inline? inline)
{
var wpfInline = GetWpfInlineFromMarkdownInline(inline);
if (wpfInline != null)
Inlines.Add(wpfInline);
}
private static void OnTextMarkdownChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
if (dependencyObject is not MarkdownTextBlock markdownTextBlock)
@ -36,34 +101,26 @@ namespace Bloxstrap.UI.Elements.Controls
if (dependencyPropertyChangedEventArgs.NewValue is not string rawDocument)
return;
MarkdownDocument document = Markdown.Parse(rawDocument);
MarkdownDocument document = Markdown.Parse(rawDocument, _markdownPipeline);
markdownTextBlock.Inlines.Clear();
if (document.FirstOrDefault() is not ParagraphBlock paragraphBlock || paragraphBlock.Inline == null)
return;
foreach (var inline in paragraphBlock.Inline)
for (int i = 0; i < paragraphBlock.Inline.Count(); i++)
{
if (inline is LiteralInline literalInline)
{
markdownTextBlock.Inlines.Add(new Run(literalInline.ToString()));
}
else if (inline is LinkInline linkInline)
{
string? url = linkInline.Url;
string? text = linkInline.FirstChild?.ToString();
var inline = paragraphBlock.Inline.ElementAt(i);
if (string.IsNullOrEmpty(url) || string.IsNullOrEmpty(text))
continue;
markdownTextBlock.AddMarkdownInline(inline);
}
}
markdownTextBlock.Inlines.Add(new Hyperlink(new Run(text))
static MarkdownTextBlock()
{
Command = GlobalViewModel.OpenWebpageCommand,
CommandParameter = url
});
}
}
_markdownPipeline = new MarkdownPipelineBuilder()
.UseEmphasisExtras(Markdig.Extensions.EmphasisExtras.EmphasisExtraOptions.Marked) // enable '==' support
.Build();
}
}
}

View File

@ -79,7 +79,7 @@
<ui:Button Content="{Binding ConfirmButtonText, Mode=OneTime}" Appearance="Primary" Command="{Binding ConfirmSettingsCommand, Mode=OneWay}" IsEnabled="{Binding ConfirmButtonEnabled, Mode=OneWay}" />
</StatusBarItem>
<StatusBarItem Grid.Column="2" Padding="4,0,0,0">
<ui:Button Content="Cancel" Command="{Binding CloseWindowCommand, Mode=OneWay}" />
<ui:Button Content="{x:Static resources:Strings.Common_Cancel}" Command="{Binding CloseWindowCommand, Mode=OneWay}" />
</StatusBarItem>
</StatusBar>
</Grid>

View File

@ -18,11 +18,7 @@
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border Grid.Column="0" Width="60" Height="60" VerticalAlignment="Center">
<Border.Background>
<ImageBrush ImageSource="pack://application:,,,/Bloxstrap.ico" />
</Border.Background>
</Border>
<Image Grid.Column="0" Width="60" Height="60" VerticalAlignment="Center" Source="pack://application:,,,/Bloxstrap.ico" RenderOptions.BitmapScalingMode="HighQuality" />
<StackPanel Grid.Column="1" Margin="12,0,0,0" VerticalAlignment="Center">
<Grid>
<Grid.ColumnDefinitions>
@ -126,6 +122,7 @@
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
@ -151,7 +148,7 @@
<TextBlock Margin="0,2,0,0" FontSize="12" Text="MIT License" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</ui:CardAction>
<ui:CardAction Grid.Row="1" Grid.Column="0" Margin="0,8,8,0" Command="models:GlobalViewModel.OpenWebpageCommand" CommandParameter="https://github.com/Lachee/discord-rpc-csharp/blob/development/LICENSE">
<ui:CardAction Grid.Row="1" Grid.Column="0" Margin="0,8,8,0" Command="models:GlobalViewModel.OpenWebpageCommand" CommandParameter="https://github.com/Lachee/discord-rpc-csharp/blob/master/LICENSE">
<StackPanel>
<TextBlock FontSize="14" Text="DiscordRPC by Lachee" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="MIT License" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
@ -169,6 +166,12 @@
<TextBlock Margin="0,2,0,0" FontSize="12" Text="MIT License" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</ui:CardAction>
<ui:CardAction Grid.Row="2" Grid.ColumnSpan="3" Margin="0,8,0,0" Command="models:GlobalViewModel.OpenWebpageCommand" CommandParameter="https://github.com/xoofx/markdig/blob/master/license.txt">
<StackPanel>
<TextBlock FontSize="14" Text="Markdig by xoofx" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="BSD 2-Clause License" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</ui:CardAction>
</Grid>
</StackPanel>
</ui:UiPage>

View File

@ -134,6 +134,8 @@ namespace Bloxstrap.UI.Elements.Menu.Pages
if (!newName.Contains(_searchFilter))
ClearSearch();
entry.Name = newName;
break;
case "Value":

View File

@ -12,7 +12,7 @@ namespace Bloxstrap.UI
public static MessageBoxResult ShowMessageBox(string message, MessageBoxImage icon = MessageBoxImage.None, MessageBoxButton buttons = MessageBoxButton.OK, MessageBoxResult defaultResult = MessageBoxResult.None)
{
if (App.IsQuiet)
if (App.LaunchSettings.IsQuiet)
return defaultResult;
switch (App.Settings.Prop.BootstrapperStyle)
@ -57,6 +57,8 @@ namespace Bloxstrap.UI
BootstrapperStyle.ProgressDialog => new ProgressDialog(),
BootstrapperStyle.FluentDialog => new FluentDialog(),
BootstrapperStyle.ByfronDialog => new ByfronDialog(),
BootstrapperStyle.ProgressFluentDialog => new ProgressFluentDialog(false),
BootstrapperStyle.ProgressFluentAeroDialog => new ProgressFluentDialog(true),
_ => new FluentDialog()
};
}

View File

@ -22,6 +22,12 @@ namespace Bloxstrap.UI.ViewModels.Bootstrapper
public bool CancelEnabled { get; set; } = false;
public Visibility CancelButtonVisibility => CancelEnabled ? Visibility.Visible : Visibility.Collapsed;
[Obsolete("Do not use this! This is for the designer only.", true)]
public BootstrapperDialogViewModel()
{
_dialog = null!;
}
public BootstrapperDialogViewModel(IBootstrapperDialog dialog)
{
_dialog = dialog;

View File

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
using Wpf.Ui.Appearance;
namespace Bloxstrap.UI.ViewModels.Bootstrapper
{
public class ProgressFluentDialogViewModel : BootstrapperDialogViewModel
{
public BackgroundType WindowBackdropType { get; set; } = BackgroundType.Mica;
public SolidColorBrush BackgroundColourBrush { get; set; } = new SolidColorBrush(Color.FromArgb(0, 0, 0, 0));
[Obsolete("Do not use this! This is for the designer only.", true)]
public ProgressFluentDialogViewModel() : base()
{ }
public ProgressFluentDialogViewModel(IBootstrapperDialog dialog, bool aero) : base(dialog)
{
const int alpha = 128;
WindowBackdropType = aero ? BackgroundType.Aero : BackgroundType.Mica;
if (aero)
BackgroundColourBrush = App.Settings.Prop.Theme.GetFinal() == Enums.Theme.Light ?
new SolidColorBrush(Color.FromArgb(alpha, 225, 225, 225)) :
new SolidColorBrush(Color.FromArgb(alpha, 30, 30, 30));
}
}
}

View File

@ -23,9 +23,9 @@ namespace Bloxstrap.UI.ViewModels.Menu
IBootstrapperDialog dialog = App.Settings.Prop.BootstrapperStyle.GetNew();
if (App.Settings.Prop.BootstrapperStyle == BootstrapperStyle.ByfronDialog)
dialog.Message = "Style preview - Click the X button at the top right to close";
dialog.Message = Resources.Strings.Bootstrapper_StylePreview_ImageCancel;
else
dialog.Message = "Style preview - Click Cancel to close";
dialog.Message = Resources.Strings.Bootstrapper_StylePreview_TextCancel;
dialog.CancelEnabled = true;
dialog.ShowBootstrapper();
@ -65,7 +65,7 @@ namespace Bloxstrap.UI.ViewModels.Menu
}
}
public IEnumerable<BootstrapperStyle> Dialogs { get; } = Enum.GetValues(typeof(BootstrapperStyle)).Cast<BootstrapperStyle>();
public IEnumerable<BootstrapperStyle> Dialogs { get; } = BootstrapperStyleEx.Selections;
public BootstrapperStyle Dialog
{

View File

@ -28,7 +28,7 @@ namespace Bloxstrap.UI.ViewModels.Menu
public ICommand OpenFastFlagEditorCommand => new RelayCommand(OpenFastFlagEditor);
public Visibility ShowDebugFlags => App.Settings.Prop.OhHeyYouFoundMe ? Visibility.Visible : Visibility.Collapsed;
public Visibility ShowDebugFlags => App.Settings.Prop.PowerTools ? Visibility.Visible : Visibility.Collapsed;
public bool HttpRequestLogging
{

View File

@ -6,9 +6,9 @@
[![Discord](https://img.shields.io/discord/1099468797410283540?logo=discord&logoColor=white&label=discord&color=4d3dff)](https://discord.gg/nKjV3mGq6R)
[![lol](https://img.shields.io/badge/mom%20made-pizza%20rolls-orange)](https://media.tenor.com/FIkSGbGycmAAAAAd/manly-roblox.gif)
An open-source, feature-packed alternative bootstrapper for Roblox.
An open-source, alternative bootstrapper for Roblox.
This a drop-in replacement for the stock Roblox bootstrapper, working more or less how you'd expect it to, while providing additional useful features. This does not touch or modify the game client itself, it's just a launcher! So don't worry, there's practically no risk of being banned for using this.
This is a drop-in replacement for the standard Roblox bootstrapper, providing additional useful features and improvements. This does not touch or modify the game client itself, it's just a launcher! So don't worry, there's no risk of being banned for using this.
Running into a problem or need help with something? [Check out the Wiki](https://github.com/pizzaboxer/bloxstrap/wiki). If you can't find anything, or would like to suggest something, please [submit an issue](https://github.com/pizzaboxer/bloxstrap/issues) or report it in our [Discord server](https://discord.gg/nKjV3mGq6R).
@ -32,7 +32,6 @@ Once installed, Bloxstrap is added to your Start Menu, where you can access the
Here's some of the features that Bloxstrap provides over the stock Roblox bootstrapper:
* Persistent file modifications, includes re-adding the old death sound!
* Support for easy and simple FastFlag editing, no need to mess around with a JSON file.
* Painless and seamless support for Discord Rich Presence - no auth cookie needed!
* A customizable launcher look
* Lets you see what region your current server is located in
@ -45,10 +44,8 @@ Bloxstrap also only runs whenever necessary, so it doesn't stay running in the b
## Screenshots
<p float="left">
<img src="https://github.com/pizzaboxer/bloxstrap/assets/41478239/cd723d23-9bff-401e-aadf-deea265a3b1c" width="829" />
<img src="https://github.com/pizzaboxer/bloxstrap/assets/41478239/dcfd0cdf-1aae-45bb-849a-f7710ec63b28" width="435" />
<img src="https://github.com/pizzaboxer/bloxstrap/assets/41478239/e08cdf28-4f99-46b5-99f2-5c338aac86db" width="390" />
<img src="https://github.com/pizzaboxer/bloxstrap/assets/41478239/a45755cb-39da-49df-b0ad-456a139e2efc" Width="593" />
<img src="https://github.com/pizzaboxer/bloxstrap/assets/41478239/7ba35223-9115-401f-bbc1-d15e9c5fd79e" width="232" />
<p>

2
wpfui

@ -1 +1 @@
Subproject commit 55d5ca08f9a1d7623f9a7e386e1f4ac9f2d024a7
Subproject commit 8f61545b386cc393f4502fb485cae9f052afbd46