From ee3b63b5ad707e89564d04b5f903cc93201c8f5b Mon Sep 17 00:00:00 2001 From: AnakinRaW Date: Tue, 3 Dec 2024 14:06:53 +0100 Subject: [PATCH 1/2] update to spec 3.0.2 --- src/EawModinfo.Tests/ModinfoValidatorTests.cs | 51 +++++++++++++++---- src/EawModinfo/Spec/IModReference.cs | 9 +++- src/EawModinfo/Spec/ModType.cs | 2 - src/EawModinfo/Utilities/ModinfoValidator.cs | 11 ++-- 4 files changed, 55 insertions(+), 18 deletions(-) diff --git a/src/EawModinfo.Tests/ModinfoValidatorTests.cs b/src/EawModinfo.Tests/ModinfoValidatorTests.cs index 58d720c..5bc4602 100644 --- a/src/EawModinfo.Tests/ModinfoValidatorTests.cs +++ b/src/EawModinfo.Tests/ModinfoValidatorTests.cs @@ -164,21 +164,22 @@ public static IEnumerable GetSteamData() }, false ]; + yield return + [ + new JsonSteamData + { + Id = long.MaxValue.ToString(), Tags = ["EAW"], ContentFolder = "testFolder", + Description = "Some description", Title = "MyTitle" + }, + false + ]; } - + public static IEnumerable GetInvalidSteamData() { yield return [new JsonSteamData(), true]; yield return [new JsonSteamData { Id = null! }, true]; - yield return [new JsonSteamData {Id = "asd", Tags = ["EAW"], ContentFolder = "testFolder"}, true]; yield return [new JsonSteamData {Id = "1234", Tags = ["EAW"], ContentFolder = "testFolder"}, true]; - yield return [new JsonSteamData {Id = "0", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title"}, true]; - yield return [new JsonSteamData {Id = "-123", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true]; - yield return - [ - new JsonSteamData {Id = "129381209812430981329048", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title"}, - true - ]; yield return [new JsonSteamData {Id = "1234", Tags = Array.Empty(), ContentFolder = "testFolder", Title = "Title" }, true]; yield return [new JsonSteamData { Id = "1234", Tags = null!, ContentFolder = "testFolder", Title = "Title" }, true]; yield return [new JsonSteamData { Id = "1234", Tags = null!, ContentFolder = "testFolder", Title = "Title" }, true]; @@ -192,9 +193,41 @@ public static IEnumerable GetInvalidSteamData() yield return [new JsonSteamData { Id = "1234312", Tags = ["FOC", new string('a', 256)], Metadata = "bla", ContentFolder = "testFolder", Title = "Title" }, true]; } + public static IEnumerable GetInvalidSteamIDs() + { + var random = new Random(); + yield return [new JsonSteamData { Id = "NaN", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true]; + yield return [new JsonSteamData { Id = "1abc", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true]; + yield return [new JsonSteamData { Id = "abc1", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true]; + yield return [new JsonSteamData { Id = "abc", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true]; + yield return [new JsonSteamData { Id = "1d", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true]; + yield return [new JsonSteamData { Id = "1f", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true]; + yield return [new JsonSteamData { Id = "0x1", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true]; + yield return [new JsonSteamData { Id = "0", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true]; + yield return [new JsonSteamData { Id = "1AF", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true]; + yield return [new JsonSteamData { Id = "1+", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true]; + yield return [new JsonSteamData { Id = "1e2", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true]; + yield return [new JsonSteamData { Id = "1E2", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true]; + yield return [new JsonSteamData { Id = random.Next(int.MinValue, -1).ToString(), Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true]; + yield return [new JsonSteamData { Id = "+123", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true]; + yield return [new JsonSteamData { Id = "-+123", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true]; + yield return [new JsonSteamData { Id = "1_23", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true]; + yield return [new JsonSteamData { Id = "1-23", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true]; + yield return [new JsonSteamData { Id = "1.23", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true]; + yield return [new JsonSteamData { Id = "1,23", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true]; + yield return [new JsonSteamData { Id = "0123", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true]; + yield return [new JsonSteamData { Id = "00123", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true]; + yield return [new JsonSteamData { Id = " 00123", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true]; + yield return [new JsonSteamData { Id = " 123", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true]; + yield return [new JsonSteamData { Id = "123 ", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true]; + yield return [new JsonSteamData { Id = "1 23", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true]; + yield return [new JsonSteamData { Id = "1" + ulong.MaxValue, Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true]; + } + [Theory] [MemberData(nameof(GetSteamData))] [MemberData(nameof(GetInvalidSteamData))] + [MemberData(nameof(GetInvalidSteamIDs))] public void Validate_SteamData(ISteamData steamData, bool shallThrow) { if (!shallThrow) diff --git a/src/EawModinfo/Spec/IModReference.cs b/src/EawModinfo/Spec/IModReference.cs index 0c6e047..839d2f4 100644 --- a/src/EawModinfo/Spec/IModReference.cs +++ b/src/EawModinfo/Spec/IModReference.cs @@ -9,8 +9,14 @@ namespace EawModinfo.Spec; public interface IModReference : IEquatable, IConvertibleToJson { /// - /// Gets the unique identifier as a textual representation. The property my indicate how the data can be interpreted. + /// Gets the unique, predictable identifier of the mod. /// + /// + /// The identifier can hold any data to uniquely identify a mod, however the concrete value shall be predictable, + /// so that it can be used to code it into modinfo JSON files to reference mod dependencies. + /// For Steam Workshop mods it is therefore recommended to use the Steam Workshops ID and for local + /// The property may indicate how the data can be interpreted. + /// string Identifier { get; } /// @@ -25,5 +31,4 @@ public interface IModReference : IEquatable, IConvertibleToJson /// As stated in the specification this property is not used for equality matching. /// SemVersionRange? VersionRange { get; } - } \ No newline at end of file diff --git a/src/EawModinfo/Spec/ModType.cs b/src/EawModinfo/Spec/ModType.cs index b8e2634..96ad12a 100644 --- a/src/EawModinfo/Spec/ModType.cs +++ b/src/EawModinfo/Spec/ModType.cs @@ -7,12 +7,10 @@ public enum ModType { /// /// The mod îs stored on the file system at a well known file system location (e.g. the game's 'Mods' directory). - /// The associated should be able to parse into a relative or absolute file system path. /// Default = 0, /// /// The mod is a Steam Workshops Item. - /// The associated must be able to parse into an which represents a Steam Workshops identifier. /// Workshops = 1, /// diff --git a/src/EawModinfo/Utilities/ModinfoValidator.cs b/src/EawModinfo/Utilities/ModinfoValidator.cs index bb819f7..48383d9 100644 --- a/src/EawModinfo/Utilities/ModinfoValidator.cs +++ b/src/EawModinfo/Utilities/ModinfoValidator.cs @@ -3,7 +3,6 @@ using System.Globalization; using System.Linq; using System.Runtime.CompilerServices; -using EawModinfo.Model.Json; using EawModinfo.Spec; using EawModinfo.Spec.Steam; @@ -16,7 +15,7 @@ public static class ModinfoValidator { /// /// Validates an data. Throws an when validation failed. - /// Also throws is subsequent data such as are invalid, if present. + /// Also throws if subsequent data such as are invalid, if present. /// /// The data to validate. /// The validation failed. @@ -47,7 +46,7 @@ public static void Validate(this ISteamData steamData) { if (string.IsNullOrEmpty(steamData.Id)) throw new ModinfoException("Steam data is invalid: Identifier is missing."); - ValidateSteamId(steamData.Id, "Steam data is invalid: "); + ValidateSteamId(steamData.Id, $"Steam data is invalid: '{steamData.Id}'"); if (string.IsNullOrEmpty(steamData.ContentFolder)) throw new ModinfoException("Steam data is invalid: ContentFolder is missing."); @@ -81,7 +80,6 @@ private static bool ContainsInvalidCharacter(ReadOnlySpan value) if (c == ',' || (uint)(c - '\x0020') > '\x007F' - '\x0020') // (c >= '\x0020' && c <= '\x007F' return true; } - return false; } @@ -152,7 +150,10 @@ private static void ValidateSteamId(string data, string errorSourceMessage) private static (bool Valid, string Error) ValidateSteamId(string data) { - if (!uint.TryParse(data, out var id)) + // Leading spaces, etc. is not a problem, because this case is handled with NumberStyles.None + if (data[0] == '0') + return (false, "Workshops ID cannot have leading zeros."); + if (!ulong.TryParse(data, NumberStyles.None, CultureInfo.InvariantCulture, out var id)) return (false, "Workshops ID must be an uint number."); if (id == 0) return (false, "Workshops ID cannot be 0."); From 9388d9899838d809a42e1499f5520da8f27ec8ab Mon Sep 17 00:00:00 2001 From: AnakinRaW Date: Tue, 3 Dec 2024 14:13:58 +0100 Subject: [PATCH 2/2] update deps --- src/EawModinfo/EawModinfo.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EawModinfo/EawModinfo.csproj b/src/EawModinfo/EawModinfo.csproj index 5020b83..40b3d96 100644 --- a/src/EawModinfo/EawModinfo.csproj +++ b/src/EawModinfo/EawModinfo.csproj @@ -39,7 +39,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive