示例#1
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;

            // 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:
            var revdep = registry.FindReverseDependencies(new List <string>()
            {
                module.Identifier
            });
            var goners = revdep.Union(
                registry.FindRemovableAutoInstalled(
                    registry.InstalledModules.Where(im => !revdep.Contains(im.identifier))
                    ).Select(im => im.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.DependsOnlyOpts()
                    )
                );
        }
示例#2
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 game instance</param>
        /// <param name="version">The version of the current game instance</param>
        public IEnumerable <ModChange> ComputeChangeSetFromModList(
            IRegistryQuerier registry, HashSet <ModChange> changeSet, ModuleInstaller installer,
            GameVersionCriteria version)
        {
            var modules_to_install = new HashSet <CkanModule>();
            var modules_to_remove  = new HashSet <CkanModule>();

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

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

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

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

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            var installed_modules =
                registry.InstalledModules.Select(imod => imod.Module).ToDictionary(mod => mod.identifier, mod => mod);

            foreach (var dependent in registry.FindReverseDependencies(
                         modules_to_remove
                         .Select(mod => mod.identifier)
                         .Except(modules_to_install.Select(m => m.identifier)),
                         modules_to_install
                         ))
            {
                //TODO This would be a good place to have an event that alters the row's graphics to show it will be removed
                CkanModule depMod;
                if (installed_modules.TryGetValue(dependent, out depMod))
                {
                    CkanModule module_by_version = registry.GetModuleByVersion(depMod.identifier,
                                                                               depMod.version)
                                                   ?? registry.InstalledModule(dependent).Module;
                    changeSet.Add(new ModChange(module_by_version, GUIModChangeType.Remove, null));
                    modules_to_remove.Add(module_by_version);
                }
            }
            foreach (var im in registry.FindRemovableAutoInstalled(
                         registry.InstalledModules.Where(im => !modules_to_remove.Any(m => m.identifier == im.identifier) || modules_to_install.Any(m => m.identifier == im.identifier))
                         ))
            {
                changeSet.Add(new ModChange(im.Module, GUIModChangeType.Remove, new SelectionReason.NoLongerUsed()));
                modules_to_remove.Add(im.Module);
            }

            // Get as many dependencies as we can, but leave decisions and prompts for installation time
            RelationshipResolverOptions opts = RelationshipResolver.DependsOnlyOpts();

            opts.without_toomanyprovides_kraken = true;
            opts.without_enforce_consistency    = true;

            var resolver = new RelationshipResolver(
                modules_to_install,
                modules_to_remove,
                opts, registry, version);

            changeSet.UnionWith(
                resolver.ModList()
                .Select(m => new ModChange(m, GUIModChangeType.Install, resolver.ReasonFor(m))));

            return(changeSet);
        }
示例#3
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,
            FactorioVersion version)
        {
            var modules_to_install = new HashSet <CfanModule>();
            var modules_to_remove  = new HashSet <CfanModule>();
            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.Update:
                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;

                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
                CfanModule module_by_version = registry.GetModuleByVersion(installed_modules[dependency].identifier,
                                                                           installed_modules[dependency].modVersion) ?? 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);
        }
示例#4
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,
            KspVersionCriteria version)
        {
            var modules_to_install = new HashSet <CkanModule>();
            var modules_to_remove  = new HashSet <CkanModule>();

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

                case GUIModChangeType.Update:
                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.Replace:
                    ModuleReplacement repl = registry.GetReplacement(change.Mod.ToModule(), version);
                    if (repl != null)
                    {
                        modules_to_remove.Add(repl.ToReplace);
                        modules_to_install.Add(repl.ReplaceWith);
                    }
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            var installed_modules =
                registry.InstalledModules.Select(imod => imod.Module).ToDictionary(mod => mod.identifier, mod => mod);

            foreach (var dependency in registry.FindReverseDependencies(
                         modules_to_remove
                         .Select(mod => mod.identifier)
                         .Except(modules_to_install.Select(m => m.identifier))
                         ))
            {
                //TODO This would be a good place to have a event that alters the row's graphics to show it will be removed
                CkanModule 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));
                modules_to_remove.Add(module_by_version);
            }
            foreach (var im in registry.FindRemovableAutoInstalled(
                         registry.InstalledModules.Where(im => !modules_to_remove.Any(m => m.identifier == im.identifier))
                         ))
            {
                changeSet.Add(new ModChange(new GUIMod(im.Module, registry, version), GUIModChangeType.Remove, new SelectionReason.NoLongerUsed()));
                modules_to_remove.Add(im.Module);
            }

            bool handled_all_too_many_provides = false;

            while (!handled_all_too_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,
                        modules_to_remove,
                        RelationshipResolver.DependsOnlyOpts(),
                        registry, version);
                    handled_all_too_many_provides = true;
                    continue;
                }
                catch (TooManyModsProvideKraken k)
                {
                    kraken = k;
                }
                //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;
                }
            }

            var resolver = new RelationshipResolver(
                modules_to_install,
                modules_to_remove,
                RelationshipResolver.DependsOnlyOpts(), registry, version);

            changeSet.UnionWith(
                resolver.ModList()
                .Select(m => new ModChange(new GUIMod(m, registry, version), GUIModChangeType.Install, resolver.ReasonFor(m))));

            return(changeSet);
        }
示例#5
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;
        }