diff --git a/build/common.props b/build/common.props
index 6ae030e..e6f063b 100644
--- a/build/common.props
+++ b/build/common.props
@@ -3,7 +3,7 @@
0
- 5.0.$(VersionOverride)
+ 6.0.$(VersionOverride)
diff --git a/src/Bannerlord.ModuleManager.Models/ApplicationVersion.cs b/src/Bannerlord.ModuleManager.Models/ApplicationVersion.cs
index ff42910..2eb85b3 100644
--- a/src/Bannerlord.ModuleManager.Models/ApplicationVersion.cs
+++ b/src/Bannerlord.ModuleManager.Models/ApplicationVersion.cs
@@ -1,18 +1,4 @@
-//
-// This code file has automatically been added by the "Bannerlord.ModuleManager.Source" NuGet package (https://www.nuget.org/packages/Bannerlord.ModuleManager.Source).
-// Please see https://github.com/BUTR/Bannerlord.ModuleManager for more information.
-//
-// IMPORTANT:
-// DO NOT DELETE THIS FILE if you are using a "packages.config" file to manage your NuGet references.
-// Consider migrating to PackageReferences instead:
-// https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference
-// Migrating brings the following benefits:
-// * The "Bannerlord.ModuleManager.Source" folder and the "ApplicationVersion.cs" file don't appear in your project.
-// * The added file is immutable and can therefore not be modified by coincidence.
-// * Updating/Uninstalling the package will work flawlessly.
-//
-
-#region License
+#region License
// MIT License
//
// Copyright (c) Bannerlord's Unofficial Tools & Resources
@@ -41,133 +27,133 @@
#pragma warning disable
#endif
-namespace Bannerlord.ModuleManager
-{
- using global::System;
+namespace Bannerlord.ModuleManager;
+
+using System;
#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
internal
#else
- public
+public
# endif
- record ApplicationVersion : IComparable
+ record ApplicationVersion : IComparable
+{
+ public static ApplicationVersion Empty { get; } = new();
+
+ public ApplicationVersionType ApplicationVersionType { get; set; }
+ public int Major { get; set; }
+ public int Minor { get; set; }
+ public int Revision { get; set; }
+ public int ChangeSet { get; set; }
+
+ public ApplicationVersion() { }
+ public ApplicationVersion(ApplicationVersionType applicationVersionType, int major, int minor, int revision, int changeSet)
{
- public static ApplicationVersion Empty { get; } = new();
+ ApplicationVersionType = applicationVersionType;
+ Major = major;
+ Minor = minor;
+ Revision = revision;
+ ChangeSet = changeSet;
+ }
- public ApplicationVersionType ApplicationVersionType { get; set; }
- public int Major { get; set; }
- public int Minor { get; set; }
- public int Revision { get; set; }
- public int ChangeSet { get; set; }
+ public bool IsSame(ApplicationVersion? other) =>
+ Major == other?.Major && Minor == other.Minor && Revision == other.Revision;
- public ApplicationVersion() { }
- public ApplicationVersion(ApplicationVersionType applicationVersionType, int major, int minor, int revision, int changeSet)
- {
- ApplicationVersionType = applicationVersionType;
- Major = major;
- Minor = minor;
- Revision = revision;
- ChangeSet = changeSet;
- }
+ public bool IsSameWithChangeSet(ApplicationVersion? other) =>
+ Major == other?.Major && Minor == other.Minor && Revision == other.Revision && ChangeSet == other.ChangeSet;
- public bool IsSame(ApplicationVersion? other) =>
- Major == other?.Major && Minor == other.Minor && Revision == other.Revision;
+ public override string ToString() => $"{GetPrefix(ApplicationVersionType)}{Major}.{Minor}.{Revision}.{ChangeSet}";
- public bool IsSameWithChangeSet(ApplicationVersion? other) =>
- Major == other?.Major && Minor == other.Minor && Revision == other.Revision && ChangeSet == other.ChangeSet;
+ public int CompareTo(ApplicationVersion? other) => ApplicationVersionComparer.CompareStandard(this, other);
- public override string ToString() => $"{GetPrefix(ApplicationVersionType)}{Major}.{Minor}.{Revision}.{ChangeSet}";
+ public static bool operator <(ApplicationVersion left, ApplicationVersion right) => left.CompareTo(right) < 0;
+ public static bool operator >(ApplicationVersion left, ApplicationVersion right) => left.CompareTo(right) > 0;
+ public static bool operator <=(ApplicationVersion left, ApplicationVersion right) => left.CompareTo(right) <= 0;
+ public static bool operator >=(ApplicationVersion left, ApplicationVersion right) => left.CompareTo(right) >= 0;
- public int CompareTo(ApplicationVersion? other) => ApplicationVersionComparer.CompareStandard(this, other);
+ public static char GetPrefix(ApplicationVersionType applicationVersionType) => applicationVersionType switch
+ {
+ ApplicationVersionType.Alpha => 'a',
+ ApplicationVersionType.Beta => 'b',
+ ApplicationVersionType.EarlyAccess => 'e',
+ ApplicationVersionType.Release => 'v',
+ ApplicationVersionType.Development => 'd',
+ _ => 'i'
+ };
+
+ public static ApplicationVersionType FromPrefix(char applicationVersionType) => applicationVersionType switch
+ {
+ 'a' => ApplicationVersionType.Alpha,
+ 'b' => ApplicationVersionType.Beta,
+ 'e' => ApplicationVersionType.EarlyAccess,
+ 'v' => ApplicationVersionType.Release,
+ 'd' => ApplicationVersionType.Development,
+ _ => ApplicationVersionType.Invalid
+ };
- public static bool operator <(ApplicationVersion left, ApplicationVersion right) => left.CompareTo(right) < 0;
- public static bool operator >(ApplicationVersion left, ApplicationVersion right) => left.CompareTo(right) > 0;
- public static bool operator <=(ApplicationVersion left, ApplicationVersion right) => left.CompareTo(right) <= 0;
- public static bool operator >=(ApplicationVersion left, ApplicationVersion right) => left.CompareTo(right) >= 0;
+ public static bool TryParse(string? versionAsString, out ApplicationVersion version) => TryParse(versionAsString, out version, true);
- public static char GetPrefix(ApplicationVersionType applicationVersionType) => applicationVersionType switch
+ public static bool TryParse(string? versionAsString, out ApplicationVersion version, bool asMin)
+ {
+ var major = asMin ? 0 : int.MaxValue;
+ var minor = asMin ? 0 : int.MaxValue;
+ var revision = asMin ? 0 : int.MaxValue;
+ var changeSet = asMin ? 0 : int.MaxValue;
+ var skipCheck = false;
+ version = Empty;
+ if (versionAsString is null)
+ return false;
+
+ var array = versionAsString.Split('.');
+ if (array.Length != 3 && array.Length != 4 && array[0].Length == 0)
+ return false;
+
+ var applicationVersionType = FromPrefix(array[0][0]);
+ if (!skipCheck && !int.TryParse(array[0].Substring(1), out major))
{
- ApplicationVersionType.Alpha => 'a',
- ApplicationVersionType.Beta => 'b',
- ApplicationVersionType.EarlyAccess => 'e',
- ApplicationVersionType.Release => 'v',
- ApplicationVersionType.Development => 'd',
- _ => 'i'
- };
-
- public static ApplicationVersionType FromPrefix(char applicationVersionType) => applicationVersionType switch
+ if (array[0].Substring(1) != "*") return false;
+ major = int.MinValue;
+ minor = int.MinValue;
+ revision = int.MinValue;
+ changeSet = int.MinValue;
+ skipCheck = true;
+ }
+ if (!skipCheck && !int.TryParse(array[1], out minor))
{
- 'a' => ApplicationVersionType.Alpha,
- 'b' => ApplicationVersionType.Beta,
- 'e' => ApplicationVersionType.EarlyAccess,
- 'v' => ApplicationVersionType.Release,
- 'd' => ApplicationVersionType.Development,
- _ => ApplicationVersionType.Invalid
- };
-
- public static bool TryParse(string? versionAsString, out ApplicationVersion version) => TryParse(versionAsString, out version, true);
+ if (array[1] != "*") return false;
+ minor = asMin ? 0 : int.MaxValue;
+ revision = asMin ? 0 : int.MaxValue;
+ changeSet = asMin ? 0 : int.MaxValue;
+ skipCheck = true;
+ }
+ if (!skipCheck && !int.TryParse(array[2], out revision))
+ {
+ if (array[2] != "*") return false;
+ revision = asMin ? 0 : int.MaxValue;
+ changeSet = asMin ? 0 : int.MaxValue;
+ skipCheck = true;
+ }
- public static bool TryParse(string? versionAsString, out ApplicationVersion version, bool asMin)
+ if (!skipCheck && array.Length == 4 && !int.TryParse(array[3], out changeSet))
{
- var major = asMin ? 0 : int.MaxValue;
- var minor = asMin ? 0 : int.MaxValue;
- var revision = asMin ? 0 : int.MaxValue;
- var changeSet = asMin ? 0 : int.MaxValue;
- var skipCheck = false;
- version = Empty;
- if (versionAsString is null)
- return false;
-
- var array = versionAsString.Split('.');
- if (array.Length != 3 && array.Length != 4 && array[0].Length == 0)
- return false;
-
- var applicationVersionType = FromPrefix(array[0][0]);
- if (!skipCheck && !int.TryParse(array[0].Substring(1), out major))
- {
- if (array[0].Substring(1) != "*") return false;
- major = int.MinValue;
- minor = int.MinValue;
- revision = int.MinValue;
- changeSet = int.MinValue;
- skipCheck = true;
- }
- if (!skipCheck && !int.TryParse(array[1], out minor))
- {
- if (array[1] != "*") return false;
- minor = asMin ? 0 : int.MaxValue;
- revision = asMin ? 0 : int.MaxValue;
- changeSet = asMin ? 0 : int.MaxValue;
- skipCheck = true;
- }
- if (!skipCheck && !int.TryParse(array[2], out revision))
- {
- if (array[2] != "*") return false;
- revision = asMin ? 0 : int.MaxValue;
- changeSet = asMin ? 0 : int.MaxValue;
- skipCheck = true;
- }
-
- if (!skipCheck && array.Length == 4 && !int.TryParse(array[3], out changeSet))
- {
- if (array[3] != "*") return false;
- changeSet = asMin ? 0 : int.MaxValue;
- skipCheck = true;
- }
-
- version = new ApplicationVersion
- {
- ApplicationVersionType = applicationVersionType,
- Major = major,
- Minor = minor,
- Revision = revision,
- ChangeSet = changeSet
- };
-
- return true;
+ if (array[3] != "*") return false;
+ changeSet = asMin ? 0 : int.MaxValue;
+ skipCheck = true;
}
+
+ version = new ApplicationVersion
+ {
+ ApplicationVersionType = applicationVersionType,
+ Major = major,
+ Minor = minor,
+ Revision = revision,
+ ChangeSet = changeSet
+ };
+
+ return true;
}
}
+
#nullable restore
#if !BANNERLORDBUTRMODULEMANAGER_ENABLE_WARNING
#pragma warning restore
diff --git a/src/Bannerlord.ModuleManager.Models/ApplicationVersionComparer.cs b/src/Bannerlord.ModuleManager.Models/ApplicationVersionComparer.cs
index 231efb4..1f94e19 100644
--- a/src/Bannerlord.ModuleManager.Models/ApplicationVersionComparer.cs
+++ b/src/Bannerlord.ModuleManager.Models/ApplicationVersionComparer.cs
@@ -1,18 +1,4 @@
-//
-// This code file has automatically been added by the "Bannerlord.ModuleManager.Source" NuGet package (https://www.nuget.org/packages/Bannerlord.ModuleManager.Source).
-// Please see https://github.com/BUTR/Bannerlord.ModuleManager for more information.
-//
-// IMPORTANT:
-// DO NOT DELETE THIS FILE if you are using a "packages.config" file to manage your NuGet references.
-// Consider migrating to PackageReferences instead:
-// https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference
-// Migrating brings the following benefits:
-// * The "Bannerlord.ModuleManager.Source" folder and the "ApplicationVersionComparer.cs" file don't appear in your project.
-// * The added file is immutable and can therefore not be modified by coincidence.
-// * Updating/Uninstalling the package will work flawlessly.
-//
-
-#region License
+#region License
// MIT License
//
// Copyright (c) Bannerlord's Unofficial Tools & Resources
@@ -41,54 +27,54 @@
#pragma warning disable
#endif
-namespace Bannerlord.ModuleManager
-{
- using global::System.Collections;
- using global::System.Collections.Generic;
+namespace Bannerlord.ModuleManager;
+
+using System.Collections;
+using System.Collections.Generic;
#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
internal
#else
- public
+public
# endif
- class ApplicationVersionComparer : IComparer, IComparer
- {
- ///
- public int Compare(object? x, object? y) => Compare(x as ApplicationVersion, y as ApplicationVersion);
+ class ApplicationVersionComparer : IComparer, IComparer
+{
+ ///
+ public int Compare(object? x, object? y) => Compare(x as ApplicationVersion, y as ApplicationVersion);
- ///
- public virtual int Compare(ApplicationVersion? x, ApplicationVersion? y) => CompareStandard(x, y);
+ ///
+ public virtual int Compare(ApplicationVersion? x, ApplicationVersion? y) => CompareStandard(x, y);
- public static int CompareStandard(ApplicationVersion? x, ApplicationVersion? y)
- {
- if (x is null && y is null)
- return 0;
+ public static int CompareStandard(ApplicationVersion? x, ApplicationVersion? y)
+ {
+ if (x is null && y is null)
+ return 0;
- if (x is null)
- return -1;
+ if (x is null)
+ return -1;
- if (y is null)
- return 1;
+ if (y is null)
+ return 1;
- var versionTypeComparison = x.ApplicationVersionType.CompareTo(y.ApplicationVersionType);
- if (versionTypeComparison != 0) return versionTypeComparison;
+ var versionTypeComparison = x.ApplicationVersionType.CompareTo(y.ApplicationVersionType);
+ if (versionTypeComparison != 0) return versionTypeComparison;
- var majorComparison = x.Major.CompareTo(y.Major);
- if (majorComparison != 0) return majorComparison;
+ var majorComparison = x.Major.CompareTo(y.Major);
+ if (majorComparison != 0) return majorComparison;
- var minorComparison = x.Minor.CompareTo(y.Minor);
- if (minorComparison != 0) return minorComparison;
+ var minorComparison = x.Minor.CompareTo(y.Minor);
+ if (minorComparison != 0) return minorComparison;
- var revisionComparison = x.Revision.CompareTo(y.Revision);
- if (revisionComparison != 0) return revisionComparison;
+ var revisionComparison = x.Revision.CompareTo(y.Revision);
+ if (revisionComparison != 0) return revisionComparison;
- var changeSetComparison = x.ChangeSet.CompareTo(y.ChangeSet);
- if (changeSetComparison != 0) return changeSetComparison;
+ var changeSetComparison = x.ChangeSet.CompareTo(y.ChangeSet);
+ if (changeSetComparison != 0) return changeSetComparison;
- return 0;
- }
+ return 0;
}
}
+
#nullable restore
#if !BANNERLORDBUTRMODULEMANAGER_ENABLE_WARNING
#pragma warning restore
diff --git a/src/Bannerlord.ModuleManager.Models/ApplicationVersionRange.cs b/src/Bannerlord.ModuleManager.Models/ApplicationVersionRange.cs
index 483d656..04185b2 100644
--- a/src/Bannerlord.ModuleManager.Models/ApplicationVersionRange.cs
+++ b/src/Bannerlord.ModuleManager.Models/ApplicationVersionRange.cs
@@ -1,18 +1,4 @@
-//
-// This code file has automatically been added by the "Bannerlord.ModuleManager.Source" NuGet package (https://www.nuget.org/packages/Bannerlord.ModuleManager.Source).
-// Please see https://github.com/BUTR/Bannerlord.ModuleManager for more information.
-//
-// IMPORTANT:
-// DO NOT DELETE THIS FILE if you are using a "packages.config" file to manage your NuGet references.
-// Consider migrating to PackageReferences instead:
-// https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference
-// Migrating brings the following benefits:
-// * The "Bannerlord.ModuleManager.Source" folder and the "ApplicationVersionRange.cs" file don't appear in your project.
-// * The added file is immutable and can therefore not be modified by coincidence.
-// * Updating/Uninstalling the package will work flawlessly.
-//
-
-#region License
+#region License
// MIT License
//
// Copyright (c) Bannerlord's Unofficial Tools & Resources
@@ -41,64 +27,64 @@
#pragma warning disable
#endif
-namespace Bannerlord.ModuleManager
-{
+namespace Bannerlord.ModuleManager;
+
#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
internal
#else
- public
+public
# endif
- record ApplicationVersionRange
- {
- public static ApplicationVersionRange Empty => new();
+ record ApplicationVersionRange
+{
+ public static ApplicationVersionRange Empty => new();
- public ApplicationVersion Min { get; set; } = ApplicationVersion.Empty;
- public ApplicationVersion Max { get; set; } = ApplicationVersion.Empty;
+ public ApplicationVersion Min { get; set; } = ApplicationVersion.Empty;
+ public ApplicationVersion Max { get; set; } = ApplicationVersion.Empty;
- public ApplicationVersionRange() { }
- public ApplicationVersionRange(ApplicationVersion min, ApplicationVersion max)
- {
- Max = max;
- Min = min;
- }
+ public ApplicationVersionRange() { }
+ public ApplicationVersionRange(ApplicationVersion min, ApplicationVersion max)
+ {
+ Max = max;
+ Min = min;
+ }
- public bool IsSame(ApplicationVersionRange? other) =>
- Min.IsSame(other?.Min) && Max.IsSame(other?.Max);
+ public bool IsSame(ApplicationVersionRange? other) =>
+ Min.IsSame(other?.Min) && Max.IsSame(other?.Max);
- public bool IsSameWithChangeSet(ApplicationVersionRange? other) =>
- Min.IsSameWithChangeSet(other?.Min) && Max.IsSameWithChangeSet(other?.Max);
+ public bool IsSameWithChangeSet(ApplicationVersionRange? other) =>
+ Min.IsSameWithChangeSet(other?.Min) && Max.IsSameWithChangeSet(other?.Max);
- public override string ToString() => $"{Min} - {Max}";
+ public override string ToString() => $"{Min} - {Max}";
- public static bool TryParse(string versionRangeAsString, out ApplicationVersionRange versionRange)
- {
- versionRange = Empty;
+ public static bool TryParse(string versionRangeAsString, out ApplicationVersionRange versionRange)
+ {
+ versionRange = Empty;
- if (string.IsNullOrWhiteSpace(versionRangeAsString))
- return false;
+ if (string.IsNullOrWhiteSpace(versionRangeAsString))
+ return false;
- versionRangeAsString = versionRangeAsString.Replace(" ", string.Empty);
- var index = versionRangeAsString.IndexOf('-');
- if (index < 0)
- return false;
+ versionRangeAsString = versionRangeAsString.Replace(" ", string.Empty);
+ var index = versionRangeAsString.IndexOf('-');
+ if (index < 0)
+ return false;
- var minAsString = versionRangeAsString.Substring(0, index);
- var maxAsString = versionRangeAsString.Substring(index + 1, versionRangeAsString.Length - 1 - index);
+ var minAsString = versionRangeAsString.Substring(0, index);
+ var maxAsString = versionRangeAsString.Substring(index + 1, versionRangeAsString.Length - 1 - index);
- if (ApplicationVersion.TryParse(minAsString, out var min, true) && ApplicationVersion.TryParse(maxAsString, out var max, false))
+ if (ApplicationVersion.TryParse(minAsString, out var min, true) && ApplicationVersion.TryParse(maxAsString, out var max, false))
+ {
+ versionRange = new ApplicationVersionRange
{
- versionRange = new ApplicationVersionRange
- {
- Min = min,
- Max = max
- };
- return true;
- }
-
- return false;
+ Min = min,
+ Max = max
+ };
+ return true;
}
+
+ return false;
}
}
+
#nullable restore
#if !BANNERLORDBUTRMODULEMANAGER_ENABLE_WARNING
#pragma warning restore
diff --git a/src/Bannerlord.ModuleManager.Models/ApplicationVersionType.cs b/src/Bannerlord.ModuleManager.Models/ApplicationVersionType.cs
index de0e38f..454f6f2 100644
--- a/src/Bannerlord.ModuleManager.Models/ApplicationVersionType.cs
+++ b/src/Bannerlord.ModuleManager.Models/ApplicationVersionType.cs
@@ -1,18 +1,4 @@
-//
-// This code file has automatically been added by the "Bannerlord.ModuleManager.Source" NuGet package (https://www.nuget.org/packages/Bannerlord.ModuleManager.Source).
-// Please see https://github.com/BUTR/Bannerlord.ModuleManager for more information.
-//
-// IMPORTANT:
-// DO NOT DELETE THIS FILE if you are using a "packages.config" file to manage your NuGet references.
-// Consider migrating to PackageReferences instead:
-// https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference
-// Migrating brings the following benefits:
-// * The "Bannerlord.ModuleManager.Source" folder and the "ApplicationVersionType.cs" file don't appear in your project.
-// * The added file is immutable and can therefore not be modified by coincidence.
-// * Updating/Uninstalling the package will work flawlessly.
-//
-
-#region License
+#region License
// MIT License
//
// Copyright (c) Bannerlord's Unofficial Tools & Resources
@@ -41,23 +27,23 @@
#pragma warning disable
#endif
-namespace Bannerlord.ModuleManager
-{
+namespace Bannerlord.ModuleManager;
+
#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
internal
#else
- public
+public
# endif
- enum ApplicationVersionType
- {
- Alpha,
- Beta,
- EarlyAccess,
- Release,
- Development,
- Invalid
- }
+ enum ApplicationVersionType
+{
+ Alpha,
+ Beta,
+ EarlyAccess,
+ Release,
+ Development,
+ Invalid
}
+
#nullable restore
#if !BANNERLORDBUTRMODULEMANAGER_ENABLE_WARNING
#pragma warning restore
diff --git a/src/Bannerlord.ModuleManager.Models/Bannerlord.ModuleManager.Models.csproj b/src/Bannerlord.ModuleManager.Models/Bannerlord.ModuleManager.Models.csproj
index a53442e..bed91c1 100644
--- a/src/Bannerlord.ModuleManager.Models/Bannerlord.ModuleManager.Models.csproj
+++ b/src/Bannerlord.ModuleManager.Models/Bannerlord.ModuleManager.Models.csproj
@@ -31,6 +31,7 @@
+
\ No newline at end of file
diff --git a/src/Bannerlord.ModuleManager.Models/DependentModule.cs b/src/Bannerlord.ModuleManager.Models/DependentModule.cs
index a11f717..c53fd32 100644
--- a/src/Bannerlord.ModuleManager.Models/DependentModule.cs
+++ b/src/Bannerlord.ModuleManager.Models/DependentModule.cs
@@ -41,28 +41,28 @@
#pragma warning disable
#endif
-namespace Bannerlord.ModuleManager
-{
+namespace Bannerlord.ModuleManager;
+
#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
internal
#else
- public
+public
# endif
- record DependentModule
- {
- public string Id { get; set; } = string.Empty;
- public ApplicationVersion Version { get; set; } = ApplicationVersion.Empty;
- public bool IsOptional { get; set; } = false;
+ record DependentModule
+{
+ public string Id { get; set; } = string.Empty;
+ public ApplicationVersion Version { get; set; } = ApplicationVersion.Empty;
+ public bool IsOptional { get; set; } = false;
- public DependentModule() { }
- public DependentModule(string id, ApplicationVersion version, bool isOptional)
- {
- Id = id;
- Version = version;
- IsOptional = isOptional;
- }
+ public DependentModule() { }
+ public DependentModule(string id, ApplicationVersion version, bool isOptional)
+ {
+ Id = id;
+ Version = version;
+ IsOptional = isOptional;
}
}
+
#nullable restore
#if !BANNERLORDBUTRMODULEMANAGER_ENABLE_WARNING
#pragma warning restore
diff --git a/src/Bannerlord.ModuleManager.Models/DependentModuleMetadata.cs b/src/Bannerlord.ModuleManager.Models/DependentModuleMetadata.cs
index dbd887a..e7174b9 100644
--- a/src/Bannerlord.ModuleManager.Models/DependentModuleMetadata.cs
+++ b/src/Bannerlord.ModuleManager.Models/DependentModuleMetadata.cs
@@ -1,18 +1,4 @@
-//
-// This code file has automatically been added by the "Bannerlord.ModuleManager.Source" NuGet package (https://www.nuget.org/packages/Bannerlord.ModuleManager.Source).
-// Please see https://github.com/BUTR/Bannerlord.ModuleManager for more information.
-//
-// IMPORTANT:
-// DO NOT DELETE THIS FILE if you are using a "packages.config" file to manage your NuGet references.
-// Consider migrating to PackageReferences instead:
-// https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference
-// Migrating brings the following benefits:
-// * The "Bannerlord.ModuleManager.Source" folder and the "DependentModuleMetadata.cs" file don't appear in your project.
-// * The added file is immutable and can therefore not be modified by coincidence.
-// * Updating/Uninstalling the package will work flawlessly.
-//
-
-#region License
+#region License
// MIT License
//
// Copyright (c) Bannerlord's Unofficial Tools & Resources
@@ -41,47 +27,47 @@
#pragma warning disable
#endif
-namespace Bannerlord.ModuleManager
-{
+namespace Bannerlord.ModuleManager;
+
#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
internal
#else
- public
+public
# endif
- record DependentModuleMetadata
- {
- public string Id { get; set; } = string.Empty;
- public LoadType LoadType { get; set; }
- public bool IsOptional { get; set; }
- public bool IsIncompatible { get; set; }
- public ApplicationVersion Version { get; set; } = ApplicationVersion.Empty;
- public ApplicationVersionRange VersionRange { get; set; } = ApplicationVersionRange.Empty;
-
- public DependentModuleMetadata() { }
- public DependentModuleMetadata(string id, LoadType loadType, bool isOptional, bool isIncompatible, ApplicationVersion version, ApplicationVersionRange versionRange)
- {
- Id = id;
- LoadType = loadType;
- IsOptional = isOptional;
- IsIncompatible = isIncompatible;
- Version = version;
- VersionRange = versionRange;
- }
+ record DependentModuleMetadata
+{
+ public string Id { get; set; } = string.Empty;
+ public LoadType LoadType { get; set; }
+ public bool IsOptional { get; set; }
+ public bool IsIncompatible { get; set; }
+ public ApplicationVersion Version { get; set; } = ApplicationVersion.Empty;
+ public ApplicationVersionRange VersionRange { get; set; } = ApplicationVersionRange.Empty;
- public static string GetLoadType(LoadType loadType) => loadType switch
- {
- LoadType.None => "",
- LoadType.LoadAfterThis => "Before ",
- LoadType.LoadBeforeThis => "After ",
- _ => "ERROR "
- };
- public static string GetVersion(ApplicationVersion? av) => av?.IsSameWithChangeSet(ApplicationVersion.Empty) == true ? "" : $" {av}";
- public static string GetVersionRange(ApplicationVersionRange? avr) => avr == ApplicationVersionRange.Empty ? "" : $" {avr}";
- public static string GetOptional(bool isOptional) => isOptional ? " Optional" : "";
- public static string GetIncompatible(bool isOptional) => isOptional ? "Incompatible " : "";
- public override string ToString() => GetLoadType(LoadType) + GetIncompatible(IsIncompatible) + Id + GetVersion(Version) + GetVersionRange(VersionRange) + GetOptional(IsOptional);
+ public DependentModuleMetadata() { }
+ public DependentModuleMetadata(string id, LoadType loadType, bool isOptional, bool isIncompatible, ApplicationVersion version, ApplicationVersionRange versionRange)
+ {
+ Id = id;
+ LoadType = loadType;
+ IsOptional = isOptional;
+ IsIncompatible = isIncompatible;
+ Version = version;
+ VersionRange = versionRange;
}
+
+ public static string GetLoadType(LoadType loadType) => loadType switch
+ {
+ LoadType.None => "",
+ LoadType.LoadAfterThis => "Before ",
+ LoadType.LoadBeforeThis => "After ",
+ _ => "ERROR "
+ };
+ public static string GetVersion(ApplicationVersion? av) => av?.IsSameWithChangeSet(ApplicationVersion.Empty) == true ? "" : $" {av}";
+ public static string GetVersionRange(ApplicationVersionRange? avr) => avr == ApplicationVersionRange.Empty ? "" : $" {avr}";
+ public static string GetOptional(bool isOptional) => isOptional ? " Optional" : "";
+ public static string GetIncompatible(bool isOptional) => isOptional ? "Incompatible " : "";
+ public override string ToString() => GetLoadType(LoadType) + GetIncompatible(IsIncompatible) + Id + GetVersion(Version) + GetVersionRange(VersionRange) + GetOptional(IsOptional);
}
+
#nullable restore
#if !BANNERLORDBUTRMODULEMANAGER_ENABLE_WARNING
#pragma warning restore
diff --git a/src/Bannerlord.ModuleManager.Models/Issues/ModuleIssueV2.cs b/src/Bannerlord.ModuleManager.Models/Issues/ModuleIssueV2.cs
new file mode 100644
index 0000000..d2f08bb
--- /dev/null
+++ b/src/Bannerlord.ModuleManager.Models/Issues/ModuleIssueV2.cs
@@ -0,0 +1,839 @@
+#region License
+// MIT License
+//
+// Copyright (c) Bannerlord's Unofficial Tools & Resources
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+#endregion
+
+#nullable enable
+#if !BANNERLORDBUTRMODULEMANAGER_ENABLE_WARNING
+#pragma warning disable
+#endif
+
+// ReSharper disable MemberCanBePrivate.Global
+
+namespace Bannerlord.ModuleManager.Models.Issues;
+
+using LegacyModuleIssue = ModuleIssue;
+
+///
+/// Base record type for all module-related issues that can occur during validation.
+/// This record serves as the abstract base class for all specific issue variants,
+/// providing a common structure and conversion capability to legacy formats.
+///
+/// The module in which the issue was detected. This is always required.
+#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
+internal
+#else
+public
+# endif
+ abstract record ModuleIssueV2(ModuleInfoExtended Module)
+{
+ ///
+ /// Converts this issue instance to the legacy ModuleIssue format for backwards compatibility
+ ///
+ /// A representation of this issue
+ public abstract LegacyModuleIssue ToLegacy();
+}
+
+///
+/// Represents an issue where a required module is missing from the module list.
+/// This indicates some sort of error with the API usage, you called a method with a
+/// module list, but the module you provided in another parameter was not in that list.
+///
+/// The module that was found to be missing
+/// The version range in which the module should exist
+#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
+internal
+#else
+public
+# endif
+ sealed record ModuleMissingIssue(
+ ModuleInfoExtended Module,
+ ApplicationVersionRange SourceVersion
+) : ModuleIssueV2(Module)
+{
+ public override string ToString() => $"Module '{Module.Id}' {Module.Version} is missing from modules list";
+ public override LegacyModuleIssue ToLegacy() => new(Module, Module.Id, ModuleIssueType.Missing, ToString(), SourceVersion);
+}
+
+///
+/// Represents an issue where a required dependency module is missing and no version was specified
+///
+/// The module with the missing dependency
+/// The missing dependency module
+///
+/// This issue occurs when a required unversioned dependency is missing.
+///
+/// Example scenario:
+/// ```xml
+///
+///
+///
+///
+///
+///
+///
+///
+/// ```
+/// If `TournamentOverhaul` is not installed at all, this issue will be raised if `SimpleTournaments` is enabled.
+/// Note that it's recommended to use `DependedModuleMetadatas` with version specifications instead.
+///
+#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
+internal
+#else
+public
+# endif
+ sealed record ModuleMissingUnversionedDependencyIssue(
+ ModuleInfoExtended Module,
+ DependentModuleMetadata Dependency
+) : ModuleIssueV2(Module)
+{
+ public override string ToString() => $"Missing '{Dependency.Id}' module";
+ public override LegacyModuleIssue ToLegacy() => new(
+ Module,
+ Dependency.Id,
+ ModuleIssueType.MissingDependencies,
+ ToString(),
+ ApplicationVersionRange.Empty);
+}
+
+///
+/// Represents an issue where a required dependency module is missing AND an exact version was specified
+///
+/// The module with the missing dependency
+/// The missing dependency module
+///
+/// This issue occurs when a required dependency with an exact version requirement is missing.
+///
+/// Example scenario:
+/// ```xml
+///
+///
+///
+///
+///
+///
+///
+///
+/// ```
+/// If `Bannerlord.UIExtenderEx` is not installed at all (any version), this issue will be raised.
+/// This is different from version mismatch issues where the module is present but with wrong version.
+///
+#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
+internal
+#else
+public
+# endif
+ sealed record ModuleMissingExactVersionDependencyIssue(
+ ModuleInfoExtended Module,
+ DependentModuleMetadata Dependency
+) : ModuleIssueV2(Module)
+{
+ public override string ToString() => $"Missing '{Dependency.Id}' with required version {Dependency.Version}";
+ public override LegacyModuleIssue ToLegacy() => new(
+ Module,
+ Dependency.Id,
+ ModuleIssueType.MissingDependencies,
+ ToString(),
+ new ApplicationVersionRange(Dependency.Version, Dependency.Version));
+}
+
+///
+/// Represents an issue where a required dependency module is missing and a version range was specified
+///
+/// The module with the missing dependency
+/// The missing dependency module
+///
+/// This issue occurs when a required dependency with a version range requirement is missing.
+///
+/// Example scenario:
+/// ```xml
+///
+///
+///
+///
+///
+///
+///
+///
+/// ```
+/// If `Bannerlord.UIExtenderEx` module is not installed at all (any version), this issue will be raised.
+/// This is different from version mismatch issues where the module is present but with wrong version.
+///
+#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
+internal
+#else
+public
+# endif
+ sealed record ModuleMissingVersionRangeDependencyIssue(
+ ModuleInfoExtended Module,
+ DependentModuleMetadata Dependency
+) : ModuleIssueV2(Module)
+{
+ public override string ToString() => $"Missing '{Dependency.Id}' with required version range [{Dependency.VersionRange}]";
+ public override LegacyModuleIssue ToLegacy() => new(Module,
+ Dependency.Id,
+ ModuleIssueType.MissingDependencies,
+ ToString(),
+ Dependency.VersionRange);
+}
+
+///
+/// Represents an issue where a module's dependency is itself missing required dependencies.
+/// This is a cascading issue where a module's dependency has unresolved dependencies,
+/// indicating a deeper problem in the dependency chain.
+///
+/// The module whose dependency has missing dependencies
+/// The ID of the dependency module that is missing its own dependencies
+///
+/// This issue occurs when a dependency has missing dependencies of its own.
+///
+/// Example scenario:
+/// ```xml
+///
+///
+///
+///
+///
+///
+///
+///
+///
+/// ```
+/// If `BetterTime` requires `Harmony` but `Harmony` is not installed, this issue will be raised for `RealisticWeather`
+/// because its dependency (`BetterTime`) has missing dependencies.
+///
+#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
+internal
+#else
+public
+# endif
+ sealed record ModuleDependencyMissingDependenciesIssue(
+ ModuleInfoExtended Module,
+ string DependencyId
+) : ModuleIssueV2(Module)
+{
+ public override string ToString() => $"Module '{Module.Id}': Required dependency '{DependencyId}' is missing its own dependencies";
+ public override LegacyModuleIssue ToLegacy() => new(Module, DependencyId, ModuleIssueType.DependencyMissingDependencies, ToString(), ApplicationVersionRange.Empty);
+}
+
+///
+/// Represents an issue where a module's dependency fails validation checks.
+/// This indicates that while the dependency exists, it has its own validation
+/// issues that need to be resolved.
+///
+/// The module with the dependency that failed validation
+/// The ID of the dependency module that failed validation
+///
+/// This issue occurs when a dependency has validation issues of its own.
+///
+/// Example scenario:
+/// ```xml
+///
+///
+///
+///
+///
+///
+///
+///
+/// ```
+/// If `CustomSpawnsFramework` has its own issues (like missing dependencies or invalid configuration),
+/// this issue will be raised for `CustomSpawns` since its dependency needs to be fixed first.
+///
+#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
+internal
+#else
+public
+# endif
+ sealed record ModuleDependencyValidationIssue(
+ ModuleInfoExtended Module,
+ string DependencyId
+) : ModuleIssueV2(Module)
+{
+ public override string ToString() => $"Module '{Module.Id}': Dependency '{DependencyId}' has unresolved validation issues";
+ public override LegacyModuleIssue ToLegacy() => new(Module, DependencyId, ModuleIssueType.DependencyValidationError, ToString(), ApplicationVersionRange.Empty);
+}
+
+///
+/// Base record type for version mismatch issues between modules and their dependencies.
+/// This serves as an abstract base for both specific version and version range issues.
+///
+/// The module with the version mismatch
+/// The dependency module with mismatched version
+#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
+internal
+#else
+public
+# endif
+ abstract record ModuleVersionMismatchIssue(
+ ModuleInfoExtended Module,
+ ModuleInfoExtended Dependency
+) : ModuleIssueV2(Module);
+
+///
+/// Base record type for version mismatch issues involving specific versions.
+/// Used when comparing against exact version numbers rather than ranges.
+///
+/// The module with the version mismatch
+/// The dependency module with mismatched version
+/// The specific version being compared against
+#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
+internal
+#else
+public
+# endif
+ abstract record ModuleVersionMismatchSpecificIssue(
+ ModuleInfoExtended Module,
+ ModuleInfoExtended Dependency,
+ ApplicationVersion Version
+) : ModuleVersionMismatchIssue(Module, Dependency);
+
+///
+/// Base record type for version mismatch issues involving version ranges.
+/// Used when comparing against version ranges rather than specific versions.
+///
+/// The module with the version mismatch
+/// The dependency module with mismatched version
+/// The version range being compared against
+#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
+internal
+#else
+public
+# endif
+ abstract record ModuleVersionMismatchRangeIssue(
+ ModuleInfoExtended Module,
+ ModuleInfoExtended Dependency,
+ ApplicationVersionRange VersionRange
+) : ModuleVersionMismatchIssue(Module, Dependency);
+
+///
+/// Represents an issue where a dependency's version is higher than the maximum allowed specific version.
+/// This occurs when a dependency module's version exceeds an exact version requirement.
+///
+/// The module with the version constraint
+/// The dependency module that exceeds the version requirement
+/// The specific version that should not be exceeded
+///
+/// This issue occurs when a module specifies incompatible versions.
+///
+/// Example scenario:
+/// ```xml
+///
+///
+///
+///
+///
+///
+///
+///
+///
+/// ```
+///
+/// If a higher version of Harmony (e.g., `v2.3.0`) is installed than allowed, this issue will be raised.
+///
+#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
+internal
+#else
+public
+# endif
+ sealed record ModuleVersionMismatchLessThanOrEqualSpecificIssue(
+ ModuleInfoExtended Module,
+ ModuleInfoExtended Dependency,
+ ApplicationVersion Version
+) : ModuleVersionMismatchSpecificIssue(Module, Dependency, Version)
+{
+ public override string ToString() =>
+ $"The module '{Module.Id}' requires version {Version} or lower of '{Dependency.Id}', but version {Dependency.Version} is installed";
+
+ public override LegacyModuleIssue ToLegacy() => new(Module, Dependency.Id, ModuleIssueType.VersionMismatchLessThanOrEqual, ToString(), new ApplicationVersionRange(Version, Version));
+}
+
+///
+/// Represents an issue where a dependency's version is less than the minimum required version range.
+/// This occurs when a dependency module's version is below the minimum version specified in a range.
+///
+/// The module with the version requirement
+/// The dependency module that doesn't meet the minimum version
+/// The version range containing the minimum version requirement
+///
+/// This issue occurs when a dependency's version is below the minimum required version range.
+///
+/// Example scenario:
+/// ```xml
+///
+///
+///
+///
+///
+///
+///
+///
+///
+/// ```
+/// If an older version of ButterLib (e.g., v2.8.14) is installed, this issue will be raised.
+///
+#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
+internal
+#else
+public
+# endif
+ sealed record ModuleVersionMismatchLessThanRangeIssue(
+ ModuleInfoExtended Module,
+ ModuleInfoExtended Dependency,
+ ApplicationVersionRange VersionRange
+) : ModuleVersionMismatchRangeIssue(Module, Dependency, VersionRange)
+{
+ public override string ToString() =>
+ $"The module '{Module.Id}' requires '{Dependency.Id}' version {VersionRange}, but version {Dependency.Version} is installed (below minimum)";
+
+ public override LegacyModuleIssue ToLegacy() => new(Module, Dependency.Id, ModuleIssueType.VersionMismatchLessThan, ToString(), VersionRange);
+}
+
+///
+/// Represents an issue where a dependency's version exceeds the maximum allowed version range.
+/// This occurs when a dependency module's version is above the maximum version specified in a range.
+///
+/// The module with the version constraint
+/// The dependency module that exceeds the version limit
+/// The version range containing the maximum version requirement
+///
+/// This issue occurs when a dependency's version exceeds the maximum allowed version range.
+///
+/// Example scenario:
+/// ```xml
+///
+///
+///
+///
+///
+///
+///
+///
+///
+/// ```
+/// If a version of `ModB` that falls within the range is installed, this issue will be raised.
+///
+#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
+internal
+#else
+public
+# endif
+ sealed record ModuleVersionMismatchGreaterThanRangeIssue(
+ ModuleInfoExtended Module,
+ ModuleInfoExtended Dependency,
+ ApplicationVersionRange VersionRange
+) : ModuleVersionMismatchRangeIssue(Module, Dependency, VersionRange)
+{
+ public override string ToString() =>
+ $"The module '{Module.Id}' requires '{Dependency.Id}' version {VersionRange}, but version {Dependency.Version} is installed (above maximum)";
+ public override LegacyModuleIssue ToLegacy() => new(Module, Dependency.Id, ModuleIssueType.VersionMismatchGreaterThan, ToString(), VersionRange);
+}
+
+///
+/// Represents an issue where two modules are incompatible with each other.
+/// This occurs when one module explicitly declares it cannot work with another module.
+///
+/// The module that has declared an incompatibility
+/// The ID of the module that is incompatible with the target
+///
+/// This issue occurs when a module explicitly marks another module as incompatible.
+///
+/// Example scenario:
+/// ```xml
+///
+///
+///
+///
+///
+///
+///
+///
+/// ```
+/// If both `AlternativeArmorSystem` is enabled when `RealisticBattleArmor` is already enabled, this issue will be raised.
+///
+#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
+internal
+#else
+public
+# endif
+ sealed record ModuleIncompatibleIssue(
+ ModuleInfoExtended Module,
+ string IncompatibleModuleId
+) : ModuleIssueV2(Module)
+{
+ public override string ToString() => $"'{IncompatibleModuleId}' is incompatible with this module";
+ public override LegacyModuleIssue ToLegacy() => new(Module, IncompatibleModuleId, ModuleIssueType.Incompatible, ToString(), ApplicationVersionRange.Empty);
+}
+
+///
+/// Represents an issue where a module is both depended upon and marked as incompatible.
+/// This indicates a contradictory configuration where a module is required but also
+/// marked as incompatible.
+///
+/// The module with the conflicting dependency declaration
+/// The ID of the module that is both depended upon and marked incompatible
+///
+/// This issue occurs when a module has conflicting configurations for dependencies.
+///
+/// Example scenario:
+/// ```xml
+///
+///
+///
+///
+///
+///
+///
+///
+///
+///
+///
+///
+/// ```
+/// This is a configuration error as `TroopOverhaul` cannot be both required and incompatible.
+///
+#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
+internal
+#else
+public
+# endif
+ sealed record ModuleDependencyConflictDependentAndIncompatibleIssue(
+ ModuleInfoExtended Module,
+ string ConflictingModuleId
+) : ModuleIssueV2(Module)
+{
+ public override string ToString() => $"Module '{Module.Id}' has conflicting configuration: '{ConflictingModuleId}' is marked as both required and incompatible";
+ public override LegacyModuleIssue ToLegacy() => new(Module, ConflictingModuleId, ModuleIssueType.DependencyConflictDependentAndIncompatible, ToString(), ApplicationVersionRange.Empty);
+}
+
+///
+/// Represents an issue where a module is declared to load both before and after another module.
+/// This indicates a contradictory load order configuration that cannot be satisfied.
+///
+/// The module with the conflicting load order declaration
+/// The module that has conflicting load order requirements
+///
+/// This issue occurs when a module has conflicting load order requirements.
+///
+/// Example scenario:
+/// ```xml
+///
+///
+///
+///
+///
+///
+///
+///
+///
+///
+///
+/// ```
+/// This creates an impossible load order requirement as `ArenaOverhaul` cannot load both before and after `ImprovedTournaments`.
+///
+#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
+internal
+#else
+public
+# endif
+ sealed record ModuleDependencyConflictLoadBeforeAndAfterIssue(
+ ModuleInfoExtended Module,
+ DependentModuleMetadata ConflictingModule
+) : ModuleIssueV2(Module)
+{
+ public override string ToString() => $"Module '{Module.Id}' has conflicting load order requirements with '{ConflictingModule.Id}' (both LoadBefore and LoadAfter)";
+ public override LegacyModuleIssue ToLegacy() => new(Module, ConflictingModule.Id, ModuleIssueType.DependencyConflictDependentLoadBeforeAndAfter, ToString(), ApplicationVersionRange.Empty);
+}
+
+///
+/// Represents an issue where modules have circular dependencies on each other.
+/// This occurs when two or more modules form a dependency cycle that cannot be resolved.
+///
+/// One of the modules in the circular dependency chain
+/// The other module in the circular dependency chain
+///
+/// This issue occurs when modules create a circular dependency chain.
+///
+/// Example scenario:
+/// Two modules depend on each other in a way that creates an unresolvable cycle:
+///
+/// ```xml
+///
+///
+///
+///
+///
+///
+///
+///
+/// ```
+///
+/// ```xml
+///
+///
+///
+///
+///
+///
+///
+///
+/// ```
+///
+/// ❌ This creates an impossible situation where each module must load before the other.
+///
+#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
+internal
+#else
+public
+# endif
+ sealed record ModuleDependencyConflictCircularIssue(
+ ModuleInfoExtended Module,
+ DependentModuleMetadata CircularDependency
+) : ModuleIssueV2(Module)
+{
+ public override string ToString() => $"Module '{Module.Id}' and '{CircularDependency.Id}' have circular dependencies";
+ public override LegacyModuleIssue ToLegacy() => new(Module, CircularDependency.Id, ModuleIssueType.DependencyConflictCircular, ToString(), ApplicationVersionRange.Empty);
+}
+
+///
+/// Represents an issue where a module that should be loaded before the target module is loaded after it.
+/// This indicates a violation of the specified load order requirements.
+///
+/// The module with the load order requirement
+/// The ID of the module that should be loaded before the target
+///
+/// This issue occurs when a required "load before" dependency loads after the specified module.
+///
+/// Example scenario:
+/// ```xml
+///
+///
+///
+///
+///
+///
+///
+///
+///
+/// ```
+/// If `Harmony` is loading after `BetterBattles` in the actual load order, this issue will be raised.
+///
+#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
+internal
+#else
+public
+# endif
+ sealed record ModuleDependencyNotLoadedBeforeIssue(
+ ModuleInfoExtended Module,
+ string DependencyId
+) : ModuleIssueV2(Module)
+{
+ public override string ToString() => $"'{DependencyId}' should be loaded before '{Module.Id}'";
+ public override LegacyModuleIssue ToLegacy() => new(Module, DependencyId, ModuleIssueType.DependencyNotLoadedBeforeThis, ToString(), ApplicationVersionRange.Empty);
+}
+
+///
+/// Represents an issue where a module that should be loaded after the target module is loaded before it.
+/// This indicates a violation of the specified load order requirements.
+///
+/// The module with the load order requirement
+/// The ID of the module that should be loaded after the target
+///
+/// This issue occurs when a required "load after" dependency loads before the specified module.
+///
+/// Example scenario:
+/// ```xml
+///
+///
+///
+///
+///
+///
+///
+///
+///
+/// ```
+/// If `ImprovedGarrisons` is loading before `BetterSettlements`, this issue will be raised.
+///
+#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
+internal
+#else
+public
+# endif
+ sealed record ModuleDependencyNotLoadedAfterIssue(
+ ModuleInfoExtended Module,
+ string DependencyId
+) : ModuleIssueV2(Module)
+{
+ public override string ToString() => $"'{DependencyId}' should be loaded after '{Module.Id}'";
+ public override LegacyModuleIssue ToLegacy() => new(Module, DependencyId, ModuleIssueType.DependencyNotLoadedAfterThis, ToString(), ApplicationVersionRange.Empty);
+}
+
+///
+/// Represents an issue where a module is missing its required module ID.
+/// This is required by every mod.
+///
+/// The module missing its ID
+///
+/// This issue occurs when a module is missing its required Id field.
+///
+/// Example scenario:
+/// ```xml
+///
+///
+///
+///
+/// ```
+/// The Id field is required for module identification and dependency management.
+///
+#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
+internal
+#else
+public
+# endif
+ sealed record ModuleMissingIdIssue(
+ ModuleInfoExtended Module
+) : ModuleIssueV2(Module)
+{
+ public override string ToString() => $"Module with Name '{Module.Name}' is missing its Id field";
+ public override LegacyModuleIssue ToLegacy() => new(Module, "UNKNOWN", ModuleIssueType.MissingModuleId, ToString(), ApplicationVersionRange.Empty);
+}
+
+///
+/// Represents an issue where a module is missing its required name.
+/// This is a required field.
+///
+/// The module missing its name
+///
+/// This issue occurs when a module has a malformed or missing Name field.
+///
+/// Example scenario:
+/// ```xml
+///
+///
+///
+///
+/// ```
+/// The Name field is required for module identification and display purposes.
+///
+#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
+internal
+#else
+public
+# endif
+ sealed record ModuleMissingNameIssue(
+ ModuleInfoExtended Module
+) : ModuleIssueV2(Module)
+{
+ public override string ToString() => $"Module with Id '{Module.Id}' is missing its Name field";
+ public override LegacyModuleIssue ToLegacy() => new(Module, Module.Id, ModuleIssueType.MissingModuleName, ToString(), ApplicationVersionRange.Empty);
+}
+
+///
+/// Represents an issue where a module has a null/empty dependency reference.
+/// This indicates an invalid dependency configuration.
+///
+/// The module with the null dependency
+///
+/// This issue occurs when a dependency entry is malformed or null.
+///
+/// Example scenario:
+/// ```xml
+///
+///
+///
+///
+///
+///
+///
+///
+///
+/// ```
+/// All dependency entries must be properly formed with required attributes.
+///
+#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
+internal
+#else
+public
+# endif
+ sealed record ModuleDependencyNullIssue(
+ ModuleInfoExtended Module
+) : ModuleIssueV2(Module)
+{
+ public override string ToString() => $"Module '{Module.Id}' has a null dependency entry";
+ public override LegacyModuleIssue ToLegacy() => new(Module, "UNKNOWN", ModuleIssueType.DependencyIsNull, ToString(), ApplicationVersionRange.Empty);
+}
+
+///
+/// Represents an issue where a module's dependency is missing its required module ID.
+/// This indicates an invalid or incomplete dependency configuration.
+///
+/// The module with a dependency missing its ID
+///
+/// This issue occurs when a dependency entry is missing its required Id field.
+///
+/// Example scenario:
+/// ```xml
+///
+///
+///
+///
+///
+///
+///
+///
+///
+/// ```
+/// All dependency entries must include an Id to identify the required module.
+///
+#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
+internal
+#else
+public
+# endif
+ sealed record ModuleDependencyMissingIdIssue(
+ ModuleInfoExtended Module
+) : ModuleIssueV2(Module)
+{
+ public override string ToString() => $"Module '{Module.Id}' has a dependency entry missing its Id field";
+ public override LegacyModuleIssue ToLegacy() => new(Module, "UNKNOWN", ModuleIssueType.DependencyMissingModuleId, ToString(), ApplicationVersionRange.Empty);
+}
+
+#nullable restore
+#if !BANNERLORDBUTRMODULEMANAGER_ENABLE_WARNING
+#pragma warning restore
+#endif
\ No newline at end of file
diff --git a/src/Bannerlord.ModuleManager.Models/LoadType.cs b/src/Bannerlord.ModuleManager.Models/LoadType.cs
index deed30f..df87bfc 100644
--- a/src/Bannerlord.ModuleManager.Models/LoadType.cs
+++ b/src/Bannerlord.ModuleManager.Models/LoadType.cs
@@ -1,18 +1,4 @@
-//
-// This code file has automatically been added by the "Bannerlord.ModuleManager.Source" NuGet package (https://www.nuget.org/packages/Bannerlord.ModuleManager.Source).
-// Please see https://github.com/BUTR/Bannerlord.ModuleManager for more information.
-//
-// IMPORTANT:
-// DO NOT DELETE THIS FILE if you are using a "packages.config" file to manage your NuGet references.
-// Consider migrating to PackageReferences instead:
-// https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference
-// Migrating brings the following benefits:
-// * The "Bannerlord.ModuleManager.Source" folder and the "LoadType.cs" file don't appear in your project.
-// * The added file is immutable and can therefore not be modified by coincidence.
-// * Updating/Uninstalling the package will work flawlessly.
-//
-
-#region License
+#region License
// MIT License
//
// Copyright (c) Bannerlord's Unofficial Tools & Resources
@@ -41,26 +27,26 @@
#pragma warning disable
#endif
-namespace Bannerlord.ModuleManager
-{
+namespace Bannerlord.ModuleManager;
+
#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
internal
#else
- public
+public
# endif
- enum LoadType
- {
- None = 0,
- LoadAfterThis = 1,
- LoadBeforeThis = 2
- }
+ enum LoadType
+{
+ None = 0,
+ LoadAfterThis = 1,
+ LoadBeforeThis = 2
+}
- internal enum LoadTypeParse
- {
- LoadAfterThis = 1,
- LoadBeforeThis = 2
- }
+internal enum LoadTypeParse
+{
+ LoadAfterThis = 1,
+ LoadBeforeThis = 2
}
+
#nullable restore
#if !BANNERLORDBUTRMODULEMANAGER_ENABLE_WARNING
#pragma warning restore
diff --git a/src/Bannerlord.ModuleManager.Models/ModuleInfoExtended.cs b/src/Bannerlord.ModuleManager.Models/ModuleInfoExtended.cs
index 6eaacf0..1afe7d8 100644
--- a/src/Bannerlord.ModuleManager.Models/ModuleInfoExtended.cs
+++ b/src/Bannerlord.ModuleManager.Models/ModuleInfoExtended.cs
@@ -1,18 +1,4 @@
-//
-// This code file has automatically been added by the "Bannerlord.ModuleManager.Source" NuGet package (https://www.nuget.org/packages/Bannerlord.ModuleManager.Source).
-// Please see https://github.com/BUTR/Bannerlord.ModuleManager for more information.
-//
-// IMPORTANT:
-// DO NOT DELETE THIS FILE if you are using a "packages.config" file to manage your NuGet references.
-// Consider migrating to PackageReferences instead:
-// https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference
-// Migrating brings the following benefits:
-// * The "Bannerlord.ModuleManager.Source" folder and the "ModuleInfoExtended.cs" file don't appear in your project.
-// * The added file is immutable and can therefore not be modified by coincidence.
-// * Updating/Uninstalling the package will work flawlessly.
-//
-
-#region License
+#region License
// MIT License
//
// Copyright (c) Bannerlord's Unofficial Tools & Resources
@@ -41,269 +27,269 @@
#pragma warning disable
#endif
-namespace Bannerlord.ModuleManager
-{
- using global::System;
- using global::System.Collections.Generic;
- using global::System.Linq;
- using global::System.Xml;
+namespace Bannerlord.ModuleManager;
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Xml;
#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
internal
#else
- public
+public
# endif
- record ModuleInfoExtended
- {
- private static readonly string NativeModuleId = "Native";
- private static readonly string[] OfficialModuleIds = { NativeModuleId, "SandBox", "SandBoxCore", "StoryMode", "CustomBattle", "BirthAndDeath", "Multiplayer" };
+ record ModuleInfoExtended
+{
+ private static readonly string NativeModuleId = "Native";
+ private static readonly string[] OfficialModuleIds = { NativeModuleId, "SandBox", "SandBoxCore", "StoryMode", "CustomBattle", "BirthAndDeath", "Multiplayer" };
- public string Id { get; set; } = string.Empty;
- public string Name { get; set; } = string.Empty;
- public bool IsOfficial { get; set; }
- public ApplicationVersion Version { get; set; } = ApplicationVersion.Empty;
- public bool IsSingleplayerModule { get; set; }
- public bool IsMultiplayerModule { get; set; }
- public bool IsServerModule { get; set; }
- public IReadOnlyList SubModules { get; set; } = Array.Empty();
- public IReadOnlyList DependentModules { get; set; } = Array.Empty();
- public IReadOnlyList ModulesToLoadAfterThis { get; set; } = Array.Empty();
- public IReadOnlyList IncompatibleModules { get; set; } = Array.Empty();
- public string Url { get; set; } = string.Empty;
- public string UpdateInfo { get; set; } = string.Empty;
- public IReadOnlyList DependentModuleMetadatas { get; set; } = Array.Empty();
+ public string Id { get; set; } = string.Empty;
+ public string Name { get; set; } = string.Empty;
+ public bool IsOfficial { get; set; }
+ public ApplicationVersion Version { get; set; } = ApplicationVersion.Empty;
+ public bool IsSingleplayerModule { get; set; }
+ public bool IsMultiplayerModule { get; set; }
+ public bool IsServerModule { get; set; }
+ public IReadOnlyList SubModules { get; set; } = Array.Empty();
+ public IReadOnlyList DependentModules { get; set; } = Array.Empty();
+ public IReadOnlyList ModulesToLoadAfterThis { get; set; } = Array.Empty();
+ public IReadOnlyList IncompatibleModules { get; set; } = Array.Empty();
+ public string Url { get; set; } = string.Empty;
+ public string UpdateInfo { get; set; } = string.Empty;
+ public IReadOnlyList DependentModuleMetadatas { get; set; } = Array.Empty();
#if BANNERLORDBUTRMODULEMANAGER_NULLABLE
- [return: global::System.Diagnostics.CodeAnalysis.NotNullIfNotNull("xmlDocument")]
+ [return: System.Diagnostics.CodeAnalysis.NotNullIfNotNull("xmlDocument")]
#endif
- public static ModuleInfoExtended? FromXml(XmlDocument? xmlDocument)
+ public static ModuleInfoExtended? FromXml(XmlDocument? xmlDocument)
+ {
+ if (xmlDocument is null)
{
- if (xmlDocument is null)
- {
- return null;
- }
+ return null;
+ }
- var moduleNode = xmlDocument.SelectSingleNode("Module");
+ var moduleNode = xmlDocument.SelectSingleNode("Module");
- var id = moduleNode?.SelectSingleNode("Id")?.Attributes?["value"]?.InnerText ?? string.Empty;
- var name = moduleNode?.SelectSingleNode("Name")?.Attributes?["value"]?.InnerText ?? string.Empty;
- ApplicationVersion.TryParse(moduleNode?.SelectSingleNode("Version")?.Attributes?["value"]?.InnerText, out var version);
+ var id = moduleNode?.SelectSingleNode("Id")?.Attributes?["value"]?.InnerText ?? string.Empty;
+ var name = moduleNode?.SelectSingleNode("Name")?.Attributes?["value"]?.InnerText ?? string.Empty;
+ ApplicationVersion.TryParse(moduleNode?.SelectSingleNode("Version")?.Attributes?["value"]?.InnerText, out var version);
- var moduleType = moduleNode?.SelectSingleNode("ModuleType")?.Attributes?["value"].InnerText;
- var isOfficial = moduleNode?.SelectSingleNode("Official")?.Attributes?["value"]?.InnerText.Equals("true") == true ||
- moduleType == "Official" || moduleType == "OfficialOptional";
+ var moduleType = moduleNode?.SelectSingleNode("ModuleType")?.Attributes?["value"].InnerText;
+ var isOfficial = moduleNode?.SelectSingleNode("Official")?.Attributes?["value"]?.InnerText.Equals("true") == true ||
+ moduleType == "Official" || moduleType == "OfficialOptional";
- var moduleCategory = moduleNode?.SelectSingleNode("ModuleCategory")?.Attributes?["value"]?.InnerText;
- var isSingleplayerModule = moduleNode?.SelectSingleNode("SingleplayerModule")?.Attributes?["value"]?.InnerText.Equals("true") == true ||
- moduleCategory == "Singleplayer" || moduleCategory == "SingleplayerOptional";
- var isMultiplayerModule = moduleNode?.SelectSingleNode("MultiplayerModule")?.Attributes?["value"]?.InnerText.Equals("true") == true ||
- moduleCategory == "Multiplayer" || moduleCategory == "MultiplayerOptional";
- var isServerModule = moduleCategory == "Server" || moduleCategory == "ServerOptional";
+ var moduleCategory = moduleNode?.SelectSingleNode("ModuleCategory")?.Attributes?["value"]?.InnerText;
+ var isSingleplayerModule = moduleNode?.SelectSingleNode("SingleplayerModule")?.Attributes?["value"]?.InnerText.Equals("true") == true ||
+ moduleCategory == "Singleplayer" || moduleCategory == "SingleplayerOptional";
+ var isMultiplayerModule = moduleNode?.SelectSingleNode("MultiplayerModule")?.Attributes?["value"]?.InnerText.Equals("true") == true ||
+ moduleCategory == "Multiplayer" || moduleCategory == "MultiplayerOptional";
+ var isServerModule = moduleCategory == "Server" || moduleCategory == "ServerOptional";
- var dependentModulesNode = moduleNode?.SelectSingleNode("DependedModules");
- var dependentModulesList = dependentModulesNode?.SelectNodes("DependedModule");
- var dependentModules = new List(dependentModulesList?.Count ?? 0);
- for (var i = 0; i < dependentModulesList?.Count; i++)
+ var dependentModulesNode = moduleNode?.SelectSingleNode("DependedModules");
+ var dependentModulesList = dependentModulesNode?.SelectNodes("DependedModule");
+ var dependentModules = new List(dependentModulesList?.Count ?? 0);
+ for (var i = 0; i < dependentModulesList?.Count; i++)
+ {
+ if (dependentModulesList?[i]?.Attributes?["Id"] is { } idAttr)
{
- if (dependentModulesList?[i]?.Attributes?["Id"] is { } idAttr)
- {
- ApplicationVersion.TryParse(dependentModulesList[i]?.Attributes?["DependentVersion"]?.InnerText, out var dVersion);
- var isOptional = dependentModulesList[i]?.Attributes?["Optional"] is { } optional && optional.InnerText.Equals("true");
- dependentModules.Add(new DependentModule(idAttr.InnerText, dVersion, isOptional));
- }
+ ApplicationVersion.TryParse(dependentModulesList[i]?.Attributes?["DependentVersion"]?.InnerText, out var dVersion);
+ var isOptional = dependentModulesList[i]?.Attributes?["Optional"] is { } optional && optional.InnerText.Equals("true");
+ dependentModules.Add(new DependentModule(idAttr.InnerText, dVersion, isOptional));
}
+ }
- var modulesToLoadAfterThisNode = moduleNode?.SelectSingleNode("ModulesToLoadAfterThis");
- var modulesToLoadAfterThisList = modulesToLoadAfterThisNode?.SelectNodes("Module");
- var modulesToLoadAfterThis = new List(modulesToLoadAfterThisList?.Count ?? 0);
- for (var i = 0; i < modulesToLoadAfterThisList?.Count; i++)
+ var modulesToLoadAfterThisNode = moduleNode?.SelectSingleNode("ModulesToLoadAfterThis");
+ var modulesToLoadAfterThisList = modulesToLoadAfterThisNode?.SelectNodes("Module");
+ var modulesToLoadAfterThis = new List(modulesToLoadAfterThisList?.Count ?? 0);
+ for (var i = 0; i < modulesToLoadAfterThisList?.Count; i++)
+ {
+ if (modulesToLoadAfterThisList?[i]?.Attributes?["Id"] is { } idAttr)
{
- if (modulesToLoadAfterThisList?[i]?.Attributes?["Id"] is { } idAttr)
+ modulesToLoadAfterThis.Add(new DependentModule
{
- modulesToLoadAfterThis.Add(new DependentModule
- {
- Id = idAttr.InnerText,
- IsOptional = true
- });
- }
+ Id = idAttr.InnerText,
+ IsOptional = true
+ });
}
+ }
- var incompatibleModulesNode = moduleNode?.SelectSingleNode("IncompatibleModules");
- var incompatibleModulesList = incompatibleModulesNode?.SelectNodes("Module");
- var incompatibleModules = new List(incompatibleModulesList?.Count ?? 0);
- for (var i = 0; i < incompatibleModulesList?.Count; i++)
+ var incompatibleModulesNode = moduleNode?.SelectSingleNode("IncompatibleModules");
+ var incompatibleModulesList = incompatibleModulesNode?.SelectNodes("Module");
+ var incompatibleModules = new List(incompatibleModulesList?.Count ?? 0);
+ for (var i = 0; i < incompatibleModulesList?.Count; i++)
+ {
+ if (incompatibleModulesList?[i]?.Attributes?["Id"] is { } idAttr)
{
- if (incompatibleModulesList?[i]?.Attributes?["Id"] is { } idAttr)
+ incompatibleModules.Add(new DependentModule
{
- incompatibleModules.Add(new DependentModule
- {
- Id = idAttr.InnerText,
- IsOptional = true
- });
- }
+ Id = idAttr.InnerText,
+ IsOptional = true
+ });
}
+ }
- var subModulesNode = moduleNode?.SelectSingleNode("SubModules");
- var subModuleList = subModulesNode?.SelectNodes("SubModule");
- var subModules = new List(subModuleList?.Count ?? 0);
- for (var i = 0; i < subModuleList?.Count; i++)
+ var subModulesNode = moduleNode?.SelectSingleNode("SubModules");
+ var subModuleList = subModulesNode?.SelectNodes("SubModule");
+ var subModules = new List(subModuleList?.Count ?? 0);
+ for (var i = 0; i < subModuleList?.Count; i++)
+ {
+ if (SubModuleInfoExtended.FromXml(subModuleList?[i]) is { } subModule)
{
- if (SubModuleInfoExtended.FromXml(subModuleList?[i]) is { } subModule)
- {
- subModules.Add(subModule);
- }
+ subModules.Add(subModule);
}
+ }
- // Custom data
- //
- var url = moduleNode?.SelectSingleNode("Url")?.Attributes?["value"]?.InnerText ?? string.Empty;
+ // Custom data
+ //
+ var url = moduleNode?.SelectSingleNode("Url")?.Attributes?["value"]?.InnerText ?? string.Empty;
- var updateInfo = moduleNode?.SelectSingleNode("UpdateInfo")?.Attributes?["value"]?.InnerText ?? string.Empty;
+ var updateInfo = moduleNode?.SelectSingleNode("UpdateInfo")?.Attributes?["value"]?.InnerText ?? string.Empty;
- var dependentModuleMetadatasNode = moduleNode?.SelectSingleNode("DependedModuleMetadatas");
- var dependentModuleMetadatasList = dependentModuleMetadatasNode?.SelectNodes("DependedModuleMetadata");
+ var dependentModuleMetadatasNode = moduleNode?.SelectSingleNode("DependedModuleMetadatas");
+ var dependentModuleMetadatasList = dependentModuleMetadatasNode?.SelectNodes("DependedModuleMetadata");
- // Fixed Launcher supported optional tag
- var loadAfterModules = moduleNode?.SelectSingleNode("LoadAfterModules");
- var loadAfterModuleList = loadAfterModules?.SelectNodes("LoadAfterModule");
+ // Fixed Launcher supported optional tag
+ var loadAfterModules = moduleNode?.SelectSingleNode("LoadAfterModules");
+ var loadAfterModuleList = loadAfterModules?.SelectNodes("LoadAfterModule");
- // Bannerlord Launcher supported optional tag
- var optionalDependentModules = moduleNode?.SelectSingleNode("OptionalDependModules");
- var optionalDependentModuleList =
- (dependentModulesNode?.SelectNodes("OptionalDependModule")?.Cast() ?? Enumerable.Empty())
- .Concat(optionalDependentModules?.SelectNodes("OptionalDependModule")?.Cast() ?? Enumerable.Empty())
- .Concat(optionalDependentModules?.SelectNodes("DependModule")?.Cast() ?? Enumerable.Empty()).ToList();
+ // Bannerlord Launcher supported optional tag
+ var optionalDependentModules = moduleNode?.SelectSingleNode("OptionalDependModules");
+ var optionalDependentModuleList =
+ (dependentModulesNode?.SelectNodes("OptionalDependModule")?.Cast() ?? Enumerable.Empty())
+ .Concat(optionalDependentModules?.SelectNodes("OptionalDependModule")?.Cast() ?? Enumerable.Empty())
+ .Concat(optionalDependentModules?.SelectNodes("DependModule")?.Cast() ?? Enumerable.Empty()).ToList();
- var dependentModuleMetadatas = new List(dependentModuleMetadatasList?.Count ?? 0 + loadAfterModuleList?.Count ?? 0 + optionalDependentModuleList.Count);
- for (var i = 0; i < dependentModuleMetadatasList?.Count; i++)
+ var dependentModuleMetadatas = new List(dependentModuleMetadatasList?.Count ?? 0 + loadAfterModuleList?.Count ?? 0 + optionalDependentModuleList.Count);
+ for (var i = 0; i < dependentModuleMetadatasList?.Count; i++)
+ {
+ if (dependentModuleMetadatasList?[i]?.Attributes?["id"] is { } idAttr)
{
- if (dependentModuleMetadatasList?[i]?.Attributes?["id"] is { } idAttr)
+ var order = dependentModuleMetadatasList[i]?.Attributes?["order"] is { } orderAttr && Enum.TryParse(orderAttr.InnerText, out var loadType) ? (LoadType) loadType : LoadType.None;
+ var optional = dependentModuleMetadatasList[i]?.Attributes?["optional"]?.InnerText.Equals("true") ?? false;
+ var incompatible = dependentModuleMetadatasList[i]?.Attributes?["incompatible"]?.InnerText.Equals("true") ?? false;
+ var dVersion = ApplicationVersion.TryParse(dependentModuleMetadatasList[i]?.Attributes?["version"]?.InnerText, out var v) ? v : ApplicationVersion.Empty;
+ var dVersionRange = ApplicationVersionRange.TryParse(dependentModuleMetadatasList[i]?.Attributes?["version"]?.InnerText ?? string.Empty, out var vr) ? vr : ApplicationVersionRange.Empty;
+ dependentModuleMetadatas.Add(new DependentModuleMetadata
{
- var order = dependentModuleMetadatasList[i]?.Attributes?["order"] is { } orderAttr && Enum.TryParse(orderAttr.InnerText, out var loadType) ? (LoadType) loadType : LoadType.None;
- var optional = dependentModuleMetadatasList[i]?.Attributes?["optional"]?.InnerText.Equals("true") ?? false;
- var incompatible = dependentModuleMetadatasList[i]?.Attributes?["incompatible"]?.InnerText.Equals("true") ?? false;
- var dVersion = ApplicationVersion.TryParse(dependentModuleMetadatasList[i]?.Attributes?["version"]?.InnerText, out var v) ? v : ApplicationVersion.Empty;
- var dVersionRange = ApplicationVersionRange.TryParse(dependentModuleMetadatasList[i]?.Attributes?["version"]?.InnerText ?? string.Empty, out var vr) ? vr : ApplicationVersionRange.Empty;
- dependentModuleMetadatas.Add(new DependentModuleMetadata
- {
- Id = idAttr.InnerText,
- LoadType = (LoadType) order,
- IsOptional = optional,
- IsIncompatible = incompatible,
- Version = dVersion,
- VersionRange = dVersionRange
- });
- }
+ Id = idAttr.InnerText,
+ LoadType = (LoadType) order,
+ IsOptional = optional,
+ IsIncompatible = incompatible,
+ Version = dVersion,
+ VersionRange = dVersionRange
+ });
}
- for (var i = 0; i < loadAfterModuleList?.Count; i++)
+ }
+ for (var i = 0; i < loadAfterModuleList?.Count; i++)
+ {
+ if (loadAfterModuleList?[i]?.Attributes?["Id"] is { } idAttr)
{
- if (loadAfterModuleList?[i]?.Attributes?["Id"] is { } idAttr)
+ dependentModuleMetadatas.Add(new DependentModuleMetadata
{
- dependentModuleMetadatas.Add(new DependentModuleMetadata
- {
- Id = idAttr.InnerText,
- LoadType = LoadType.LoadAfterThis,
- IsOptional = false,
- IsIncompatible = false,
- Version = ApplicationVersion.Empty,
- VersionRange = ApplicationVersionRange.Empty
- });
- }
+ Id = idAttr.InnerText,
+ LoadType = LoadType.LoadAfterThis,
+ IsOptional = false,
+ IsIncompatible = false,
+ Version = ApplicationVersion.Empty,
+ VersionRange = ApplicationVersionRange.Empty
+ });
}
- for (var i = 0; i < optionalDependentModuleList.Count; i++)
+ }
+ for (var i = 0; i < optionalDependentModuleList.Count; i++)
+ {
+ if (optionalDependentModuleList[i].Attributes?["Id"] is { } idAttr)
{
- if (optionalDependentModuleList[i].Attributes?["Id"] is { } idAttr)
+ dependentModuleMetadatas.Add(new DependentModuleMetadata
{
- dependentModuleMetadatas.Add(new DependentModuleMetadata
- {
- Id = idAttr.InnerText,
- LoadType = LoadType.None,
- IsOptional = true,
- IsIncompatible = false,
- Version = ApplicationVersion.Empty,
- VersionRange = ApplicationVersionRange.Empty
- });
- }
+ Id = idAttr.InnerText,
+ LoadType = LoadType.None,
+ IsOptional = true,
+ IsIncompatible = false,
+ Version = ApplicationVersion.Empty,
+ VersionRange = ApplicationVersionRange.Empty
+ });
}
+ }
- var requiredGameVersion = moduleNode?.SelectSingleNode("RequiredGameVersion");
- var requiredGameVersionVal = requiredGameVersion?.Attributes?["value"]?.InnerText ?? string.Empty;
- var requiredGameVersionOptional = requiredGameVersion?.Attributes?["optional"]?.InnerText.Equals("true") == true;
- if (!string.IsNullOrWhiteSpace(requiredGameVersionVal) && ApplicationVersion.TryParse(requiredGameVersionVal, out var gameVersion))
+ var requiredGameVersion = moduleNode?.SelectSingleNode("RequiredGameVersion");
+ var requiredGameVersionVal = requiredGameVersion?.Attributes?["value"]?.InnerText ?? string.Empty;
+ var requiredGameVersionOptional = requiredGameVersion?.Attributes?["optional"]?.InnerText.Equals("true") == true;
+ if (!string.IsNullOrWhiteSpace(requiredGameVersionVal) && ApplicationVersion.TryParse(requiredGameVersionVal, out var gameVersion))
+ {
+ foreach (var moduleId in OfficialModuleIds)
{
- foreach (var moduleId in OfficialModuleIds)
- {
- var isNative = moduleId.Equals(NativeModuleId);
+ var isNative = moduleId.Equals(NativeModuleId);
- // Override any existing metadata
- if (dependentModuleMetadatas.Find(dmm => moduleId.Equals(dmm.Id, StringComparison.Ordinal)) is { } module)
- {
- dependentModuleMetadatas.Remove(module);
- }
-
- dependentModuleMetadatas.Add(new DependentModuleMetadata
- {
- Id = moduleId,
- LoadType = LoadType.LoadBeforeThis,
- IsOptional = requiredGameVersionOptional && !isNative,
- IsIncompatible = false,
- Version = gameVersion,
- VersionRange = ApplicationVersionRange.Empty
- });
+ // Override any existing metadata
+ if (dependentModuleMetadatas.Find(dmm => moduleId.Equals(dmm.Id, StringComparison.Ordinal)) is { } module)
+ {
+ dependentModuleMetadatas.Remove(module);
}
- }
- return new ModuleInfoExtended
- {
- Id = id,
- Name = name,
- IsOfficial = isOfficial,
- Version = version,
- IsSingleplayerModule = isSingleplayerModule,
- IsMultiplayerModule = isMultiplayerModule,
- IsServerModule = isServerModule,
- SubModules = subModules,
- DependentModules = dependentModules,
- ModulesToLoadAfterThis = modulesToLoadAfterThis,
- IncompatibleModules = incompatibleModules,
- Url = url,
- UpdateInfo = !string.IsNullOrEmpty(updateInfo) ? updateInfo : string.Empty,
- DependentModuleMetadatas = dependentModuleMetadatas
- };
+ dependentModuleMetadatas.Add(new DependentModuleMetadata
+ {
+ Id = moduleId,
+ LoadType = LoadType.LoadBeforeThis,
+ IsOptional = requiredGameVersionOptional && !isNative,
+ IsIncompatible = false,
+ Version = gameVersion,
+ VersionRange = ApplicationVersionRange.Empty
+ });
+ }
}
- public ModuleInfoExtended() { }
- public ModuleInfoExtended(string id, string name, bool isOfficial, ApplicationVersion version, bool isSingleplayerModule, bool isMultiplayerModule,
- IReadOnlyList subModules, IReadOnlyList dependentModules, IReadOnlyList modulesToLoadAfterThis,
- IReadOnlyList incompatibleModules, IReadOnlyList dependentModuleMetadatas, string url)
+ return new ModuleInfoExtended
{
- Id = id;
- Name = name;
- IsOfficial = isOfficial;
- Version = version;
- IsSingleplayerModule = isSingleplayerModule;
- IsMultiplayerModule = isMultiplayerModule;
- SubModules = subModules;
- DependentModules = dependentModules;
- ModulesToLoadAfterThis = modulesToLoadAfterThis;
- IncompatibleModules = incompatibleModules;
- DependentModuleMetadatas = dependentModuleMetadatas;
- Url = url;
- }
+ Id = id,
+ Name = name,
+ IsOfficial = isOfficial,
+ Version = version,
+ IsSingleplayerModule = isSingleplayerModule,
+ IsMultiplayerModule = isMultiplayerModule,
+ IsServerModule = isServerModule,
+ SubModules = subModules,
+ DependentModules = dependentModules,
+ ModulesToLoadAfterThis = modulesToLoadAfterThis,
+ IncompatibleModules = incompatibleModules,
+ Url = url,
+ UpdateInfo = !string.IsNullOrEmpty(updateInfo) ? updateInfo : string.Empty,
+ DependentModuleMetadatas = dependentModuleMetadatas
+ };
+ }
+
+ public ModuleInfoExtended() { }
+ public ModuleInfoExtended(string id, string name, bool isOfficial, ApplicationVersion version, bool isSingleplayerModule, bool isMultiplayerModule,
+ IReadOnlyList subModules, IReadOnlyList dependentModules, IReadOnlyList modulesToLoadAfterThis,
+ IReadOnlyList incompatibleModules, IReadOnlyList dependentModuleMetadatas, string url)
+ {
+ Id = id;
+ Name = name;
+ IsOfficial = isOfficial;
+ Version = version;
+ IsSingleplayerModule = isSingleplayerModule;
+ IsMultiplayerModule = isMultiplayerModule;
+ SubModules = subModules;
+ DependentModules = dependentModules;
+ ModulesToLoadAfterThis = modulesToLoadAfterThis;
+ IncompatibleModules = incompatibleModules;
+ DependentModuleMetadatas = dependentModuleMetadatas;
+ Url = url;
+ }
- public bool IsNative() => NativeModuleId.Equals(Id, StringComparison.OrdinalIgnoreCase);
+ public bool IsNative() => NativeModuleId.Equals(Id, StringComparison.OrdinalIgnoreCase);
- public override string ToString() => $"{Id} - {Version}";
+ public override string ToString() => $"{Id} - {Version}";
- public virtual bool Equals(ModuleInfoExtended? other)
- {
- if (other is null) return false;
- if (ReferenceEquals(this, other)) return true;
- return Id == other.Id;
- }
- public override int GetHashCode() => Id.GetHashCode();
+ public virtual bool Equals(ModuleInfoExtended? other)
+ {
+ if (other is null) return false;
+ if (ReferenceEquals(this, other)) return true;
+ return Id == other.Id;
}
+ public override int GetHashCode() => Id.GetHashCode();
}
+
#nullable restore
#if !BANNERLORDBUTRMODULEMANAGER_ENABLE_WARNING
#pragma warning restore
diff --git a/src/Bannerlord.ModuleManager.Models/ModuleIssue.cs b/src/Bannerlord.ModuleManager.Models/ModuleIssue.cs
index 3901c71..0d3378e 100644
--- a/src/Bannerlord.ModuleManager.Models/ModuleIssue.cs
+++ b/src/Bannerlord.ModuleManager.Models/ModuleIssue.cs
@@ -1,18 +1,4 @@
-//
-// This code file has automatically been added by the "Bannerlord.ModuleManager.Source" NuGet package (https://www.nuget.org/packages/Bannerlord.ModuleManager.Source).
-// Please see https://github.com/BUTR/Bannerlord.ModuleManager for more information.
-//
-// IMPORTANT:
-// DO NOT DELETE THIS FILE if you are using a "packages.config" file to manage your NuGet references.
-// Consider migrating to PackageReferences instead:
-// https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference
-// Migrating brings the following benefits:
-// * The "Bannerlord.ModuleManager.Source" folder and the "ModuleIssue.cs" file don't appear in your project.
-// * The added file is immutable and can therefore not be modified by coincidence.
-// * Updating/Uninstalling the package will work flawlessly.
-//
-
-#region License
+#region License
// MIT License
//
// Copyright (c) Bannerlord's Unofficial Tools & Resources
@@ -41,48 +27,44 @@
#pragma warning disable
#endif
-namespace Bannerlord.ModuleManager
-{
- using global::System;
- using global::System.Collections.Generic;
- using global::System.Linq;
+namespace Bannerlord.ModuleManager;
#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
internal
#else
- public
+public
# endif
- sealed record ModuleIssue
- {
- public ModuleInfoExtended Target { get; set; }
- public string SourceId { get; set; }
- public ModuleIssueType Type { get; set; }
- public string Reason { get; set; }
- public ApplicationVersionRange SourceVersion { get; set; }
+ sealed record ModuleIssue
+{
+ public ModuleInfoExtended Target { get; set; }
+ public string SourceId { get; set; }
+ public ModuleIssueType Type { get; set; }
+ public string Reason { get; set; }
+ public ApplicationVersionRange SourceVersion { get; set; }
- public ModuleIssue()
- {
- Target = new();
- SourceId = string.Empty;
- Type = ModuleIssueType.NONE;
- Reason = string.Empty;
- SourceVersion = ApplicationVersionRange.Empty;
- }
- public ModuleIssue(ModuleInfoExtended target, string sourceId, ModuleIssueType type)
- {
- Target = target;
- SourceId = sourceId;
- Type = type;
- Reason = string.Empty;
- SourceVersion = ApplicationVersionRange.Empty;
- }
- public ModuleIssue(ModuleInfoExtended target, string sourceId, ModuleIssueType type, string reason, ApplicationVersionRange sourceVersion) : this(target, sourceId, type)
- {
- Reason = reason;
- SourceVersion = sourceVersion;
- }
+ public ModuleIssue()
+ {
+ Target = new();
+ SourceId = string.Empty;
+ Type = ModuleIssueType.NONE;
+ Reason = string.Empty;
+ SourceVersion = ApplicationVersionRange.Empty;
+ }
+ public ModuleIssue(ModuleInfoExtended target, string sourceId, ModuleIssueType type)
+ {
+ Target = target;
+ SourceId = sourceId;
+ Type = type;
+ Reason = string.Empty;
+ SourceVersion = ApplicationVersionRange.Empty;
+ }
+ public ModuleIssue(ModuleInfoExtended target, string sourceId, ModuleIssueType type, string reason, ApplicationVersionRange sourceVersion) : this(target, sourceId, type)
+ {
+ Reason = reason;
+ SourceVersion = sourceVersion;
}
}
+
#nullable restore
#if !BANNERLORDBUTRMODULEMANAGER_ENABLE_WARNING
#pragma warning restore
diff --git a/src/Bannerlord.ModuleManager.Models/ModuleIssueType.cs b/src/Bannerlord.ModuleManager.Models/ModuleIssueType.cs
index fe81e54..5048785 100644
--- a/src/Bannerlord.ModuleManager.Models/ModuleIssueType.cs
+++ b/src/Bannerlord.ModuleManager.Models/ModuleIssueType.cs
@@ -1,18 +1,4 @@
-//
-// This code file has automatically been added by the "Bannerlord.ModuleManager.Source" NuGet package (https://www.nuget.org/packages/Bannerlord.ModuleManager.Source).
-// Please see https://github.com/BUTR/Bannerlord.ModuleManager for more information.
-//
-// IMPORTANT:
-// DO NOT DELETE THIS FILE if you are using a "packages.config" file to manage your NuGet references.
-// Consider migrating to PackageReferences instead:
-// https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference
-// Migrating brings the following benefits:
-// * The "Bannerlord.ModuleManager.Source" folder and the "ModuleIssueType.cs" file don't appear in your project.
-// * The added file is immutable and can therefore not be modified by coincidence.
-// * Updating/Uninstalling the package will work flawlessly.
-//
-
-#region License
+#region License
// MIT License
//
// Copyright (c) Bannerlord's Unofficial Tools & Resources
@@ -41,41 +27,37 @@
#pragma warning disable
#endif
-namespace Bannerlord.ModuleManager
-{
- using global::System;
- using global::System.Collections.Generic;
- using global::System.Linq;
+namespace Bannerlord.ModuleManager;
#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
internal
#else
- public
+public
# endif
- enum ModuleIssueType
- {
- NONE,
- Missing,
- MissingDependencies,
- DependencyMissingDependencies,
- DependencyValidationError,
- VersionMismatchLessThanOrEqual,
- VersionMismatchLessThan,
- VersionMismatchGreaterThan,
- Incompatible,
- DependencyConflictDependentAndIncompatible,
- DependencyConflictDependentLoadBeforeAndAfter,
- DependencyConflictCircular,
+ enum ModuleIssueType
+{
+ NONE,
+ Missing,
+ MissingDependencies,
+ DependencyMissingDependencies,
+ DependencyValidationError,
+ VersionMismatchLessThanOrEqual,
+ VersionMismatchLessThan,
+ VersionMismatchGreaterThan,
+ Incompatible,
+ DependencyConflictDependentAndIncompatible,
+ DependencyConflictDependentLoadBeforeAndAfter,
+ DependencyConflictCircular,
- DependencyNotLoadedBeforeThis,
- DependencyNotLoadedAfterThis,
+ DependencyNotLoadedBeforeThis,
+ DependencyNotLoadedAfterThis,
- MissingModuleId,
- MissingModuleName,
- DependencyIsNull,
- DependencyMissingModuleId,
- }
+ MissingModuleId,
+ MissingModuleName,
+ DependencyIsNull,
+ DependencyMissingModuleId,
}
+
#nullable restore
#if !BANNERLORDBUTRMODULEMANAGER_ENABLE_WARNING
#pragma warning restore
diff --git a/src/Bannerlord.ModuleManager.Models/SubModuleInfoExtended.cs b/src/Bannerlord.ModuleManager.Models/SubModuleInfoExtended.cs
index fcd89a0..6b37f31 100644
--- a/src/Bannerlord.ModuleManager.Models/SubModuleInfoExtended.cs
+++ b/src/Bannerlord.ModuleManager.Models/SubModuleInfoExtended.cs
@@ -1,18 +1,4 @@
-//
-// This code file has automatically been added by the "Bannerlord.ModuleManager.Source" NuGet package (https://www.nuget.org/packages/Bannerlord.ModuleManager.Source).
-// Please see https://github.com/BUTR/Bannerlord.ModuleManager for more information.
-//
-// IMPORTANT:
-// DO NOT DELETE THIS FILE if you are using a "packages.config" file to manage your NuGet references.
-// Consider migrating to PackageReferences instead:
-// https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference
-// Migrating brings the following benefits:
-// * The "Bannerlord.ModuleManager.Source" folder and the "SubModuleInfoExtended.cs" file don't appear in your project.
-// * The added file is immutable and can therefore not be modified by coincidence.
-// * Updating/Uninstalling the package will work flawlessly.
-//
-
-#region License
+#region License
// MIT License
//
// Copyright (c) Bannerlord's Unofficial Tools & Resources
@@ -41,97 +27,97 @@
#pragma warning disable
#endif
-namespace Bannerlord.ModuleManager
-{
- using global::System;
- using global::System.Collections.Generic;
- using global::System.Collections.ObjectModel;
- using global::System.Linq;
- using global::System.Xml;
+namespace Bannerlord.ModuleManager;
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Xml;
#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
internal
#else
- public
+public
# endif
- record SubModuleInfoExtended
- {
- public string Name { get; set; } = string.Empty;
- public string DLLName { get; set; } = string.Empty;
- public IReadOnlyList Assemblies { get; set; } = Array.Empty();
- public string SubModuleClassType { get; set; } = string.Empty;
- public IReadOnlyDictionary> Tags { get; set; } = new Dictionary>();
+ record SubModuleInfoExtended
+{
+ public string Name { get; set; } = string.Empty;
+ public string DLLName { get; set; } = string.Empty;
+ public IReadOnlyList Assemblies { get; set; } = Array.Empty();
+ public string SubModuleClassType { get; set; } = string.Empty;
+ public IReadOnlyDictionary> Tags { get; set; } = new Dictionary>();
- public SubModuleInfoExtended() { }
- public SubModuleInfoExtended(string name, string dllName, IReadOnlyList assemblies, string subModuleClassType, IReadOnlyDictionary> tags)
- {
- Name = name;
- DLLName = dllName;
- Assemblies = assemblies;
- SubModuleClassType = subModuleClassType;
- Tags = tags;
- }
+ public SubModuleInfoExtended() { }
+ public SubModuleInfoExtended(string name, string dllName, IReadOnlyList assemblies, string subModuleClassType, IReadOnlyDictionary> tags)
+ {
+ Name = name;
+ DLLName = dllName;
+ Assemblies = assemblies;
+ SubModuleClassType = subModuleClassType;
+ Tags = tags;
+ }
#if BANNERLORDBUTRMODULEMANAGER_NULLABLE
- [return: global::System.Diagnostics.CodeAnalysis.NotNullIfNotNull("xmlDocument")]
+ [return: System.Diagnostics.CodeAnalysis.NotNullIfNotNull("xmlDocument")]
#endif
- public static SubModuleInfoExtended? FromXml(XmlNode? subModuleNode)
- {
- if (subModuleNode is null) return null;
+ public static SubModuleInfoExtended? FromXml(XmlNode? subModuleNode)
+ {
+ if (subModuleNode is null) return null;
- var name = subModuleNode.SelectSingleNode("Name")?.Attributes?["value"]?.InnerText ?? string.Empty;
- var dllName = subModuleNode.SelectSingleNode("DLLName")?.Attributes?["value"]?.InnerText ?? string.Empty;
+ var name = subModuleNode.SelectSingleNode("Name")?.Attributes?["value"]?.InnerText ?? string.Empty;
+ var dllName = subModuleNode.SelectSingleNode("DLLName")?.Attributes?["value"]?.InnerText ?? string.Empty;
- var subModuleClassType = subModuleNode.SelectSingleNode("SubModuleClassType")?.Attributes?["value"]?.InnerText ?? string.Empty;
- var assemblies = Array.Empty();
- if (subModuleNode.SelectSingleNode("Assemblies") != null)
+ var subModuleClassType = subModuleNode.SelectSingleNode("SubModuleClassType")?.Attributes?["value"]?.InnerText ?? string.Empty;
+ var assemblies = Array.Empty();
+ if (subModuleNode.SelectSingleNode("Assemblies") != null)
+ {
+ var assembliesList = subModuleNode.SelectSingleNode("Assemblies")?.SelectNodes("Assembly");
+ assemblies = new string[assembliesList?.Count ?? 0];
+ for (var i = 0; i < assembliesList?.Count; i++)
{
- var assembliesList = subModuleNode.SelectSingleNode("Assemblies")?.SelectNodes("Assembly");
- assemblies = new string[assembliesList?.Count ?? 0];
- for (var i = 0; i < assembliesList?.Count; i++)
- {
- assemblies[i] = assembliesList?[i]?.Attributes?["value"]?.InnerText is { } value ? value : string.Empty;
- }
+ assemblies[i] = assembliesList?[i]?.Attributes?["value"]?.InnerText is { } value ? value : string.Empty;
}
+ }
- var tagsList = subModuleNode.SelectSingleNode("Tags")?.SelectNodes("Tag");
- var tags = new Dictionary>();
- for (var i = 0; i < tagsList?.Count; i++)
+ var tagsList = subModuleNode.SelectSingleNode("Tags")?.SelectNodes("Tag");
+ var tags = new Dictionary>();
+ for (var i = 0; i < tagsList?.Count; i++)
+ {
+ if (tagsList?[i]?.Attributes?["key"]?.InnerText is { } key && tagsList[i]?.Attributes?["value"]?.InnerText is { } value)
{
- if (tagsList?[i]?.Attributes?["key"]?.InnerText is { } key && tagsList[i]?.Attributes?["value"]?.InnerText is { } value)
+ if (tags.TryGetValue(key, out var list))
{
- if (tags.TryGetValue(key, out var list))
- {
- list.Add(value);
- }
- else
- {
- tags[key] = new List { value };
- }
+ list.Add(value);
+ }
+ else
+ {
+ tags[key] = new List { value };
}
}
-
- return new SubModuleInfoExtended
- {
- Name = name,
- DLLName = dllName,
- Assemblies = assemblies,
- SubModuleClassType = subModuleClassType,
- Tags = new ReadOnlyDictionary>(tags.ToDictionary(x => x.Key, x => new ReadOnlyCollection(x.Value) as IReadOnlyList))
- };
}
- public override string ToString() => $"{Name} - {DLLName}";
-
- public virtual bool Equals(SubModuleInfoExtended? other)
+ return new SubModuleInfoExtended
{
- if (other is null) return false;
- if (ReferenceEquals(this, other)) return true;
- return Name == other.Name;
- }
- public override int GetHashCode() => Name.GetHashCode();
+ Name = name,
+ DLLName = dllName,
+ Assemblies = assemblies,
+ SubModuleClassType = subModuleClassType,
+ Tags = new ReadOnlyDictionary>(tags.ToDictionary(x => x.Key, x => new ReadOnlyCollection(x.Value) as IReadOnlyList))
+ };
}
+
+ public override string ToString() => $"{Name} - {DLLName}";
+
+ public virtual bool Equals(SubModuleInfoExtended? other)
+ {
+ if (other is null) return false;
+ if (ReferenceEquals(this, other)) return true;
+ return Name == other.Name;
+ }
+ public override int GetHashCode() => Name.GetHashCode();
}
+
#nullable restore
#if !BANNERLORDBUTRMODULEMANAGER_ENABLE_WARNING
#pragma warning restore
diff --git a/src/Bannerlord.ModuleManager.Models/SubModuleTags.cs b/src/Bannerlord.ModuleManager.Models/SubModuleTags.cs
index 70f7237..d178f91 100644
--- a/src/Bannerlord.ModuleManager.Models/SubModuleTags.cs
+++ b/src/Bannerlord.ModuleManager.Models/SubModuleTags.cs
@@ -1,18 +1,4 @@
-//
-// This code file has automatically been added by the "Bannerlord.ModuleManager.Source" NuGet package (https://www.nuget.org/packages/Bannerlord.ModuleManager.Source).
-// Please see https://github.com/BUTR/Bannerlord.ModuleManager for more information.
-//
-// IMPORTANT:
-// DO NOT DELETE THIS FILE if you are using a "packages.config" file to manage your NuGet references.
-// Consider migrating to PackageReferences instead:
-// https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference
-// Migrating brings the following benefits:
-// * The "Bannerlord.ModuleManager.Source" folder and the "SubModuleTags.cs" file don't appear in your project.
-// * The added file is immutable and can therefore not be modified by coincidence.
-// * Updating/Uninstalling the package will work flawlessly.
-//
-
-#region License
+#region License
// MIT License
//
// Copyright (c) Bannerlord's Unofficial Tools & Resources
@@ -41,24 +27,24 @@
#pragma warning disable
#endif
-namespace Bannerlord.ModuleManager
-{
+namespace Bannerlord.ModuleManager;
+
#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
internal
#else
- public
+public
# endif
- enum SubModuleTags
- {
- RejectedPlatform,
- ExclusivePlatform,
- DedicatedServerType,
- IsNoRenderModeElement,
- DependantRuntimeLibrary,
- PlayerHostedDedicatedServer,
- EngineType
- }
+ enum SubModuleTags
+{
+ RejectedPlatform,
+ ExclusivePlatform,
+ DedicatedServerType,
+ IsNoRenderModeElement,
+ DependantRuntimeLibrary,
+ PlayerHostedDedicatedServer,
+ EngineType
}
+
#nullable restore
#if !BANNERLORDBUTRMODULEMANAGER_ENABLE_WARNING
#pragma warning restore
diff --git a/src/Bannerlord.ModuleManager.Source/Bannerlord.ModuleManager.Source.csproj b/src/Bannerlord.ModuleManager.Source/Bannerlord.ModuleManager.Source.csproj
index de9b701..ef309f2 100644
--- a/src/Bannerlord.ModuleManager.Source/Bannerlord.ModuleManager.Source.csproj
+++ b/src/Bannerlord.ModuleManager.Source/Bannerlord.ModuleManager.Source.csproj
@@ -1,9 +1,8 @@
-
+
netstandard2.0
10.0
- enable
$(DefineConstants);BANNERLORDBUTRMODULEMANAGER_PUBLIC;BANNERLORDBUTRMODULEMANAGER_ENABLE_WARNING;BANNERLORDBUTRMODULEMANAGER_NULLABLE;
Bannerlord.ModuleManager
@@ -38,18 +37,20 @@
-
-
+
+
+
+
diff --git a/src/Bannerlord.ModuleManager.Tests/ModuleStorageTests.cs b/src/Bannerlord.ModuleManager.Tests/ModuleStorageTests.cs
index d16a8e4..0b17ed3 100644
--- a/src/Bannerlord.ModuleManager.Tests/ModuleStorageTests.cs
+++ b/src/Bannerlord.ModuleManager.Tests/ModuleStorageTests.cs
@@ -162,7 +162,7 @@ public void Test_Main()
Assert.That(validationResult1, Is.Empty, () => string.Join(", ", validationResult1?.Select(x => x.Reason) ?? Enumerable.Empty()));
var validationResult2 = ModuleUtilities.ValidateModule(unsortedInvalid, invalid, validationManager.IsSelected).ToArray();
- Assert.That(validationResult2, Has.Length.EqualTo(1), () => string.Join(", ", validationResult2?.Select(x => x.Reason) ?? Enumerable.Empty()));
+ Assert.That(validationResult2, Has.Length.EqualTo(2), () => string.Join(", ", validationResult2?.Select(x => x.Reason) ?? Enumerable.Empty()));
var enableDisableManager = new EnableDisableManager();
ModuleUtilities.EnableModule(unsorted, uiExtenderEx, enableDisableManager.GetSelected, enableDisableManager.SetSelected, enableDisableManager.GetDisabled, enableDisableManager.SetDisabled);
diff --git a/src/Bannerlord.ModuleManager/AlphanumComparatorFast.cs b/src/Bannerlord.ModuleManager/AlphanumComparatorFast.cs
index 17f1749..f73105e 100644
--- a/src/Bannerlord.ModuleManager/AlphanumComparatorFast.cs
+++ b/src/Bannerlord.ModuleManager/AlphanumComparatorFast.cs
@@ -1,18 +1,4 @@
-//
-// This code file has automatically been added by the "Bannerlord.ModuleManager.Source" NuGet package (https://www.nuget.org/packages/Bannerlord.ModuleManager.Source).
-// Please see https://github.com/BUTR/Bannerlord.ModuleManager for more information.
-//
-// IMPORTANT:
-// DO NOT DELETE THIS FILE if you are using a "packages.config" file to manage your NuGet references.
-// Consider migrating to PackageReferences instead:
-// https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference
-// Migrating brings the following benefits:
-// * The "Bannerlord.ModuleManager.Source" folder and the "AlphanumComparatorFast.cs" file don't appear in your project.
-// * The added file is immutable and can therefore not be modified by coincidence.
-// * Updating/Uninstalling the package will work flawlessly.
-//
-
-#region License
+#region License
// MIT License
//
// Copyright (c) Bannerlord's Unofficial Tools & Resources
@@ -41,104 +27,104 @@
#pragma warning disable
#endif
-namespace Bannerlord.ModuleManager
+namespace Bannerlord.ModuleManager;
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+
+///
+/// Alphanumeric sort. This sorting algorithm logically handles numbers in strings. It makes sense to humans.
+/// Highway names like 50F and 100F will be sorted wrongly with ASCII sort.
+/// It is different from alphabetic, ASCII or numeric sorting. This algorithmic approach is used in file managers.
+///
+internal sealed class AlphanumComparatorFast : IComparer, IComparer
{
- using global::System;
- using global::System.Collections;
- using global::System.Collections.Generic;
- using global::System.Text;
-
- ///
- /// Alphanumeric sort. This sorting algorithm logically handles numbers in strings. It makes sense to humans.
- /// Highway names like 50F and 100F will be sorted wrongly with ASCII sort.
- /// It is different from alphabetic, ASCII or numeric sorting. This algorithmic approach is used in file managers.
- ///
- internal sealed class AlphanumComparatorFast : IComparer, IComparer
- {
- ///
- public int Compare(object? x, object? y) => Compare(x as string, y as string);
+ ///
+ public int Compare(object? x, object? y) => Compare(x as string, y as string);
- ///
- public int Compare(string? s1, string? s2)
+ ///
+ public int Compare(string? s1, string? s2)
+ {
+ if (s1 is null && s2 is null) return 0;
+ if (s1 is null) return -1;
+ if (s2 is null) return 1;
+
+ var len1 = s1.Length;
+ var len2 = s2.Length;
+ if (len1 == 0 && len2 == 0) return 0;
+ if (len1 == 0) return -1;
+ if (len2 == 0) return 1;
+
+ var marker1 = 0;
+ var marker2 = 0;
+ while (marker1 < len1 || marker2 < len2)
{
- if (s1 is null && s2 is null) return 0;
- if (s1 is null) return -1;
- if (s2 is null) return 1;
-
- var len1 = s1.Length;
- var len2 = s2.Length;
- if (len1 == 0 && len2 == 0) return 0;
- if (len1 == 0) return -1;
- if (len2 == 0) return 1;
-
- var marker1 = 0;
- var marker2 = 0;
- while (marker1 < len1 || marker2 < len2)
+ if (marker1 >= len1) return -1;
+ if (marker2 >= len2) return 1;
+ var ch1 = s1[marker1];
+ var ch2 = s2[marker2];
+
+ var chunk1 = new StringBuilder();
+ var chunk2 = new StringBuilder();
+
+ while (marker1 < len1 && (chunk1.Length == 0 || InChunk(ch1, chunk1[0])))
{
- if (marker1 >= len1) return -1;
- if (marker2 >= len2) return 1;
- var ch1 = s1[marker1];
- var ch2 = s2[marker2];
-
- var chunk1 = new StringBuilder();
- var chunk2 = new StringBuilder();
-
- while (marker1 < len1 && (chunk1.Length == 0 || InChunk(ch1, chunk1[0])))
- {
- chunk1.Append(ch1);
- marker1++;
-
- if (marker1 < len1)
- ch1 = s1[marker1];
- }
-
- while (marker2 < len2 && (chunk2.Length == 0 || InChunk(ch2, chunk2[0])))
- {
- chunk2.Append(ch2);
- marker2++;
-
- if (marker2 < len2)
- ch2 = s2[marker2];
- }
-
- // If both chunks contain numeric characters, sort them numerically
- if (char.IsDigit(chunk1[0]) && char.IsDigit(chunk2[0]))
- {
- var numericChunk1 = Convert.ToInt32(chunk1.ToString());
- var numericChunk2 = Convert.ToInt32(chunk2.ToString());
-
- if (numericChunk1 < numericChunk2) return -1;
- if (numericChunk1 > numericChunk2) return 1;
- }
- else
- {
- var result = string.CompareOrdinal(chunk1.ToString(), chunk2.ToString());
- // Normalize for cases when the code can't handle 2 or -2 and futher
- if (result >= 1) return 1;
- if (result <= -1) return -1;
- }
+ chunk1.Append(ch1);
+ marker1++;
+
+ if (marker1 < len1)
+ ch1 = s1[marker1];
}
- return 0;
- }
+ while (marker2 < len2 && (chunk2.Length == 0 || InChunk(ch2, chunk2[0])))
+ {
+ chunk2.Append(ch2);
+ marker2++;
- private static bool InChunk(char ch, char otherCh)
- {
- var type = ChunkType.Alphanumeric;
+ if (marker2 < len2)
+ ch2 = s2[marker2];
+ }
- if (char.IsDigit(otherCh))
- type = ChunkType.Numeric;
+ // If both chunks contain numeric characters, sort them numerically
+ if (char.IsDigit(chunk1[0]) && char.IsDigit(chunk2[0]))
+ {
+ var numericChunk1 = Convert.ToInt32(chunk1.ToString());
+ var numericChunk2 = Convert.ToInt32(chunk2.ToString());
- return (type != ChunkType.Alphanumeric || !char.IsDigit(ch)) && (type != ChunkType.Numeric || char.IsDigit(ch));
+ if (numericChunk1 < numericChunk2) return -1;
+ if (numericChunk1 > numericChunk2) return 1;
+ }
+ else
+ {
+ var result = string.CompareOrdinal(chunk1.ToString(), chunk2.ToString());
+ // Normalize for cases when the code can't handle 2 or -2 and futher
+ if (result >= 1) return 1;
+ if (result <= -1) return -1;
+ }
}
- private enum ChunkType
- {
- Alphanumeric,
- Numeric
- }
+ return 0;
+ }
+
+ private static bool InChunk(char ch, char otherCh)
+ {
+ var type = ChunkType.Alphanumeric;
+
+ if (char.IsDigit(otherCh))
+ type = ChunkType.Numeric;
+
+ return (type != ChunkType.Alphanumeric || !char.IsDigit(ch)) && (type != ChunkType.Numeric || char.IsDigit(ch));
+ }
+
+ private enum ChunkType
+ {
+ Alphanumeric,
+ Numeric
}
}
+
#nullable restore
#if !BANNERLORDBUTRMODULEMANAGER_ENABLE_WARNING
#pragma warning restore
diff --git a/src/Bannerlord.ModuleManager/CollectionsExtensions.cs b/src/Bannerlord.ModuleManager/CollectionsExtensions.cs
index 9f9d3ec..e809f3d 100644
--- a/src/Bannerlord.ModuleManager/CollectionsExtensions.cs
+++ b/src/Bannerlord.ModuleManager/CollectionsExtensions.cs
@@ -1,18 +1,4 @@
-//
-// This code file has automatically been added by the "Bannerlord.ModuleManager.Source" NuGet package (https://www.nuget.org/packages/Bannerlord.ModuleManager.Source).
-// Please see https://github.com/BUTR/Bannerlord.ModuleManager for more information.
-//
-// IMPORTANT:
-// DO NOT DELETE THIS FILE if you are using a "packages.config" file to manage your NuGet references.
-// Consider migrating to PackageReferences instead:
-// https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference
-// Migrating brings the following benefits:
-// * The "Bannerlord.ModuleManager.Source" folder and the "CollectionsExtensions.cs" file don't appear in your project.
-// * The added file is immutable and can therefore not be modified by coincidence.
-// * Updating/Uninstalling the package will work flawlessly.
-//
-
-#region License
+#region License
// MIT License
//
// Copyright (c) Bannerlord's Unofficial Tools & Resources
@@ -41,62 +27,62 @@
#pragma warning disable
#endif
-namespace Bannerlord.ModuleManager
-{
- using global::System;
- using global::System.Collections.Generic;
+namespace Bannerlord.ModuleManager;
+
+using System;
+using System.Collections.Generic;
- internal static class CollectionsExtensions
+internal static class CollectionsExtensions
+{
+ public static int IndexOf(this IReadOnlyList self, T elementToFind)
{
- public static int IndexOf(this IReadOnlyList self, T elementToFind)
+ var i = 0;
+ foreach (T element in self)
{
- var i = 0;
- foreach (T element in self)
- {
- if (Equals(element, elementToFind))
- return i;
- i++;
- }
- return -1;
+ if (Equals(element, elementToFind))
+ return i;
+ i++;
}
- public static int IndexOf(this IReadOnlyList self, Func preficate)
+ return -1;
+ }
+ public static int IndexOf(this IReadOnlyList self, Func preficate)
+ {
+ var i = 0;
+ foreach (T element in self)
{
- var i = 0;
- foreach (T element in self)
- {
- if (preficate(element))
- return i;
- i++;
- }
- return -1;
+ if (preficate(element))
+ return i;
+ i++;
}
+ return -1;
+ }
- public static IEnumerable DistinctBy(this IEnumerable source, Func keySelector) =>
- DistinctBy(source, keySelector, null);
+ public static IEnumerable DistinctBy(this IEnumerable source, Func keySelector) =>
+ DistinctBy(source, keySelector, null);
- public static IEnumerable DistinctBy(this IEnumerable source, Func keySelector, IEqualityComparer? comparer) =>
- DistinctByIterator(source, keySelector, comparer);
+ public static IEnumerable DistinctBy(this IEnumerable source, Func keySelector, IEqualityComparer? comparer) =>
+ DistinctByIterator(source, keySelector, comparer);
- private static IEnumerable DistinctByIterator(IEnumerable source, Func keySelector, IEqualityComparer? comparer)
- {
- using var enumerator = source.GetEnumerator();
+ private static IEnumerable DistinctByIterator(IEnumerable source, Func keySelector, IEqualityComparer? comparer)
+ {
+ using var enumerator = source.GetEnumerator();
- if (enumerator.MoveNext())
+ if (enumerator.MoveNext())
+ {
+ var set = new HashSet(comparer);
+ do
{
- var set = new HashSet(comparer);
- do
+ TSource element = enumerator.Current;
+ if (set.Add(keySelector(element)))
{
- TSource element = enumerator.Current;
- if (set.Add(keySelector(element)))
- {
- yield return element;
- }
+ yield return element;
}
- while (enumerator.MoveNext());
}
+ while (enumerator.MoveNext());
}
}
}
+
#nullable restore
#if !BANNERLORDBUTRMODULEMANAGER_ENABLE_WARNING
#pragma warning restore
diff --git a/src/Bannerlord.ModuleManager/ModuleInfoExtendedExtensions.cs b/src/Bannerlord.ModuleManager/ModuleInfoExtendedExtensions.cs
index afc1869..2c04317 100644
--- a/src/Bannerlord.ModuleManager/ModuleInfoExtendedExtensions.cs
+++ b/src/Bannerlord.ModuleManager/ModuleInfoExtendedExtensions.cs
@@ -1,18 +1,4 @@
-//
-// This code file has automatically been added by the "Bannerlord.ModuleManager.Source" NuGet package (https://www.nuget.org/packages/Bannerlord.ModuleManager.Source).
-// Please see https://github.com/BUTR/Bannerlord.ModuleManager for more information.
-//
-// IMPORTANT:
-// DO NOT DELETE THIS FILE if you are using a "packages.config" file to manage your NuGet references.
-// Consider migrating to PackageReferences instead:
-// https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference
-// Migrating brings the following benefits:
-// * The "Bannerlord.ModuleManager.Source" folder and the "ModuleInfoExtendedExtensions.cs" file don't appear in your project.
-// * The added file is immutable and can therefore not be modified by coincidence.
-// * Updating/Uninstalling the package will work flawlessly.
-//
-
-#region License
+#region License
// MIT License
//
// Copyright (c) Bannerlord's Unofficial Tools & Resources
@@ -41,145 +27,144 @@
#pragma warning disable
#endif
-namespace Bannerlord.ModuleManager
-{
- using global::System;
- using global::System.Collections.Generic;
- using global::System.Linq;
+namespace Bannerlord.ModuleManager;
+
+using System.Collections.Generic;
+using System.Linq;
#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
internal
#else
- public
+public
# endif
- static class ModuleInfoExtendedExtensions
+ static class ModuleInfoExtendedExtensions
+{
+ public static IEnumerable DependenciesAllDistinct(this ModuleInfoExtended module) => DependenciesAll(module).DistinctBy(x => x.Id);
+ public static IEnumerable DependenciesAll(this ModuleInfoExtended module)
{
- public static IEnumerable DependenciesAllDistinct(this ModuleInfoExtended module) => DependenciesAll(module).DistinctBy(x => x.Id);
- public static IEnumerable DependenciesAll(this ModuleInfoExtended module)
+ foreach (var metadata in module.DependentModuleMetadatas.Where(x => x is not null))
{
- foreach (var metadata in module.DependentModuleMetadatas.Where(x => x is not null))
- {
- yield return metadata;
- }
- foreach (var metadata in module.DependentModules.Where(x => x is not null))
+ yield return metadata;
+ }
+ foreach (var metadata in module.DependentModules.Where(x => x is not null))
+ {
+ yield return new DependentModuleMetadata
{
- yield return new DependentModuleMetadata
- {
- Id = metadata.Id,
- LoadType = LoadType.LoadBeforeThis,
- IsOptional = metadata.IsOptional,
- Version = metadata.Version
- };
- }
- foreach (var metadata in module.ModulesToLoadAfterThis.Where(x => x is not null))
+ Id = metadata.Id,
+ LoadType = LoadType.LoadBeforeThis,
+ IsOptional = metadata.IsOptional,
+ Version = metadata.Version
+ };
+ }
+ foreach (var metadata in module.ModulesToLoadAfterThis.Where(x => x is not null))
+ {
+ yield return new DependentModuleMetadata
{
- yield return new DependentModuleMetadata
- {
- Id = metadata.Id,
- LoadType = LoadType.LoadAfterThis,
- IsOptional = metadata.IsOptional,
- Version = metadata.Version
- };
- }
- foreach (var metadata in module.IncompatibleModules.Where(x => x is not null))
+ Id = metadata.Id,
+ LoadType = LoadType.LoadAfterThis,
+ IsOptional = metadata.IsOptional,
+ Version = metadata.Version
+ };
+ }
+ foreach (var metadata in module.IncompatibleModules.Where(x => x is not null))
+ {
+ yield return new DependentModuleMetadata
{
- yield return new DependentModuleMetadata
- {
- Id = metadata.Id,
- IsIncompatible = true,
- IsOptional = metadata.IsOptional,
- Version = metadata.Version
- };
- }
+ Id = metadata.Id,
+ IsIncompatible = true,
+ IsOptional = metadata.IsOptional,
+ Version = metadata.Version
+ };
}
+ }
- public static IEnumerable DependenciesToLoadDistinct(this ModuleInfoExtended module) => DependenciesToLoad(module).DistinctBy(x => x.Id);
- public static IEnumerable DependenciesToLoad(this ModuleInfoExtended module)
+ public static IEnumerable DependenciesToLoadDistinct(this ModuleInfoExtended module) => DependenciesToLoad(module).DistinctBy(x => x.Id);
+ public static IEnumerable DependenciesToLoad(this ModuleInfoExtended module)
+ {
+ foreach (var metadata in module.DependentModuleMetadatas.Where(x => x is not null).Where(x => !x.IsIncompatible))
{
- foreach (var metadata in module.DependentModuleMetadatas.Where(x => x is not null).Where(x => !x.IsIncompatible))
- {
- yield return metadata;
- }
- foreach (var metadata in module.DependentModules.Where(x => x is not null))
+ yield return metadata;
+ }
+ foreach (var metadata in module.DependentModules.Where(x => x is not null))
+ {
+ yield return new DependentModuleMetadata
{
- yield return new DependentModuleMetadata
- {
- Id = metadata.Id,
- LoadType = LoadType.LoadBeforeThis,
- IsOptional = metadata.IsOptional,
- Version = metadata.Version
- };
- }
- foreach (var metadata in module.ModulesToLoadAfterThis.Where(x => x is not null))
+ Id = metadata.Id,
+ LoadType = LoadType.LoadBeforeThis,
+ IsOptional = metadata.IsOptional,
+ Version = metadata.Version
+ };
+ }
+ foreach (var metadata in module.ModulesToLoadAfterThis.Where(x => x is not null))
+ {
+ yield return new DependentModuleMetadata
{
- yield return new DependentModuleMetadata
- {
- Id = metadata.Id,
- LoadType = LoadType.LoadAfterThis,
- IsOptional = metadata.IsOptional,
- Version = metadata.Version
- };
- }
+ Id = metadata.Id,
+ LoadType = LoadType.LoadAfterThis,
+ IsOptional = metadata.IsOptional,
+ Version = metadata.Version
+ };
}
+ }
- public static IEnumerable DependenciesLoadBeforeThisDistinct(this ModuleInfoExtended module) => DependenciesLoadBeforeThis(module).DistinctBy(x => x.Id);
- public static IEnumerable DependenciesLoadBeforeThis(this ModuleInfoExtended module)
+ public static IEnumerable DependenciesLoadBeforeThisDistinct(this ModuleInfoExtended module) => DependenciesLoadBeforeThis(module).DistinctBy(x => x.Id);
+ public static IEnumerable DependenciesLoadBeforeThis(this ModuleInfoExtended module)
+ {
+ foreach (var metadata in module.DependentModuleMetadatas.Where(x => x is not null).Where(x => x.LoadType == LoadType.LoadBeforeThis))
{
- foreach (var metadata in module.DependentModuleMetadatas.Where(x => x is not null).Where(x => x.LoadType == LoadType.LoadBeforeThis))
- {
- yield return metadata;
- }
- foreach (var metadata in module.DependentModules.Where(x => x is not null))
+ yield return metadata;
+ }
+ foreach (var metadata in module.DependentModules.Where(x => x is not null))
+ {
+ yield return new DependentModuleMetadata
{
- yield return new DependentModuleMetadata
- {
- Id = metadata.Id,
- LoadType = LoadType.LoadBeforeThis,
- IsOptional = metadata.IsOptional,
- Version = metadata.Version
- };
- }
+ Id = metadata.Id,
+ LoadType = LoadType.LoadBeforeThis,
+ IsOptional = metadata.IsOptional,
+ Version = metadata.Version
+ };
}
+ }
- public static IEnumerable DependenciesLoadAfterThisDistinct(this ModuleInfoExtended module) => DependenciesLoadAfterThis(module).DistinctBy(x => x.Id);
- public static IEnumerable DependenciesLoadAfterThis(this ModuleInfoExtended module)
+ public static IEnumerable DependenciesLoadAfterThisDistinct(this ModuleInfoExtended module) => DependenciesLoadAfterThis(module).DistinctBy(x => x.Id);
+ public static IEnumerable DependenciesLoadAfterThis(this ModuleInfoExtended module)
+ {
+ foreach (var metadata in module.DependentModuleMetadatas.Where(x => x is not null).Where(x => x.LoadType == LoadType.LoadAfterThis))
{
- foreach (var metadata in module.DependentModuleMetadatas.Where(x => x is not null).Where(x => x.LoadType == LoadType.LoadAfterThis))
- {
- yield return metadata;
- }
- foreach (var metadata in module.ModulesToLoadAfterThis.Where(x => x is not null))
+ yield return metadata;
+ }
+ foreach (var metadata in module.ModulesToLoadAfterThis.Where(x => x is not null))
+ {
+ yield return new DependentModuleMetadata
{
- yield return new DependentModuleMetadata
- {
- Id = metadata.Id,
- LoadType = LoadType.LoadAfterThis,
- IsOptional = metadata.IsOptional,
- Version = metadata.Version
- };
- }
+ Id = metadata.Id,
+ LoadType = LoadType.LoadAfterThis,
+ IsOptional = metadata.IsOptional,
+ Version = metadata.Version
+ };
}
+ }
- public static IEnumerable DependenciesIncompatiblesDistinct(this ModuleInfoExtended module) => DependenciesIncompatibles(module).DistinctBy(x => x.Id);
- public static IEnumerable DependenciesIncompatibles(this ModuleInfoExtended module)
+ public static IEnumerable DependenciesIncompatiblesDistinct(this ModuleInfoExtended module) => DependenciesIncompatibles(module).DistinctBy(x => x.Id);
+ public static IEnumerable DependenciesIncompatibles(this ModuleInfoExtended module)
+ {
+ foreach (var metadata in module.DependentModuleMetadatas.Where(x => x is not null).Where(x => x.IsIncompatible))
{
- foreach (var metadata in module.DependentModuleMetadatas.Where(x => x is not null).Where(x => x.IsIncompatible))
- {
- yield return metadata;
- }
- foreach (var metadata in module.IncompatibleModules.Where(x => x is not null))
+ yield return metadata;
+ }
+ foreach (var metadata in module.IncompatibleModules.Where(x => x is not null))
+ {
+ yield return new DependentModuleMetadata
{
- yield return new DependentModuleMetadata
- {
- Id = metadata.Id,
- IsIncompatible = true,
- IsOptional = metadata.IsOptional,
- Version = metadata.Version
- };
- }
+ Id = metadata.Id,
+ IsIncompatible = true,
+ IsOptional = metadata.IsOptional,
+ Version = metadata.Version
+ };
}
}
}
+
#nullable restore
#if !BANNERLORDBUTRMODULEMANAGER_ENABLE_WARNING
#pragma warning restore
diff --git a/src/Bannerlord.ModuleManager/ModuleSorter.cs b/src/Bannerlord.ModuleManager/ModuleSorter.cs
index b937f1a..9f53f99 100644
--- a/src/Bannerlord.ModuleManager/ModuleSorter.cs
+++ b/src/Bannerlord.ModuleManager/ModuleSorter.cs
@@ -1,18 +1,4 @@
-//
-// This code file has automatically been added by the "Bannerlord.ModuleManager.Source" NuGet package (https://www.nuget.org/packages/Bannerlord.ModuleManager.Source).
-// Please see https://github.com/BUTR/Bannerlord.ModuleManager for more information.
-//
-// IMPORTANT:
-// DO NOT DELETE THIS FILE if you are using a "packages.config" file to manage your NuGet references.
-// Consider migrating to PackageReferences instead:
-// https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference
-// Migrating brings the following benefits:
-// * The "Bannerlord.ModuleManager.Source" folder and the "ModuleSorter.cs" file don't appear in your project.
-// * The added file is immutable and can therefore not be modified by coincidence.
-// * Updating/Uninstalling the package will work flawlessly.
-//
-
-#region License
+#region License
// MIT License
//
// Copyright (c) Bannerlord's Unofficial Tools & Resources
@@ -41,88 +27,88 @@
#pragma warning disable
#endif
-namespace Bannerlord.ModuleManager
-{
- using global::System;
- using global::System.Collections.Generic;
- using global::System.Linq;
+namespace Bannerlord.ModuleManager;
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
internal
#else
- public
+public
# endif
- sealed record ModuleSorterOptions
- {
- public bool SkipOptionals { get; set; }
- public bool SkipExternalDependencies { get; set; }
+ sealed record ModuleSorterOptions
+{
+ public bool SkipOptionals { get; set; }
+ public bool SkipExternalDependencies { get; set; }
- public ModuleSorterOptions() { }
- public ModuleSorterOptions(bool skipOptionals, bool skipExternalDependencies)
- {
- SkipOptionals = skipOptionals;
- SkipExternalDependencies = skipExternalDependencies;
- }
+ public ModuleSorterOptions() { }
+ public ModuleSorterOptions(bool skipOptionals, bool skipExternalDependencies)
+ {
+ SkipOptionals = skipOptionals;
+ SkipExternalDependencies = skipExternalDependencies;
}
+}
#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
internal
#else
- public
+public
# endif
- static class ModuleSorter
+ static class ModuleSorter
+{
+ public static IList Sort(IReadOnlyCollection source)
{
- public static IList Sort(IReadOnlyCollection source)
- {
- var correctModules = source
- .Where(x => ModuleUtilities.AreDependenciesPresent(source, x))
- .OrderByDescending(x => x.IsOfficial)
- .ThenByDescending(mim => mim.Id, new AlphanumComparatorFast())
- .ToArray();
+ var correctModules = source
+ .Where(x => ModuleUtilities.AreDependenciesPresent(source, x))
+ .OrderByDescending(x => x.IsOfficial)
+ .ThenByDescending(mim => mim.Id, new AlphanumComparatorFast())
+ .ToArray();
- return TopologySort(correctModules, module => ModuleUtilities.GetDependencies(correctModules, module));
- }
- public static IList Sort(IReadOnlyCollection source, ModuleSorterOptions options)
- {
- var correctModules = source
- .Where(x => ModuleUtilities.AreDependenciesPresent(source, x))
- .OrderByDescending(x => x.IsOfficial)
- .ThenByDescending(mim => mim.Id, new AlphanumComparatorFast())
- .ToArray();
+ return TopologySort(correctModules, module => ModuleUtilities.GetDependencies(correctModules, module));
+ }
+ public static IList Sort(IReadOnlyCollection source, ModuleSorterOptions options)
+ {
+ var correctModules = source
+ .Where(x => ModuleUtilities.AreDependenciesPresent(source, x))
+ .OrderByDescending(x => x.IsOfficial)
+ .ThenByDescending(mim => mim.Id, new AlphanumComparatorFast())
+ .ToArray();
- return TopologySort(correctModules, module => ModuleUtilities.GetDependencies(correctModules, module, options));
- }
+ return TopologySort(correctModules, module => ModuleUtilities.GetDependencies(correctModules, module, options));
+ }
- public static IList TopologySort(IEnumerable source, Func> getDependencies)
+ public static IList TopologySort(IEnumerable source, Func> getDependencies)
+ {
+ var list = new List();
+ var visited = new HashSet();
+ foreach (var item in source)
{
- var list = new List();
- var visited = new HashSet();
- foreach (var item in source)
- {
- Visit(item, getDependencies, item => list.Add(item), visited);
- }
- return list;
+ Visit(item, getDependencies, item => list.Add(item), visited);
}
+ return list;
+ }
- public static void Visit(T item, Func> getDependencies, Action addItem, HashSet visited)
+ public static void Visit(T item, Func> getDependencies, Action addItem, HashSet visited)
+ {
+ if (visited.Contains(item))
{
- if (visited.Contains(item))
- {
- return;
- }
+ return;
+ }
- visited.Add(item);
- if (getDependencies(item) is { } enumerable)
+ visited.Add(item);
+ if (getDependencies(item) is { } enumerable)
+ {
+ foreach (var item2 in enumerable)
{
- foreach (var item2 in enumerable)
- {
- Visit(item2, getDependencies, addItem, visited);
- }
+ Visit(item2, getDependencies, addItem, visited);
}
- addItem(item);
}
+ addItem(item);
}
}
+
#nullable restore
#if !BANNERLORDBUTRMODULEMANAGER_ENABLE_WARNING
#pragma warning restore
diff --git a/src/Bannerlord.ModuleManager/ModuleUtilities.cs b/src/Bannerlord.ModuleManager/ModuleUtilities.cs
index 5821ac2..d756de6 100644
--- a/src/Bannerlord.ModuleManager/ModuleUtilities.cs
+++ b/src/Bannerlord.ModuleManager/ModuleUtilities.cs
@@ -1,18 +1,4 @@
-//
-// This code file has automatically been added by the "Bannerlord.ModuleManager.Source" NuGet package (https://www.nuget.org/packages/Bannerlord.ModuleManager.Source).
-// Please see https://github.com/BUTR/Bannerlord.ModuleManager for more information.
-//
-// IMPORTANT:
-// DO NOT DELETE THIS FILE if you are using a "packages.config" file to manage your NuGet references.
-// Consider migrating to PackageReferences instead:
-// https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference
-// Migrating brings the following benefits:
-// * The "Bannerlord.ModuleManager.Source" folder and the "ModuleUtilities.cs" file don't appear in your project.
-// * The added file is immutable and can therefore not be modified by coincidence.
-// * Updating/Uninstalling the package will work flawlessly.
-//
-
-#region License
+#region License
// MIT License
//
// Copyright (c) Bannerlord's Unofficial Tools & Resources
@@ -41,655 +27,728 @@
#pragma warning disable
#endif
-namespace Bannerlord.ModuleManager
-{
- using global::System;
- using global::System.Collections.Generic;
- using global::System.Linq;
+namespace Bannerlord.ModuleManager;
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Models.Issues;
#if !BANNERLORDBUTRMODULEMANAGER_PUBLIC
internal
#else
- public
+public
# endif
- static class ModuleUtilities
+ static class ModuleUtilities
+{
+ ///
+ /// Checks if all dependencies for a module are present
+ ///
+ /// Assumed that only valid and selected to launch modules are in the list
+ /// The module that is being checked
+ public static bool AreDependenciesPresent(IReadOnlyCollection modules, ModuleInfoExtended module)
{
- ///
- /// Checks if all dependencies for a module are present
- ///
- /// Assumed that only valid and selected to launch modules are in the list
- /// The module that is being checked
- public static bool AreDependenciesPresent(IReadOnlyCollection modules, ModuleInfoExtended module)
+ foreach (var metadata in module.DependenciesLoadBeforeThisDistinct())
{
- foreach (var metadata in module.DependenciesLoadBeforeThisDistinct())
- {
- if (metadata.IsOptional)
- continue;
+ if (metadata.IsOptional)
+ continue;
- if (modules.All(x => !string.Equals(x.Id, metadata.Id, StringComparison.Ordinal)))
- return false;
- }
- foreach (var metadata in module.DependenciesIncompatiblesDistinct())
- {
- if (modules.Any(x => string.Equals(x.Id, metadata.Id, StringComparison.Ordinal)))
- return false;
- }
- return true;
+ if (modules.All(x => !string.Equals(x.Id, metadata.Id, StringComparison.Ordinal)))
+ return false;
}
-
- ///
- /// Returns all dependencies for a module
- ///
- public static IEnumerable GetDependencies(IReadOnlyCollection modules, ModuleInfoExtended module)
+ foreach (var metadata in module.DependenciesIncompatiblesDistinct())
{
- var visited = new HashSet();
- return GetDependencies(modules, module, visited, new ModuleSorterOptions() { SkipOptionals = false, SkipExternalDependencies = false });
+ if (modules.Any(x => string.Equals(x.Id, metadata.Id, StringComparison.Ordinal)))
+ return false;
}
- ///
- /// Returns all dependencies for a module
- ///
- public static IEnumerable GetDependencies(IReadOnlyCollection modules, ModuleInfoExtended module, ModuleSorterOptions options)
+ return true;
+ }
+
+ ///
+ /// Returns all dependencies for a module
+ ///
+ public static IEnumerable GetDependencies(IReadOnlyCollection modules, ModuleInfoExtended module)
+ {
+ var visited = new HashSet();
+ return GetDependencies(modules, module, visited, new ModuleSorterOptions() { SkipOptionals = false, SkipExternalDependencies = false });
+ }
+ ///
+ /// Returns all dependencies for a module
+ ///
+ public static IEnumerable GetDependencies(IReadOnlyCollection modules, ModuleInfoExtended module, ModuleSorterOptions options)
+ {
+ var visited = new HashSet();
+ return GetDependencies(modules, module, visited, options);
+ }
+ ///
+ /// Returns all dependencies for a module
+ ///
+ public static IEnumerable GetDependencies(IReadOnlyCollection modules, ModuleInfoExtended module, HashSet visited, ModuleSorterOptions options)
+ {
+ var dependencies = new List();
+ ModuleSorter.Visit(module, x => GetDependenciesInternal(modules, x, options), moduleToAdd =>
{
- var visited = new HashSet();
- return GetDependencies(modules, module, visited, options);
- }
- ///
- /// Returns all dependencies for a module
- ///
- public static IEnumerable GetDependencies(IReadOnlyCollection modules, ModuleInfoExtended module, HashSet visited, ModuleSorterOptions options)
+ if (moduleToAdd != module)
+ dependencies.Add(moduleToAdd);
+ }, visited);
+ return dependencies;
+ }
+ private static IEnumerable GetDependenciesInternal(IReadOnlyCollection modules, ModuleInfoExtended module, ModuleSorterOptions options)
+ {
+ foreach (var dependentModuleMetadata in module.DependenciesLoadBeforeThisDistinct())
{
- var dependencies = new List();
- ModuleSorter.Visit(module, x => GetDependenciesInternal(modules, x, options), moduleToAdd =>
+ if (dependentModuleMetadata.IsOptional && options.SkipOptionals)
+ continue;
+
+ var moduleInfo = modules.FirstOrDefault(x => string.Equals(x.Id, dependentModuleMetadata.Id, StringComparison.Ordinal));
+ if (!dependentModuleMetadata.IsOptional && moduleInfo is null)
{
- if (moduleToAdd != module)
- dependencies.Add(moduleToAdd);
- }, visited);
- return dependencies;
- }
- private static IEnumerable GetDependenciesInternal(IReadOnlyCollection modules, ModuleInfoExtended module, ModuleSorterOptions options)
- {
- foreach (var dependentModuleMetadata in module.DependenciesLoadBeforeThisDistinct())
+ // We should not hit this place. If we do, the module list is invalid
+ }
+ else if (moduleInfo is not null)
{
- if (dependentModuleMetadata.IsOptional && options.SkipOptionals)
- continue;
-
- var moduleInfo = modules.FirstOrDefault(x => string.Equals(x.Id, dependentModuleMetadata.Id, StringComparison.Ordinal));
- if (!dependentModuleMetadata.IsOptional && moduleInfo is null)
- {
- // We should not hit this place. If we do, the module list is invalid
- }
- else if (moduleInfo is not null)
- {
- yield return moduleInfo;
- }
+ yield return moduleInfo;
}
+ }
- if (!options.SkipExternalDependencies)
+ if (!options.SkipExternalDependencies)
+ {
+ foreach (var moduleInfo in modules)
{
- foreach (var moduleInfo in modules)
+ foreach (var dependentModuleMetadata in moduleInfo.DependenciesLoadAfterThisDistinct())
{
- foreach (var dependentModuleMetadata in moduleInfo.DependenciesLoadAfterThisDistinct())
- {
- if (dependentModuleMetadata.IsOptional && options.SkipOptionals)
- continue;
+ if (dependentModuleMetadata.IsOptional && options.SkipOptionals)
+ continue;
- if (!string.Equals(dependentModuleMetadata.Id, module.Id, StringComparison.Ordinal))
- continue;
+ if (!string.Equals(dependentModuleMetadata.Id, module.Id, StringComparison.Ordinal))
+ continue;
- yield return moduleInfo;
- }
+ yield return moduleInfo;
}
}
}
+ }
- ///
- /// Validates a module
- ///
- /// All available modules
- /// Any error that were detected during inspection
- public static IEnumerable ValidateModule(IReadOnlyList modules, ModuleInfoExtended targetModule, Func isSelected)
+ #region Polyfills
+ ///
+ /// Validates a module
+ ///
+ /// All available modules (in any order)
+ /// The module to validate
+ /// Function that determines if a module is selected (is enabled)
+ /// Any errors that were detected during inspection
+ public static IEnumerable ValidateModule(
+ IReadOnlyList modules,
+ ModuleInfoExtended targetModule,
+ Func isSelected)
+ {
+ var visited = new HashSet();
+ return ValidateModuleEx(modules, targetModule, visited, isSelected,
+ x => ValidateModuleEx(modules, x, isSelected).Count() == 0)
+ .Select(x => x.ToLegacy());
+ }
+
+ ///
+ /// Validates a module
+ ///
+ /// All available modules (in any order)
+ /// The module to validate
+ /// Function that determines if a module is selected (is enabled)
+ /// Function that determines if a module is valid
+ /// Any errors that were detected during inspection
+ public static IEnumerable ValidateModule(
+ IReadOnlyList modules,
+ ModuleInfoExtended targetModule,
+ Func isSelected,
+ Func isValid)
+ {
+ var visited = new HashSet();
+ return ValidateModuleEx(modules, targetModule, visited, isSelected, isValid)
+ .Select(x => x.ToLegacy());
+ }
+
+ ///
+ /// Validates a module's common data
+ ///
+ /// The module to validate
+ /// Any errors that were detected during inspection of common data
+ public static IEnumerable ValidateModuleCommonData(ModuleInfoExtended module) =>
+ ValidateModuleCommonDataEx(module).Select(x => x.ToLegacy());
+
+ ///
+ /// Validates a module's dependency declarations
+ ///
+ /// All available modules (in any order)
+ /// The module whose dependencies are being validated
+ /// Any errors that were detected during inspection of dependencies
+ public static IEnumerable ValidateModuleDependenciesDeclarations(
+ IReadOnlyList modules,
+ ModuleInfoExtended targetModule) =>
+ ValidateModuleDependenciesDeclarationsEx(modules, targetModule).Select(x => x.ToLegacy());
+
+ ///
+ /// Validates module dependencies
+ ///
+ /// All available modules (in any order)
+ /// The module whose dependencies are being validated
+ /// Set of modules already validated to prevent cycles
+ /// Function that determines if a module is selected
+ /// Function that determines if a module is valid
+ /// Any errors that were detected during inspection of dependencies
+ public static IEnumerable ValidateModuleDependencies(
+ IReadOnlyList modules,
+ ModuleInfoExtended targetModule,
+ HashSet visitedModules,
+ Func isSelected,
+ Func isValid) =>
+ ValidateModuleDependenciesEx(modules, targetModule, visitedModules, isSelected, isValid)
+ .Select(x => x.ToLegacy());
+
+ ///
+ /// Validates whether the load order is correctly sorted
+ ///
+ /// All available modules in they order they are expected to be loaded in
+ /// Assumed that it's present in
+ /// Any errors that were detected during inspection
+ public static IEnumerable ValidateLoadOrder(
+ IReadOnlyList modules,
+ ModuleInfoExtended targetModule)
+ {
+ foreach (var issue in ValidateModuleCommonData(targetModule))
+ yield return issue;
+
+ var visited = new HashSet();
+ foreach (var issue in ValidateLoadOrderEx(modules, targetModule, visited)
+ .Select(x => x.ToLegacy()))
+ yield return issue;
+ }
+
+ ///
+ /// Validates whether the load order is correctly sorted
+ ///
+ /// All available modules in they order they are expected to be loaded in
+ /// Assumed that it's present in
+ /// Used to track that we traverse each module only once
+ /// Any errors that were detected during inspection
+ public static IEnumerable ValidateLoadOrder(
+ IReadOnlyList modules,
+ ModuleInfoExtended targetModule,
+ HashSet visitedModules) =>
+ ValidateLoadOrderEx(modules, targetModule, visitedModules).Select(x => x.ToLegacy());
+ #endregion
+
+ ///
+ /// Validates a module using the new variant-based issue system
+ ///
+ /// All available modules (in any order)
+ /// The module to validate
+ /// Function that determines if a module is enabled
+ /// Any errors that were detected during inspection
+ public static IEnumerable ValidateModuleEx(
+ IReadOnlyList modules,
+ ModuleInfoExtended targetModule,
+ Func isSelected)
+ {
+ var visited = new HashSet();
+ foreach (var issue in ValidateModuleEx(modules, targetModule, visited, isSelected, x => ValidateModuleEx(modules, x, isSelected).Count() == 0))
{
- var visited = new HashSet();
- foreach (var issue in ValidateModule(modules, targetModule, visited, isSelected, x => ValidateModule(modules, x, isSelected).Count() == 0))
- yield return issue;
+ yield return issue;
}
- ///
- /// Validates a module
- ///
- /// All available modules
- /// Any error that were detected during inspection
- public static IEnumerable ValidateModule(IReadOnlyList modules, ModuleInfoExtended targetModule, Func isSelected, Func isValid)
+ }
+
+ ///
+ /// Validates a module using the new variant-based issue system
+ ///
+ /// All available modules (in any order)
+ /// The module to validate
+ /// Function that determines if a module is enabled
+ /// Function that determines if a module is valid
+ /// Any errors that were detected during inspection
+ public static IEnumerable ValidateModuleEx(
+ IReadOnlyList modules,
+ ModuleInfoExtended targetModule,
+ Func isSelected,
+ Func isValid)
+ {
+ var visited = new HashSet();
+ foreach (var issue in ValidateModuleEx(modules, targetModule, visited, isSelected, isValid))
{
- var visited = new HashSet();
- foreach (var issue in ValidateModule(modules, targetModule, visited, isSelected, isValid))
- yield return issue;
+ yield return issue;
}
- ///
- /// Validates a module
- ///
- /// All available modules
- /// Any error that were detected during inspection
- public static IEnumerable ValidateModule(IReadOnlyList modules, ModuleInfoExtended targetModule, HashSet visitedModules, Func isSelected, Func isValid)
- {
- // Validate common data
- foreach (var issue in ValidateModuleCommonData(targetModule))
- yield return issue;
+ }
+
+ ///
+ /// Internal validation method that handles the core validation logic
+ ///
+ /// All available modules (in any order)
+ /// The module to validate
+ /// Set of modules already validated to prevent cycles
+ /// Function that determines if a module is enabled
+ /// Function that determines if a module is valid
+ /// Set this to true to also report errors in the target module's dependencies. e.g. Missing dependencies of dependencies.
+ /// Any errors that were detected during inspection
+ private static IEnumerable ValidateModuleEx(
+ IReadOnlyList modules,
+ ModuleInfoExtended targetModule,
+ HashSet visitedModules,
+ Func isSelected,
+ Func isValid,
+ bool validateDependencies = true)
+ {
+ foreach (var issue in ValidateModuleCommonDataEx(targetModule))
+ yield return issue;
- // Validate dependency declaration
- foreach (var issue in ValidateModuleDependenciesDeclarations(modules, targetModule))
- yield return issue;
+ foreach (var issue in ValidateModuleDependenciesDeclarationsEx(modules, targetModule))
+ yield return issue;
- // Check that all dependencies are present
- foreach (var issue in ValidateModuleDependencies(modules, targetModule, visitedModules, isSelected, isValid))
- yield return issue;
- }
+ foreach (var issue in ValidateModuleDependenciesEx(modules, targetModule, visitedModules, isSelected, isValid, validateDependencies))
+ yield return issue;
+ }
- ///