diff --git a/CHANGELOG.md b/CHANGELOG.md index bc95bf4f34..9d973e3a8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. ### Bugfixes - [GUI] Splitter and tabstrip visual improvements (#2413 by: HebaruSan; reviewed: politas) - [GUI] Fix "Collection was modified" exception for redundant optional dependencies (#2423 by: HebaruSan; reviewed: politas) +- [core] Treat installed DLC as compatible dependency (#2424 by: HebaruSan; reviewed: politas) ### Internal diff --git a/Core/Registry/Registry.cs b/Core/Registry/Registry.cs index b54c672e98..3a16542220 100644 --- a/Core/Registry/Registry.cs +++ b/Core/Registry/Registry.cs @@ -498,7 +498,8 @@ private bool allDependenciesCompatible(CkanModule mod, KspVersionCriteria ksp_ve { try { - if (!LatestAvailableWithProvides(dependency.name, ksp_version).Any()) + if (!dependency.MatchesAny(null, InstalledDlls.ToHashSet(), InstalledDlc) + && !LatestAvailableWithProvides(dependency.name, ksp_version).Any()) { return false; } diff --git a/GUI/MainModInfo.cs b/GUI/MainModInfo.cs index 445d46c2f2..b10d8ceaa0 100644 --- a/GUI/MainModInfo.cs +++ b/GUI/MainModInfo.cs @@ -302,6 +302,13 @@ private TreeNode findDependencyShallow(IRegistryQuerier registry, string identif } catch (ModuleNotFoundKraken) { + // Maybe it's a DLC? + ModuleVersion installedVersion = registry.InstalledVersion(identifier, false); + if (installedVersion != null) + { + return nonModuleNode(identifier, installedVersion, relationship); + } + // If we don't find a module by this name, look for other modules that provide it. List dependencyModules = registry.LatestAvailableWithProvides(identifier, crit); if (dependencyModules != null && dependencyModules.Count > 0) @@ -342,6 +349,16 @@ private TreeNode indexedNode(IRegistryQuerier registry, CkanModule module, Relat }; } + private TreeNode nonModuleNode(string identifier, ModuleVersion version, RelationshipType relationship) + { + int icon = (int)relationship + 1; + return new TreeNode($"{identifier} {version}", icon, icon) + { + Name = identifier, + ToolTipText = relationship.ToString() + }; + } + private TreeNode nonindexedNode(string identifier, RelationshipType relationship) { // Completely nonexistent dependency, e.g. "AJE" diff --git a/Tests/Core/Registry/Registry.cs b/Tests/Core/Registry/Registry.cs index 9c58e91f6c..d810f27a43 100644 --- a/Tests/Core/Registry/Registry.cs +++ b/Tests/Core/Registry/Registry.cs @@ -1,4 +1,5 @@ using System.Transactions; +using System.Collections.Generic; using CKAN; using CKAN.Versioning; using NUnit.Framework; @@ -90,6 +91,98 @@ public void LatestAvailable() }); } + [Test] + public void Available_NoDLCInstalled_ExcludesModulesDependingOnMH() + { + // Arrange + CkanModule DLCDepender = CkanModule.FromJson(@"{ + ""identifier"": ""DLC-Depender"", + ""version"": ""1.0.0"", + ""download"": ""https://kerbalstuff.com/mod/269/Dogecoin%20Flag/download/1.01"", + ""depends"": [ { + ""name"":""MakingHistory-DLC"" + } ] + }"); + registry.AddAvailable(DLCDepender); + + // Act + List avail = registry.Available(v0_24_2); + + // Assert + Assert.IsFalse(avail.Contains(DLCDepender)); + } + + [Test] + public void Available_MHInstalled_IncludesModulesDependingOnMH() + { + // Arrange + registry.RegisterDlc("MakingHistory-DLC", new UnmanagedModuleVersion("1.1.0")); + + CkanModule DLCDepender = CkanModule.FromJson(@"{ + ""identifier"": ""DLC-Depender"", + ""version"": ""1.0.0"", + ""download"": ""https://kerbalstuff.com/mod/269/Dogecoin%20Flag/download/1.01"", + ""depends"": [ { + ""name"":""MakingHistory-DLC"" + } ] + }"); + registry.AddAvailable(DLCDepender); + + // Act + List avail = registry.Available(v0_24_2); + + // Assert + Assert.IsTrue(avail.Contains(DLCDepender)); + } + + [Test] + public void Available_MH110Installed_IncludesModulesDependingOnMH110() + { + // Arrange + registry.RegisterDlc("MakingHistory-DLC", new UnmanagedModuleVersion("1.1.0")); + + CkanModule DLCDepender = CkanModule.FromJson(@"{ + ""identifier"": ""DLC-Depender"", + ""version"": ""1.0.0"", + ""download"": ""https://kerbalstuff.com/mod/269/Dogecoin%20Flag/download/1.01"", + ""depends"": [ { + ""name"": ""MakingHistory-DLC"", + ""version"": ""1.1.0"" + } ] + }"); + registry.AddAvailable(DLCDepender); + + // Act + List avail = registry.Available(v0_24_2); + + // Assert + Assert.IsTrue(avail.Contains(DLCDepender)); + } + + [Test] + public void Available_MH100Installed_ExcludesModulesDependingOnMH110() + { + // Arrange + registry.RegisterDlc("MakingHistory-DLC", new UnmanagedModuleVersion("1.0.0")); + + CkanModule DLCDepender = CkanModule.FromJson(@"{ + ""identifier"": ""DLC-Depender"", + ""version"": ""1.0.0"", + ""download"": ""https://kerbalstuff.com/mod/269/Dogecoin%20Flag/download/1.01"", + ""depends"": [ { + ""name"": ""MakingHistory-DLC"", + ""version"": ""1.1.0"" + } ] + }"); + registry.AddAvailable(DLCDepender); + + // Act + List avail = registry.Available(v0_24_2); + + // Assert + Assert.IsFalse(avail.Contains(DLCDepender)); + } + [Test] public void TxEmbeddedCommit() { @@ -186,4 +279,3 @@ public void TxAmbient() } } } -