fail mods if their unique ID isn't unique (#323)
This commit is contained in:
parent
7bf0c66088
commit
61d13d370c
|
@ -179,6 +179,26 @@ namespace StardewModdingAPI.Tests.Core
|
|||
mock.Verify(p => p.SetStatus(ModMetadataStatus.Failed, It.IsAny<string>()), Times.Once, "The validation did not fail the metadata.");
|
||||
}
|
||||
|
||||
#if SMAPI_2_0
|
||||
[Test(Description = "Assert that validation fails when multiple mods have the same unique ID.")]
|
||||
public void ValidateManifests_DuplicateUniqueID_Fails()
|
||||
{
|
||||
// arrange
|
||||
Mock<IModMetadata> modA = this.GetMetadata("Mod A", new string[0], allowStatusChange: true);
|
||||
Mock<IModMetadata> modB = this.GetMetadata(this.GetManifest("Mod A", "1.0", manifest => manifest.Name = "Mod B"), allowStatusChange: true);
|
||||
Mock<IModMetadata> modC = this.GetMetadata("Mod C", new string[0], allowStatusChange: false);
|
||||
foreach (Mock<IModMetadata> mod in new[] { modA, modB, modC })
|
||||
this.SetupMetadataForValidation(mod);
|
||||
|
||||
// act
|
||||
new ModResolver().ValidateManifests(new[] { modA.Object, modB.Object }, apiVersion: new SemanticVersion("1.0"));
|
||||
|
||||
// assert
|
||||
modA.Verify(p => p.SetStatus(ModMetadataStatus.Failed, It.IsAny<string>()), Times.Once, "The validation did not fail the first mod with a unique ID.");
|
||||
modB.Verify(p => p.SetStatus(ModMetadataStatus.Failed, It.IsAny<string>()), Times.Once, "The validation did not fail the second mod with a unique ID.");
|
||||
}
|
||||
#endif
|
||||
|
||||
[Test(Description = "Assert that validation fails when the manifest references a DLL that does not exist.")]
|
||||
public void ValidateManifests_Valid_Passes()
|
||||
{
|
||||
|
|
|
@ -95,6 +95,9 @@ namespace StardewModdingAPI.Framework.ModLoading
|
|||
/// <param name="apiVersion">The current SMAPI version.</param>
|
||||
public void ValidateManifests(IEnumerable<IModMetadata> mods, ISemanticVersion apiVersion)
|
||||
{
|
||||
mods = mods.ToArray();
|
||||
|
||||
// validate each manifest
|
||||
foreach (IModMetadata mod in mods)
|
||||
{
|
||||
// skip if already failed
|
||||
|
@ -153,6 +156,24 @@ namespace StardewModdingAPI.Framework.ModLoading
|
|||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// validate IDs are unique
|
||||
#if SMAPI_2_0
|
||||
{
|
||||
var duplicatesByID = mods
|
||||
.GroupBy(mod => mod.Manifest.UniqueID?.Trim(), mod => mod, StringComparer.InvariantCultureIgnoreCase)
|
||||
.Where(p => p.Count() > 1);
|
||||
foreach (var group in duplicatesByID)
|
||||
{
|
||||
foreach (IModMetadata mod in group)
|
||||
{
|
||||
if (mod.Status == ModMetadataStatus.Failed)
|
||||
continue; // don't replace metadata error
|
||||
mod.SetStatus(ModMetadataStatus.Failed, $"its unique ID '{mod.Manifest.UniqueID}' is used by multiple mods ({string.Join(", ", group.Select(p => p.DisplayName))}).");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>Sort the given mods by the order they should be loaded.</summary>
|
||||
|
|
Loading…
Reference in New Issue