/// <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,
     KSPVersion kspversion)
     : this(module_names.Select(name => CkanModule.FromIDandVersion(registry, name, kspversion)).ToList(),
             options,
             registry,
             kspversion)
 {
     // Does nothing, just calls the other overloaded constructor
 }
Beispiel #2
0
 public void Export(IRegistryQuerier registry, Stream stream)
 {
     using (var writer = new StreamWriter(stream))
     {
         foreach (var mod in registry.InstalledModules.OrderBy(i => i.Module.name))
         {
             writer.WriteLine(@"- **{0}** `{1} {2}`", mod.Module.name, mod.identifier, mod.Module.version);
         }
     }
 }
        public void Export(IRegistryQuerier registry, Stream stream)
        {
            using (var writer = new StreamWriter(stream))
            {
                writer.WriteLine(WritePattern,
                    _delimter,
                    "identifier",
                    "version",
                    "name",
                    "abstract",
                    "description",
                    "author",
                    "kind",
                    "download",
                    "download_size",
                    "ksp_version",
                    "ksp_version_min",
                    "ksp_version_max",
                    "license",
                    "release_status",
                    "repository",
                    "homepage",
                    "bugtracker",
                    "kerbalstuff",
                    "spacedock"
                );

                foreach (var mod in registry.InstalledModules.OrderBy(i => i.Module.name))
                {
                    writer.WriteLine(WritePattern,
                        _delimter,
                        mod.Module.identifier,
                        mod.Module.version,
                        QuoteIfNecessary(mod.Module.name),
                        QuoteIfNecessary(mod.Module.@abstract),
                        QuoteIfNecessary(mod.Module.description),
                        QuoteIfNecessary(string.Join(";", mod.Module.author)),
                        QuoteIfNecessary(mod.Module.kind),
                        WriteUri(mod.Module.download),
                        mod.Module.download_size,
                        mod.Module.ksp_version,
                        mod.Module.ksp_version_min,
                        mod.Module.ksp_version_max,
                        mod.Module.license,
                        mod.Module.release_status,
                        WriteRepository(mod.Module.resources),
                        WriteHomepage(mod.Module.resources),
                        WriteBugtracker(mod.Module.resources),
                        WriteKerbalStuff(mod.Module.resources),
                        WriteSpaceDock(mod.Module.resources)
                    );
                }
            }
        }
        /// <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, KSPVersion kspversion)
        {
            this.registry = registry;
            this.kspversion = kspversion;
            this.options = options;

            installed_modules = new HashSet<Module>(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);
            }
        }
Beispiel #5
0
        private async Task UpdateChangeSetAndConflicts(IRegistryQuerier registry)
        {
            IEnumerable <ModChange>     full_change_set = null;
            Dictionary <GUIMod, string> new_conflicts   = null;

            bool too_many_provides_thrown = false;
            var  user_change_set          = mainModList.ComputeUserChangeSet();

            try
            {
                var module_installer = ModuleInstaller.GetInstance(CurrentInstance, Manager.Cache, GUI.user);
                full_change_set = await mainModList.ComputeChangeSetFromModList(registry, user_change_set, module_installer, CurrentInstance.VersionCriteria());
            }
            catch (InconsistentKraken k)
            {
                // Need to be recomputed due to ComputeChangeSetFromModList possibly changing it with too many provides handling.
                AddStatusMessage(k.ShortDescription);
                user_change_set = mainModList.ComputeUserChangeSet();
                new_conflicts   = MainModList.ComputeConflictsFromModList(registry, user_change_set, CurrentInstance.VersionCriteria());
                full_change_set = null;
            }
            catch (TooManyModsProvideKraken)
            {
                // Can be thrown by ComputeChangeSetFromModList if the user cancels out of it.
                // We can just rerun it as the ModInfoTabControl has been removed.
                too_many_provides_thrown = true;
            }
            catch (DependencyNotSatisfiedKraken k)
            {
                GUI.user.RaiseError(
                    "{0} depends on {1}, which is not compatible with the currently installed version of KSP",
                    k.parent,
                    k.module
                    );

                // Uncheck the box
                MarkModForInstall(k.parent.identifier, true);
            }

            if (too_many_provides_thrown)
            {
                await UpdateChangeSetAndConflicts(registry);

                new_conflicts   = Conflicts;
                full_change_set = ChangeSet;
            }

            last_mod_to_have_install_toggled.Clear();
            Conflicts = new_conflicts;
            ChangeSet = full_change_set;
        }
Beispiel #6
0
        public void Export(IRegistryQuerier registry, Stream stream)
        {
            using (var writer = new StreamWriter(stream))
            {
                writer.WriteLine("[LIST]");

                foreach (var mod in registry.InstalledModules.OrderBy(i => i.Module.identifier))
                {
                    writer.WriteLine(@"[*][B]{0}[/B] ({1} {2})", mod.Module.title, mod.identifier, mod.Module.modVersion);
                }

                writer.WriteLine("[/LIST]");
            }
        }
Beispiel #7
0
        private TreeNode indexedNode(IRegistryQuerier registry, CkanModule module, RelationshipType relationship, bool compatible)
        {
            int    icon   = (int)relationship + 1;
            string suffix = compatible ? ""
                : $" ({registry.CompatibleGameVersions(module.identifier)})";

            return(new TreeNode($"{module.name} {module.version}{suffix}", icon, icon)
            {
                Name = module.identifier,
                ToolTipText = relationship.ToString(),
                Tag = module,
                ForeColor = compatible ? SystemColors.WindowText : Color.Red,
            });
        }
Beispiel #8
0
        public void Export(IRegistryQuerier registry, Stream stream)
        {
            using (var writer = new StreamWriter(stream))
            {
                writer.WriteLine("[LIST]");

                foreach (var mod in registry.InstalledModules.OrderBy(i => i.Module.name))
                {
                    writer.WriteLine(@"[*][B]{0}[/B] ({1} {2})", mod.Module.name, mod.identifier, mod.Module.version);
                }

                writer.WriteLine("[/LIST]");
            }
        }
Beispiel #9
0
 /// <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;
     InstalledMod     = instMod;
     IsAutoInstalled  = instMod.AutoInstalled;
     InstallDate      = instMod.InstallTime;
     InstalledVersion = instMod.Module.version.ToString();
     if (LatestVersion == null || LatestVersion.Equals("-"))
     {
         LatestVersion = InstalledVersion;
     }
 }
Beispiel #10
0
        /// <summary>
        /// Creates a new Relationship resolver.
        /// </summary>
        /// <param name="options">Options for the RelationshipResolver</param>
        /// <param name="registry">CKAN registry object for current game instance</param>
        /// <param name="GameVersion">The current KSP version criteria to consider</param>
        public RelationshipResolver(RelationshipResolverOptions options, IRegistryQuerier registry, GameVersionCriteria GameVersion)
        {
            this.registry    = registry;
            this.GameVersion = GameVersion;
            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);
            }
        }
Beispiel #11
0
        // Build up the list of who recommends what
        private Dictionary <CkanModule, List <string> > getDependersIndex(
            IEnumerable <CkanModule> sourceModules,
            IRegistryQuerier registry,
            HashSet <CkanModule> toExclude
            )
        {
            Dictionary <CkanModule, List <string> > dependersIndex = new Dictionary <CkanModule, List <string> >();

            foreach (CkanModule mod in sourceModules)
            {
                foreach (List <RelationshipDescriptor> relations in new List <List <RelationshipDescriptor> >()
                {
                    mod.recommends, mod.suggests
                })
                {
                    if (relations != null)
                    {
                        foreach (RelationshipDescriptor rel in relations)
                        {
                            List <CkanModule> providers = rel.LatestAvailableWithProvides(
                                registry,
                                CurrentInstance.VersionCriteria()
                                );
                            foreach (CkanModule provider in providers)
                            {
                                if (!registry.IsInstalled(provider.identifier) &&
                                    !toExclude.Any(m => m.identifier == provider.identifier))
                                {
                                    List <string> dependers;
                                    if (dependersIndex.TryGetValue(provider, out dependers))
                                    {
                                        // Add the dependent mod to the list of reasons this dependency is shown.
                                        dependers.Add(mod.identifier);
                                    }
                                    else
                                    {
                                        // Add a new entry if this provider isn't listed yet.
                                        dependersIndex.Add(provider, new List <string>()
                                        {
                                            mod.identifier
                                        });
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return(dependersIndex);
        }
Beispiel #12
0
        public HashSet <ModChange> ComputeUserChangeSet(IRegistryQuerier registry)
        {
            var removableAuto = registry?.FindRemovableAutoInstalled(registry?.InstalledModules)
                                ?? new InstalledModule[] {};

            return(new HashSet <ModChange>(
                       Modules
                       .SelectMany(mod => mod.GetModChanges())
                       .Union(removableAuto.Select(im => new ModChange(
                                                       im.Module,
                                                       GUIModChangeType.Remove,
                                                       new SelectionReason.NoLongerUsed())))
                       ));
        }
Beispiel #13
0
        public static Dictionary <GUIMod, string> ComputeConflictsFromModList(IRegistryQuerier registry,
                                                                              IEnumerable <ModChange> change_set, FactorioVersion ksp_version)
        {
            var modules_to_install = new HashSet <string>();
            var modules_to_remove  = new HashSet <string>();
            var options            = new RelationshipResolverOptions
            {
                without_toomanyprovides_kraken = true,
                procede_with_inconsistencies   = true,
                without_enforce_consistency    = true,
                with_recommends = false
            };

            foreach (var change in change_set)
            {
                switch (change.ChangeType)
                {
                case GUIModChangeType.None:
                    break;

                case GUIModChangeType.Install:
                    modules_to_install.Add(change.Mod.Identifier);
                    break;

                case GUIModChangeType.Remove:
                    modules_to_remove.Add(change.Mod.Identifier);
                    break;

                case GUIModChangeType.Update:
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            var installed =
                registry.Installed()
                .Where(pair => pair.Value.CompareTo(new ProvidedVersion("", "0.0.0")) != 0)
                .Select(pair => pair.Key);

            //We wish to only check mods that would exist after the changes are made.
            var mods_to_check =
                installed.Union(modules_to_install).Except(modules_to_remove).Select(p => new CfanModuleIdAndVersion(p));
            var resolver = new RelationshipResolver(mods_to_check.ToList(), options, registry, ksp_version);

            return(resolver.ConflictList.ToDictionary(item => new GUIMod(item.Key, registry, ksp_version),
                                                      item => item.Value));
        }
Beispiel #14
0
        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()
                    )
                );
        }
Beispiel #15
0
        /// <summary>
        /// Initiate the GUI installer flow for one specific module
        /// </summary>
        /// <param name="registry">Reference to the registry</param>
        /// <param name="module">Module to install</param>
        public async void InstallModuleDriver(IRegistryQuerier registry, CkanModule module)
        {
            RelationshipResolverOptions install_ops = RelationshipResolver.DefaultOpts();

            install_ops.with_recommends = false;

            try
            {
                // Resolve the provides relationships in the dependencies
                List <ModChange> fullChangeSet = new List <ModChange>(
                    await mainModList.ComputeChangeSetFromModList(
                        registry,
                        new HashSet <ModChange>()
                {
                    new ModChange(
                        new GUIMod(
                            module,
                            registry,
                            CurrentInstance.VersionCriteria()
                            ),
                        GUIModChangeType.Install,
                        null
                        )
                },
                        ModuleInstaller.GetInstance(CurrentInstance, Manager.Cache, GUI.user),
                        CurrentInstance.VersionCriteria()
                        )
                    );
                if (fullChangeSet != null && fullChangeSet.Count > 0)
                {
                    installWorker.RunWorkerAsync(
                        new KeyValuePair <List <ModChange>, RelationshipResolverOptions>(
                            fullChangeSet,
                            install_ops
                            )
                        );
                }
            }
            catch
            {
                // If we failed, do the clean-up normally done by PostInstallMods.
                HideWaitDialog(false);
                menuStrip1.Enabled = true;
            }
            finally
            {
                changeSet = null;
            }
        }
Beispiel #16
0
        private IEnumerable <ModuleReplacement> AllReplacements(IEnumerable <string> identifiers)
        {
            IRegistryQuerier registry = RegistryManager.Instance(manager.CurrentInstance).registry;

            foreach (string id in identifiers)
            {
                ModuleReplacement repl = registry.GetReplacement(
                    id, manager.CurrentInstance.VersionCriteria()
                    );
                if (repl != null)
                {
                    yield return(repl);
                }
            }
        }
Beispiel #17
0
        /// <summary>
        /// Is the mod installed and does it have a replaced_by relationship with a compatible version
        /// Check latest information on installed version of mod "identifier" and if it has a "replaced_by"
        /// value, check if there is a compatible version of the linked mod
        /// Given a mod identifier, return a ModuleReplacement containing the relevant replacement
        /// if compatibility matches.
        /// </summary>
        public static ModuleReplacement GetReplacement(this IRegistryQuerier querier, string identifier, KspVersionCriteria version)
        {
            // We only care about the installed version
            CkanModule installedVersion;

            try
            {
                installedVersion = querier.GetInstalledVersion(identifier);
            }
            catch (ModuleNotFoundKraken)
            {
                return(null);
            }
            return(querier.GetReplacement(installedVersion, version));
        }
Beispiel #18
0
        private bool allowInstall(CkanModule module)
        {
            GameInstance     currentInstance = Main.Instance.Manager.CurrentInstance;
            IRegistryQuerier registry        = RegistryManager.Instance(currentInstance).registry;
            var installer = new ModuleInstaller(
                currentInstance,
                Main.Instance.Manager.Cache,
                Main.Instance.currentUser);

            return(installable(installer, module, registry) ||
                   Main.Instance.YesNoDialog(
                       string.Format(Properties.Resources.AllModVersionsInstallPrompt, module.ToString()),
                       Properties.Resources.AllModVersionsInstallYes,
                       Properties.Resources.AllModVersionsInstallNo));
        }
Beispiel #19
0
        private void UpdateRepo(object sender, DoWorkEventArgs e)
        {
            try
            {
                AddStatusMessage(Properties.Resources.MainRepoScanning);
                log.Debug("Scanning before repo update");
                bool scanChanged = CurrentInstance.Scan();

                AddStatusMessage(Properties.Resources.MainRepoUpdating);

                // Note the current mods' compatibility for the NewlyCompatible filter
                GameVersionCriteria       versionCriteria = CurrentInstance.VersionCriteria();
                IRegistryQuerier          registry        = RegistryManager.Instance(CurrentInstance).registry;
                Dictionary <string, bool> oldModules      = registry.CompatibleModules(versionCriteria)
                                                            .ToDictionary(m => m.identifier, m => false);
                registry.IncompatibleModules(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, currentUser);
                if (result == RepoUpdateResult.NoChanges && scanChanged)
                {
                    result = RepoUpdateResult.Updated;
                }
                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 (ReinstallModuleKraken)
            {
                // Bypass the generic error dialog so the Post can handle this
                throw;
            }
            catch (Exception ex)
            {
                errorDialog.ShowErrorDialog(string.Format(Properties.Resources.MainRepoFailedToConnect, ex.Message));
            }
        }
Beispiel #20
0
        private void _CheckForConsistency()
        {
            IRegistryQuerier registry = RegistryManager.Instance(CurrentInstance).registry;

            try
            {
                registry.CheckSanity();
            }
            catch (InconsistentKraken e)
            {
                m_User.displayError(
                    "Installed mods has unmet dependencies. \"Apply changes\" button will be unavailable until you fix inconsistencies:\n{0}",
                    new object[] { e.InconsistenciesPretty }
                    );
            }
        }
Beispiel #21
0
 private static List <CfanModule> getModulesFromRegistry(
     IEnumerable <CfanModuleIdAndVersion> module_names, IRegistryQuerier registry, FactorioVersion kspversion)
 {
     return(module_names.Select(
                p =>
     {
         var mod = p.version != null
                     ? registry.GetModuleByVersion(p.identifier, p.version)
                     : registry.LatestAvailable(p.identifier, kspversion);
         if (mod == null)
         {
             throw new ModuleNotFoundKraken(p.identifier, p.version?.ToString(), "Module not found.");
         }
         return mod;
     }).ToList());
 }
Beispiel #22
0
        public int RunCommand(CKAN.KSP ksp, object raw_options)
        {
            IRegistryQuerier registry = RegistryManager.Instance(ksp).registry;

            List <CkanModule> available = registry.Available(ksp.VersionCriteria());

            user.RaiseMessage("Mods available for KSP {0}", ksp.Version());
            user.RaiseMessage("");

            foreach (CkanModule module in available)
            {
                user.RaiseMessage("* {0} ({1}) - {2}", module.identifier, module.version, module.name);
            }

            return(Exit.OK);
        }
Beispiel #23
0
 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());
     });
 }
Beispiel #24
0
 /// <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_game_version">Current game version</param>
 /// <param name="incompatible">If true, mark this module as incompatible</param>
 public GUIMod(InstalledModule instMod, IRegistryQuerier registry, GameVersionCriteria current_game_version, bool?incompatible = null)
     : this(instMod.Module, registry, current_game_version, incompatible)
 {
     IsInstalled      = true;
     IsInstallChecked = true;
     InstalledMod     = instMod;
     selectedMod      = instMod.Module;
     IsAutoInstalled  = instMod.AutoInstalled;
     InstallDate      = instMod.InstallTime;
     InstalledVersion = instMod.Module.version.ToString();
     if (LatestVersion == null || LatestVersion.Equals("-"))
     {
         LatestVersion = InstalledVersion;
     }
     // For mods not known to the registry LatestCompatibleMod is null, however the installed module might be compatible
     IsIncompatible = incompatible ?? LatestCompatibleMod == null && !instMod.Module.IsCompatibleKSP(current_game_version);
 }
Beispiel #25
0
        private void LoadRelationships(IRegistryQuerier registry)
        {
            if (module.depends == null)
            {
                module.depends = new List <RelationshipDescriptor>();
            }
            if (module.recommends == null)
            {
                module.recommends = new List <RelationshipDescriptor>();
            }
            if (module.suggests == null)
            {
                module.suggests = new List <RelationshipDescriptor>();
            }

            ignored.Clear();
            // Find installed modules that aren't in the module's relationships
            ignored.AddRange(registry.Installed(false, false)
                             .Where(kvp => {
                var ids = new string[] { kvp.Key };
                return(!module.depends.Any(rel => rel.ContainsAny(ids)) &&
                       !module.recommends.Any(rel => rel.ContainsAny(ids)) &&
                       !module.suggests.Any(rel => rel.ContainsAny(ids)));
            })
                             .Select(kvp => (RelationshipDescriptor) new ModuleRelationshipDescriptor()
            {
                name    = kvp.Key,
                version = kvp.Value,
            })
                             );
            RelationshipsListView.Items.Clear();
            AddGroup(module.depends, DependsGroup, registry);
            AddGroup(module.recommends, RecommendationsGroup, registry);
            AddGroup(module.suggests, SuggestionsGroup, registry);
            AddGroup(ignored, IgnoredGroup, registry);
            RelationshipsListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);

            GroupToRelationships.Clear();
            GroupToRelationships.Add(DependsGroup, module.depends);
            GroupToRelationships.Add(RecommendationsGroup, module.recommends);
            GroupToRelationships.Add(SuggestionsGroup, module.suggests);
            GroupToRelationships.Add(IgnoredGroup, ignored);

            RelationshipsListView_ItemSelectionChanged(null, null);
        }
Beispiel #26
0
        public HashSet <ModChange> ComputeUserChangeSet(IRegistryQuerier registry)
        {
            var removableAuto = registry?.FindRemovableAutoInstalled(registry?.InstalledModules)
                                ?? new InstalledModule[] {};

            return(new HashSet <ModChange>(
                       Modules
                       .Where(mod => mod.IsInstallable())
                       .Select(mod => mod.GetRequestedChange())
                       .Where(change => change.HasValue)
                       .Select(change => change.Value)
                       .Select(change => new ModChange(change.Key, change.Value, null))
                       .Union(removableAuto.Select(im => new ModChange(
                                                       new GUIMod(im, registry, Main.Instance.CurrentInstance.VersionCriteria()),
                                                       GUIModChangeType.Remove,
                                                       new SelectionReason.NoLongerUsed())))
                       ));
        }
Beispiel #27
0
        private void _UpdateModDependencyGraph()
        {
            CkanModule module = (CkanModule)ModInfoTabControl.Tag;

            DependsGraphTree.BeginUpdate();
            DependsGraphTree.Nodes.Clear();
            IRegistryQuerier registry = RegistryManager.Instance(manager.CurrentInstance).registry;
            TreeNode         root     = new TreeNode($"{module.name} {module.version}", 0, 0)
            {
                Name = module.identifier,
                Tag  = module
            };

            DependsGraphTree.Nodes.Add(root);
            AddChildren(registry, root);
            root.Expand();
            DependsGraphTree.EndUpdate();
        }
Beispiel #28
0
        private void _UpdateModDependencyGraph(CkanModule module)
        {
            DependsGraphTree.BeginUpdate();
            DependsGraphTree.BackColor = SystemColors.Window;
            DependsGraphTree.LineColor = SystemColors.WindowText;
            DependsGraphTree.Nodes.Clear();
            IRegistryQuerier registry = RegistryManager.Instance(manager.CurrentInstance).registry;
            TreeNode         root     = new TreeNode($"{module.name} {module.version}", 0, 0)
            {
                Name = module.identifier,
                Tag  = module
            };

            DependsGraphTree.Nodes.Add(root);
            AddChildren(registry, root);
            root.Expand();
            DependsGraphTree.EndUpdate();
        }
        /// <summary>
        /// Is the mod installed and does it have a newer version compatible with version
        /// </summary>
        public static bool HasUpdate(this IRegistryQuerier querier, string identifier, KSPVersion version)
        {
            CkanModule newest_version;

            try
            {
                newest_version = querier.LatestAvailable(identifier, version);
            }
            catch (ModuleNotFoundKraken)
            {
                return(false);
            }
            if (newest_version == null)
            {
                return(false);
            }
            return(querier.IsInstalled(identifier) && newest_version.version.IsGreaterThan(querier.InstalledVersion(identifier)));
        }
Beispiel #30
0
 /// <summary>
 /// Return a mod's current status
 /// This can't be static because the user's installation plans are part of the object.
 /// This function is extremely performance-sensitive because it's the default sort for
 /// the main mod list, so anything in here should be O(1) and fast.
 /// </summary>
 /// <param name="manager">KSP manager containing the instances</param>
 /// <param name="registry">Registry of instance being displayed</param>
 /// <param name="identifier">The mod</param>
 /// <returns>
 /// Status of mod
 /// </returns>
 public InstallStatus GetModStatus(KSPManager manager, IRegistryQuerier registry, string identifier)
 {
     if (registry.IsInstalled(identifier, false))
     {
         if (registry.IsAutodetected(identifier))
         {
             return(InstallStatus.AutoDetected);
         }
         else if (Remove.Contains(identifier))
         {
             return(InstallStatus.Removing);
         }
         else if (registry.HasUpdate(identifier, manager.CurrentInstance.VersionCriteria()))
         {
             if (Upgrade.Contains(identifier))
             {
                 return(InstallStatus.Upgrading);
             }
             else
             {
                 return(InstallStatus.Upgradeable);
             }
         }
         else if (!IsAnyAvailable(registry, identifier))
         {
             return(InstallStatus.Unavailable);
         }
         else
         {
             return(InstallStatus.Installed);
         }
     }
     else
     {
         foreach (CkanModule m in Install)
         {
             if (m.identifier == identifier)
             {
                 return(InstallStatus.Installing);
             }
         }
         return(InstallStatus.NotInstalled);
     }
 }
Beispiel #31
0
 /// <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,
                           RelationshipResolver.DependsOnlyOpts(),
                           toInstall.ToList().Concat(new List <CkanModule>()
     {
         kvp.Key
     }).ToList()
                           )).ToDictionary(
                kvp => kvp.Key,
                kvp => string.Join(", ", kvp.Value.ToArray())
                ));
 }
Beispiel #32
0
 /// <summary>
 /// Initiate the GUI installer flow for one specific module
 /// </summary>
 /// <param name="registry">Reference to the registry</param>
 /// <param name="module">Module to install</param>
 public async void InstallModuleDriver(IRegistryQuerier registry, CkanModule module)
 {
     try
     {
         var             userChangeSet = new List <ModChange>();
         InstalledModule installed     = registry.InstalledModule(module.identifier);
         if (installed != null)
         {
             // Already installed, remove it first
             userChangeSet.Add(new ModChange(
                                   new GUIMod(installed.Module, registry, CurrentInstance.VersionCriteria()),
                                   GUIModChangeType.Remove,
                                   null
                                   ));
         }
         // Install the selected mod
         userChangeSet.Add(new ModChange(
                               new GUIMod(module, registry, CurrentInstance.VersionCriteria()),
                               GUIModChangeType.Install,
                               null
                               ));
         if (userChangeSet.Count > 0)
         {
             // Resolve the provides relationships in the dependencies
             installWorker.RunWorkerAsync(
                 new KeyValuePair <List <ModChange>, RelationshipResolverOptions>(
                     userChangeSet,
                     RelationshipResolver.DependsOnlyOpts()
                     )
                 );
         }
     }
     catch
     {
         // If we failed, do the clean-up normally done by PostInstallMods.
         HideWaitDialog(false);
         menuStrip1.Enabled = true;
     }
     finally
     {
         changeSet = null;
     }
 }
Beispiel #33
0
        /// <summary>
        /// Is the mod installed and does it have a newer version compatible with version
        /// We can't update AD mods
        /// </summary>
        public static bool HasUpdate(this IRegistryQuerier querier, string identifier, FactorioVersion version)
        {
            CfanModule newest_version;

            try
            {
                newest_version = querier.LatestAvailable(identifier, version);
            }
            catch (ModuleNotFoundKraken)
            {
                return(false);
            }
            if (newest_version == null)
            {
                return(false);
            }
            return(!new List <string>(querier.InstalledPreexistingModules).Contains(identifier) && querier.IsInstalled(identifier, false) &&
                   newest_version.modVersion.IsGreaterThan(querier.InstalledVersion(identifier)));
        }
Beispiel #34
0
        private void UpdateRepo(object sender, DoWorkEventArgs e)
        {
            try
            {
                AddStatusMessage("Scanning GameData for DLCs and manually installed modules...");
                bool scanChanged = CurrentInstance.ScanGameData();

                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);
                if (result == RepoUpdateResult.NoChanges && scanChanged)
                {
                    result = RepoUpdateResult.Updated;
                }
                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);
            }
        }
Beispiel #35
0
 private void AddMod(
     IEnumerable <RelationshipDescriptor> relations,
     Dictionary <CkanModule, List <string> > chooseAble,
     string identifier,
     IRegistryQuerier registry,
     HashSet <CkanModule> toInstall)
 {
     if (relations == null)
     {
         return;
     }
     foreach (RelationshipDescriptor rel in relations)
     {
         List <CkanModule> providers = registry.LatestAvailableWithProvides(
             rel.name,
             CurrentInstance.VersionCriteria(),
             rel
             );
         foreach (CkanModule provider in providers)
         {
             if (!registry.IsInstalled(provider.identifier) &&
                 !toInstall.Any(m => m.identifier == provider.identifier))
             {
                 // We want to show this mod to the user. Add it.
                 List <string> dependers;
                 if (chooseAble.TryGetValue(provider, out dependers))
                 {
                     // Add the dependent mod to the list of reasons this dependency is shown.
                     dependers.Add(identifier);
                 }
                 else
                 {
                     // Add a new entry if this provider isn't listed yet.
                     chooseAble.Add(provider, new List <string>()
                     {
                         identifier
                     });
                 }
             }
         }
     }
 }
Beispiel #36
0
        public GUIMod(Module mod, IRegistryQuerier registry, KSPVersion 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() : "-";
            LatestVersion = latest_version != null ? latest_version.ToString() : "-";
            KSPversion = ksp_version != null ? ksp_version.ToString() : "-";

            Abstract = mod.@abstract;
            Homepage = mod.resources != null && mod.resources.homepage != null
                ? (object) mod.resources.homepage
                : "N/A";

            Identifier = mod.identifier;
        }
 /// <summary>
 /// Creates a new resolver that will find a way to install all the modules specified.
 /// </summary>
 public RelationshipResolver(IEnumerable<CkanModule> modules, RelationshipResolverOptions options, IRegistryQuerier registry,
     KSPVersion kspversion)
     : this(options,registry,kspversion)
 {
     AddModulesToInstall(modules);
 }
Beispiel #38
0
        private async Task UpdateChangeSetAndConflicts(IRegistryQuerier registry)
        {
            IEnumerable<ModChange> full_change_set = null;
            Dictionary<GUIMod, string> new_conflicts = null;

            bool too_many_provides_thrown = false;
            var user_change_set = mainModList.ComputeUserChangeSet();
            try
            {
                var module_installer = ModuleInstaller.GetInstance(CurrentInstance, GUI.user);
                full_change_set =
                    await mainModList.ComputeChangeSetFromModList(registry, user_change_set, module_installer,
                    CurrentInstance.VersionCriteria());
            }
            catch (InconsistentKraken)
            {
                //Need to be recomputed due to ComputeChangeSetFromModList possibly changing it with too many provides handling.
                user_change_set = mainModList.ComputeUserChangeSet();
                new_conflicts = MainModList.ComputeConflictsFromModList(registry, user_change_set, CurrentInstance.VersionCriteria());
                full_change_set = null;
            }
            catch (TooManyModsProvideKraken)
            {
                //Can be thrown by ComputeChangeSetFromModList if the user cancels out of it.
                //We can just rerun it as the ModInfoTabControl has been removed.
                too_many_provides_thrown = true;
            }
            if (too_many_provides_thrown)
            {
                await UpdateChangeSetAndConflicts(registry);
                new_conflicts = Conflicts;
                full_change_set = ChangeSet;
            }
            last_mod_to_have_install_toggled.Clear();
            Conflicts = new_conflicts;
            ChangeSet = full_change_set;
        }
Beispiel #39
0
        /// <summary>
        /// This function returns a changeset based on the selections of the user.
        /// Currently returns null if a conflict is detected.
        /// </summary>
        /// <param name="registry"></param>
        /// <param name="changeSet"></param>
        /// <param name="installer">A module installer for the current KSP install</param>
        /// <param name="version">The version of the current KSP install</param>
        public async Task<IEnumerable<ModChange>> ComputeChangeSetFromModList(
            IRegistryQuerier registry, HashSet<ModChange> changeSet, ModuleInstaller installer,
            KSPVersion version)
        {
            var modules_to_install = new HashSet<CkanModule>();
            var modules_to_remove = new HashSet<Module>();
            var options = new RelationshipResolverOptions
            {
                without_toomanyprovides_kraken = false,
                with_recommends = false
            };

            foreach (var change in changeSet)
            {
                switch (change.ChangeType)
                {
                    case GUIModChangeType.None:
                        break;
                    case GUIModChangeType.Install:
                        //TODO: Fix
                        //This will give us a mod with a wrong version!
                        modules_to_install.Add(change.Mod.ToCkanModule());
                        break;
                    case GUIModChangeType.Remove:
                        modules_to_remove.Add(change.Mod);
                        break;
                    case GUIModChangeType.Update:
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
            var installed_modules =
                registry.InstalledModules.Select(imod => imod.Module).ToDictionary(mod => mod.identifier, mod => mod);


            bool handled_all_to_many_provides = false;
            while (!handled_all_to_many_provides)
            {
                //Can't await in catch clause - doesn't seem to work in mono. Hence this flag
                TooManyModsProvideKraken kraken;
                try
                {
                    new RelationshipResolver(modules_to_install.ToList(), options, registry, version);
                    handled_all_to_many_provides = true;
                    continue;
                }
                catch (TooManyModsProvideKraken k)
                {
                    kraken = k;
                }
                catch (ModuleNotFoundKraken k)
                {
                    //We shouldn't need this. However the relationship provider will throw TMPs with incompatible mods.
                    user.RaiseError("Module {0} has not been found. This may be because it is not compatible " +
                                    "with the currently installed version of KSP", k.module);
                    return null;
                }
                //Shouldn't get here unless there is a kraken.
                var mod = await too_many_provides(kraken);
                if (mod != null)
                {
                    modules_to_install.Add(mod);
                }
                else
                {
                    //TODO Is could be a new type of Kraken.
                    throw kraken;
                }
            }


            foreach (var dependency in registry.FindReverseDependencies(modules_to_remove.Select(mod=>mod.identifier)))
            {
                //TODO This would be a good place to have a event that alters the row's graphics to show it will be removed
                Module module_by_version = registry.GetModuleByVersion(installed_modules[dependency].identifier,
                    installed_modules[dependency].version) ?? registry.InstalledModule(dependency).Module;
                changeSet.Add(new ModChange(new GUIMod(module_by_version, registry, version), GUIModChangeType.Remove, null));
            }
            //May throw InconsistentKraken
            var resolver = new RelationshipResolver(options, registry, version);
            resolver.RemoveModsFromInstalledList(
                changeSet.Where(change => change.ChangeType.Equals(GUIModChangeType.Remove)).Select(m => m.Mod.ToModule()));
            resolver.AddModulesToInstall(modules_to_install.ToList());
            changeSet.UnionWith(
                resolver.ModList()
                    .Select(m => new ModChange(new GUIMod(m, registry, version), GUIModChangeType.Install, resolver.ReasonFor(m))));


            return changeSet;
        }
Beispiel #40
0
        public static Dictionary<GUIMod, string> ComputeConflictsFromModList(IRegistryQuerier registry,
            IEnumerable<ModChange> change_set, KSPVersion ksp_version)
        {
            var modules_to_install = new HashSet<string>();
            var modules_to_remove = new HashSet<string>();
            var options = new RelationshipResolverOptions
            {
                without_toomanyprovides_kraken = true,
                procede_with_inconsistencies = true,
                without_enforce_consistency = true,
                with_recommends = false
            };

            foreach (var change in change_set)
            {
                switch (change.ChangeType)
                {
                    case GUIModChangeType.None:
                        break;
                    case GUIModChangeType.Install:
                        modules_to_install.Add(change.Mod.Identifier);
                        break;
                    case GUIModChangeType.Remove:
                        modules_to_remove.Add(change.Mod.Identifier);
                        break;
                    case GUIModChangeType.Update:
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }

            var installed =
                registry.Installed()
                    .Where(pair => pair.Value.CompareTo(new ProvidesVersion("")) != 0)
                    .Select(pair => pair.Key);

            //We wish to only check mods that would exist after the changes are made.
            var mods_to_check = installed.Union(modules_to_install).Except(modules_to_remove);
            var resolver = new RelationshipResolver(mods_to_check.ToList(), options, registry, ksp_version);
            return resolver.ConflictList.ToDictionary(item => new GUIMod(item.Key, registry, ksp_version),
                item => item.Value);
        }
Beispiel #41
0
 public GUIMod(CkanModule mod, IRegistryQuerier registry, KSPVersion current_ksp_version)
     : this((Module) mod, registry, current_ksp_version)
 {
 }
Beispiel #42
0
 private void AddMod(IEnumerable<RelationshipDescriptor> relations, Dictionary<string, List<string>> chooseAble, 
     string identifier, IRegistryQuerier registry)
 {
     if (relations == null)
         return;
     foreach (RelationshipDescriptor mod in relations)
     {
         try
         {
             // if the mod is available for the current KSP version _and_
             // the mod is not installed _and_
             // the mod is not already in the install list
             if (
                 registry.LatestAvailable(mod.name, CurrentInstance.Version()) != null &&
                 !registry.IsInstalled(mod.name) && !toInstall.Contains(mod.name))
             {
                 // add it to the list of chooseAble mods we display to the user
                 if (!chooseAble.ContainsKey(mod.name))
                 {
                     chooseAble.Add(mod.name, new List<string>());
                 }
                 chooseAble[mod.name].Add(identifier);
             }
         }
         // XXX - Don't ignore all krakens! Those things are important!
         catch (Kraken)
         {
         }
     }
 }
Beispiel #43
0
        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();
        }
Beispiel #44
0
 public void Export(IRegistryQuerier registry, Stream stream)
 {
     _exporter.Export(registry, stream);
 }