Files
MPF/MPF.Library/Utilities/Tools.cs
2021-09-28 11:46:37 -07:00

142 lines
4.9 KiB
C#

using System;
using System.Net;
using System.Reflection;
using Newtonsoft.Json.Linq;
namespace MPF.Utilities
{
public static class Tools
{
#region Byte Arrays
/// <summary>
/// Search for a byte array in another array
/// </summary>
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;
}
/// <summary>
/// See if a byte array starts with another
/// </summary>
public static bool StartsWith(this byte[] stack, byte[] needle)
{
return stack.Contains(needle, out int _, start: 0, end: 1);
}
/// <summary>
/// Get if a stack at a certain index is equal to a needle
/// </summary>
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
/// <summary>
/// Check for a new MPF version
/// </summary>
/// <returns>
/// Bool representing if the values are different.
/// String representing the message to display the the user.
/// String representing the new release URL.
/// </returns>
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);
}
}
/// <summary>
/// Get the current informational version formatted as a string
/// </summary>
public static string GetCurrentVersion()
{
var assemblyVersion = Attribute.GetCustomAttribute(Assembly.GetEntryAssembly(), typeof(AssemblyInformationalVersionAttribute)) as AssemblyInformationalVersionAttribute;
return assemblyVersion.InformationalVersion;
}
/// <summary>
/// Get the latest version of MPF from GitHub and the release URL
/// </summary>
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
}
}