Finalize update for v1.2.0

- Features
    - Added three new bootstrapper styles (Vista, Legacy 2009 and Progress Dark Theme)
    - Added ability to disable rich presence activity buttons
    - Added ability to restore old mouse cursor

 - Quality of Life
    - Refactored code for bootstrapper styles
This commit is contained in:
pizzaboxer 2022-08-16 23:06:08 +01:00
parent 6152bce70d
commit 462d48fafd
33 changed files with 1191 additions and 454 deletions

View File

@ -9,8 +9,8 @@
<PlatformTarget>AnyCPU</PlatformTarget>
<Platforms>AnyCPU;x86</Platforms>
<ApplicationIcon>Bloxstrap.ico</ApplicationIcon>
<Version>1.1.0</Version>
<FileVersion>1.1.0.0</FileVersion>
<Version>1.2.0</Version>
<FileVersion>1.2.0.0</FileVersion>
</PropertyGroup>
<ItemGroup>
@ -27,6 +27,12 @@
</ItemGroup>
<ItemGroup>
<Compile Update="Dialogs\BootstrapperStyles\LegacyDialog2009.cs">
<SubType>Form</SubType>
</Compile>
<Compile Update="Dialogs\BootstrapperStyles\ProgressDialogDark.cs">
<SubType>Form</SubType>
</Compile>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>

View File

@ -81,8 +81,6 @@ namespace Bloxstrap
CheckIfRunning();
// lots of try/catches here... lol
Message = $"Uninstalling {Program.ProjectName}...";
Program.SettingsManager.ShouldSave = false;
@ -122,7 +120,6 @@ namespace Bloxstrap
catch (Exception) { }
ShowSuccess($"{Program.ProjectName} has been uninstalled");
Program.Exit();
}
}
}

View File

@ -91,8 +91,11 @@ namespace Bloxstrap
File.Delete(filename);
}
// and also to delete our old version folder
Directory.Delete(Path.Combine(Program.BaseDirectory, "Versions", Program.Settings.VersionGuid), true);
if (VersionGuid != Program.Settings.VersionGuid)
{
// and also to delete our old version folder
Directory.Delete(Path.Combine(Program.BaseDirectory, "Versions", Program.Settings.VersionGuid), true);
}
}
CancelEnabled = false;
@ -115,6 +118,7 @@ namespace Bloxstrap
// but for now, let's just keep it at this
await ModifyDeathSound();
await ModifyMouseCursor();
}
private async void DownloadPackage(Package package)
@ -204,5 +208,36 @@ namespace Bloxstrap
}
}
}
private void ExtractFilesFromPackage(string packageName, string[] files)
{
Package? package = VersionPackageManifest.Find(x => x.Name == packageName);
if (package is null)
return;
DownloadPackage(package);
string packageLocation = Path.Combine(DownloadsFolder, package.Signature);
string packageFolder = Path.Combine(VersionFolder, PackageDirectories[package.Name]);
using (ZipArchive archive = ZipFile.OpenRead(packageLocation))
{
foreach (string fileName in files)
{
ZipArchiveEntry? entry = archive.Entries.Where(x => x.FullName == fileName).FirstOrDefault();
if (entry is null)
return;
string fileLocation = Path.Combine(packageFolder, entry.FullName);
if (File.Exists(fileLocation))
File.Delete(fileLocation);
entry.ExtractToFile(fileLocation);
}
}
}
}
}

View File

@ -1,6 +1,4 @@
using System.IO.Compression;
using Bloxstrap.Helpers;
using Bloxstrap.Helpers;
namespace Bloxstrap
{
@ -12,10 +10,10 @@ namespace Bloxstrap
string fileContentLocation = "content\\sounds\\ouch.ogg";
string fileLocation = Path.Combine(VersionFolder, fileContentLocation);
string officialDeathSoundHash = VersionFileManifest[fileContentLocation];
string currentDeathSoundHash = Utilities.CalculateMD5(fileLocation);
string officialHash = VersionFileManifest[fileContentLocation];
string currentHash = Utilities.CalculateMD5(fileLocation);
if (Program.Settings.UseOldDeathSound && currentDeathSoundHash == officialDeathSoundHash)
if (Program.Settings.UseOldDeathSound && currentHash == officialHash)
{
// let's get the old one!
@ -29,33 +27,37 @@ namespace Bloxstrap
await response.Content.CopyToAsync(fileStream);
}
}
else if (!Program.Settings.UseOldDeathSound && currentDeathSoundHash != officialDeathSoundHash)
else if (!Program.Settings.UseOldDeathSound && currentHash != officialHash)
{
// who's lame enough to ever do this?
// well, we need to re-extract the one that's in the content-sounds.zip package
var package = VersionPackageManifest.Find(x => x.Name == "content-sounds.zip");
string[] files = { fileContentName };
ExtractFilesFromPackage("content-sounds.zip", files);
}
}
if (package is null)
return;
private async Task ModifyMouseCursor()
{
string baseFolder = Path.Combine(VersionFolder, "content\\textures\\");
DownloadPackage(package);
string arrowCursor = "Cursors\\KeyboardMouse\\ArrowCursor.png";
string arrowFarCursor = "Cursors\\KeyboardMouse\\ArrowFarCursor.png";
string packageLocation = Path.Combine(DownloadsFolder, package.Signature);
string packageFolder = Path.Combine(VersionFolder, PackageDirectories[package.Name]);
string officialHash = VersionFileManifest["content\\textures\\Cursors\\KeyboardMouse\\ArrowCursor.png"];
string currentHash = Utilities.CalculateMD5(Path.Combine(baseFolder, arrowCursor));
using (ZipArchive archive = ZipFile.OpenRead(packageLocation))
{
ZipArchiveEntry? entry = archive.Entries.Where(x => x.FullName == fileContentName).FirstOrDefault();
if (Program.Settings.UseOldMouseCursor && currentHash == officialHash)
{
// the old cursors are actually still in the content\textures\ folder, so we can just get them from there
if (entry is null)
return;
if (File.Exists(fileLocation))
File.Delete(fileLocation);
entry.ExtractToFile(fileLocation);
}
File.Copy(Path.Combine(baseFolder, "ArrowCursor.png"), Path.Combine(baseFolder, arrowCursor), true);
File.Copy(Path.Combine(baseFolder, "ArrowFarCursor.png"), Path.Combine(baseFolder, arrowFarCursor), true);
}
else if (!Program.Settings.UseOldMouseCursor && currentHash != officialHash)
{
string[] files = { arrowCursor, arrowFarCursor };
ExtractFilesFromPackage("content-textures2.zip", files);
}
}
}

View File

@ -26,16 +26,24 @@ namespace Bloxstrap
switch (bootstrapperStyle)
{
case BootstrapperStyle.VistaDialog:
new VistaDialog(this);
Application.Run(new VistaDialog(this));
break;
case BootstrapperStyle.LegacyDialog:
Application.Run(new LegacyDialog(this));
case BootstrapperStyle.LegacyDialog2009:
Application.Run(new LegacyDialog2009(this));
break;
case BootstrapperStyle.LegacyDialog2011:
Application.Run(new LegacyDialog2011(this));
break;
case BootstrapperStyle.ProgressDialog:
Application.Run(new ProgressDialog(this));
break;
case BootstrapperStyle.ProgressDialogDark:
Application.Run(new ProgressDialogDark(this));
break;
}
}
@ -136,6 +144,7 @@ namespace Bloxstrap
return;
CloseDialog();
await gameClient.WaitForExitAsync();
}
}

View File

@ -1,36 +1,29 @@
using System.Diagnostics;
using Bloxstrap.Helpers;
using Bloxstrap.Helpers.RSMM;
namespace Bloxstrap.Dialogs.BootstrapperStyles
{
// TODO - universal implementation for winforms-based styles? (to reduce duplicate code)
// example: https://youtu.be/3K9oCEMHj2s?t=35
// so this specifically emulates the 2011 version of the legacy dialog,
// but once winforms code is cleaned up we could also do the 2009 version too
// example: https://youtu.be/VpduiruysuM?t=18
public partial class LegacyDialog : Form
public class BootstrapperStyleForm : Form, IBootstrapperStyle
{
private readonly Bootstrapper? Bootstrapper;
public Bootstrapper? Bootstrapper { get; set; }
public LegacyDialog(Bootstrapper? bootstrapper = null)
public virtual string Message { get; set; }
public virtual ProgressBarStyle ProgressStyle { get; set; }
public virtual int ProgressValue { get; set; }
public virtual bool CancelEnabled { get; set; }
public void SetupDialog()
{
InitializeComponent();
Bootstrapper = bootstrapper;
Icon icon = IconManager.GetIconResource();
this.Text = Program.ProjectName;
this.Icon = icon;
this.IconBox.Image = icon.ToBitmap();
this.Icon = IconManager.GetIconResource();
if (Bootstrapper is null)
{
this.Message.Text = "Click the Cancel button to return to preferences";
this.ButtonCancel.Enabled = true;
this.ButtonCancel.Visible = true;
Message = "Select Cancel to return to preferences";
CancelEnabled = true;
}
else
{
@ -46,6 +39,7 @@ namespace Bloxstrap.Dialogs.BootstrapperStyles
}
}
public async void RunBootstrapper()
{
if (Bootstrapper is null)
@ -60,22 +54,10 @@ namespace Bloxstrap.Dialogs.BootstrapperStyles
// string message = String.Format("{0}: {1}", ex.GetType(), ex.Message);
string message = ex.ToString();
ShowError(message);
Program.Exit();
}
}
private void ShowError(string message)
{
MessageBox.Show(
$"An error occurred while starting Roblox\n\nDetails: {message}",
Program.ProjectName,
MessageBoxButtons.OK,
MessageBoxIcon.Error
);
}
private void ShowSuccess(object sender, ChangeEventArgs<string> e)
public virtual void ShowSuccess(object sender, ChangeEventArgs<string> e)
{
MessageBox.Show(
e.Value,
@ -83,14 +65,36 @@ namespace Bloxstrap.Dialogs.BootstrapperStyles
MessageBoxButtons.OK,
MessageBoxIcon.Information
);
Program.Exit();
}
private void CloseDialog(object? sender, EventArgs e)
public virtual void ShowError(string message)
{
this.Close();
MessageBox.Show(
$"An error occurred while starting Roblox\n\nDetails: {message}",
Program.ProjectName,
MessageBoxButtons.OK,
MessageBoxIcon.Error
);
Program.Exit();
}
private void PromptShutdown(object? sender, EventArgs e)
public virtual void CloseDialog(object? sender, EventArgs e)
{
if (this.InvokeRequired)
{
EventHandler handler = new(CloseDialog);
this.Invoke(handler, sender, e);
}
else
{
this.Hide();
}
}
public void PromptShutdown(object? sender, EventArgs e)
{
DialogResult result = MessageBox.Show(
"Roblox is currently running, but needs to close. Would you like close Roblox now?",
@ -103,60 +107,61 @@ namespace Bloxstrap.Dialogs.BootstrapperStyles
Environment.Exit(0);
}
private void MessageChanged(object sender, ChangeEventArgs<string> e)
public void MessageChanged(object sender, ChangeEventArgs<string> e)
{
if (this.InvokeRequired)
{
ChangeEventHandler<string> handler = new(MessageChanged);
this.Message.Invoke(handler, sender, e);
this.Invoke(handler, sender, e);
}
else
{
this.Message.Text = e.Value;
Message = e.Value;
}
}
private void ProgressBarValueChanged(object sender, ChangeEventArgs<int> e)
public void ProgressBarStyleChanged(object sender, ChangeEventArgs<ProgressBarStyle> e)
{
if (this.ProgressBar.InvokeRequired)
{
ChangeEventHandler<int> handler = new(ProgressBarValueChanged);
this.ProgressBar.Invoke(handler, sender, e);
}
else
{
this.ProgressBar.Value = e.Value;
}
}
private void ProgressBarStyleChanged(object sender, ChangeEventArgs<ProgressBarStyle> e)
{
if (this.ProgressBar.InvokeRequired)
if (this.InvokeRequired)
{
ChangeEventHandler<ProgressBarStyle> handler = new(this.ProgressBarStyleChanged);
this.ProgressBar.Invoke(handler, sender, e);
this.Invoke(handler, sender, e);
}
else
{
this.ProgressBar.Style = e.Value;
ProgressStyle = e.Value;
}
}
private void CancelEnabledChanged(object sender, ChangeEventArgs<bool> e)
public void ProgressBarValueChanged(object sender, ChangeEventArgs<int> e)
{
if (this.ButtonCancel.InvokeRequired)
if (this.InvokeRequired)
{
ChangeEventHandler<int> handler = new(ProgressBarValueChanged);
this.Invoke(handler, sender, e);
}
else
{
ProgressValue = e.Value;
}
}
public void CancelEnabledChanged(object sender, ChangeEventArgs<bool> e)
{
if (this.InvokeRequired)
{
ChangeEventHandler<bool> handler = new(CancelEnabledChanged);
this.ButtonCancel.Invoke(handler, sender, e);
this.Invoke(handler, sender, e);
}
else
{
this.ButtonCancel.Enabled = e.Value;
this.ButtonCancel.Visible = e.Value;
this.CancelEnabled = e.Value;
}
}
private void ButtonCancel_Click(object sender, EventArgs e)
public void ButtonCancel_Click(object? sender, EventArgs e)
{
if (Bootstrapper is null)
this.Close();

View File

@ -0,0 +1,27 @@
using Bloxstrap.Helpers.RSMM;
namespace Bloxstrap.Dialogs.BootstrapperStyles
{
interface IBootstrapperStyle
{
Bootstrapper? Bootstrapper { get; set; }
string Message { get; set; }
ProgressBarStyle ProgressStyle { get; set; }
int ProgressValue { get; set; }
bool CancelEnabled { get; set; }
void RunBootstrapper();
void ShowError(string message);
void ShowSuccess(object sender, ChangeEventArgs<string> e);
void CloseDialog(object? sender, EventArgs e);
void PromptShutdown(object? sender, EventArgs e);
void MessageChanged(object sender, ChangeEventArgs<string> e);
void ProgressBarValueChanged(object sender, ChangeEventArgs<int> e);
void ProgressBarStyleChanged(object sender, ChangeEventArgs<ProgressBarStyle> e);
void CancelEnabledChanged(object sender, ChangeEventArgs<bool> e);
void ButtonCancel_Click(object sender, EventArgs e);
}
}

View File

@ -0,0 +1,93 @@
namespace Bloxstrap.Dialogs.BootstrapperStyles
{
partial class LegacyDialog2009
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.labelMessage = new System.Windows.Forms.Label();
this.ProgressBar = new System.Windows.Forms.ProgressBar();
this.buttonCancel = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// labelMessage
//
this.labelMessage.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.labelMessage.Location = new System.Drawing.Point(12, 16);
this.labelMessage.Name = "labelMessage";
this.labelMessage.Size = new System.Drawing.Size(287, 17);
this.labelMessage.TabIndex = 0;
this.labelMessage.Text = "Please wait...";
//
// ProgressBar
//
this.ProgressBar.Location = new System.Drawing.Point(15, 47);
this.ProgressBar.MarqueeAnimationSpeed = 33;
this.ProgressBar.Name = "ProgressBar";
this.ProgressBar.Size = new System.Drawing.Size(281, 20);
this.ProgressBar.Style = System.Windows.Forms.ProgressBarStyle.Marquee;
this.ProgressBar.TabIndex = 1;
//
// buttonCancel
//
this.buttonCancel.Enabled = false;
this.buttonCancel.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.buttonCancel.Location = new System.Drawing.Point(221, 83);
this.buttonCancel.Name = "buttonCancel";
this.buttonCancel.Size = new System.Drawing.Size(75, 23);
this.buttonCancel.TabIndex = 3;
this.buttonCancel.Text = "Cancel";
this.buttonCancel.UseVisualStyleBackColor = true;
this.buttonCancel.Click += new System.EventHandler(this.ButtonCancel_Click);
//
// LegacyDialog2009
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(311, 122);
this.Controls.Add(this.buttonCancel);
this.Controls.Add(this.ProgressBar);
this.Controls.Add(this.labelMessage);
this.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.MaximumSize = new System.Drawing.Size(327, 161);
this.MinimizeBox = false;
this.MinimumSize = new System.Drawing.Size(327, 161);
this.Name = "LegacyDialog2009";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "LegacyDialog2009";
this.ResumeLayout(false);
}
#endregion
private Label labelMessage;
private ProgressBar ProgressBar;
private Button buttonCancel;
}
}

View File

@ -0,0 +1,41 @@
namespace Bloxstrap.Dialogs.BootstrapperStyles
{
// windows: https://youtu.be/VpduiruysuM?t=18
// mac: https://youtu.be/ncHhbcVDRgQ?t=63
public partial class LegacyDialog2009 : BootstrapperStyleForm
{
public override string Message
{
get => labelMessage.Text;
set => labelMessage.Text = value;
}
public override ProgressBarStyle ProgressStyle
{
get => ProgressBar.Style;
set => ProgressBar.Style = value;
}
public override int ProgressValue
{
get => ProgressBar.Value;
set => ProgressBar.Value = value;
}
public override bool CancelEnabled
{
get => this.buttonCancel.Enabled;
set => this.buttonCancel.Enabled = value;
}
public LegacyDialog2009(Bootstrapper? bootstrapper = null)
{
InitializeComponent();
Bootstrapper = bootstrapper;
SetupDialog();
}
}
}

View File

@ -1,6 +1,6 @@
namespace Bloxstrap.Dialogs.BootstrapperStyles
{
partial class LegacyDialog
partial class LegacyDialog2011
{
/// <summary>
/// Required designer variable.
@ -28,20 +28,20 @@
/// </summary>
private void InitializeComponent()
{
this.Message = new System.Windows.Forms.Label();
this.labelMessage = new System.Windows.Forms.Label();
this.ProgressBar = new System.Windows.Forms.ProgressBar();
this.IconBox = new System.Windows.Forms.PictureBox();
this.ButtonCancel = new System.Windows.Forms.Button();
this.buttonCancel = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.IconBox)).BeginInit();
this.SuspendLayout();
//
// Message
// labelMessage
//
this.Message.Location = new System.Drawing.Point(55, 23);
this.Message.Name = "Message";
this.Message.Size = new System.Drawing.Size(287, 17);
this.Message.TabIndex = 0;
this.Message.Text = "Please wait...";
this.labelMessage.Location = new System.Drawing.Point(55, 23);
this.labelMessage.Name = "labelMessage";
this.labelMessage.Size = new System.Drawing.Size(287, 17);
this.labelMessage.TabIndex = 0;
this.labelMessage.Text = "Please wait...";
//
// ProgressBar
//
@ -62,37 +62,37 @@
this.IconBox.TabIndex = 2;
this.IconBox.TabStop = false;
//
// ButtonCancel
// buttonCancel
//
this.ButtonCancel.Enabled = false;
this.ButtonCancel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.ButtonCancel.Location = new System.Drawing.Point(271, 83);
this.ButtonCancel.Name = "ButtonCancel";
this.ButtonCancel.Size = new System.Drawing.Size(75, 23);
this.ButtonCancel.TabIndex = 3;
this.ButtonCancel.Text = "Cancel";
this.ButtonCancel.UseVisualStyleBackColor = true;
this.ButtonCancel.Visible = false;
this.ButtonCancel.Click += new System.EventHandler(this.ButtonCancel_Click);
this.buttonCancel.Enabled = false;
this.buttonCancel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.buttonCancel.Location = new System.Drawing.Point(271, 83);
this.buttonCancel.Name = "buttonCancel";
this.buttonCancel.Size = new System.Drawing.Size(75, 23);
this.buttonCancel.TabIndex = 3;
this.buttonCancel.Text = "Cancel";
this.buttonCancel.UseVisualStyleBackColor = true;
this.buttonCancel.Visible = false;
this.buttonCancel.Click += new System.EventHandler(this.ButtonCancel_Click);
//
// LegacyDialogStyle
// LegacyDialog
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(362, 131);
this.Controls.Add(this.ButtonCancel);
this.Controls.Add(this.buttonCancel);
this.Controls.Add(this.IconBox);
this.Controls.Add(this.ProgressBar);
this.Controls.Add(this.Message);
this.Controls.Add(this.labelMessage);
this.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.MaximumSize = new System.Drawing.Size(378, 170);
this.MinimizeBox = false;
this.MinimumSize = new System.Drawing.Size(378, 170);
this.Name = "LegacyDialogStyle";
this.Name = "LegacyDialog2011";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "LegacyDialogStyle";
this.Text = "LegacyDialog2011";
((System.ComponentModel.ISupportInitialize)(this.IconBox)).EndInit();
this.ResumeLayout(false);
@ -100,9 +100,9 @@
#endregion
private Label Message;
private Label labelMessage;
private ProgressBar ProgressBar;
private PictureBox IconBox;
private Button ButtonCancel;
private Button buttonCancel;
}
}

View File

@ -0,0 +1,45 @@
using Bloxstrap.Helpers;
namespace Bloxstrap.Dialogs.BootstrapperStyles
{
// https://youtu.be/3K9oCEMHj2s?t=35
public partial class LegacyDialog2011 : BootstrapperStyleForm
{
public override string Message
{
get => labelMessage.Text;
set => labelMessage.Text = value;
}
public override ProgressBarStyle ProgressStyle
{
get => ProgressBar.Style;
set => ProgressBar.Style = value;
}
public override int ProgressValue
{
get => ProgressBar.Value;
set => ProgressBar.Value = value;
}
public override bool CancelEnabled
{
get => this.buttonCancel.Enabled;
set => this.buttonCancel.Enabled = this.buttonCancel.Visible = value;
}
public LegacyDialog2011(Bootstrapper? bootstrapper = null)
{
InitializeComponent();
Bootstrapper = bootstrapper;
// have to convert icon -> bitmap since winforms scaling is poop
this.IconBox.Image = IconManager.GetIconResource().ToBitmap();
SetupDialog();
}
}
}

View File

@ -0,0 +1,60 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -29,12 +29,12 @@
private void InitializeComponent()
{
this.ProgressBar = new System.Windows.Forms.ProgressBar();
this.Message = new System.Windows.Forms.Label();
this.labelMessage = new System.Windows.Forms.Label();
this.IconBox = new System.Windows.Forms.PictureBox();
this.ButtonCancel = new System.Windows.Forms.PictureBox();
this.buttonCancel = new System.Windows.Forms.PictureBox();
this.panel1 = new System.Windows.Forms.Panel();
((System.ComponentModel.ISupportInitialize)(this.IconBox)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.ButtonCancel)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.buttonCancel)).BeginInit();
this.panel1.SuspendLayout();
this.SuspendLayout();
//
@ -48,16 +48,16 @@
this.ProgressBar.Style = System.Windows.Forms.ProgressBarStyle.Marquee;
this.ProgressBar.TabIndex = 0;
//
// Message
// labelMessage
//
this.Message.Font = new System.Drawing.Font("Tahoma", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.Message.Location = new System.Drawing.Point(29, 199);
this.Message.Name = "Message";
this.Message.Size = new System.Drawing.Size(460, 18);
this.Message.TabIndex = 1;
this.Message.Text = "Please wait...";
this.Message.TextAlign = System.Drawing.ContentAlignment.TopCenter;
this.Message.UseMnemonic = false;
this.labelMessage.Font = new System.Drawing.Font("Tahoma", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.labelMessage.Location = new System.Drawing.Point(29, 199);
this.labelMessage.Name = "labelMessage";
this.labelMessage.Size = new System.Drawing.Size(460, 18);
this.labelMessage.TabIndex = 1;
this.labelMessage.Text = "Please wait...";
this.labelMessage.TextAlign = System.Drawing.ContentAlignment.TopCenter;
this.labelMessage.UseMnemonic = false;
//
// IconBox
//
@ -69,33 +69,33 @@
this.IconBox.TabIndex = 2;
this.IconBox.TabStop = false;
//
// ButtonCancel
// buttonCancel
//
this.ButtonCancel.Enabled = false;
this.ButtonCancel.Image = global::Bloxstrap.Properties.Resources.CancelButton;
this.ButtonCancel.Location = new System.Drawing.Point(194, 264);
this.ButtonCancel.Name = "ButtonCancel";
this.ButtonCancel.Size = new System.Drawing.Size(130, 44);
this.ButtonCancel.TabIndex = 3;
this.ButtonCancel.TabStop = false;
this.ButtonCancel.Visible = false;
this.ButtonCancel.Click += new System.EventHandler(this.ButtonCancel_Click);
this.ButtonCancel.MouseEnter += new System.EventHandler(this.ButtonCancel_MouseEnter);
this.ButtonCancel.MouseLeave += new System.EventHandler(this.ButtonCancel_MouseLeave);
this.buttonCancel.Enabled = false;
this.buttonCancel.Image = global::Bloxstrap.Properties.Resources.CancelButton;
this.buttonCancel.Location = new System.Drawing.Point(194, 264);
this.buttonCancel.Name = "buttonCancel";
this.buttonCancel.Size = new System.Drawing.Size(130, 44);
this.buttonCancel.TabIndex = 3;
this.buttonCancel.TabStop = false;
this.buttonCancel.Visible = false;
this.buttonCancel.Click += new System.EventHandler(this.ButtonCancel_Click);
this.buttonCancel.MouseEnter += new System.EventHandler(this.ButtonCancel_MouseEnter);
this.buttonCancel.MouseLeave += new System.EventHandler(this.ButtonCancel_MouseLeave);
//
// panel1
//
this.panel1.BackColor = System.Drawing.SystemColors.Window;
this.panel1.Controls.Add(this.Message);
this.panel1.Controls.Add(this.labelMessage);
this.panel1.Controls.Add(this.IconBox);
this.panel1.Controls.Add(this.ButtonCancel);
this.panel1.Controls.Add(this.buttonCancel);
this.panel1.Controls.Add(this.ProgressBar);
this.panel1.Location = new System.Drawing.Point(1, 1);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(518, 318);
this.panel1.TabIndex = 4;
//
// ProgressDialogStyle
// ProgressDialog
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
@ -105,11 +105,11 @@
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.MaximumSize = new System.Drawing.Size(520, 320);
this.MinimumSize = new System.Drawing.Size(520, 320);
this.Name = "ProgressDialogStyle";
this.Name = "ProgressDialog";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "ProgressDialogStyle";
this.Text = "ProgressDialog";
((System.ComponentModel.ISupportInitialize)(this.IconBox)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.ButtonCancel)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.buttonCancel)).EndInit();
this.panel1.ResumeLayout(false);
this.ResumeLayout(false);
@ -118,9 +118,9 @@
#endregion
private ProgressBar ProgressBar;
private Label Message;
private Label labelMessage;
private PictureBox IconBox;
private PictureBox ButtonCancel;
private PictureBox buttonCancel;
private Panel panel1;
}
}

View File

@ -1,15 +1,34 @@
using System.Diagnostics;
using Bloxstrap.Helpers;
using Bloxstrap.Helpers.RSMM;
using Bloxstrap.Helpers;
namespace Bloxstrap.Dialogs.BootstrapperStyles
{
// TODO - universal implementation for winforms-based styles? (to reduce duplicate code)
// basically just the modern dialog
public partial class ProgressDialog : Form
public partial class ProgressDialog : BootstrapperStyleForm
{
private readonly Bootstrapper? Bootstrapper;
public override string Message
{
get => labelMessage.Text;
set => labelMessage.Text = value;
}
public override ProgressBarStyle ProgressStyle
{
get => ProgressBar.Style;
set => ProgressBar.Style = value;
}
public override int ProgressValue
{
get => ProgressBar.Value;
set => ProgressBar.Value = value;
}
public override bool CancelEnabled
{
get => this.buttonCancel.Enabled;
set => this.buttonCancel.Enabled = this.buttonCancel.Visible = value;
}
public ProgressDialog(Bootstrapper? bootstrapper = null)
{
@ -17,156 +36,19 @@ namespace Bloxstrap.Dialogs.BootstrapperStyles
Bootstrapper = bootstrapper;
this.Text = Program.ProjectName;
this.Icon = IconManager.GetIconResource();
this.IconBox.BackgroundImage = IconManager.GetBitmapResource();
if (Bootstrapper is null)
{
this.Message.Text = "Click the Cancel button to return to preferences";
this.ButtonCancel.Enabled = true;
this.ButtonCancel.Visible = true;
}
else
{
Bootstrapper.CloseDialogEvent += new EventHandler(CloseDialog);
Bootstrapper.PromptShutdownEvent += new EventHandler(PromptShutdown);
Bootstrapper.ShowSuccessEvent += new ChangeEventHandler<string>(ShowSuccess);
Bootstrapper.MessageChanged += new ChangeEventHandler<string>(MessageChanged);
Bootstrapper.ProgressBarValueChanged += new ChangeEventHandler<int>(ProgressBarValueChanged);
Bootstrapper.ProgressBarStyleChanged += new ChangeEventHandler<ProgressBarStyle>(ProgressBarStyleChanged);
Bootstrapper.CancelEnabledChanged += new ChangeEventHandler<bool>(CancelEnabledChanged);
Task.Run(() => RunBootstrapper());
}
}
public async void RunBootstrapper()
{
if (Bootstrapper is null)
return;
try
{
await Bootstrapper.Run();
}
catch (Exception ex)
{
// string message = String.Format("{0}: {1}", ex.GetType(), ex.Message);
string message = ex.ToString();
ShowError(message);
Program.Exit();
}
}
private void ShowError(string message)
{
MessageBox.Show(
$"An error occurred while starting Roblox\n\nDetails: {message}",
Program.ProjectName,
MessageBoxButtons.OK,
MessageBoxIcon.Error
);
}
private void ShowSuccess(object sender, ChangeEventArgs<string> e)
{
MessageBox.Show(
e.Value,
Program.ProjectName,
MessageBoxButtons.OK,
MessageBoxIcon.Information
);
}
private void CloseDialog(object? sender, EventArgs e)
{
this.Hide();
}
private void PromptShutdown(object? sender, EventArgs e)
{
DialogResult result = MessageBox.Show(
"Roblox is currently running, but needs to close. Would you like close Roblox now?",
Program.ProjectName,
MessageBoxButtons.OKCancel,
MessageBoxIcon.Information
);
if (result != DialogResult.OK)
Environment.Exit(0);
}
private void MessageChanged(object sender, ChangeEventArgs<string> e)
{
if (this.InvokeRequired)
{
ChangeEventHandler<string> handler = new(MessageChanged);
this.Message.Invoke(handler, sender, e);
}
else
{
this.Message.Text = e.Value;
}
}
private void ProgressBarValueChanged(object sender, ChangeEventArgs<int> e)
{
if (this.ProgressBar.InvokeRequired)
{
ChangeEventHandler<int> handler = new(ProgressBarValueChanged);
this.ProgressBar.Invoke(handler, sender, e);
}
else
{
this.ProgressBar.Value = e.Value;
}
}
private void ProgressBarStyleChanged(object sender, ChangeEventArgs<ProgressBarStyle> e)
{
if (this.ProgressBar.InvokeRequired)
{
ChangeEventHandler<ProgressBarStyle> handler = new(ProgressBarStyleChanged);
this.ProgressBar.Invoke(handler, sender, e);
}
else
{
this.ProgressBar.Style = e.Value;
}
}
private void CancelEnabledChanged(object sender, ChangeEventArgs<bool> e)
{
if (this.ButtonCancel.InvokeRequired)
{
ChangeEventHandler<bool> handler = new(CancelEnabledChanged);
this.ButtonCancel.Invoke(handler, sender, e);
}
else
{
this.ButtonCancel.Enabled = e.Value;
this.ButtonCancel.Visible = e.Value;
}
}
private void ButtonCancel_Click(object sender, EventArgs e)
{
if (Bootstrapper is null)
this.Close();
else
Task.Run(() => Bootstrapper.CancelButtonClicked());
SetupDialog();
}
private void ButtonCancel_MouseEnter(object sender, EventArgs e)
{
this.ButtonCancel.Image = Properties.Resources.CancelButtonHover;
this.buttonCancel.Image = Properties.Resources.CancelButtonHover;
}
private void ButtonCancel_MouseLeave(object sender, EventArgs e)
{
this.ButtonCancel.Image = Properties.Resources.CancelButton;
this.buttonCancel.Image = Properties.Resources.CancelButton;
}
}
}

View File

@ -0,0 +1,127 @@
namespace Bloxstrap.Dialogs.BootstrapperStyles
{
partial class ProgressDialogDark
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.ProgressBar = new System.Windows.Forms.ProgressBar();
this.labelMessage = new System.Windows.Forms.Label();
this.IconBox = new System.Windows.Forms.PictureBox();
this.buttonCancel = new System.Windows.Forms.PictureBox();
this.panel1 = new System.Windows.Forms.Panel();
((System.ComponentModel.ISupportInitialize)(this.IconBox)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.buttonCancel)).BeginInit();
this.panel1.SuspendLayout();
this.SuspendLayout();
//
// ProgressBar
//
this.ProgressBar.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.ProgressBar.Location = new System.Drawing.Point(29, 241);
this.ProgressBar.MarqueeAnimationSpeed = 20;
this.ProgressBar.Name = "ProgressBar";
this.ProgressBar.Size = new System.Drawing.Size(460, 20);
this.ProgressBar.Style = System.Windows.Forms.ProgressBarStyle.Marquee;
this.ProgressBar.TabIndex = 0;
//
// labelMessage
//
this.labelMessage.Font = new System.Drawing.Font("Tahoma", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.labelMessage.ForeColor = System.Drawing.SystemColors.Window;
this.labelMessage.Location = new System.Drawing.Point(29, 199);
this.labelMessage.Name = "labelMessage";
this.labelMessage.Size = new System.Drawing.Size(460, 18);
this.labelMessage.TabIndex = 1;
this.labelMessage.Text = "Please wait...";
this.labelMessage.TextAlign = System.Drawing.ContentAlignment.TopCenter;
this.labelMessage.UseMnemonic = false;
//
// IconBox
//
this.IconBox.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
this.IconBox.ImageLocation = "";
this.IconBox.Location = new System.Drawing.Point(212, 66);
this.IconBox.Name = "IconBox";
this.IconBox.Size = new System.Drawing.Size(92, 92);
this.IconBox.TabIndex = 2;
this.IconBox.TabStop = false;
//
// buttonCancel
//
this.buttonCancel.Enabled = false;
this.buttonCancel.Image = global::Bloxstrap.Properties.Resources.DarkCancelButton;
this.buttonCancel.Location = new System.Drawing.Point(194, 264);
this.buttonCancel.Name = "buttonCancel";
this.buttonCancel.Size = new System.Drawing.Size(130, 44);
this.buttonCancel.TabIndex = 3;
this.buttonCancel.TabStop = false;
this.buttonCancel.Visible = false;
this.buttonCancel.Click += new System.EventHandler(this.ButtonCancel_Click);
this.buttonCancel.MouseEnter += new System.EventHandler(this.ButtonCancel_MouseEnter);
this.buttonCancel.MouseLeave += new System.EventHandler(this.ButtonCancel_MouseLeave);
//
// panel1
//
this.panel1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(35)))), ((int)(((byte)(37)))), ((int)(((byte)(39)))));
this.panel1.Controls.Add(this.labelMessage);
this.panel1.Controls.Add(this.IconBox);
this.panel1.Controls.Add(this.buttonCancel);
this.panel1.Controls.Add(this.ProgressBar);
this.panel1.Location = new System.Drawing.Point(1, 1);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(518, 318);
this.panel1.TabIndex = 4;
//
// ProgressDialogDark
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(25)))), ((int)(((byte)(27)))), ((int)(((byte)(29)))));
this.ClientSize = new System.Drawing.Size(520, 320);
this.Controls.Add(this.panel1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.MaximumSize = new System.Drawing.Size(520, 320);
this.MinimumSize = new System.Drawing.Size(520, 320);
this.Name = "ProgressDialogDark";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "ProgressDialog";
((System.ComponentModel.ISupportInitialize)(this.IconBox)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.buttonCancel)).EndInit();
this.panel1.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private ProgressBar ProgressBar;
private Label labelMessage;
private PictureBox IconBox;
private PictureBox buttonCancel;
private Panel panel1;
}
}

View File

@ -0,0 +1,54 @@
using Bloxstrap.Helpers;
namespace Bloxstrap.Dialogs.BootstrapperStyles
{
// basically just the modern dialog
public partial class ProgressDialogDark : BootstrapperStyleForm
{
public override string Message
{
get => labelMessage.Text;
set => labelMessage.Text = value;
}
public override ProgressBarStyle ProgressStyle
{
get => ProgressBar.Style;
set => ProgressBar.Style = value;
}
public override int ProgressValue
{
get => ProgressBar.Value;
set => ProgressBar.Value = value;
}
public override bool CancelEnabled
{
get => this.buttonCancel.Enabled;
set => this.buttonCancel.Enabled = this.buttonCancel.Visible = value;
}
public ProgressDialogDark(Bootstrapper? bootstrapper = null)
{
InitializeComponent();
Bootstrapper = bootstrapper;
this.IconBox.BackgroundImage = IconManager.GetBitmapResource();
SetupDialog();
}
private void ButtonCancel_MouseEnter(object sender, EventArgs e)
{
this.buttonCancel.Image = Properties.Resources.DarkCancelButtonHover;
}
private void ButtonCancel_MouseLeave(object sender, EventArgs e)
{
this.buttonCancel.Image = Properties.Resources.DarkCancelButton;
}
}
}

View File

@ -0,0 +1,60 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,49 @@
namespace Bloxstrap.Dialogs.BootstrapperStyles
{
partial class VistaDialog
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout();
//
// TestDialog
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(0, 0);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Name = "VistaDialog";
this.ShowInTaskbar = false;
this.Text = "VistaDialog";
this.Load += new System.EventHandler(this.TestDialog_Load);
this.ResumeLayout(false);
}
#endregion
}
}

View File

@ -3,34 +3,71 @@ using Bloxstrap.Helpers.RSMM;
namespace Bloxstrap.Dialogs.BootstrapperStyles
{
// example: https://youtu.be/h0_AL95Sc3o?t=48
// https://youtu.be/h0_AL95Sc3o?t=48
// this currently doesn't work because c# is stupid
// technically, task dialogs are treated as winforms controls, but they don't classify as winforms controls at all
// all winforms controls have the ability to be invoked from another thread, but task dialogs don't
// so we're just kind of stuck with this not working in multithreaded use
// (unless we want the bootstrapper to freeze during package extraction)
// a bit hacky, but this is actually a hidden form
// since taskdialog is part of winforms, it can't really be properly used without a form
// for example, cross-threaded calls to ui controls can't really be done outside of a form
// for now, just stick to legacydialog and progressdialog
public class VistaDialog
public partial class VistaDialog : BootstrapperStyleForm
{
private readonly Bootstrapper Bootstrapper;
private TaskDialogPage Dialog;
public VistaDialog(Bootstrapper bootstrapper)
public override string Message
{
get => Dialog.Heading ?? "";
set => Dialog.Heading = value;
}
public override ProgressBarStyle ProgressStyle
{
set
{
if (Dialog.ProgressBar is null)
return;
switch (value)
{
case ProgressBarStyle.Continuous:
case ProgressBarStyle.Blocks:
Dialog.ProgressBar.State = TaskDialogProgressBarState.Normal;
break;
case ProgressBarStyle.Marquee:
Dialog.ProgressBar.State = TaskDialogProgressBarState.Marquee;
break;
}
}
}
public override int ProgressValue
{
get => Dialog.ProgressBar is null ? 0 : Dialog.ProgressBar.Value;
set
{
if (Dialog.ProgressBar is null)
return;
Dialog.ProgressBar.Value = value;
}
}
public override bool CancelEnabled
{
get => Dialog.Buttons[0].Enabled;
set => Dialog.Buttons[0].Enabled = value;
}
public VistaDialog(Bootstrapper? bootstrapper = null)
{
InitializeComponent();
Bootstrapper = bootstrapper;
Bootstrapper.ShowSuccessEvent += new ChangeEventHandler<string>(ShowSuccess);
Bootstrapper.MessageChanged += new ChangeEventHandler<string>(MessageChanged);
Bootstrapper.ProgressBarValueChanged += new ChangeEventHandler<int>(ProgressBarValueChanged);
Bootstrapper.ProgressBarStyleChanged += new ChangeEventHandler<ProgressBarStyle>(ProgressBarStyleChanged);
Dialog = new TaskDialogPage()
{
Icon = new TaskDialogIcon(IconManager.GetIconResource()),
Caption = Program.ProjectName,
Heading = "Please wait...",
Buttons = { TaskDialogButton.Cancel },
ProgressBar = new TaskDialogProgressBar()
@ -39,92 +76,95 @@ namespace Bloxstrap.Dialogs.BootstrapperStyles
}
};
Task.Run(() => RunBootstrapper());
TaskDialog.ShowDialog(Dialog);
Message = "Please wait...";
CancelEnabled = false;
Dialog.Buttons[0].Click += (sender, e) => ButtonCancel_Click(sender, e);
SetupDialog();
}
public async void RunBootstrapper()
public override void ShowSuccess(object sender, ChangeEventArgs<string> e)
{
try
if (this.InvokeRequired)
{
await Bootstrapper.Run();
ChangeEventHandler<string> handler = new(ShowSuccess);
this.Invoke(handler, sender, e);
}
catch (Exception ex)
else
{
// string message = String.Format("{0}: {1}", ex.GetType(), ex.Message);
string message = ex.ToString();
ShowError(message);
Program.Exit();
}
}
public void ShowError(string message)
{
TaskDialogPage errorDialog = new()
{
Icon = TaskDialogIcon.Error,
Caption = Program.ProjectName,
Heading = "An error occurred while starting Roblox",
Buttons = { TaskDialogButton.Close },
Expander = new TaskDialogExpander()
TaskDialogPage successDialog = new()
{
Text = message,
CollapsedButtonText = "See details",
ExpandedButtonText = "Hide details",
Position = TaskDialogExpanderPosition.AfterText
}
};
Icon = TaskDialogIcon.ShieldSuccessGreenBar,
Caption = Program.ProjectName,
Heading = e.Value,
Buttons = { TaskDialogButton.OK }
};
Dialog.Navigate(errorDialog);
Dialog = errorDialog;
}
successDialog.Buttons[0].Click += (sender, e) => Program.Exit();
public void ShowSuccess(object sender, ChangeEventArgs<string> e)
{
TaskDialogPage successDialog = new()
{
Icon = TaskDialogIcon.ShieldSuccessGreenBar,
Caption = Program.ProjectName,
Heading = e.Value
};
Dialog.Navigate(successDialog);
Dialog = successDialog;
}
private void MessageChanged(object sender, ChangeEventArgs<string> e)
{
if (Dialog is null)
return;
Dialog.Heading = e.Value;
}
private void ProgressBarValueChanged(object sender, ChangeEventArgs<int> e)
{
if (Dialog is null || Dialog.ProgressBar is null)
return;
Dialog.ProgressBar.Value = e.Value;
}
private void ProgressBarStyleChanged(object sender, ChangeEventArgs<ProgressBarStyle> e)
{
if (Dialog is null || Dialog.ProgressBar is null)
return;
switch (e.Value)
{
case ProgressBarStyle.Continuous:
case ProgressBarStyle.Blocks:
Dialog.ProgressBar.State = TaskDialogProgressBarState.Normal;
break;
case ProgressBarStyle.Marquee:
Dialog.ProgressBar.State = TaskDialogProgressBarState.Marquee;
break;
Dialog.Navigate(successDialog);
Dialog = successDialog;
}
}
private void InvokeShowError(object sender, ChangeEventArgs<string> e)
{
ShowError(e.Value);
}
public override void ShowError(string message)
{
if (this.InvokeRequired)
{
ChangeEventHandler<string> handler = new(InvokeShowError);
this.Invoke(handler, this, new ChangeEventArgs<string>(message));
}
else
{
TaskDialogPage errorDialog = new()
{
Icon = TaskDialogIcon.Error,
Caption = Program.ProjectName,
Heading = "An error occurred while starting Roblox",
Buttons = { TaskDialogButton.Close },
Expander = new TaskDialogExpander()
{
Text = message,
CollapsedButtonText = "See details",
ExpandedButtonText = "Hide details",
Position = TaskDialogExpanderPosition.AfterText
}
};
errorDialog.Buttons[0].Click += (sender, e) => Program.Exit();
Dialog.Navigate(errorDialog);
Dialog = errorDialog;
}
}
public override void CloseDialog(object? sender, EventArgs e)
{
if (this.InvokeRequired)
{
EventHandler handler = new(CloseDialog);
this.Invoke(handler, sender, e);
}
else
{
if (Dialog.BoundDialog is null)
return;
Dialog.BoundDialog.Close();
}
}
private void TestDialog_Load(object sender, EventArgs e)
{
this.Hide();
TaskDialog.ShowDialog(Dialog);
}
}
}

View File

@ -0,0 +1,60 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -33,6 +33,7 @@
this.Tabs = new System.Windows.Forms.TabControl();
this.DialogTab = new System.Windows.Forms.TabPage();
this.groupBox5 = new System.Windows.Forms.GroupBox();
this.ToggleRPCButtons = new System.Windows.Forms.CheckBox();
this.ToggleDiscordRichPresence = new System.Windows.Forms.CheckBox();
this.groupBox3 = new System.Windows.Forms.GroupBox();
this.IconPreview = new System.Windows.Forms.PictureBox();
@ -41,6 +42,7 @@
this.StyleSelection = new System.Windows.Forms.ListBox();
this.InstallationTab = new System.Windows.Forms.TabPage();
this.groupBox4 = new System.Windows.Forms.GroupBox();
this.ToggleMouseCursor = new System.Windows.Forms.CheckBox();
this.ToggleDeathSound = new System.Windows.Forms.CheckBox();
this.GroupBoxInstallLocation = new System.Windows.Forms.GroupBox();
this.InstallLocationBrowseButton = new System.Windows.Forms.Button();
@ -79,7 +81,7 @@
this.Tabs.Location = new System.Drawing.Point(12, 40);
this.Tabs.Name = "Tabs";
this.Tabs.SelectedIndex = 0;
this.Tabs.Size = new System.Drawing.Size(442, 226);
this.Tabs.Size = new System.Drawing.Size(442, 247);
this.Tabs.TabIndex = 2;
//
// DialogTab
@ -90,20 +92,32 @@
this.DialogTab.Location = new System.Drawing.Point(4, 24);
this.DialogTab.Name = "DialogTab";
this.DialogTab.Padding = new System.Windows.Forms.Padding(3);
this.DialogTab.Size = new System.Drawing.Size(434, 198);
this.DialogTab.Size = new System.Drawing.Size(434, 219);
this.DialogTab.TabIndex = 0;
this.DialogTab.Text = "Bootstrapper";
this.DialogTab.UseVisualStyleBackColor = true;
//
// groupBox5
//
this.groupBox5.Controls.Add(this.ToggleRPCButtons);
this.groupBox5.Controls.Add(this.ToggleDiscordRichPresence);
this.groupBox5.Location = new System.Drawing.Point(5, 146);
this.groupBox5.Name = "groupBox5";
this.groupBox5.Size = new System.Drawing.Size(422, 46);
this.groupBox5.Size = new System.Drawing.Size(422, 67);
this.groupBox5.TabIndex = 7;
this.groupBox5.TabStop = false;
this.groupBox5.Text = "Launch";
this.groupBox5.Text = "Discord Rich Presence";
//
// ToggleRPCButtons
//
this.ToggleRPCButtons.AutoSize = true;
this.ToggleRPCButtons.Location = new System.Drawing.Point(9, 40);
this.ToggleRPCButtons.Name = "ToggleRPCButtons";
this.ToggleRPCButtons.Size = new System.Drawing.Size(196, 19);
this.ToggleRPCButtons.TabIndex = 1;
this.ToggleRPCButtons.Text = "Hide activity interaction buttons";
this.ToggleRPCButtons.UseVisualStyleBackColor = true;
this.ToggleRPCButtons.CheckedChanged += new System.EventHandler(this.ToggleRPCButtons_CheckedChanged);
//
// ToggleDiscordRichPresence
//
@ -112,9 +126,9 @@
this.ToggleDiscordRichPresence.CheckState = System.Windows.Forms.CheckState.Checked;
this.ToggleDiscordRichPresence.Location = new System.Drawing.Point(9, 19);
this.ToggleDiscordRichPresence.Name = "ToggleDiscordRichPresence";
this.ToggleDiscordRichPresence.Size = new System.Drawing.Size(274, 19);
this.ToggleDiscordRichPresence.Size = new System.Drawing.Size(129, 19);
this.ToggleDiscordRichPresence.TabIndex = 0;
this.ToggleDiscordRichPresence.Text = "Show game activity with Discord Rich Presence";
this.ToggleDiscordRichPresence.Text = "Show game activity";
this.ToggleDiscordRichPresence.UseVisualStyleBackColor = true;
this.ToggleDiscordRichPresence.CheckedChanged += new System.EventHandler(this.ToggleDiscordRichPresence_CheckedChanged);
//
@ -176,21 +190,34 @@
this.InstallationTab.Location = new System.Drawing.Point(4, 24);
this.InstallationTab.Name = "InstallationTab";
this.InstallationTab.Padding = new System.Windows.Forms.Padding(3);
this.InstallationTab.Size = new System.Drawing.Size(434, 198);
this.InstallationTab.Size = new System.Drawing.Size(434, 219);
this.InstallationTab.TabIndex = 2;
this.InstallationTab.Text = "Installation";
this.InstallationTab.UseVisualStyleBackColor = true;
//
// groupBox4
//
this.groupBox4.Controls.Add(this.ToggleMouseCursor);
this.groupBox4.Controls.Add(this.ToggleDeathSound);
this.groupBox4.Location = new System.Drawing.Point(5, 60);
this.groupBox4.Name = "groupBox4";
this.groupBox4.Size = new System.Drawing.Size(422, 46);
this.groupBox4.Size = new System.Drawing.Size(422, 65);
this.groupBox4.TabIndex = 2;
this.groupBox4.TabStop = false;
this.groupBox4.Text = "Modifications";
//
// ToggleMouseCursor
//
this.ToggleMouseCursor.AutoSize = true;
this.ToggleMouseCursor.Location = new System.Drawing.Point(9, 40);
this.ToggleMouseCursor.Margin = new System.Windows.Forms.Padding(2);
this.ToggleMouseCursor.Name = "ToggleMouseCursor";
this.ToggleMouseCursor.Size = new System.Drawing.Size(140, 19);
this.ToggleMouseCursor.TabIndex = 2;
this.ToggleMouseCursor.Text = "Use old mouse cursor";
this.ToggleMouseCursor.UseVisualStyleBackColor = true;
this.ToggleMouseCursor.CheckedChanged += new System.EventHandler(this.ToggleMouseCursor_CheckedChanged);
//
// ToggleDeathSound
//
this.ToggleDeathSound.AutoSize = true;
@ -214,7 +241,7 @@
this.GroupBoxInstallLocation.Size = new System.Drawing.Size(422, 54);
this.GroupBoxInstallLocation.TabIndex = 0;
this.GroupBoxInstallLocation.TabStop = false;
this.GroupBoxInstallLocation.Text = "Install Location";
this.GroupBoxInstallLocation.Text = "Location";
//
// InstallLocationBrowseButton
//
@ -252,10 +279,9 @@
this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panel1.BackColor = System.Drawing.SystemColors.Control;
this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.panel1.Controls.Add(this.PreviewButton);
this.panel1.Controls.Add(this.SaveButton);
this.panel1.Location = new System.Drawing.Point(-1, 277);
this.panel1.Location = new System.Drawing.Point(-1, 298);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(466, 42);
this.panel1.TabIndex = 6;
@ -282,7 +308,7 @@
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.SystemColors.Window;
this.ClientSize = new System.Drawing.Size(464, 318);
this.ClientSize = new System.Drawing.Size(464, 339);
this.Controls.Add(this.panel1);
this.Controls.Add(this.Tabs);
this.Controls.Add(this.label1);
@ -332,5 +358,7 @@
private GroupBox groupBox5;
private CheckBox ToggleDiscordRichPresence;
private ToolTip InfoTooltip;
private CheckBox ToggleMouseCursor;
private CheckBox ToggleRPCButtons;
}
}

View File

@ -10,8 +10,11 @@ namespace Bloxstrap.Dialogs
{
private static readonly IReadOnlyDictionary<string, BootstrapperStyle> SelectableStyles = new Dictionary<string, BootstrapperStyle>()
{
{ "Legacy (2011 - 2014)", BootstrapperStyle.LegacyDialog },
{ "Vista (2009 - 2011)", BootstrapperStyle.VistaDialog },
{ "Legacy (2009 - 2011)", BootstrapperStyle.LegacyDialog2009 },
{ "Legacy (2011 - 2014)", BootstrapperStyle.LegacyDialog2011 },
{ "Progress (~2014)", BootstrapperStyle.ProgressDialog },
{ "Progress (Dark)", BootstrapperStyle.ProgressDialogDark },
};
private static readonly IReadOnlyDictionary<string, BootstrapperIcon> SelectableIcons = new Dictionary<string, BootstrapperIcon>()
@ -28,7 +31,9 @@ namespace Bloxstrap.Dialogs
private BootstrapperStyle? _selectedStyle;
private BootstrapperIcon? _selectedIcon;
private bool _useDiscordRichPresence = true;
private bool _hideRPCButtons = false;
private bool _useOldDeathSound = true;
private bool _useOldMouseCursor = false;
private BootstrapperStyle SelectedStyle
{
@ -75,6 +80,22 @@ namespace Bloxstrap.Dialogs
_useDiscordRichPresence = value;
this.ToggleDiscordRichPresence.Checked = value;
this.ToggleRPCButtons.Enabled = value;
}
}
private bool HideRPCButtons
{
get => _hideRPCButtons;
set
{
if (_hideRPCButtons == value)
return;
_hideRPCButtons = value;
this.ToggleRPCButtons.Checked = value;
}
}
@ -93,6 +114,21 @@ namespace Bloxstrap.Dialogs
}
}
private bool UseOldMouseCursor
{
get => _useOldMouseCursor;
set
{
if (_useOldMouseCursor == value)
return;
_useOldMouseCursor = value;
this.ToggleMouseCursor.Checked = value;
}
}
public Preferences()
{
InitializeComponent();
@ -122,15 +158,18 @@ namespace Bloxstrap.Dialogs
this.IconSelection.Items.Add(icon.Key);
}
this.InfoTooltip.SetToolTip(this.StyleSelection, "Choose how the bootstrapper dialog should look.");
this.InfoTooltip.SetToolTip(this.StyleSelection, "Choose how the bootstrapper dialog should look.\nYou can use the 'Preview' button to preview the bootstrapper look.");
this.InfoTooltip.SetToolTip(this.IconSelection, "Choose what icon the bootstrapper should use.");
this.InfoTooltip.SetToolTip(this.GroupBoxInstallLocation, "Choose where Bloxstrap should install to.\nThis is useful if you typically install all your games to a separate storage drive.");
this.InfoTooltip.SetToolTip(this.ToggleDiscordRichPresence, "Choose whether to show what game you're playing on your Discord profile.\nThis will ONLY work when you launch a game from the website, and is not supported in the Beta App.");
this.InfoTooltip.SetToolTip(this.ToggleDiscordRichPresence, "Choose whether to show what game you're playing on your Discord activity status.\nThis will only work when you launch a game from the website, and is not supported in the Beta App.");
this.InfoTooltip.SetToolTip(this.ToggleRPCButtons, "Choose whether the buttons to play/view game info should be hidden from activity status.");
SelectedStyle = Program.Settings.BootstrapperStyle;
SelectedIcon = Program.Settings.BootstrapperIcon;
UseDiscordRichPresence = Program.Settings.UseDiscordRichPresence;
HideRPCButtons = Program.Settings.HideRPCButtons;
UseOldDeathSound = Program.Settings.UseOldDeathSound;
UseOldMouseCursor = Program.Settings.UseOldMouseCursor;
}
private void InstallLocationBrowseButton_Click(object sender, EventArgs e)
@ -196,32 +235,37 @@ namespace Bloxstrap.Dialogs
// this will be set in the registry after first install
Program.BaseDirectory = installLocation;
}
else if (Program.BaseDirectory != installLocation)
else
{
Program.ShowMessageBox(MessageBoxIcon.Information, $"{Program.ProjectName} will install to the new location you've set the next time it runs.");
Program.Settings.VersionGuid = "";
using (RegistryKey registryKey = Registry.CurrentUser.CreateSubKey($@"Software\{Program.ProjectName}"))
{
registryKey.SetValue("InstallLocation", installLocation);
registryKey.SetValue("OldInstallLocation", Program.BaseDirectory);
}
// preserve settings
// we don't need to copy the bootstrapper over since the install process will do that automatically
Program.SettingsManager.Save();
File.Copy(Path.Combine(Program.BaseDirectory, "Settings.json"), Path.Combine(installLocation, "Settings.json"));
}
if (!Program.IsFirstRun)
Program.SettingsManager.ShouldSave = true;
if (Program.BaseDirectory != installLocation)
{
Program.ShowMessageBox(MessageBoxIcon.Information, $"{Program.ProjectName} will install to the new location you've set the next time it runs.");
Program.Settings.VersionGuid = "";
using (RegistryKey registryKey = Registry.CurrentUser.CreateSubKey($@"Software\{Program.ProjectName}"))
{
registryKey.SetValue("InstallLocation", installLocation);
registryKey.SetValue("OldInstallLocation", Program.BaseDirectory);
}
// preserve settings
// we don't need to copy the bootstrapper over since the install process will do that automatically
Program.SettingsManager.Save();
File.Copy(Path.Combine(Program.BaseDirectory, "Settings.json"), Path.Combine(installLocation, "Settings.json"));
}
}
Program.Settings.BootstrapperStyle = SelectedStyle;
Program.Settings.BootstrapperIcon = SelectedIcon;
Program.Settings.UseDiscordRichPresence = UseDiscordRichPresence;
Program.Settings.HideRPCButtons = HideRPCButtons;
Program.Settings.UseOldDeathSound = UseOldDeathSound;
Program.Settings.UseOldMouseCursor = UseOldMouseCursor;
this.Close();
}
@ -236,13 +280,25 @@ namespace Bloxstrap.Dialogs
switch (SelectedStyle)
{
case BootstrapperStyle.LegacyDialog:
new LegacyDialog().ShowDialog();
case BootstrapperStyle.VistaDialog:
new VistaDialog().ShowDialog();
break;
case BootstrapperStyle.LegacyDialog2009:
new LegacyDialog2009().ShowDialog();
break;
case BootstrapperStyle.LegacyDialog2011:
new LegacyDialog2011().ShowDialog();
break;
case BootstrapperStyle.ProgressDialog:
new ProgressDialog().ShowDialog();
break;
case BootstrapperStyle.ProgressDialogDark:
new ProgressDialogDark().ShowDialog();
break;
}
Program.Settings.BootstrapperIcon = savedIcon;
@ -255,9 +311,19 @@ namespace Bloxstrap.Dialogs
UseDiscordRichPresence = this.ToggleDiscordRichPresence.Checked;
}
private void ToggleRPCButtons_CheckedChanged(object sender, EventArgs e)
{
HideRPCButtons = this.ToggleRPCButtons.Checked;
}
private void ToggleDeathSound_CheckedChanged(object sender, EventArgs e)
{
UseOldDeathSound = this.ToggleDeathSound.Checked;
}
private void ToggleMouseCursor_CheckedChanged(object sender, EventArgs e)
{
UseOldMouseCursor = this.ToggleMouseCursor.Checked;
}
}
}

View File

@ -3,7 +3,9 @@
public enum BootstrapperStyle
{
VistaDialog,
LegacyDialog,
ProgressDialog
LegacyDialog2009,
LegacyDialog2011,
ProgressDialog,
ProgressDialogDark,
}
}

View File

@ -30,6 +30,26 @@ namespace Bloxstrap.Helpers
placeThumbnail = thumbnailInfo["data"][0]["imageUrl"].Value<string>();
}
DiscordRPC.Button[]? buttons = null;
if (!Program.Settings.HideRPCButtons)
{
buttons = new DiscordRPC.Button[]
{
new DiscordRPC.Button()
{
Label = "Play",
Url = $"https://www.roblox.com/games/start?placeId={placeId}&launchData=%7B%7D"
},
new DiscordRPC.Button()
{
Label = "View Details",
Url = $"https://www.roblox.com/games/{placeId}"
}
};
}
RichPresence.Initialize();
RichPresence.SetPresence(new RichPresence()
@ -46,20 +66,7 @@ namespace Bloxstrap.Helpers
SmallImageText = "Rich Presence provided by Bloxstrap"
},
Buttons = new DiscordRPC.Button[]
{
new DiscordRPC.Button()
{
Label = "Play",
Url = $"https://www.roblox.com/games/start?placeId={placeId}&launchData=%7B%7D"
},
new DiscordRPC.Button()
{
Label = "View Details",
Url = $"https://www.roblox.com/games/{placeId}"
}
}
Buttons = buttons
});
return true;

View File

@ -17,7 +17,7 @@ namespace Bloxstrap.Helpers
if (installedVersionInfo.ProductVersion != currentVersionInfo.ProductVersion)
{
DialogResult result = MessageBox.Show(
$"The version of {Program.ProjectName} you've launched is newer than the version you currently have installed.\nWould you like to update your installed version of {Program.ProjectName}?",
$"The version of {Program.ProjectName} you've launched is newer than the version you currently have installed.\nWould you like to update your currently installed version?",
Program.ProjectName,
MessageBoxButtons.YesNo,
MessageBoxIcon.Question
@ -59,7 +59,7 @@ namespace Bloxstrap.Helpers
if (currentVersion != latestVersion)
{
DialogResult result = MessageBox.Show(
$"A new version of {Program.ProjectName} is available\n\nRelease notes:\n{releaseNotes}\n\nDo you want to download {latestVersion}?",
$"A new version of {Program.ProjectName} is available\n\n[{latestVersion}]\n{releaseNotes}\n\nWould you like to download it?",
Program.ProjectName,
MessageBoxButtons.YesNo,
MessageBoxIcon.Question

View File

@ -80,6 +80,26 @@ namespace Bloxstrap.Properties {
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap DarkCancelButton {
get {
object obj = ResourceManager.GetObject("DarkCancelButton", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap DarkCancelButtonHover {
get {
object obj = ResourceManager.GetObject("DarkCancelButtonHover", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
/// </summary>

View File

@ -124,6 +124,12 @@
<data name="CancelButtonHover" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\CancelButtonHover.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="DarkCancelButton" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\DarkCancelButton.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="DarkCancelButtonHover" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\DarkCancelButtonHover.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Icon2009_ico" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Icon2009-ico.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -11,13 +11,16 @@ namespace Bloxstrap
public BootstrapperStyle BootstrapperStyle { get; set; } = BootstrapperStyle.ProgressDialog;
public BootstrapperIcon BootstrapperIcon { get; set; } = BootstrapperIcon.IconBloxstrap;
public bool UseDiscordRichPresence { get; set; } = true;
public bool HideRPCButtons { get; set; } = false;
public bool UseOldDeathSound { get; set; } = true;
public bool UseOldMouseCursor { get; set; } = false;
}
public class SettingsManager
{
public SettingsFormat Settings = new();
public bool ShouldSave = false;
private bool IsSaving = false;
private string _saveLocation;
public string SaveLocation
@ -52,6 +55,17 @@ namespace Bloxstrap
public void Save()
{
if (IsSaving)
{
// sometimes Save() is called at the same time from both Main() and Exit(),
// so this is here to avoid the program exiting before saving
Thread.Sleep(1000);
return;
}
IsSaving = true;
Debug.WriteLine("Attempting to save...");
string SettingsJson = JsonSerializer.Serialize(Settings, new JsonSerializerOptions { WriteIndented = true });
@ -65,6 +79,8 @@ namespace Bloxstrap
// save settings
File.WriteAllText(SaveLocation, SettingsJson);
IsSaving = false;
}
}
}

View File

@ -14,10 +14,10 @@ Please keep in mind that **Bloxstrap is in very early development**, and you'll
## Features
Here's some of the features that Bloxstrap provides over the stock Roblox bootstrapper:
* Bootstrapper style can be customized (including being able to emulate older version looks)
* Ability to choose where to install Roblox to
* Old death sound can be re-enabled permanently
* Support for Discord Rich Presence
* Old death sound and mouse cursor can be permanently re-enabled
* Lets you choose where to install Roblox to
* Integration with Discord Rich Presence
* Custom bootstrapper styles (includes old versions and dark theme)
## Installing
Bloxstrap requires the [x86 .NET 6 Desktop Runtime](https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-desktop-6.0.7-windows-x86-installer). If you don't already have it installed, you'll be prompted to install it when running Bloxstrap.