public void FakeInstance_ValidArgumentsWithDLCs_ManagerHasValidInstance() { string name = "testname"; KspVersion mhVersion = KspVersion.Parse("1.1.0"); KspVersion bgVersion = KspVersion.Parse("1.0.0"); string tempdir = TestData.NewTempDir(); KspVersion version = KspVersion.Parse("1.7.1"); Dictionary <CKAN.DLC.IDlcDetector, KspVersion> dlcs = new Dictionary <CKAN.DLC.IDlcDetector, KspVersion>() { { new CKAN.DLC.MakingHistoryDlcDetector(), mhVersion }, { new CKAN.DLC.BreakingGroundDlcDetector(), bgVersion } }; manager.FakeInstance(name, tempdir, version, dlcs); CKAN.KSP newKSP = new CKAN.KSP(tempdir, name, new NullUser()); CKAN.DLC.MakingHistoryDlcDetector mhDetector = new CKAN.DLC.MakingHistoryDlcDetector(); CKAN.DLC.BreakingGroundDlcDetector bgDetector = new CKAN.DLC.BreakingGroundDlcDetector(); Assert.IsTrue(manager.HasInstance(name)); Assert.IsTrue(mhDetector.IsInstalled(newKSP, out string _, out UnmanagedModuleVersion detectedMhVersion)); Assert.IsTrue(bgDetector.IsInstalled(newKSP, out string _, out UnmanagedModuleVersion detectedBgVersion)); Assert.IsTrue(detectedMhVersion == new UnmanagedModuleVersion(mhVersion.ToString())); Assert.IsTrue(detectedBgVersion == new UnmanagedModuleVersion(bgVersion.ToString())); // Tidy up. CKAN.RegistryManager.Instance(newKSP).ReleaseLock(); System.IO.Directory.Delete(tempdir, true); }
/// <summary> /// Returns a human readable string indicating the highest compatible /// version of KSP this module will run with. (Eg: 1.0.2, /// "All versions", etc). /// /// This is for *human consumption only*, as the strings may change in the /// future as we support additional locales. /// </summary> public string HighestCompatibleKSP() { KspVersion v = LatestCompatibleKSP(); if (v.IsAny) { return("All versions"); } else { return(v.ToString()); } }
/// <summary> /// Returns a human readable string indicating the highest compatible /// version of KSP this module will run with. (Eg: 1.0.2, 1.0.2+, /// "All version", etc). /// /// This is for *human consumption only*, as the strings may change in the /// future as we support additional locales. /// </summary> public string HighestCompatibleKSP() { // Find the highest compatible KSP version if (ksp_version_max != null) { return(ksp_version_max.ToString()); } else if (ksp_version != null) { return(ksp_version.ToString()); } else if (ksp_version_min != null) { return(ksp_version_min + "+"); } return("All versions"); }
public void QuadrupleParameterCtorWorksCorrectly() { // Act var result = new KspVersion(1, 2, 3, 4); // Assert Assert.AreEqual(1, result.Major); Assert.AreEqual(2, result.Minor); Assert.AreEqual(3, result.Patch); Assert.AreEqual(4, result.Build); Assert.IsTrue(result.IsMajorDefined); Assert.IsTrue(result.IsMinorDefined); Assert.IsTrue(result.IsPatchDefined); Assert.IsTrue(result.IsBuildDefined); Assert.IsTrue(result.IsFullyDefined); Assert.IsFalse(result.IsAny); Assert.AreEqual("1.2.3.4", result.ToString()); }
public void SingleParameterCtorWorksCorrectly() { // Act var result = new KspVersion(1); // Assert Assert.AreEqual(1, result.Major); Assert.AreEqual(-1, result.Minor); Assert.AreEqual(-1, result.Patch); Assert.AreEqual(-1, result.Build); Assert.IsTrue(result.IsMajorDefined); Assert.IsFalse(result.IsMinorDefined); Assert.IsFalse(result.IsPatchDefined); Assert.IsFalse(result.IsBuildDefined); Assert.IsFalse(result.IsFullyDefined); Assert.IsFalse(result.IsAny); Assert.AreEqual("1", result.ToString()); }
private Metadata TransformOne(JObject json, CurseMod curseMod, CurseFile latestVersion) { Log.InfoFormat("Found Curse mod: {0} {1}", curseMod.GetName(), latestVersion.GetFileVersion()); // Only pre-fill version info if there's none already. GH #199 if (json["ksp_version_min"] == null && json["ksp_version_max"] == null && json["ksp_version"] == null) { KspVersion minVer = latestVersion.versions.Min(); KspVersion maxVer = latestVersion.versions.Max(); if (minVer == maxVer) { Log.DebugFormat("Writing ksp_version from Curse: {0}", latestVersion.version); json["ksp_version"] = latestVersion.version.ToString(); } else { Log.DebugFormat("Writing ksp_version_min,_max from Curse: {0}, {1}", minVer, maxVer); json["ksp_version_min"] = minVer.ToString(); json["ksp_version_max"] = maxVer.ToString(); } } var useDownloadNameVersion = false; var useFilenameVersion = false; var useCurseIdVersion = false; var curseMetadata = (JObject)json["x_netkan_curse"]; if (curseMetadata != null) { var useDownloadNameVersionMetadata = (bool?)curseMetadata["use_download_name_version"]; if (useDownloadNameVersionMetadata != null) { useDownloadNameVersion = useDownloadNameVersionMetadata.Value; } var useFilenameVersionMetadata = (bool?)curseMetadata["use_filename_version"]; if (useFilenameVersionMetadata != null) { useFilenameVersion = useFilenameVersionMetadata.Value; } var useCurseIdVersionMetadata = (bool?)curseMetadata["use_curse_id_version"]; if (useCurseIdVersionMetadata != null) { useCurseIdVersion = useCurseIdVersionMetadata.Value; } if ((useDownloadNameVersion ? 1 : 0) + (useFilenameVersion ? 1 : 0) + (useCurseIdVersion ? 1 : 0) > 1) { throw new Kraken("Conflicting version options set in x_netkan_curse"); } } json.SafeAdd("name", curseMod.GetName()); json.SafeAdd("abstract", curseMod.description); if (useDownloadNameVersion) { json.SafeAdd("version", latestVersion.name); } else if (useFilenameVersion) { json.SafeAdd("version", latestVersion.GetFilename()); } else if (useCurseIdVersion) { json.SafeAdd("version", latestVersion.GetCurseIdVersion()); } else { json.SafeAdd("version", latestVersion.GetFileVersion()); } json.SafeAdd("author", JToken.FromObject(curseMod.authors)); json.SafeAdd("download", Regex.Replace(latestVersion.GetDownloadUrl(), " ", "%20")); // Curse provides users with the following default selection of licenses. Let's convert them to CKAN // compatible license strings if possible. // // "Academic Free License v3.0" - Becomes "AFL-3.0" // "Ace3 Style BSD" - Becomes "restricted" // "All Rights Reserved" - Becomes "restricted" // "Apache License version 2.0" - Becomes "Apache-2.0" // "Apple Public Source License version 2.0 (APSL)" - Becomes "APSL-2.0" // "BSD License" - Becomes "BSD-3-clause" // "Common Development and Distribution License (CDDL) " - Becomes "CDDL" // "GNU Affero General Public License version 3 (AGPLv3)" - Becomes "AGPL-3.0" // "GNU General Public License version 2 (GPLv2)" - Becomes "GPL-2.0" // "GNU General Public License version 3 (GPLv3)" - Becomes "GPL-3.0" // "GNU Lesser General Public License version 2.1 (LGPLv2.1)" - Becomes "LGPL-2.1" // "GNU Lesser General Public License version 3 (LGPLv3)" - Becomes "LGPL-3.0" // "ISC License (ISCL)" - Becomes "ISC" // "Microsoft Public License (Ms-PL)" - Becomes "Ms-PL" // "Microsoft Reciprocal License (Ms-RL)" - Becomes "Ms-RL" // "MIT License" - Becomes "MIT" // "Mozilla Public License 1.0 (MPL)" - Becomes "MPL-1.0" // "Mozilla Public License 1.1 (MPL 1.1)" - Becomes "MPL-1.1" // "Public Domain" - Becomes "public-domain" // "WTFPL" - Becomes "WTFPL" // "zlib/libpng License" - Becomes "Zlib" // "Custom License" - Becomes "unknown" var curseLicense = curseMod.license.Trim(); switch (curseLicense) { case "Academic Free License v3.0": json.SafeAdd("license", "AFL-3.0"); break; case "Ace3 Style BSD": json.SafeAdd("license", "restricted"); break; case "All Rights Reserved": json.SafeAdd("license", "restricted"); break; case "Apache License version 2.0": json.SafeAdd("license", "Apache-2.0"); break; case "Apple Public Source License version 2.0 (APSL)": json.SafeAdd("license", "APSL-2.0"); break; case "BSD License": json.SafeAdd("license", "BSD-3-clause"); break; case "Common Development and Distribution License (CDDL) ": json.SafeAdd("license", "CDDL"); break; case "GNU Affero General Public License version 3 (AGPLv3)": json.SafeAdd("license", "AGPL-3.0"); break; case "GNU General Public License version 2 (GPLv2)": json.SafeAdd("license", "GPL-2.0"); break; case "GNU General Public License version 3 (GPLv3)": json.SafeAdd("license", "GPL-3.0"); break; case "GNU Lesser General Public License version 2.1 (LGPLv2.1)": json.SafeAdd("license", "LGPL-2.1"); break; case "GNU Lesser General Public License version 3 (LGPLv3)": json.SafeAdd("license", "LGPL-3.0"); break; case "ISC License (ISCL)": json.SafeAdd("license", "ISC"); break; case "Microsoft Public License (Ms-PL)": json.SafeAdd("license", "Ms-PL"); break; case "Microsoft Reciprocal License (Ms-RL)": json.SafeAdd("license", "Ms-RL"); break; case "MIT License": json.SafeAdd("license", "MIT"); break; case "Mozilla Public License 1.0 (MPL)": json.SafeAdd("license", "MPL-1.0"); break; case "Mozilla Public License 1.1 (MPL 1.1)": json.SafeAdd("license", "MPL-1.1"); break; case "Public Domain": json.SafeAdd("license", "public-domain"); break; case "WTFPL": json.SafeAdd("license", "WTFPL"); break; case "zlib/libpng License": json.SafeAdd("license", "Zlib"); break; default: json.SafeAdd("license", "unknown"); break; } // Make sure resources exist. if (json["resources"] == null) { json["resources"] = new JObject(); } var resourcesJson = (JObject)json["resources"]; //resourcesJson.SafeAdd("homepage", Normalize(curseMod.website)); //resourcesJson.SafeAdd("repository", Normalize(curseMod.source_code)); resourcesJson.SafeAdd("curse", curseMod.GetProjectUrl()); if (curseMod.thumbnail != null) { resourcesJson.SafeAdd("x_screenshot", Normalize(new Uri(curseMod.thumbnail))); } Log.DebugFormat("Transformed metadata:{0}{1}", Environment.NewLine, json); return(new Metadata(json)); }
/// <summary> /// Create a new fake KSP instance /// </summary> /// <param name="newName">The name for the new instance.</param> /// <param name="newPath">The loaction of the new instance.</param> /// <param name="version">The version of the new instance. Should have a build number.</param> /// <param name="dlcs">The IDlcDetector implementations for the DLCs that should be faked and the requested dlc version as a dictionary.</param> public void FakeInstance(string newName, string newPath, KspVersion version, Dictionary<DLC.IDlcDetector, KspVersion> dlcs = null) { TxFileManager fileMgr = new TxFileManager(); using (TransactionScope transaction = CkanTransaction.CreateTransactionScope()) { if (HasInstance(newName)) { throw new InstanceNameTakenKraken(newName); } if (!version.InBuildMap()) { throw new BadKSPVersionKraken(String.Format("The specified KSP version is not a known version: {0}", version.ToString())); } if (Directory.Exists(newPath) && (Directory.GetFiles(newPath).Length != 0 || Directory.GetDirectories(newPath).Length != 0)) { throw new BadInstallLocationKraken("The specified folder already exists and is not empty."); } try { log.DebugFormat("Creating folder structure and text files at {0} for KSP version {1}", Path.GetFullPath(newPath), version.ToString()); // Create a KSP root directory, containing a GameData folder, a buildID.txt/buildID64.txt and a readme.txt fileMgr.CreateDirectory(newPath); fileMgr.CreateDirectory(Path.Combine(newPath, "GameData")); fileMgr.CreateDirectory(Path.Combine(newPath, "Ships")); fileMgr.CreateDirectory(Path.Combine(newPath, "Ships", "VAB")); fileMgr.CreateDirectory(Path.Combine(newPath, "Ships", "SPH")); fileMgr.CreateDirectory(Path.Combine(newPath, "Ships", "@thumbs")); fileMgr.CreateDirectory(Path.Combine(newPath, "Ships", "@thumbs", "VAB")); fileMgr.CreateDirectory(Path.Combine(newPath, "Ships", "@thumbs", "SPH")); // Don't write the buildID.txts if we have no build, otherwise it would be -1. if (version.IsBuildDefined) { fileMgr.WriteAllText(Path.Combine(newPath, "buildID.txt"), String.Format("build id = {0}", version.Build)); fileMgr.WriteAllText(Path.Combine(newPath, "buildID64.txt"), String.Format("build id = {0}", version.Build)); } // Create the readme.txt WITHOUT build number. fileMgr.WriteAllText(Path.Combine(newPath, "readme.txt"), String.Format("Version {0}", new KspVersion(version.Major, version.Minor, version.Patch).ToString())); // Create the needed folder structure and the readme.txt for DLCs that should be simulated. if (dlcs != null) { foreach (KeyValuePair<DLC.IDlcDetector, KspVersion> dlc in dlcs) { DLC.IDlcDetector dlcDetector = dlc.Key; KspVersion dlcVersion = dlc.Value; if (!dlcDetector.AllowedOnBaseVersion(version)) throw new WrongKSPVersionKraken( version, String.Format("KSP version {0} or above is needed for {1} DLC.", dlcDetector.ReleaseGameVersion, dlcDetector.IdentifierBaseName )); string dlcDir = Path.Combine(newPath, dlcDetector.InstallPath()); fileMgr.CreateDirectory(dlcDir); fileMgr.WriteAllText( Path.Combine(dlcDir, "readme.txt"), String.Format("Version {0}", dlcVersion)); } } // Add the new instance to the registry KSP new_instance = new KSP(newPath, newName, User, false); AddInstance(new_instance); } // Thrown by AddInstance() if created instance is not valid. // Thrown f.e. if a write operation didn't complete for unknown reasons. catch (NotKSPDirKraken kraken) { throw kraken; } transaction.Complete(); } }
/// <summary> /// Create a new fake KSP instance /// </summary> /// <param name="new_name">The name for the new instance.</param> /// <param name="new_path">The loaction of the new instance.</param> /// <param name="version">The version of the new instance. Should have a build number.</param> /// <param name="dlcVersion">The version of the DLC. Null if DLC should be faked.</param> public void FakeInstance(string new_name, string new_path, KspVersion version, string dlcVersion = null) { if (!version.InBuildMap()) { throw new IncorrectKSPVersionKraken(String.Format("The specified KSP version is not a known version: {0}", version.ToString())); } if (Directory.Exists(new_path) && (Directory.GetFiles(new_path).Length != 0 || Directory.GetDirectories(new_path).Length != 0)) { throw new BadInstallLocationKraken("The specified folder already exists and is not empty."); } try { log.DebugFormat("Creating folder structure and text files at {0} for KSP version {1}", Path.GetFullPath(new_path), version.ToString()); // Create a KSP root directory, containing a GameData folder, a buildID.txt/buildID64.txt and a readme.txt Directory.CreateDirectory(new_path); Directory.CreateDirectory(Path.Combine(new_path, "GameData")); Directory.CreateDirectory(Path.Combine(new_path, "Ships")); Directory.CreateDirectory(Path.Combine(new_path, "Ships", "VAB")); Directory.CreateDirectory(Path.Combine(new_path, "Ships", "SPH")); Directory.CreateDirectory(Path.Combine(new_path, "Ships", "@thumbs")); Directory.CreateDirectory(Path.Combine(new_path, "Ships", "@thumbs", "VAB")); Directory.CreateDirectory(Path.Combine(new_path, "Ships", "@thumbs", "SPH")); // Don't write the buildID.txts if we have no build, otherwise it would be -1. if (version.IsBuildDefined) { File.WriteAllText(Path.Combine(new_path, "buildID.txt"), String.Format("build id = {0}", version.Build)); File.WriteAllText(Path.Combine(new_path, "buildID64.txt"), String.Format("build id = {0}", version.Build)); } // Create the readme.txt WITHOUT build number. File.WriteAllText(Path.Combine(new_path, "readme.txt"), String.Format("Version {0}", new KspVersion(version.Major, version.Minor, version.Patch).ToString())); // If a installed DLC should be simulated, we create the needed folder structure and the readme.txt if (!String.IsNullOrEmpty(dlcVersion) && version.CompareTo(new KspVersion(1, 4, 0)) >= 0) { Directory.CreateDirectory(Path.Combine(new_path, "GameData", "SquadExpansion", "MakingHistory")); File.WriteAllText( Path.Combine(new_path, "GameData", "SquadExpansion", "MakingHistory", "readme.txt"), String.Format("Version {0}", dlcVersion)); } // Add the new instance to the registry KSP new_instance = new KSP(new_path, new_name, User); AddInstance(new_instance); } // Thrown by AddInstance() if created instance is not valid. // Thrown f.e. if a write operation didn't complete for unknown reasons. catch (NotKSPDirKraken kraken) { throw kraken; } }
public GUIMod(CkanModule mod, IRegistryQuerier registry, KspVersionCriteria current_ksp_version, bool incompatible = false) { IsCKAN = mod is CkanModule; //Currently anything which could alter these causes a full reload of the modlist // If this is ever changed these could be moved into the properties Mod = mod; IsInstalled = registry.IsInstalled(mod.identifier, false); IsInstallChecked = IsInstalled; HasUpdate = registry.HasUpdate(mod.identifier, current_ksp_version); IsIncompatible = incompatible || !mod.IsCompatibleKSP(current_ksp_version); IsAutodetected = registry.IsAutodetected(mod.identifier); Authors = mod.author == null ? "N/A" : String.Join(",", mod.author); var installed_version = registry.InstalledVersion(mod.identifier); ModuleVersion latest_version = null; var ksp_version = mod.ksp_version; try { var latest_available = registry.LatestAvailable(mod.identifier, current_ksp_version); if (latest_available != null) { latest_version = latest_available.version; } } catch (ModuleNotFoundKraken) { latest_version = installed_version; } InstalledVersion = installed_version != null?installed_version.ToString() : "-"; // Let's try to find the compatibility for this mod. If it's not in the registry at // all (because it's a DarkKAN mod) then this might fail. CkanModule latest_available_for_any_ksp = null; try { latest_available_for_any_ksp = registry.LatestAvailable(mod.identifier, null); } catch { // If we can't find the mod in the CKAN, but we've a CkanModule installed, then // use that. if (IsCKAN) { latest_available_for_any_ksp = (CkanModule)mod; } } // If there's known information for this mod in any form, calculate the highest compatible // KSP. if (latest_available_for_any_ksp != null) { if (!VersionMaxWasGenerated) { VersionMaxWasGenerated = true; List <KspVersion> versions = new KspBuildMap(new Win32Registry()).KnownVersions; // should be sorted VersionsMax = new Dictionary <string, KspVersion>(); VersionsMax[""] = versions.Last(); foreach (var v in versions) { VersionsMax[v.Major.ToString()] = v; // add or replace VersionsMax[v.Major + "." + v.Minor] = v; } } const int Undefined = -1; KspVersion ksp_ver = registry.LatestCompatibleKSP(mod.identifier); string ver = ksp_ver?.ToString(); int major = ksp_ver.Major, minor = ksp_ver.Minor, patch = ksp_ver.Patch; KspVersion value; if (major == Undefined //|| (major >= UptoNines(VersionsMax[""].Major)) // 9.99.99 || (major > VersionsMax[""].Major) || // 2.0.0 (major == VersionsMax[""].Major && VersionsMax.TryGetValue(major.ToString(), out value) && minor >= UptoNines(value.Minor)) // 1.99.99 ? ) { KSPCompatibility = "any"; } else if (minor != Undefined && VersionsMax.TryGetValue(major + "." + minor, out value) && (patch == Undefined || patch >= UptoNines(value.Patch)) ) { KSPCompatibility = major + "." + minor + "." + UptoNines(value.Patch); } else { KSPCompatibility = ver; } // KSPCompatibility += " | " + major + "." + minor + "." + patch; // for testing // If the mod we have installed is *not* the mod we have installed, or we don't know // what we have installed, indicate that an upgrade would be needed. if (installed_version == null || !latest_available_for_any_ksp.version.IsEqualTo(installed_version)) { KSPCompatibilityLong = string.Format("{0} (using mod version {1})", KSPCompatibility, latest_available_for_any_ksp.version); // ver, latest_available_for_any_ksp.version); // true values in the right tab } else { KSPCompatibilityLong = KSPCompatibility; // KSPCompatibilityLong = ver; // true values in the right tab } } else { // No idea what this mod is, sorry! KSPCompatibility = KSPCompatibilityLong = "unknown"; } if (latest_version != null) { LatestVersion = latest_version.ToString(); } else if (latest_available_for_any_ksp != null) { LatestVersion = latest_available_for_any_ksp.version.ToString(); } else { LatestVersion = "-"; } KSPversion = ksp_version != null?ksp_version.ToString() : "-"; Abstract = mod.@abstract; // If we have a homepage provided, use that; otherwise use the spacedock page, curse page or the github repo so that users have somewhere to get more info than just the abstract. Homepage = "N/A"; if (mod.resources != null) { if (mod.resources.homepage != null) { Homepage = mod.resources.homepage.ToString(); } else if (mod.resources.spacedock != null) { Homepage = mod.resources.spacedock.ToString(); } else if (mod.resources.curse != null) { Homepage = mod.resources.curse.ToString(); } else if (mod.resources.repository != null) { Homepage = mod.resources.repository.ToString(); } } Identifier = mod.identifier; DownloadSize = (mod.download_size == 0) ? "N/A" : CkanModule.FmtSize(mod.download_size); Abbrevation = new string(mod.name.Split(' '). Where(s => s.Length > 0).Select(s => s[0]).ToArray()); UpdateIsCached(); }