diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/SMAPI.Toolkit/SemanticVersionComparer.cs | 32 | ||||
-rw-r--r-- | src/SMAPI.Web/Framework/ModSiteManager.cs | 73 |
2 files changed, 83 insertions, 22 deletions
diff --git a/src/SMAPI.Toolkit/SemanticVersionComparer.cs b/src/SMAPI.Toolkit/SemanticVersionComparer.cs new file mode 100644 index 00000000..9f6b57a2 --- /dev/null +++ b/src/SMAPI.Toolkit/SemanticVersionComparer.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; + +namespace StardewModdingAPI.Toolkit +{ + /// <summary>A comparer for semantic versions based on the <see cref="SemanticVersion.CompareTo(ISemanticVersion)"/> field.</summary> + public class SemanticVersionComparer : IComparer<ISemanticVersion> + { + /********* + ** Accessors + *********/ + /// <summary>A singleton instance of the comparer.</summary> + public static SemanticVersionComparer Instance { get; } = new SemanticVersionComparer(); + + + /********* + ** Public methods + *********/ + /// <inheritdoc /> + public int Compare(ISemanticVersion x, ISemanticVersion y) + { + if (object.ReferenceEquals(x, y)) + return 0; + + if (x is null) + return -1; + if (y is null) + return 1; + + return x.CompareTo(y); + } + } +} diff --git a/src/SMAPI.Web/Framework/ModSiteManager.cs b/src/SMAPI.Web/Framework/ModSiteManager.cs index 68b4c6ac..8f21d2f5 100644 --- a/src/SMAPI.Web/Framework/ModSiteManager.cs +++ b/src/SMAPI.Web/Framework/ModSiteManager.cs @@ -110,41 +110,70 @@ namespace StardewModdingAPI.Web.Framework main = null; preview = null; - ISemanticVersion ParseVersion(string raw) + // parse all versions from the mod page + IEnumerable<(string name, string description, ISemanticVersion version)> GetAllVersions() { - raw = this.NormalizeVersion(raw); - return this.GetMappedVersion(raw, mapRemoteVersions, allowNonStandardVersions); + if (mod != null) + { + ISemanticVersion ParseAndMapVersion(string raw) + { + raw = this.NormalizeVersion(raw); + return this.GetMappedVersion(raw, mapRemoteVersions, allowNonStandardVersions); + } + + // get mod version + ISemanticVersion modVersion = ParseAndMapVersion(mod.Version); + if (modVersion != null) + yield return (name: null, description: null, version: ParseAndMapVersion(mod.Version)); + + // get file versions + foreach (IModDownload download in mod.Downloads) + { + ISemanticVersion cur = ParseAndMapVersion(download.Version); + if (cur != null) + yield return (download.Name, download.Description, cur); + } + } } + var versions = GetAllVersions() + .OrderByDescending(p => p.version, SemanticVersionComparer.Instance) + .ToArray(); - if (mod != null) + // get main + preview versions + void TryGetVersions(out ISemanticVersion mainVersion, out ISemanticVersion previewVersion, Func<(string name, string description, ISemanticVersion version), bool> filter = null) { - // get mod version - if (subkey == null) - main = ParseVersion(mod.Version); + mainVersion = null; + previewVersion = null; - // get file versions - foreach (IModDownload download in mod.Downloads) + // get latest main + preview version + foreach (var entry in versions) { - // check for subkey if specified - if (subkey != null && download.Name?.Contains(subkey, StringComparison.OrdinalIgnoreCase) != true && download.Description?.Contains(subkey, StringComparison.OrdinalIgnoreCase) != true) + if (filter?.Invoke(entry) == false) continue; - // parse version - ISemanticVersion cur = ParseVersion(download.Version); - if (cur == null) - continue; + if (entry.version.IsPrerelease()) + previewVersion ??= entry.version; + else + mainVersion ??= entry.version; - // track highest versions - if (main == null || cur.IsNewerThan(main)) - main = cur; - if (cur.IsPrerelease() && (preview == null || cur.IsNewerThan(preview))) - preview = cur; + if (mainVersion != null) + break; // any other values will be older } - if (preview != null && !preview.IsNewerThan(main)) - preview = null; + // normalize values + if (previewVersion is not null) + { + mainVersion ??= previewVersion; // if every version is prerelease, latest one is the main version + if (!previewVersion.IsNewerThan(mainVersion)) + previewVersion = null; + } } + if (subkey is not null) + TryGetVersions(out main, out preview, entry => entry.name?.Contains(subkey, StringComparison.OrdinalIgnoreCase) == true || entry.description?.Contains(subkey, StringComparison.OrdinalIgnoreCase) == true); + if (main is null) + TryGetVersions(out main, out preview); + return main != null; } |