From c75647923946738805156a27ff58e368a97f9e73 Mon Sep 17 00:00:00 2001 From: DrakiaXYZ <565558+DrakiaXYZ@users.noreply.github.com> Date: Tue, 7 Oct 2025 08:56:48 -0700 Subject: [PATCH] Fix mod SptVersion to be a range (#605) * Fix mod SptVersion to be a range - SptVersion and ModDependencies now use a Range instead of a set version - Remove IsValid and IsValidRange checks from ModValidator, as invalid values will fail to parse into the strong types before this method is called - Remove unused "AnySatisfies" and "IsValid*" methods from ISemVer - Update TestMod to use Range types * Formatting --------- Co-authored-by: DrakiaXYZ <565558+TheDgtl@users.noreply.github.com> --- Libraries/SPTarkov.Common/Semver/ISemVer.cs | 8 +++----- .../SemanticVersioningSemVer.cs | 19 ++----------------- .../Models/Spt/Mod/AbstractModMetadata.cs | 11 ++++++----- SPTarkov.Server/Modding/ModValidator.cs | 7 ------- Testing/TestMod/TestMod.cs | 5 +++-- 5 files changed, 14 insertions(+), 36 deletions(-) diff --git a/Libraries/SPTarkov.Common/Semver/ISemVer.cs b/Libraries/SPTarkov.Common/Semver/ISemVer.cs index 42d207c2..6a3f5d54 100644 --- a/Libraries/SPTarkov.Common/Semver/ISemVer.cs +++ b/Libraries/SPTarkov.Common/Semver/ISemVer.cs @@ -1,4 +1,5 @@ -using Version = SemanticVersioning.Version; +using Range = SemanticVersioning.Range; +using Version = SemanticVersioning.Version; namespace SPTarkov.Common.Semver; @@ -8,8 +9,5 @@ public interface ISemVer string MaxSatisfying(IEnumerable versions); string MaxSatisfying(string version, List versions); string MaxSatisfying(string version, IEnumerable versions); - bool Satisfies(Version version, Version testVersion); - bool AnySatisfies(Version version, List testVersions); - bool IsValid(Version version); - bool IsValidRange(Version version); + bool Satisfies(Version version, Range testRange); } diff --git a/Libraries/SPTarkov.Common/Semver/Implementations/SemanticVersioningSemVer.cs b/Libraries/SPTarkov.Common/Semver/Implementations/SemanticVersioningSemVer.cs index 9709aeae..3413090c 100644 --- a/Libraries/SPTarkov.Common/Semver/Implementations/SemanticVersioningSemVer.cs +++ b/Libraries/SPTarkov.Common/Semver/Implementations/SemanticVersioningSemVer.cs @@ -26,23 +26,8 @@ public class SemanticVersioningSemVer : ISemVer return Range.MaxSatisfying(version, versionRanges, true); } - public bool Satisfies(Version version, Version testVersion) + public bool Satisfies(Version version, Range testRange) { - return Range.IsSatisfied(testVersion.ToString(), version.ToString(), true); - } - - public bool AnySatisfies(Version version, List testVersions) - { - return testVersions.Any(v => Satisfies(version, v)); - } - - public bool IsValid(Version version) - { - return Version.TryParse(version.ToString(), out _); - } - - public bool IsValidRange(Version version) - { - return Range.TryParse(version.ToString(), out _); + return testRange.IsSatisfied(version, true); } } diff --git a/Libraries/SPTarkov.Server.Core/Models/Spt/Mod/AbstractModMetadata.cs b/Libraries/SPTarkov.Server.Core/Models/Spt/Mod/AbstractModMetadata.cs index a8e9bd70..17d0c435 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Spt/Mod/AbstractModMetadata.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Spt/Mod/AbstractModMetadata.cs @@ -1,4 +1,5 @@ -using Version = SemanticVersioning.Version; +using Range = SemanticVersioning.Range; +using Version = SemanticVersioning.Version; namespace SPTarkov.Server.Core.Models.Spt.Mod; @@ -42,13 +43,13 @@ public abstract record AbstractModMetadata public abstract Version Version { get; init; } /// - /// SPT version this mod was built for, this uses the semver standard: https://semver.org/ + /// SPT version this mod was built for, this uses the semver standard constraints: https://semver.org/ ///

- /// Version = new Version("4.0.0"); is valid + /// Version = new Version("~4.0.0"); is valid ///
/// Version = new Version("4.0.0.0"); is not ///
- public abstract Version SptVersion { get; init; } + public abstract Range SptVersion { get; init; } /// /// List of mods not compatible with this mod @@ -60,7 +61,7 @@ public abstract record AbstractModMetadata /// /// Mod dependency is the key, version is the value /// - public abstract Dictionary? ModDependencies { get; init; } + public abstract Dictionary? ModDependencies { get; init; } /// /// Link to this mod's mod page, or GitHub page diff --git a/SPTarkov.Server/Modding/ModValidator.cs b/SPTarkov.Server/Modding/ModValidator.cs index 608cbd91..88e4e0e0 100644 --- a/SPTarkov.Server/Modding/ModValidator.cs +++ b/SPTarkov.Server/Modding/ModValidator.cs @@ -126,13 +126,6 @@ public class ModValidator(ISptLogger logger, ServerLocalisationSer var sptVersion = ProgramStatics.SPT_VERSION(); var modName = $"{mod.Author}-{mod.Name}"; - // Error and prevent loading if sptVersion property is not a valid semver string - if (!(semVer.IsValid(mod.SptVersion) || semVer.IsValidRange(mod.SptVersion))) - { - logger.Error(localisationService.GetText("modloader-invalid_sptversion_field", modName)); - return false; - } - // Warning and allow loading if semver is not satisfied if (!semVer.Satisfies(sptVersion, mod.SptVersion)) { diff --git a/Testing/TestMod/TestMod.cs b/Testing/TestMod/TestMod.cs index 00ecd265..587a4bc3 100644 --- a/Testing/TestMod/TestMod.cs +++ b/Testing/TestMod/TestMod.cs @@ -3,6 +3,7 @@ using SPTarkov.Server.Core.DI; using SPTarkov.Server.Core.Models.Spt.Mod; using SPTarkov.Server.Core.Models.Utils; using SPTarkov.Server.Web; +using Range = SemanticVersioning.Range; using Version = SemanticVersioning.Version; namespace TestMod; @@ -14,9 +15,9 @@ public record TestModMetadata : AbstractModMetadata, IModWebMetadata public override string Author { get; init; } = "SPTarkov"; public override List? Contributors { get; init; } public override Version Version { get; init; } = new("1.0.0"); - public override Version SptVersion { get; init; } = new("~4.0.0"); + public override Range SptVersion { get; init; } = new("~4.0.0"); public override List? Incompatibilities { get; init; } - public override Dictionary? ModDependencies { get; init; } + public override Dictionary? ModDependencies { get; init; } public override string? Url { get; init; } public override bool? IsBundleMod { get; init; } public override string License { get; init; } = "MIT";