Beispiel #1
0
        public void GetsInternalAvcCorrectly()
        {
            //Arrange
            var json = new JObject();

            json["spec_version"] = 1;
            json["identifier"]   = "DogeCoinFlag";
            json["version"]      = "1.0.0";
            json["download"]     = "https://awesomemod.example/AwesomeMod.zip";

            var sut = new ModuleService();

            // Act
            var result = sut.GetInternalAvc(CkanModule.FromJson(json.ToString()), TestData.DogeCoinFlagAvcZip());

            // Assert
            Assert.That(result, Is.Not.Null,
                        "ModuleService should get an internal AVC file."
                        );
            Assert.That(result.version, Is.EqualTo(new Version("1.1.0")),
                        "ModuleService should get correct version from the internal AVC file."
                        );
            Assert.That(result.ksp_version, Is.EqualTo(new KSPVersion("0.24.2")),
                        "ModuleService should get correct ksp_version from the internal AVC file."
                        );
            Assert.That(result.ksp_version_min, Is.EqualTo(new KSPVersion("0.24.0")),
                        "ModuleService should get correct ksp_version_min from the internal AVC file."
                        );
            Assert.That(result.ksp_version_max, Is.EqualTo(new KSPVersion("0.24.2")),
                        "ModuleService should get correct ksp_version_max from  the internal AVC file."
                        );
        }
Beispiel #2
0
        public void IsConsistent_MultipleVersionsOfSelfProvidesConflictingModule_Consistent()
        {
            // Arrange
            List <CkanModule> modules = new List <CkanModule>()
            {
                CkanModule.FromJson(@"{
                    ""identifier"": ""provides-conflictor"",
                    ""version"":    ""1.0.0"",
                    ""download"":   ""https://kerbalstuff.com/mod/269/Dogecoin%20Flag/download/1.01"",
                    ""provides"":   [ ""providee"" ],
                    ""conflicts"": [ {
                        ""name"":    ""providee""
                    } ]
                }"),
                CkanModule.FromJson(@"{
                    ""identifier"": ""provides-conflictor"",
                    ""version"":    ""1.2.3"",
                    ""download"":   ""https://kerbalstuff.com/mod/269/Dogecoin%20Flag/download/1.01"",
                    ""provides"":   [ ""providee"" ],
                    ""conflicts"": [ {
                        ""name"":    ""providee""
                    } ]
                }")
            };

            // Act & Assert
            Assert.IsTrue(CKAN.SanityChecker.IsConsistent(modules));
        }
Beispiel #3
0
        public void Validate(Metadata metadata)
        {
            Log.Info("Validating that metadata dependencies are consistent with cfg file syntax");

            JObject    json = metadata.Json();
            CkanModule mod  = CkanModule.FromJson(json.ToString());

            if (!mod.IsDLC)
            {
                var package = _http.DownloadModule(metadata);
                if (!string.IsNullOrEmpty(package))
                {
                    ZipFile zip = new ZipFile(package);

                    var mmConfigs = _moduleService.GetConfigFiles(mod, zip)
                                    .Where(cfg => moduleManagerRegex.IsMatch(
                                               new StreamReader(zip.GetInputStream(cfg.source)).ReadToEnd()))
                                    .Memoize();

                    bool dependsOnMM = mod?.depends?.Any(r => r.ContainsAny(identifiers)) ?? false;

                    if (!dependsOnMM && mmConfigs.Any())
                    {
                        Log.WarnFormat(
                            "ModuleManager syntax used without ModuleManager dependency: {0}",
                            string.Join(", ", mmConfigs.Select(cfg => cfg.source))
                            );
                    }
                    else if (dependsOnMM && !mmConfigs.Any())
                    {
                        Log.Warn("ModuleManager dependency may not be needed, no ModuleManager syntax found");
                    }
                }
            }
        }
Beispiel #4
0
        public void HasUpdate_WithUpgradeableManuallyInstalledMod_ReturnsTrue()
        {
            // Arrange
            using (var gameInstWrapper = new DisposableKSP())
            {
                CkanModule mod = CkanModule.FromJson(@"{
                    ""spec_version"": ""v1.4"",
                    ""identifier"":   ""AutoDetectedMod"",
                    ""version"":      ""1.0"",
                    ""ksp_version"":  ""1.11.1"",
                    ""download"":     ""https://mymods/AD/1.0""
                }");
                registry.AddAvailable(mod);
                GameInstance gameInst = gameInstWrapper.KSP;
                registry.RegisterDll(gameInst, Path.Combine(
                                         gameInst.GameDir(), "GameData", $"{mod.identifier}.dll"));
                GameVersionCriteria crit = new GameVersionCriteria(mod.ksp_version);

                // Act
                bool has = registry.HasUpdate(mod.identifier, crit);

                // Assert
                Assert.IsTrue(has, "Can't upgrade manually installed DLL");
            }
        }
Beispiel #5
0
        public void Validate(Metadata metadata)
        {
            Log.Info("Validating that craft files are installed into Ships");

            JObject    json = metadata.Json();
            CkanModule mod  = CkanModule.FromJson(json.ToString());

            if (!mod.IsDLC)
            {
                var package = _http.DownloadModule(metadata);
                if (!string.IsNullOrEmpty(package))
                {
                    var zip       = new ZipFile(package);
                    var ksp       = new KSP("/", "dummy", null, false);
                    var badCrafts = _moduleService.GetCrafts(mod, zip, ksp)
                                    .Where(f => !AllowedCraftPath(ksp.ToRelativeGameDir(f.destination)))
                                    .ToList();

                    if (badCrafts.Any())
                    {
                        Log.WarnFormat(
                            "Craft files installed outside Ships folder: {0}",
                            string.Join(", ", badCrafts.Select(f =>
                                                               ksp.ToRelativeGameDir(f.destination)
                                                               ))
                            );
                    }
                }
            }
        }
Beispiel #6
0
        public void CompatibleModules_PastAndFutureCompatibility_ReturnsCurrentOnly()
        {
            // Arrange
            CkanModule modFor161 = CkanModule.FromJson(@"{
                ""identifier"":  ""TypicalMod"",
                ""version"":     ""0.9.0"",
                ""download"":    ""https://kerbalstuff.com/mod/269/Dogecoin%20Flag/download/1.01"",
                ""ksp_version"": ""1.6.1""
            }");
            CkanModule modFor173 = CkanModule.FromJson(@"{
                ""identifier"":  ""TypicalMod"",
                ""version"":     ""1.0.0"",
                ""download"":    ""https://kerbalstuff.com/mod/269/Dogecoin%20Flag/download/1.01"",
                ""ksp_version"": ""1.7.3""
            }");
            CkanModule modFor181 = CkanModule.FromJson(@"{
                ""identifier"":  ""TypicalMod"",
                ""version"":     ""1.1.0"",
                ""download"":    ""https://kerbalstuff.com/mod/269/Dogecoin%20Flag/download/1.01"",
                ""ksp_version"": ""1.8.1""
            }");

            registry.AddAvailable(modFor161);
            registry.AddAvailable(modFor173);
            registry.AddAvailable(modFor181);

            // Act
            GameVersionCriteria v173   = new GameVersionCriteria(GameVersion.Parse("1.7.3"));
            List <CkanModule>   compat = registry.CompatibleModules(v173).ToList();

            // Assert
            Assert.IsFalse(compat.Contains(modFor161));
            Assert.IsTrue(compat.Contains(modFor173));
            Assert.IsFalse(compat.Contains(modFor181));
        }
Beispiel #7
0
        public void Validate(Metadata metadata)
        {
            Log.Info("Validating that metadata compatibility is appropriate for DLLs");

            JObject    json = metadata.Json();
            CkanModule mod  = CkanModule.FromJson(json.ToString());

            if (!mod.IsDLC)
            {
                var package = _http.DownloadModule(metadata);
                if (!string.IsNullOrEmpty(package))
                {
                    ZipFile zip = new ZipFile(package);

                    bool hasPlugin = _moduleService.GetPlugins(mod, zip).Any();

                    bool boundedCompatibility = json.ContainsKey("ksp_version") || json.ContainsKey("ksp_version_max");

                    if (hasPlugin && !boundedCompatibility)
                    {
                        Log.Warn("Unbounded future compatibility for module with a plugin, consider setting $vref or ksp_version or ksp_version_max");
                    }
                }
            }
        }
Beispiel #8
0
        public void KSPCompatibility_OutOfOrderGameVersions_TrueMaxVersion()
        {
            using (var tidy = new DisposableKSP())
            {
                // Arrange
                CkanModule mainVersion = CkanModule.FromJson(@"{
                    ""identifier"":  ""OutOfOrderMod"",
                    ""version"":     ""1.2.0"",
                    ""ksp_version"": ""0.90"",
                    ""download"":    ""http://www.ksp-ckan.org""
                }");
                CkanModule prevVersion = CkanModule.FromJson(@"{
                    ""identifier"":  ""OutOfOrderMod"",
                    ""version"":     ""1.1.0"",
                    ""ksp_version"": ""1.4.2"",
                    ""download"":    ""http://www.ksp-ckan.org""
                }");

                Registry registry = Registry.Empty();
                registry.AddAvailable(mainVersion);
                registry.AddAvailable(prevVersion);

                // Act
                GUIMod m = new GUIMod(mainVersion, registry, tidy.KSP.VersionCriteria(), false);

                // Assert
                Assert.AreEqual("1.4.2", m.KSPCompatibility);
            }
        }
Beispiel #9
0
        public void MetaData()
        {
            CkanModule module = CkanModule.FromJson(TestData.kOS_014());

            // TODO: Test all the metadata here!
            Assert.AreEqual("https://github.com/KSP-KOS/KOS/issues", module.resources.bugtracker.ToString());
        }
Beispiel #10
0
        public void Validate(Metadata metadata)
        {
            JObject    json = metadata.Json();
            CkanModule mod  = CkanModule.FromJson(json.ToString());

            // The Harmony2 module is allowed to install a Harmony DLL;
            // anybody else must have "provides":["Harmony1"] to do so
            if (!mod.IsDLC && mod.identifier != "Harmony2")
            {
                // Need to peek at the mod's files
                var package = _http.DownloadModule(metadata);
                if (!string.IsNullOrEmpty(package))
                {
                    ZipFile      zip  = new ZipFile(package);
                    GameInstance inst = new GameInstance(new KerbalSpaceProgram(), "/", "dummy", new NullUser());

                    var harmonyDLLs = _moduleService.GetPlugins(mod, zip, inst)
                                      .Select(instF => instF.source.Name)
                                      .Where(f => f.IndexOf("Harmony", StringComparison.InvariantCultureIgnoreCase) != -1)
                                      .ToList();
                    bool bundlesHarmony   = harmonyDLLs.Any();
                    bool providesHarmony1 = mod.ProvidesList.Contains("Harmony1");
                    if (bundlesHarmony && !providesHarmony1)
                    {
                        throw new Kraken($"Harmony DLL found at {string.Join(", ", harmonyDLLs)}, but Harmony1 is not in the provides list");
                    }
                    else if (providesHarmony1 && !bundlesHarmony)
                    {
                        Log.Warn("Harmony1 provided by module that doesn't install a Harmony DLL, consider removing from provides list");
                    }
                }
            }
        }
Beispiel #11
0
        public void Validate(Metadata metadata)
        {
            var mod  = CkanModule.FromJson(metadata.Json().ToString());
            var file = _http.DownloadPackage(metadata.Download, metadata.Identifier, metadata.RemoteTimestamp);

            // Make sure this would actually generate an install.
            if (!_moduleService.HasInstallableFiles(mod, file))
            {
                throw new Kraken(string.Format(
                                     "Module contains no files matching: {0}",
                                     mod.DescribeInstallStanzas()
                                     ));
            }

            // Make sure no paths include GameData other than at the start
            var gamedatas = _moduleService.FileDestinations(mod, file)
                            .Where(p => p.StartsWith("GameData") && p.LastIndexOf("/GameData/") > 0)
                            .ToList();

            if (gamedatas.Any())
            {
                var badPaths = string.Join("\r\n", gamedatas);
                throw new Kraken($"GameData directory found within GameData:\r\n{badPaths}");
            }
        }
Beispiel #12
0
        public void multilicense_986()
        {
            CkanModule mod = CkanModule.FromJson(TestData.kOS_014_multilicense());

            Assert.AreEqual(2, mod.license.Count, "Dual-license");
            Assert.AreEqual("GPL-3.0", mod.license[0].ToString());
            Assert.AreEqual("GPL-2.0", mod.license[1].ToString());
        }
Beispiel #13
0
 public void FutureModule()
 {
     // Modules from the future are unsupported.
     Assert.Throws <UnsupportedKraken>(delegate
     {
         CkanModule.FromJson(TestData.FutureMetaData());
     });
 }
Beispiel #14
0
        public void Validate(Metadata metadata)
        {
            var mod = CkanModule.FromJson(metadata.Json().ToString());

            if (!mod.IsCompatibleKSP(new KspVersionCriteria(null, buildMap.KnownVersions)))
            {
                throw new Kraken($"{metadata.Identifier} doesn't match any valid game version");
            }
        }
Beispiel #15
0
        public void good_resource_1208()
        {
            CkanModule mod = CkanModule.FromJson(TestData.kOS_014());

            Assert.AreEqual(
                "http://forum.kerbalspaceprogram.com/threads/68089-0-23-kOS-Scriptable-Autopilot-System-v0-11-2-13",
                mod.resources.homepage.ToString()
                );
        }
        public void Validate(Metadata metadata)
        {
            Log.Info("Validating that metadata vref is consistent with download contents");

            JObject json      = metadata.Json();
            var     noVersion = metadata.Version == null;

            if (noVersion)
            {
                json["version"] = "0";
            }
            var mod = CkanModule.FromJson(json.ToString());

            if (noVersion)
            {
                json.Remove("version");
            }

            if (!mod.IsDLC)
            {
                var file = _http.DownloadModule(metadata);
                if (!string.IsNullOrEmpty(file))
                {
                    bool hasVref = (metadata.Vref != null);

                    bool hasVersionFile = false;
                    try
                    {
                        // Pass a regex that matches anything so it returns the first if found
                        var avc = _moduleService.GetInternalAvc(mod, file, ".");
                        hasVersionFile = (avc != null);
                    }
                    catch (BadMetadataKraken k)
                    {
                        // This means the install stanzas don't match any files.
                        // That's not our problem; someone else will report it.
                    }
                    catch (Kraken k)
                    {
                        // If GetInternalAvc throws anything else, then there's a version file with a syntax error.
                        // This shouldn't cause the inflation to fail.
                        hasVersionFile = true;
                        Log.Warn(k.Message);
                    }

                    if (hasVref && !hasVersionFile)
                    {
                        Log.Warn("$vref present, version file missing");
                    }
                    else if (!hasVref && hasVersionFile)
                    {
                        Log.Warn("$vref absent, version file present");
                    }
                }
            }
        }
Beispiel #17
0
        public void FilterRead()
        {
            CkanModule module = CkanModule.FromJson(TestData.DogeCoinFlag_101());

            // Assert known things about this mod.
            Assert.IsNotNull(module.install[0].filter);
            Assert.IsNotNull(module.install[0].filter_regexp);

            Assert.AreEqual(2, module.install[0].filter.Count);
        }
Beispiel #18
0
        public void StandardName()
        {
            CkanModule module = CkanModule.FromJson(TestData.kOS_014());

            Assert.AreEqual(module.StandardName(), "kOS-0.14.zip");

            CkanModule module2 = CkanModule.FromJson(TestData.kOS_014_with_invalid_version_characters());

            Assert.AreEqual(module2.StandardName(), "kOS-0-14-0.zip");
        }
Beispiel #19
0
        internal static JObject HTTP(JObject orig_metadata, string remote_id, NetFileCache cache, IUser user)
        {
            var metadata = orig_metadata;

            // Check if we should auto-inflate.
            string kref = (string)metadata[expand_token];

            if (kref == (string)orig_metadata[expand_token] || kref == "#/ckan/http")
            {
                log.InfoFormat("Inflating from HTTP download... {0}", metadata[expand_token]);
                metadata["download"] = remote_id;
                metadata["version"]  = "0.0.0"; // add a dummy version that will be replaced by the KSP-AVC parser later
                metadata.Remove(expand_token);

                var remote_uri      = new Uri(remote_id);
                var downloaded_file = Net.Download(remote_uri);
                var module          = CkanModule.FromJson(metadata.ToString());

                if (metadata[version_token] != null && (metadata[version_token].ToString()).StartsWith("#/ckan/ksp-avc"))
                {
                    // TODO pass the correct vref here...
                    var versionRemote = FindVersionRemote(metadata, metadata[version_token].ToString());
                    metadata.Remove(version_token);

                    try
                    {
                        AVC avc = AVC.FromZipFile(module, downloaded_file, versionRemote.id);
                        avc.InflateMetadata(metadata, null, null);
                        metadata["version"] = avc.version.ToString();
                        module.version      = avc.version;
                    }
                    catch (JsonReaderException)
                    {
                        user.RaiseMessage("Bad embedded KSP-AVC file for {0}, halting.", module);
                        return(null);
                    }

                    // If we've done this, we need to re-inflate our mod, too.
                    module = CkanModule.FromJson(metadata.ToString());
                }
                else
                {
                    throw new Kraken("No $vref specified, $kref HTTP method requires it, bailing out..");
                }

                ModuleInstaller.CachedOrDownload(module.identifier, module.version, module.download, cache);
            }
            else
            {
                log.WarnFormat("Not inflating metadata for {0}", orig_metadata["identifier"]);
            }

            // metadata["download"] = metadata["download"].ToString() + '#' + metadata["version"].ToString();
            return(metadata);
        }
Beispiel #20
0
        public void bad_resource_1208()
        {
            JObject metadata = JObject.Parse(TestData.kOS_014());

            // Guess which string totally isn't a valid Url? This one.
            metadata["resources"]["homepage"] = "https://included%in%the%download";

            CkanModule mod = CkanModule.FromJson(metadata.ToString());

            Assert.IsNotNull(mod);
            Assert.IsNull(mod.resources.homepage);
        }
        public void Validate(Metadata metadata)
        {
            var mod  = CkanModule.FromJson(metadata.Json().ToString());
            var file = _http.DownloadPackage(metadata.Download, metadata.Identifier);

            // Make sure this would actually generate an install.

            if (!_moduleService.HasInstallableFiles(mod, file))
            {
                throw new Kraken("Module contains no files to install.");
            }
        }
Beispiel #22
0
        public void FutureModule()
        {
            if (CKAN.Meta.ReleaseNumber() == null)
            {
                Assert.Inconclusive("Dev build");
            }

            // Modules form the future are unsupported.

            Assert.Throws <UnsupportedKraken>(delegate
            {
                CkanModule.FromJson(TestData.FutureMetaData());
            });
        }
Beispiel #23
0
        public void Validate(Metadata metadata)
        {
            var mod = CkanModule.FromJson(metadata.Json().ToString());

            if (!mod.IsCompatibleKSP(new KspVersionCriteria(null, buildMap.KnownVersions)))
            {
                KspVersion minKsp = null, maxKsp = null;
                Registry.GetMinMaxVersions(new List <CkanModule>()
                {
                    mod
                }, out _, out _, out minKsp, out maxKsp);
                throw new Kraken($"{metadata.Identifier} doesn't match any valid game version: {KspVersionRange.VersionSpan(minKsp, maxKsp)}");
            }
        }
Beispiel #24
0
        public void Validate(Metadata metadata)
        {
            var mod  = CkanModule.FromJson(metadata.Json().ToString());
            var file = _http.DownloadPackage(metadata.Download, metadata.Identifier, metadata.RemoteTimestamp);

            // Make sure this would actually generate an install.

            if (!_moduleService.HasInstallableFiles(mod, file))
            {
                throw new Kraken(string.Format(
                                     "Module contains no files matching: {0}",
                                     mod.DescribeInstallStanzas()
                                     ));
            }
        }
Beispiel #25
0
        public void HasInstallableFilesReturnsTrueWhenInstallableFiles()
        {
            // Arrange
            var zip  = TestData.DogeCoinFlagZip();
            var json = JObject.Parse(TestData.DogeCoinFlag_101());

            var sut = new ModuleService();

            // Act
            var result = sut.HasInstallableFiles(CkanModule.FromJson(json.ToString()), zip);

            // Assert
            Assert.IsTrue(result,
                          "HasInstallableFiles() should return true when there are installable files."
                          );
        }
Beispiel #26
0
        public void HasUpdate_OtherModDependsOnCurrent_ReturnsFalse()
        {
            // Arrange
            using (var gameInstWrapper = new DisposableKSP())
            {
                CkanModule olderDepMod  = CkanModule.FromJson(@"{
                    ""spec_version"": ""v1.4"",
                    ""identifier"":   ""DependencyMod"",
                    ""version"":      ""1.0"",
                    ""ksp_version"":  ""1.11.1"",
                    ""download"":     ""https://mymods/DM/1.0""
                }");
                CkanModule newerDepMod  = CkanModule.FromJson(@"{
                    ""spec_version"": ""v1.4"",
                    ""identifier"":   ""DependencyMod"",
                    ""version"":      ""2.0"",
                    ""ksp_version"":  ""1.11.1"",
                    ""download"":     ""https://mymods/DM/2.0""
                }");
                CkanModule dependingMod = CkanModule.FromJson(@"{
                    ""spec_version"": ""v1.4"",
                    ""identifier"":   ""DependingMod"",
                    ""version"":      ""1.0"",
                    ""ksp_version"":  ""1.11.1"",
                    ""download"":     ""https://mymods/DM/2.0"",
                    ""depends"": [
                        {
                            ""name"":    ""DependencyMod"",
                            ""version"": ""1.0""
                        }
                    ]
                }");
                registry.AddAvailable(olderDepMod);
                registry.AddAvailable(newerDepMod);
                registry.AddAvailable(dependingMod);
                GameInstance gameInst = gameInstWrapper.KSP;
                registry.RegisterModule(olderDepMod, new string[0], gameInst, false);
                registry.RegisterModule(dependingMod, new string[0], gameInst, false);
                GameVersionCriteria crit = new GameVersionCriteria(olderDepMod.ksp_version);

                // Act
                bool has = registry.HasUpdate(olderDepMod.identifier, crit);

                // Assert
                Assert.IsFalse(has, "Upgrade allowed that would break another mod's dependency");
            }
        }
Beispiel #27
0
        /// <summary>
        /// Apply the locale transformation to the metadata
        /// </summary>
        /// <param name="metadata">Data about the module</param>
        /// <returns>
        /// Updated metadata with the `locales` property set
        /// </returns>
        public IEnumerable <Metadata> Transform(Metadata metadata, TransformOptions opts)
        {
            JObject json = metadata.Json();

            if (json.ContainsKey(localizationsProperty))
            {
                log.Debug("Localizations property already set, skipping");
                // Already set, don't override (skips a bunch of file processing)
                yield return(metadata);
            }
            else
            {
                CkanModule mod = CkanModule.FromJson(json.ToString());
                ZipFile    zip = new ZipFile(_http.DownloadPackage(
                                                 metadata.Download,
                                                 metadata.Identifier,
                                                 metadata.RemoteTimestamp
                                                 ));

                log.Debug("Extracting locales");
                // Extract the locale names from the ZIP's cfg files
                var locales = _moduleService.GetConfigFiles(mod, zip)
                              .Select(cfg => new StreamReader(zip.GetInputStream(cfg.source)).ReadToEnd())
                              .SelectMany(contents => localizationRegex.Matches(contents).Cast <Match>()
                                          .Select(m => m.Groups["contents"].Value))
                              .SelectMany(contents => localeRegex.Matches(contents).Cast <Match>()
                                          .Where(m => m.Groups["contents"].Value.Contains("="))
                                          .Select(m => m.Groups["locale"].Value))
                              .Distinct()
                              .Memoize();
                log.Debug("Locales extracted");

                if (locales.Any())
                {
                    json.SafeAdd(localizationsProperty, new JArray(locales));
                    log.Debug("Localizations property set");
                    yield return(new Metadata(json));
                }
                else
                {
                    log.Debug("No localizations found");
                    yield return(metadata);
                }
            }
        }
Beispiel #28
0
        public void AllowInstallsToScenarios()
        {
            // Bogus zip with example to install.
            var zip = ZipFile.Create(new MemoryStream());

            zip.BeginUpdate();
            zip.AddDirectory("saves");
            zip.AddDirectory("saves/scenarios");
            zip.Add(new ZipEntry("/saves/scenarios/AwesomeRace.sfs")
            {
                Size = 0, CompressedSize = 0
            });
            zip.CommitUpdate();

            // NB: The spec version really would be "v1.14", but travis is sad when it sees
            // releases that don't exist yet.
            var mod = CkanModule.FromJson(@"
                {
                    ""spec_version"": ""1"",
                    ""identifier"": ""AwesomeMod"",
                    ""version"": ""1.0.0"",
                    ""download"": ""https://awesomemod.example/AwesomeMod.zip"",
                    ""install"": [
                        {
                            ""file"": ""saves/scenarios/AwesomeRace.sfs"",
                            ""install_to"": ""Scenarios""
                        }
                    ]
                }")
            ;

            List <InstallableFile> results;

            using (var ksp = new DisposableKSP())
            {
                results = CKAN.ModuleInstaller.FindInstallableFiles(mod.install.First(), zip, ksp.KSP);

                Assert.AreEqual(
                    CKAN.KSPPathUtils.NormalizePath(
                        Path.Combine(ksp.KSP.GameDir(), "saves/scenarios/AwesomeRace.sfs")
                        ),
                    results.First().destination
                    );
            }
        }
Beispiel #29
0
        public void HasInstallableFilesReturnsFalseWhenNoInstallableFiles()
        {
            // Arrange
            var zip  = TestData.DogeCoinFlagZip();
            var json = JObject.Parse(TestData.DogeCoinFlag_101());

            json["install"][0]["file"] = "DOES_NOT_EXIST";

            var sut = new ModuleService();

            // Act
            var result = sut.HasInstallableFiles(CkanModule.FromJson(json.ToString()), zip);

            // Assert
            Assert.IsFalse(result,
                           "HasInstallableFiles() should return false when there are no installable files."
                           );
        }
Beispiel #30
0
        public void Validate(Metadata metadata)
        {
            Log.Info("Validating that metadata is appropriate for DLLs");

            JObject    json = metadata.Json();
            CkanModule mod  = CkanModule.FromJson(json.ToString());

            if (!mod.IsDLC)
            {
                var package = _http.DownloadModule(metadata);
                if (!string.IsNullOrEmpty(package))
                {
                    ZipFile      zip  = new ZipFile(package);
                    GameInstance inst = new GameInstance(new KerbalSpaceProgram(), "/", "dummy", new NullUser());

                    var  plugins   = _moduleService.GetPlugins(mod, zip, inst).ToList();
                    bool hasPlugin = plugins.Any();
                    if (hasPlugin)
                    {
                        var dllPaths = plugins
                                       .Select(f => inst.ToRelativeGameDir(f.destination))
                                       .OrderBy(f => f)
                                       .ToList();
                        var dllIdentifiers = dllPaths
                                             .Select(p => inst.DllPathToIdentifier(p))
                                             .Where(ident => !string.IsNullOrEmpty(ident) &&
                                                    !identifiersToIgnore.Contains(ident))
                                             .ToHashSet();
                        if (dllIdentifiers.Any() && !dllIdentifiers.Contains(metadata.Identifier))
                        {
                            Log.WarnFormat(
                                "No plugin matching the identifier, manual installations won't be detected: {0}",
                                string.Join(", ", dllPaths));
                        }

                        bool boundedCompatibility = json.ContainsKey("ksp_version") || json.ContainsKey("ksp_version_max");
                        if (!boundedCompatibility)
                        {
                            Log.Warn("Unbounded future compatibility for module with a plugin, consider setting $vref or ksp_version or ksp_version_max");
                        }
                    }
                }
            }
        }