diff --git a/Core/ModuleInstaller.cs b/Core/ModuleInstaller.cs index ed13591d6b..d14c14f4f5 100644 --- a/Core/ModuleInstaller.cs +++ b/Core/ModuleInstaller.cs @@ -340,10 +340,10 @@ private IEnumerable InstallModule(CkanModule module, string zip_filename { // Find where we're installing identifier.optionalversion.dll // (file name might not be an exact match with manually installed) - var dllFolders = files.Where(f => - Path.GetFileName(f.destination).StartsWith(module.identifier) - && f.destination.EndsWith(".dll", StringComparison.CurrentCultureIgnoreCase)) - .Select(f => Path.GetDirectoryName(ksp.ToRelativeGameDir(f.destination))) + var dllFolders = files + .Select(f => ksp.ToRelativeGameDir(f.destination)) + .Where(relPath => ksp.DllPathToIdentifier(relPath) == module.identifier) + .Select(relPath => Path.GetDirectoryName(relPath)) .ToHashSet(); // Make sure that the DLL is actually included in the install // (NearFutureElectrical, NearFutureElectrical-Core) diff --git a/Tests/Core/ModuleInstallerTests.cs b/Tests/Core/ModuleInstallerTests.cs index be0ffa18f7..1a21969698 100644 --- a/Tests/Core/ModuleInstallerTests.cs +++ b/Tests/Core/ModuleInstallerTests.cs @@ -1118,5 +1118,62 @@ public void Upgrade_WithAutoInst_RemovesAutoRemovable(string[] regularMods, registry.InstalledModules.Select(im => im.identifier).ToArray()); } } + + [TestCase] + public void Install_WithMatchedUnmanagedDll_Throws() + { + const string unmanaged = "GameData/DogeCoinPlugin.1.0.0.dll"; + var kraken = Assert.Throws(() => + installTestPlugin(unmanaged, + TestData.DogeCoinPlugin(), + TestData.DogeCoinPluginZip())); + Assert.AreEqual(unmanaged, kraken.path); + } + + [TestCase] + public void Install_WithUnmatchedUnmanagedDll_DoesNotThrow() + { + Assert.DoesNotThrow(() => installTestPlugin("GameData/DogeCoinPlugin-1-0-0.dll", + TestData.DogeCoinPlugin(), + TestData.DogeCoinPluginZip()), + "Unmanaged file must match identifier"); + Assert.DoesNotThrow(() => installTestPlugin("GameData/DogeCoinPlugin.dll", + TestData.DogeCoinPluginAddonFerram(), + TestData.DogeCoinPluginAddonFerramZip()), + "Managed file being installed must match identifier"); + } + + private void installTestPlugin(string unmanaged, string moduleJson, string zipPath) + { + // Arrange + using (var repo = new TemporaryRepository(moduleJson)) + using (var repoData = new TemporaryRepositoryData(nullUser, repo.repo)) + using (var inst = new DisposableKSP()) + using (var config = new FakeConfiguration(inst.KSP, inst.KSP.Name)) + using (var manager = new GameInstanceManager(nullUser, config) + { + CurrentInstance = inst.KSP + }) + { + var regMgr = RegistryManager.Instance(manager.CurrentInstance, + repoData.Manager); + var module = CkanModule.FromJson(moduleJson); + var modules = new List { module }; + var installer = new ModuleInstaller(inst.KSP, manager.Cache, nullUser); + File.WriteAllText(inst.KSP.ToAbsoluteGameDir(unmanaged), + "Not really a DLL, are we?"); + regMgr.ScanUnmanagedFiles(); + manager.Cache.Store(module, zipPath, new Progress(bytes => {})); + + // Act + HashSet possibleConfigOnlyDirs = null; + new ModuleInstaller(inst.KSP, manager.Cache, nullUser) + .InstallList(modules, + new RelationshipResolverOptions(), + regMgr, + ref possibleConfigOnlyDirs); + } + } + } } diff --git a/Tests/Data/DogeCoinPlugin.zip b/Tests/Data/DogeCoinPlugin.zip index 43b12641d7..8b3ec85a34 100644 Binary files a/Tests/Data/DogeCoinPlugin.zip and b/Tests/Data/DogeCoinPlugin.zip differ diff --git a/Tests/Data/DogeCoinPluginAddonFerram.zip b/Tests/Data/DogeCoinPluginAddonFerram.zip new file mode 100644 index 0000000000..2c09d43e17 Binary files /dev/null and b/Tests/Data/DogeCoinPluginAddonFerram.zip differ diff --git a/Tests/Data/TestData.cs b/Tests/Data/TestData.cs index 403b922b2b..a7f4a39b15 100644 --- a/Tests/Data/TestData.cs +++ b/Tests/Data/TestData.cs @@ -46,13 +46,6 @@ public static string DogeCoinFlagZipWithExtras() public static string DogeCoinFlagZipCorrupt() => Path.Combine(DataDir(), "DogeCoinFlag-1.01-corrupt.zip"); - /// - /// Adds a plugins directory to the DogeCoinFlag directory to test. - /// - /// The coin plugin. - public static string DogeCoinPluginZip() - => Path.Combine(DataDir(), "DogeCoinPlugin.zip"); - /// /// DogeCoinFlag 1.01 info. This doesn't contain any bugs. /// @@ -339,8 +332,8 @@ public static string DogeCoinPlugin() ""identifier"": ""DogeCoinPlugin"", ""install"": [ { - ""file"": ""GameData/DogeCoinFlag/plugin"", - ""install_to"": ""GameData/DogeCoinFlag"", + ""file"": ""GameData/DogeCoinPlugin/Plugins"", + ""install_to"": ""GameData/DogeCoinPlugin"", ""filter"" : [ ""Thumbs.db"", ""README.md"" ], ""filter_regexp"" : ""\\.bak$"" } @@ -357,10 +350,10 @@ public static string DogeCoinPlugin() ""author"": ""politas"", ""version"": ""1.01"", ""download"": ""https://kerbalstuff.com/mod/269/Dogecoin%20Flag/download/1.01"", - ""download_size"": 528, + ""download_size"": 447, ""download_hash"": { - ""sha1"": ""8B4F4DD53E702E0C1D3FBCA1C9CB4E4027F50E8A"", - ""sha256"": ""CEB1F30B8E1561EFD7F02D680407FE8FEC36B37AE073ABA8B06EEE05701F0EEF"", + ""sha1"": ""9EC130C7D212DB664A97C28AFCA46CD186B73B3C"", + ""sha256"": ""C7D787A875C92A0DCA5B7F0B8900F92F5FAE9DC23F2FDB95509B31420F209015"", }, ""ksp_version"": ""0.25"" } @@ -369,6 +362,54 @@ public static string DogeCoinPlugin() public static CkanModule DogeCoinPlugin_module() => CkanModule.FromJson(DogeCoinPlugin()); + /// + /// Adds a plugins directory to the DogeCoinFlag directory to test. + /// + /// The coin plugin. + public static string DogeCoinPluginZip() + => Path.Combine(DataDir(), "DogeCoinPlugin.zip"); + + public static string DogeCoinPluginAddonFerram() + => @" + { + ""spec_version"": ""v1.2"", + ""identifier"": ""DogeCoinPlugin"", + ""install"": [ + { + ""file"": ""GameData/DogeCoinPlugin/Plugins"", + ""install_to"": ""GameData/DogeCoinPlugin"", + ""filter"" : [ ""Thumbs.db"", ""README.md"" ], + ""filter_regexp"" : ""\\.bak$"" + } + ], + ""resources"": { + ""kerbalstuff"": { + ""url"": ""https://kerbalstuff.com/mod/269/Dogecoin%20Flag"" + }, + ""homepage"": ""https://www.reddit.com/r/dogecoin/comments/1tdlgg/i_made_a_more_accurate_dogecoin_and_a_ksp_flag/"" + }, + ""name"": ""Dogecoin Plugin Addon - Ferram"", + ""license"": ""CC-BY"", + ""abstract"": ""Such plugin. Very linkage. Dynamically Minmus! Wow!"", + ""author"": ""politas"", + ""version"": ""1.01"", + ""download"": ""https://kerbalstuff.com/mod/269/Dogecoin%20Flag/download/1.01"", + ""download_size"": 357, + ""download_hash"": { + ""sha1"": ""07B05B89258E0D17FF7586054F6CE486AA6FFB7D"", + ""sha256"": ""568F4F2C8B3C6492CF63518272F0DF86E3FBC6A3ADBCC9EC3FD2B6457CC67053"", + }, + ""ksp_version"": ""0.25"" + } + "; + + /// + /// Adds a plugins directory to the DogeCoinFlag directory to test. + /// + /// The coin plugin. + public static string DogeCoinPluginAddonFerramZip() + => Path.Combine(DataDir(), "DogeCoinPluginAddonFerram.zip"); + /// /// Taurus HCV pod, which seems to cause weird KS errors when the unescaped /// download string is used.