/// <summary> /// Return the most recent release of a module with a optional ksp version to target and a RelationshipDescriptor to satisfy. /// </summary> /// <param name="ksp_version">If not null only consider mods which match this ksp version.</param> /// <param name="relationship">If not null only consider mods which satisfy the RelationshipDescriptor.</param> /// <param name="installed">Modules that are already installed</param> /// <param name="toInstall">Modules that are planned to be installed</param> /// <returns></returns> public CkanModule Latest( KspVersionCriteria ksp_version = null, RelationshipDescriptor relationship = null, IEnumerable <CkanModule> installed = null, IEnumerable <CkanModule> toInstall = null ) { log.DebugFormat("Our dictionary has {0} keys", module_version.Keys.Count); IEnumerable <CkanModule> modules = module_version.Values; if (relationship != null) { modules = modules.Where(relationship.WithinBounds); } if (ksp_version != null) { modules = modules.Where(m => m.IsCompatibleKSP(ksp_version)); } if (installed != null) { modules = modules.Where(m => DependsAndConflictsOK(m, installed)); } if (toInstall != null) { modules = modules.Where(m => DependsAndConflictsOK(m, toInstall)); } return(modules.LastOrDefault()); }
/// <summary> /// Initialize a GUIMod based on just an identifier /// </summary> /// <param name="identifier">The id of the module to represent</param> /// <param name="registry">CKAN registry object for current game instance</param> /// <param name="current_ksp_version">Current game version</param> /// <param name="incompatible">If true, mark this module as incompatible</param> public GUIMod(string identifier, IRegistryQuerier registry, KspVersionCriteria current_ksp_version, bool?incompatible = null) { Identifier = identifier; IsAutodetected = registry.IsAutodetected(identifier); DownloadCount = registry.DownloadCount(identifier); if (IsAutodetected) { IsInstalled = true; } ModuleVersion latest_version = null; try { LatestCompatibleMod = registry.LatestAvailable(identifier, current_ksp_version); latest_version = LatestCompatibleMod?.version; } catch (ModuleNotFoundKraken) { } IsIncompatible = incompatible ?? LatestCompatibleMod == null; // 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(identifier, null); } catch { } // If there's known information for this mod in any form, calculate the highest compatible // KSP. if (latest_available_for_any_ksp != null) { KSPCompatibilityVersion = registry.LatestCompatibleKSP(identifier); KSPCompatibility = KSPCompatibilityVersion?.ToYalovString() ?? Properties.Resources.GUIModUnknown; KSPCompatibilityLong = string.Format(Properties.Resources.GUIModKSPCompatibilityLong, KSPCompatibility, latest_available_for_any_ksp.version); } 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 = "-"; } SearchableIdentifier = CkanModule.nonAlphaNums.Replace(Identifier, ""); }
/// <summary> /// <see cref="IRegistryQuerier.LatestAvailableWithProvides" /> /// </summary> public List <CkanModule> LatestAvailableWithProvides( string identifier, KspVersionCriteria ksp_version, RelationshipDescriptor relationship_descriptor = null, IEnumerable <CkanModule> toInstall = null) { if (providers.TryGetValue(identifier, out HashSet <AvailableModule> provs)) { // For each AvailableModule, we want the latest one matching our constraints return(provs .Select(am => am.Latest( ksp_version, relationship_descriptor, InstalledModules.Select(im => im.Module), toInstall )) .Where(m => m?.ProvidesList?.Contains(identifier) ?? false) .ToList()); } else { // Nothing provides this, return empty list return(new List <CkanModule>()); } }
private bool allDependenciesCompatible(CkanModule mod, KspVersionCriteria ksp_version) { // we need to check that we can get everything we depend on if (mod.depends != null) { foreach (RelationshipDescriptor dependency in mod.depends) { try { if (!dependency.MatchesAny(null, InstalledDlls.ToHashSet(), InstalledDlc) && !LatestAvailableWithProvides(dependency.name, ksp_version).Any()) { return(false); } } catch (KeyNotFoundException e) { log.ErrorFormat("Cannot find available version with provides for {0} in registry", dependency.name); throw e; } catch (ModuleNotFoundKraken) { return(false); } } } return(true); }
private void AuditRecommendations(IRegistryQuerier registry, KspVersionCriteria versionCriteria) { var toInstall = new HashSet <CkanModule>(); var rows = getRecSugRows(registry.InstalledModules.Select(im => im.Module), registry, toInstall); if (!rows.Any()) { GUI.user.RaiseError("No recommendations or suggestions found."); return; } // Prompt user to choose installCanceled = false; ShowRecSugDialog(rows, toInstall); tabController.HideTab("ChooseRecommendedModsTabPage"); // Install if (!installCanceled && toInstall.Any()) { installWorker.RunWorkerAsync( new KeyValuePair <List <ModChange>, RelationshipResolverOptions>( toInstall.Select(mod => new ModChange( new GUIMod(mod, registry, versionCriteria), GUIModChangeType.Install, null )).ToList(), RelationshipResolver.DependsOnlyOpts() ) ); } }
/// <summary> /// Tries to get every mod in the Dictionary, which can be installed /// It also transforms the Recommender list to a string /// </summary> /// <param name="mods">Map from recommendations to lists of recommenders</param> /// <param name="registry">Registry of current game instance</param> /// <param name="versionCriteria">Versions compatible with current instance</param> /// <param name="toInstall">Modules planned to be installed</param> /// <returns>Map from installable recommendations to string describing recommenders</returns> private Dictionary <CkanModule, string> GetShowableMods( Dictionary <CkanModule, List <string> > mods, IRegistryQuerier registry, KspVersionCriteria versionCriteria, HashSet <CkanModule> toInstall ) { return(mods.Where(kvp => CanInstall( registry, versionCriteria, new RelationshipResolverOptions() { with_all_suggests = false, with_recommends = false, with_suggests = false, without_enforce_consistency = false, without_toomanyprovides_kraken = false }, toInstall.ToList().Concat(new List <CkanModule>() { kvp.Key }).ToList() )).ToDictionary( kvp => kvp.Key, kvp => string.Join(", ", kvp.Value.ToArray()) )); }
/// <summary> /// <see cref="IRegistryQuerier.Incompatible"/> /// </summary> public List <CkanModule> Incompatible(KspVersionCriteria ksp_version) { var candidates = new List <string>(available_modules.Keys); var incompatible = new List <CkanModule>(); CkanModule[] modules_for_current_version = available_modules.Values .Select(pair => pair.Latest(ksp_version)) .Where(mod => mod != null) .ToArray(); // It's nice to see things in alphabetical order, so sort our keys first. candidates.Sort(); // Now find what we can give our user. foreach (string candidate in candidates) { CkanModule available = LatestAvailable(candidate, ksp_version); // If a mod is available, it might still have incompatible dependencies. if (available == null || !allDependenciesCompatible(available, ksp_version, modules_for_current_version)) { incompatible.Add(LatestAvailable(candidate, null)); } } return(incompatible); }
/// <summary> /// Initialize a GUIMod based on a CkanModule /// </summary> /// <param name="mod">The module to represent</param> /// <param name="registry">CKAN registry object for current game instance</param> /// <param name="current_ksp_version">Current game version</param> /// <param name="incompatible">If true, mark this module as incompatible</param> public GUIMod(CkanModule mod, IRegistryQuerier registry, KspVersionCriteria current_ksp_version, bool incompatible = false) : this(mod.identifier, registry, current_ksp_version, incompatible) { Mod = mod; IsCKAN = mod is CkanModule; Name = mod.name.Trim(); Abstract = [email protected](); Description = mod.description?.Trim() ?? string.Empty; Abbrevation = new string(Name.Split(' ').Where(s => s.Length > 0).Select(s => s[0]).ToArray()); Authors = mod.author == null ? Properties.Resources.GUIModNSlashA : String.Join(",", mod.author); HasUpdate = registry.HasUpdate(mod.identifier, current_ksp_version); HasReplacement = registry.GetReplacement(mod, current_ksp_version) != null; DownloadSize = mod.download_size == 0 ? Properties.Resources.GUIModNSlashA : CkanModule.FmtSize(mod.download_size); IsIncompatible = IsIncompatible || !mod.IsCompatibleKSP(current_ksp_version); if (mod.resources != null) { Homepage = mod.resources.homepage?.ToString() ?? mod.resources.spacedock?.ToString() ?? mod.resources.curse?.ToString() ?? mod.resources.repository?.ToString() ?? Properties.Resources.GUIModNSlashA; } // Get the Searchables. SearchableName = mod.SearchableName; SearchableAbstract = mod.SearchableAbstract; SearchableDescription = mod.SearchableDescription; SearchableAuthors = mod.SearchableAuthors; UpdateIsCached(); }
/// <summary> /// Returns true if our mod is compatible with the KSP version specified. /// </summary> public bool IsCompatibleKSP(KspVersionCriteria version) { log.DebugFormat("Testing if {0} is compatible with KSP {1}", this, version); return(_comparator.Compatible(version, this)); }
private void UpdateRepo(object sender, DoWorkEventArgs e) { try { AddStatusMessage("Updating repositories..."); // Note the current mods' compatibility for the NewlyCompatible filter KspVersionCriteria versionCriteria = CurrentInstance.VersionCriteria(); IRegistryQuerier registry = RegistryManager.Instance(CurrentInstance).registry; Dictionary <string, bool> oldModules = registry.Available(versionCriteria) .ToDictionary(m => m.identifier, m => false); registry.Incompatible(versionCriteria) .Where(m => !oldModules.ContainsKey(m.identifier)) .ToList() .ForEach(m => oldModules.Add(m.identifier, true)); RepoUpdateResult result = Repo.UpdateAllRepositories( RegistryManager.Instance(CurrentInstance), CurrentInstance, Manager.Cache, GUI.user); e.Result = new KeyValuePair <RepoUpdateResult, Dictionary <string, bool> >( result, oldModules); } catch (UriFormatException ex) { errorDialog.ShowErrorDialog(ex.Message); } catch (MissingCertificateKraken ex) { errorDialog.ShowErrorDialog(ex.ToString()); } catch (Exception ex) { errorDialog.ShowErrorDialog("Failed to connect to repository. Exception: " + ex.Message); } }
/// <summary> /// Initialize a GUIMod based on a CkanModule /// </summary> /// <param name="mod">The module to represent</param> /// <param name="registry">CKAN registry object for current game instance</param> /// <param name="current_ksp_version">Current game version</param> /// <param name="incompatible">If true, mark this module as incompatible</param> public GUIMod(CkanModule mod, IRegistryQuerier registry, KspVersionCriteria current_ksp_version, bool incompatible = false) : this(mod.identifier, registry, current_ksp_version, incompatible) { Mod = mod; IsCKAN = mod is CkanModule; Name = mod.name.Trim(); Abstract = [email protected](); Abbrevation = new string(Name.Split(' ').Where(s => s.Length > 0).Select(s => s[0]).ToArray()); Authors = mod.author == null ? "N/A" : String.Join(",", mod.author); HasUpdate = registry.HasUpdate(mod.identifier, current_ksp_version); DownloadSize = mod.download_size == 0 ? "N/A" : CkanModule.FmtSize(mod.download_size); IsIncompatible = IsIncompatible || !mod.IsCompatibleKSP(current_ksp_version); if (mod.resources != null) { Homepage = mod.resources.homepage?.ToString() ?? mod.resources.spacedock?.ToString() ?? mod.resources.curse?.ToString() ?? mod.resources.repository?.ToString() ?? "N/A"; } UpdateIsCached(); }
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 KspVersionCriteria v173 = new KspVersionCriteria(KspVersion.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)); }
/// <summary> /// Initialize a GUIMod based on just an identifier /// </summary> /// <param name="identifier">The id of the module to represent</param> /// <param name="registry">CKAN registry object for current game instance</param> /// <param name="current_ksp_version">Current game version</param> /// <param name="incompatible">If true, mark this module as incompatible</param> public GUIMod(string identifier, IRegistryQuerier registry, KspVersionCriteria current_ksp_version, bool incompatible = false) { Identifier = identifier; IsIncompatible = incompatible; IsAutodetected = registry.IsAutodetected(identifier); DownloadCount = registry.DownloadCount(identifier); ModuleVersion latest_version = null; try { latest_version = registry.LatestAvailable(identifier, current_ksp_version)?.version; } catch (ModuleNotFoundKraken) { } // 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(identifier, null); } catch { } // If there's known information for this mod in any form, calculate the highest compatible // KSP. if (latest_available_for_any_ksp != null) { KSPCompatibility = registry.LatestCompatibleKSP(identifier)?.ToYalovString() ?? "Unknown"; KSPCompatibilityLong = $"{KSPCompatibility} (using mod version {latest_available_for_any_ksp.version})"; } 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 = "-"; } // 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"; }
/// <summary> /// Attempts to convert the module_names to ckan modules via CkanModule.FromIDandVersion and then calls RelationshipResolver.ctor(IEnumerable{CkanModule}, Registry, KSPVersion)"/> /// </summary> /// <param name="module_names"></param> /// <param name="options"></param> /// <param name="registry"></param> /// <param name="kspversion"></param> public RelationshipResolver(IEnumerable <string> module_names, RelationshipResolverOptions options, IRegistryQuerier registry, KspVersionCriteria kspversion) : this(module_names.Select(name => TranslateModule(name, options, registry, kspversion)).ToList(), options, registry, kspversion) { // Does nothing, just calls the other overloaded constructor }
/// <summary> /// <see cref = "IRegistryQuerier.LatestAvailableWithProvides" /> /// </summary> public List <CkanModule> LatestAvailableWithProvides(string module, KspVersionCriteria ksp_version, RelationshipDescriptor relationship_descriptor = null) { // This public interface calculates a cache of modules which // are compatible with the current version of KSP, and then // calls the private version below for heavy lifting. return(LatestAvailableWithProvides(module, ksp_version, available_modules.Values.Select(pair => pair.Latest(ksp_version)).Where(mod => mod != null).ToArray(), relationship_descriptor)); }
/// <summary> /// Partition all CkanModules in available_modules into /// compatible and incompatible groups. /// </summary> /// <param name="versCrit">Version criteria to determine compatibility</param> public void SetCompatibleVersion(KspVersionCriteria versCrit) { if (!versCrit.Equals(sorter?.CompatibleVersions)) { sorter = new CompatibilitySorter( versCrit, available_modules, providers, InstalledDlls.ToHashSet(), _installedDlcModules ); } }
/// <summary> /// Return the most recent release of a module with a optional ksp version to target and a RelationshipDescriptor to satisfy. /// </summary> /// <param name="ksp_version">If not null only consider mods which match this ksp version.</param> /// <param name="relationship">If not null only consider mods which satisfy the RelationshipDescriptor.</param> /// <returns></returns> public CkanModule Latest(KspVersionCriteria ksp_version = null, RelationshipDescriptor relationship = null) { var available_versions = new List <Version>(module_version.Keys); CkanModule module; log.DebugFormat("Our dictionary has {0} keys", module_version.Keys.Count); log.DebugFormat("Choosing between {0} available versions", available_versions.Count); // Uh oh, nothing available. Maybe this existed once, but not any longer. if (available_versions.Count == 0) { return(null); } // No restrictions? Great, we can just pick the first one! if (ksp_version == null && relationship == null) { module = module_version[available_versions.First()]; log.DebugFormat("No KSP version restriction, {0} is most recent", module); return(module); } // If there's no relationship to satisfy, we can just pick the first that is // compatible with our version of KSP. if (relationship == null) { // Time to check if there's anything that we can satisfy. var version = available_versions.FirstOrDefault(v => module_version[v].IsCompatibleKSP(ksp_version)); if (version != null) { return(module_version[version]); } log.DebugFormat("No version of {0} is compatible with KSP {1}", module_version[available_versions[0]].identifier, ksp_version); return(null); } // If we're here, then we have a relationship to satisfy, so things get more complex. if (ksp_version == null) { var version = available_versions.FirstOrDefault(relationship.version_within_bounds); return(version == null ? null : module_version[version]); } else { var version = available_versions.FirstOrDefault(v => relationship.version_within_bounds(v) && module_version[v].IsCompatibleKSP(ksp_version)); return(version == null ? null : module_version[version]); } }
/// <summary> /// <see cref="IRegistryQuerier.Available"/> /// </summary> public List <CkanModule> Available(KspVersionCriteria ksp_version) { var candidates = new List <string>(available_modules.Keys); var compatible = new List <CkanModule>(); // It's nice to see things in alphabetical order, so sort our keys first. candidates.Sort(); //Cache CkanModule[] modules_for_current_version = available_modules.Values.Select(pair => pair.Latest(ksp_version)).Where(mod => mod != null).ToArray(); // Now find what we can give our user. foreach (string candidate in candidates) { CkanModule available = LatestAvailable(candidate, ksp_version); if (available != null) { // we need to check that we can get everything we depend on bool failedDepedency = false; if (available.depends != null) { foreach (RelationshipDescriptor dependency in available.depends) { try { if (!LatestAvailableWithProvides(dependency.name, ksp_version, modules_for_current_version).Any()) { failedDepedency = true; break; } } catch (KeyNotFoundException e) { log.ErrorFormat("Cannot find available version with provides for {0} in registry", dependency.name); throw e; } catch (ModuleNotFoundKraken) { failedDepedency = true; break; } } } if (!failedDepedency) { compatible.Add(available); } } } return(compatible); }
/// <summary> /// Initialize a GUIMod based on an InstalledModule /// </summary> /// <param name="instMod">The installed module to represent</param> /// <param name="registry">CKAN registry object for current game instance</param> /// <param name="current_ksp_version">Current game version</param> /// <param name="incompatible">If true, mark this module as incompatible</param> public GUIMod(InstalledModule instMod, IRegistryQuerier registry, KspVersionCriteria current_ksp_version, bool incompatible = false) : this(instMod.Module, registry, current_ksp_version, incompatible) { IsInstalled = true; IsInstallChecked = true; InstallDate = instMod.InstallTime; InstalledVersion = instMod.Module.version.ToString(); if (LatestVersion == null || LatestVersion.Equals("-")) { LatestVersion = InstalledVersion; } }
public void EnforceSizeLimit(long bytes, Registry registry) { int numFiles; long curBytes; GetSizeInfo(out numFiles, out curBytes); if (curBytes > bytes) { // This object will let us determine whether a module is compatible with any of our instances KspVersionCriteria aggregateCriteria = manager?.Instances.Values .Where(ksp => ksp.Valid) .Select(ksp => ksp.VersionCriteria()) .Aggregate( manager?.CurrentInstance?.VersionCriteria() ?? new KspVersionCriteria(null), (combinedCrit, nextCrit) => combinedCrit.Union(nextCrit) ); // This object lets us find the modules associated with a cached file Dictionary <string, List <CkanModule> > hashMap = registry.GetDownloadHashIndex(); // Prune the module lists to only those that are compatible foreach (var kvp in hashMap) { kvp.Value.RemoveAll(mod => !mod.IsCompatibleKSP(aggregateCriteria)); } // Now get all the files in all the caches... List <FileInfo> files = allFiles(); // ... and sort them by compatibilty and timestamp... files.Sort((a, b) => compareFiles( hashMap, aggregateCriteria, a, b )); // ... and delete them till we're under the limit foreach (FileInfo fi in files) { curBytes -= fi.Length; fi.Delete(); File.Delete($"{fi.Name}.sha1"); File.Delete($"{fi.Name}.sha256"); if (curBytes <= bytes) { // Limit met, all done! break; } } OnCacheChanged(); sha1Cache.Clear(); sha256Cache.Clear(); } }
/// <summary> /// Initialize the sorter and partition the mods. /// </summary> /// <param name="crit">Versions to be considered compatible</param> /// <param name="available">Collection of mods from registry</param> /// <param name="providers">Dictionary mapping every identifier to the modules providing it</param> /// <param name="dlls">Collection of found dlls</param> /// <param name="dlc">Collection of installed DLCs</param> public CompatibilitySorter( KspVersionCriteria crit, Dictionary <string, AvailableModule> available, Dictionary <string, HashSet <AvailableModule> > providers, HashSet <string> dlls, Dictionary <string, UnmanagedModuleVersion> dlc ) { CompatibleVersions = crit; this.dlls = dlls; this.dlc = dlc; PartitionModules(available, providers); }
public override bool Compatible(KspVersionCriteria gameVersionCriteria, CkanModule module) { // If it's strictly compatible, then it's compatible. if (strict.Compatible (gameVersionCriteria, module)) return true; // If we're in strict mode, and it's not strictly compatible, then it's // not compatible. if (module.ksp_version_strict) return false; return base.Compatible (gameVersionCriteria, module); }
/// <summary> /// Creates a new resolver that will find a way to install all the modules specified. /// </summary> /// <param name="modulesToInstall">Modules to install</param> /// <param name="modulesToRemove">Modules to remove</param> /// <param name="options">Options for the RelationshipResolver</param> /// <param name="registry">CKAN registry object for current game instance</param> /// <param name="kspversion">The current KSP version criteria to consider</param> public RelationshipResolver(IEnumerable <CkanModule> modulesToInstall, IEnumerable <CkanModule> modulesToRemove, RelationshipResolverOptions options, IRegistryQuerier registry, KspVersionCriteria kspversion) : this(options, registry, kspversion) { if (modulesToRemove != null) { RemoveModsFromInstalledList(modulesToRemove); } if (modulesToInstall != null) { AddModulesToInstall(modulesToInstall); } }
/// <summary> /// Creates a new Relationship resolver. /// </summary> /// <param name="options"><see cref="RelationshipResolverOptions"/></param> /// <param name="registry">The registry to use</param> /// <param name="kspversion">The version of the install that the registry corresponds to</param> public RelationshipResolver(RelationshipResolverOptions options, IRegistryQuerier registry, KspVersionCriteria kspversion) { this.registry = registry; this.kspversion = kspversion; this.options = options; installed_modules = new HashSet <CkanModule>(registry.InstalledModules.Select(i_module => i_module.Module)); var installed_relationship = new SelectionReason.Installed(); foreach (var module in installed_modules) { reasons.Add(module, installed_relationship); } }
private void reinstallToolStripMenuItem_Click(object sender, EventArgs e) { GUIMod module = ModInfoTabControl.SelectedModule; if (module == null || !module.IsCKAN) { return; } YesNoDialog reinstallDialog = new YesNoDialog(); string confirmationText = $"Do you want to reinstall {module.Name}?"; if (reinstallDialog.ShowYesNoDialog(confirmationText) == DialogResult.No) { return; } IRegistryQuerier registry = RegistryManager.Instance(CurrentInstance).registry; KspVersionCriteria versCrit = CurrentInstance.VersionCriteria(); // Build the list of changes, first the mod to remove: List <ModChange> toReinstall = new List <ModChange>() { new ModChange(module, GUIModChangeType.Remove, null) }; // Then everything we need to re-install: HashSet <string> goners = registry.FindReverseDependencies( new List <string>() { module.Identifier } ); foreach (string id in goners) { toReinstall.Add(new ModChange( mainModList.full_list_of_mod_rows[id]?.Tag as GUIMod, GUIModChangeType.Install, null )); } // Hand off to centralized [un]installer code installWorker.RunWorkerAsync( new KeyValuePair <List <ModChange>, RelationshipResolverOptions>( toReinstall, RelationshipResolver.DefaultOpts() ) ); }
public virtual bool Compatible(KspVersionCriteria gameVersionCriteria, CkanModule module) { if (gameVersionCriteria.Versions.Count == 0) { return(true); } foreach (KspVersion gameVersion in gameVersionCriteria.Versions) { if (SingleVersionsCompatible(gameVersion, module)) { return(true); } } return(false); }
/// <summary> /// Initialize the sorter and partition the mods. /// </summary> /// <param name="crit">Versions to be considered compatible</param> /// <param name="available">Collection of mods from registry</param> /// <param name="providers">Dictionary mapping every identifier to the modules providing it</param> /// <param name="dlls">Collection of found dlls</param> /// <param name="dlc">Collection of installed DLCs</param> public CompatibilitySorter( KspVersionCriteria crit, Dictionary <string, AvailableModule> available, Dictionary <string, HashSet <AvailableModule> > providers, Dictionary <string, InstalledModule> installed, HashSet <string> dlls, IDictionary <string, ModuleVersion> dlc ) { CompatibleVersions = crit; this.installed = installed; this.dlls = dlls; this.dlc = dlc; PartitionModules(available, CompatibleProviders(crit, providers)); }
/// <summary> /// Attempts to convert the identifiers to CkanModules and then calls RelationshipResolver.ctor(IEnumerable{CkanModule}, IEnumerable{CkanModule}, Registry, KSPVersion)"/> /// </summary> /// <param name="modulesToInstall">Identifiers of modules to install, will be converted to CkanModules using CkanModule.FromIDandVersion</param> /// <param name="modulesToRemove">Identifiers of modules to remove, will be converted to CkanModules using Registry.InstalledModule</param> /// <param name="options">Options for the RelationshipResolver</param> /// <param name="registry">CKAN registry object for current game instance</param> /// <param name="kspversion">The current KSP version criteria to consider</param> public RelationshipResolver(IEnumerable <string> modulesToInstall, IEnumerable <string> modulesToRemove, RelationshipResolverOptions options, IRegistryQuerier registry, KspVersionCriteria kspversion) : this( modulesToInstall?.Select(mod => TranslateModule(mod, options, registry, kspversion)), modulesToRemove? .Select(mod => { var match = CkanModule.idAndVersionMatcher.Match(mod); return(match.Success ? match.Groups["mod"].Value : mod); }) .Where(identifier => registry.InstalledModule(identifier) != null) .Select(identifier => registry.InstalledModule(identifier).Module), options, registry, kspversion) { // Does nothing, just calls the other overloaded constructor }
public override bool Compatible(KspVersionCriteria gameVersionCriteria, CkanModule module) { // If it's strictly compatible, then it's compatible. if (strict.Compatible(gameVersionCriteria, module)) { return(true); } // If we're in strict mode, and it's not strictly compatible, then it's // not compatible. if (module.ksp_version_strict) { return(false); } return(base.Compatible(gameVersionCriteria, module)); }
public void LoadRecommendations( IRegistryQuerier registry, KspVersionCriteria kspVersion, NetModuleCache cache, Dictionary <CkanModule, Tuple <bool, List <string> > > recommendations, Dictionary <CkanModule, List <string> > suggestions, Dictionary <CkanModule, HashSet <string> > supporters ) { this.registry = registry; this.kspVersion = kspVersion; Util.Invoke(this, () => { RecommendedModsToggleCheckbox.Checked = true; RecommendedModsListView.Items.Clear(); RecommendedModsListView.Items.AddRange( getRecSugRows(cache, recommendations, suggestions, supporters).ToArray()); }); }
/// <summary> /// <see cref = "IRegistryQuerier.LatestAvailable" /> /// </summary> // TODO: Consider making this internal, because practically everything should // be calling LatestAvailableWithProvides() public CkanModule LatestAvailable( string module, KspVersionCriteria ksp_version, RelationshipDescriptor relationship_descriptor = null) { log.DebugFormat("Finding latest available for {0}", module); // TODO: Check user's stability tolerance (stable, unstable, testing, etc) try { return(available_modules[module].Latest(ksp_version, relationship_descriptor)); } catch (KeyNotFoundException) { throw new ModuleNotFoundKraken(module); } }
public bool Compatible(KspVersionCriteria gameVersion, CkanModule module) { return true; }
public GUIMod(CkanModule mod, IRegistryQuerier registry, KspVersionCriteria current_ksp_version) { 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 = !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); Version 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) { KSPCompatibility = KSPCompatibilityLong = latest_available_for_any_ksp.HighestCompatibleKSP(); // 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); } } 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; if (mod.download_size == 0) DownloadSize = "N/A"; else if (mod.download_size / 1024.0 < 1) DownloadSize = "1<KB"; else DownloadSize = mod.download_size / 1024+""; Abbrevation = new string(mod.name.Split(' '). Where(s => s.Length > 0).Select(s => s[0]).ToArray()); UpdateIsCached(); }