Пример #1
0
        private void installFromckanToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog open_file_dialog = new OpenFileDialog {
                Filter = Resources.CKANFileFilter
            };

            if (open_file_dialog.ShowDialog() == DialogResult.OK)
            {
                var        path = open_file_dialog.FileName;
                CkanModule module;

                try
                {
                    module = CkanModule.FromFile(path);
                }
                catch (Kraken kraken)
                {
                    currentUser.RaiseError(kraken.InnerException == null
                        ? kraken.Message
                        : $"{kraken.Message}: {kraken.InnerException.Message}");

                    return;
                }
                catch (Exception ex)
                {
                    currentUser.RaiseError(ex.Message);
                    return;
                }

                // We'll need to make some registry changes to do this.
                RegistryManager registry_manager = RegistryManager.Instance(CurrentInstance);

                // Remove this version of the module in the registry, if it exists.
                registry_manager.registry.RemoveAvailable(module);

                // Sneakily add our version in...
                registry_manager.registry.AddAvailable(module);

                var changeset = new List <ModChange>
                {
                    new ModChange(
                        new GUIMod(module, registry_manager.registry, CurrentInstance.VersionCriteria()),
                        GUIModChangeType.Install, null)
                };

                menuStrip1.Enabled = false;

                RelationshipResolverOptions install_ops = RelationshipResolver.DefaultOpts();
                install_ops.with_recommends = false;

                installWorker.RunWorkerAsync(
                    new KeyValuePair <List <ModChange>, RelationshipResolverOptions>(
                        changeset, install_ops));

                changeSet = null;

                UpdateChangesDialog(null, installWorker);
                ShowWaitDialog();
            }
        }
Пример #2
0
        /// <summary>
        /// Resolves all relationships for a module.
        /// May recurse to ResolveStanza, which may add additional modules to be installed.
        /// </summary>
        private void Resolve(CkanModule module, RelationshipResolverOptions options, IEnumerable <RelationshipDescriptor> old_stanza = null)
        {
            // Even though we may resolve top-level suggests for our module,
            // we don't install suggestions all the down unless with_all_suggests
            // is true.
            var sub_options = (RelationshipResolverOptions)options.Clone();

            sub_options.with_suggests = false;

            old_stanza = old_stanza?.Memoize();

            log.DebugFormat("Resolving dependencies for {0}", module.identifier);
            ResolveStanza(module.depends, new SelectionReason.Depends(module), sub_options, false, old_stanza);

            if (options.with_recommends)
            {
                log.DebugFormat("Resolving recommends for {0}", module.identifier);
                ResolveStanza(module.recommends, new SelectionReason.Recommended(module), sub_options, true, old_stanza);
            }

            if (options.with_suggests || options.with_all_suggests)
            {
                log.DebugFormat("Resolving suggests for {0}", module.identifier);
                ResolveStanza(module.suggests, new SelectionReason.Suggested(module), sub_options, true, old_stanza);
            }
        }
Пример #3
0
        /// <summary>
        /// Creates a new resolver that will find a way to install all the modules specified.
        /// </summary>
        public RelationshipResolver(ICollection <CkanModule> modules, RelationshipResolverOptions options, Registry registry,
                                    KSPVersion kspversion)
        {
            this.registry   = registry;
            this.kspversion = kspversion;

            // Start by figuring out what versions we're installing, and then
            // adding them to the list. This *must* be pre-populated with all
            // user-specified modules, as they may be supplying things that provide
            // virtual packages.

            var user_requested_mods = new List <CkanModule>();

            log.DebugFormat("Processing relationships for {0} modules", modules.Count);

            foreach (CkanModule module in modules)
            {
                log.DebugFormat("Preparing to resolve relationships for {0} {1}", module.identifier, module.version);

                var module1 = module; //Silence a warning re. closures over foreach var.
                foreach (CkanModule listed_mod in modlist.Values.Where(listed_mod => listed_mod.ConflictsWith(module1)))
                {
                    if (options.procede_with_inconsistencies)
                    {
                        conflicts.Add(new KeyValuePair <Module, Module>(listed_mod, module));
                        conflicts.Add(new KeyValuePair <Module, Module>(module, listed_mod));
                    }
                    else
                    {
                        throw new InconsistentKraken(string.Format("{0} conflicts with {1}, can't install both.", module,
                                                                   listed_mod));
                    }
                }

                user_requested_mods.Add(module);
                Add(module, new Relationship.UserRequested());
            }

            // Now that we've already pre-populated modlist, we can resolve
            // the rest of our dependencies.

            foreach (CkanModule module in user_requested_mods)
            {
                log.InfoFormat("Resolving relationships for {0}", module.identifier);
                Resolve(module, options);
            }

            var final_modules = new List <Module>(modlist.Values);

            final_modules.AddRange(registry.InstalledModules.Select(x => x.Module));

            if (!options.without_enforce_consistency)
            {
                // Finally, let's do a sanity check that our solution is actually sane.
                SanityChecker.EnforceConsistency(
                    final_modules,
                    registry.InstalledDlls
                    );
            }
        }
Пример #4
0
        private void ConfirmChangesButton_Click(object sender, EventArgs e)
        {
            if (m_Changeset == null)
            {
                return;
            }

            menuStrip1.Enabled = false;

            RelationshipResolverOptions install_ops = RelationshipResolver.DefaultOpts();

            install_ops.with_recommends = false;
            //Using the changeset passed in can cause issues with versions.
            // An example is Mechjeb for FAR at 25/06/2015 with a 1.0.2 install.
            // TODO Work out why this is.
            var user_change_set = mainModList.ComputeUserChangeSet().ToList();

            m_InstallWorker.RunWorkerAsync(
                new KeyValuePair <List <KeyValuePair <GUIMod, GUIModChangeType> >, RelationshipResolverOptions>(
                    user_change_set, install_ops));
            m_Changeset = null;

            UpdateChangesDialog(null, m_InstallWorker);
            ShowWaitDialog();
        }
Пример #5
0
 public void Setup()
 {
     registry = CKAN.Registry.Empty();
     options = RelationshipResolver.DefaultOpts();
     generator = new RandomModuleGenerator(new Random(0451));
     //Sanity checker means even incorrect RelationshipResolver logic was passing
     options.without_enforce_consistency = true;
 }
Пример #6
0
        public static Dictionary <GUIMod, string> ComputeConflictsFromModList(IRegistryQuerier registry,
                                                                              IEnumerable <ModChange> change_set, KspVersionCriteria ksp_version)
        {
            var modules_to_install = new HashSet <string>();
            var modules_to_remove  = new HashSet <string>();
            var options            = new RelationshipResolverOptions
            {
                without_toomanyprovides_kraken = true,
                proceed_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();
                }
            }

            // Only check mods that would exist after the changes are made.
            IEnumerable <CkanModule> installed = registry.InstalledModules.Where(
                im => !modules_to_remove.Contains(im.Module.identifier)
                ).Select(im => im.Module);

            // Convert ONLY modules_to_install with CkanModule.FromIDandVersion,
            // because it may not find already-installed modules.
            IEnumerable <CkanModule> mods_to_check = installed.Union(
                modules_to_install.Except(modules_to_remove).Select(
                    name => CkanModule.FromIDandVersion(registry, name, ksp_version)
                    )
                );
            var resolver = new RelationshipResolver(
                mods_to_check,
                change_set.Where(ch => ch.ChangeType == GUIModChangeType.Remove)
                .Select(ch => ch.Mod.ToModule()),
                options, registry, ksp_version
                );

            return(resolver.ConflictList.ToDictionary(item => new GUIMod(item.Key, registry, ksp_version),
                                                      item => item.Value));
        }
Пример #7
0
 /// <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
 }
Пример #8
0
 public void Constructor_WithoutModules_AlwaysReturns()
 {
     registry = CKAN.Registry.Empty();
     options = RelationshipResolver.DefaultOpts();
     Assert.DoesNotThrow(() => new RelationshipResolver(new List<string>(),
         options,
         registry,
         null));
 }
Пример #9
0
 public RelationshipResolver(ICollection <string> moduleNames, RelationshipResolverOptions options, Registry registry,
                             KSPVersion kspversion) :
     this(moduleNames.Select(name => CkanModule.FromIDandVersion(registry, name, kspversion)).ToList(),
          options,
          registry,
          kspversion)
 {
     // Does nothing, just calles the other overloaded constructor
 }
Пример #10
0
 /// <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
 }
Пример #11
0
 /// <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, Registry 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
 }
Пример #12
0
        /// <summary>
        /// Creates a new resolver that will find a way to install all the modules specified.
        /// </summary>
        public RelationshipResolver(List <string> modules, RelationshipResolverOptions options, Registry registry)
        {
            this.registry = registry;

            // Start by figuring out what versions we're installing, and then
            // adding them to the list. This *must* be pre-populated with all
            // user-specified modules, as they may be supplying things that provide
            // virtual packages.

            var user_requested_mods = new List <CkanModule>();

            log.DebugFormat("Processing relationships for {0} modules", modules.Count);

            foreach (string module in modules)
            {
                CkanModule mod = registry.LatestAvailable(module);
                if (mod == null)
                {
                    throw new ModuleNotFoundKraken(module);
                }

                log.DebugFormat("Preparing to resolve relationships for {0} {1}", mod.identifier, mod.version);

                foreach (CkanModule listed_mod in this.modlist.Values)
                {
                    if (listed_mod.ConflictsWith(mod))
                    {
                        throw new InconsistentKraken(string.Format("{0} conflicts with {1}, can't install both.", mod, listed_mod));
                    }
                }

                user_requested_mods.Add(mod);
                this.Add(mod);
            }

            // Now that we've already pre-populated modlist, we can resolve
            // the rest of our dependencies.

            foreach (CkanModule module in user_requested_mods)
            {
                log.InfoFormat("Resolving relationships for {0}", module.identifier);
                Resolve(module, options);
            }

            var final_modules = new List <Module>(modlist.Values);

            final_modules.AddRange(registry.InstalledModules.Select(x => x.Module));

            if (!options.without_enforce_consistency)
            {
                // Finally, let's do a sanity check that our solution is actually sane.
                SanityChecker.EnforceConsistency(
                    final_modules,
                    registry.InstalledDlls
                    );
            }
        }
Пример #13
0
        public static Dictionary <GUIMod, string> ComputeConflictsFromModList(IRegistryQuerier registry,
                                                                              IEnumerable <ModChange> change_set, GameVersionCriteria ksp_version)
        {
            var modules_to_install = new HashSet <CkanModule>();
            var modules_to_remove  = new HashSet <CkanModule>();
            var options            = new RelationshipResolverOptions
            {
                without_toomanyprovides_kraken = true,
                proceed_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);
                    break;

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

                case GUIModChangeType.Update:
                    break;

                case GUIModChangeType.Replace:
                    ModuleReplacement repl = registry.GetReplacement(change.Mod, ksp_version);
                    if (repl != null)
                    {
                        modules_to_remove.Add(repl.ToReplace);
                        modules_to_install.Add(repl.ReplaceWith);
                    }
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            var resolver = new RelationshipResolver(
                modules_to_install.Except(modules_to_remove),
                modules_to_remove,
                options, registry, ksp_version
                );

            return(resolver.ConflictList.ToDictionary(
                       item => new GUIMod(item.Key, registry, ksp_version),
                       item => item.Value
                       ));
        }
Пример #14
0
        /// <summary>
        ///     Returns the default options for relationship resolution.
        /// </summary>
        public static RelationshipResolverOptions DefaultOpts()
        {
            var opts = new RelationshipResolverOptions();

            opts.with_recommends   = true;
            opts.with_suggests     = false;
            opts.with_all_suggests = false;

            return(opts);
        }
Пример #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
            {
                var initialChangeSet = new HashSet <ModChange>();
                // Install the selected mod
                initialChangeSet.Add(new ModChange(
                                         new GUIMod(module, registry, CurrentInstance.VersionCriteria()),
                                         GUIModChangeType.Install,
                                         null
                                         ));
                InstalledModule installed = registry.InstalledModule(module.identifier);
                if (installed != null)
                {
                    // Already installed, remove it first
                    initialChangeSet.Add(new ModChange(
                                             new GUIMod(installed.Module, registry, CurrentInstance.VersionCriteria()),
                                             GUIModChangeType.Remove,
                                             null
                                             ));
                }
                List <ModChange> fullChangeSet = new List <ModChange>(
                    await mainModList.ComputeChangeSetFromModList(
                        registry,
                        initialChangeSet,
                        ModuleInstaller.GetInstance(CurrentInstance, Manager.Cache, GUI.user),
                        CurrentInstance.VersionCriteria()
                        )
                    );
                if (fullChangeSet != null && fullChangeSet.Count > 0)
                {
                    // Resolve the provides relationships in the dependencies
                    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;
            }
        }
Пример #16
0
        public void InstallList(
            List <string> modules,
            RelationshipResolverOptions options,
            IDownloader downloader = null
            )
        {
            var resolver = new RelationshipResolver(modules, options, registry_manager.registry, ksp.Version());
            List <CkanModule> modsToInstall = resolver.ModList();

            InstallList(modsToInstall, options, downloader);
        }
Пример #17
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="current_instance"></param>
        public static IEnumerable <KeyValuePair <CkanModule, GUIModChangeType> > ComputeChangeSetFromModList(
            Registry registry, HashSet <KeyValuePair <CkanModule, GUIModChangeType> > changeSet, ModuleInstaller installer,
            KSPVersion version)
        {
            var modules_to_install = new HashSet <string>();
            var modules_to_remove  = new HashSet <string>();
            var options            = new RelationshipResolverOptions()
            {
                without_toomanyprovides_kraken = true,
                with_recommends = false
            };

            foreach (var change in changeSet)
            {
                switch (change.Value)
                {
                case GUIModChangeType.None:
                    break;

                case GUIModChangeType.Install:
                    modules_to_install.Add(change.Key.identifier);
                    break;

                case GUIModChangeType.Remove:
                    modules_to_remove.Add(change.Key.identifier);
                    break;

                case GUIModChangeType.Update:
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            //May throw InconsistentKraken
            var resolver = new RelationshipResolver(modules_to_install.ToList(), options, registry, version);

            changeSet.UnionWith(
                resolver.ModList()
                .Select(mod => new KeyValuePair <CkanModule, GUIModChangeType>(mod, GUIModChangeType.Install)));


            foreach (var reverse_dependencies in modules_to_remove.Select(installer.FindReverseDependencies))
            {
                //TODO This would be a good place to have a event that alters the row's graphics to show it will be removed
                //TODO This currently gets the latest version. This may cause the displayed version to wrong in the changset.
                var modules = reverse_dependencies.Select(rDep => registry.LatestAvailable(rDep, null));
                changeSet.UnionWith(
                    modules.Select(mod => new KeyValuePair <CkanModule, GUIModChangeType>(mod, GUIModChangeType.Remove)));
            }
            return(changeSet);
        }
Пример #18
0
        /// <summary>
        /// Upgrades the mods listed to the latest versions for the user's KSP.
        /// Will *re-install* with warning even if an upgrade is not available.
        /// Throws ModuleNotFoundKraken if module is not installed, or not available.
        /// </summary>
        public void Upgrade(IEnumerable <string> identifiers, IDownloader netAsyncDownloader, bool enforceConsistency = true)
        {
            var options = new RelationshipResolverOptions();

            // We do not wish to pull in any suggested or recommended mods.
            options.with_recommends = false;
            options.with_suggests   = false;

            var resolver = new RelationshipResolver(identifiers.ToList(), options, registry_manager.registry, ksp.VersionCriteria());

            Upgrade(resolver.ModList(), netAsyncDownloader, enforceConsistency);
        }
Пример #19
0
        private bool InstallList(ModuleResolution modules, RelationshipResolverOptions options)
        {
            if (toInstall.Any())
            {
                // actual magic happens here, we run the installer with our mod list
                var module_installer = ModuleInstaller.GetInstance(manager.CurrentInstance, GUI.user);
                module_installer.onReportModInstalled = OnModInstalled;
                return(WasSuccessful(() => module_installer.InstallList(modules, options)));
            }

            return(true);
        }
Пример #20
0
        /// <summary>
        /// Upgrades the mods listed to the latest versions for the user's KSP.
        /// Will *re-install* with warning even if an upgrade is not available.
        /// Throws ModuleNotFoundKraken if module is not installed, or not available.
        /// </summary>
        public void Upgrade(IEnumerable <string> identifiers, IDownloader netAsyncDownloader)
        {
            var options = new RelationshipResolverOptions();

            // We do not wish to pull in any suggested or recommended mods.
            options.with_recommends = false;
            options.with_suggests   = false;

            var resolver = new RelationshipResolver(identifiers.ToList(), options, registry_manager.registry, ksp.Version());
            List <CkanModule> upgrades = resolver.ModList();

            Upgrade(upgrades, netAsyncDownloader);
        }
Пример #21
0
        /// <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, Registry 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);
            }
        }
Пример #22
0
        private bool InstallList(HashSet <string> toInstall, RelationshipResolverOptions options, IDownloader downloader)
        {
            if (toInstall.Any())
            {
                // actual magic happens here, we run the installer with our mod list
                var module_installer = ModuleInstaller.GetInstance(manager.CurrentInstance, GUI.user);
                module_installer.onReportModInstalled = OnModInstalled;
                return(WasSuccessful(
                           () => module_installer.InstallList(toInstall.ToList(), options, downloader)));
            }

            return(true);
        }
Пример #23
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);
            }
        }
Пример #24
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, 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;
            }
        }
Пример #25
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));
        }
Пример #26
0
        private void ConfirmChangesButton_Click(object sender, EventArgs e)
        {
            menuStrip1.Enabled = false;

            RelationshipResolverOptions install_ops = RelationshipResolver.DefaultOpts();

            install_ops.with_recommends = false;

            m_InstallWorker.RunWorkerAsync(
                new KeyValuePair <List <KeyValuePair <CkanModule, GUIModChangeType> >, RelationshipResolverOptions>(
                    m_Changeset, install_ops));
            m_Changeset = null;

            UpdateChangesDialog(null, m_InstallWorker);
            ShowWaitDialog();
        }
Пример #27
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"></param>
        /// <returns></returns>
        private Dictionary <CkanModule, string> GetShowableMods(Dictionary <string, List <string> > mods)
        {
            Dictionary <CkanModule, string> modules = new Dictionary <CkanModule, string>();

            var opts = new RelationshipResolverOptions
            {
                with_all_suggests              = false,
                with_recommends                = false,
                with_suggests                  = false,
                without_enforce_consistency    = false,
                without_toomanyprovides_kraken = true
            };

            foreach (var pair in mods)
            {
                CkanModule module;

                try
                {
                    var resolver = new RelationshipResolver(new List <string> {
                        pair.Key
                    }, opts,
                                                            RegistryManager.Instance(manager.CurrentInstance).registry, CurrentInstance.VersionCriteria());
                    if (!resolver.ModList().Any())
                    {
                        continue;
                    }

                    module = RegistryManager.Instance(manager.CurrentInstance)
                             .registry.LatestAvailable(pair.Key, CurrentInstance.VersionCriteria());
                }
                catch
                {
                    continue;
                }

                if (module == null)
                {
                    continue;
                }
                modules.Add(module, String.Join(",", pair.Value.ToArray()));
            }
            return(modules);
        }
Пример #28
0
        private void InstallList(HashSet <string> toInstall, RelationshipResolverOptions options)
        {
            if (toInstall.Any())
            {
                var downloader = new NetAsyncDownloader();

                // actual magic happens here, we run the installer with our mod list
                ModuleInstaller.Instance.onReportModInstalled = OnModInstalled;
                cancelCallback = downloader.CancelDownload;

                try
                {
                    ModuleInstaller.Instance.InstallList(toInstall.ToList(), options, downloader);
                }
                catch (CancelledActionKraken)
                {
                    // User cancelled, no action needed.
                }
                catch (InconsistentKraken inconsistency)
                {
                    string message = "";
                    bool   first   = true;
                    foreach (var msg in inconsistency.inconsistencies)
                    {
                        if (!first)
                        {
                            message += ", ";
                        }
                        else
                        {
                            first = false;
                        }

                        message += msg;
                    }

                    User.Error("Inconsistency detected - {0}", message);
                }

                // TODO: Handle our other krakens here, we want the user to know
                // when things have gone wrong!
            }
        }
Пример #29
0
 /// <summary>
 /// Translate mods from identifiers in its default or identifier=version format into CkanModules,
 /// optionally falling back to incompatible modules if no compatibles could be found.
 /// </summary>
 /// <param name="name">The identifier or identifier=version of the module</param>
 /// <param name="options">If options.allow_incompatible is set, fall back to searching incompatible modules if no compatible has been found</param>
 /// <param name="registry">CKAN registry object for current game instance</param>
 /// <param name="GameVersion">The current KSP version criteria to consider</param>
 /// <returns>A CkanModule</returns>
 private static CkanModule TranslateModule(string name, RelationshipResolverOptions options, IRegistryQuerier registry, GameVersionCriteria GameVersion)
 {
     if (options.allow_incompatible)
     {
         try
         {
             return(CkanModule.FromIDandVersion(registry, name, GameVersion));
         }
         catch (ModuleNotFoundKraken)
         {
             // No versions found matching our game version, so
             // look for incompatible versions.
             return(CkanModule.FromIDandVersion(registry, name, null));
         }
     }
     else
     {
         return(CkanModule.FromIDandVersion(registry, name, GameVersion));
     }
 }
Пример #30
0
        public void InstallList(ModuleResolution modules, RelationshipResolverOptions options)
        {
            // We're about to install all our mods; so begin our transaction.
            using (TransactionScope transaction = CkanTransaction.CreateTransactionScope())
            {
                var enumeratedMods = modules.Select((m, i) => new { Idx = i, Module = m });
                foreach (var item in enumeratedMods)
                {
                    var percentComplete = (item.Idx * 100) / modules.Count;
                    User.RaiseProgress(string.Format("Installing mod \"{0}\"", item.Module), percentComplete);
                    Install(item.Module);
                }

                User.RaiseProgress("Updating registry", 70);

                registry_manager.Save(!options.without_enforce_consistency);

                User.RaiseProgress("Commiting filesystem changes", 80);

                transaction.Complete();
            }
        }
Пример #31
0
        /// <summary>
        /// Returns mods that we require to install the selected module.
        /// This returns null if we can't compute these without user input,
        /// or if the mods conflict.
        /// </summary>
        private List <CkanModule> GetInstallDependencies(CkanModule module, RelationshipResolverOptions options)
        {
            var tmp = new List <string>();

            tmp.Add(module.identifier);

            RelationshipResolver resolver = null;

            try
            {
                resolver = new RelationshipResolver(tmp, options, RegistryManager.Instance(KSPManager.CurrentInstance).registry);
            }
            catch (Kraken kraken)
            {
                // TODO: Both of these krakens contain extra information; either a list of
                // mods the user can choose from, or a list of inconsistencies that are blocking
                // this selection. We *should* display those to the user. See GH #345.
                if (kraken is TooManyModsProvideKraken || kraken is InconsistentKraken)
                {
                    // Expected krakens.
                    return(null);
                }
                else if (kraken is ModuleNotFoundKraken)
                {
                    var not_found = (ModuleNotFoundKraken)kraken;
                    log.ErrorFormat(
                        "Can't find {0}, but {1} depends on it",
                        not_found.module, module
                        );
                    return(null);
                }

                log.ErrorFormat("Unexpected Kraken in GetInstallDeps: {0}", kraken.GetType());
                return(null);
            }

            return(resolver.ModList());
        }
Пример #32
0
        private void ConfirmChangesButton_Click(object sender, EventArgs e)
        {
            if (changeSet == null)
            {
                return;
            }

            menuStrip1.Enabled = false;
            RetryCurrentActionButton.Visible = false;

            RelationshipResolverOptions install_ops = RelationshipResolver.DefaultOpts();

            install_ops.with_recommends = false;
            //Using the changeset passed in can cause issues with versions.
            // An example is Mechjeb for FAR at 25/06/2015 with a 1.0.2 install.
            // TODO Work out why this is.
            installWorker.RunWorkerAsync(
                new KeyValuePair <List <ModChange>, RelationshipResolverOptions>(
                    mainModList.ComputeUserChangeSet().ToList(),
                    install_ops
                    )
                );
        }
Пример #33
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"></param>
        /// <returns></returns>
        private Dictionary <CkanModule, string> GetShowableMods(Dictionary <CkanModule, List <string> > mods)
        {
            Dictionary <CkanModule, string> modules = new Dictionary <CkanModule, string>();

            var opts = new RelationshipResolverOptions
            {
                with_all_suggests              = false,
                with_recommends                = false,
                with_suggests                  = false,
                without_enforce_consistency    = false,
                without_toomanyprovides_kraken = true
            };

            foreach (var pair in mods)
            {
                try
                {
                    RelationshipResolver resolver = new RelationshipResolver(
                        new List <CkanModule> {
                        pair.Key
                    },
                        null,
                        opts,
                        RegistryManager.Instance(manager.CurrentInstance).registry,
                        CurrentInstance.VersionCriteria()
                        );

                    if (resolver.ModList().Any())
                    {
                        // Resolver was able to find a way to install, so show it to the user
                        modules.Add(pair.Key, String.Join(",", pair.Value.ToArray()));
                    }
                }
                catch { }
            }
            return(modules);
        }
Пример #34
0
        /// <summary>
        /// Resolves all relationships for a module.
        /// May recurse to ResolveStanza, which may add additional modules to be installed.
        /// </summary>
        private void Resolve(CkanModule module, RelationshipResolverOptions options)
        {
            // Even though we may resolve top-level suggests for our module,
            // we don't install suggestions all the down unless with_all_suggests
            // is true.
            var sub_options = (RelationshipResolverOptions)options.Clone();

            sub_options.with_suggests = false;

            log.DebugFormat("Resolving dependencies for {0}", module.identifier);
            ResolveStanza(module.depends, sub_options);

            if (options.with_recommends)
            {
                log.DebugFormat("Resolving recommends for {0}", module.identifier);
                ResolveStanza(module.recommends, sub_options, true);
            }

            if (options.with_suggests || options.with_all_suggests)
            {
                log.DebugFormat("Resolving suggests for {0}", module.identifier);
                ResolveStanza(module.suggests, sub_options, true);
            }
        }
Пример #35
0
        private void UpdateRecommendedDialog(Dictionary<string, List<string>> mods, bool suggested = false)
        {
            if (!suggested)
            {
                RecommendedDialogLabel.Text =
                    "The following modules have been recommended by one or more of the chosen modules:";
                RecommendedModsListView.Columns[1].Text = "Recommended by:";
                RecommendedModsToggleCheckbox.Text = "(De-)select all recommended mods.";
                RecommendedModsToggleCheckbox.Checked=true;
                m_TabController.RenameTab("ChooseRecommendedModsTabPage", "Choose recommended mods");
            }
            else
            {
                RecommendedDialogLabel.Text =
                    "The following modules have been suggested by one or more of the chosen modules:";
                RecommendedModsListView.Columns[1].Text = "Suggested by:";
                RecommendedModsToggleCheckbox.Text = "(De-)select all suggested mods.";
                RecommendedModsToggleCheckbox.Checked=false;
                m_TabController.RenameTab("ChooseRecommendedModsTabPage", "Choose suggested mods");
            }

            RecommendedModsListView.Items.Clear();

            foreach (var pair in mods)
            {
                Module module;

                try
                {
                    var opts = new RelationshipResolverOptions
                    {
                        with_all_suggests = false,
                        with_recommends = false,
                        with_suggests = false,
                        without_enforce_consistency = false,
                        without_toomanyprovides_kraken = true
                    };

                    var resolver = new RelationshipResolver(new List<string> {pair.Key}, opts,
                        RegistryManager.Instance(manager.CurrentInstance).registry, CurrentInstance.Version());
                    if (!resolver.ModList().Any())
                    {
                        continue;
                    }

                    module = RegistryManager.Instance(manager.CurrentInstance)
                        .registry.LatestAvailable(pair.Key, CurrentInstance.Version());
                }
                catch
                {
                    continue;
                }

                if (module == null)
                {
                    continue;
                }

                ListViewItem item = new ListViewItem {Tag = module, Checked = !suggested, Text = pair.Key};

                ListViewItem.ListViewSubItem recommendedBy = new ListViewItem.ListViewSubItem();
                string recommendedByString = "";

                bool first = true;
                foreach (string mod in pair.Value)
                {
                    if (!first)
                    {
                        recommendedByString += ", ";
                    }
                    else
                    {
                        first = false;
                    }

                    recommendedByString += mod;
                }

                recommendedBy.Text = recommendedByString;

                item.SubItems.Add(recommendedBy);

                ListViewItem.ListViewSubItem description = new ListViewItem.ListViewSubItem {Text = module.@abstract};

                item.SubItems.Add(description);

                RecommendedModsListView.Items.Add(item);
            }
        }
Пример #36
0
        private bool InstallList(HashSet<string> toInstall, RelationshipResolverOptions options, IDownloader downloader)
        {
            if (toInstall.Any())
            {
                // actual magic happens here, we run the installer with our mod list
                var module_installer = ModuleInstaller.GetInstance(manager.CurrentInstance, GUI.user);
                module_installer.onReportModInstalled = OnModInstalled;
                return WasSuccessful(
                    () => module_installer.InstallList(toInstall.ToList(), options, downloader));
            }

            return true;
        }
Пример #37
0
 /// <summary>
 /// Creates a new resolver that will find a way to install all the modules specified.
 /// </summary>
 public RelationshipResolver(IEnumerable<CkanModule> modules, RelationshipResolverOptions options, Registry registry,
     KSPVersion kspversion)
     : this(options,registry,kspversion)
 {
     AddModulesToInstall(modules);
 }
Пример #38
0
        void MigrateMods(object sender, DoWorkEventArgs e)
        {
            SetStatus("Starting mod migration process");
            SetProgressMarquee();

            var registry = Main.Instance.CurrentInstance.Registry;

            var identifiers =
                (List<string>)e.Argument;

            foreach (var identifier in identifiers)
            {
                CkanModule module = null;

                try
                {
                    module = registry.LatestAvailable(identifier, Main.Instance.CurrentInstance.Version());
                }
                catch (Exception ex)
                {
                    e.Result = ex;
                    return;
                }

                if (module == null)
                {
                    e.Result = null;
                    return;
                }

                var installer = ModuleInstaller.GetInstance(Main.Instance.CurrentInstance, Main.Instance.m_User);
                SetStatus(String.Format("Downloading mod - {0}", identifier));
                string zip = installer.CachedOrDownload(module);

                var files = ModuleInstaller.FindInstallableFiles(module, new ZipFile(zip), Main.Instance.CurrentInstance);

                SetStatus(String.Format("Removing existing files for {0}", identifier));

                foreach (var file in files)
                {
                    if (File.Exists(file.destination))
                    {
                        try
                        {
                            File.Delete(file.destination);
                            log.InfoFormat("Deleted \"{0}\"", file);
                        }
                        catch (Exception ex)
                        {
                            log.WarnFormat("Failed to delete \"{0}\" - {1}", file, ex.Message);
                            break;
                        }
                    }
                }

                SetStatus("Scanning GameData");
                Main.Instance.CurrentInstance.ScanGameData();

                SetStatus("Unregistering auto-detected module");
                // registry.DeregisterModule(Main.Instance.CurrentInstance, identifier);

                var opts = new RelationshipResolverOptions()
                {
                    with_all_suggests = false,
                    with_recommends = true,
                    with_suggests = false,
                    without_toomanyprovides_kraken = true
                };

                SetStatus(String.Format("Installing {0} using CKAN", identifier));
                installer.User = new NullUser();

                bool success = false;
                while (!success)
                {
                    try
                    {
                        installer.InstallList(new List<string>() { identifier }, opts);
                        success = true;
                    }
                    catch (FileExistsKraken ex)
                    {
                        File.Delete(Path.Combine(Main.Instance.CurrentInstance.GameDir(), ex.filename));
                    }
                    catch (Exception ex)
                    {
                        e.Result = ex;
                        return;
                    }
                }
            }
        }
Пример #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<KeyValuePair<GUIMod, GUIModChangeType>>> ComputeChangeSetFromModList(
            Registry registry, HashSet<KeyValuePair<GUIMod, GUIModChangeType>> 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.Value)
                {
                    case GUIModChangeType.None:
                        break;
                    case GUIModChangeType.Install:
                        modules_to_install.Add(change.Key.ToCkanModule());
                        break;
                    case GUIModChangeType.Remove:
                        modules_to_remove.Add(change.Key);
                        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 modules_to_remove.
                Select(mod => installer.FindReverseDependencies(mod.identifier)).
                SelectMany(reverse_dependencies => reverse_dependencies))
            {
                //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 KeyValuePair<GUIMod, GUIModChangeType>(
                        new GUIMod(module_by_version, registry, version), GUIModChangeType.Remove));
            }
            //May throw InconsistentKraken
            var resolver = new RelationshipResolver(options, registry, version);
            resolver.RemoveModsFromInstalledList(
                changeSet.Where(change => change.Value.Equals(GUIModChangeType.Remove)).Select(m => m.Key.ToModule()));
            resolver.AddModulesToInstall(modules_to_install.ToList());
            changeSet.UnionWith(
                resolver.ModList()
                    .Select(
                        mod =>
                            new KeyValuePair<GUIMod, GUIModChangeType>(new GUIMod(mod, registry, version),
                                GUIModChangeType.Install)));


            return changeSet;
        }
Пример #40
0
        /// <summary>
        /// Resolve a relationship stanza (a list of relationships).
        /// This will add modules to be installed, if required.
        /// May recurse back to Resolve for those new modules.
        ///
        /// If `soft_resolve` is true, we warn rather than throw exceptions on mods we cannot find.
        /// If `soft_resolve` is false (default), we throw a ModuleNotFoundKraken if we can't find a dependency.
        ///
        /// Throws a TooManyModsProvideKraken if we have too many choices and
        /// options.without_toomanyprovides_kraken is not set.
        ///
        /// See RelationshipResolverOptions for further adjustments that can be made.
        ///
        /// </summary>
        private void ResolveStanza(IEnumerable<RelationshipDescriptor> stanza, SelectionReason reason,
            RelationshipResolverOptions options, bool soft_resolve = false)
        {
            if (stanza == null)
            {
                return;
            }

            foreach (var descriptor in stanza)
            {
                string dep_name = descriptor.name;
                log.DebugFormat("Considering {0}", dep_name);

                // If we already have this dependency covered, skip.
                // If it's already installed, skip.

                if (modlist.ContainsKey(dep_name))
                {
                    if (descriptor.version_within_bounds(modlist[dep_name].version))
                        continue;
                    //TODO Ideally we could check here if it can be replaced by the version we want.
                    throw new InconsistentKraken(
                        string.Format(
                            "{0} requires a version {1}. However a incompatible version, {2}, is in the resolver",
                            dep_name, descriptor.RequiredVersion, modlist[dep_name].version));

                }

                if (registry.IsInstalled(dep_name))
                {
                    if(descriptor.version_within_bounds(registry.InstalledVersion(dep_name)))
                    continue;
                    //TODO Ideally we could check here if it can be replaced by the version we want.
                    throw new InconsistentKraken(
                        string.Format(
                            "{0} requires a version {1}. However a incompatible version, {2}, is already installed",
                            dep_name, descriptor.RequiredVersion, registry.InstalledVersion(dep_name)));
                }

                List<CkanModule> candidates = registry.LatestAvailableWithProvides(dep_name, kspversion, descriptor)
                    .Where(mod=>MightBeInstallable(mod)).ToList();

                if (candidates.Count == 0)
                {
                    if (!soft_resolve)
                    {
                        log.ErrorFormat("Dependency on {0} found, but nothing provides it.", dep_name);
                        throw new ModuleNotFoundKraken(dep_name);
                    }
                    log.InfoFormat("{0} is recommended/suggested, but nothing provides it.", dep_name);
                    continue;
                }
                if (candidates.Count > 1)
                {
                    // Oh no, too many to pick from!
                    // TODO: It would be great if instead we picked the one with the
                    // most recommendations.
                    if (options.without_toomanyprovides_kraken)
                    {
                        continue;
                    }

                    throw new TooManyModsProvideKraken(dep_name, candidates);
                }

                CkanModule candidate = candidates[0];

                // Finally, check our candidate against everything which might object
                // to it being installed; that's all the mods which are fixed in our
                // list thus far, as well as everything on the system.

                var fixed_mods = new HashSet<Module>(modlist.Values);
                fixed_mods.UnionWith(installed_modules);

                var conflicting_mod = fixed_mods.FirstOrDefault(mod => mod.ConflictsWith(candidate));
                if (conflicting_mod == null)
                {
                    // Okay, looks like we want this one. Adding.
                    Add(candidate, reason);
                    Resolve(candidate, options);
                }
                else if (soft_resolve)
                {
                    log.InfoFormat("{0} would cause conflicts, excluding it from consideration", candidate);
                }
                else
                {
                    if (options.procede_with_inconsistencies)
                    {
                        Add(candidate, reason);
                        conflicts.Add(new KeyValuePair<Module, Module>(conflicting_mod, candidate));
                        conflicts.Add(new KeyValuePair<Module, Module>(candidate, conflicting_mod));
                    }
                    else
                    {
                        throw new InconsistentKraken(string.Format("{0} conflicts with {1}, can't install both.", conflicting_mod,
                            candidate));
                    }
                }
            }
        }
Пример #41
0
        /// <summary>
        /// Resolves all relationships for a module.
        /// May recurse to ResolveStanza, which may add additional modules to be installed.
        /// </summary>
        private void Resolve(CkanModule module, RelationshipResolverOptions options)
        {
            // Even though we may resolve top-level suggests for our module,
            // we don't install suggestions all the down unless with_all_suggests
            // is true.
            var sub_options = (RelationshipResolverOptions) options.Clone();
            sub_options.with_suggests = false;

            log.DebugFormat("Resolving dependencies for {0}", module.identifier);
            ResolveStanza(module.depends, new SelectionReason.Depends(module), sub_options);

            if (options.with_recommends)
            {
                log.DebugFormat("Resolving recommends for {0}", module.identifier);
                ResolveStanza(module.recommends, new SelectionReason.Recommended(module), sub_options, true);
            }

            if (options.with_suggests || options.with_all_suggests)
            {
                log.DebugFormat("Resolving suggests for {0}", module.identifier);
                ResolveStanza(module.suggests, new SelectionReason.Suggested(module), sub_options, true);
            }
        }
Пример #42
0
        /// <summary>
        ///     Returns the default options for relationship resolution.
        /// </summary>
        // TODO: This should just be able to return a new RelationshipResolverOptions
        // and the defaults in the class definition should do the right thing.
        public static RelationshipResolverOptions DefaultOpts()
        {
            var opts = new RelationshipResolverOptions
            {
                with_recommends = true,
                with_suggests = false,
                with_all_suggests = false
            };

            return opts;
        }
Пример #43
0
        public static Dictionary<GUIMod, string> ComputeConflictsFromModList(Registry registry,
            IEnumerable<KeyValuePair<GUIMod, GUIModChangeType>> 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.Value)
                {
                    case GUIModChangeType.None:
                        break;
                    case GUIModChangeType.Install:
                        modules_to_install.Add(change.Key.Identifier);
                        break;
                    case GUIModChangeType.Remove:
                        modules_to_remove.Add(change.Key.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);
        }
Пример #44
0
        /// <summary>
        /// Upgrades the mods listed to the latest versions for the user's KSP.
        /// Will *re-install* with warning even if an upgrade is not available.
        /// Throws ModuleNotFoundKraken if module is not installed, or not available.
        /// </summary>
        public void Upgrade(IEnumerable<string> identifiers, NetAsyncModulesDownloader netAsyncDownloader, bool enforceConsistency = true)
        {
            var options = new RelationshipResolverOptions();

            // We do not wish to pull in any suggested or recommended mods.
            options.with_recommends = false;
            options.with_suggests = false;

            var resolver = new RelationshipResolver(identifiers.ToList(), options, registry_manager.registry, ksp.VersionCriteria());
            Upgrade(resolver.ModList(), netAsyncDownloader, enforceConsistency);
        }
Пример #45
0
        /// <summary>
        ///     Installs all modules given a list of identifiers as a transaction. Resolves dependencies.
        ///     This *will* save the registry at the end of operation.
        ///
        /// Propagates a BadMetadataKraken if our install metadata is bad.
        /// Propagates a FileExistsKraken if we were going to overwrite a file.
        /// Propagates a CancelledActionKraken if the user cancelled the install.
        /// </summary>
        //
        // TODO: Break this up into smaller pieces! It's huge!
        public void InstallList(
            ICollection<CkanModule> modules,
            RelationshipResolverOptions options,
            IDownloader downloader = null
        )
        {
            var resolver = new RelationshipResolver(modules, options, registry_manager.registry, ksp.Version());
            List<CkanModule> modsToInstall = resolver.ModList();
            List<CkanModule> downloads = new List<CkanModule> ();

            // TODO: All this user-stuff should be happening in another method!
            // We should just be installing mods as a transaction.

            User.RaiseMessage("About to install...\n");

            foreach (CkanModule module in modsToInstall)
            {
                if (!ksp.Cache.IsCachedZip(module.download))
                {
                    User.RaiseMessage(" * {0} {1}", module.name, module.version);
                    downloads.Add(module);
                }
                else
                {
                    User.RaiseMessage(" * {0} {1}(cached)", module.name, module.version);
                }
            }

            bool ok = User.RaiseYesNoDialog("\nContinue?");

            if (!ok)
            {
                throw new CancelledActionKraken("User declined install list");
            }

            User.RaiseMessage(String.Empty); // Just to look tidy.

            if (downloads.Count > 0)
            {
                if (downloader == null)
                {
                    downloader = new NetAsyncDownloader(User);
                }

                downloader.DownloadModules(ksp.Cache, downloads);
            }

            // We're about to install all our mods; so begin our transaction.
            using (TransactionScope transaction = CkanTransaction.CreateTransactionScope())
            {
                for (int i = 0; i < modsToInstall.Count; i++)
                {
                    int percent_complete = (i * 100) / modsToInstall.Count;

                    User.RaiseProgress(String.Format("Installing mod \"{0}\"", modsToInstall[i]),
                                         percent_complete);

                    Install(modsToInstall[i]);
                }

                User.RaiseProgress("Updating registry", 70);

                registry_manager.Save(!options.without_enforce_consistency);

                User.RaiseProgress("Commiting filesystem changes", 80);

                transaction.Complete();

            }

            // We can scan GameData as a separate transaction. Installing the mods
            // leaves everything consistent, and this is just gravy. (And ScanGameData
            // acts as a Tx, anyway, so we don't need to provide our own.)

            User.RaiseProgress("Rescanning GameData", 90);

            if (!options.without_enforce_consistency)
            {
                ksp.ScanGameData();
            }

            User.RaiseProgress("Done!\n", 100);
        }
Пример #46
0
        /// <summary>
        /// Upgrades the mods listed to the latest versions for the user's KSP.
        /// Will *re-install* with warning even if an upgrade is not available.
        /// Throws ModuleNotFoundKraken if module is not installed, or not available.
        /// </summary>
        public void Upgrade(IEnumerable<string> identifiers, IDownloader netAsyncDownloader)
        {
            var options = new RelationshipResolverOptions();

            // We do not wish to pull in any suggested or recommended mods.
            options.with_recommends = false;
            options.with_suggests = false;

            var resolver = new RelationshipResolver(identifiers.ToList(), options, registry_manager.registry, ksp.Version());
            List<CkanModule> upgrades = resolver.ModList();

            Upgrade(upgrades, netAsyncDownloader);
        }
Пример #47
0
        public void InstallList(
            List<string> modules,
            RelationshipResolverOptions options,
            IDownloader downloader = null
        )
        {
            var resolver = new RelationshipResolver(modules, options, registry_manager.registry, ksp.Version());
            List<CkanModule> modsToInstall = resolver.ModList();

            InstallList(modsToInstall, options, downloader);
        }
Пример #48
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"></param>
        /// <returns></returns>
        private Dictionary<CkanModule, string> GetShowableMods(Dictionary<string, List<string>> mods)
        {
            Dictionary<CkanModule, string> modules = new Dictionary<CkanModule, string>();

            var opts = new RelationshipResolverOptions
            {
                with_all_suggests = false,
                with_recommends = false,
                with_suggests = false,
                without_enforce_consistency = false,
                without_toomanyprovides_kraken = true
            };

            foreach (var pair in mods)
            {
                CkanModule module;

                try
                {
                    var resolver = new RelationshipResolver(new List<string> { pair.Key }, opts,
                        RegistryManager.Instance(manager.CurrentInstance).registry, CurrentInstance.Version());
                    if (!resolver.ModList().Any())
                    {
                        continue;
                    }

                    module = RegistryManager.Instance(manager.CurrentInstance)
                        .registry.LatestAvailable(pair.Key, CurrentInstance.Version());
                }
                catch
                {
                    continue;
                }

                if (module == null)
                {
                    continue;
                }
                modules.Add(module, String.Join(",", pair.Value.ToArray()));
            }
            return modules;
        }