commit 2303d56d6624c8f8baea2242e397b3e9308f3482 Author: Zack Rauen Date: Mon Oct 29 02:15:48 2018 -0400 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8c96e05 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.vs/ +bin/ +obj/ + +*.user diff --git a/BandagedBD.sln b/BandagedBD.sln new file mode 100644 index 0000000..ca95908 --- /dev/null +++ b/BandagedBD.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27130.2010 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BandagedBD", "BandagedBD\BandagedBD.csproj", "{390615F1-CE33-4173-9E8C-4E4F3EB1758D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {390615F1-CE33-4173-9E8C-4E4F3EB1758D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {390615F1-CE33-4173-9E8C-4E4F3EB1758D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {390615F1-CE33-4173-9E8C-4E4F3EB1758D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {390615F1-CE33-4173-9E8C-4E4F3EB1758D}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C4B9CD4A-4904-43C7-BE3F-B72A35C86ADF} + EndGlobalSection +EndGlobal diff --git a/BandagedBD/App.config b/BandagedBD/App.config new file mode 100644 index 0000000..7d44913 --- /dev/null +++ b/BandagedBD/App.config @@ -0,0 +1,37 @@ + + + + +
+ + +
+ + + + + + + + + False + + + + + + + 28, 28, 28 + + + 42, 42, 42 + + + 62, 130, 229 + + + White + + + + diff --git a/BandagedBD/BBD_small64.ico b/BandagedBD/BBD_small64.ico new file mode 100644 index 0000000..885493b Binary files /dev/null and b/BandagedBD/BBD_small64.ico differ diff --git a/BandagedBD/BandagedBD.csproj b/BandagedBD/BandagedBD.csproj new file mode 100644 index 0000000..349e9be --- /dev/null +++ b/BandagedBD/BandagedBD.csproj @@ -0,0 +1,236 @@ + + + + + Debug + AnyCPU + {390615F1-CE33-4173-9E8C-4E4F3EB1758D} + WinExe + BandagedBD + BandagedBD + v4.5.2 + 512 + true + + + + false + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + BBD_small64.ico + + + + false + + + false + + + app.manifest + + + + + + + + + + + + + + + + + + + Component + + + Button.cs + + + Component + + + Component + + + Form + + + FormMain.cs + + + UserControl + + + ActionPanel.cs + + + UserControl + + + DiscordLocator.cs + + + UserControl + + + InstallConfigPanel.cs + + + UserControl + + + RepairConfigPanel.cs + + + UserControl + + + RepairPanel.cs + + + UserControl + + + UninstallPanel.cs + + + UserControl + + + UninstallConfigPanel.cs + + + UserControl + + + InstallPanel.cs + + + + UserControl + + + LicensePanel.cs + + + + + + FormMain.cs + + + ActionPanel.cs + + + DiscordLocator.cs + + + InstallConfigPanel.cs + + + RepairConfigPanel.cs + + + RepairPanel.cs + + + UninstallPanel.cs + + + UninstallConfigPanel.cs + + + InstallPanel.cs + + + LicensePanel.cs + + + ResXFileCodeGenerator + Designer + Resources.Designer.cs + + + Designer + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + True + Resources.resx + + + True + Settings.settings + True + + + + + Designer + + + + + + + + + + + + + False + Microsoft .NET Framework 4.5.2 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + + + \ No newline at end of file diff --git a/BandagedBD/Controls/Button.cs b/BandagedBD/Controls/Button.cs new file mode 100644 index 0000000..30bb02c --- /dev/null +++ b/BandagedBD/Controls/Button.cs @@ -0,0 +1,33 @@ +namespace BandagedBD.Controls { + public partial class Button : System.Windows.Forms.Button { + + public Button HideDisable(string newText = null) { + if (newText != null) Text = newText; + Hide(); + Enabled = false; + return this; + } + + public Button HideEnable(string newText = null) { + if (newText != null) Text = newText; + Hide(); + Enabled = true; + return this; + } + + public Button ShowDisable(string newText = null) { + if (newText != null) Text = newText; + Show(); + Enabled = false; + return this; + } + + public Button ShowEnable(string newText = null) { + if (newText != null) Text = newText; + Show(); + Enabled = true; + return this; + } + + } +} diff --git a/BandagedBD/Controls/DiscordLocator.Designer.cs b/BandagedBD/Controls/DiscordLocator.Designer.cs new file mode 100644 index 0000000..bc52e93 --- /dev/null +++ b/BandagedBD/Controls/DiscordLocator.Designer.cs @@ -0,0 +1,251 @@ +namespace BandagedBD.Controls { + partial class DiscordLocator { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) { + if (disposing && (components != null)) { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() { + this.titleLabel = new System.Windows.Forms.Label(); + this.browsePTB = new BandagedBD.Controls.Button(); + this.tbPTB = new System.Windows.Forms.TextBox(); + this.panel3 = new System.Windows.Forms.Panel(); + this.browseCanary = new BandagedBD.Controls.Button(); + this.tbCanary = new System.Windows.Forms.TextBox(); + this.panel1 = new System.Windows.Forms.Panel(); + this.browseStable = new BandagedBD.Controls.Button(); + this.tbStable = new System.Windows.Forms.TextBox(); + this.panel2 = new System.Windows.Forms.Panel(); + this.discordPTB = new BandagedBD.Controls.FlatCheckBox(); + this.discordCanary = new BandagedBD.Controls.FlatCheckBox(); + this.discordStable = new BandagedBD.Controls.FlatCheckBox(); + this.SuspendLayout(); + // + // titleLabel + // + this.titleLabel.Anchor = System.Windows.Forms.AnchorStyles.None; + this.titleLabel.AutoSize = true; + this.titleLabel.BackColor = System.Drawing.Color.Transparent; + this.titleLabel.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.titleLabel.Location = new System.Drawing.Point(6, 9); + this.titleLabel.Name = "titleLabel"; + this.titleLabel.Size = new System.Drawing.Size(533, 13); + this.titleLabel.TabIndex = 37; + this.titleLabel.Text = "BandagedBD can attempt to fix several common problems. First we need to locate al" + + "l BandagedBD installations:"; + // + // browsePTB + // + this.browsePTB.Anchor = System.Windows.Forms.AnchorStyles.None; + this.browsePTB.BackColor = global::BandagedBD.Properties.Settings.Default.Accent; + this.browsePTB.Cursor = System.Windows.Forms.Cursors.Hand; + this.browsePTB.FlatAppearance.BorderSize = 0; + this.browsePTB.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.browsePTB.ForeColor = System.Drawing.Color.White; + this.browsePTB.Location = new System.Drawing.Point(573, 120); + this.browsePTB.Name = "browsePTB"; + this.browsePTB.Size = new System.Drawing.Size(75, 23); + this.browsePTB.TabIndex = 36; + this.browsePTB.Text = "Browse"; + this.browsePTB.UseVisualStyleBackColor = false; + this.browsePTB.Click += new System.EventHandler(this.browsePTB_Click); + // + // tbPTB + // + this.tbPTB.Anchor = System.Windows.Forms.AnchorStyles.None; + this.tbPTB.BackColor = global::BandagedBD.Properties.Settings.Default.SecondaryBackground; + this.tbPTB.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.tbPTB.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(128))); + this.tbPTB.ForeColor = System.Drawing.Color.White; + this.tbPTB.Location = new System.Drawing.Point(169, 125); + this.tbPTB.Name = "tbPTB"; + this.tbPTB.ReadOnly = true; + this.tbPTB.Size = new System.Drawing.Size(385, 13); + this.tbPTB.TabIndex = 34; + // + // panel3 + // + this.panel3.Anchor = System.Windows.Forms.AnchorStyles.None; + this.panel3.BackColor = global::BandagedBD.Properties.Settings.Default.SecondaryBackground; + this.panel3.Location = new System.Drawing.Point(156, 120); + this.panel3.Name = "panel3"; + this.panel3.Size = new System.Drawing.Size(411, 23); + this.panel3.TabIndex = 35; + // + // browseCanary + // + this.browseCanary.Anchor = System.Windows.Forms.AnchorStyles.None; + this.browseCanary.BackColor = global::BandagedBD.Properties.Settings.Default.Accent; + this.browseCanary.Cursor = System.Windows.Forms.Cursors.Hand; + this.browseCanary.FlatAppearance.BorderSize = 0; + this.browseCanary.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.browseCanary.ForeColor = System.Drawing.Color.White; + this.browseCanary.Location = new System.Drawing.Point(573, 78); + this.browseCanary.Name = "browseCanary"; + this.browseCanary.Size = new System.Drawing.Size(75, 23); + this.browseCanary.TabIndex = 33; + this.browseCanary.Text = "Browse"; + this.browseCanary.UseVisualStyleBackColor = false; + this.browseCanary.Click += new System.EventHandler(this.browseCanary_Click); + // + // tbCanary + // + this.tbCanary.Anchor = System.Windows.Forms.AnchorStyles.None; + this.tbCanary.BackColor = global::BandagedBD.Properties.Settings.Default.SecondaryBackground; + this.tbCanary.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.tbCanary.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(128))); + this.tbCanary.ForeColor = System.Drawing.Color.White; + this.tbCanary.Location = new System.Drawing.Point(169, 83); + this.tbCanary.Name = "tbCanary"; + this.tbCanary.ReadOnly = true; + this.tbCanary.Size = new System.Drawing.Size(385, 13); + this.tbCanary.TabIndex = 31; + // + // panel1 + // + this.panel1.Anchor = System.Windows.Forms.AnchorStyles.None; + this.panel1.BackColor = global::BandagedBD.Properties.Settings.Default.SecondaryBackground; + this.panel1.Location = new System.Drawing.Point(156, 78); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(411, 23); + this.panel1.TabIndex = 32; + // + // browseStable + // + this.browseStable.Anchor = System.Windows.Forms.AnchorStyles.None; + this.browseStable.BackColor = global::BandagedBD.Properties.Settings.Default.Accent; + this.browseStable.Cursor = System.Windows.Forms.Cursors.Hand; + this.browseStable.FlatAppearance.BorderSize = 0; + this.browseStable.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.browseStable.ForeColor = System.Drawing.Color.White; + this.browseStable.Location = new System.Drawing.Point(573, 37); + this.browseStable.Name = "browseStable"; + this.browseStable.Size = new System.Drawing.Size(75, 23); + this.browseStable.TabIndex = 30; + this.browseStable.Text = "Browse"; + this.browseStable.UseVisualStyleBackColor = false; + this.browseStable.Click += new System.EventHandler(this.browseStable_Click); + // + // tbStable + // + this.tbStable.Anchor = System.Windows.Forms.AnchorStyles.None; + this.tbStable.BackColor = global::BandagedBD.Properties.Settings.Default.SecondaryBackground; + this.tbStable.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.tbStable.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(128))); + this.tbStable.ForeColor = System.Drawing.Color.White; + this.tbStable.Location = new System.Drawing.Point(169, 42); + this.tbStable.Name = "tbStable"; + this.tbStable.ReadOnly = true; + this.tbStable.Size = new System.Drawing.Size(385, 13); + this.tbStable.TabIndex = 28; + // + // panel2 + // + this.panel2.Anchor = System.Windows.Forms.AnchorStyles.None; + this.panel2.BackColor = global::BandagedBD.Properties.Settings.Default.SecondaryBackground; + this.panel2.Location = new System.Drawing.Point(156, 37); + this.panel2.Name = "panel2"; + this.panel2.Size = new System.Drawing.Size(411, 23); + this.panel2.TabIndex = 29; + // + // discordPTB + // + this.discordPTB.Anchor = System.Windows.Forms.AnchorStyles.None; + this.discordPTB.AutoSize = true; + this.discordPTB.Cursor = System.Windows.Forms.Cursors.Hand; + this.discordPTB.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.discordPTB.Location = new System.Drawing.Point(9, 124); + this.discordPTB.Name = "discordPTB"; + this.discordPTB.Size = new System.Drawing.Size(98, 17); + this.discordPTB.TabIndex = 27; + this.discordPTB.Text = "Repair On PTB"; + this.discordPTB.UseVisualStyleBackColor = true; + this.discordPTB.CheckedChanged += new System.EventHandler(this.discordPTB_CheckedChanged); + // + // discordCanary + // + this.discordCanary.Anchor = System.Windows.Forms.AnchorStyles.None; + this.discordCanary.AutoSize = true; + this.discordCanary.Cursor = System.Windows.Forms.Cursors.Hand; + this.discordCanary.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.discordCanary.Location = new System.Drawing.Point(9, 82); + this.discordCanary.Name = "discordCanary"; + this.discordCanary.Size = new System.Drawing.Size(110, 17); + this.discordCanary.TabIndex = 26; + this.discordCanary.Text = "Repair On Canary"; + this.discordCanary.UseVisualStyleBackColor = true; + this.discordCanary.CheckedChanged += new System.EventHandler(this.discordCanary_CheckedChanged); + // + // discordStable + // + this.discordStable.Anchor = System.Windows.Forms.AnchorStyles.None; + this.discordStable.AutoSize = true; + this.discordStable.Cursor = System.Windows.Forms.Cursors.Hand; + this.discordStable.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.discordStable.Location = new System.Drawing.Point(9, 41); + this.discordStable.Name = "discordStable"; + this.discordStable.Size = new System.Drawing.Size(107, 17); + this.discordStable.TabIndex = 25; + this.discordStable.Text = "Repair On Stable"; + this.discordStable.UseVisualStyleBackColor = true; + this.discordStable.CheckedChanged += new System.EventHandler(this.discordStable_CheckedChanged); + // + // DiscordLocator + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.Transparent; + this.Controls.Add(this.titleLabel); + this.Controls.Add(this.browsePTB); + this.Controls.Add(this.tbPTB); + this.Controls.Add(this.panel3); + this.Controls.Add(this.browseCanary); + this.Controls.Add(this.tbCanary); + this.Controls.Add(this.panel1); + this.Controls.Add(this.browseStable); + this.Controls.Add(this.tbStable); + this.Controls.Add(this.panel2); + this.Controls.Add(this.discordPTB); + this.Controls.Add(this.discordCanary); + this.Controls.Add(this.discordStable); + this.Name = "DiscordLocator"; + this.Size = new System.Drawing.Size(662, 161); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private Controls.Button browsePTB; + private System.Windows.Forms.TextBox tbPTB; + private System.Windows.Forms.Panel panel3; + private Controls.Button browseCanary; + private System.Windows.Forms.TextBox tbCanary; + private System.Windows.Forms.Panel panel1; + private Controls.Button browseStable; + private System.Windows.Forms.TextBox tbStable; + private System.Windows.Forms.Panel panel2; + private BandagedBD.Controls.FlatCheckBox discordPTB; + private BandagedBD.Controls.FlatCheckBox discordCanary; + private BandagedBD.Controls.FlatCheckBox discordStable; + private System.Windows.Forms.Label titleLabel; + } +} diff --git a/BandagedBD/Controls/DiscordLocator.cs b/BandagedBD/Controls/DiscordLocator.cs new file mode 100644 index 0000000..6bb848f --- /dev/null +++ b/BandagedBD/Controls/DiscordLocator.cs @@ -0,0 +1,68 @@ +using System; +using System.Windows.Forms; + +namespace BandagedBD.Controls { + public partial class DiscordLocator : UserControl { + + public bool stable => discordStable.Checked; + public bool canary => discordCanary.Checked; + public bool ptb => discordPTB.Checked; + public EventHandler OnCheckedChange; + + public DiscordLocator() { + InitializeComponent(); + if (Utilities.CurrentStablePath != null) tbStable.Text = Utilities.CurrentStablePath; + if (Utilities.CurrentCanaryPath != null) tbCanary.Text = Utilities.CurrentCanaryPath; + if (Utilities.CurrentPtbPath != null) tbPTB.Text = Utilities.CurrentPtbPath; + Utilities.EnsureDiscord(tbStable, discordStable, Discord.Stable); + Utilities.EnsureDiscord(tbCanary, discordCanary, Discord.Canary); + Utilities.EnsureDiscord(tbPTB, discordPTB, Discord.PTB); + } + + public void setLabel(string label) { + titleLabel.Text = label; + } + + public void setCheckboxLabel(Discord which, string label) { + if (which == Discord.Stable) discordStable.Text = label; + if (which == Discord.Canary) discordCanary.Text = label; + if (which == Discord.PTB) discordPTB.Text = label; + } + + private void browseStable_Click(object sender, EventArgs e) { + var fbd = new FolderBrowserDialog { SelectedPath = tbStable.Text }; + fbd.ShowDialog(); + tbStable.Text = fbd.SelectedPath; + Utilities.EnsureDiscord(tbStable, discordStable, Discord.Stable); + } + + private void browseCanary_Click(object sender, EventArgs e) { + var fbd = new FolderBrowserDialog { SelectedPath = tbCanary.Text }; + fbd.ShowDialog(); + tbCanary.Text = fbd.SelectedPath; + Utilities.EnsureDiscord(tbCanary, discordCanary, Discord.Canary); + } + + private void browsePTB_Click(object sender, EventArgs e) { + var fbd = new FolderBrowserDialog { SelectedPath = tbPTB.Text }; + fbd.ShowDialog(); + tbPTB.Text = fbd.SelectedPath; + Utilities.EnsureDiscord(tbPTB, discordPTB, Discord.PTB); + } + + private void discordStable_CheckedChanged(object sender, EventArgs e) { + if (discordStable.Checked) Utilities.EnsureDiscord(tbStable, discordStable, Discord.Stable); + OnCheckedChange?.Invoke(sender, e); + } + + private void discordCanary_CheckedChanged(object sender, EventArgs e) { + if (discordCanary.Checked) Utilities.EnsureDiscord(tbCanary, discordCanary, Discord.Canary); + OnCheckedChange?.Invoke(sender, e); + } + + private void discordPTB_CheckedChanged(object sender, EventArgs e) { + if (discordPTB.Checked) Utilities.EnsureDiscord(tbPTB, discordPTB, Discord.PTB); + OnCheckedChange?.Invoke(sender, e); + } + } +} diff --git a/BandagedBD/Controls/DiscordLocator.resx b/BandagedBD/Controls/DiscordLocator.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/BandagedBD/Controls/DiscordLocator.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/BandagedBD/Controls/FlatCheckBox.cs b/BandagedBD/Controls/FlatCheckBox.cs new file mode 100644 index 0000000..4fa0398 --- /dev/null +++ b/BandagedBD/Controls/FlatCheckBox.cs @@ -0,0 +1,21 @@ +using System.Drawing; +using System.Drawing.Text; +using System.Windows.Forms; + +namespace BandagedBD.Controls { + class FlatCheckBox : CheckBox { + public FlatCheckBox() { + SetStyle(ControlStyles.UserPaint, true); + SetStyle(ControlStyles.AllPaintingInWmPaint, true); + } + + protected override void OnPaint(PaintEventArgs e) { + base.OnPaint(e); + e.Graphics.FillRectangle(new SolidBrush(Properties.Settings.Default.SecondaryBackground), new Rectangle(0, 0, 13, 14)); + if (Checked) { + e.Graphics.TextRenderingHint = TextRenderingHint.AntiAlias; + e.Graphics.DrawString("\u2714", this.Font, new SolidBrush(Properties.Settings.Default.Accent), -1, 1); + } + } + } +} diff --git a/BandagedBD/Controls/FlatProgressBar.cs b/BandagedBD/Controls/FlatProgressBar.cs new file mode 100644 index 0000000..6c6dd46 --- /dev/null +++ b/BandagedBD/Controls/FlatProgressBar.cs @@ -0,0 +1,28 @@ +using System.Drawing; +using System.Windows.Forms; + +namespace BandagedBD.Controls { + public class FlatProgressBar : ProgressBar { + public FlatProgressBar() { + SetStyle(ControlStyles.UserPaint, true); + } + + protected override void OnPaintBackground(PaintEventArgs pevent) { + // None... Helps control the flicker. + // No seriously, it works. + } + + protected override void OnPaint(PaintEventArgs e) { + using (Image offscreenImage = new Bitmap(Width, Height)) { + using (Graphics offscreen = Graphics.FromImage(offscreenImage)) { + Rectangle rect = new Rectangle(0, 0, Width, Height); + offscreen.FillRectangle(new SolidBrush(BackColor), rect); + rect.Width = (int) (rect.Width * ((double) (Value - Minimum) / (Maximum - Minimum))); + if (rect.Width > 0) offscreen.FillRectangle(new SolidBrush(ForeColor), 0, 0, rect.Width, rect.Height); + e.Graphics.DrawImage(offscreenImage, 0, 0); + offscreenImage.Dispose(); + } + } + } + } +} diff --git a/BandagedBD/FormMain.Designer.cs b/BandagedBD/FormMain.Designer.cs new file mode 100644 index 0000000..de2167c --- /dev/null +++ b/BandagedBD/FormMain.Designer.cs @@ -0,0 +1,190 @@ +using System.Drawing; + +namespace BandagedBD { + partial class FormMain { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + private readonly Pen headerPen = new Pen(Color.FromArgb(32, 32, 32)); + private readonly SolidBrush headerBrush = new SolidBrush(Properties.Settings.Default.SecondaryBackground); + private Rectangle headerShape => new Rectangle(0, 0, Width, 85); + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) { + if (disposing) { + headerBrush.Dispose(); + headerPen.Dispose(); + if (components != null) components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormMain)); + this.panelDock = new System.Windows.Forms.Panel(); + this.lblTitle = new System.Windows.Forms.Label(); + this.logo = new System.Windows.Forms.Panel(); + this.linkLabel1 = new System.Windows.Forms.LinkLabel(); + this.label1 = new System.Windows.Forms.Label(); + this.btnCancel = new BandagedBD.Controls.Button(); + this.btnNext = new BandagedBD.Controls.Button(); + this.btnBack = new BandagedBD.Controls.Button(); + this.SuspendLayout(); + // + // panelDock + // + this.panelDock.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.panelDock.BackColor = System.Drawing.Color.Transparent; + this.panelDock.Location = new System.Drawing.Point(12, 96); + this.panelDock.Name = "panelDock"; + this.panelDock.Size = new System.Drawing.Size(752, 339); + this.panelDock.TabIndex = 0; + // + // lblTitle + // + this.lblTitle.AutoSize = true; + this.lblTitle.BackColor = System.Drawing.Color.Transparent; + this.lblTitle.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold); + this.lblTitle.ForeColor = System.Drawing.Color.White; + this.lblTitle.Location = new System.Drawing.Point(82, 37); + this.lblTitle.Name = "lblTitle"; + this.lblTitle.Size = new System.Drawing.Size(145, 16); + this.lblTitle.TabIndex = 5; + this.lblTitle.Text = "BandagedBD Setup"; + // + // logo + // + this.logo.BackColor = System.Drawing.Color.Transparent; + this.logo.BackgroundImage = global::BandagedBD.Properties.Resources.BBDVS; + this.logo.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; + this.logo.Cursor = System.Windows.Forms.Cursors.Hand; + this.logo.Location = new System.Drawing.Point(12, 12); + this.logo.Name = "logo"; + this.logo.Size = new System.Drawing.Size(64, 64); + this.logo.TabIndex = 4; + // + // linkLabel1 + // + this.linkLabel1.ActiveLinkColor = global::BandagedBD.Properties.Settings.Default.Accent; + this.linkLabel1.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.linkLabel1.AutoSize = true; + this.linkLabel1.Cursor = System.Windows.Forms.Cursors.Hand; + this.linkLabel1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(128))); + this.linkLabel1.LinkBehavior = System.Windows.Forms.LinkBehavior.HoverUnderline; + this.linkLabel1.LinkColor = global::BandagedBD.Properties.Settings.Default.Accent; + this.linkLabel1.Location = new System.Drawing.Point(132, 471); + this.linkLabel1.Name = "linkLabel1"; + this.linkLabel1.Size = new System.Drawing.Size(95, 13); + this.linkLabel1.TabIndex = 34; + this.linkLabel1.TabStop = true; + this.linkLabel1.Text = "Consider donating."; + this.linkLabel1.VisitedLinkColor = global::BandagedBD.Properties.Settings.Default.Accent; + this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked); + // + // label1 + // + this.label1.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.label1.AutoSize = true; + this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(128))); + this.label1.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.label1.Location = new System.Drawing.Point(13, 471); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(120, 13); + this.label1.TabIndex = 33; + this.label1.Text = "Enjoying BandagedBD?"; + // + // btnCancel + // + this.btnCancel.BackColor = global::BandagedBD.Properties.Settings.Default.Accent; + this.btnCancel.Cursor = System.Windows.Forms.Cursors.Hand; + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.FlatAppearance.BorderSize = 0; + this.btnCancel.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnCancel.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.btnCancel.Location = new System.Drawing.Point(689, 466); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(75, 23); + this.btnCancel.TabIndex = 8; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = false; + this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); + // + // btnNext + // + this.btnNext.BackColor = global::BandagedBD.Properties.Settings.Default.Accent; + this.btnNext.Cursor = System.Windows.Forms.Cursors.Hand; + this.btnNext.FlatAppearance.BorderSize = 0; + this.btnNext.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnNext.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.btnNext.Location = new System.Drawing.Point(608, 466); + this.btnNext.Name = "btnNext"; + this.btnNext.Size = new System.Drawing.Size(75, 23); + this.btnNext.TabIndex = 7; + this.btnNext.Text = "Next >"; + this.btnNext.UseVisualStyleBackColor = false; + this.btnNext.Click += new System.EventHandler(this.btnNext_Click); + // + // btnBack + // + this.btnBack.BackColor = global::BandagedBD.Properties.Settings.Default.Accent; + this.btnBack.Cursor = System.Windows.Forms.Cursors.Hand; + this.btnBack.FlatAppearance.BorderSize = 0; + this.btnBack.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnBack.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.btnBack.Location = new System.Drawing.Point(527, 466); + this.btnBack.Name = "btnBack"; + this.btnBack.Size = new System.Drawing.Size(75, 23); + this.btnBack.TabIndex = 6; + this.btnBack.Text = "< Back"; + this.btnBack.UseVisualStyleBackColor = false; + this.btnBack.Click += new System.EventHandler(this.btnBack_Click); + // + // FormMain + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = global::BandagedBD.Properties.Settings.Default.PrimaryBackground; + this.ClientSize = new System.Drawing.Size(776, 501); + this.Controls.Add(this.linkLabel1); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.label1); + this.Controls.Add(this.btnNext); + this.Controls.Add(this.btnBack); + this.Controls.Add(this.lblTitle); + this.Controls.Add(this.logo); + this.Controls.Add(this.panelDock); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MaximizeBox = false; + this.Name = "FormMain"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "BandagedBD Installer v0.3.2"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Panel panelDock; + private System.Windows.Forms.Panel logo; + private System.Windows.Forms.Label lblTitle; + public Controls.Button btnNext; + public Controls.Button btnCancel; + public Controls.Button btnBack; + private System.Windows.Forms.LinkLabel linkLabel1; + private System.Windows.Forms.Label label1; + } +} + diff --git a/BandagedBD/FormMain.cs b/BandagedBD/FormMain.cs new file mode 100644 index 0000000..b41e807 --- /dev/null +++ b/BandagedBD/FormMain.cs @@ -0,0 +1,100 @@ +using BandagedBD.Panels; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Windows.Forms; + +namespace BandagedBD { + + public enum PanelTypes { License, Action, InstallConfig, RepairConfig, UninstallConfig, Install, Repair, Uninstall, NONE }; + + public partial class FormMain : Form { + + private PanelTypes CurrentPanel = PanelTypes.NONE; + public PanelTypes Action = PanelTypes.NONE; + + private Dictionary panelMap = new Dictionary(); + + + public FormMain() { + InitializeComponent(); + logo.Click += Logo_Click; + + panelMap[PanelTypes.License] = new LicensePanel(); + panelMap[PanelTypes.Action] = new ActionPanel(); + panelMap[PanelTypes.InstallConfig] = new InstallConfigPanel(); + panelMap[PanelTypes.UninstallConfig] = new UninstallConfigPanel(); + panelMap[PanelTypes.RepairConfig] = new RepairConfigPanel(); + panelMap[PanelTypes.Install] = new InstallPanel(); + panelMap[PanelTypes.Uninstall] = new UninstallPanel(); + panelMap[PanelTypes.Repair] = new RepairPanel(); + + foreach (KeyValuePair entry in panelMap) { + entry.Value.SetWindow(this); + entry.Value.Control.Dock = DockStyle.Fill; + } + + if (!Properties.Settings.Default.AgreedToTerms) SwitchPanel(PanelTypes.License); + else SwitchPanel(PanelTypes.Action); + } + + public void SetTitle(string title) => lblTitle.Text = title; + + public IPanel GetPanel(PanelTypes which) { + return panelMap[which]; + } + + public void SwitchPanel(PanelTypes which) { + if (CurrentPanel != PanelTypes.NONE) panelDock.Controls.Remove(panelMap[CurrentPanel].Control); + + CurrentPanel = which; + panelDock.Controls.Add(panelMap[which].Control); + SetTitle($"BandagedBD — {panelMap[which].Title}"); + panelMap[which].OnShow(); + + if (panelMap[CurrentPanel].PreviousPanel == PanelTypes.NONE) btnBack.HideDisable(); + if (panelMap[CurrentPanel].NextPanel == PanelTypes.NONE) { + btnBack.HideDisable(); + btnNext.HideDisable(); + btnCancel.ShowEnable("Exit"); + } + } + + protected override void OnPaint(PaintEventArgs e) { + base.OnPaint(e); + var g = e.Graphics; + g.FillRectangle(headerBrush, headerShape); + g.DrawLine(headerPen, 0, 85, Width, 85); + } + + private void btnNext_Click(object sender, EventArgs e) { + if (CurrentPanel == PanelTypes.License) { + Properties.Settings.Default.AgreedToTerms = true; + Properties.Settings.Default.Save(); + } + SwitchPanel(panelMap[CurrentPanel].NextPanel); + } + + private void btnCancel_Click(object sender, EventArgs e) { + Application.Exit(); + } + + private void btnBack_Click(object sender, EventArgs e) { + SwitchPanel(panelMap[CurrentPanel].PreviousPanel); + } + + public void Fail() { + btnCancel.ShowEnable(); + btnNext.ShowDisable(); + btnBack.ShowEnable(); + } + + private void Logo_Click(object sender, EventArgs e) { + Utilities.OpenProcess("https://github.com/rauenzi/BetterDiscordApp"); + } + + private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { + Utilities.OpenProcess("https://www.paypal.me/ZackRauen"); + } + } +} diff --git a/BandagedBD/FormMain.resx b/BandagedBD/FormMain.resx new file mode 100644 index 0000000..a9da4bb --- /dev/null +++ b/BandagedBD/FormMain.resx @@ -0,0 +1,479 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAIAQEAAAAEAIAAoQgAAJgAAACAgAAABACAAqBAAAE5CAAAoAAAAQAAAAIAAAAABACAAAAAAAABA + AAATCwAAEwsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABJCQkAjEx + MQIxMTECMTExAjIyMgI0NDQCNjY2AjY2NgI2NjYCNjY2Ajc3NwI3NzcCNzc3Ajg4OAI4ODgCOjo6AkRE + RAJdXV0BlZWVAeDg4AGmpqYBbGxsAmhoaAJfX18CSUlJAikpKQEODg4BAAAAAQAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5+flw8vLyrPHx8a3x8fGt8fHxrfHx + 8a3x8fGt8fHxrfHx8a/x8fGw8vLysPLy8rDy8vKw8fHxsPHx8bDx8fGw8fHxsPHx8bDy8vKw8vLysPHx + 8bHx8fGx8vLysPHw8K/w6uWv693TrubLuKzes5Wq1JNmq8t2PK7Tej2u0no+rsNzPK6pZjiuh1Uyrl0/ + K6kqJSGcGxsbiBYWFmsTExNFCwsLGAAAAAcAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////qv// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////8+PX/7dfI/9+x + kf/ThlL/2ns7/+OBPf/lgj7/44E+/79wOv+LVzL/TTcn/x0cHP0XFxfUFRUVlBMTE0YBAQELAAAAAgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP///6r///////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////+zZzP/Um3P/03g5/+OAPf/lgj7/5YI+/+WCPv/Ldjz/eU4w/yYj + IP8YGBj/FxcX3hQUFH0KCgoZAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///+q//////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////+7f1P/Mil3/2Xs7/+WC + Pv/lgj7/5YI+/+WCPv/Tej3/a0gv/x0dHf8XFxf/FxcX6hQUFHUCAgINAAAAAQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////qv////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////v38/9auk//OdTj/5IE9/+WCPv/lgj7/5YI+/+WCPv+pZzn/Kycj/xgYGP8XFxf/FhYWyA4O + Di4AAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /6r///////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////38Sx/8lzOP/kgT3/5YI+/+WCPv/lgj7/5YI+/8Nz + O/8zLCb/GBgY/xcXF/8XFxfrEBAQSwAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///+q//////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////avKf/zHM3/+SC + Pv/lgj7/5YI+/+WCPv/lgj7/wHI7/yonJP8XFxf/FxcX/xcXF/QQEBBPAAAAAwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////qv////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////8iYeP/Yejr/5YI+/+WCPv/lgj7/5YI+/+WCPv+dYjn/Hh4e/xcXF/8XFxf/FxcX7g0N + DTcAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///6r///////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////38u//u3E+/+KAPf/lgj7/5YI+/+WCPv/lgj7/5YI+/1hA + MP8YGBj/FxcX/xcXF/8WFhbQAwMDFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///+q//////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////9Gvl//Sdzn/5YI+/+WC + Pv/lgj7/5YI+/+WCPv+6bzz/ISEh/xcXF/8XFxf/FxcX/xMTE4EAAAAFAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////qv////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///28e3/ums1/+SBPv/lgj7/5YI+/+WCPv/lgj7/5YI+/0w6Lv8YGBj/FxcX/xcXF/8XFxfsBgYGIAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPr6+nn09PS69PT0uvT09Lr09PS69PT0uvT0 + 9Lr09PS69PT0uvT09Lr09PS69PT0uvT09Lr09PS69PT0uvT09Lr09PS69PT0uvT09Lr09PS69PT0uvT0 + 9Lr09PS69vb2wvv7++P///////////////////////////////////////////////////////////// + /////////////////////////////8CLZv/efjz/5YI+/+WCPv/lgj7/5YI+/+WCPv+OWzj/Gxsb/xcX + F/8XFxf/FxcX/xISEnsAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAA + AAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAA + AAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAAD4uLiLPr6+p3////+//////////////////////// + ///////////////////////////////////////////////////Sspz/0nc5/+WCPv/lgj7/5YI+/+WC + Pv/lgj7/v3I8/yEhIf8XFxf/FxcX/xcXF/8WFhbMAAAADwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+Pj4Vf// + //v/////////////////////////////////////////////////////////////////////5NLG/8Zw + Nf/lgj7/5YI+/+WCPv/lgj7/5YI+/+GAPv8oKCf/FxcX/xcXF/8XFxf/FxcX/AgICCkAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD9/f2B//////////////////////////////////////////////////////// + //////////////Lq5P+8ajL/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/QTUt/xcXF/8XFxf/FxcX/xcX + F/8QEBBgAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9PT0Dv7+/vb///////////////////////////// + ///////////////////////////////////8+vj/tWYv/+SBPv/lgj7/5YI+/+WCPv/lgj7/5YI+/1I+ + MP8YGBj/FxcX/xcXF/8XFxf/ExMTiQAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD9/f3G//////// + /////////////////////////////////////////////////////////v7+/7NlMP/kgT7/5YI+/+WC + Pv/lgj7/5YI+/+WCPv9ZQTH/GBgY/xcXF/8XFxf/FxcX/xQUFKQAAAAGAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA/f39u/////////////////////////////////////////////////////////////////z6 + +f+1ZS//5IE+/+WCPv/lgj7/5YI+/+WCPv/lgj7/Uz4w/xgYGP8XFxf/FxcX/xcXF/8UFBS0AAAACQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAmpqaAP7+/uL///////////////////////////////////////////// + ///////////////////07un/umky/+SCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/0U3Lf8XFxf/FxcX/xcX + F/8XFxf/FRUVuQAAAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAA8PDwEy8vLIMnJyS6WlpYfAAAACwAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPv7+0L///////////////////////////// + ////////////////////////////////////////6dvR/8JuNP/lgj7/5YI+/+WCPv/lgj7/5YI+/+WC + Pv8uKyn/FxcX/xcXF/8XFxf/FxcX/xUVFbkAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAPDw8Bv6+vqY/f397f////////////////f39+LY2NiOPz8/IgAAAAMAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPDw8BH+/v7X//////// + /////////////////////////////////////////////////////////////9rBr//NdDf/5YI+/+WC + Pv/lgj7/5YI+/+WCPv/PeT3/JCQk/xcXF/8XFxf/FxcX/xcXF/8VFRW5AAAACgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPn5+Tj+/v7s//////////////////////////////////////Hx + 8dtdXV08AAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfHx + 8S/+/v7S//////////////////////////////////////////////////////////////////////// + ///JoIP/2Ho6/+WCPv/lgj7/5YI+/+WCPv/lgj7/qWg7/x4eHv8XFxf/FxcX/xcXF/8XFxf/FRUVuQAA + AAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPn5+Rn+/v7r//////////////////////// + ////////////////////////6urq0w4ODicAAAABAAAAAAAAAADx8fEz39/fS93d3Uzd3d1M3d3dTN3d + 3Uzj4+NU8fHxdvr6+rn////9//////////////////////////////////////////////////////// + ////////////////////////uXlN/+F/Pf/lgj7/5YI+/+WCPv/lgj7/5YI+/3ZQNf8ZGRn/FxcX/xcX + F/8XFxf/FxcX/xUVFbkAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD+/v6b//////// + //////////////////////////////////////////////////+vr6+HAAAADQAAAAAAAAAA////u/// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////7N/W/8BtM//kgj7/5YI+/+WCPv/lgj7/5YI+/+GA + Pv82Lyr/FxcX/xcXF/8XFxf/FxcX/xcXF/8VFRW5AAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD29vYQ////9///////////////////////////////////////////////////////////6+vr2QAA + ACYAAAAAAAAAAP///7v///////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////8icfv/Yejr/5YI+/+WC + Pv/lgj7/5YI+/+WCPv+kZTr/Hh4e/xcXF/8XFxf/FxcX/xcXF/8XFxf/FRUVuQAAAAoAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA/Pz8Vf////////////////////////////////////////////////// + //////////////////9OTk5LAAAAAwAAAAD///+7//////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////Hn + 4P++bjf/5IE9/+WCPv/lgj7/5YI+/+WCPv/hgT7/RDYs/xgYGP8XFxf/FxcX/xcXF/8XFxf/FxcX/xUV + FbkAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP39/Yj///////////////////////////// + ////////////////////////////////////////mpqaeQAAAAgAAAAA////u/////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////+/v/Ci2X/23w7/+WCPv/lgj7/5YI+/+WCPv/lgj7/i1k3/xwcHP8XFxf/FxcX/xcX + F/8XFxf/FxcX/xcXF/8VFRW5AAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///+l//////// + /////////////////////////////////////////////////////////////7Ozs5EAAAAMAAAAAP// + /7v///////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////RrpX/0HY4/+WCPv/lgj7/5YI+/+WCPv/lgj7/tm07/yUj + Iv8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FRUVuQAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////qv////////////////////////////////////////////////////////////////// + //+3t7eWAAAADgAAAAD///+7//////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////0KuS/9B2OP/lgj7/5YI+/+WC + Pv/lgj7/5YI+/7RsO/8kIyL/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xUVFbkAAAAKAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///6r///////////////////////////////////////////// + ////////////////////////uLi4lwAAAA4AAAAA////u/////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////7+ + /v/BiWP/3Hw7/+WCPv/lgj7/5YI+/+WCPv/lgj7/iVg2/xwcHP8XFxf/FxcX/xcXF/8XFxf/FxcX/xcX + F/8VFRW5AAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///+q//////////////////////// + /////////////////////////////////////////////7i4uJcAAAAOAAAAAP///7v///////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////8Obf/75uNv/kgT3/5YI+/+WCPv/lgj7/5YI+/+GAPv9DNiz/GBgY/xcX + F/8XFxf/FxcX/xcXF/8XFxf/FRUVuQAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////qv// + //////////////////////////////////////////////////////////////////+5ubmYAAAADgAA + AAD///+7//////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////Im3z/2Xs6/+WCPv/lgj7/5YI+/+WC + Pv/lgj7/omQ6/x4eHv8XFxf/FxcX/xcXF/8XFxf/FxcX/xUVFbkAAAAKAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP///6r///////////////////////////////////////////////////////////// + ////////u7u7mQAAAA4AAAAA////u/////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////693U/8Ft + NP/lgj7/5YI+/+WCPv/lgj7/5YI+/+GAPv81Lyr/FxcX/xcXF/8XFxf/FxcX/xcXF/8VFRW5AAAACgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///+q//////////////////////////////////////// + /////////////////////////////7u7u5kAAAAPAAAAAPHx8TXf399N3d3dTt3d3U7d3d1O3d3dTuTk + 5Ffx8fF4+vr6vP////3///////////////////////////////////////////////////////////// + //////////////////+5eEz/4X89/+WCPv/lgj7/5YI+/+WCPv/lgj7/dU81/xkZGf8XFxf/FxcX/xcX + F/8XFxf/FRUVuQAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////qv////////////////// + //////////////////////////////////////////////////+7u7uaAAAADwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHx8fEx/v7+0/////////////////////////////////// + ////////////////////////////////////////yZ+C/9h7Ov/lgj7/5YI+/+WCPv/lgj7/5YI+/6lo + O/8eHh7/FxcX/xcXF/8XFxf/FxcX/xUVFbkAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /6r/////////////////////////////////////////////////////////////////////u7u7mgAA + AA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO/v7xH+/v7Y//////// + /////////////////////////////////////////////////////////////9rAr//NdDf/5YI+/+WC + Pv/lgj7/5YI+/+WCPv/PeD3/JCQk/xcXF/8XFxf/FxcX/xcXF/8VFRW5AAAACgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///+q//////////////////////////////////////////////////////// + /////////////7u7u5sAAAAPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA+/v7Q/////////////////////////////////////////////////////////////////// + ///p2tD/wm40/+WCPv/lgj7/5YI+/+WCPv/lgj7/5YI+/y4rKf8XFxf/FxcX/xcXF/8XFxf/FRUVuQAA + AAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////qv////////////////////////////////// + //////////////////////////////////+8vLybAAAADwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAKOjowD+/v7i//////////////////////////////////////// + ////////////////////////9O3o/7ppMv/kgj7/5YI+/+WCPv/lgj7/5YI+/+WCPv9FNy3/FxcX/xcX + F/8XFxf/FxcX/xUVFbgAAAAJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///6r///////////// + ////////////////////////////////////////////////////////vLy8nAAAAA8AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/f39u/////////////////// + //////////////////////////////////////////////z6+f+1ZS//5IE+/+WCPv/lgj7/5YI+/+WC + Pv/lgj7/Uz4w/xgYGP8XFxf/FxcX/xcXF/8UFBSxAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///+q/////////////////////////////////////////////////////////////////////729 + vZwAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP39 + /cX////////////////////////////////////////////////////////////////+/v7/s2Uw/+SB + Pv/lgj7/5YI+/+WCPv/lgj7/5YI+/1lBMf8YGBj/FxcX/xcXF/8XFxf/FBQUnwAAAAUAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////qv////////////////////////////////////////////////// + //////////////////+9vb2dAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAPPz8w3+/v72//////////////////////////////////////////////////////// + /////////Pr4/7VmL//kgT7/5YI+/+WCPv/lgj7/5YI+/+WCPv9TPjD/GBgY/xcXF/8XFxf/FxcX/xIS + EoAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///6r///////////////////////////// + ////////////////////////////////////////vb29nQAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD9/f1///////////////////////////////////////// + //////////////////////////////Lq5P+8ajL/5YI+/+WCPv/lgj7/5YI+/+WCPv/lgj7/QTUt/xcX + F/8XFxf/FxcX/xcXF/8PDw9TAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///+q//////// + /////////////////////////////////////////////////////////////76+vp4AAAAQAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5+flS////+/////////////////// + ///////////////////////////////////////////////////k08f/xXA1/+WCPv/lgj7/5YI+/+WC + Pv/lgj7/4YA+/ykoKP8XFxf/FxcX/xcXF/8XFxf2BAQEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////qv////////////////////////////////////////////////////////////////// + //++vr6eAAAAEgAAAAIAAAACAAAAAgAAAAIAAAACBAQEAjo6OgJAQEADKioqBOHh4Sn6+vqa/////f// + ////////////////////////////////////////////////////////////////////////07Od/9J3 + Of/lgj7/5YI+/+WCPv/lgj7/5YI+/8ByPP8hISH/FxcX/xcXF/8XFxf/FRUVvQAAAAsAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///6r///////////////////////////////////////////// + ////////////////////////8fHx4u/v77z09PS49PT0uPT09Lj09PS49PT0uPT09Lnz8/O89fX1wvv7 + ++H///////////////////////////////////////////////////////////////////////////// + /////////////8CLZ//dfTz/5YI+/+WCPv/lgj7/5YI+/+WCPv+QXDj/Gxsb/xcXF/8XFxf/FxcX/xER + EWcAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///+q//////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////fx7v+5azb/5IE9/+WCPv/lgj7/5YI+/+WCPv/lgj7/Tjsv/xgY + GP8XFxf/FxcX/xYWFt8CAgIXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////qv// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////SsJn/0nc4/+WCPv/lgj7/5YI+/+WC + Pv/lgj7/vHA8/yEhIf8XFxf/FxcX/xcXF/8SEhJqAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP///6r///////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////48/D/u3I//+KA + Pf/lgj7/5YI+/+WCPv/lgj7/5YI+/1pBMP8ZGRn/FxcX/xcXF/8VFRW8AAAADgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///+q//////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////yZp6/9d6Ov/lgj7/5YI+/+WCPv/lgj7/5YI+/6BjOf8eHh7/FxcX/xcXF/8WFhbiCgoKKAAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////qv////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////276r/8tzNv/kgT7/5YI+/+WCPv/lgj7/5YI+/8JzPP8rJyX/FxcX/xcX + F/8XFxfqDg4OPAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /6r///////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////4Ma1/8hzOP/jgT3/5YI+/+WCPv/lgj7/5YI+/8V0 + PP81LCf/GBgY/xcXF/8WFhbgDw8POQAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///+q//////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////+/f3/17GX/811OP/jgT3/5YI+/+WC + Pv/lgj7/5YI+/61oOf8tKCT/GBgY/xcXF/8WFha2CwsLIgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////qv////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////v4df/zIxg/9l7 + Ov/kgj7/5YI+/+WCPv/lgj7/1Xs9/29KMP8dHR3/FxcX/xcXF+ETExNjAAAACgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///6r///////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////+3c + 0P/VnXf/0ng6/+KAPf/lgj7/5YI+/+WCPv/Odzz/fFAx/ygkIf8YGBj/FhYW1RQUFHAGBgYSAAAAAgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///+q//////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////z5 + +P/u2cv/4LOU/9SIVf/Zezr/44E9/+WCPv/kgj7/wnI6/49YM/9QOCj/HR0d+xcXF88VFRWOEhISPQAA + AAkAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA+/v7cvPz87Dy8vKx8vLysfLy8rHy8vKx8vLysfLy8rHy8vKz8vLytPLy + 8rTy8vK08vLytPLy8rTy8vK08vLytPLy8rTy8vK08vLytPLy8rTy8vK08vLytPLy8rTx8PCy8Ovnsuze + 1bDmzbuu37WYrdSVaq7Ldz6y03o9stN6PrHEczyxq2c4sopWMrFhQSusLScinhsbG4kXFxdqExMTQwoK + ChUAAAAGAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAIAAAACAAAAAgAA + AAIAAAACJiYmAjIyMgIyMjICMjIyAjMzMwIzMzMCNTU1AjY2NgI3NzcCNzc3Ajg4OAI4ODgCODg4Ajk5 + OQI6OjoCOzs7AkNDQwJbW1sBjY2NAdfX1wGdnZ0BbW1tAmpqagJgYGACSUlJAisrKwIQEBACAQEBAQAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////////////////////////AAAAAAH///8AAAAAAA + ///wAAAAAAAf//AAAAAAAAf/8AAAAAAAA//wAAAAAAAB//AAAAAAAAB/8AAAAAAAAH/wAAAAAAAAP/AA + AAAAAAAf8AAAAAAAAB/wAAAAAAAAD/AAAAAAAAAP8AAAAAAAAA/////8AAAAB/////4AAAAH/////wAA + AAf/////gAAAB/////+AAAAH/////wAAAAf/AP//AAAAB/wAP/4AAAAH/AA/8AAAAAf4ABgAAAAAB/gA + GAAAAAAH8AAIAAAAAAfwAAgAAAAAB/AACAAAAAAH8AAIAAAAAAfwAAgAAAAAB/AACAAAAAAH8AAIAAAA + AAfwAAgAAAAAB/AACAAAAAAH8AAIAAAAAAfwAA/wAAAAB/AAD/4AAAAH8AAP/wAAAAfwAA//AAAAB/AA + D/+AAAAH8AAP/4AAAAfwAA//AAAAB/AAD/4AAAAH8AAP/AAAAAfwAAAAAAAAD/AAAAAAAAAP8AAAAAAA + AA/wAAAAAAAAH/AAAAAAAAAf8AAAAAAAAD/wAAAAAAAAf/AAAAAAAAD/8AAAAAAAAf/wAAAAAAAD//AA + AAAAAAf/8AAAAAAAH//wAAAAAAD///AAAAAAH///////////////////////////////////KAAAACAA + AABAAAAAAQAgAAAAAAAAEAAAEwsAABMLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA + AAEAAAABKysrATExMQEzMzMBNjY2ATY2NgE3NzcBODg4ATk5OQFPT08Btra2AIODgwFkZGQBOjo6AQgI + CAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPv7 + +7H5+fnW+fn51vn5+db5+fnX+fn52Pn5+dj5+fnY+fn52Pn5+dj5+fnY+fn51/j08dfz5dvV68u21t6m + f9fJeUHXtms31ZFYMclWOierGRkZfBQUFDcBAQEDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////1P////////////////////////////////////////////////////////////////// + //////////////r18v/lvKD/24JF/+WCPv/Dcjr/Xz8p/xgYGNYVFRVeAgICAwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD////U//////////////////////////////////////////////////////// + ///////////////////////////////////06uP/1otY/+WCPv/lgj7/n2E1/x4cG/8WFha4Dw8PFAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///9T///////////////////////////////////////////// + ///////////////////////////////////////////////////27un/1IJK/+WCPv/lgj7/m182/xkZ + Gf8WFhbMDAwMDwAAAAAAAAAAAAAAAAAAAAAAAAAA////1P////////////////////////////////// + ///////////////////////////////////////////////////////////////////hxLH/4H88/+WC + Pv/lgj7/Uzop/xcXF/8VFRWZAAAAAQAAAAAAAAAAAAAAAAAAAAD7+/u3+vr63fr6+t36+vrd+vr63fr6 + +t36+vrd+vr63fr6+t36+vrd+vr63fv7+9/+/v74//////////////////////////////////////37 + +v/PfUX/5YI+/+WCPv+pZjn/GBgY/xcXF/oPDw8oAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAA + AAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAdLS0gz8/Px8/////v////////////////// + /////////////9SbdP/lgj7/5YI+/9p9Pv8eHh7/FxcX/xQUFIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD+/v6h//////// + ////////////////////////2K2P/+WCPv/lgj7/5YI+/zAoI/8XFxf/FRUVugAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP39 + /WD////////////////////////////////ZsZX/5II+/+WCPv/lgj7/Nywk/xcXF/8WFhbWAAAABAAA + AAAAAAAAAAAAAAAAAAAAAAAAOTk5AcrKyhRvb28KAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA/v7+if///////////////////////////////9aoiP/lgj7/5YI+/+WCPv8oJCH/FxcX/xYW + FtwAAAAFAAAAAAAAAAAAAAAAAAAAAPz8/FD+/v7h//////39/fjo6OiiU1NTEQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAPr6+kT////1////////////////////////////////0pRp/+WCPv/lgj7/0Xk9/xwc + HP8XFxf/FhYW3AAAAAUAAAAAAAAAAAAAAAD9/f0t////+v/////////////////////Z2dmgAAAAA/z8 + /Dz39/el9/f3pvj4+Kj8/PzL/////v////////////////////////////////r39f/Qej//5YI+/+WC + Pv+dYDf/GBgY/xcXF/8WFhbcAAAABQAAAAAAAAAAAAAAAP7+/pf///////////////////////////v7 + +/YyMjId////Xv//////////////////////////////////////////////////////////3byl/+GA + Pf/lgj7/5II+/0c0J/8XFxf/FxcX/xYWFtwAAAAFAAAAAAAAAAAAAAAA////y/////////////////// + /////////////5ycnEj///9e//////////////////////////////////////////////////////Pq + 5P/UgEX/5YI+/+WCPv+TWzX/GBgY/xcXF/8XFxf/FhYW3AAAAAUAAAAAAAAAAAAAAAD////U//////// + ////////////////////////qKioUv///17///////////////////////////////////////////// + ////////8+rj/9V/Rf/lgj7/5YI+/5FaNP8YGBj/FxcX/xcXF/8WFhbcAAAABQAAAAAAAAAAAAAAAP// + /9T///////////////////////////////+pqalT////Xv////////////////////////////////// + ////////////////////////3buk/+KAPf/lgj7/5II+/0c0J/8XFxf/FxcX/xYWFtwAAAAFAAAAAAAA + AAAAAAAA////1P///////////////////////////////6urq1T8/Pw89/f3pvf396f4+Pip/Pz8zP// + ///////////////////////////////////69/T/0Ho+/+WCPv/lgj7/nGA3/xgYGP8XFxf/FhYW3AAA + AAUAAAAAAAAAAAAAAAD////U////////////////////////////////q6urVAAAAAAAAAAAAAAAAAAA + AAAAAAAA+/v7Rf////X////////////////////////////////Sk2n/5YI+/+WCPv/QeT3/HBwc/xcX + F/8WFhbcAAAABQAAAAAAAAAAAAAAAP///9T///////////////////////////////+rq6tVAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA/v7+if///////////////////////////////9aoiP/lgj7/5YI+/+WC + Pv8oJCH/FxcX/xYWFtwAAAAFAAAAAAAAAAAAAAAA////1P///////////////////////////////6ys + rFYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD9/f1g////////////////////////////////2bGV/+SC + Pv/lgj7/5YI+/zcsJP8XFxf/FhYW0wAAAAMAAAAAAAAAAAAAAAD////U//////////////////////// + ////////rKysVgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/qD///////////////////////////// + ///YrZD/5YI+/+WCPv/lgj7/MSgj/xcXF/8VFRW0AAAAAQAAAAAAAAAAAAAAAP///9T///////////// + //////////////////+srKxXAAAAAQAAAAECAgIBPT09AdHR0Qv8/Px7/////v////////////////// + /////////////9SbdP/lgj7/5YI+/9t+Pv8eHh7/FxcX/xQUFHcAAAAAAAAAAAAAAAAAAAAA////1P// + //////////////////////////////j4+Of6+vrc+vr63Pr6+tz6+vrf/v7+9/////////////////// + ///////////////////9/Pv/z31F/+WCPv/lgj7/qmc5/xgYGP8XFxf3Dg4OIAAAAAAAAAAAAAAAAAAA + AAD////U//////////////////////////////////////////////////////////////////////// + /////////////////////////////+HFsv/ffzz/5YI+/+WCPv9UOyn/FxcX/xUVFY0AAAABAAAAAAAA + AAAAAAAAAAAAAP///9T///////////////////////////////////////////////////////////// + ///////////////////////////////////27+r/1IJK/+WCPv/lgj7/nWA2/xkZGf8WFhbCCgoKCwAA + AAAAAAAAAAAAAAAAAAAAAAAA////1P////////////////////////////////////////////////// + ////////////////////////////////////////9evl/9aMWf/lgj7/5YI+/6FhNv8fHRv/FhYWrg4O + Dg8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD////U//////////////////////////////////////// + ////////////////////////////////////////+/bz/+W9ov/bgkX/5YI+/8VzOv9hQCn/GBgY0RUV + FVYAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8/LP6+vrY+vr62Pr6+tj6+vrZ+vr62vr6 + +tr6+vra+vr62vr6+tr6+vra+fn52fj08tj05tzW68y319+ngdjKeULYt2w415NZMclZOyerGhkZeRQU + FDMAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAASws + LAEyMjIBMzMzATU1NQE3NzcBODg4ATk5OQE6OjoBTk5OAa2trQCBgYEBZWVlATs7OwEJCQkBAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////wAAD/8AA + AD/AAAAfwAAAB8AAAAfAAAADwAAAA8AAAAH//gAB//8AAfD/AAHgfAABwAAAAcAAAAHAAAABwAAAAcAA + AAHAAAABwDwAAcA/AAHAPwABwD4AAcAAAAHAAAADwAAAA8AAAAfAAAAPwAAAH8AAAD/AAAP//////w== + + + \ No newline at end of file diff --git a/BandagedBD/Panels/ActionPanel.Designer.cs b/BandagedBD/Panels/ActionPanel.Designer.cs new file mode 100644 index 0000000..a06b297 --- /dev/null +++ b/BandagedBD/Panels/ActionPanel.Designer.cs @@ -0,0 +1,208 @@ +namespace BandagedBD.Panels +{ + partial class ActionPanel + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.installButton = new System.Windows.Forms.Button(); + this.repairButton = new System.Windows.Forms.Button(); + this.uninstallButton = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.label4 = new System.Windows.Forms.Label(); + this.label5 = new System.Windows.Forms.Label(); + this.label6 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // installButton + // + this.installButton.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.installButton.BackColor = global::BandagedBD.Properties.Settings.Default.Accent; + this.installButton.BackgroundImage = global::BandagedBD.Properties.Resources.archive_small; + this.installButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; + this.installButton.Cursor = System.Windows.Forms.Cursors.Hand; + this.installButton.FlatAppearance.BorderSize = 0; + this.installButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.installButton.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.installButton.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.installButton.Location = new System.Drawing.Point(29, 17); + this.installButton.Name = "installButton"; + this.installButton.Size = new System.Drawing.Size(56, 56); + this.installButton.TabIndex = 0; + this.installButton.UseVisualStyleBackColor = false; + this.installButton.Click += new System.EventHandler(this.installButton_Click); + // + // repairButton + // + this.repairButton.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.repairButton.BackColor = global::BandagedBD.Properties.Settings.Default.Accent; + this.repairButton.BackgroundImage = global::BandagedBD.Properties.Resources.build_small; + this.repairButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; + this.repairButton.Cursor = System.Windows.Forms.Cursors.Hand; + this.repairButton.FlatAppearance.BorderSize = 0; + this.repairButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.repairButton.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.repairButton.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.repairButton.Location = new System.Drawing.Point(29, 123); + this.repairButton.Name = "repairButton"; + this.repairButton.Size = new System.Drawing.Size(56, 56); + this.repairButton.TabIndex = 1; + this.repairButton.UseVisualStyleBackColor = false; + this.repairButton.Click += new System.EventHandler(this.repairButton_Click); + // + // uninstallButton + // + this.uninstallButton.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.uninstallButton.BackColor = global::BandagedBD.Properties.Settings.Default.Accent; + this.uninstallButton.BackgroundImage = global::BandagedBD.Properties.Resources.delete_small; + this.uninstallButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; + this.uninstallButton.Cursor = System.Windows.Forms.Cursors.Hand; + this.uninstallButton.FlatAppearance.BorderSize = 0; + this.uninstallButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.uninstallButton.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.uninstallButton.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.uninstallButton.Location = new System.Drawing.Point(29, 231); + this.uninstallButton.Name = "uninstallButton"; + this.uninstallButton.Size = new System.Drawing.Size(56, 56); + this.uninstallButton.TabIndex = 2; + this.uninstallButton.UseVisualStyleBackColor = false; + this.uninstallButton.Click += new System.EventHandler(this.uninstallButton_Click); + // + // label1 + // + this.label1.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.label1.AutoSize = true; + this.label1.BackColor = System.Drawing.Color.Transparent; + this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(128))); + this.label1.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.label1.Location = new System.Drawing.Point(102, 17); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(119, 13); + this.label1.TabIndex = 3; + this.label1.Text = "Install BandagedBD"; + // + // label2 + // + this.label2.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.label2.AutoSize = true; + this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(128))); + this.label2.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.label2.Location = new System.Drawing.Point(102, 123); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(122, 13); + this.label2.TabIndex = 4; + this.label2.Text = "Repair BandagedBD"; + // + // label3 + // + this.label3.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.label3.AutoSize = true; + this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(128))); + this.label3.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.label3.Location = new System.Drawing.Point(102, 231); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(134, 13); + this.label3.TabIndex = 5; + this.label3.Text = "Uninstall BandagedBD"; + // + // label4 + // + this.label4.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.label4.AutoSize = true; + this.label4.BackColor = System.Drawing.Color.Transparent; + this.label4.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.label4.Location = new System.Drawing.Point(102, 39); + this.label4.MaximumSize = new System.Drawing.Size(450, 0); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(434, 26); + this.label4.TabIndex = 6; + this.label4.Text = "This allows you to install BandagedBD to your existing Discord installation. Band" + + "agedBD is able to install to Discord Stable, Discord Canary, and Discord PTB sep" + + "arately."; + // + // label5 + // + this.label5.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.label5.AutoSize = true; + this.label5.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.label5.Location = new System.Drawing.Point(102, 145); + this.label5.MaximumSize = new System.Drawing.Size(450, 0); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(447, 26); + this.label5.TabIndex = 7; + this.label5.Text = "This repairs an existing BandagedBD installation fixing multiple issues. This inc" + + "ludes but is not limited to a broken injection, corrupt data files, and Discord " + + "update loops."; + // + // label6 + // + this.label6.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.label6.AutoSize = true; + this.label6.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.label6.Location = new System.Drawing.Point(102, 253); + this.label6.MaximumSize = new System.Drawing.Size(450, 0); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(450, 26); + this.label6.TabIndex = 8; + this.label6.Text = "This option fully removes BandagedBD from a Discord installation and optionally c" + + "leans up any user data related to BandagedBD."; + // + // ActionPanel + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = global::BandagedBD.Properties.Settings.Default.PrimaryBackground; + this.Controls.Add(this.label6); + this.Controls.Add(this.label5); + this.Controls.Add(this.label4); + this.Controls.Add(this.label3); + this.Controls.Add(this.label2); + this.Controls.Add(this.label1); + this.Controls.Add(this.uninstallButton); + this.Controls.Add(this.repairButton); + this.Controls.Add(this.installButton); + this.Name = "ActionPanel"; + this.Size = new System.Drawing.Size(580, 350); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button installButton; + private System.Windows.Forms.Button repairButton; + private System.Windows.Forms.Button uninstallButton; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.Label label6; + } +} diff --git a/BandagedBD/Panels/ActionPanel.cs b/BandagedBD/Panels/ActionPanel.cs new file mode 100644 index 0000000..0e28aa8 --- /dev/null +++ b/BandagedBD/Panels/ActionPanel.cs @@ -0,0 +1,45 @@ +using System; +using System.Windows.Forms; + +namespace BandagedBD.Panels { + public partial class ActionPanel : UserControl, IPanel { + private FormMain Window; + public void SetWindow(FormMain window) => Window = window; + + public string Title => "Choose an Action"; + public UserControl Control => this; + + public PanelTypes PreviousPanel => PanelTypes.License; + public PanelTypes NextPanel => _nextPanel; + private PanelTypes _nextPanel = PanelTypes.Install; + + public ActionPanel() { + InitializeComponent(); + } + + public void OnShow() { + Window.btnBack.ShowEnable(); + Window.btnCancel.ShowEnable("Cancel"); + Window.btnNext.HideDisable(); + Show(); + } + + private void GoToNext(PanelTypes next) { + _nextPanel = next; + Window.btnNext.ShowEnable(""); + Window.btnNext.PerformClick(); + } + + private void installButton_Click(object sender, EventArgs e) { + GoToNext(PanelTypes.InstallConfig); + } + + private void repairButton_Click(object sender, EventArgs e) { + GoToNext(PanelTypes.RepairConfig); + } + + private void uninstallButton_Click(object sender, EventArgs e) { + GoToNext(PanelTypes.UninstallConfig); + } + } +} diff --git a/BandagedBD/Panels/ActionPanel.resx b/BandagedBD/Panels/ActionPanel.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/BandagedBD/Panels/ActionPanel.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/BandagedBD/Panels/IPanel.cs b/BandagedBD/Panels/IPanel.cs new file mode 100644 index 0000000..fe43cf0 --- /dev/null +++ b/BandagedBD/Panels/IPanel.cs @@ -0,0 +1,12 @@ +using System.Windows.Forms; + +namespace BandagedBD.Panels { + public interface IPanel { + void OnShow(); + void SetWindow(FormMain window); + string Title { get; } + UserControl Control { get; } + PanelTypes PreviousPanel { get; } + PanelTypes NextPanel { get; } + } +} diff --git a/BandagedBD/Panels/InstallConfigPanel.Designer.cs b/BandagedBD/Panels/InstallConfigPanel.Designer.cs new file mode 100644 index 0000000..8e42db4 --- /dev/null +++ b/BandagedBD/Panels/InstallConfigPanel.Designer.cs @@ -0,0 +1,92 @@ +namespace BandagedBD.Panels +{ + partial class InstallConfigPanel + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.cbShouldRestart = new BandagedBD.Controls.FlatCheckBox(); + this.discordLocator = new BandagedBD.Controls.DiscordLocator(); + this.label1 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // cbShouldRestart + // + this.cbShouldRestart.Anchor = System.Windows.Forms.AnchorStyles.None; + this.cbShouldRestart.AutoSize = true; + this.cbShouldRestart.Checked = true; + this.cbShouldRestart.CheckState = System.Windows.Forms.CheckState.Checked; + this.cbShouldRestart.Cursor = System.Windows.Forms.Cursors.Hand; + this.cbShouldRestart.FlatAppearance.CheckedBackColor = System.Drawing.Color.Transparent; + this.cbShouldRestart.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.cbShouldRestart.Location = new System.Drawing.Point(9, 196); + this.cbShouldRestart.Name = "cbShouldRestart"; + this.cbShouldRestart.Size = new System.Drawing.Size(162, 17); + this.cbShouldRestart.TabIndex = 5; + this.cbShouldRestart.Text = "Restart All Discord Instances"; + this.cbShouldRestart.UseVisualStyleBackColor = true; + // + // discordLocator + // + this.discordLocator.Anchor = System.Windows.Forms.AnchorStyles.None; + this.discordLocator.BackColor = System.Drawing.Color.Transparent; + this.discordLocator.Location = new System.Drawing.Point(0, 3); + this.discordLocator.Name = "discordLocator"; + this.discordLocator.Size = new System.Drawing.Size(662, 161); + this.discordLocator.TabIndex = 6; + // + // label1 + // + this.label1.Anchor = System.Windows.Forms.AnchorStyles.None; + this.label1.AutoSize = true; + this.label1.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.label1.Location = new System.Drawing.Point(6, 170); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(95, 13); + this.label1.TabIndex = 8; + this.label1.Text = "Additional Options:"; + // + // InstallConfigPanel + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.Transparent; + this.Controls.Add(this.label1); + this.Controls.Add(this.cbShouldRestart); + this.Controls.Add(this.discordLocator); + this.Name = "InstallConfigPanel"; + this.Size = new System.Drawing.Size(662, 284); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + private BandagedBD.Controls.FlatCheckBox cbShouldRestart; + private BandagedBD.Controls.DiscordLocator discordLocator; + private System.Windows.Forms.Label label1; + } +} diff --git a/BandagedBD/Panels/InstallConfigPanel.cs b/BandagedBD/Panels/InstallConfigPanel.cs new file mode 100644 index 0000000..1f4e482 --- /dev/null +++ b/BandagedBD/Panels/InstallConfigPanel.cs @@ -0,0 +1,40 @@ +using System; +using System.Windows.Forms; + +namespace BandagedBD.Panels { + public partial class InstallConfigPanel : UserControl, IPanel { + + private FormMain Window; + public void SetWindow(FormMain formMain) => Window = formMain; + + public string Title => "Installation Setup"; + public UserControl Control => this; + + public PanelTypes PreviousPanel => PanelTypes.Action; + public PanelTypes NextPanel => PanelTypes.Install; + + public bool shouldRestart => cbShouldRestart.Checked; + public string[] paths => Utilities.GetLocalPaths(discordLocator.stable, discordLocator.canary, discordLocator.ptb); + public string[] executables => Utilities.GetExecutables(discordLocator.stable, discordLocator.canary, discordLocator.ptb); + + public InstallConfigPanel() { + InitializeComponent(); + discordLocator.setLabel("BandagedBD will be installed to the locations below. Click browse if the locations are incorrect."); + discordLocator.setCheckboxLabel(Discord.Stable, "Install To Stable"); + discordLocator.setCheckboxLabel(Discord.Canary, "Install To Canary"); + discordLocator.setCheckboxLabel(Discord.PTB, "Install To PTB"); + discordLocator.OnCheckedChange += OnCheckedChange; + } + + public void OnShow() { + Window.btnBack.ShowEnable(); + Window.btnCancel.ShowEnable("Cancel"); + Window.btnNext.ShowDisable("Install"); + } + + private void OnCheckedChange(object sender, EventArgs e) { + if (discordLocator.stable || discordLocator.canary || discordLocator.ptb) Window.btnNext.ShowEnable("Install"); + else Window.btnNext.ShowDisable("Install"); + } + } +} diff --git a/BandagedBD/Panels/InstallConfigPanel.resx b/BandagedBD/Panels/InstallConfigPanel.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/BandagedBD/Panels/InstallConfigPanel.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/BandagedBD/Panels/InstallPanel.Designer.cs b/BandagedBD/Panels/InstallPanel.Designer.cs new file mode 100644 index 0000000..4f5e1d8 --- /dev/null +++ b/BandagedBD/Panels/InstallPanel.Designer.cs @@ -0,0 +1,126 @@ +namespace BandagedBD.Panels { + partial class InstallPanel { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) { + if (disposing && (components != null)) { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() { + this.rtbStatus = new System.Windows.Forms.RichTextBox(); + this.cbDetailed = new BandagedBD.Controls.FlatCheckBox(); + this.rtbDetailed = new System.Windows.Forms.RichTextBox(); + this.panel1 = new System.Windows.Forms.Panel(); + this.pbStatus = new BandagedBD.Controls.FlatProgressBar(); + this.SuspendLayout(); + // + // rtbStatus + // + this.rtbStatus.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.rtbStatus.BackColor = global::BandagedBD.Properties.Settings.Default.SecondaryBackground; + this.rtbStatus.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.rtbStatus.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.rtbStatus.Location = new System.Drawing.Point(13, 8); + this.rtbStatus.Name = "rtbStatus"; + this.rtbStatus.ReadOnly = true; + this.rtbStatus.Size = new System.Drawing.Size(474, 113); + this.rtbStatus.TabIndex = 0; + this.rtbStatus.Text = ""; + // + // cbDetailed + // + this.cbDetailed.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.cbDetailed.AutoSize = true; + this.cbDetailed.Cursor = System.Windows.Forms.Cursors.Hand; + this.cbDetailed.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.cbDetailed.Location = new System.Drawing.Point(4, 138); + this.cbDetailed.Name = "cbDetailed"; + this.cbDetailed.Size = new System.Drawing.Size(58, 17); + this.cbDetailed.TabIndex = 2; + this.cbDetailed.Text = "Details"; + this.cbDetailed.UseVisualStyleBackColor = true; + this.cbDetailed.CheckedChanged += new System.EventHandler(this.cbDetailed_CheckedChanged); + // + // rtbDetailed + // + this.rtbDetailed.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.rtbDetailed.BackColor = global::BandagedBD.Properties.Settings.Default.SecondaryBackground; + this.rtbDetailed.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.rtbDetailed.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.rtbDetailed.Location = new System.Drawing.Point(13, 8); + this.rtbDetailed.Name = "rtbDetailed"; + this.rtbDetailed.ReadOnly = true; + this.rtbDetailed.Size = new System.Drawing.Size(474, 113); + this.rtbDetailed.TabIndex = 3; + this.rtbDetailed.Text = ""; + this.rtbDetailed.Visible = false; + // + // panel1 + // + this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.panel1.BackColor = global::BandagedBD.Properties.Settings.Default.SecondaryBackground; + this.panel1.Location = new System.Drawing.Point(4, 0); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(491, 129); + this.panel1.TabIndex = 4; + // + // pbStatus + // + this.pbStatus.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.pbStatus.BackColor = global::BandagedBD.Properties.Settings.Default.SecondaryBackground; + this.pbStatus.ForeColor = global::BandagedBD.Properties.Settings.Default.Accent; + this.pbStatus.Location = new System.Drawing.Point(67, 135); + this.pbStatus.Name = "pbStatus"; + this.pbStatus.Size = new System.Drawing.Size(428, 23); + this.pbStatus.Style = System.Windows.Forms.ProgressBarStyle.Continuous; + this.pbStatus.TabIndex = 7; + // + // InstallPanel + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.Transparent; + this.Controls.Add(this.pbStatus); + this.Controls.Add(this.cbDetailed); + this.Controls.Add(this.rtbStatus); + this.Controls.Add(this.rtbDetailed); + this.Controls.Add(this.panel1); + this.Name = "InstallPanel"; + this.Size = new System.Drawing.Size(501, 166); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.RichTextBox rtbStatus; + private BandagedBD.Controls.FlatCheckBox cbDetailed; + private System.Windows.Forms.RichTextBox rtbDetailed; + private System.Windows.Forms.Panel panel1; + private Controls.FlatProgressBar pbStatus; + } +} diff --git a/BandagedBD/Panels/InstallPanel.cs b/BandagedBD/Panels/InstallPanel.cs new file mode 100644 index 0000000..7adb182 --- /dev/null +++ b/BandagedBD/Panels/InstallPanel.cs @@ -0,0 +1,195 @@ +using System; +using System.IO; +using System.IO.Compression; +using System.Net; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace BandagedBD.Panels { + public partial class InstallPanel : UserControl, IPanel { + private FormMain Window; + public void SetWindow(FormMain formMain) => Window = formMain; + + public string Title => "Installing"; + public UserControl Control => this; + + public PanelTypes PreviousPanel => PanelTypes.InstallConfig; + public PanelTypes NextPanel => PanelTypes.NONE; + + private InstallConfigPanel config => (InstallConfigPanel) Window.GetPanel(PanelTypes.InstallConfig); + + private WebHeaderCollection Headers = new WebHeaderCollection { ["User-Agent"] = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11" }; + private readonly SynchronizationContext _synchronizationContext; + private int progressChunk => 100 / config.paths.Length; + private int iteration = 0; + + private string repo = "rauenzi"; + private string branch = "injector"; + + public InstallPanel() { + InitializeComponent(); + _synchronizationContext = SynchronizationContext.Current; + } + + private void setProgress(int baseAmount) { + _synchronizationContext.Post(_ => { + pbStatus.Value = ((baseAmount * progressChunk) / 100) + (progressChunk * iteration); + }, 100); + } + + private async Task InstallTask() { + string[] processNames = config.executables; + string[] paths = config.paths; + for (int i = 0; i < paths.Length; i++) { + iteration = i; + Append($"Starting installation for {processNames[i]}"); + Append($"Killing {processNames[i]} Processes"); + string currentExecutable = Utilities.KillProcess(processNames[i], Append); + + + if (await DownloadBd(paths[i]) != 1) return 0; + setProgress(75); + if (Verify(paths[i]) != 1) return 0; + setProgress(90); + if (config.shouldRestart && currentExecutable != string.Empty) { + Append($"Restarting {processNames[i]}"); + Utilities.OpenProcess(currentExecutable); + } + setProgress(100); + Append($"Finished installing BandagedBD for {processNames[i]}!"); + Append("---------------------------------------------------------------------------------"); + } + return 1; + } + + private async Task DownloadBd(string installationPath) { + var channel = $"https://github.com/{repo}/BetterDiscordApp/archive/{branch}.zip"; + var dest = $"{installationPath}\\resources\\BetterDiscord.zip"; + + Append("Downloading BandagedBD package"); + + ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3; + + + using (var wc = new WebClient { Headers = this.Headers }) { + wc.DownloadProgressChanged += (sender, args) => { + setProgress(args.ProgressPercentage / 2); + }; + + Append($"Using channel: {channel}", true); + Append($"Downloading to: {dest}", true); + + await wc.DownloadFileTaskAsync(channel, dest); + + } + + Append("Finished downloading BandagedBD package"); + + ExtractBd(dest, $"{installationPath}\\resources"); + + return 1; + } + + private void ExtractBd(string path, string dest) { + + if (Directory.Exists($"{dest}\\app")) { + Append("Deleting old BetterDiscord"); + Directory.Delete($"{dest}\\app", true); + } + + if (Directory.Exists($"{dest}\\BetterDiscordApp-{branch}")) { + Append($"Deleting old BetterDiscordApp-{branch}"); + Directory.Delete($"{dest}\\BetterDiscordApp-{branch}", true); + } + + Append("Extracting BandagedBD package"); + + if (!File.Exists(path)) { + Append($"BandagedBD package does not exist in: {path}. Cannot continue."); + Window.Fail(); + return; + } + + var zar = ZipFile.OpenRead(path); + + if (!Directory.Exists(dest)) { + Directory.CreateDirectory(dest); + } + + zar.ExtractToDirectory(dest); + zar.Dispose(); + if (!Directory.Exists($"{dest}\\BetterDiscordApp-{branch}")) { + Append($"BandagedBD package does not exist in: {dest}\\BetterDiscordApp-{branch}. Cannot continue."); + Window.Fail(); + return; + } + + Append("Renaming package dir"); + + Directory.Move($"{dest}\\BetterDiscordApp-{branch}", $"{dest}\\app"); + + if (File.Exists(path)) { + Append($"Deleting temp file {path}"); + File.Delete(path); + } + } + + private int Verify(string installationPath) { + + Append("Verifying installation"); + + var appFolder = $"{installationPath}\\resources\\app"; + if (!Directory.Exists(appFolder)) { + Append($"{appFolder} does not exist! Verification failed!"); + Window.Fail(); + return 0; + } + + var injectorFiles = new[] { "index.js", "config.json", "package.json", "betterdiscord\\index.js", "betterdiscord\\config.json", "betterdiscord\\utils.js" }; + + foreach (var bdFile in injectorFiles) { + if (File.Exists($"{appFolder}\\{bdFile}")) { + Append($"Verifying {appFolder}\\{bdFile}", true); + continue; + } + Append($"{appFolder}\\{bdFile} does not exist! Verification failed!"); + Window.Fail(); + return 0; + } + + Append("Verification successful"); + + return 1; + } + + public void OnShow() { + rtbStatus.Text = ""; + Task.Run(InstallTask).ContinueWith(result => { + if (result.Result == 0) Window.Fail(); + _synchronizationContext.Post(o => { + Window.btnCancel.ShowEnable("Exit"); + }, result); + }); + + } + + private void Append(string text, bool detailed = false) { + _synchronizationContext.Post(o => { + if (!detailed) { + rtbStatus.AppendText((string) o); + rtbStatus.AppendText(Environment.NewLine); + } + rtbDetailed.AppendText((string) o); + rtbDetailed.AppendText(Environment.NewLine); + rtbStatus.ScrollToCaret(); + rtbDetailed.ScrollToCaret(); + }, text); + } + + private void cbDetailed_CheckedChanged(object sender, EventArgs e) { + rtbDetailed.Visible = cbDetailed.Checked; + rtbStatus.Visible = !cbDetailed.Checked; + } + } +} \ No newline at end of file diff --git a/BandagedBD/Panels/InstallPanel.resx b/BandagedBD/Panels/InstallPanel.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/BandagedBD/Panels/InstallPanel.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/BandagedBD/Panels/LicensePanel.Designer.cs b/BandagedBD/Panels/LicensePanel.Designer.cs new file mode 100644 index 0000000..ec881a7 --- /dev/null +++ b/BandagedBD/Panels/LicensePanel.Designer.cs @@ -0,0 +1,90 @@ +namespace BandagedBD.Panels { + partial class LicensePanel { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) { + if (disposing && (components != null)) { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() { + this.label1 = new System.Windows.Forms.Label(); + this.richTextBox1 = new System.Windows.Forms.RichTextBox(); + this.panel1 = new System.Windows.Forms.Panel(); + this.SuspendLayout(); + // + // label1 + // + this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.label1.ForeColor = System.Drawing.Color.White; + this.label1.Location = new System.Drawing.Point(3, 5); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(480, 13); + this.label1.TabIndex = 2; + this.label1.Text = "Please read the following License Agreement and accept the terms before continuin" + + "g the installation."; + // + // richTextBox1 + // + this.richTextBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.richTextBox1.BackColor = global::BandagedBD.Properties.Settings.Default.SecondaryBackground; + this.richTextBox1.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.richTextBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(128))); + this.richTextBox1.ForeColor = System.Drawing.Color.White; + this.richTextBox1.Location = new System.Drawing.Point(11, 29); + this.richTextBox1.Name = "richTextBox1"; + this.richTextBox1.ReadOnly = true; + this.richTextBox1.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.Vertical; + this.richTextBox1.Size = new System.Drawing.Size(521, 248); + this.richTextBox1.TabIndex = 3; + this.richTextBox1.Text = ""; + // + // panel1 + // + this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.panel1.BackColor = global::BandagedBD.Properties.Settings.Default.SecondaryBackground; + this.panel1.Location = new System.Drawing.Point(3, 21); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(536, 264); + this.panel1.TabIndex = 4; + // + // LicensePanel + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.Transparent; + this.Controls.Add(this.richTextBox1); + this.Controls.Add(this.label1); + this.Controls.Add(this.panel1); + this.Name = "LicensePanel"; + this.Size = new System.Drawing.Size(542, 306); + this.ResumeLayout(false); + + } + + #endregion + private System.Windows.Forms.Label label1; + private System.Windows.Forms.RichTextBox richTextBox1; + private System.Windows.Forms.Panel panel1; + } +} diff --git a/BandagedBD/Panels/LicensePanel.cs b/BandagedBD/Panels/LicensePanel.cs new file mode 100644 index 0000000..2196960 --- /dev/null +++ b/BandagedBD/Panels/LicensePanel.cs @@ -0,0 +1,27 @@ +using System.Windows.Forms; + +namespace BandagedBD.Panels { + + public partial class LicensePanel : UserControl, IPanel { + + private FormMain Window; + public void SetWindow(FormMain formMain) => Window = formMain; + + public string Title => "License Agreement"; + public UserControl Control => this; + + public PanelTypes PreviousPanel => PanelTypes.NONE; + public PanelTypes NextPanel => PanelTypes.Action; + + public LicensePanel() { + InitializeComponent(); + richTextBox1.Text += Properties.Resources.License; + } + + public void OnShow() { + Window.btnBack.HideDisable(); + Window.btnNext.ShowEnable("Agree"); + Window.btnCancel.ShowEnable("Decline"); + } + } +} diff --git a/BandagedBD/Panels/LicensePanel.resx b/BandagedBD/Panels/LicensePanel.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/BandagedBD/Panels/LicensePanel.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/BandagedBD/Panels/RepairConfigPanel.Designer.cs b/BandagedBD/Panels/RepairConfigPanel.Designer.cs new file mode 100644 index 0000000..5e7962e --- /dev/null +++ b/BandagedBD/Panels/RepairConfigPanel.Designer.cs @@ -0,0 +1,207 @@ +namespace BandagedBD.Panels +{ + partial class RepairConfigPanel + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.label2 = new System.Windows.Forms.Label(); + this.cbBootLoop = new BandagedBD.Controls.FlatCheckBox(); + this.cbInfinite = new BandagedBD.Controls.FlatCheckBox(); + this.cbError = new BandagedBD.Controls.FlatCheckBox(); + this.cbUninjected = new BandagedBD.Controls.FlatCheckBox(); + this.discordLocator = new BandagedBD.Controls.DiscordLocator(); + this.label1 = new System.Windows.Forms.Label(); + this.linkLabel1 = new System.Windows.Forms.LinkLabel(); + this.label3 = new System.Windows.Forms.Label(); + this.cbShouldRestart = new BandagedBD.Controls.FlatCheckBox(); + this.SuspendLayout(); + // + // label2 + // + this.label2.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.label2.AutoSize = true; + this.label2.BackColor = System.Drawing.Color.Transparent; + this.label2.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.label2.Location = new System.Drawing.Point(6, 197); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(292, 13); + this.label2.TabIndex = 25; + this.label2.Text = "Which of the following problems are affecting BandagedBD?"; + // + // cbBootLoop + // + this.cbBootLoop.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.cbBootLoop.AutoSize = true; + this.cbBootLoop.Cursor = System.Windows.Forms.Cursors.Hand; + this.cbBootLoop.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.cbBootLoop.Location = new System.Drawing.Point(120, 223); + this.cbBootLoop.Name = "cbBootLoop"; + this.cbBootLoop.Size = new System.Drawing.Size(121, 17); + this.cbBootLoop.TabIndex = 26; + this.cbBootLoop.Text = "Discord update loop"; + this.cbBootLoop.UseVisualStyleBackColor = true; + // + // cbInfinite + // + this.cbInfinite.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.cbInfinite.AutoSize = true; + this.cbInfinite.Cursor = System.Windows.Forms.Cursors.Hand; + this.cbInfinite.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.cbInfinite.Location = new System.Drawing.Point(120, 257); + this.cbInfinite.Name = "cbInfinite"; + this.cbInfinite.Size = new System.Drawing.Size(167, 17); + this.cbInfinite.TabIndex = 27; + this.cbInfinite.Text = "BandagedBD loading infinitely"; + this.cbInfinite.UseVisualStyleBackColor = true; + // + // cbError + // + this.cbError.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.cbError.AutoSize = true; + this.cbError.Cursor = System.Windows.Forms.Cursors.Hand; + this.cbError.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.cbError.Location = new System.Drawing.Point(358, 257); + this.cbError.Name = "cbError"; + this.cbError.Size = new System.Drawing.Size(176, 17); + this.cbError.TabIndex = 28; + this.cbError.Text = "Fatal JavaScript error on launch"; + this.cbError.UseVisualStyleBackColor = true; + // + // cbUninjected + // + this.cbUninjected.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.cbUninjected.AutoSize = true; + this.cbUninjected.Cursor = System.Windows.Forms.Cursors.Hand; + this.cbUninjected.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.cbUninjected.Location = new System.Drawing.Point(358, 223); + this.cbUninjected.Name = "cbUninjected"; + this.cbUninjected.Size = new System.Drawing.Size(218, 17); + this.cbUninjected.TabIndex = 29; + this.cbUninjected.Text = "BandagedBD not launching with Discord"; + this.cbUninjected.UseVisualStyleBackColor = true; + // + // discordLocator + // + this.discordLocator.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.discordLocator.BackColor = System.Drawing.Color.Transparent; + this.discordLocator.Location = new System.Drawing.Point(0, 2); + this.discordLocator.Name = "discordLocator"; + this.discordLocator.Size = new System.Drawing.Size(662, 161); + this.discordLocator.TabIndex = 30; + // + // label1 + // + this.label1.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.label1.AutoSize = true; + this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(128))); + this.label1.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.label1.Location = new System.Drawing.Point(179, 308); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(144, 13); + this.label1.TabIndex = 31; + this.label1.Text = "Can\'t find your problem here?"; + // + // linkLabel1 + // + this.linkLabel1.ActiveLinkColor = global::BandagedBD.Properties.Settings.Default.Accent; + this.linkLabel1.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.linkLabel1.AutoSize = true; + this.linkLabel1.Cursor = System.Windows.Forms.Cursors.Hand; + this.linkLabel1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(128))); + this.linkLabel1.LinkBehavior = System.Windows.Forms.LinkBehavior.HoverUnderline; + this.linkLabel1.LinkColor = global::BandagedBD.Properties.Settings.Default.Accent; + this.linkLabel1.Location = new System.Drawing.Point(322, 308); + this.linkLabel1.Name = "linkLabel1"; + this.linkLabel1.Size = new System.Drawing.Size(114, 13); + this.linkLabel1.TabIndex = 32; + this.linkLabel1.TabStop = true; + this.linkLabel1.Text = "Try this troubleshooter."; + this.linkLabel1.VisitedLinkColor = global::BandagedBD.Properties.Settings.Default.Accent; + this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked); + // + // label3 + // + this.label3.Anchor = System.Windows.Forms.AnchorStyles.None; + this.label3.AutoSize = true; + this.label3.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.label3.Location = new System.Drawing.Point(6, 169); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(95, 13); + this.label3.TabIndex = 34; + this.label3.Text = "Additional Options:"; + // + // cbShouldRestart + // + this.cbShouldRestart.Anchor = System.Windows.Forms.AnchorStyles.None; + this.cbShouldRestart.AutoSize = true; + this.cbShouldRestart.Checked = true; + this.cbShouldRestart.CheckState = System.Windows.Forms.CheckState.Checked; + this.cbShouldRestart.Cursor = System.Windows.Forms.Cursors.Hand; + this.cbShouldRestart.FlatAppearance.CheckedBackColor = System.Drawing.Color.Transparent; + this.cbShouldRestart.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.cbShouldRestart.Location = new System.Drawing.Point(120, 168); + this.cbShouldRestart.Name = "cbShouldRestart"; + this.cbShouldRestart.Size = new System.Drawing.Size(162, 17); + this.cbShouldRestart.TabIndex = 33; + this.cbShouldRestart.Text = "Restart All Discord Instances"; + this.cbShouldRestart.UseVisualStyleBackColor = true; + // + // RepairConfigPanel + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.Transparent; + this.Controls.Add(this.label3); + this.Controls.Add(this.cbShouldRestart); + this.Controls.Add(this.linkLabel1); + this.Controls.Add(this.label1); + this.Controls.Add(this.discordLocator); + this.Controls.Add(this.cbUninjected); + this.Controls.Add(this.cbError); + this.Controls.Add(this.cbInfinite); + this.Controls.Add(this.cbBootLoop); + this.Controls.Add(this.label2); + this.Name = "RepairConfigPanel"; + this.Size = new System.Drawing.Size(662, 335); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + private System.Windows.Forms.Label label2; + private BandagedBD.Controls.FlatCheckBox cbBootLoop; + private BandagedBD.Controls.FlatCheckBox cbInfinite; + private BandagedBD.Controls.FlatCheckBox cbError; + private BandagedBD.Controls.FlatCheckBox cbUninjected; + private BandagedBD.Controls.DiscordLocator discordLocator; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.LinkLabel linkLabel1; + private System.Windows.Forms.Label label3; + private BandagedBD.Controls.FlatCheckBox cbShouldRestart; + } +} diff --git a/BandagedBD/Panels/RepairConfigPanel.cs b/BandagedBD/Panels/RepairConfigPanel.cs new file mode 100644 index 0000000..5caffe0 --- /dev/null +++ b/BandagedBD/Panels/RepairConfigPanel.cs @@ -0,0 +1,56 @@ +using System; +using System.Windows.Forms; + +namespace BandagedBD.Panels { + public partial class RepairConfigPanel : UserControl, IPanel { + + private FormMain Window; + public void SetWindow(FormMain formMain) => Window = formMain; + + public PanelTypes PreviousPanel => PanelTypes.Action; + public PanelTypes NextPanel => PanelTypes.Repair; + + public string Title => "Repair Setup"; + public UserControl Control => this; + + public string[] localPaths => Utilities.GetLocalPaths(discordLocator.stable, discordLocator.canary, discordLocator.ptb, "resources\\app"); + public string[] roamingPaths => Utilities.GetRoamingPaths(discordLocator.stable, discordLocator.canary, discordLocator.ptb); + public string[] executables => Utilities.GetExecutables(discordLocator.stable, discordLocator.canary, discordLocator.ptb); + + public bool shouldDeleteRoaming => cbError.Checked || cbBootLoop.Checked; + public bool shouldDeleteLocal => cbBootLoop.Checked; + public bool shouldDeleteStorage => cbInfinite.Checked; + public bool shouldReinstall => cbUninjected.Checked || cbBootLoop.Checked; + public bool shouldRestart => cbShouldRestart.Checked; + + public RepairConfigPanel() { + InitializeComponent(); + discordLocator.setLabel("BandagedBD can attempt to fix several common problems. First we need to locate all BandagedBD installations:"); + discordLocator.setCheckboxLabel(Discord.Stable, "Repair On Stable"); + discordLocator.setCheckboxLabel(Discord.Canary, "Repair On Canary"); + discordLocator.setCheckboxLabel(Discord.PTB, "Repair On PTB"); + discordLocator.OnCheckedChange += OnCheckedChange; + cbError.CheckedChanged += OnCheckedChange; + cbBootLoop.CheckedChanged += OnCheckedChange; + cbUninjected.CheckedChanged += OnCheckedChange; + cbInfinite.CheckedChanged += OnCheckedChange; + } + + public void OnShow() { + Window.btnBack.ShowEnable(); + Window.btnCancel.ShowEnable("Cancel"); + Window.btnNext.ShowDisable("Repair"); + } + + private void OnCheckedChange(object sender, EventArgs e) { + bool location = discordLocator.stable || discordLocator.canary || discordLocator.ptb; + bool problem = cbError.Checked || cbBootLoop.Checked || cbUninjected.Checked || cbInfinite.Checked; + if (location && problem) Window.btnNext.ShowEnable("Repair"); + else Window.btnNext.ShowDisable("Repair"); + } + + private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { + Utilities.OpenProcess("https://0x71.cc/bd/troubleshoot/"); + } + } +} diff --git a/BandagedBD/Panels/RepairConfigPanel.resx b/BandagedBD/Panels/RepairConfigPanel.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/BandagedBD/Panels/RepairConfigPanel.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/BandagedBD/Panels/RepairPanel.Designer.cs b/BandagedBD/Panels/RepairPanel.Designer.cs new file mode 100644 index 0000000..4725626 --- /dev/null +++ b/BandagedBD/Panels/RepairPanel.Designer.cs @@ -0,0 +1,94 @@ +namespace BandagedBD.Panels +{ + partial class RepairPanel + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.richText = new System.Windows.Forms.RichTextBox(); + this.panel1 = new System.Windows.Forms.Panel(); + this.pbStatus = new BandagedBD.Controls.FlatProgressBar(); + this.SuspendLayout(); + // + // richText + // + this.richText.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.richText.BackColor = global::BandagedBD.Properties.Settings.Default.SecondaryBackground; + this.richText.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.richText.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.richText.Location = new System.Drawing.Point(13, 8); + this.richText.Name = "richText"; + this.richText.ReadOnly = true; + this.richText.Size = new System.Drawing.Size(474, 113); + this.richText.TabIndex = 0; + this.richText.Text = ""; + // + // panel1 + // + this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.panel1.BackColor = global::BandagedBD.Properties.Settings.Default.SecondaryBackground; + this.panel1.Location = new System.Drawing.Point(4, 0); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(491, 129); + this.panel1.TabIndex = 4; + // + // pbStatus + // + this.pbStatus.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.pbStatus.BackColor = global::BandagedBD.Properties.Settings.Default.SecondaryBackground; + this.pbStatus.ForeColor = global::BandagedBD.Properties.Settings.Default.Accent; + this.pbStatus.Location = new System.Drawing.Point(4, 135); + this.pbStatus.Name = "pbStatus"; + this.pbStatus.Size = new System.Drawing.Size(491, 23); + this.pbStatus.Style = System.Windows.Forms.ProgressBarStyle.Continuous; + this.pbStatus.TabIndex = 5; + // + // RepairPanel + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.Transparent; + this.Controls.Add(this.pbStatus); + this.Controls.Add(this.richText); + this.Controls.Add(this.panel1); + this.Name = "RepairPanel"; + this.Size = new System.Drawing.Size(501, 166); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.RichTextBox richText; + private System.Windows.Forms.Panel panel1; + private Controls.FlatProgressBar pbStatus; + } +} diff --git a/BandagedBD/Panels/RepairPanel.cs b/BandagedBD/Panels/RepairPanel.cs new file mode 100644 index 0000000..e128234 --- /dev/null +++ b/BandagedBD/Panels/RepairPanel.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Windows.Forms; + +namespace BandagedBD.Panels { + public partial class RepairPanel : UserControl, IPanel { + + private FormMain Window; + public void SetWindow(FormMain formMain) => Window = formMain; + + public string Title => "Repairing"; + public UserControl Control => this; + + public PanelTypes PreviousPanel => PanelTypes.InstallConfig; + public PanelTypes NextPanel => Config.shouldReinstall ? PanelTypes.InstallConfig : PanelTypes.NONE; + + private RepairConfigPanel Config => (RepairConfigPanel) Window.GetPanel(PanelTypes.RepairConfig); + + public RepairPanel() { + InitializeComponent(); + } + + private void Repair() { + List exes = new List(); + foreach (var process in Config.executables) exes.Add(Utilities.KillProcess(process, Append)); + pbStatus.Value = 25; + if (Config.shouldDeleteRoaming) Utilities.DeleteFolders(Config.roamingPaths, Append); + pbStatus.Value = 50; + if (Config.shouldDeleteLocal) Utilities.DeleteFolders(Config.localPaths, Append); + pbStatus.Value = 75; + if (Config.shouldDeleteStorage) Utilities.DeleteFiles(new string[] { $"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\\BetterDiscord\\bdstorage.json" }, Append); + pbStatus.Value = 100; + if (Config.shouldReinstall) { + Append("In order to complete repairs, BandagedBD needs to be reinstalled. Click Install to continue."); + Window.btnNext.ShowEnable("Install"); + var confirmResult = MessageBox.Show("In order to complete repairs, BandagedBD needs to be reinstalled. Reinstall now?", "Reinstall needed!", MessageBoxButtons.YesNo); + if (confirmResult == DialogResult.Yes) Window.btnNext.PerformClick(); + else { + Window.btnNext.HideDisable(); + Window.btnBack.HideDisable(); + Window.btnCancel.ShowEnable("Exit"); + } + } + else { + foreach (var exe in exes) { + if (exe != string.Empty && Config.shouldRestart) Utilities.OpenProcess(exe); + } + Append("Repairs completed!"); + } + + } + + public void OnShow() { + richText.Text = ""; + if (Config.shouldReinstall) Window.btnNext.HideDisable("Install"); + Repair(); + } + + private void Append(string text) { + Debug.WriteLine(text); + richText.AppendText(text); + richText.AppendText(Environment.NewLine); + richText.ScrollToCaret(); + } + } +} diff --git a/BandagedBD/Panels/RepairPanel.resx b/BandagedBD/Panels/RepairPanel.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/BandagedBD/Panels/RepairPanel.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/BandagedBD/Panels/UninstallConfigPanel.Designer.cs b/BandagedBD/Panels/UninstallConfigPanel.Designer.cs new file mode 100644 index 0000000..e7d7a2f --- /dev/null +++ b/BandagedBD/Panels/UninstallConfigPanel.Designer.cs @@ -0,0 +1,109 @@ +namespace BandagedBD.Panels +{ + partial class UninstallConfigPanel + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.userData = new BandagedBD.Controls.FlatCheckBox(); + this.label1 = new System.Windows.Forms.Label(); + this.cbShouldRestart = new BandagedBD.Controls.FlatCheckBox(); + this.discordLocator = new BandagedBD.Controls.DiscordLocator(); + this.SuspendLayout(); + // + // userData + // + this.userData.Anchor = System.Windows.Forms.AnchorStyles.None; + this.userData.AutoSize = true; + this.userData.Cursor = System.Windows.Forms.Cursors.Hand; + this.userData.FlatAppearance.CheckedBackColor = System.Drawing.Color.Transparent; + this.userData.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.userData.Location = new System.Drawing.Point(9, 196); + this.userData.Name = "userData"; + this.userData.Size = new System.Drawing.Size(170, 17); + this.userData.TabIndex = 5; + this.userData.Text = "Remove all BandagedBD data"; + this.userData.UseVisualStyleBackColor = true; + // + // label1 + // + this.label1.Anchor = System.Windows.Forms.AnchorStyles.None; + this.label1.AutoSize = true; + this.label1.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.label1.Location = new System.Drawing.Point(6, 170); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(95, 13); + this.label1.TabIndex = 7; + this.label1.Text = "Additional Options:"; + // + // cbShouldRestart + // + this.cbShouldRestart.Anchor = System.Windows.Forms.AnchorStyles.None; + this.cbShouldRestart.AutoSize = true; + this.cbShouldRestart.Checked = true; + this.cbShouldRestart.CheckState = System.Windows.Forms.CheckState.Checked; + this.cbShouldRestart.Cursor = System.Windows.Forms.Cursors.Hand; + this.cbShouldRestart.FlatAppearance.CheckedBackColor = System.Drawing.Color.Transparent; + this.cbShouldRestart.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.cbShouldRestart.Location = new System.Drawing.Point(9, 219); + this.cbShouldRestart.Name = "cbShouldRestart"; + this.cbShouldRestart.Size = new System.Drawing.Size(162, 17); + this.cbShouldRestart.TabIndex = 34; + this.cbShouldRestart.Text = "Restart All Discord Instances"; + this.cbShouldRestart.UseVisualStyleBackColor = true; + // + // discordLocator + // + this.discordLocator.Anchor = System.Windows.Forms.AnchorStyles.None; + this.discordLocator.BackColor = System.Drawing.Color.Transparent; + this.discordLocator.Location = new System.Drawing.Point(0, 3); + this.discordLocator.Name = "discordLocator"; + this.discordLocator.Size = new System.Drawing.Size(662, 161); + this.discordLocator.TabIndex = 6; + // + // UninstallConfigPanel + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.Transparent; + this.Controls.Add(this.cbShouldRestart); + this.Controls.Add(this.label1); + this.Controls.Add(this.userData); + this.Controls.Add(this.discordLocator); + this.Name = "UninstallConfigPanel"; + this.Size = new System.Drawing.Size(662, 284); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + private BandagedBD.Controls.FlatCheckBox userData; + private BandagedBD.Controls.DiscordLocator discordLocator; + private System.Windows.Forms.Label label1; + private BandagedBD.Controls.FlatCheckBox cbShouldRestart; + } +} diff --git a/BandagedBD/Panels/UninstallConfigPanel.cs b/BandagedBD/Panels/UninstallConfigPanel.cs new file mode 100644 index 0000000..5a174a7 --- /dev/null +++ b/BandagedBD/Panels/UninstallConfigPanel.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Windows.Forms; + +namespace BandagedBD.Panels { + public partial class UninstallConfigPanel : UserControl, IPanel { + + private FormMain Window; + public void SetWindow(FormMain formMain) => Window = formMain; + + public string Title => "Uninstall Setup"; + public UserControl Control => this; + + public PanelTypes PreviousPanel => PanelTypes.Action; + public PanelTypes NextPanel => PanelTypes.Uninstall; + + public string[] pathsToDelete { + get { + List paths = new List(Utilities.GetLocalPaths(discordLocator.stable, discordLocator.canary, discordLocator.ptb, "resources\\app")); + if (userData.Checked) paths.Add($"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\\BetterDiscord"); + return paths.ToArray(); + } + } + public string[] executables => Utilities.GetExecutables(discordLocator.stable, discordLocator.canary, discordLocator.ptb); + public bool shouldRestart => cbShouldRestart.Checked; + + public UninstallConfigPanel() { + InitializeComponent(); + discordLocator.setLabel("BandagedBD will be removed from the locations below. Click browse if the locations are incorrect."); + discordLocator.setCheckboxLabel(Discord.Stable, "Remove from Stable"); + discordLocator.setCheckboxLabel(Discord.Canary, "Remove from Canary"); + discordLocator.setCheckboxLabel(Discord.PTB, "Remove from PTB"); + discordLocator.OnCheckedChange += OnCheckedChange; + } + + public void OnShow() { + Window.btnBack.ShowEnable(); + Window.btnCancel.ShowEnable("Cancel"); + Window.btnNext.ShowDisable("Uninstall"); + } + + private void OnCheckedChange(object sender, EventArgs e) { + if (discordLocator.stable || discordLocator.canary || discordLocator.ptb) Window.btnNext.ShowEnable("Uninstall"); + else Window.btnNext.ShowDisable("Uninstall"); + } + } +} diff --git a/BandagedBD/Panels/UninstallConfigPanel.resx b/BandagedBD/Panels/UninstallConfigPanel.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/BandagedBD/Panels/UninstallConfigPanel.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/BandagedBD/Panels/UninstallPanel.Designer.cs b/BandagedBD/Panels/UninstallPanel.Designer.cs new file mode 100644 index 0000000..310992d --- /dev/null +++ b/BandagedBD/Panels/UninstallPanel.Designer.cs @@ -0,0 +1,94 @@ +namespace BandagedBD.Panels +{ + partial class UninstallPanel + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.richText = new System.Windows.Forms.RichTextBox(); + this.panel1 = new System.Windows.Forms.Panel(); + this.pbStatus = new BandagedBD.Controls.FlatProgressBar(); + this.SuspendLayout(); + // + // richText + // + this.richText.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.richText.BackColor = global::BandagedBD.Properties.Settings.Default.SecondaryBackground; + this.richText.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.richText.ForeColor = global::BandagedBD.Properties.Settings.Default.TextColor; + this.richText.Location = new System.Drawing.Point(13, 8); + this.richText.Name = "richText"; + this.richText.ReadOnly = true; + this.richText.Size = new System.Drawing.Size(474, 113); + this.richText.TabIndex = 0; + this.richText.Text = ""; + // + // panel1 + // + this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.panel1.BackColor = global::BandagedBD.Properties.Settings.Default.SecondaryBackground; + this.panel1.Location = new System.Drawing.Point(4, 0); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(491, 129); + this.panel1.TabIndex = 4; + // + // pbStatus + // + this.pbStatus.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.pbStatus.BackColor = global::BandagedBD.Properties.Settings.Default.SecondaryBackground; + this.pbStatus.ForeColor = global::BandagedBD.Properties.Settings.Default.Accent; + this.pbStatus.Location = new System.Drawing.Point(4, 135); + this.pbStatus.Name = "pbStatus"; + this.pbStatus.Size = new System.Drawing.Size(491, 23); + this.pbStatus.Style = System.Windows.Forms.ProgressBarStyle.Continuous; + this.pbStatus.TabIndex = 6; + // + // UninstallPanel + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.Transparent; + this.Controls.Add(this.pbStatus); + this.Controls.Add(this.richText); + this.Controls.Add(this.panel1); + this.Name = "UninstallPanel"; + this.Size = new System.Drawing.Size(501, 166); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.RichTextBox richText; + private System.Windows.Forms.Panel panel1; + private Controls.FlatProgressBar pbStatus; + } +} diff --git a/BandagedBD/Panels/UninstallPanel.cs b/BandagedBD/Panels/UninstallPanel.cs new file mode 100644 index 0000000..40592c3 --- /dev/null +++ b/BandagedBD/Panels/UninstallPanel.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Windows.Forms; + +namespace BandagedBD.Panels { + public partial class UninstallPanel : UserControl, IPanel { + + private FormMain Window; + public void SetWindow(FormMain formMain) => Window = formMain; + + public string Title => "Uninstalling"; + public UserControl Control => this; + + public PanelTypes PreviousPanel => PanelTypes.InstallConfig; + public PanelTypes NextPanel => PanelTypes.NONE; + + private UninstallConfigPanel Config => (UninstallConfigPanel) Window.GetPanel(PanelTypes.UninstallConfig); + + public UninstallPanel() { + InitializeComponent(); + } + + private void Uninstall() { + List exes = new List(); + foreach (var process in Config.executables) exes.Add(Utilities.KillProcess(process, Append)); + pbStatus.Value = 20; + string[] paths = Config.pathsToDelete; + int chunk = 80 / paths.Length; + int i = 0; + Utilities.DeleteFolders(paths, (message) => { + Append(message); + pbStatus.Value = (chunk * i + chunk) + 20; + i++; + }); + foreach (var exe in exes) { + if (exe != string.Empty && Config.shouldRestart) Utilities.OpenProcess(exe); + } + Append("Uninstalling Complete!"); + } + + public void OnShow() { + richText.Text = ""; + Uninstall(); + Window.btnCancel.ShowEnable("Exit"); + } + + private void Append(string text) { + richText.AppendText(text); + richText.AppendText(Environment.NewLine); + richText.ScrollToCaret(); + } + } +} diff --git a/BandagedBD/Panels/UninstallPanel.resx b/BandagedBD/Panels/UninstallPanel.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/BandagedBD/Panels/UninstallPanel.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/BandagedBD/Program.cs b/BandagedBD/Program.cs new file mode 100644 index 0000000..37b7967 --- /dev/null +++ b/BandagedBD/Program.cs @@ -0,0 +1,16 @@ +using System; +using System.Windows.Forms; + +namespace BandagedBD { + static class Program { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new FormMain()); + } + } +} diff --git a/BandagedBD/Properties/AssemblyInfo.cs b/BandagedBD/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..e476b4c --- /dev/null +++ b/BandagedBD/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("BandagedBD")] +[assembly: AssemblyDescription("BetterDiscord Windows Installer")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Zerebos")] +[assembly: AssemblyProduct("BandagedBD")] +[assembly: AssemblyCopyright("Copyright © 2018")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("390615f1-ce33-4173-9e8c-4e4f3eb1758d")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("0.3.0.0")] +[assembly: AssemblyFileVersion("0.3.0.0")] diff --git a/BandagedBD/Properties/Resources.Designer.cs b/BandagedBD/Properties/Resources.Designer.cs new file mode 100644 index 0000000..54bd14c --- /dev/null +++ b/BandagedBD/Properties/Resources.Designer.cs @@ -0,0 +1,125 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace BandagedBD.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BandagedBD.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap archive_small { + get { + object obj = ResourceManager.GetObject("archive_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap BBDVS { + get { + object obj = ResourceManager.GetObject("BBDVS", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap build_small { + get { + object obj = ResourceManager.GetObject("build_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap delete_small { + get { + object obj = ResourceManager.GetObject("delete_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to Copyright (c) 2015 - Present Jiiks | 2017 - Present Zerebos + /// + ///Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + /// + ///The above cop [rest of string was truncated]";. + /// + internal static string License { + get { + return ResourceManager.GetString("License", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to 0.3.2. + /// + internal static string Version { + get { + return ResourceManager.GetString("Version", resourceCulture); + } + } + } +} diff --git a/BandagedBD/Properties/Resources.resx b/BandagedBD/Properties/Resources.resx new file mode 100644 index 0000000..60b1281 --- /dev/null +++ b/BandagedBD/Properties/Resources.resx @@ -0,0 +1,318 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAAOD8YVAtlgAAAvdpQ0NQUGhv + dG9zaG9wIElDQyBwcm9maWxlAAA4y2NgYJ7g6OLkyiTAwFBQVFLkHuQYGREZpcB+noGNgZkBDBKTiwsc + AwJ8QOy8/LxUBlTAyMDw7RqIZGC4rAsyi4E0wJoMtBhIHwBio5TU4mQg/QWI08tLCoDijDFAtkhSNphd + AGJnhwQ5A9ktDAxMPCWpFSC9DM75BZVFmekZJQqGlpaWCo4p+UmpCsGVxSWpucUKnnnJ+UUF+UWJJakp + QLVQO0CA1yW/RME9MTNPwchAlYHKABSOEBYifBBiCJBcWlQGD0oGBgEGBQYDBgeGAIZEhnqGBQxHGd4w + ijO6MJYyrmC8xyTGFMQ0gekCszBzJPNC5jcsliwdLLdY9VhbWe+xWbJNY/vGHs6+m0OJo4vjC2ci5wUu + R64t3JrcC3ikeKbyCvFO4hPmm8Yvw79YQEdgh6Cr4BWhVKEfwr0iKiJ7RcNFv4hNEjcSvyJRISkneUwq + X1pa+oRMmay67C25PnkX+T8KWxULlfSU3iqvVSlQNVH9qXZQvUsjVFNJ84PWAe1JOqm6VnqCeq/0jxgs + MKw1ijG2NZE3ZTZ9aXbBfKfFEssJVnXWuTZxtoF2rvbWDsaOOk5qzkouCq7ybgruyh7qnrpeJt42Pu6+ + wX4J/vkB9YETg5YG7wq5GPoynClCLtIqKiK6ImZm7J64BwlsibpJYckNKWtSb6ZzZFhkZmbNzb6Yy55n + n19RsKnwXbF2SVbpqrI3FfqVJVW7ahhrveqm1j9s1GuqaT7bKtdW2H60U7qrqPt0r2pfY//diTaTZk/+ + OzV+2uEZGjP7Z32fkzD39HzzBUsXiSxuXfJtWebyeytDVp1e47J233rLDds2mWzestVk2/YdVjv373bd + c3Zf2P4HB3MO/TzSfkz8+IqT1qfOnUk+++v8pIval45eSbz67/qcmza37t6pv6d8/8TDvMdiT/Y/y3wh + 8vLg6/y38u8ufGj6ZPr51dcF38N/Cvw69af1n+P//wANAA8013ReGAAAAAlwSFlzAAALEQAACxEBf2Rf + kQAAAV9JREFUWEftljtOA0EQRJ2QggRHICACYiIEEQkJCQfgAFyFa5ACCZcg5Q6IwPwCPtJST2pL0+M2 + u/LsjBNKekGXp7vKcgCTrutWSmi2JDRbEpotCU3jVLyKUj0JbkUZCwvsC3QvDgs4Eg8CcXMua84QW2L2 + zS/EbgF74lKgF8Ftl+cG40bU0p1weW4wvkQtfQuX5wbjTdQSt12eG4ypqCVuuzw3GP8FhhS4EucZeH0a + rcCxyPfw+rRUgQ/xKPBnnIl8Dy99ww67qfDdnhsMHqViPhF8ti42xJrNKXh8xhtmdqJbbs8NRr6E+IOy + I6L3EbxlJ9fSBdCPOBDRTgpveBupqADqK/FXOCougBaV6AtHoxRAeYkh4Wi0AojAbWNIOBq1AOKfDBiq + QQXeRS1x2+W5wfgUtcRtl+cG41bUErddnhuMTXEtngW/2Rhwi5vcdnluWAWh2ZLQbElotqOb/AI+U8G+ + OLxbNAAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAAOD8YVAtlgAAAvdpQ0NQUGhv + dG9zaG9wIElDQyBwcm9maWxlAAA4y2NgYJ7g6OLkyiTAwFBQVFLkHuQYGREZpcB+noGNgZkBDBKTiwsc + AwJ8QOy8/LxUBlTAyMDw7RqIZGC4rAsyi4E0wJoMtBhIHwBio5TU4mQg/QWI08tLCoDijDFAtkhSNphd + AGJnhwQ5A9ktDAxMPCWpFSC9DM75BZVFmekZJQqGlpaWCo4p+UmpCsGVxSWpucUKnnnJ+UUF+UWJJakp + QLVQO0CA1yW/RME9MTNPwchAlYHKABSOEBYifBBiCJBcWlQGD0oGBgEGBQYDBgeGAIZEhnqGBQxHGd4w + ijO6MJYyrmC8xyTGFMQ0gekCszBzJPNC5jcsliwdLLdY9VhbWe+xWbJNY/vGHs6+m0OJo4vjC2ci5wUu + R64t3JrcC3ikeKbyCvFO4hPmm8Yvw79YQEdgh6Cr4BWhVKEfwr0iKiJ7RcNFv4hNEjcSvyJRISkneUwq + X1pa+oRMmay67C25PnkX+T8KWxULlfSU3iqvVSlQNVH9qXZQvUsjVFNJ84PWAe1JOqm6VnqCeq/0jxgs + MKw1ijG2NZE3ZTZ9aXbBfKfFEssJVnXWuTZxtoF2rvbWDsaOOk5qzkouCq7ybgruyh7qnrpeJt42Pu6+ + wX4J/vkB9YETg5YG7wq5GPoynClCLtIqKiK6ImZm7J64BwlsibpJYckNKWtSb6ZzZFhkZmbNzb6Yy55n + n19RsKnwXbF2SVbpqrI3FfqVJVW7ahhrveqm1j9s1GuqaT7bKtdW2H60U7qrqPt0r2pfY//diTaTZk/+ + OzV+2uEZGjP7Z32fkzD39HzzBUsXiSxuXfJtWebyeytDVp1e47J233rLDds2mWzestVk2/YdVjv373bd + c3Zf2P4HB3MO/TzSfkz8+IqT1qfOnUk+++v8pIval45eSbz67/qcmza37t6pv6d8/8TDvMdiT/Y/y3wh + 8vLg6/y38u8ufGj6ZPr51dcF38N/Cvw69af1n+P//wANAA8013ReGAAAAAlwSFlzAAALEQAACxEBf2Rf + kQAAAZtJREFUWEfF1k8rRUEYx/HLTsneytYLURaUDZJiL/m7kG4oJCy8AjskC7wWpSx4A/Imju9znNHM + 3OfMzD1zD7/61JznzjM93c6953SKovhXarEygXmc4R4PuMQMtP2NqMXKAuryjnVofX1Ri5ZthPIMrS+Z + WvRsIJSsIdSiYguhrEDrizKLcSybYo0d1OUTQ9D6gsxiDpJ9OBs8S6jLNLSeILM4gckunE2W0ADn0HqC + zOIWduTrdjYi9ouQM/yeKLO4gx+58cznsZtQcgOzP5lZXECL/Bkt/iyjOYZzeAqzkBsoN5NwDk9hFsP4 + Qk724Byewr5YRW66sM+M8gtPyM0B/HNracVH5OYQ2tk91CLW8IGcJA2hFityY85C/uHkZURcYQpyeEqi + Q6jFRPKmlJIjaP0ltdiHU6REnjVaf/YAwn6QhaIO0VNoqPEQzkWmRkPYBwyCPJBSIjdw2eMfMAipP9FN + tDKASBlC/nFbG0CEhniDvAi3OoDQhnjFGMo9fkMb5BFt8oJR/H5ub2yTvFNeY8SqlZyLv1d0vgGxPCyB + cSeH3AAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAAOD8YVAtlgAAAvdpQ0NQUGhv + dG9zaG9wIElDQyBwcm9maWxlAAA4y2NgYJ7g6OLkyiTAwFBQVFLkHuQYGREZpcB+noGNgZkBDBKTiwsc + AwJ8QOy8/LxUBlTAyMDw7RqIZGC4rAsyi4E0wJoMtBhIHwBio5TU4mQg/QWI08tLCoDijDFAtkhSNphd + AGJnhwQ5A9ktDAxMPCWpFSC9DM75BZVFmekZJQqGlpaWCo4p+UmpCsGVxSWpucUKnnnJ+UUF+UWJJakp + QLVQO0CA1yW/RME9MTNPwchAlYHKABSOEBYifBBiCJBcWlQGD0oGBgEGBQYDBgeGAIZEhnqGBQxHGd4w + ijO6MJYyrmC8xyTGFMQ0gekCszBzJPNC5jcsliwdLLdY9VhbWe+xWbJNY/vGHs6+m0OJo4vjC2ci5wUu + R64t3JrcC3ikeKbyCvFO4hPmm8Yvw79YQEdgh6Cr4BWhVKEfwr0iKiJ7RcNFv4hNEjcSvyJRISkneUwq + X1pa+oRMmay67C25PnkX+T8KWxULlfSU3iqvVSlQNVH9qXZQvUsjVFNJ84PWAe1JOqm6VnqCeq/0jxgs + MKw1ijG2NZE3ZTZ9aXbBfKfFEssJVnXWuTZxtoF2rvbWDsaOOk5qzkouCq7ybgruyh7qnrpeJt42Pu6+ + wX4J/vkB9YETg5YG7wq5GPoynClCLtIqKiK6ImZm7J64BwlsibpJYckNKWtSb6ZzZFhkZmbNzb6Yy55n + n19RsKnwXbF2SVbpqrI3FfqVJVW7ahhrveqm1j9s1GuqaT7bKtdW2H60U7qrqPt0r2pfY//diTaTZk/+ + OzV+2uEZGjP7Z32fkzD39HzzBUsXiSxuXfJtWebyeytDVp1e47J233rLDds2mWzestVk2/YdVjv373bd + c3Zf2P4HB3MO/TzSfkz8+IqT1qfOnUk+++v8pIval45eSbz67/qcmza37t6pv6d8/8TDvMdiT/Y/y3wh + 8vLg6/y38u8ufGj6ZPr51dcF38N/Cvw69af1n+P//wANAA8013ReGAAAAAlwSFlzAAALEQAACxEBf2Rf + kQAAAYpJREFUWEftlj1KxFAUhcdGFEQtxAW4Cl2CjVvQxtYVuAVbFQTBTm1nASK2gohoIbZWFlpoI2I8 + X5Ind56XDIl5z8YDH7yc+5NDMoQZFEXxp7hmTlwzJ66ZE9dsYFKcC/QSgajR4826uGbNljgTJ+JYHIhr + MU700MsMs+xgl3ePxgAs6Evs8u7RGOBQIB7vc0fCq2GXd4/GADNiXkwYry3MsoNdXn3sj3Ba7IgjsdsS + Zphlh7e7xDUNcyI8xi5ilh3e7hLXNPwH8AJ8iPfqOCI8alZJAmyLZfFZXlXijEfNqvcAeyLUVjFqcQ7+ + Pkat3gNciCkR6hti3VxToyeo9wDoXiyIuHdRPAirJAHQpYh7r0SsZAE2RdyLFytJgDUR6ks14ZqaVe8B + +LaH2qx4quEcfHqCkjyBFUHtpryqxBmPmlWSAI/itjqO6E5Qs0oSoI1+HYB3yz+brmLW/j5+4JoRp6Kr + mPV2fuOaEXz1huJNvAoeaxP00MuM98UcwTVz4po5cc2cuGY+isEXoP8jiBrKoSYAAAAASUVORK5CYII= + + + + Copyright (c) 2015 - Present Jiiks | 2017 - Present Zerebos + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + + 0.3.2 + + + + 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 + TkSuQmCC + + + \ No newline at end of file diff --git a/BandagedBD/Properties/Settings.Designer.cs b/BandagedBD/Properties/Settings.Designer.cs new file mode 100644 index 0000000..956ca7f --- /dev/null +++ b/BandagedBD/Properties/Settings.Designer.cs @@ -0,0 +1,74 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace BandagedBD.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.5.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool AgreedToTerms { + get { + return ((bool)(this["AgreedToTerms"])); + } + set { + this["AgreedToTerms"] = value; + } + } + + [global::System.Configuration.ApplicationScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("28, 28, 28")] + public global::System.Drawing.Color PrimaryBackground { + get { + return ((global::System.Drawing.Color)(this["PrimaryBackground"])); + } + } + + [global::System.Configuration.ApplicationScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("42, 42, 42")] + public global::System.Drawing.Color SecondaryBackground { + get { + return ((global::System.Drawing.Color)(this["SecondaryBackground"])); + } + } + + [global::System.Configuration.ApplicationScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("62, 130, 229")] + public global::System.Drawing.Color Accent { + get { + return ((global::System.Drawing.Color)(this["Accent"])); + } + } + + [global::System.Configuration.ApplicationScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("White")] + public global::System.Drawing.Color TextColor { + get { + return ((global::System.Drawing.Color)(this["TextColor"])); + } + } + } +} diff --git a/BandagedBD/Properties/Settings.settings b/BandagedBD/Properties/Settings.settings new file mode 100644 index 0000000..1d740f3 --- /dev/null +++ b/BandagedBD/Properties/Settings.settings @@ -0,0 +1,21 @@ + + + + + + False + + + 28, 28, 28 + + + 42, 42, 42 + + + 62, 130, 229 + + + White + + + \ No newline at end of file diff --git a/BandagedBD/Resources/BBDVS.png b/BandagedBD/Resources/BBDVS.png new file mode 100644 index 0000000..6ac0684 Binary files /dev/null and b/BandagedBD/Resources/BBDVS.png differ diff --git a/BandagedBD/Resources/archive_small.png b/BandagedBD/Resources/archive_small.png new file mode 100644 index 0000000..da9da23 Binary files /dev/null and b/BandagedBD/Resources/archive_small.png differ diff --git a/BandagedBD/Resources/build_small.png b/BandagedBD/Resources/build_small.png new file mode 100644 index 0000000..478c5e6 Binary files /dev/null and b/BandagedBD/Resources/build_small.png differ diff --git a/BandagedBD/Resources/delete_small.png b/BandagedBD/Resources/delete_small.png new file mode 100644 index 0000000..d72a4a9 Binary files /dev/null and b/BandagedBD/Resources/delete_small.png differ diff --git a/BandagedBD/Utilities.cs b/BandagedBD/Utilities.cs new file mode 100644 index 0000000..989afdd --- /dev/null +++ b/BandagedBD/Utilities.cs @@ -0,0 +1,152 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Text.RegularExpressions; +using System.Windows.Forms; + +namespace BandagedBD { + + public enum Discord { Stable, Canary, PTB }; + + public class Utilities { + public static readonly Regex _matcher = new Regex(@"[0-9]+\.[0-9]+\.[0-9]+"); + public static string StablePath => $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\\Discord"; + public static bool StableExists() => Directory.Exists(StablePath); + public static string CanaryPath => $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\\DiscordCanary"; + public static bool CanaryExists() => Directory.Exists(CanaryPath); + public static string PtbPath => $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\\DiscordPTB"; + public static bool PtbExists() => Directory.Exists(PtbPath); + + public static string CurrentStablePath = StableExists() ? StablePath : null; + public static string CurrentCanaryPath = CanaryExists() ? CanaryPath : null; + public static string CurrentPtbPath = PtbExists() ? PtbPath : null; + + public static void OpenProcess(string url) { + Process.Start(url); + } + + public static void DeleteFolders(string[] paths, Action onMessage = null) { + for (int i = 0; i < paths.Length; i++) { + onMessage?.Invoke($"Deleting {paths[i]}"); + if (!Directory.Exists(paths[i])) { + onMessage?.Invoke($"{paths[i]} does not exist, skipping."); + continue; + } + try { + Directory.Delete(paths[i], true); + } + catch { + onMessage?.Invoke($"Could not delete {paths[i]} please delete manually."); + } + } + } + + public static void DeleteFiles(string[] paths, Action onMessage = null) { + for (int i = 0; i < paths.Length; i++) { + onMessage?.Invoke($"Deleting {paths[i]}"); + try { + File.Delete(paths[i]); + } + catch { + onMessage?.Invoke($"Could not delete {paths[i]} please delete manually."); + } + } + } + + public static string KillProcess(string processName, Action onMessage = null) { + return KillProcess(processName, (str, boolean) => { + onMessage?.Invoke(str); + }); + } + + public static string KillProcess(string processName, Action onMessage = null) { + var currentExecutable = string.Empty; + try { + foreach (var process in Process.GetProcessesByName(processName)) { + onMessage?.Invoke($"Killing {processName} process {process.Id}", true); + currentExecutable = process.MainModule.FileName; + process.Kill(); + } + } + catch { } + return currentExecutable; + } + + public static string[] GetExecutables(bool stable, bool canary, bool ptb) { + List exes = new List(); + if (stable) exes.Add("Discord"); + if (canary) exes.Add("DiscordCanary"); + if (ptb) exes.Add("DiscordPTB"); + return exes.ToArray(); + } + + public static string[] GetRoamingPaths(bool stable, bool canary, bool ptb, string subFolder = "") { + List roaming = new List(); + var stableFolder = GetRoaming("discord"); + var canaryFolder = GetRoaming("discordcanary"); + var ptbFolder = GetRoaming("discordptb"); + if (stable && stableFolder != string.Empty) roaming.Add($"{stableFolder}\\{subFolder}"); + if (canary && canaryFolder != string.Empty) roaming.Add($"{canaryFolder}\\{subFolder}"); + if (ptb && ptbFolder != string.Empty) roaming.Add($"{ptbFolder}\\{subFolder}"); + return roaming.ToArray(); + } + + public static string[] GetLocalPaths(bool stable, bool canary, bool ptb, string subFolder = "") { + List paths = new List(); + if (stable) paths.Add($"{CurrentStablePath}\\{subFolder}"); + if (canary) paths.Add($"{CurrentCanaryPath}\\{subFolder}"); + if (ptb) paths.Add($"{CurrentPtbPath}\\{subFolder}"); + return paths.ToArray(); + } + + public static string GetExe(Discord which) { + if (which == Discord.Stable) return "Discord"; + if (which == Discord.Canary) return "DiscordCanary"; + if (which == Discord.PTB) return "DiscordPTB"; + return ""; + } + + public static void EnsureDiscord(TextBox tb, CheckBox cb, Discord which) { + if (tb.Text.ToLower().Contains("could not find")) { + cb.Checked = false; + return; + } + + var baseFolder = GetLatestVersion(tb.Text); + if (baseFolder == string.Empty) baseFolder = tb.Text; + string executable = GetExe(which); + tb.ForeColor = Properties.Settings.Default.TextColor; + if (!File.Exists(baseFolder + $"\\{executable}.exe")) { + tb.Text = $"Could not find {executable}.exe!"; + tb.ForeColor = Color.Red; + cb.Checked = false; + } + else { + tb.Text = baseFolder; + if (which == Discord.Stable) CurrentStablePath = baseFolder; + if (which == Discord.Canary) CurrentCanaryPath = baseFolder; + if (which == Discord.PTB) CurrentPtbPath = baseFolder; + } + } + + public static string GetLatestVersion(string path) { + if (path == string.Empty) return path; + var dirs = Directory.GetDirectories(path); + if (dirs.Length <= 0) return string.Empty; + var latest = Path.GetFileName(dirs[0]); + + foreach (var dir in dirs) { + if (!_matcher.IsMatch(Path.GetFileName(dir))) continue; + if (string.CompareOrdinal(Path.GetFileName(dir), latest) > 0) latest = Path.GetFileName(dir); + } + + return _matcher.IsMatch(latest) ? Path.Combine(path, latest) : string.Empty; + } + + public static string GetRoaming(string version) { + return GetLatestVersion($"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\\{version}"); + } + } +} diff --git a/BandagedBD/app.manifest b/BandagedBD/app.manifest new file mode 100644 index 0000000..47a484e --- /dev/null +++ b/BandagedBD/app.manifest @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a679f45 --- /dev/null +++ b/LICENSE @@ -0,0 +1,7 @@ +Copyright 2018 Zack Rauen www.ZackRauen.com + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software the rights to use, copy, modify, merge, publish, distribute, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..efaa35d --- /dev/null +++ b/README.md @@ -0,0 +1,61 @@ +# BandagedBD Installer + +This is the source for the Windows installer of [BandagedBD](https://github.com/rauenzi/BetterDiscordApp), a mod for Discord. I decided to put this in a separate repo mainly because it didn't feel quite right to have it in with the actual application itself as the application is JavaScript injection onto an Electron.js platform, and this is an actual executable that only sets ups files for it. + +## Preview + +![ScreenShot](https://i.zackrauen.com/2.png) + +## System Structure + +The system starts through the `FormMain` object which then adds the necessary control to the form. The controls to be added implement the interface `IPanel` and are represented in the accomanying enumeration `PanelTypes`. These two in tandem determine how the navigation through the installer occurs. + +### PanelTypes + +An enumeration representing all the available panels to have in the installer. + +### IPanel + +The interface `IPanel` requires the following functions: + +1. `void OnShow` - Called when the control is added to the form +2. `void SetWindow(FormMain)` - Called when the main form prepares the panels, allows panels to keep a reference to the window/form + +The interface also requires the following gettable properties: + +1. `string Title` - The title of the panel to be shown in the form +2. `UserControl Control` - Returns an implied cast of self (useful for passing to other function in the main form) +3. `PanelTypes PreviousPanel` - Representation of the panel to go to when going "back" +4. `PanelTypes NextPanel` - Representation of the panel to go to when going "forward" + +### FormMain + +Creates and keeps a reference to all the `IPanel`s and even handles the navigation through the application. Also holds the enumeration of `PanelTypes`. Includes a function to return a reference to a specific panel so panels may reference each other (mainly used for panels to refer to the configuration panel). + +### Discord + +An enumeration representing the 3 release channels of Discord: Stable, Canary and PTB. + +### Utilities + +Utilities contains several functions used multple times throughout the application including things like killing and launching processes as well as searching for and resolving paths. Contains the `Discord` enumeration. + +## Custom Components + +The installer makes use of a few custom components either for modularity as in the `DiscordLocator` control or for the custom "flat" design as in WinForms not all controls have a decent flat style. + +### DiscordLocator + +This is a custom group of controls consisting of: 3 checkboxes that represent location enable, 3 textboxes showing the currently entered/found path, and 3 buttons that allow the user to browse for the path. + +### Button + +This is a simple wrap around the normal `Button` object to add some helpful functions. + +### FlatCheckBox + +The native checkbox leaves a lot to be desired in terms of extensibility and customization. To create custom styling this component paints it's own checkbox using the current graphics and imposing the string "✔" overtop. + +### FlatProgressBar + +Similar to the checkbox the native progressbar has little to no customization options. This paints a flat checkbox using the an offscreen image as adapted from this [StackOverflow answer](https://stackoverflow.com/a/7490884). \ No newline at end of file