diff --git a/ModLinks.cs b/ModLinks.cs index 2694dfd..9e03114 100644 --- a/ModLinks.cs +++ b/ModLinks.cs @@ -1,10 +1,7 @@ using System; -using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Xml; -using System.Xml.Schema; using System.Xml.Serialization; namespace ModlinksShaVerifier; @@ -41,26 +38,23 @@ public Links Links set => _links = value; } - [XmlArray("Dependencies")] - [XmlArrayItem("Dependency")] - public string[]? Dependencies { get; set; } - - public string Description { get; set; } = null!; - public override string ToString() { return "{\n" + $"\t{nameof(Name)}: {Name},\n" + $"\t{nameof(Links)}: {(object?) _link ?? Links},\n" - + $"\t{nameof(Dependencies)}: {string.Join(", ", Dependencies ?? Array.Empty())},\n" - + $"\t{nameof(Description)}: {Description}\n" + "}"; } + + public override int GetHashCode() + { + return HashCode.Combine(Name, Links); + } } -public class Links +public record Links { - public Link? Windows; + public Link Windows = null!; public Link? Mac; public Link? Linux; @@ -72,7 +66,7 @@ public override string ToString() + $"\t{nameof(Linux)} = {Linux}\n" + "}"; } - + public IEnumerable AsEnumerable() { if (Windows is not null) @@ -84,7 +78,7 @@ public IEnumerable AsEnumerable() } } -public class Link +public record Link { [XmlAttribute] public string SHA256 = null!; diff --git a/Program.cs b/Program.cs index 4f69da0..94cd95b 100755 --- a/Program.cs +++ b/Program.cs @@ -53,49 +53,93 @@ private static async Task CheckSingleSha(Manifest m) return res.All(x => x); } + private static void TrimManifest(ref Manifest m) + { + foreach (var link in m.Links.AsEnumerable()) + { + link.URL = link.URL.Trim(); + } + } + internal static async Task Main(string[] args) { var sw = new Stopwatch(); sw.Start(); - if (args.Length != 1) + if (args.Length != 2) { - await Console.Error.WriteLineAsync("Usage: ModlinksShaVerifier [FILE]"); + await Console.Error.WriteLineAsync("Usage: ModlinksShaVerifier [CURRENT_FILE] [INCOMING_FILE]"); return 1; } - var path = args[0]; + string currentPath = args[0]; - if (!File.Exists(path)) + if (!File.Exists(currentPath)) { - await Console.Error.WriteLineAsync($"Unable to access {path}! Does it exist?"); + await Console.Error.WriteLineAsync($"Unable to access current XML file {currentPath}! Does it exist?"); return 1; } - var reader = XmlReader.Create(path, new XmlReaderSettings {Async = true}); + var incomingPath = args[1]; + if (!File.Exists(incomingPath)) + { + await Console.Error.WriteLineAsync( + $"Unable to access incoming XML file {incomingPath}! Does it exist?"); + return 1; + } + + var currentReader = XmlReader.Create(currentPath, new XmlReaderSettings { Async = true }); + var incomingReader = XmlReader.Create(incomingPath, new XmlReaderSettings { Async = true }); + var serializer = new XmlSerializer(typeof(Manifest)); - List> checks = new(); - - while (await reader.ReadAsync()) + Dictionary checkedLinksDict = new(); + + while (await currentReader.ReadAsync()) { - if (reader.NodeType != XmlNodeType.Element) + if (currentReader.NodeType != XmlNodeType.Element) + continue; + + if (currentReader.Name != "Manifest") continue; - if (reader.Name != "Manifest") + var currentManifest = (Manifest?)serializer.Deserialize(currentReader) ?? throw new InvalidDataException(); + TrimManifest(ref currentManifest); + checkedLinksDict.Add(currentManifest.Name, currentManifest.Links); + } + + List> checks = new(); + + while (await incomingReader.ReadAsync()) + { + if (incomingReader.NodeType != XmlNodeType.Element) continue; - var manifest = (Manifest?) serializer.Deserialize(reader) ?? throw new InvalidDataException(); + if (incomingReader.Name != "Manifest") + continue; - checks.Add(CheckSingleSha(manifest)); + var incomingManifest = (Manifest?)serializer.Deserialize(incomingReader) ?? throw new InvalidDataException(); + TrimManifest(ref incomingManifest); + + if (checkedLinksDict.TryGetValue(incomingManifest.Name, out var checkedLinks)) + { + if (checkedLinks != incomingManifest.Links) + { + checks.Add(CheckSingleSha(incomingManifest)); + } + } + else + { + checks.Add(CheckSingleSha(incomingManifest)); + } } var res = await Task.WhenAll(checks); sw.Stop(); - Console.WriteLine($"Completed in {sw.ElapsedMilliseconds}ms."); + Console.WriteLine($"Checked {checks.Count} mods in {sw.ElapsedMilliseconds}ms."); // If they're not all correct, error. return !res.All(x => x) ? 1 : 0; @@ -104,4 +148,4 @@ internal static async Task Main(string[] args) private static void WriteError(string title, string message) => Console.WriteLine($"::error title={title}::{message}"); } -} +} \ No newline at end of file