diff --git a/BSIPA.sln b/BSIPA.sln
index f2a38632..f4997616 100644
--- a/BSIPA.sln
+++ b/BSIPA.sln
@@ -50,6 +50,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IPA.Loader", "IPA.Loader\IP
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Net3-Proxy", "Net3-Proxy\Net3-Proxy.csproj", "{0DEDB099-9A26-4069-A4C1-A76CEB16283B}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SemVer", "SemVer\SemVer.csproj", "{B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -224,6 +226,30 @@ Global
{0DEDB099-9A26-4069-A4C1-A76CEB16283B}.Verbose|x64.Build.0 = Debug|Any CPU
{0DEDB099-9A26-4069-A4C1-A76CEB16283B}.Verbose|x86.ActiveCfg = Debug|Any CPU
{0DEDB099-9A26-4069-A4C1-A76CEB16283B}.Verbose|x86.Build.0 = Debug|Any CPU
+ {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Debug|x64.Build.0 = Debug|Any CPU
+ {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Debug|x86.Build.0 = Debug|Any CPU
+ {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Release|x64.ActiveCfg = Release|Any CPU
+ {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Release|x64.Build.0 = Release|Any CPU
+ {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Release|x86.ActiveCfg = Release|Any CPU
+ {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Release|x86.Build.0 = Release|Any CPU
+ {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Verbose_Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Verbose_Release|Any CPU.Build.0 = Release|Any CPU
+ {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Verbose_Release|x64.ActiveCfg = Release|Any CPU
+ {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Verbose_Release|x64.Build.0 = Release|Any CPU
+ {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Verbose_Release|x86.ActiveCfg = Release|Any CPU
+ {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Verbose_Release|x86.Build.0 = Release|Any CPU
+ {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Verbose|Any CPU.ActiveCfg = Debug|Any CPU
+ {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Verbose|Any CPU.Build.0 = Debug|Any CPU
+ {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Verbose|x64.ActiveCfg = Debug|Any CPU
+ {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Verbose|x64.Build.0 = Debug|Any CPU
+ {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Verbose|x86.ActiveCfg = Debug|Any CPU
+ {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Verbose|x86.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/IPA.Injector/IPA.Injector.csproj b/IPA.Injector/IPA.Injector.csproj
index e7f5169a..f44c7342 100644
--- a/IPA.Injector/IPA.Injector.csproj
+++ b/IPA.Injector/IPA.Injector.csproj
@@ -81,8 +81,12 @@
-
+
+
+
+ $(MSBuildThisFileDirectory)..\Libs\thirdparty\Hive.Versioning.dll
+
diff --git a/IPA.Loader/IPA.Loader.csproj b/IPA.Loader/IPA.Loader.csproj
index bd4d4609..cfc46967 100644
--- a/IPA.Loader/IPA.Loader.csproj
+++ b/IPA.Loader/IPA.Loader.csproj
@@ -52,9 +52,13 @@
-
-
+
+
+
+
+ $(MSBuildThisFileDirectory)..\Libs\thirdparty\Hive.Versioning.dll
+
diff --git a/IPA.Loader/Properties/AssemblyInfo.cs b/IPA.Loader/Properties/AssemblyInfo.cs
index 456c770b..6f7ebb52 100644
--- a/IPA.Loader/Properties/AssemblyInfo.cs
+++ b/IPA.Loader/Properties/AssemblyInfo.cs
@@ -1,4 +1,5 @@
-using System.Reflection;
+using System;
+using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@@ -18,6 +19,7 @@ using System.Runtime.InteropServices;
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
+[assembly: CLSCompliant(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("5ad344f0-01a0-4ca8-92e5-9d095737744d")]
diff --git a/Libs/thirdparty/Hive.Versioning.dll b/Libs/thirdparty/Hive.Versioning.dll
index 93ed807e..25631609 100644
Binary files a/Libs/thirdparty/Hive.Versioning.dll and b/Libs/thirdparty/Hive.Versioning.dll differ
diff --git a/Libs/thirdparty/Hive.Versioning.pdb b/Libs/thirdparty/Hive.Versioning.pdb
index 846207fb..c74f836c 100644
Binary files a/Libs/thirdparty/Hive.Versioning.pdb and b/Libs/thirdparty/Hive.Versioning.pdb differ
diff --git a/Libs/thirdparty/Hive.Versioning.xml b/Libs/thirdparty/Hive.Versioning.xml
index 8143d72c..8a3c5787 100644
--- a/Libs/thirdparty/Hive.Versioning.xml
+++ b/Libs/thirdparty/Hive.Versioning.xml
@@ -459,7 +459,7 @@
The first argument.
The second argument.
- The logical disjunction of and .
+ The logical conjunction of and .
diff --git a/SemVer/Range.cs b/SemVer/Range.cs
new file mode 100644
index 00000000..1f7a6f32
--- /dev/null
+++ b/SemVer/Range.cs
@@ -0,0 +1,78 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Hive.Versioning;
+using HVersion = Hive.Versioning.Version;
+
+namespace SemVer
+{
+ [Obsolete("Use Hive.Versioning.VersionRange instead.")]
+ public class Range : IEquatable, IEquatable
+ {
+ public VersionRange UnderlyingRange { get; }
+
+ private Range(VersionRange real) => UnderlyingRange = real;
+
+ public Range(string rangeSpec, bool loose = false) : this(new(rangeSpec))
+ => _ = loose; // loose is ignored because Hive doesn't have an equivalent
+
+ public static Range ForHiveRange(VersionRange real) => new(real);
+
+ public bool IsSatisfied(Version version) => IsSatisfied(version.UnderlyingVersion);
+ public bool IsSatisfied(HVersion version) => UnderlyingRange.Matches(version);
+ public bool IsSatisfied(string versionString, bool loose = false) => IsSatisfied(new Version(versionString, loose));
+
+ public IEnumerable Satisfying(IEnumerable versions) => versions.Where(IsSatisfied);
+ public IEnumerable Satisfying(IEnumerable versions, bool loose = false)
+ => versions.Where(v => IsSatisfied(v, loose));
+ public Version? MaxSatisfying(IEnumerable versions) => Satisfying(versions).Max();
+ public string? MaxSatisfying(IEnumerable versionStrings, bool loose = false)
+ => MaxSatisfying(ValidVersions(versionStrings, loose))?.ToString();
+ public Range Intersect(Range other) => new(UnderlyingRange & other.UnderlyingRange); // the conjunction is the intersection
+ public override string ToString() => UnderlyingRange.ToString();
+
+ public bool Equals(Range? other) => UnderlyingRange.Equals(other?.UnderlyingRange);
+ public bool Equals(VersionRange? other) => UnderlyingRange.Equals(other);
+ public override bool Equals(object? obj)
+ => obj switch
+ {
+ Range r => Equals(r),
+ VersionRange vr => Equals(vr),
+ _ => false
+ };
+
+ public static bool operator ==(Range? a, Range? b) => a?.Equals(b) ?? b is null;
+
+ public static bool operator !=(Range? a, Range? b) => !(a == b);
+
+ public override int GetHashCode() => UnderlyingRange.GetHashCode();
+
+ public static bool IsSatisfied(string rangeSpec, string versionString, bool loose = false)
+ => new Range(rangeSpec, loose).IsSatisfied(versionString, loose);
+ public static IEnumerable Satisfying(string rangeSpec, IEnumerable versions, bool loose = false)
+ => new Range(rangeSpec, loose).Satisfying(versions, loose);
+
+ public static string? MaxSatisfying(string rangeSpec, IEnumerable versions, bool loose = false)
+ => new Range(rangeSpec, loose).MaxSatisfying(versions, loose);
+
+ private IEnumerable ValidVersions(IEnumerable versionStrings, bool loose)
+ {
+ foreach (string versionString in versionStrings)
+ {
+ Version? version = null;
+ try
+ {
+ version = new Version(versionString, loose);
+ }
+ catch (ArgumentException)
+ {
+ }
+
+ if (version is not null)
+ {
+ yield return version;
+ }
+ }
+ }
+ }
+}
diff --git a/SemVer/SemVer.csproj b/SemVer/SemVer.csproj
new file mode 100644
index 00000000..eb567912
--- /dev/null
+++ b/SemVer/SemVer.csproj
@@ -0,0 +1,16 @@
+
+
+
+
+
+ net461
+ enable
+
+
+
+
+ $(MSBuildThisFileDirectory)..\Libs\thirdparty\Hive.Versioning.dll
+
+
+
+
diff --git a/SemVer/Version.cs b/SemVer/Version.cs
new file mode 100644
index 00000000..6db9b027
--- /dev/null
+++ b/SemVer/Version.cs
@@ -0,0 +1,70 @@
+using System;
+using System.Linq;
+using HVersion = Hive.Versioning.Version;
+
+namespace SemVer
+{
+ [Obsolete("Use Hive.Versioning.Version instead.")]
+ public class Version : IComparable, IComparable, IComparable, IEquatable, IEquatable
+ {
+ public HVersion UnderlyingVersion { get; }
+
+ private Version(HVersion real) => UnderlyingVersion = real;
+
+ public static Version ForHiveVersion(HVersion real) => new(real);
+
+ public Version(string input, bool loose = false) : this(new HVersion(input))
+ => _ = loose; // specifically unused because Hive has no equivalent (by design)
+ public Version(int major, int minor, int patch, string? preRelease = null, string? build = null)
+ : this(new HVersion(major, minor, patch,
+ preRelease is null ? Enumerable.Empty() : preRelease.Split('.'),
+ build is null ? Enumerable.Empty() : build.Split('.')))
+ {
+ }
+
+ public int Major => (int)UnderlyingVersion.Major;
+ public int Minor => (int)UnderlyingVersion.Minor;
+ public int Patch => (int)UnderlyingVersion.Patch;
+ public string PreRelease => string.Join(".", UnderlyingVersion.PreReleaseIds);
+ public string Build => string.Join(".", UnderlyingVersion.BuildIds);
+
+ public Version BaseVersion() => new(new(UnderlyingVersion.Major, UnderlyingVersion.Minor, UnderlyingVersion.Patch));
+ public override string ToString() => UnderlyingVersion.ToString();
+ public string Clean() => ToString(); // normally this is the other way around kek
+ public override int GetHashCode() => UnderlyingVersion.GetHashCode();
+ public bool Equals(Version? other) => UnderlyingVersion.Equals(other?.UnderlyingVersion);
+ public bool Equals(HVersion? other) => UnderlyingVersion.Equals(other);
+ public override bool Equals(object? obj)
+ => obj switch
+ {
+ Version v => Equals(v),
+ HVersion h => Equals(h),
+ _ => false
+ };
+
+ public int CompareTo(Version? other) => UnderlyingVersion.CompareTo(other?.UnderlyingVersion);
+ public int CompareTo(HVersion? other) => UnderlyingVersion.CompareTo(other);
+ public int CompareTo(object? obj)
+ => obj switch
+ {
+ null => 1,
+ Version v => CompareTo(v),
+ HVersion h => CompareTo(h),
+ _ => throw new ArgumentException("Object is not a Version")
+ };
+
+ public static bool operator ==(Version? a, Version? b)
+ => a?.UnderlyingVersion == b?.UnderlyingVersion;
+ public static bool operator !=(Version? a, Version? b)
+ => a?.UnderlyingVersion != b?.UnderlyingVersion;
+
+ public static bool operator >(Version? a, Version? b)
+ => a is null ? b is not null && b.CompareTo(a) < 0 : a.CompareTo(b) > 0;
+ public static bool operator >=(Version? a, Version? b)
+ => !(a < b);
+ public static bool operator <(Version? a, Version? b)
+ => a is null ? b is not null && b.CompareTo(a) > 0 : a.CompareTo(b) < 0;
+ public static bool operator <=(Version? a, Version? b)
+ => !(a > b);
+ }
+}