From 0a2382d590d13975e40d18b2f0949f8e888172f3 Mon Sep 17 00:00:00 2001 From: pizzaboxer <41478239+pizzaboxer@users.noreply.github.com> Date: Fri, 26 Aug 2022 12:48:35 +0100 Subject: [PATCH] v1.4.0: Build channel support, use rbxcdn, cleanup thanks clonetrooper for reminding me rbxcdn exists - don't know why i used s3 directly since it's so much slower --- Bloxstrap/Bloxstrap.csproj | 4 +- Bloxstrap/Bootstrapper.cs | 13 +- .../BootstrapperStyleForm.cs | 23 +-- Bloxstrap/Dialogs/Preferences.Designer.cs | 59 +++++++ Bloxstrap/Dialogs/Preferences.cs | 166 ++++++++++-------- Bloxstrap/Dialogs/Preferences.resx | 3 + Bloxstrap/Helpers/DeployManager.cs | 154 ++++++++++++++++ Bloxstrap/Helpers/Protocol.cs | 20 ++- Bloxstrap/Helpers/RSMM/PackageManifest.cs | 2 +- Bloxstrap/Helpers/Updater.cs | 14 +- Bloxstrap/Models/SettingsFormat.cs | 7 +- Bloxstrap/Models/VersionDeploy.cs | 15 ++ Bloxstrap/Program.cs | 17 +- 13 files changed, 374 insertions(+), 123 deletions(-) create mode 100644 Bloxstrap/Helpers/DeployManager.cs create mode 100644 Bloxstrap/Models/VersionDeploy.cs diff --git a/Bloxstrap/Bloxstrap.csproj b/Bloxstrap/Bloxstrap.csproj index 33a188f1..bd9d446b 100644 --- a/Bloxstrap/Bloxstrap.csproj +++ b/Bloxstrap/Bloxstrap.csproj @@ -9,8 +9,8 @@ AnyCPU AnyCPU;x86 Bloxstrap.ico - 1.3.0 - 1.3.0.0 + 1.4.0 + 1.4.0.0 True diff --git a/Bloxstrap/Bootstrapper.cs b/Bloxstrap/Bootstrapper.cs index 2042ad76..007929e1 100644 --- a/Bloxstrap/Bootstrapper.cs +++ b/Bloxstrap/Bootstrapper.cs @@ -89,11 +89,11 @@ public Bootstrapper() Client.Timeout = TimeSpan.FromMinutes(10); } - public void Initialize(BootstrapperStyle bootstrapperStyle, string? launchCommandLine = null) + public void Initialize(string? launchCommandLine = null) { LaunchCommandLine = launchCommandLine; - switch (bootstrapperStyle) + switch (Program.Settings.BootstrapperStyle) { case BootstrapperStyle.VistaDialog: Application.Run(new VistaDialog(this)); @@ -128,12 +128,7 @@ public async Task Run() await CheckLatestVersion(); if (!Directory.Exists(VersionFolder) || Program.Settings.VersionGuid != VersionGuid) - { - Debug.WriteLineIf(!Directory.Exists(VersionFolder), $"Installing latest version (!Directory.Exists({VersionFolder}))"); - Debug.WriteLineIf(Program.Settings.VersionGuid != VersionGuid, $"Installing latest version ({Program.Settings.VersionGuid} != {VersionGuid})"); - await InstallLatestVersion(); - } ApplyModifications(); @@ -156,7 +151,7 @@ private async Task CheckLatestVersion() { Dialog.Message = "Connecting to Roblox..."; - VersionGuid = await Client.GetStringAsync($"{Program.BaseUrlSetup}/version"); + VersionGuid = await Client.GetStringAsync($"{DeployManager.BaseUrl}/version"); VersionFolder = Path.Combine(Directories.Versions, VersionGuid); VersionPackageManifest = await PackageManifest.Get(VersionGuid); } @@ -587,7 +582,7 @@ private static void CheckModPreset(bool condition, string location, string base6 private async void DownloadPackage(Package package) { - string packageUrl = $"{Program.BaseUrlSetup}/{VersionGuid}-{package.Name}"; + string packageUrl = $"{DeployManager.BaseUrl}/{VersionGuid}-{package.Name}"; string packageLocation = Path.Combine(Directories.Downloads, package.Signature); string robloxPackageLocation = Path.Combine(Program.LocalAppData, "Roblox", "Downloads", package.Signature); diff --git a/Bloxstrap/Dialogs/BootstrapperStyles/BootstrapperStyleForm.cs b/Bloxstrap/Dialogs/BootstrapperStyles/BootstrapperStyleForm.cs index a4a88cf8..eefdd19c 100644 --- a/Bloxstrap/Dialogs/BootstrapperStyles/BootstrapperStyleForm.cs +++ b/Bloxstrap/Dialogs/BootstrapperStyles/BootstrapperStyleForm.cs @@ -97,25 +97,13 @@ public async void RunBootstrapper() public virtual void ShowSuccess(string message) { - MessageBox.Show( - message, - Program.ProjectName, - MessageBoxButtons.OK, - MessageBoxIcon.Information - ); - + Program.ShowMessageBox(message, MessageBoxIcon.Information); Program.Exit(); } public virtual void ShowError(string message) { - MessageBox.Show( - $"An error occurred while starting Roblox\n\nDetails: {message}", - Program.ProjectName, - MessageBoxButtons.OK, - MessageBoxIcon.Error - ); - + Program.ShowMessageBox($"An error occurred while starting Roblox\n\nDetails: {message}", MessageBoxIcon.Error); Program.Exit(); } @@ -129,11 +117,10 @@ public virtual void CloseDialog() public void PromptShutdown() { - DialogResult result = MessageBox.Show( + DialogResult result = Program.ShowMessageBox( "Roblox is currently running, but needs to close. Would you like close Roblox now?", - Program.ProjectName, - MessageBoxButtons.OKCancel, - MessageBoxIcon.Information + MessageBoxIcon.Information, + MessageBoxButtons.OKCancel ); if (result != DialogResult.OK) diff --git a/Bloxstrap/Dialogs/Preferences.Designer.cs b/Bloxstrap/Dialogs/Preferences.Designer.cs index 0ac8886b..9c126ef8 100644 --- a/Bloxstrap/Dialogs/Preferences.Designer.cs +++ b/Bloxstrap/Dialogs/Preferences.Designer.cs @@ -45,6 +45,10 @@ private void InitializeComponent() this.groupBox2 = new System.Windows.Forms.GroupBox(); this.StyleSelection = new System.Windows.Forms.ListBox(); this.InstallationTab = new System.Windows.Forms.TabPage(); + this.groupBox6 = new System.Windows.Forms.GroupBox(); + this.ToggleShowAllChannels = new System.Windows.Forms.CheckBox(); + this.LabelChannelInfo = new System.Windows.Forms.Label(); + this.SelectChannel = new System.Windows.Forms.ComboBox(); this.groupBox4 = new System.Windows.Forms.GroupBox(); this.LabelModFolderInstall = new System.Windows.Forms.Label(); this.ButtonOpenModFolder = new System.Windows.Forms.Button(); @@ -67,6 +71,7 @@ private void InitializeComponent() ((System.ComponentModel.ISupportInitialize)(this.IconPreview)).BeginInit(); this.groupBox2.SuspendLayout(); this.InstallationTab.SuspendLayout(); + this.groupBox6.SuspendLayout(); this.groupBox4.SuspendLayout(); this.GroupBoxInstallLocation.SuspendLayout(); this.panel1.SuspendLayout(); @@ -259,6 +264,7 @@ private void InitializeComponent() // // InstallationTab // + this.InstallationTab.Controls.Add(this.groupBox6); this.InstallationTab.Controls.Add(this.groupBox4); this.InstallationTab.Controls.Add(this.GroupBoxInstallLocation); this.InstallationTab.Location = new System.Drawing.Point(4, 24); @@ -269,6 +275,53 @@ private void InitializeComponent() this.InstallationTab.Text = "Installation"; this.InstallationTab.UseVisualStyleBackColor = true; // + // groupBox6 + // + this.groupBox6.Controls.Add(this.ToggleShowAllChannels); + this.groupBox6.Controls.Add(this.LabelChannelInfo); + this.groupBox6.Controls.Add(this.SelectChannel); + this.groupBox6.Location = new System.Drawing.Point(5, 158); + this.groupBox6.Name = "groupBox6"; + this.groupBox6.Size = new System.Drawing.Size(422, 56); + this.groupBox6.TabIndex = 3; + this.groupBox6.TabStop = false; + this.groupBox6.Text = "Build Channel"; + // + // ToggleShowAllChannels + // + this.ToggleShowAllChannels.AutoSize = true; + this.ToggleShowAllChannels.BackColor = System.Drawing.Color.White; + this.ToggleShowAllChannels.Location = new System.Drawing.Point(289, 0); + this.ToggleShowAllChannels.Name = "ToggleShowAllChannels"; + this.ToggleShowAllChannels.Padding = new System.Windows.Forms.Padding(7, 0, 0, 0); + this.ToggleShowAllChannels.Size = new System.Drawing.Size(127, 19); + this.ToggleShowAllChannels.TabIndex = 2; + this.ToggleShowAllChannels.Text = "Show all channels"; + this.ToggleShowAllChannels.UseVisualStyleBackColor = false; + this.ToggleShowAllChannels.CheckedChanged += new System.EventHandler(this.ToggleShowAllChannels_CheckedChanged); + // + // LabelChannelInfo + // + this.LabelChannelInfo.Location = new System.Drawing.Point(134, 18); + this.LabelChannelInfo.Name = "LabelChannelInfo"; + this.LabelChannelInfo.Size = new System.Drawing.Size(282, 28); + this.LabelChannelInfo.TabIndex = 1; + this.LabelChannelInfo.Text = "Getting latest deploy, please wait..."; + this.LabelChannelInfo.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // SelectChannel + // + this.SelectChannel.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.SelectChannel.DropDownWidth = 265; + this.SelectChannel.FormattingEnabled = true; + this.SelectChannel.Location = new System.Drawing.Point(9, 21); + this.SelectChannel.Name = "SelectChannel"; + this.SelectChannel.Size = new System.Drawing.Size(120, 23); + this.SelectChannel.TabIndex = 0; + this.InfoTooltip.SetToolTip(this.SelectChannel, "Choose what deploy channel to use.\r\nThe default channel is LIVE.\r\nYou should only" + + " change this if you\'re know exactly what you\'re doing.\r\n"); + this.SelectChannel.SelectedValueChanged += new System.EventHandler(this.SelectChannel_SelectedValueChanged); + // // groupBox4 // this.groupBox4.Controls.Add(this.LabelModFolderInstall); @@ -444,6 +497,8 @@ private void InitializeComponent() ((System.ComponentModel.ISupportInitialize)(this.IconPreview)).EndInit(); this.groupBox2.ResumeLayout(false); this.InstallationTab.ResumeLayout(false); + this.groupBox6.ResumeLayout(false); + this.groupBox6.PerformLayout(); this.groupBox4.ResumeLayout(false); this.groupBox4.PerformLayout(); this.GroupBoxInstallLocation.ResumeLayout(false); @@ -486,5 +541,9 @@ private void InitializeComponent() private CheckBox ToggleCheckForUpdates; private Button ButtonOpenModFolder; private Label LabelModFolderInstall; + private GroupBox groupBox6; + private ComboBox SelectChannel; + private Label LabelChannelInfo; + private CheckBox ToggleShowAllChannels; } } \ No newline at end of file diff --git a/Bloxstrap/Dialogs/Preferences.cs b/Bloxstrap/Dialogs/Preferences.cs index e011066f..ad67e070 100644 --- a/Bloxstrap/Dialogs/Preferences.cs +++ b/Bloxstrap/Dialogs/Preferences.cs @@ -7,11 +7,13 @@ using Bloxstrap.Enums; using Bloxstrap.Helpers; using Bloxstrap.Helpers.Integrations; +using Bloxstrap.Models; namespace Bloxstrap.Dialogs { public partial class Preferences : Form { + #region Properties private static readonly IReadOnlyDictionary SelectableStyles = new Dictionary() { { "Vista (2009 - 2011)", BootstrapperStyle.VistaDialog }, @@ -32,40 +34,33 @@ public partial class Preferences : Form { "2019", BootstrapperIcon.Icon2019 }, }; - private BootstrapperStyle? _selectedStyle; - private BootstrapperIcon? _selectedIcon; - - private BootstrapperStyle SelectedStyle + private string ChannelInfo { - get => _selectedStyle ?? BootstrapperStyle.ProgressDialog; - set { - if (_selectedStyle == value) - return; - - _selectedStyle = value; - - int index = SelectableStyles.Values.ToList().IndexOf(value); - this.StyleSelection.SetSelected(index, true); + if (this.InvokeRequired) + { + this.Invoke(new Action(() => { this.LabelChannelInfo.Text = value; })); + } + else + { + this.LabelChannelInfo.Text = value; + } } } + #endregion - private BootstrapperIcon SelectedIcon + #region Core + private async Task GetChannelInfo(string channel) { - get => _selectedIcon ?? BootstrapperIcon.IconBloxstrap; + ChannelInfo = "Getting latest deploy, please wait..."; - set - { - if (_selectedIcon == value) - return; + VersionDeploy info = await DeployManager.GetLastDeploy(channel); - _selectedIcon = value; + if (info.FileVersion is null || info.Date is null) + return; - int index = SelectableIcons.Values.ToList().IndexOf(value); - this.IconSelection.SetSelected(index, true); - this.IconPreview.BackgroundImage = IconManager.GetBitmapResource(value); - } + ChannelInfo = $"Last deploy:\nv{info.FileVersion} @ {info.Date}"; } public Preferences() @@ -89,21 +84,21 @@ public Preferences() this.InstallLocation.Text = Program.BaseDirectory; } - foreach (var style in SelectableStyles) - { - this.StyleSelection.Items.Add(style.Key); - } - - foreach (var icon in SelectableIcons) - { - this.IconSelection.Items.Add(icon.Key); - } - if (!Environment.Is64BitOperatingSystem) this.ToggleRFUEnabled.Enabled = false; - SelectedStyle = Program.Settings.BootstrapperStyle; - SelectedIcon = Program.Settings.BootstrapperIcon; + // set data sources for list controls + this.StyleSelection.DataSource = SelectableStyles.Keys.ToList(); + this.IconSelection.DataSource = SelectableIcons.Keys.ToList(); + + if (DeployManager.ChannelsAbstracted.Contains(Program.Settings.Channel)) + this.SelectChannel.DataSource = DeployManager.ChannelsAbstracted; + else + this.ToggleShowAllChannels.Checked = true; + + // populate preferences + this.StyleSelection.Text = SelectableStyles.FirstOrDefault(x => x.Value == Program.Settings.BootstrapperStyle).Key; + this.IconSelection.Text = SelectableIcons.FirstOrDefault(x => x.Value == Program.Settings.BootstrapperIcon).Key; this.ToggleCheckForUpdates.Checked = Program.Settings.CheckForUpdates; @@ -115,26 +110,19 @@ public Preferences() this.ToggleDeathSound.Checked = Program.Settings.UseOldDeathSound; this.ToggleMouseCursor.Checked = Program.Settings.UseOldMouseCursor; - } - - private void InstallLocationBrowseButton_Click(object sender, EventArgs e) - { - DialogResult result = this.InstallLocationBrowseDialog.ShowDialog(); - if (result == DialogResult.OK) - this.InstallLocation.Text = this.InstallLocationBrowseDialog.SelectedPath; + this.SelectChannel.Text = Program.Settings.Channel; } + #endregion - private void StyleSelection_SelectedIndexChanged(object sender, EventArgs e) + #region Dialog Events + private void ToggleShowAllChannels_CheckedChanged(object sender, EventArgs e) { - string selected = this.StyleSelection.Text; - SelectedStyle = SelectableStyles[selected]; - } + if (this.ToggleShowAllChannels.Checked) + this.SelectChannel.DataSource = DeployManager.ChannelsAll; + else + this.SelectChannel.DataSource = DeployManager.ChannelsAbstracted; - private void IconSelection_SelectedIndexChanged(object sender, EventArgs e) - { - string selected = this.IconSelection.Text; - SelectedIcon = SelectableIcons[selected]; } private void SaveButton_Click(object sender, EventArgs e) @@ -143,7 +131,7 @@ private void SaveButton_Click(object sender, EventArgs e) if (String.IsNullOrEmpty(installLocation)) { - Program.ShowMessageBox(MessageBoxIcon.Error, "You must set an install location"); + Program.ShowMessageBox("You must set an install location", MessageBoxIcon.Error); return; } @@ -166,12 +154,12 @@ private void SaveButton_Click(object sender, EventArgs e) } catch (UnauthorizedAccessException) { - Program.ShowMessageBox(MessageBoxIcon.Error, $"{Program.ProjectName} does not have write access to the install location you selected. Please choose another install location."); + Program.ShowMessageBox($"{Program.ProjectName} does not have write access to the install location you selected. Please choose another install location.", MessageBoxIcon.Error); return; } catch (Exception ex) { - Program.ShowMessageBox(MessageBoxIcon.Error, ex.Message); + Program.ShowMessageBox(ex.Message, MessageBoxIcon.Error); return; } @@ -186,7 +174,7 @@ private void SaveButton_Click(object sender, EventArgs e) if (Program.BaseDirectory is not null && Program.BaseDirectory != installLocation) { - Program.ShowMessageBox(MessageBoxIcon.Information, $"{Program.ProjectName} will install to the new location you've set the next time it runs."); + Program.ShowMessageBox($"{Program.ProjectName} will install to the new location you've set the next time it runs.", MessageBoxIcon.Information); Program.Settings.VersionGuid = ""; @@ -205,19 +193,14 @@ private void SaveButton_Click(object sender, EventArgs e) } } - Program.Settings.BootstrapperStyle = SelectedStyle; - Program.Settings.BootstrapperIcon = SelectedIcon; - this.Close(); } private void PreviewButton_Click(object sender, EventArgs e) { - Program.Settings.BootstrapperIcon = SelectedIcon; - this.Visible = false; - switch (SelectedStyle) + switch (Program.Settings.BootstrapperStyle) { case BootstrapperStyle.VistaDialog: new VistaDialog().ShowDialog(); @@ -243,6 +226,33 @@ private void PreviewButton_Click(object sender, EventArgs e) this.Visible = true; } + private void Preferences_Load(object sender, EventArgs e) + { + this.Activate(); + } + #endregion + + #region Preference Events + private void StyleSelection_SelectedIndexChanged(object sender, EventArgs e) + { + if (!this.Visible) + return; + + Program.Settings.BootstrapperStyle = SelectableStyles[this.StyleSelection.Text]; + } + + private void IconSelection_SelectedIndexChanged(object sender, EventArgs e) + { + BootstrapperIcon icon = SelectableIcons[this.IconSelection.Text]; + + this.IconPreview.BackgroundImage = IconManager.GetBitmapResource(icon); + + if (!this.Visible) + return; + + Program.Settings.BootstrapperIcon = icon; + } + private void ToggleDiscordRichPresence_CheckedChanged(object sender, EventArgs e) { Program.Settings.UseDiscordRichPresence = this.ToggleRPCButtons.Enabled = this.ToggleDiscordRichPresence.Checked; @@ -253,6 +263,11 @@ private void ToggleRPCButtons_CheckedChanged(object sender, EventArgs e) Program.Settings.HideRPCButtons = this.ToggleRPCButtons.Checked; } + private void RFUWebsite_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + Utilities.OpenWebsite($"https://github.com/{RbxFpsUnlocker.ProjectRepository}"); + } + private void ToggleRFUEnabled_CheckedChanged(object sender, EventArgs e) { Program.Settings.RFUEnabled = this.ToggleRFUAutoclose.Enabled = this.ToggleRFUEnabled.Checked; @@ -263,6 +278,14 @@ private void ToggleRFUAutoclose_CheckedChanged(object sender, EventArgs e) Program.Settings.RFUAutoclose = this.ToggleRFUAutoclose.Checked; } + private void InstallLocationBrowseButton_Click(object sender, EventArgs e) + { + DialogResult result = this.InstallLocationBrowseDialog.ShowDialog(); + + if (result == DialogResult.OK) + this.InstallLocation.Text = this.InstallLocationBrowseDialog.SelectedPath; + } + private void ToggleDeathSound_CheckedChanged(object sender, EventArgs e) { Program.Settings.UseOldDeathSound = this.ToggleDeathSound.Checked; @@ -273,24 +296,25 @@ private void ToggleMouseCursor_CheckedChanged(object sender, EventArgs e) Program.Settings.UseOldMouseCursor = this.ToggleMouseCursor.Checked; } - private void ToggleCheckForUpdates_CheckedChanged(object sender, EventArgs e) + private void ButtonOpenModFolder_Click(object sender, EventArgs e) { - Program.Settings.CheckForUpdates = this.ToggleCheckForUpdates.Checked; + Process.Start("explorer.exe", Directories.Modifications); } - private void RFUWebsite_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + private void SelectChannel_SelectedValueChanged(object sender, EventArgs e) { - Utilities.OpenWebsite($"https://github.com/{RbxFpsUnlocker.ProjectRepository}"); - } + Task.Run(() => GetChannelInfo(Program.Settings.Channel)); + + if (!this.Visible) + return; - private void ButtonOpenModFolder_Click(object sender, EventArgs e) - { - Process.Start("explorer.exe", Directories.Modifications); + Program.Settings.Channel = this.SelectChannel.Text; } - private void Preferences_Load(object sender, EventArgs e) + private void ToggleCheckForUpdates_CheckedChanged(object sender, EventArgs e) { - this.Activate(); + Program.Settings.CheckForUpdates = this.ToggleCheckForUpdates.Checked; } + #endregion } } diff --git a/Bloxstrap/Dialogs/Preferences.resx b/Bloxstrap/Dialogs/Preferences.resx index b2b5813c..ccfe85c9 100644 --- a/Bloxstrap/Dialogs/Preferences.resx +++ b/Bloxstrap/Dialogs/Preferences.resx @@ -63,4 +63,7 @@ 17, 17 + + 222, 17 + \ No newline at end of file diff --git a/Bloxstrap/Helpers/DeployManager.cs b/Bloxstrap/Helpers/DeployManager.cs new file mode 100644 index 00000000..dfdbd631 --- /dev/null +++ b/Bloxstrap/Helpers/DeployManager.cs @@ -0,0 +1,154 @@ +using System.IO; +using System.Net.Http; + +using Bloxstrap.Models; + +namespace Bloxstrap.Helpers +{ + public class DeployManager + { + #region Properties + public const string DefaultBaseUrl = "https://setup.rbxcdn.com"; + public static string BaseUrl { get; private set; } = DefaultBaseUrl; + + public static readonly string DefaultChannel = "LIVE"; + + public static string Channel { set => BaseUrl = BuildBaseUrl(value); } + + // basically any channel that has had a deploy within the past month with a windowsplayer build + public static readonly List ChannelsAbstracted = new List() + { + "LIVE", + "ZAvatarTeam", + "ZCanary", + "ZIntegration", + "ZLive", + "ZNext", + "ZPublic", + "ZSocialTeam" + }; + + // why not? + public static readonly List ChannelsAll = new List() + { + "LIVE", + "Ganesh", + "ZAvatarTeam", + "ZBugFixBoost-Mutex-Revert", + "ZBugFixCLI-54676-Test", + "ZBugFixCLI-55214-Master", + "ZCanary", + "ZCanary1", + "ZCanary2", + "ZCanaryApps", + "ZClientIntegration", + "ZClientWatcher", + "ZFeatureBaseline", + "ZFeatureBoost_Removal_Test_In_Prod", + "ZFeatureFMOD-20115", + "ZFeatureFMOD-Recording-Test", + "ZFeatureHSR2CDNPlayTest", + "ZFeatureHSR2CDNPlayTest2", + "ZFeatureInstance-Parent-Weak-Ptr", + "ZFeatureInstance-Parent-Weak-Ptr-2", + "ZFeatureLTCG1", + "ZFeatureLuaIInline1", + "ZFeatureQt5.15", + "ZFeatureRail", + "ZFeatureRetchecksV2", + "ZFeatureSubsystemAtomic", + "ZFeatureSubsystemHttpClient", + "ZFeatureTelemLife", + "ZFeatureUse-New-RapidJson-In-Flag-Loading", + "ZIntegration", + "ZIntegration1", + "ZLang", + "ZLive", + "ZLive1", + "ZLoom", + "ZNext", + "ZProject512-Boost-Remove-Mutex-1", + "ZProject516-Boost-Remove-Mutex-Network", + "ZPublic", + "ZQtitanStudio", + "ZQTitanStudioRelease", + "ZReleaseVS2019", + "ZSocialTeam", + "ZStIntegration", + "ZStudioInt1", + "ZStudioInt2", + "ZStudioInt3", + "ZStudioInt4", + "ZStudioInt5", + "ZStudioInt6", + "ZStudioInt7", + "ZStudioInt8", + "ZTesting", + "ZVS2019" + }; + #endregion + + private static string BuildBaseUrl(string channel) + { + if (channel == DefaultChannel) + return DefaultBaseUrl; + else + return $"{DefaultBaseUrl}/channel/{channel.ToLower()}"; + } + + public static async Task GetLastDeploy(string channel) + { + string baseUrl = BuildBaseUrl(channel); + string deployHistory = ""; + string lastDeploy = ""; + + using (HttpClient client = new()) + { + deployHistory = await client.GetStringAsync($"{baseUrl}/DeployHistory.txt"); + } + + using (StringReader reader = new(deployHistory)) + { + string? line; + + while ((line = await reader.ReadLineAsync()) is not null) + { + if (line.Contains("WindowsPlayer")) + lastDeploy = line; + } + } + + if (String.IsNullOrEmpty(lastDeploy)) + throw new Exception($"Could not get latest deploy for channel {channel}"); + + // here's to hoping roblox doesn't change their deployment entry format + // (last time they did so was may 2021 so we should be fine?) + // example entry: 'New WindowsPlayer version-29fb7cdd06e84001 at 8/23/2022 2:07:27 PM, file version: 0, 542, 100, 5420251, git hash: b98d6b2bea36fa2161f48cca979fb620bb0c24fd ...' + + lastDeploy = lastDeploy[18..]; // 'version-29fb7cdd06e84001 at 8/23/2022 2:07:27 PM, file version: 0, 542, 100, 5420251, git hash: b98d6b2bea36fa2161f48cca979fb620bb0c24fd ...' + string versionGuid = lastDeploy[..lastDeploy.IndexOf(" at")]; // 'version-29fb7cdd06e84001' + + lastDeploy = lastDeploy[(versionGuid.Length + 4)..]; // '8/23/2022 2:07:27 PM, file version: 0, 542, 100, 5420251, git hash: b98d6b2bea36fa2161f48cca979fb620bb0c24fd ...' + string date = lastDeploy[..lastDeploy.IndexOf(", file")]; // '8/23/2022 2:07:27 PM' + + lastDeploy = lastDeploy[(date.Length + 16)..]; // '0, 542, 100, 5420251, git hash: b98d6b2bea36fa2161f48cca979fb620bb0c24fd ...' + string fileVersion = ""; + + if (lastDeploy.Contains("git hash")) + { + // ~may 2021 entry: ends like 'file version: 0, 542, 100, 5420251, git hash: b98d6b2bea36fa2161f48cca979fb620bb0c24fd ...' + fileVersion = lastDeploy[..lastDeploy.IndexOf(", git")]; // '0, 542, 100, 5420251' + } + else + { + // pre-may 2021 entry: ends like 'file version: 0, 448, 0, 411122...' + fileVersion = lastDeploy[..lastDeploy.IndexOf("...")]; // '0, 448, 0, 411122' + } + + // convert to traditional version format + fileVersion = fileVersion.Replace(" ", "").Replace(',', '.'); + + return new VersionDeploy { VersionGuid = versionGuid, Date = date, FileVersion = fileVersion }; + } + } +} diff --git a/Bloxstrap/Helpers/Protocol.cs b/Bloxstrap/Helpers/Protocol.cs index e24330d2..01f81bc1 100644 --- a/Bloxstrap/Helpers/Protocol.cs +++ b/Bloxstrap/Helpers/Protocol.cs @@ -9,16 +9,17 @@ public class Protocol // map uri keys to command line args private static readonly IReadOnlyDictionary UriKeyArgMap = new Dictionary() { - // excluding roblox-player, browsertrackerid and channel + // excluding roblox-player and browsertrackerid { "launchmode", "--" }, { "gameinfo", "-t " }, { "placelauncherurl", "-j "}, // { "launchtime", "--launchtime=" }, we'll set this when launching the game client { "robloxLocale", "--rloc " }, { "gameLocale", "--gloc " }, + { "channel", "-channel " } }; - public static string Parse(string protocol) + public static string ParseUri(string protocol) { string[] keyvalPair; string key; @@ -34,12 +35,25 @@ public static string Parse(string protocol) key = keyvalPair[0]; val = keyvalPair[1]; - if (!UriKeyArgMap.ContainsKey(key)) + if (!UriKeyArgMap.ContainsKey(key) || String.IsNullOrEmpty(val)) continue; if (key == "placelauncherurl") val = HttpUtility.UrlDecode(val).Replace("browserTrackerId", "lol"); + if (key == "channel" && val != Program.Settings.Channel) + { + DialogResult result = Program.ShowMessageBox( + $"{Program.ProjectName} was launched with the Roblox build channel set to {val}, however your current preferred channel is {Program.Settings.Channel}.\n\n" + + $"Would you like to switch channels from {Program.Settings.Channel} to {val}?", + MessageBoxIcon.Question, + MessageBoxButtons.YesNo + ); + + if (result == DialogResult.Yes) + Program.Settings.Channel = val; + } + commandLine.Append(UriKeyArgMap[key] + val + " "); } diff --git a/Bloxstrap/Helpers/RSMM/PackageManifest.cs b/Bloxstrap/Helpers/RSMM/PackageManifest.cs index 29e70356..bacfabdf 100644 --- a/Bloxstrap/Helpers/RSMM/PackageManifest.cs +++ b/Bloxstrap/Helpers/RSMM/PackageManifest.cs @@ -72,7 +72,7 @@ private PackageManifest(string data) public static async Task Get(string versionGuid) { - string pkgManifestUrl = $"{Program.BaseUrlSetup}/{versionGuid}-rbxPkgManifest.txt"; + string pkgManifestUrl = $"{DeployManager.BaseUrl}/{versionGuid}-rbxPkgManifest.txt"; string pkgManifestData; using (HttpClient http = new()) diff --git a/Bloxstrap/Helpers/Updater.cs b/Bloxstrap/Helpers/Updater.cs index 2569bc62..05bb55ad 100644 --- a/Bloxstrap/Helpers/Updater.cs +++ b/Bloxstrap/Helpers/Updater.cs @@ -22,11 +22,10 @@ public static bool CheckInstalledVersion() if (installedVersionInfo.ProductVersion != currentVersionInfo.ProductVersion) { - DialogResult result = MessageBox.Show( + DialogResult result = Program.ShowMessageBox( $"The version of {Program.ProjectName} you've launched is newer than the version you currently have installed.\nWould you like to update your currently installed version?", - Program.ProjectName, - MessageBoxButtons.YesNo, - MessageBoxIcon.Question + MessageBoxIcon.Question, + MessageBoxButtons.YesNo ); if (result == DialogResult.Yes) @@ -66,11 +65,10 @@ public static async Task Check() if (currentVersion != latestVersion) { - DialogResult result = MessageBox.Show( + DialogResult result = Program.ShowMessageBox( $"A new version of {Program.ProjectName} is available\n\n[{latestVersion}]\n{releaseNotes}\n\nWould you like to download it?", - Program.ProjectName, - MessageBoxButtons.YesNo, - MessageBoxIcon.Question + MessageBoxIcon.Question, + MessageBoxButtons.YesNo ); if (result == DialogResult.Yes) diff --git a/Bloxstrap/Models/SettingsFormat.cs b/Bloxstrap/Models/SettingsFormat.cs index 1960505a..29ddbd58 100644 --- a/Bloxstrap/Models/SettingsFormat.cs +++ b/Bloxstrap/Models/SettingsFormat.cs @@ -1,12 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Bloxstrap.Enums; +using Bloxstrap.Enums; +using Bloxstrap.Helpers; namespace Bloxstrap.Models { public class SettingsFormat { + public string Channel { get; set; } = DeployManager.DefaultChannel; public string VersionGuid { get; set; } = ""; public bool CheckForUpdates { get; set; } = true; diff --git a/Bloxstrap/Models/VersionDeploy.cs b/Bloxstrap/Models/VersionDeploy.cs new file mode 100644 index 00000000..0d7d9882 --- /dev/null +++ b/Bloxstrap/Models/VersionDeploy.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Bloxstrap.Models +{ + public class VersionDeploy + { + public string? VersionGuid { get; set; } + public string? Date { get; set; } + public string? FileVersion { get; set; } + } +} diff --git a/Bloxstrap/Program.cs b/Bloxstrap/Program.cs index 4cdad024..2ed66fe1 100644 --- a/Bloxstrap/Program.cs +++ b/Bloxstrap/Program.cs @@ -14,7 +14,6 @@ internal static class Program public const string ProjectName = "Bloxstrap"; public const string ProjectRepository = "pizzaboxer/bloxstrap"; - public const string BaseUrlSetup = "https://s3.amazonaws.com/setup.roblox.com"; #region base64 stuff // TODO: using IPFS as a reliable method for static asset storage instead of base64? @@ -32,10 +31,10 @@ internal static class Program public static SettingsManager SettingsManager = new(); public static SettingsFormat Settings = SettingsManager.Settings; - - public static void ShowMessageBox(MessageBoxIcon icon, string message) + // shorthand + public static DialogResult ShowMessageBox(string message, MessageBoxIcon icon = MessageBoxIcon.None, MessageBoxButtons buttons = MessageBoxButtons.OK) { - MessageBox.Show(message, ProjectName, MessageBoxButtons.OK, icon); + return MessageBox.Show(message, ProjectName, buttons, icon); } public static void Exit() @@ -56,7 +55,7 @@ static void Main(string[] args) if (Process.GetProcessesByName(ProjectName).Length > 1) { - ShowMessageBox(MessageBoxIcon.Error, $"{ProjectName} is already running. Please close any currently open {ProjectName} window.\nIf you have Discord Rich Presence enabled, then close Roblox if it's running."); + ShowMessageBox($"{ProjectName} is already running. Please close any currently open {ProjectName} window.\nIf you have Discord Rich Presence enabled, then close Roblox if it's running.", MessageBoxIcon.Error); return; } @@ -107,7 +106,7 @@ static void Main(string[] args) } else if (args[0].StartsWith("roblox-player:")) { - commandLine = Protocol.Parse(args[0]); + commandLine = Protocol.ParseUri(args[0]); } else if (args[0].StartsWith("roblox:")) { @@ -123,8 +122,12 @@ static void Main(string[] args) commandLine = "--app"; } + if (!String.IsNullOrEmpty(commandLine)) - new Bootstrapper().Initialize(Settings.BootstrapperStyle, commandLine); + { + DeployManager.Channel = Settings.Channel; + new Bootstrapper().Initialize(commandLine); + } SettingsManager.Save(); }