diff --git a/src/Core_Sideloader/Core.Sideloader.ManifestVersionComparer.cs b/src/Core_Sideloader/Core.Sideloader.ManifestVersionComparer.cs index 6ef0017c..897b362e 100644 --- a/src/Core_Sideloader/Core.Sideloader.ManifestVersionComparer.cs +++ b/src/Core_Sideloader/Core.Sideloader.ManifestVersionComparer.cs @@ -13,8 +13,10 @@ public int Compare(string x, string y) public static int CompareVersions(string firstVer, string secondVer) { - firstVer = firstVer?.Trim().TrimStart('v', 'V', 'r') ?? ""; - secondVer = secondVer?.Trim().TrimStart('v', 'V', 'r') ?? ""; + firstVer = firstVer?.Trim().TrimStart('v', 'V', 'r', 'R', ' '); + if (string.IsNullOrEmpty(firstVer)) firstVer = "0"; + secondVer = secondVer?.Trim().TrimStart('v', 'V', 'r', 'R', ' '); + if (string.IsNullOrEmpty(secondVer)) secondVer = "0"; if (firstVer == secondVer) return 0; @@ -22,8 +24,8 @@ public static int CompareVersions(string firstVer, string secondVer) var limit = Math.Max(version.First.Count, version.Second.Count); for (var i = 0; i < limit; i++) { - var first = version.First.ElementAtOrDefault(i) ?? string.Empty; - var second = version.Second.ElementAtOrDefault(i) ?? string.Empty; + var first = version.First.ElementAtOrDefault(i) ?? 0; + var second = version.Second.ElementAtOrDefault(i) ?? 0; try { var result = first.CompareTo(second); @@ -32,16 +34,22 @@ public static int CompareVersions(string firstVer, string secondVer) } catch (ArgumentException) { - if (first is string s1 && second is string s2) - { - // Handle invalid characters in strings by comparing them byte by byte - var result = string.CompareOrdinal(s1, s2); - if (result != 0) - return result; - } + var s1 = first.ToString(); + var s2 = second.ToString(); + + if (s1 == "0" && s2 != "0") + return -1; + + if (s2 == "0" && s1 != "0") + return 1; + + // Handle invalid characters in strings by comparing them byte by byte + var result = string.CompareOrdinal(s1, s2); + if (result != 0) + return result; } } - return version.First.Count.CompareTo(version.Second.Count); + return 0; } private static ICollection Tokenize(string version) @@ -49,6 +57,12 @@ private static ICollection Tokenize(string version) var results = new List(2); foreach (var part in version.Trim().Split('.', ' ', '-', ',', '_')) { + if (part.Length == 0) + { + results.Add(0); + continue; + } + // Handle mixed digit + letter parts by splitting them (1.0a -> 1 0 a) var isDigit = char.IsDigit(part[0]); var current = part[0].ToString(); diff --git a/src/Core_Sideloader/Core.Sideloader.cs b/src/Core_Sideloader/Core.Sideloader.cs index ac8c6d7d..ec73feb1 100644 --- a/src/Core_Sideloader/Core.Sideloader.cs +++ b/src/Core_Sideloader/Core.Sideloader.cs @@ -261,13 +261,23 @@ void AddZipmodToLoad(ZipmodInfo zipmodInfo) // Handle multiple versions/copies of a single zipmod if (modGroup.Count > 1) { - // Order by version if available, else use modified dates (less reliable) - // If versions match, prefer mods inside folders or with more descriptive names so modpacks are preferred - var orderedModsQuery = modGroup.All(x => !string.IsNullOrEmpty(x.Manifest.Version)) - ? modGroup.OrderByDescending(x => x.Manifest.Version, new ManifestVersionComparer()).ThenByDescending(x => x.FileName.Length) - : modGroup.OrderByDescending(x => x.LastWriteTime); + List orderedMods; + try + { + // Order by version if available, else use modified dates (less reliable) + // If versions match, prefer mods inside folders or with more descriptive names so modpacks are preferred + var orderedModsQuery = modGroup.All(x => !string.IsNullOrEmpty(x.Manifest.Version)) + ? modGroup.OrderByDescending(x => x.Manifest.Version, new ManifestVersionComparer()).ThenByDescending(x => x.FileName.Length) + : modGroup.OrderByDescending(x => x.LastWriteTime); + + orderedMods = orderedModsQuery.ToList(); + } + catch (Exception e) + { + Logger.LogError($"Failed to sort versions of [{modGroup[0].Manifest.GUID}]: [{string.Join("] , [", modGroup.Select(x => x.Manifest.Version).ToArray())}] with error: {e}"); + orderedMods = modGroup; + } - var orderedMods = orderedModsQuery.ToList(); zipmod = orderedMods[0]; var modList = string.Join(", ", orderedMods.Skip(1).Select(x => '"' + x.RelativeFileName + '"').ToArray());