using System; using System.Net; using System.Reflection; using Newtonsoft.Json.Linq; namespace MPF.Utilities { public static class Tools { #region Byte Arrays /// /// Search for a byte array in another array /// public static bool Contains(this byte[] stack, byte[] needle, out int position, int start = 0, int end = -1) { // Initialize the found position to -1 position = -1; // If either array is null or empty, we can't do anything if (stack == null || stack.Length == 0 || needle == null || needle.Length == 0) return false; // If the needle array is larger than the stack array, it can't be contained within if (needle.Length > stack.Length) return false; // If start or end are not set properly, set them to defaults if (start < 0) start = 0; if (end < 0) end = stack.Length - needle.Length; for (int i = start; i < end; i++) { if (stack.EqualAt(needle, i)) { position = i; return true; } } return false; } /// /// See if a byte array starts with another /// public static bool StartsWith(this byte[] stack, byte[] needle) { return stack.Contains(needle, out int _, start: 0, end: 1); } /// /// Get if a stack at a certain index is equal to a needle /// private static bool EqualAt(this byte[] stack, byte[] needle, int index) { // If we're too close to the end of the stack, return false if (needle.Length >= stack.Length - index) return false; for (int i = 0; i < needle.Length; i++) { if (stack[i + index] != needle[i]) return false; } return true; } #endregion #region Versioning /// /// Check for a new MPF version /// /// /// Bool representing if the values are different. /// String representing the message to display the the user. /// String representing the new release URL. /// public static (bool different, string message, string url) CheckForNewVersion() { try { // Get current assembly version var assemblyVersion = Assembly.GetEntryAssembly().GetName().Version; string version = $"{assemblyVersion.Major}.{assemblyVersion.Minor}" + (assemblyVersion.Build != 0 ? $".{assemblyVersion.Build}" : string.Empty); // Get the latest tag from GitHub (string tag, string url) = GetRemoteVersionAndUrl(); bool different = version != tag; string message = $"Local version: {version}" + $"{Environment.NewLine}Remote version: {tag}" + (different ? $"{Environment.NewLine}The update URL has been added copied to your clipboard" : $"{Environment.NewLine}You have the newest version!"); return (different, message, url); } catch (Exception ex) { return (false, ex.ToString(), null); } } /// /// Get the current informational version formatted as a string /// public static string GetCurrentVersion() { var assemblyVersion = Attribute.GetCustomAttribute(Assembly.GetEntryAssembly(), typeof(AssemblyInformationalVersionAttribute)) as AssemblyInformationalVersionAttribute; return assemblyVersion.InformationalVersion; } /// /// Get the latest version of MPF from GitHub and the release URL /// private static (string tag, string url) GetRemoteVersionAndUrl() { using (WebClient wc = new WebClient()) { wc.Headers["User-Agent"] = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:64.0) Gecko/20100101 Firefox/64.0"; // TODO: Figure out a better way than having this hardcoded... string url = "https://api.github.com/repos/SabreTools/MPF/releases/latest"; string latestReleaseJsonString = wc.DownloadString(url); var latestReleaseJson = JObject.Parse(latestReleaseJsonString); string latestTag = latestReleaseJson["tag_name"].ToString(); string releaseUrl = latestReleaseJson["html_url"].ToString(); return (latestTag, releaseUrl); } } #endregion } }