From 2cd87f790df320058622da9889506a1b0b4ce77b Mon Sep 17 00:00:00 2001 From: pbannon Date: Mon, 12 May 2025 20:10:17 +0100 Subject: [PATCH] - refactor --- .gitignore | 38 +- PS5 NOR Modifier.sln | 44 + PS5 NOR Modifier.sln.DotSettings.user | 6 + .../Configuration/InMemoryConfiguration.cs | 12 + .../Dialogs/MessageBoxNotificationHandler.cs | 47 + .../Extensions/NotificationTypeExtensions.cs | 31 + .../Extensions/ServiceCollectionExtensions.cs | 17 + PS5 NOR Modifier/Form1.Designer.cs | 2 +- PS5 NOR Modifier/Form1.cs | 1361 +++++++---------- PS5 NOR Modifier/PS5 NOR Modifier.csproj | 9 +- PS5 NOR Modifier/Program.cs | 19 +- .../UART-CL By TheCod3r/Program.cs | 129 +- .../UART-CL By TheCod3r.csproj | 6 +- UART.Core.Tests/UART.Core.Tests.csproj | 27 + .../Abstractions/INotificationHandler.cs | 11 + UART.Core/Abstractions/IUartProvider.cs | 9 + UART.Core/Configuration/Constants.cs | 9 + UART.Core/Data/XmlUartProvider.cs | 177 +++ UART.Core/Extensions/ByteExtensions.cs | 18 + UART.Core/Extensions/StringExtensions.cs | 117 ++ UART.Core/Models/BasicMessage.cs | 7 + UART.Core/Models/Notification.cs | 6 + UART.Core/Models/NotificationType.cs | 8 + UART.Core/Models/Question.cs | 18 + UART.Core/UART.Core.csproj | 13 + 25 files changed, 1194 insertions(+), 947 deletions(-) create mode 100644 PS5 NOR Modifier.sln.DotSettings.user create mode 100644 PS5 NOR Modifier/Configuration/InMemoryConfiguration.cs create mode 100644 PS5 NOR Modifier/Dialogs/MessageBoxNotificationHandler.cs create mode 100644 PS5 NOR Modifier/Extensions/NotificationTypeExtensions.cs create mode 100644 PS5 NOR Modifier/Extensions/ServiceCollectionExtensions.cs create mode 100644 UART.Core.Tests/UART.Core.Tests.csproj create mode 100644 UART.Core/Abstractions/INotificationHandler.cs create mode 100644 UART.Core/Abstractions/IUartProvider.cs create mode 100644 UART.Core/Configuration/Constants.cs create mode 100644 UART.Core/Data/XmlUartProvider.cs create mode 100644 UART.Core/Extensions/ByteExtensions.cs create mode 100644 UART.Core/Extensions/StringExtensions.cs create mode 100644 UART.Core/Models/BasicMessage.cs create mode 100644 UART.Core/Models/Notification.cs create mode 100644 UART.Core/Models/NotificationType.cs create mode 100644 UART.Core/Models/Question.cs create mode 100644 UART.Core/UART.Core.csproj diff --git a/.gitignore b/.gitignore index 4b2c31e..cf16340 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,31 @@ -################################################################################ -# This .gitignore file was automatically created by Microsoft(R) Visual Studio. -################################################################################ - -/.vs -/PS5 NOR Modifier/bin/ -/PS5 NOR Modifier/obj/ \ No newline at end of file +################################################################################ +# This .gitignore file was automatically created by Microsoft(R) Visual Studio. +################################################################################ + +#IDE +.vs/ +.idea/ + +# build folders +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +[Xx]64/ +[Xx]86/ +[Bb]uild/ +bld/ +[Bb]in/ +[Oo]bj/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets \ No newline at end of file diff --git a/PS5 NOR Modifier.sln b/PS5 NOR Modifier.sln index 1cfcbf0..462ca67 100644 --- a/PS5 NOR Modifier.sln +++ b/PS5 NOR Modifier.sln @@ -5,6 +5,22 @@ VisualStudioVersion = 17.3.32901.215 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PS5 NOR Modifier", "PS5 NOR Modifier\PS5 NOR Modifier.csproj", "{BBBF9E78-9480-436A-92F1-B5B8943BCDEF}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionFiles", "SolutionFiles", "{1AC636D7-87A9-40A2-8008-AD282DA5D185}" + ProjectSection(SolutionItems) = preProject + README.md = README.md + .gitignore = .gitignore + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UART-CL By TheCod3r", "UART-CL By TheCod3r\UART-CL By TheCod3r\UART-CL By TheCod3r.csproj", "{5FA52746-F93B-4DF4-8BBE-970D5C744AFF}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libraries", "Libraries", "{2437D9F4-EC35-400C-9D98-AA510B1DAD3B}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{D9AD1813-3D4C-4CD9-82F2-1A56BCA2B0E6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UART.Core", "UART.Core\UART.Core.csproj", "{AC5043E7-B7B2-45A1-8FCD-1B935DD93BCD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UART.Core.Tests", "UART.Core.Tests\UART.Core.Tests.csproj", "{5B44A453-8C97-4024-8701-4C4AA5E7EB0D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -21,6 +37,30 @@ Global {BBBF9E78-9480-436A-92F1-B5B8943BCDEF}.Release|Any CPU.Build.0 = Release|Any CPU {BBBF9E78-9480-436A-92F1-B5B8943BCDEF}.Release|x86.ActiveCfg = Release|x86 {BBBF9E78-9480-436A-92F1-B5B8943BCDEF}.Release|x86.Build.0 = Release|x86 + {5FA52746-F93B-4DF4-8BBE-970D5C744AFF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5FA52746-F93B-4DF4-8BBE-970D5C744AFF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5FA52746-F93B-4DF4-8BBE-970D5C744AFF}.Debug|x86.ActiveCfg = Debug|Any CPU + {5FA52746-F93B-4DF4-8BBE-970D5C744AFF}.Debug|x86.Build.0 = Debug|Any CPU + {5FA52746-F93B-4DF4-8BBE-970D5C744AFF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5FA52746-F93B-4DF4-8BBE-970D5C744AFF}.Release|Any CPU.Build.0 = Release|Any CPU + {5FA52746-F93B-4DF4-8BBE-970D5C744AFF}.Release|x86.ActiveCfg = Release|Any CPU + {5FA52746-F93B-4DF4-8BBE-970D5C744AFF}.Release|x86.Build.0 = Release|Any CPU + {AC5043E7-B7B2-45A1-8FCD-1B935DD93BCD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AC5043E7-B7B2-45A1-8FCD-1B935DD93BCD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AC5043E7-B7B2-45A1-8FCD-1B935DD93BCD}.Debug|x86.ActiveCfg = Debug|Any CPU + {AC5043E7-B7B2-45A1-8FCD-1B935DD93BCD}.Debug|x86.Build.0 = Debug|Any CPU + {AC5043E7-B7B2-45A1-8FCD-1B935DD93BCD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AC5043E7-B7B2-45A1-8FCD-1B935DD93BCD}.Release|Any CPU.Build.0 = Release|Any CPU + {AC5043E7-B7B2-45A1-8FCD-1B935DD93BCD}.Release|x86.ActiveCfg = Release|Any CPU + {AC5043E7-B7B2-45A1-8FCD-1B935DD93BCD}.Release|x86.Build.0 = Release|Any CPU + {5B44A453-8C97-4024-8701-4C4AA5E7EB0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5B44A453-8C97-4024-8701-4C4AA5E7EB0D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5B44A453-8C97-4024-8701-4C4AA5E7EB0D}.Debug|x86.ActiveCfg = Debug|Any CPU + {5B44A453-8C97-4024-8701-4C4AA5E7EB0D}.Debug|x86.Build.0 = Debug|Any CPU + {5B44A453-8C97-4024-8701-4C4AA5E7EB0D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5B44A453-8C97-4024-8701-4C4AA5E7EB0D}.Release|Any CPU.Build.0 = Release|Any CPU + {5B44A453-8C97-4024-8701-4C4AA5E7EB0D}.Release|x86.ActiveCfg = Release|Any CPU + {5B44A453-8C97-4024-8701-4C4AA5E7EB0D}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -28,4 +68,8 @@ Global GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {406F6CF1-EBE8-4A32-86BA-26B4FEDF751B} EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {AC5043E7-B7B2-45A1-8FCD-1B935DD93BCD} = {2437D9F4-EC35-400C-9D98-AA510B1DAD3B} + {5B44A453-8C97-4024-8701-4C4AA5E7EB0D} = {D9AD1813-3D4C-4CD9-82F2-1A56BCA2B0E6} + EndGlobalSection EndGlobal diff --git a/PS5 NOR Modifier.sln.DotSettings.user b/PS5 NOR Modifier.sln.DotSettings.user new file mode 100644 index 0000000..dc05b90 --- /dev/null +++ b/PS5 NOR Modifier.sln.DotSettings.user @@ -0,0 +1,6 @@ + + ForceIncluded + ForceIncluded + ForceIncluded + ForceIncluded + ForceIncluded \ No newline at end of file diff --git a/PS5 NOR Modifier/Configuration/InMemoryConfiguration.cs b/PS5 NOR Modifier/Configuration/InMemoryConfiguration.cs new file mode 100644 index 0000000..5014b51 --- /dev/null +++ b/PS5 NOR Modifier/Configuration/InMemoryConfiguration.cs @@ -0,0 +1,12 @@ +using UART.Core.Configuration; + +namespace PS5_NOR_Modifier.Configuration; + +public class InMemoryConfiguration +{ + public static IEnumerable> Configuration = new Dictionary + { + {Constants.UartDbFilePathKey, "errorDB.xml"}, + {Constants.UartSourceUrlKey, "http://uartcodes.com/xml.php"}, + }; +} \ No newline at end of file diff --git a/PS5 NOR Modifier/Dialogs/MessageBoxNotificationHandler.cs b/PS5 NOR Modifier/Dialogs/MessageBoxNotificationHandler.cs new file mode 100644 index 0000000..7751ea7 --- /dev/null +++ b/PS5 NOR Modifier/Dialogs/MessageBoxNotificationHandler.cs @@ -0,0 +1,47 @@ +using PS5_NOR_Modifier.Extensions; +using UART.Core.Abstractions; +using UART.Core.Models; + +namespace PS5_NOR_Modifier.Dialogs; + +public class MessageBoxNotificationHandler : INotificationHandler +{ + public void HandleMessage(Notification notificationDetails) + { + MessageBox.Show( + notificationDetails.Message, + notificationDetails.Title, + notificationDetails.Type.ToMessageBoxButtons(), + notificationDetails.Type.ToMessageBoxIcon()); + } + + public void HandleQuestion(Question question) + { + DialogResult result = MessageBox.Show( + question.Message, + question.Title, + MessageBoxButtons.YesNo, + MessageBoxIcon.Question); + + if (result == DialogResult.Yes && question.OnYes != null) + question.OnYes.Invoke(); + + if (result == DialogResult.No && question.OnNo != null) + question.OnNo.Invoke(); + } + + public async Task HandleQuestion(AsyncQuestion asyncQuestion) + { + DialogResult result = MessageBox.Show( + asyncQuestion.Message, + asyncQuestion.Title, + MessageBoxButtons.YesNo, + MessageBoxIcon.Question); + + if (result == DialogResult.Yes && asyncQuestion.OnYes != null) + await asyncQuestion.OnYes.Invoke(); + + if (result == DialogResult.No && asyncQuestion.OnNo != null) + await asyncQuestion.OnNo.Invoke(); + } +} \ No newline at end of file diff --git a/PS5 NOR Modifier/Extensions/NotificationTypeExtensions.cs b/PS5 NOR Modifier/Extensions/NotificationTypeExtensions.cs new file mode 100644 index 0000000..5d9be23 --- /dev/null +++ b/PS5 NOR Modifier/Extensions/NotificationTypeExtensions.cs @@ -0,0 +1,31 @@ +using UART.Core.Models; + +namespace PS5_NOR_Modifier.Extensions; + +public static class NotificationTypeExtensions +{ + public static MessageBoxButtons ToMessageBoxButtons(this NotificationType notificationType) + { + switch (notificationType) + { + default: + return MessageBoxButtons.OK; + + } + } + + public static MessageBoxIcon ToMessageBoxIcon(this NotificationType notificationType) + { + switch (notificationType) + { + case NotificationType.Error: + return MessageBoxIcon.Error; + case NotificationType.Warning: + return MessageBoxIcon.Warning; + case NotificationType.Information: + return MessageBoxIcon.Information; + default: + return MessageBoxIcon.None; + } + } +} \ No newline at end of file diff --git a/PS5 NOR Modifier/Extensions/ServiceCollectionExtensions.cs b/PS5 NOR Modifier/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..4af48ba --- /dev/null +++ b/PS5 NOR Modifier/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,17 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using PS5_NOR_Modifier.Configuration; + +namespace PS5_NOR_Modifier.Extensions; + +public static class ServiceCollectionExtensions +{ + public static IServiceCollection AddInMemoryConfiguration(this IServiceCollection services) + { + var cfgBuilder = new ConfigurationBuilder(); + cfgBuilder.AddInMemoryCollection(InMemoryConfiguration.Configuration); + var cfg = cfgBuilder.Build(); + services.AddSingleton(cfg); + return services; + } +} \ No newline at end of file diff --git a/PS5 NOR Modifier/Form1.Designer.cs b/PS5 NOR Modifier/Form1.Designer.cs index 3889d30..1634ee7 100644 --- a/PS5 NOR Modifier/Form1.Designer.cs +++ b/PS5 NOR Modifier/Form1.Designer.cs @@ -503,7 +503,7 @@ private void InitializeComponent() this.tabControl1.Controls.Add(this.tabPage2); this.tabControl1.Location = new System.Drawing.Point(12, 132); this.tabControl1.Name = "tabControl1"; - this.tabControl1.SelectedIndex = 0; + //this.tabControl1.SelectedIndex = 0; this.tabControl1.Size = new System.Drawing.Size(821, 311); this.tabControl1.TabIndex = 46; // diff --git a/PS5 NOR Modifier/Form1.cs b/PS5 NOR Modifier/Form1.cs index 8f6dec8..5eb9437 100644 --- a/PS5 NOR Modifier/Form1.cs +++ b/PS5 NOR Modifier/Form1.cs @@ -1,95 +1,38 @@ -using System.Diagnostics; -using System.Globalization; -using System.IO; -using System.Runtime.InteropServices; using System.Text; -using System.Text.RegularExpressions; -using System.Windows.Forms; using System.IO.Ports; -using System; -using System.Threading; -using System.Collections.Generic; -using static System.Windows.Forms.LinkLabel; -using static System.Windows.Forms.VisualStyles.VisualStyleElement; -using System.Net; -using System.Xml; -using System.Security.Policy; +using UART.Core.Extensions; +using UART.Core.Abstractions; +using UART.Core.Configuration; +using UART.Core.Models; namespace PS5_NOR_Modifier { public partial class Form1 : Form { - - public Form1() - { - InitializeComponent(); - } - - static string CalculateChecksum(string str) - { - int sum = 0; - foreach (char c in str) - { - sum += (int)c; - } - return str + ":" + (sum & 0xFF).ToString("X2"); - } - - private void throwError(string errmsg) - { - MessageBox.Show(errmsg, "An Error Has Occurred", MessageBoxButtons.OK, MessageBoxIcon.Warning); - } - - // We want this app to work offline, so let's declare where the local "offline" database will be stored - string localDatabaseFile = "errorDB.xml"; - + private readonly IUartProvider _uartProvider; + private readonly INotificationHandler _notificationHandler; static SerialPort UARTSerial = new SerialPort(); - - /// - /// With thanks to @jjxtra on Github. The code has already been created and there's no need to reinvent the wheel is there? - /// - #region Hex Code - - private static IEnumerable PatternAt(byte[] source, byte[] pattern) + + public Form1(IUartProvider uartProvider, INotificationHandler notificationHandler) { - for (int i = 0; i < source.Length; i++) - { - if (source.Skip(i).Take(pattern.Length).SequenceEqual(pattern)) - { - yield return i; - } - } + _uartProvider = uartProvider; + _notificationHandler = notificationHandler; + InitializeComponent(); } - private static byte[] ConvertHexStringToByteArray(string hexString) + private void DisplayErrorMessage(string errmsg) { - if (hexString.Length % 2 != 0) + _notificationHandler.HandleMessage(new Notification { - throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The binary key cannot have an odd number of digits: {0}", hexString)); - } - - byte[] data = new byte[hexString.Length / 2]; - for (int index = 0; index < data.Length; index++) - { - string byteValue = hexString.Substring(index * 2, 2); - data[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture); - } - - return data; + Message = errmsg, + Title = "An Error Has Occurred", + Type = NotificationType.Warning, + }); } - #endregion - + // Upon first launch, we need to get a list of COM ports available for UART private void Form1_Load(object sender, EventArgs e) - { - // Upon first launch, we need to get a list of COM ports available for UART - string[] ports = SerialPort.GetPortNames(); - comboComPorts.Items.Clear(); - comboComPorts.Items.AddRange(ports); - comboComPorts.SelectedIndex = 0; - btnConnectCom.Enabled = true; - btnDisconnectCom.Enabled = false; - } + => UpdatePorts(); // Declare offsets to detect console version long offsetOne = 0x1c7010; @@ -107,223 +50,22 @@ private void Form1_Load(object sender, EventArgs e) long moboSerialOffset = 0x1C7200; string? moboSerialValue = null; - private async Task DownloadDatabaseAsync() - { - // Define the URL - string url = "http://uartcodes.com/xml.php"; // Update with your URL - - // Define the file path to save the XML - - try - { - // Create a WebClient instance - using (HttpClient client = new()) - { - // Download the XML data from the URL - string xmlData = await client.GetStringAsync(url); - - // Create an XmlDocument instance and load the XML data - XmlDocument xmlDoc = new XmlDocument(); - xmlDoc.LoadXml(xmlData); - - // Save the XML data to a file - xmlDoc.Save(localDatabaseFile); - - MessageBox.Show("The most recent offline database has been updated successfully.", "Offline Database Updated!", MessageBoxButtons.OK, MessageBoxIcon.Information); - } - } - catch (Exception ex) - { - Console.WriteLine("Error: " + ex.Message); - } - } - /// /// We need to be able to send the error code we received from the console and fetch an XML result back from the server /// Once we have a result from the server, parse the XML data and output it in an easy to understand format for the user /// - /// + /// /// - async Task ParseErrorsAsync(string ErrorCode) + async Task ParseErrorsAsync(string errorCode) { // If the user has opted to parse errors with an offline database, run the parse offline function - if (chkUseOffline.Checked == true) - { - return ParseErrorsOffline(ErrorCode); - } - else - { - // The user wants to use the online version. Proceed at will - - // Define the URL with the error code parameter - string url = "http://uartcodes.com/xml.php?errorCode=" + ErrorCode; - - string results = ""; - - try - { - string response = ""; - // Create a WebClient instance to send the request - using (HttpClient client = new()) - { - // Send the request and retrieve the response as a string - response = await client.GetStringAsync(url); - } - // Load the XML response into an XmlDocument - XmlDocument xmlDoc = new XmlDocument(); - xmlDoc.LoadXml(response); - - - // Get the root node - XmlNode? root = xmlDoc.DocumentElement; - if (root is null) { - throw new Exception("Error reading the file"); - } - - // Check if the root node is - if (root.Name == "errorCodes") - { - // Loop through each errorCode node - foreach (XmlNode errorCodeNode in root.ChildNodes) - { - // Check if the node is - if (errorCodeNode.Name == "errorCode") - { - // Get ErrorCode and Description - string errorCode = errorCodeNode.SelectSingleNode("ErrorCode")?.InnerText ?? ""; - string description = errorCodeNode.SelectSingleNode("Description")?.InnerText??""; - - // Output the results - results = "Error code: " - + errorCode - + Environment.NewLine - + "Description: " - + description; - } - } - } - else - { - results = "Error code: " - + ErrorCode - + Environment.NewLine - + "An error occurred while fetching a result for this error. Please try again!"; - } - } - catch (Exception ex) - { - results = "Error code: " - + ErrorCode - + Environment.NewLine - + ex.Message; - } - return results; - } - } - - string ParseErrorsOffline(string errorCode) - { - string results = ""; - - try - { - // Check if the XML file exists - if (File.Exists(localDatabaseFile)) - { - // Load the XML file - XmlDocument xmlDoc = new XmlDocument(); - xmlDoc.Load(localDatabaseFile); - - // Get the root node - XmlNode? root = xmlDoc.DocumentElement; - if (root is null) return results; - - // Check if the root node is - if (root.Name == "errorCodes") - { - // Loop through each errorCode node - foreach (XmlNode errorCodeNode in root.ChildNodes) - { - // Check if the node is - if (errorCodeNode.Name == "errorCode") - { - // Get ErrorCode and Description - string errorCodeValue = errorCodeNode.SelectSingleNode("ErrorCode")?.InnerText??""; - string description = errorCodeNode.SelectSingleNode("Description")?.InnerText??""; - - // Check if the current error code matches the requested error code - if (errorCodeValue == errorCode) - { - // Output the results - results = "Error code: " + errorCodeValue + Environment.NewLine + "Description: " + description; - break; // Exit the loop after finding the matching error code - } - } - } - } - else - { - results = "Error: Invalid XML database file. Please reconfigure the application, redownload the offline database, or uncheck the option to use the offline database."; - } - } - else - { - results = "Error: Local XML file not found."; - } - } - catch (Exception ex) - { - results = "Error: " + ex.Message; - } - - return results; - } - - string HexStringToString(string hexString) - { - if (hexString == null || (hexString.Length & 1) == 1) - { - throw new ArgumentException(); - } - var sb = new StringBuilder(); - for (var i = 0; i < hexString.Length; i += 2) - { - var hexChar = hexString.Substring(i, 2); - sb.Append((char)Convert.ToByte(hexChar, 16)); - } - return sb.ToString(); - } - - /// - /// Lauinches a URL in a new window using the default browser... - /// - /// The URL you want to launch - private void OpenUrl(string url) - { - try + if (chkUseOffline.Checked) { - Process.Start(url); - } - catch - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - url = url.Replace("&", "^&"); - Process.Start(new ProcessStartInfo(url) { UseShellExecute = true }); - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - { - Process.Start("xdg-open", url); - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - Process.Start("open", url); - } - else - { - throw; - } + return _uartProvider.ParseErrorsOffline(errorCode); } + + // The user wants to use the online version. Proceed at will + return await _uartProvider.ParseErrorsOnline(errorCode); } private void ResetAppFields() @@ -346,12 +88,12 @@ private void ResetAppFields() /// private void label4_Click(object sender, EventArgs e) { - OpenUrl("https://www.streamelements.com/thecod3r/tip"); + Constants.TipUrl.OpenUrl(); } private void pictureBox2_Click(object sender, EventArgs e) { - OpenUrl("https://www.streamelements.com/thecod3r/tip"); + Constants.TipUrl.OpenUrl(); } @@ -363,255 +105,156 @@ private void browseFileButton_Click(object sender, EventArgs e) fileDialogBox.Title = "Open NOR BIN File"; fileDialogBox.Filter = "PS5 BIN Files|*.bin"; - if (fileDialogBox.ShowDialog() == DialogResult.OK) + if (fileDialogBox.ShowDialog() != DialogResult.OK) + return; + + if(fileDialogBox.CheckFileExists == false) + { + DisplayErrorMessage("The file you selected could not be found. Please check the file exists and is a valid BIN file."); + return; + } + + if(!fileDialogBox.SafeFileName.EndsWith(".bin")) { - if(fileDialogBox.CheckFileExists == false) + DisplayErrorMessage("The file you selected is not a valid. Please ensure the file you are choosing is a correct BIN file and try again."); + return; + } + + // Let's load simple information first, before loading BIN specific data + fileLocationBox.Text = ""; + // Get the path selected and print it into the path box + string selectedPath = fileDialogBox.FileName; + toolStripStatusLabel1.Text = "Status: Selected file " + selectedPath; + fileLocationBox.Text = selectedPath; + + // Get file length and show in bytes and MB + long length = new FileInfo(selectedPath).Length; + fileSizeInfo.Text = length + " bytes (" + length / 1024 / 1024 + "MB)"; + + #region Extract PS5 Version + + offsetOneValue = fileDialogBox.FileName.ExtractValueFromFile(offsetOne, 12, x => x.Replace("-", null)); + //bug: original code is using offsetOne, is this a bug? + offsetTwoValue = fileDialogBox.FileName.ExtractValueFromFile(offsetOne, 12, x => x.Replace("-", null)); + + if(offsetOneValue?.Contains("22020101")??false) + { + modelInfo.Text = "Disc Edition"; + } + else + { + if(offsetTwoValue?.Contains("22030101") ?? false) { - throwError("The file you selected could not be found. Please check the file exists and is a valid BIN file."); + modelInfo.Text = "Digital Edition"; } else { - if(!fileDialogBox.SafeFileName.EndsWith(".bin")) - { - throwError("The file you selected is not a valid. Please ensure the file you are choosing is a correct BIN file and try again."); - } - else - { - // Let's load simple information first, before loading BIN specific data - fileLocationBox.Text = ""; - // Get the path selected and print it into the path box - string selectedPath = fileDialogBox.FileName; - toolStripStatusLabel1.Text = "Status: Selected file " + selectedPath; - fileLocationBox.Text = selectedPath; - - // Get file length and show in bytes and MB - long length = new System.IO.FileInfo(selectedPath).Length; - fileSizeInfo.Text = length.ToString() + " bytes (" + length / 1024 / 1024 + "MB)"; - - #region Extract PS5 Version - - try - { - BinaryReader reader = new BinaryReader(new FileStream(fileDialogBox.FileName, FileMode.Open)); - //Set the position of the reader - reader.BaseStream.Position = offsetOne; - //Read the offset - offsetOneValue = BitConverter.ToString(reader.ReadBytes(12)).Replace("-", null); - reader.Close(); - } - catch - { - // Obviously this value is invalid, so null the value and move on - offsetOneValue = null; - } - - try - { - BinaryReader reader = new BinaryReader(new FileStream(fileDialogBox.FileName, FileMode.Open)); - //Set the position of the reader - reader.BaseStream.Position = offsetOne; - //Read the offset - offsetTwoValue = BitConverter.ToString(reader.ReadBytes(12)).Replace("-", null); - reader.Close(); - } - catch - { - // Obviously this value is invalid, so null the value and move on - offsetTwoValue = null; - } - - - if(offsetOneValue?.Contains("22020101")??false) - { - modelInfo.Text = "Disc Edition"; - } - else - { - if(offsetTwoValue?.Contains("22030101") ?? false) - { - modelInfo.Text = "Digital Edition"; - } - else - { - modelInfo.Text = "Unknown"; - } - } - - #endregion - - #region Extract Motherboard Serial Number - - try - { - BinaryReader reader = new BinaryReader(new FileStream(fileDialogBox.FileName, FileMode.Open)); - //Set the position of the reader - reader.BaseStream.Position = moboSerialOffset; - //Read the offset - moboSerialValue = BitConverter.ToString(reader.ReadBytes(16)).Replace("-", null); - reader.Close(); - } - catch - { - // Obviously this value is invalid, so null the value and move on - moboSerialValue = null; - } - - - - if(moboSerialValue != null) - { - moboSerialInfo.Text = HexStringToString(moboSerialValue); - } - else - { - moboSerialInfo.Text = "Unknown"; - } + modelInfo.Text = "Unknown"; + } + } - #endregion - - #region Extract Board Serial Number - - try - { - BinaryReader reader = new BinaryReader(new FileStream(fileDialogBox.FileName, FileMode.Open)); - //Set the position of the reader - reader.BaseStream.Position = serialOffset; - //Read the offset - serialValue = BitConverter.ToString(reader.ReadBytes(17)).Replace("-", null); - reader.Close(); - } - catch - { - // Obviously this value is invalid, so null the value and move on - serialValue = null; - } + #endregion + #region Extract Motherboard Serial Number + moboSerialValue = fileDialogBox.FileName.ExtractValueFromFile(moboSerialOffset, 12, x => x.Replace("-", null)); + + if(moboSerialValue != null) + { + moboSerialInfo.Text = moboSerialValue.HexStringToString(); + } + else + { + moboSerialInfo.Text = "Unknown"; + } - if (serialValue != null) - { - serialNumber.Text = HexStringToString(serialValue); - serialNumberTextbox.Text = HexStringToString(serialValue); + #endregion - } - else - { - serialNumber.Text = "Unknown"; - } + #region Extract Board Serial Number - #endregion + serialValue = fileDialogBox.FileName.ExtractValueFromFile(serialOffset, 17, x => x.Replace("-", null)); - #region Extract WiFi Mac Address + if (serialValue != null) + { + var hexString = serialValue.HexStringToString(); + serialNumber.Text = hexString; + serialNumberTextbox.Text = hexString; - try - { - BinaryReader reader = new BinaryReader(new FileStream(fileDialogBox.FileName, FileMode.Open)); - //Set the position of the reader - reader.BaseStream.Position = WiFiMacOffset; - //Read the offset - WiFiMacValue = BitConverter.ToString(reader.ReadBytes(6)); - reader.Close(); - } - catch - { - // Obviously this value is invalid, so null the value and move on - WiFiMacValue = null; - } + } + else + { + serialNumber.Text = "Unknown"; + } - if (WiFiMacValue != null) - { - macAddressInfo.Text = WiFiMacValue; - wifiMacAddressTextbox.Text = WiFiMacValue; - } - else - { - macAddressInfo.Text = "Unknown"; - wifiMacAddressTextbox.Text = ""; - } + #endregion - #endregion + #region Extract WiFi Mac Address - #region Extract LAN Mac Address + WiFiMacValue = fileDialogBox.FileName.ExtractValueFromFile(WiFiMacOffset, 6); - try - { - BinaryReader reader = new BinaryReader(new FileStream(fileDialogBox.FileName, FileMode.Open)); - //Set the position of the reader - reader.BaseStream.Position = LANMacOffset; - //Read the offset - LANMacValue = BitConverter.ToString(reader.ReadBytes(6)); - reader.Close(); - } - catch - { - // Obviously this value is invalid, so null the value and move on - LANMacValue = null; - } + if (WiFiMacValue != null) + { + macAddressInfo.Text = WiFiMacValue; + wifiMacAddressTextbox.Text = WiFiMacValue; + } + else + { + macAddressInfo.Text = "Unknown"; + wifiMacAddressTextbox.Text = ""; + } - if (LANMacValue != null) - { - LANMacAddressInfo.Text = LANMacValue; - lanMacAddressTextbox.Text = LANMacValue; - } - else - { - LANMacAddressInfo.Text = "Unknown"; - lanMacAddressTextbox.Text = ""; - } + #endregion - #endregion + #region Extract LAN Mac Address - #region Extract Board Variant + LANMacValue = fileDialogBox.FileName.ExtractValueFromFile(LANMacOffset, 6); - try - { - BinaryReader reader = new BinaryReader(new FileStream(fileDialogBox.FileName, FileMode.Open)); - //Set the position of the reader - reader.BaseStream.Position = variantOffset; - //Read the offset - variantValue = BitConverter.ToString(reader.ReadBytes(19)).Replace("-", null).Replace("FF", null); - reader.Close(); - } - catch - { - // Obviously this value is invalid, so null the value and move on - variantValue = null; - } + if (LANMacValue != null) + { + LANMacAddressInfo.Text = LANMacValue; + lanMacAddressTextbox.Text = LANMacValue; + } + else + { + LANMacAddressInfo.Text = "Unknown"; + lanMacAddressTextbox.Text = ""; + } + #endregion + #region Extract Board Variant - if (variantValue != null) - { - boardVariant.Text = HexStringToString(variantValue); - } - else - { - boardVariant.Text = "Unknown"; - } + variantValue = fileDialogBox.FileName.ExtractValueFromFile(variantOffset, 19, x => x.Replace("-", null).Replace("FF", null)); - boardVariant.Text += boardVariant.Text switch { - _ when boardVariant.Text.EndsWith("00A") || boardVariant.Text.EndsWith("00B") => " - Japan", - _ when boardVariant.Text.EndsWith("01A") || boardVariant.Text.EndsWith("01B") || - boardVariant.Text.EndsWith("15A") || boardVariant.Text.EndsWith("15B") => " - US, Canada, (North America)", - _ when boardVariant.Text.EndsWith("02A") || boardVariant.Text.EndsWith("02B") => " - Australia / New Zealand, (Oceania)", - _ when boardVariant.Text.EndsWith("03A") || boardVariant.Text.EndsWith("03B") => " - United Kingdom / Ireland", - _ when boardVariant.Text.EndsWith("04A") || boardVariant.Text.EndsWith("04B") => " - Europe / Middle East / Africa", - _ when boardVariant.Text.EndsWith("05A") || boardVariant.Text.EndsWith("05B") => " - South Korea", - _ when boardVariant.Text.EndsWith("06A") || boardVariant.Text.EndsWith("06B") => " - Southeast Asia / Hong Kong", - _ when boardVariant.Text.EndsWith("07A") || boardVariant.Text.EndsWith("07B") => " - Taiwan", - _ when boardVariant.Text.EndsWith("08A") || boardVariant.Text.EndsWith("08B") => " - Russia, Ukraine, India, Central Asia", - _ when boardVariant.Text.EndsWith("09A") || boardVariant.Text.EndsWith("09B") => " - Mainland China", - _ when boardVariant.Text.EndsWith("11A") || boardVariant.Text.EndsWith("11B") || - boardVariant.Text.EndsWith("14A") || boardVariant.Text.EndsWith("14B") - => " - Mexico, Central America, South America", - _ when boardVariant.Text.EndsWith("16A") || boardVariant.Text.EndsWith("16B") => " - Europe / Middle East / Africa", - _ when boardVariant.Text.EndsWith("18A") || boardVariant.Text.EndsWith("18B") => " - Singapore, Korea, Asia", - _=> " - Unknown Region" - }; - #endregion - } - } + if (variantValue != null) + { + boardVariant.Text = variantValue.HexStringToString(); } + else + { + boardVariant.Text = "Unknown"; + } + + boardVariant.Text += boardVariant.Text switch { + _ when boardVariant.Text.EndsWith("00A") || boardVariant.Text.EndsWith("00B") => " - Japan", + _ when boardVariant.Text.EndsWith("01A") || boardVariant.Text.EndsWith("01B") || + boardVariant.Text.EndsWith("15A") || boardVariant.Text.EndsWith("15B") => " - US, Canada, (North America)", + _ when boardVariant.Text.EndsWith("02A") || boardVariant.Text.EndsWith("02B") => " - Australia / New Zealand, (Oceania)", + _ when boardVariant.Text.EndsWith("03A") || boardVariant.Text.EndsWith("03B") => " - United Kingdom / Ireland", + _ when boardVariant.Text.EndsWith("04A") || boardVariant.Text.EndsWith("04B") => " - Europe / Middle East / Africa", + _ when boardVariant.Text.EndsWith("05A") || boardVariant.Text.EndsWith("05B") => " - South Korea", + _ when boardVariant.Text.EndsWith("06A") || boardVariant.Text.EndsWith("06B") => " - Southeast Asia / Hong Kong", + _ when boardVariant.Text.EndsWith("07A") || boardVariant.Text.EndsWith("07B") => " - Taiwan", + _ when boardVariant.Text.EndsWith("08A") || boardVariant.Text.EndsWith("08B") => " - Russia, Ukraine, India, Central Asia", + _ when boardVariant.Text.EndsWith("09A") || boardVariant.Text.EndsWith("09B") => " - Mainland China", + _ when boardVariant.Text.EndsWith("11A") || boardVariant.Text.EndsWith("11B") || + boardVariant.Text.EndsWith("14A") || boardVariant.Text.EndsWith("14B") + => " - Mexico, Central America, South America", + _ when boardVariant.Text.EndsWith("16A") || boardVariant.Text.EndsWith("16B") => " - Europe / Middle East / Africa", + _ when boardVariant.Text.EndsWith("18A") || boardVariant.Text.EndsWith("18B") => " - Singapore, Korea, Asia", + _=> " - Unknown Region" + }; + #endregion } private void convertToDigitalEditionButton_Click(object sender, EventArgs e) @@ -623,199 +266,176 @@ private void convertToDigitalEditionButton_Click(object sender, EventArgs e) if (modelInfo.Text == "" || modelInfo.Text == "...") { // No valid BIN file seems to have been selected - throwError("Please select a valid BIOS file first..."); - errorShownAlready = true; + DisplayErrorMessage("Please select a valid BIOS file first..."); + return; } - else + + if(boardModelSelectionBox.Text == "") { - if(boardModelSelectionBox.Text == "") + DisplayErrorMessage("Please select a valid board model before saving new BIOS information!"); + return; + } + + if(boardVariantSelectionBox.Text == "") + { + DisplayErrorMessage("Please select a valid board variant before saving new BIOS information!"); + return; + } + + SaveFileDialog saveBox = new SaveFileDialog(); + saveBox.Title = "Save NOR BIN File"; + saveBox.Filter = "PS5 BIN Files|*.bin"; + + if (saveBox.ShowDialog() != DialogResult.OK) + { + DisplayErrorMessage("Save operation cancelled!"); + return; + } + + // First create a copy of the old BIOS file + byte[] existingFile = File.ReadAllBytes(fileLocationBox.Text); + string newFile = saveBox.FileName; + + File.WriteAllBytes(newFile, existingFile); + + fileNameToLookFor = saveBox.FileName; + + #region Set the new model info + + try + { + GetBiosDetails(out byte[]? find, out byte[]? replace); + + if (find == null || replace == null || find.Length != replace.Length) { - throwError("Please select a valid board model before saving new BIOS information!"); + DisplayErrorMessage("The length of the old hex value does not match the length of the new hex value!"); errorShownAlready = true; } else { - if(boardVariantSelectionBox.Text == "") + byte[] bytes = File.ReadAllBytes(newFile); + foreach (int index in bytes.PatternAt(find)) { - throwError("Please select a valid board variant before saving new BIOS information!"); - errorShownAlready = true; - } - else - { - SaveFileDialog saveBox = new SaveFileDialog(); - saveBox.Title = "Save NOR BIN File"; - saveBox.Filter = "PS5 BIN Files|*.bin"; - - if (saveBox.ShowDialog() == DialogResult.OK) + for (int i = index, replaceIndex = 0; + i < bytes.Length && replaceIndex < replace.Length; + i++, replaceIndex++) { - // First create a copy of the old BIOS file - byte[] existingFile = File.ReadAllBytes(fileLocationBox.Text); - string newFile = saveBox.FileName; - - File.WriteAllBytes(newFile, existingFile); - - fileNameToLookFor = saveBox.FileName; - - #region Set the new model info - if (modelInfo.Text == "Disc Edition") - { - try - { - - if (boardModelSelectionBox.Text == "Digital Edition") - - { - - byte[] find = ConvertHexStringToByteArray(Regex.Replace("22020101", "0x|[ ,]", string.Empty).Normalize().Trim()); - byte[] replace = ConvertHexStringToByteArray(Regex.Replace("22030101", "0x|[ ,]", string.Empty).Normalize().Trim()); - if (find.Length != replace.Length) - { - throwError("The length of the old hex value does not match the length of the new hex value!"); - errorShownAlready = true; - } - byte[] bytes = File.ReadAllBytes(newFile); - foreach (int index in PatternAt(bytes, find)) - { - for (int i = index, replaceIndex = 0; i < bytes.Length && replaceIndex < replace.Length; i++, replaceIndex++) - { - bytes[i] = replace[replaceIndex]; - } - File.WriteAllBytes(newFile, bytes); - } - } - - } - catch - { - throwError("An error occurred while saving your BIOS file"); - errorShownAlready = true; - } - } - else - { - if(modelInfo.Text == "Digital Edition") - { - try - { - - if (boardModelSelectionBox.Text == "Disc Edition") - - { - - byte[] find = ConvertHexStringToByteArray(Regex.Replace("22030101", "0x|[ ,]", string.Empty).Normalize().Trim()); - byte[] replace = ConvertHexStringToByteArray(Regex.Replace("22020101", "0x|[ ,]", string.Empty).Normalize().Trim()); - if (find.Length != replace.Length) - { - throwError("The length of the old hex value does not match the length of the new hex value!"); - errorShownAlready = true; - } - byte[] bytes = File.ReadAllBytes(newFile); - foreach (int index in PatternAt(bytes, find)) - { - for (int i = index, replaceIndex = 0; i < bytes.Length && replaceIndex < replace.Length; i++, replaceIndex++) - { - bytes[i] = replace[replaceIndex]; - } - File.WriteAllBytes(newFile, bytes); - } - } - - } - catch - { - throwError("An error occurred while saving your BIOS file"); - errorShownAlready = true; - } - } - } - #endregion + bytes[i] = replace[replaceIndex]; + } - #region Set the new board variant + File.WriteAllBytes(newFile, bytes); + } + } + } + catch (Exception) + { + DisplayErrorMessage("An error occurred while saving your BIOS file"); + errorShownAlready = true; + } + + #endregion - try - { - byte[] oldVariant = Encoding.UTF8.GetBytes(boardVariant.Text); - string oldVariantHex = Convert.ToHexString(oldVariant); + #region Set the new board variant - byte[] newVariantSelection = Encoding.UTF8.GetBytes(boardVariantSelectionBox.Text); - string newVariantHex = Convert.ToHexString(newVariantSelection); + try + { + byte[] oldVariant = Encoding.UTF8.GetBytes(boardVariant.Text); + string oldVariantHex = Convert.ToHexString(oldVariant); - byte[] find = ConvertHexStringToByteArray(Regex.Replace(oldVariantHex, "0x|[ ,]", string.Empty).Normalize().Trim()); - byte[] replace = ConvertHexStringToByteArray(Regex.Replace(newVariantHex, "0x|[ ,]", string.Empty).Normalize().Trim()); + byte[] newVariantSelection = Encoding.UTF8.GetBytes(boardVariantSelectionBox.Text); + string newVariantHex = Convert.ToHexString(newVariantSelection); - byte[] bytes = File.ReadAllBytes(newFile); - foreach (int index in PatternAt(bytes, find)) - { - for (int i = index, replaceIndex = 0; i < bytes.Length && replaceIndex < replace.Length; i++, replaceIndex++) - { - bytes[i] = replace[replaceIndex]; - } - File.WriteAllBytes(newFile, bytes); - } + byte[] find = oldVariantHex.ConvertHexStringToByteArray("0x|[ ,]", string.Empty); + byte[] replace = newVariantHex.ConvertHexStringToByteArray("0x|[ ,]", string.Empty); - } - catch(System.ArgumentException ex) - { - throwError(ex.Message.ToString()); - errorShownAlready = true; - } - - #endregion + byte[] bytes = File.ReadAllBytes(newFile); + foreach (int index in bytes.PatternAt(find)) + { + for (int i = index, replaceIndex = 0; i < bytes.Length && replaceIndex < replace.Length; i++, replaceIndex++) + { + bytes[i] = replace[replaceIndex]; + } + File.WriteAllBytes(newFile, bytes); + } - #region Change Serial Number + } + catch(ArgumentException ex) + { + DisplayErrorMessage(ex.Message.ToString()); + errorShownAlready = true; + } - try - { + #endregion - byte[] oldSerial = Encoding.UTF8.GetBytes(serialNumber.Text); - string oldSerialHex = Convert.ToHexString(oldSerial); + #region Change Serial Number - byte[] newSerial = Encoding.UTF8.GetBytes(serialNumberTextbox.Text); - string newSerialHex = Convert.ToHexString(newSerial); + try + { - byte[] find = ConvertHexStringToByteArray(Regex.Replace(oldSerialHex, "0x|[ ,]", string.Empty).Normalize().Trim()); - byte[] replace = ConvertHexStringToByteArray(Regex.Replace(newSerialHex, "0x|[ ,]", string.Empty).Normalize().Trim()); + byte[] oldSerial = Encoding.UTF8.GetBytes(serialNumber.Text); + string oldSerialHex = Convert.ToHexString(oldSerial); - byte[] bytes = File.ReadAllBytes(newFile); - foreach (int index in PatternAt(bytes, find)) - { - for (int i = index, replaceIndex = 0; i < bytes.Length && replaceIndex < replace.Length; i++, replaceIndex++) - { - bytes[i] = replace[replaceIndex]; - } - File.WriteAllBytes(newFile, bytes); - } + byte[] newSerial = Encoding.UTF8.GetBytes(serialNumberTextbox.Text); + string newSerialHex = Convert.ToHexString(newSerial); - } - catch (System.ArgumentException ex) - { - throwError(ex.Message.ToString()); - errorShownAlready = true; - } + byte[] find = oldSerialHex.ConvertHexStringToByteArray("0x|[ ,]", string.Empty); + byte[] replace = newSerialHex.ConvertHexStringToByteArray("0x|[ ,]", string.Empty); - #endregion - } - else - { - throwError("Save operation cancelled!"); - errorShownAlready = true; - } + byte[] bytes = File.ReadAllBytes(newFile); + foreach (int index in bytes.PatternAt(find)) + { + for (int i = index, replaceIndex = 0; i < bytes.Length && replaceIndex < replace.Length; i++, replaceIndex++) + { + bytes[i] = replace[replaceIndex]; } + File.WriteAllBytes(newFile, bytes); } + } + catch (ArgumentException ex) + { + DisplayErrorMessage(ex.Message); + errorShownAlready = true; + } + + #endregion + - if(File.Exists(fileNameToLookFor) && errorShownAlready == false) + if(File.Exists(fileNameToLookFor) && !errorShownAlready) { // Reset everything and show message ResetAppFields(); - MessageBox.Show("A new BIOS file was successfully created. Please load the new BIOS file to verify the information you entered before installing onto your motherboard. Remember this software was created by TheCod3r with nothing but love. Why not show some love back by dropping me a small donation to say thanks ;).", "All done!", MessageBoxButtons.OK, MessageBoxIcon.Information); + _notificationHandler.HandleMessage(new Notification + { + Message = "A new BIOS file was successfully created. Please load the new BIOS file to verify the information you entered before installing onto your motherboard. Remember this software was created by TheCod3r with nothing but love. Why not show some love back by dropping me a small donation to say thanks ;).", + Title = "All done!", + Type = NotificationType.Information, + }); } + } + private void GetBiosDetails(out byte[]? find, out byte[]? replace) + { + find = null; + replace = null; + + if (modelInfo.Text == "Disc Edition" && boardModelSelectionBox.Text == "Digital Edition") + { + find = "22020101".ConvertHexStringToByteArray("0x|[ ,]", string.Empty); + replace = "22030101".ConvertHexStringToByteArray("0x|[ ,]", string.Empty); + return; + } + + if (modelInfo.Text == "Digital Edition" && boardModelSelectionBox.Text == "Disc Edition") + { + find = "22030101".ConvertHexStringToByteArray("0x|[ ,]", string.Empty); + replace = "22020101".ConvertHexStringToByteArray("0x|[ ,]", string.Empty); + } } private void label15_Click(object sender, EventArgs e) { - OpenUrl("https://www.consolefix.shop"); + Constants.ShopUrl.OpenUrl(); } private void label1_Click(object sender, EventArgs e) @@ -823,13 +443,19 @@ private void label1_Click(object sender, EventArgs e) } + // When the "refresh ports" button is pressed, we need to refresh the list of available COM ports for UART private void btnRefreshPorts_Click(object sender, EventArgs e) + => UpdatePorts(); + + private void UpdatePorts() { - // When the "refresh ports" button is pressed, we need to refresh the list of available COM ports for UART string[] ports = SerialPort.GetPortNames(); comboComPorts.Items.Clear(); - comboComPorts.Items.AddRange(ports); - comboComPorts.SelectedIndex = 0; + if (ports.Length > 0) + { + comboComPorts.Items.AddRange(ports); + comboComPorts.SelectedIndex = 0; + } btnConnectCom.Enabled = true; btnDisconnectCom.Enabled = false; } @@ -839,34 +465,41 @@ private void btnConnectCom_Click(object sender, EventArgs e) // Let's try and connect to the UART reader btnConnectCom.Enabled = false; - if (comboComPorts.Text != "") + if (string.IsNullOrWhiteSpace(comboComPorts.Text)) { - - try - { - // Set port to selected port - UARTSerial.PortName = comboComPorts.Text; - // Set the BAUD rate to 115200 - UARTSerial.BaudRate = 115200; - // Enable RTS - UARTSerial.RtsEnable = true; - // Open the COM port - UARTSerial.Open(); - btnDisconnectCom.Enabled = true; - toolStripStatusLabel1.Text = "Connected to UART via COM port " + comboComPorts.Text + " at a BAUD rate of 115200."; - } - catch (Exception ex) + _notificationHandler.HandleMessage(new Notification { - MessageBox.Show(ex.Message, "An error occurred...", MessageBoxButtons.OK, MessageBoxIcon.Error); - btnConnectCom.Enabled = true; - btnDisconnectCom.Enabled = false; - toolStripStatusLabel1.Text = "Could not connect to UART. Please try again!"; - } - + Message = "Please select a COM port from the ports list to establish a connection.", + Title = "An error occurred...", + Type = NotificationType.Error, + }); + btnConnectCom.Enabled = true; + btnDisconnectCom.Enabled = false; + toolStripStatusLabel1.Text = "Could not connect to UART. Please try again!"; + return; } - else + + try { - MessageBox.Show("Please select a COM port from the ports list to establish a connection.", "An error occurred...", MessageBoxButtons.OK, MessageBoxIcon.Error); + // Set port to selected port + UARTSerial.PortName = comboComPorts.Text; + // Set the BAUD rate to 115200 + UARTSerial.BaudRate = 115200; + // Enable RTS + UARTSerial.RtsEnable = true; + // Open the COM port + UARTSerial.Open(); + btnDisconnectCom.Enabled = true; + toolStripStatusLabel1.Text = $"Connected to UART via COM port {comboComPorts.Text} at a BAUD rate of 115200."; + } + catch (Exception ex) + { + _notificationHandler.HandleMessage(new Notification + { + Message = ex.Message, + Title = "An error occurred...", + Type = NotificationType.Error, + }); btnConnectCom.Enabled = true; btnDisconnectCom.Enabled = false; toolStripStatusLabel1.Text = "Could not connect to UART. Please try again!"; @@ -888,7 +521,12 @@ private void btnDisconnectCom_Click(object sender, EventArgs e) } catch(Exception ex) { - MessageBox.Show(ex.Message, "An error occurred...", MessageBoxButtons.OK, MessageBoxIcon.Error); + _notificationHandler.HandleMessage(new Notification + { + Message = ex.Message, + Title = "An error occurred...", + Type = NotificationType.Error + }); toolStripStatusLabel1.Text = "An error occurred while disconnecting from UART. Please try again..."; } } @@ -903,76 +541,88 @@ private async void button1_Click(object sender, EventArgs e) // Let's read the error codes from UART txtUARTOutput.Text = ""; - if (UARTSerial.IsOpen == true) + if (!UARTSerial.IsOpen) { - try + _notificationHandler.HandleMessage(new Notification { + Message = "Please connect to UART before attempting to read the error codes.", + Title = "An error occurred...", + Type = NotificationType.Warning + }); + return; + } + + try + { + List UARTLines = new(); - List UARTLines = new(); - - for (var i = 0; i <= 10; i++) + for (var i = 0; i <= 10; i++) + { + var command = $"errlog {i}"; + var checksum = command.CalculateChecksum(); + UARTSerial.WriteLine(checksum); + do { - var command = $"errlog {i}"; - var checksum = CalculateChecksum(command); - UARTSerial.WriteLine(checksum); - do + var line = UARTSerial.ReadLine(); + if (!string.Equals($"{command}:{checksum:X2}", line, StringComparison.InvariantCultureIgnoreCase)) { - var line = UARTSerial.ReadLine(); - if (!string.Equals($"{command}:{checksum:X2}", line, StringComparison.InvariantCultureIgnoreCase)) - { - UARTLines.Add(line); - } - } while (UARTSerial.BytesToRead != 0); + UARTLines.Add(line); + } + } while (UARTSerial.BytesToRead != 0); - foreach (var l in UARTLines) - { - var split = l.Split(' '); - if (!split.Any()) continue; - switch (split[0]) - { - case "NG": - break; - case "OK": - var errorCode = split[2]; - // Now that the error code has been isolated from the rest of the junk sent by the system - // let's check it against the database. The error server will need to return XML results - string errorResult = await ParseErrorsAsync(errorCode); - if (!txtUARTOutput.Text.Contains(errorResult)) - { - txtUARTOutput.AppendText(errorResult + Environment.NewLine); - } - break; - } + foreach (var l in UARTLines) + { + var split = l.Split(' '); + if (!split.Any()) continue; + switch (split[0]) + { + case "NG": + break; + case "OK": + var errorCode = split[2]; + // Now that the error code has been isolated from the rest of the junk sent by the system + // let's check it against the database. The error server will need to return XML results + string errorResult = await ParseErrorsAsync(errorCode); + if (!txtUARTOutput.Text.Contains(errorResult)) + { + txtUARTOutput.AppendText(errorResult + Environment.NewLine); + } + break; } } } - catch (Exception ex) - { - MessageBox.Show(ex.Message, "An error occurred...", MessageBoxButtons.OK, MessageBoxIcon.Error); - toolStripStatusLabel1.Text = "An error occurred while reading error codes from UART. Please try again..."; - } } - else + catch (Exception ex) { - MessageBox.Show("Please connect to UART before attempting to read the error codes.", "An error occurred...", MessageBoxButtons.OK, MessageBoxIcon.Warning); + _notificationHandler.HandleMessage(new Notification + { + Message = ex.Message, + Title = "An error occurred...", + Type = NotificationType.Error + }); + toolStripStatusLabel1.Text = "An error occurred while reading error codes from UART. Please try again..."; } } // If the app is closed before UART is terminated, we need to at least try to close the COM port gracefully first private void Form1_FormClosing(object sender, FormClosingEventArgs e) { - if(UARTSerial.IsOpen == true) + if (!UARTSerial.IsOpen) + return; + + try { - try - { - UARTSerial.Close(); - } - catch(Exception ex) + UARTSerial.Close(); + } + catch(Exception ex) + { + _notificationHandler.HandleMessage(new Notification { - MessageBox.Show(ex.Message, "An error occurred...", MessageBoxButtons.OK, MessageBoxIcon.Error); - } + Message = ex.Message, + Title = "An error occurred...", + Type = NotificationType.Error + }); } - } /// @@ -993,18 +643,18 @@ private void button3_Click(object sender, EventArgs e) /// private async void btnDownloadDatabase_Click(object sender, EventArgs e) { - DialogResult result = MessageBox.Show("Downloading the error database will overwrite any existing offline database you currently have. Are you sure you would like to do this?", "Are you sure?", MessageBoxButtons.YesNo, MessageBoxIcon.Question); - // Check if user wants to proceed - if (result == DialogResult.Yes) - { - // Call the function to download and save the XML data - await DownloadDatabaseAsync(); - } - else - { - // Do nothing. The user cancelled the request// The user cancelled - } + await _notificationHandler.HandleQuestion( + new AsyncQuestion + { + Message = + "Downloading the error database will overwrite any existing offline database you currently have. Are you sure you would like to do this?", + Title = "Are you sure?", + + // Call the function to download and save the XML data + OnYes = async () => await _uartProvider.UpdateErrorDatabase() + // Do nothing. The user cancelled the request// The user cancelled + }); } /// @@ -1016,67 +666,78 @@ private async void btnDownloadDatabase_Click(object sender, EventArgs e) /// private void btnClearErrorCodes_Click(object sender, EventArgs e) { - DialogResult result = MessageBox.Show("This will clear error codes from the console by sending the \"errlog clear\" command. Are you sure you would like to proceed? This action cannot be undone!", "Are you sure?", MessageBoxButtons.YesNo, MessageBoxIcon.Question); + _notificationHandler.HandleQuestion(new Question + { + Message = + "This will clear error codes from the console by sending the \"errlog clear\" command. Are you sure you would like to proceed? This action cannot be undone!", + Title = "Are you sure?", + OnYes = ClearErrorCodes + }); + } - if(result == DialogResult.Yes) + private void ClearErrorCodes() + { + // Let's read the error codes from UART + txtUARTOutput.Text = ""; + + if (!UARTSerial.IsOpen) + { + _notificationHandler.HandleMessage(new Notification + { + Message = "Please connect to UART before attempting to send commands.", + Title = "An error occurred...", + Type = NotificationType.Warning + }); + return; + } + + try { - // Let's read the error codes from UART - txtUARTOutput.Text = ""; + List UARTLines = new(); - if (UARTSerial.IsOpen == true) + var command = "errlog clear"; + var checksum = command.CalculateChecksum(); + UARTSerial.WriteLine(checksum); + do { - try + var line = UARTSerial.ReadLine(); + if (!string.Equals($"{command}:{checksum:X2}", line, StringComparison.InvariantCultureIgnoreCase)) { + UARTLines.Add(line); + } + } while (UARTSerial.BytesToRead != 0); - List UARTLines = new(); - - var command = "errlog clear"; - var checksum = CalculateChecksum(command); - UARTSerial.WriteLine(checksum); - do + foreach (var l in UARTLines) + { + var split = l.Split(' '); + if (!split.Any()) continue; + switch (split[0]) + { + case "NG": + if (!txtUARTOutput.Text.Contains("FAIL")) { - var line = UARTSerial.ReadLine(); - if (!string.Equals($"{command}:{checksum:X2}", line, StringComparison.InvariantCultureIgnoreCase)) - { - UARTLines.Add(line); - } - } while (UARTSerial.BytesToRead != 0); - - foreach (var l in UARTLines) - { - var split = l.Split(' '); - if (!split.Any()) continue; - switch (split[0]) + txtUARTOutput.AppendText("Response: FAIL" + Environment.NewLine + "Information: An error occurred while clearing the error logs from the system. Please try again..."); + } + break; + case "OK": + if (!txtUARTOutput.Text.Contains("SUCCESS")) { - case "NG": - if (!txtUARTOutput.Text.Contains("FAIL")) - { - txtUARTOutput.AppendText("Response: FAIL" + Environment.NewLine + "Information: An error occurred while clearing the error logs from the system. Please try again..."); - } - break; - case "OK": - if (!txtUARTOutput.Text.Contains("SUCCESS")) - { - txtUARTOutput.AppendText("Response: SUCCESS" + Environment.NewLine + "Information: All error codes cleared successfully"); - } - break; + txtUARTOutput.AppendText("Response: SUCCESS" + Environment.NewLine + "Information: All error codes cleared successfully"); } - } + break; } - catch (Exception ex) - { - MessageBox.Show(ex.Message, "An error occurred...", MessageBoxButtons.OK, MessageBoxIcon.Error); - toolStripStatusLabel1.Text = "An error occurred while attempting to send a UART command. Please try again..."; - } - } - else - { - MessageBox.Show("Please connect to UART before attempting to send commands.", "An error occurred...", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } - else + catch (Exception ex) { - // Do nothing. The user cancelled the request + _notificationHandler.HandleMessage(new Notification + { + Message = ex.Message, + Title = "An error occurred...", + Type = NotificationType.Error + }); + + toolStripStatusLabel1.Text = "An error occurred while attempting to send a UART command. Please try again..."; } } @@ -1087,58 +748,72 @@ private void btnClearErrorCodes_Click(object sender, EventArgs e) /// private void btnSendCommand_Click(object sender, EventArgs e) { - if (txtCustomCommand.Text != "") + if (string.IsNullOrWhiteSpace(txtCustomCommand.Text)) { - // Let's read the error codes from UART - txtUARTOutput.Text = ""; + _notificationHandler.HandleMessage(new Notification + { + Message = "Please enter a command to send via UART.", + Title = "An error occurred...", + Type = NotificationType.Warning + }); + return; + } - if (UARTSerial.IsOpen == true) + if (!UARTSerial.IsOpen) + { + _notificationHandler.HandleMessage(new Notification { - try - { + Message = "Please connect to UART before attempting to send commands.", + Title = "An error occurred...", + Type = NotificationType.Warning + }); + return; + } + + // Let's read the error codes from UART + txtUARTOutput.Text = ""; - List UARTLines = new(); + try + { - var checksum = CalculateChecksum(txtCustomCommand.Text); - UARTSerial.WriteLine(checksum); - do - { - var line = UARTSerial.ReadLine(); - if (!string.Equals($"{txtCustomCommand.Text}:{checksum:X2}", line, StringComparison.InvariantCultureIgnoreCase)) - { - UARTLines.Add(line); - } - } while (UARTSerial.BytesToRead != 0); + List uartLines = new(); - foreach (var l in UARTLines) - { - var split = l.Split(' '); - if (!split.Any()) continue; - switch (split[0]) - { - case "NG": - txtUARTOutput.Text = "ERROR: " + l; - break; - case "OK": - txtUARTOutput.Text = "SUCCESS: " + l; - break; - } - } - } - catch (Exception ex) + var checksum = txtCustomCommand.Text.CalculateChecksum(); + UARTSerial.WriteLine(checksum); + do + { + var line = UARTSerial.ReadLine(); + if (!string.Equals($"{txtCustomCommand.Text}:{checksum:X2}", line, StringComparison.InvariantCultureIgnoreCase)) { - MessageBox.Show(ex.Message, "An error occurred...", MessageBoxButtons.OK, MessageBoxIcon.Error); - toolStripStatusLabel1.Text = "An error occurred while reading error codes from UART. Please try again..."; + uartLines.Add(line); } - } - else + } while (UARTSerial.BytesToRead != 0); + + foreach (var l in uartLines) { - MessageBox.Show("Please connect to UART before attempting to send commands.", "An error occurred...", MessageBoxButtons.OK, MessageBoxIcon.Warning); + var split = l.Split(' '); + if (!split.Any()) continue; + switch (split[0]) + { + case "NG": + txtUARTOutput.Text = $"ERROR: {l}"; + break; + case "OK": + txtUARTOutput.Text = $"SUCCESS: {l}"; + break; + } } } - else + catch (Exception ex) { - MessageBox.Show("Please enter a command to send via UART.", "An error occurred...", MessageBoxButtons.OK, MessageBoxIcon.Warning); + _notificationHandler.HandleMessage(new Notification + { + Message = ex.Message, + Title = "An error occurred...", + Type = NotificationType.Error + }); + + toolStripStatusLabel1.Text = "An error occurred while reading error codes from UART. Please try again..."; } } diff --git a/PS5 NOR Modifier/PS5 NOR Modifier.csproj b/PS5 NOR Modifier/PS5 NOR Modifier.csproj index 811a503..c581016 100644 --- a/PS5 NOR Modifier/PS5 NOR Modifier.csproj +++ b/PS5 NOR Modifier/PS5 NOR Modifier.csproj @@ -2,7 +2,7 @@ WinExe - net6.0-windows + net8.0-windows PS5_NOR_Modifier enable true @@ -34,6 +34,9 @@ + + + @@ -64,4 +67,8 @@ + + + + \ No newline at end of file diff --git a/PS5 NOR Modifier/Program.cs b/PS5 NOR Modifier/Program.cs index 62a6e6b..9f74ba0 100644 --- a/PS5 NOR Modifier/Program.cs +++ b/PS5 NOR Modifier/Program.cs @@ -1,3 +1,9 @@ +using Microsoft.Extensions.DependencyInjection; +using PS5_NOR_Modifier.Dialogs; +using PS5_NOR_Modifier.Extensions; +using UART.Core.Abstractions; +using UART.Core.Data; + namespace PS5_NOR_Modifier { internal static class Program @@ -8,10 +14,21 @@ internal static class Program [STAThread] static void Main() { + IServiceProvider provider = new ServiceCollection() + .AddInMemoryConfiguration() + .AddSingleton() + .AddSingleton() + .BuildServiceProvider(); + // To customize application configuration such as set high DPI settings or default font, // see https://aka.ms/applicationconfiguration. ApplicationConfiguration.Initialize(); - Application.Run(new Form1()); + Application.Run( + new Form1( + provider.GetRequiredService(), + provider.GetRequiredService() + ) + ); } } } \ No newline at end of file diff --git a/UART-CL By TheCod3r/UART-CL By TheCod3r/Program.cs b/UART-CL By TheCod3r/UART-CL By TheCod3r/Program.cs index aa87133..dd082ab 100644 --- a/UART-CL By TheCod3r/UART-CL By TheCod3r/Program.cs +++ b/UART-CL By TheCod3r/UART-CL By TheCod3r/Program.cs @@ -11,6 +11,7 @@ using System.Text; using System.Text.RegularExpressions; using System.Globalization; +using UART.Core.Extensions; #region Reminders (remove before publishing) // Add check inside sub menu to confirm that the selected .bin file is a valid PS5 dump @@ -24,64 +25,6 @@ // Set the application title System.Console.Title = appTitle; -#region Checksum generation -static string CalculateChecksum(string str) -{ - // Math stuff. I don't understand it either! - int sum = 0; - foreach (char c in str) - { - sum += (int)c; - } - return str + ":" + (sum & 0xFF).ToString("X2"); -} -#endregion - -#region Hex conversions -static string HexStringToString(string hexString) -{ - if (hexString == null || (hexString.Length & 1) == 1) - { - throw new ArgumentException(); - } - var sb = new StringBuilder(); - for (var i = 0; i < hexString.Length; i += 2) - { - var hexChar = hexString.Substring(i, 2); - sb.Append((char)Convert.ToByte(hexChar, 16)); - } - return sb.ToString(); -} - -static IEnumerable PatternAt(byte[] source, byte[] pattern) -{ - for (int i = 0; i < source.Length; i++) - { - if (source.Skip(i).Take(pattern.Length).SequenceEqual(pattern)) - { - yield return i; - } - } -} - -static byte[] ConvertHexStringToByteArray(string hexString) -{ - if (hexString.Length % 2 != 0) - { - throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The binary key cannot have an odd number of digits: {0}", hexString)); - } - - byte[] data = new byte[hexString.Length / 2]; - for (int index = 0; index < data.Length; index++) - { - string byteValue = hexString.Substring(index * 2, 2); - data[index] = Convert.ToByte(byteValue, 16); // Parse hex string directly - } - - return data; -} -#endregion - #region Error parsing (via XML database) // When fetching errors from the PS5 we want to be able to convert the received codes into readable text to make it easier @@ -491,7 +434,7 @@ static void RunSubMenu(string appTitle, Dictionary regionMap) // Catch any exceptions and ignore, setting variantValue to null } - ConsoleModelInfo = HexStringToString(variantValue); + ConsoleModelInfo = variantValue.HexStringToString(); string region = "Unknown Region"; if (ConsoleModelInfo != null && ConsoleModelInfo.Length >= 3) @@ -503,7 +446,7 @@ static void RunSubMenu(string appTitle, Dictionary regionMap) } } - ModelInfo = HexStringToString(variantValue) + " - " + region; + ModelInfo = variantValue.HexStringToString() + " - " + region; #endregion #region Get Console Serial Number @@ -527,8 +470,8 @@ static void RunSubMenu(string appTitle, Dictionary regionMap) if (serialValue != null) { - ConsoleSerialNumber = HexStringToString(serialValue); - ConsoleSerialNumber = HexStringToString(serialValue); + ConsoleSerialNumber = serialValue.HexStringToString(); + ConsoleSerialNumber = serialValue.HexStringToString(); } else @@ -559,7 +502,7 @@ static void RunSubMenu(string appTitle, Dictionary regionMap) if (moboSerialValue != null) { - MotherboardSerialNumber = HexStringToString(moboSerialValue); + MotherboardSerialNumber = moboSerialValue.HexStringToString(); } else { @@ -716,11 +659,11 @@ static void RunSubMenu(string appTitle, Dictionary regionMap) // Modify the values to set the file as "Digital Edition" try { - byte[] find = ConvertHexStringToByteArray(Regex.Replace("22010101", "0x|[ ,]", string.Empty).Normalize().Trim()); - byte[] replace = ConvertHexStringToByteArray(Regex.Replace("22030101", "0x|[ ,]", string.Empty).Normalize().Trim()); + byte[] find = "22010101".ConvertHexStringToByteArray("0x|[ ,]", string.Empty); + byte[] replace = "22030101".ConvertHexStringToByteArray("0x|[ ,]", string.Empty); byte[] bytes = File.ReadAllBytes(pathToDump); - foreach (int index in PatternAt(bytes, find)) + foreach (int index in bytes.PatternAt(find)) { for (int i = index, replaceIndex = 0; i < bytes.Length && replaceIndex < replace.Length; i++, replaceIndex++) { @@ -729,10 +672,10 @@ static void RunSubMenu(string appTitle, Dictionary regionMap) File.WriteAllBytes(pathToDump, bytes); } - byte[] find2 = ConvertHexStringToByteArray(Regex.Replace("22020101", "0x|[ ,]", string.Empty).Normalize().Trim()); - byte[] replace2 = ConvertHexStringToByteArray(Regex.Replace("22030101", "0x|[ ,]", string.Empty).Normalize().Trim()); + byte[] find2 = "22020101".ConvertHexStringToByteArray("0x|[ ,]", string.Empty); + byte[] replace2 = "22030101".ConvertHexStringToByteArray("0x|[ ,]", string.Empty); - foreach (int index in PatternAt(bytes, find2)) + foreach (int index in bytes.PatternAt(find2)) { for (int i = index, replaceIndex = 0; i < bytes.Length && replaceIndex < replace.Length; i++, replaceIndex++) { @@ -849,11 +792,11 @@ static void RunSubMenu(string appTitle, Dictionary regionMap) // Modify the values to set the file as "Disc Edition" try { - byte[] find = ConvertHexStringToByteArray(Regex.Replace("22010101", "0x|[ ,]", string.Empty).Normalize().Trim()); - byte[] replace = ConvertHexStringToByteArray(Regex.Replace("22020101", "0x|[ ,]", string.Empty).Normalize().Trim()); + byte[] find = "22010101".ConvertHexStringToByteArray("0x|[ ,]", string.Empty); + byte[] replace = "22020101".ConvertHexStringToByteArray( "0x|[ ,]", string.Empty); byte[] bytes = File.ReadAllBytes(pathToDump); - foreach (int index in PatternAt(bytes, find)) + foreach (int index in bytes.PatternAt(find)) { for (int i = index, replaceIndex = 0; i < bytes.Length && replaceIndex < replace.Length; i++, replaceIndex++) { @@ -862,10 +805,10 @@ static void RunSubMenu(string appTitle, Dictionary regionMap) File.WriteAllBytes(pathToDump, bytes); } - byte[] find2 = ConvertHexStringToByteArray(Regex.Replace("22030101", "0x|[ ,]", string.Empty).Normalize().Trim()); - byte[] replace2 = ConvertHexStringToByteArray(Regex.Replace("22020101", "0x|[ ,]", string.Empty).Normalize().Trim()); + byte[] find2 = "22030101".ConvertHexStringToByteArray("0x|[ ,]", string.Empty); + byte[] replace2 = "22020101".ConvertHexStringToByteArray("0x|[ ,]", string.Empty); - foreach (int index in PatternAt(bytes, find2)) + foreach (int index in bytes.PatternAt(find2)) { for (int i = index, replaceIndex = 0; i < bytes.Length && replaceIndex < replace.Length; i++, replaceIndex++) { @@ -981,11 +924,11 @@ static void RunSubMenu(string appTitle, Dictionary regionMap) // Modify the values to set the file as "Slim Edition" try { - byte[] find = ConvertHexStringToByteArray(Regex.Replace("22020101", "0x|[ ,]", string.Empty).Normalize().Trim()); - byte[] replace = ConvertHexStringToByteArray(Regex.Replace("22010101", "0x|[ ,]", string.Empty).Normalize().Trim()); + byte[] find = "22020101".ConvertHexStringToByteArray("0x|[ ,]", string.Empty); + byte[] replace = "22010101".ConvertHexStringToByteArray("0x|[ ,]", string.Empty); byte[] bytes = File.ReadAllBytes(pathToDump); - foreach (int index in PatternAt(bytes, find)) + foreach (int index in bytes.PatternAt(find)) { for (int i = index, replaceIndex = 0; i < bytes.Length && replaceIndex < replace.Length; i++, replaceIndex++) { @@ -994,10 +937,10 @@ static void RunSubMenu(string appTitle, Dictionary regionMap) File.WriteAllBytes(pathToDump, bytes); } - byte[] find2 = ConvertHexStringToByteArray(Regex.Replace("22030101", "0x|[ ,]", string.Empty).Normalize().Trim()); - byte[] replace2 = ConvertHexStringToByteArray(Regex.Replace("22010101", "0x|[ ,]", string.Empty).Normalize().Trim()); + byte[] find2 = "22030101".ConvertHexStringToByteArray("0x|[ ,]", string.Empty); + byte[] replace2 = "22010101".ConvertHexStringToByteArray("0x|[ ,]", string.Empty); - foreach (int index in PatternAt(bytes, find2)) + foreach (int index in bytes.PatternAt(find2)) { for (int i = index, replaceIndex = 0; i < bytes.Length && replaceIndex < replace.Length; i++, replaceIndex++) { @@ -1119,7 +1062,7 @@ static void RunSubMenu(string appTitle, Dictionary regionMap) Array.Copy(newSerialBytes, newSerialBytesPadded, Math.Min(newSerialBytes.Length, 17)); // Find the index of the old serial number in the file - int index = PatternAt(existingFile, oldSerialBytes).FirstOrDefault(); + int index = existingFile.PatternAt(oldSerialBytes).FirstOrDefault(); if (index != -1) { @@ -1192,7 +1135,7 @@ static void RunSubMenu(string appTitle, Dictionary regionMap) // Catch any exceptions and ignore, setting MotherboardSerial to null } - MotherboardSerial = HexStringToString(moboValue); + MotherboardSerial = moboValue.HexStringToString(); if (!string.IsNullOrEmpty(moboValue) != null && !string.IsNullOrEmpty(MotherboardSerial)) { @@ -1237,11 +1180,11 @@ static void RunSubMenu(string appTitle, Dictionary regionMap) byte[] newSerialBytes = Encoding.UTF8.GetBytes(newSerial); string newSerialHex = Convert.ToHexString(newSerialBytes); - byte[] find = ConvertHexStringToByteArray(Regex.Replace(oldSerialHex, "0x|[ ,]", string.Empty).Normalize().Trim()); - byte[] replace = ConvertHexStringToByteArray(Regex.Replace(newSerialHex, "0x|[ ,]", string.Empty).Normalize().Trim()); + byte[] find = oldSerialHex.ConvertHexStringToByteArray("0x|[ ,]", string.Empty); + byte[] replace = newSerialHex.ConvertHexStringToByteArray("0x|[ ,]", string.Empty); byte[] bytes = File.ReadAllBytes(pathToDump); - foreach (int index in PatternAt(bytes, find)) + foreach (int index in bytes.PatternAt(find)) { for (int i = index, replaceIndex = 0; i < bytes.Length && replaceIndex < replace.Length; i++, replaceIndex++) { @@ -1317,7 +1260,7 @@ static void RunSubMenu(string appTitle, Dictionary regionMap) // Catch any exceptions and ignore, setting variantValue to null } - ConsoleModel = HexStringToString(variantValue); + ConsoleModel = variantValue.HexStringToString(); if(!string.IsNullOrEmpty(variantValue) != null && !string.IsNullOrEmpty(ConsoleModel)) { @@ -1363,11 +1306,11 @@ static void RunSubMenu(string appTitle, Dictionary regionMap) byte[] newModelBytes = Encoding.UTF8.GetBytes(newModel); string newModelHex = Convert.ToHexString(newModelBytes); - byte[] find = ConvertHexStringToByteArray(Regex.Replace(oldModelHex, "0x|[ ,]", string.Empty).Normalize().Trim()); - byte[] replace = ConvertHexStringToByteArray(Regex.Replace(newModelHex, "0x|[ ,]", string.Empty).Normalize().Trim()); + byte[] find = oldModelHex.ConvertHexStringToByteArray("0x|[ ,]", string.Empty); + byte[] replace = newModelHex.ConvertHexStringToByteArray("0x|[ ,]", string.Empty); byte[] bytes = File.ReadAllBytes(pathToDump); - foreach (int index in PatternAt(bytes, find)) + foreach (int index in bytes.PatternAt(find)) { for (int i = index, replaceIndex = 0; i < bytes.Length && replaceIndex < replace.Length; i++, replaceIndex++) { @@ -1530,7 +1473,7 @@ static bool MainMenu(string appTitle, Dictionary regionMap) // Create a command variable depending on what number we're at in the loop (where "i" is the current number) var command = $"errlog {i}"; // Add the checksum to the command - var checksum = CalculateChecksum(command); + var checksum = command.CalculateChecksum(); // Send the current command to the UART device serialPort.WriteLine(checksum); @@ -1653,7 +1596,7 @@ static bool MainMenu(string appTitle, Dictionary regionMap) // Reset the foreground color to default before proceeding System.Console.ResetColor(); - var checksum = CalculateChecksum("errlog clear"); + var checksum = "errlog clear".CalculateChecksum(); serialPort.WriteLine(checksum); List UARTLines = new(); @@ -1751,7 +1694,7 @@ static bool MainMenu(string appTitle, Dictionary regionMap) } else if (!string.IsNullOrEmpty(UARTCommand)) // If the command is not empty or null { - var checksum = CalculateChecksum(UARTCommand); + var checksum = UARTCommand.CalculateChecksum(); serialPort.WriteLine(checksum); List UARTLines = new(); diff --git a/UART-CL By TheCod3r/UART-CL By TheCod3r/UART-CL By TheCod3r.csproj b/UART-CL By TheCod3r/UART-CL By TheCod3r/UART-CL By TheCod3r.csproj index 8f54f13..404bb8e 100644 --- a/UART-CL By TheCod3r/UART-CL By TheCod3r/UART-CL By TheCod3r.csproj +++ b/UART-CL By TheCod3r/UART-CL By TheCod3r/UART-CL By TheCod3r.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + net8.0 UART_CL_By_TheCod3r enable enable @@ -29,4 +29,8 @@ + + + + diff --git a/UART.Core.Tests/UART.Core.Tests.csproj b/UART.Core.Tests/UART.Core.Tests.csproj new file mode 100644 index 0000000..4d6b14d --- /dev/null +++ b/UART.Core.Tests/UART.Core.Tests.csproj @@ -0,0 +1,27 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + + + + + + + + + + + diff --git a/UART.Core/Abstractions/INotificationHandler.cs b/UART.Core/Abstractions/INotificationHandler.cs new file mode 100644 index 0000000..78bb5bd --- /dev/null +++ b/UART.Core/Abstractions/INotificationHandler.cs @@ -0,0 +1,11 @@ +using UART.Core.Models; +namespace UART.Core.Abstractions; + +public interface INotificationHandler +{ + void HandleMessage(Notification notificationDetails); + + void HandleQuestion(Question question); + + Task HandleQuestion(AsyncQuestion asyncQuestion); +} \ No newline at end of file diff --git a/UART.Core/Abstractions/IUartProvider.cs b/UART.Core/Abstractions/IUartProvider.cs new file mode 100644 index 0000000..ad104b5 --- /dev/null +++ b/UART.Core/Abstractions/IUartProvider.cs @@ -0,0 +1,9 @@ +namespace UART.Core.Abstractions; + +public interface IUartProvider +{ + Task UpdateErrorDatabase(); + string ParseErrorsOffline(string errorCode); + + Task ParseErrorsOnline(string errorCode); +} \ No newline at end of file diff --git a/UART.Core/Configuration/Constants.cs b/UART.Core/Configuration/Constants.cs new file mode 100644 index 0000000..cd71f4c --- /dev/null +++ b/UART.Core/Configuration/Constants.cs @@ -0,0 +1,9 @@ +namespace UART.Core.Configuration; + +public static class Constants +{ + public const string UartDbFilePathKey = "UartDbFilePath"; + public const string UartSourceUrlKey = "UartSourceUrl"; + public const string TipUrl = "https://www.streamelements.com/thecod3r/tip"; + public const string ShopUrl = "https://www.consolefix.shop"; +} \ No newline at end of file diff --git a/UART.Core/Data/XmlUartProvider.cs b/UART.Core/Data/XmlUartProvider.cs new file mode 100644 index 0000000..4082514 --- /dev/null +++ b/UART.Core/Data/XmlUartProvider.cs @@ -0,0 +1,177 @@ +using System.Xml; +using Microsoft.Extensions.Configuration; +using UART.Core.Abstractions; +using UART.Core.Configuration; +using UART.Core.Models; + +namespace UART.Core.Data; + +public class XmlUartProvider : IUartProvider +{ + private readonly string? _localDatabaseFile; + private readonly string? _uartSourceUrl; + private readonly INotificationHandler _notificationHandler; + + public XmlUartProvider(IConfiguration configuration, INotificationHandler notificationHandler) + { + _localDatabaseFile = configuration[Constants.UartDbFilePathKey]; + _uartSourceUrl = configuration[Constants.UartSourceUrlKey]; + _notificationHandler = notificationHandler; + } + + public async Task UpdateErrorDatabase() + { + // Define the file path to save the XML + + try + { + // Create a WebClient instance + using (HttpClient client = new()) + { + // Download the XML data from the URL + string xmlData = await client.GetStringAsync(_uartSourceUrl); + + // Create an XmlDocument instance and load the XML data + XmlDocument xmlDoc = new XmlDocument(); + xmlDoc.LoadXml(xmlData); + + // Save the XML data to a file + xmlDoc.Save(_localDatabaseFile); + + _notificationHandler.HandleMessage(new Notification + { + Message = "The most recent offline database has been updated successfully.", + Title = "Offline Database Updated!", + Type = NotificationType.Information, + }); + } + } + catch (Exception ex) + { + Console.WriteLine("Error: " + ex.Message); + } + } + + public string ParseErrorsOffline(string errorCode) + { + string results = ""; + + try + { + // Check if the XML file exists + if (File.Exists(_localDatabaseFile)) + { + // Load the XML file + XmlDocument xmlDoc = new XmlDocument(); + xmlDoc.Load(_localDatabaseFile); + + // Get the root node + XmlNode? root = xmlDoc.DocumentElement; + if (root is null) return results; + + // Check if the root node is + if (root.Name == "errorCodes") + { + // Loop through each errorCode node + foreach (XmlNode errorCodeNode in root.ChildNodes) + { + // Check if the node is + if (errorCodeNode.Name == "errorCode") + { + // Get ErrorCode and Description + string errorCodeValue = errorCodeNode.SelectSingleNode("ErrorCode")?.InnerText??""; + string description = errorCodeNode.SelectSingleNode("Description")?.InnerText??""; + + // Check if the current error code matches the requested error code + if (errorCodeValue == errorCode) + { + // Output the results + results = "Error code: " + errorCodeValue + Environment.NewLine + "Description: " + description; + break; // Exit the loop after finding the matching error code + } + } + } + } + else + { + results = "Error: Invalid XML database file. Please reconfigure the application, redownload the offline database, or uncheck the option to use the offline database."; + } + } + else + { + results = "Error: Local XML file not found."; + } + } + catch (Exception ex) + { + results = "Error: " + ex.Message; + } + + return results; + } + + public async Task ParseErrorsOnline(string errorCode) + { + string results = ""; + + try + { + string response = ""; + // Create a WebClient instance to send the request + using (HttpClient client = new()) + { + // Send the request and retrieve the response as a string + response = await client.GetStringAsync($"{_uartSourceUrl}?errorCode={errorCode}"); + } + // Load the XML response into an XmlDocument + XmlDocument xmlDoc = new XmlDocument(); + xmlDoc.LoadXml(response); + + + // Get the root node + XmlNode? root = xmlDoc.DocumentElement; + if (root is null) { + throw new Exception("Error reading the file"); + } + + // Check if the root node is + if (root.Name == "errorCodes") + { + // Loop through each errorCode node + foreach (XmlNode errorCodeNode in root.ChildNodes) + { + // Check if the node is + if (errorCodeNode.Name == "errorCode") + { + // Get ErrorCode and Description + string parsedErrorCode = errorCodeNode.SelectSingleNode("ErrorCode")?.InnerText ?? ""; + string description = errorCodeNode.SelectSingleNode("Description")?.InnerText??""; + + // Output the results + results = "Error code: " + + parsedErrorCode + + Environment.NewLine + + "Description: " + + description; + } + } + } + else + { + results = "Error code: " + + errorCode + + Environment.NewLine + + "An error occurred while fetching a result for this error. Please try again!"; + } + } + catch (Exception ex) + { + results = "Error code: " + + errorCode + + Environment.NewLine + + ex.Message; + } + + return results; + } +} \ No newline at end of file diff --git a/UART.Core/Extensions/ByteExtensions.cs b/UART.Core/Extensions/ByteExtensions.cs new file mode 100644 index 0000000..ada319b --- /dev/null +++ b/UART.Core/Extensions/ByteExtensions.cs @@ -0,0 +1,18 @@ +namespace UART.Core.Extensions; + +public static class ByteExtensions +{ + /// + /// With thanks to @jjxtra on Github. The code has already been created and there's no need to reinvent the wheel is there? + /// + public static IEnumerable PatternAt(this byte[] source, byte[] pattern) + { + for (int i = 0; i < source.Length; i++) + { + if (source.Skip(i).Take(pattern.Length).SequenceEqual(pattern)) + { + yield return i; + } + } + } +} \ No newline at end of file diff --git a/UART.Core/Extensions/StringExtensions.cs b/UART.Core/Extensions/StringExtensions.cs new file mode 100644 index 0000000..dfcd317 --- /dev/null +++ b/UART.Core/Extensions/StringExtensions.cs @@ -0,0 +1,117 @@ +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Runtime.InteropServices; +using System.Text; +using System.Text.RegularExpressions; + +namespace UART.Core.Extensions; + +public static class StringExtensions +{ + public static string HexStringToString(this string hexString) + { + if (hexString == null || (hexString.Length & 1) == 1) + { + throw new ArgumentException(); + } + var sb = new StringBuilder(); + for (var i = 0; i < hexString.Length; i += 2) + { + var hexChar = hexString.Substring(i, 2); + sb.Append((char)Convert.ToByte(hexChar, 16)); + } + return sb.ToString(); + } + + /// + /// Lauinches a URL in a new window using the default browser... + /// + /// The URL you want to launch + public static void OpenUrl(this string url) + { + try + { + Process.Start(url); + } + catch + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + url = url.Replace("&", "^&"); + Process.Start(new ProcessStartInfo(url) { UseShellExecute = true }); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + Process.Start("xdg-open", url); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + Process.Start("open", url); + } + else + { + throw; + } + } + } + + public static byte[] ConvertHexStringToByteArray(this string hexString, [StringSyntax(StringSyntaxAttribute.Regex)]string pattern, string replacement = "") + => Regex.Replace(hexString, pattern, replacement) + .Normalize() + .Trim() + .ConvertHexStringToByteArray(); + + public static byte[] ConvertHexStringToByteArray(this string hexString) + { + if (hexString.Length % 2 != 0) + { + throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The binary key cannot have an odd number of digits: {0}", hexString)); + } + + byte[] data = new byte[hexString.Length / 2]; + for (int index = 0; index < data.Length; index++) + { + string byteValue = hexString.Substring(index * 2, 2); + data[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture); + } + + return data; + } + + public static string CalculateChecksum(this string str) + { + int sum = 0; + foreach (char c in str) + { + sum += c; + } + return str + ":" + (sum & 0xFF).ToString("X2"); + } + + //TODO: move into class that implements IDisposable and allow methods to extract specific values + public static string? ExtractValueFromFile(this string fileName, long offset, int count, Func? postProcess = null, string? defaultValue = null) + { + try + { + using (FileStream fs = new FileStream(fileName, FileMode.Open)) + using (BinaryReader reader = new BinaryReader(fs)) + { + //Set the position of the reader + reader.BaseStream.Position = offset; + + // read the offset + var result = BitConverter.ToString(reader.ReadBytes(count)); + + if (postProcess != null) + return postProcess(result); + + return result; + } + } + catch + { + return defaultValue; + } + } +} \ No newline at end of file diff --git a/UART.Core/Models/BasicMessage.cs b/UART.Core/Models/BasicMessage.cs new file mode 100644 index 0000000..221ef83 --- /dev/null +++ b/UART.Core/Models/BasicMessage.cs @@ -0,0 +1,7 @@ +namespace UART.Core.Models; + +public class BasicMessage +{ + public string? Title { get; set; } + public string? Message { get; set; } +} \ No newline at end of file diff --git a/UART.Core/Models/Notification.cs b/UART.Core/Models/Notification.cs new file mode 100644 index 0000000..a977d90 --- /dev/null +++ b/UART.Core/Models/Notification.cs @@ -0,0 +1,6 @@ +namespace UART.Core.Models; + +public class Notification : BasicMessage +{ + public NotificationType Type { get; set; } +} \ No newline at end of file diff --git a/UART.Core/Models/NotificationType.cs b/UART.Core/Models/NotificationType.cs new file mode 100644 index 0000000..c7a4b49 --- /dev/null +++ b/UART.Core/Models/NotificationType.cs @@ -0,0 +1,8 @@ +namespace UART.Core.Models; + +public enum NotificationType +{ + Information, + Warning, + Error +} \ No newline at end of file diff --git a/UART.Core/Models/Question.cs b/UART.Core/Models/Question.cs new file mode 100644 index 0000000..83f2ce8 --- /dev/null +++ b/UART.Core/Models/Question.cs @@ -0,0 +1,18 @@ +namespace UART.Core.Models; + +public class Question : BasicMessage +{ + public T? OnYes { get; set; } + + public T? OnNo { get; set; } +} + +public class Question : Question +{ + +} + +public class AsyncQuestion : Question> +{ + +} \ No newline at end of file diff --git a/UART.Core/UART.Core.csproj b/UART.Core/UART.Core.csproj new file mode 100644 index 0000000..f07976b --- /dev/null +++ b/UART.Core/UART.Core.csproj @@ -0,0 +1,13 @@ + + + + net8.0 + enable + enable + + + + + + +