Example #1
0
        private void ContentsDownloadButton_Click(object sender, EventArgs e)
        {
            if (ModList.SelectedRows.Count == 0)
            {
                return;
            }

            DataGridViewRow selectedItem = ModList.SelectedRows[0];

            if (selectedItem == null)
            {
                return;
            }

            var module = ((GUIMod)selectedItem.Tag).ToCkanModule();

            if (module == null)
            {
                return;
            }

            ResetProgress();
            ShowWaitDialog(false);
            ModuleInstaller.GetInstance(CurrentInstance, GUI.user).CachedOrDownload(module);
            HideWaitDialog(true);

            UpdateModContentsTree(module);
            RecreateDialogs();
        }
Example #2
0
        private void _UpdateModContentsTree(CkanModule module, bool force = false)
        {
            ContentsPreviewTree.BackColor = SystemColors.Window;
            ContentsPreviewTree.LineColor = SystemColors.WindowText;

            if (Equals(module, currentModContentsModule) && !force)
            {
                return;
            }
            else
            {
                currentModContentsModule = module;
            }
            if (module.IsMetapackage)
            {
                NotCachedLabel.Text            = Properties.Resources.ModInfoNoDownload;
                ContentsPreviewTree.Enabled    = false;
                ContentsDownloadButton.Enabled = false;
                ContentsOpenButton.Enabled     = false;
                ContentsPreviewTree.Nodes.Clear();
            }
            else
            {
                ContentsPreviewTree.Enabled = true;
                ContentsPreviewTree.Nodes.Clear();
                ContentsPreviewTree.Nodes.Add(module.name);
                if (!Main.Instance.Manager.Cache.IsMaybeCachedZip(module))
                {
                    NotCachedLabel.Text            = Properties.Resources.ModInfoNotCached;
                    ContentsDownloadButton.Enabled = true;
                    ContentsOpenButton.Enabled     = false;
                    ContentsPreviewTree.Enabled    = false;
                }
                else
                {
                    NotCachedLabel.Text            = Properties.Resources.ModInfoCached;
                    ContentsDownloadButton.Enabled = false;
                    ContentsOpenButton.Enabled     = true;
                    ContentsPreviewTree.Enabled    = true;

                    // Get all the data; can put this in bg if slow
                    var contents = ModuleInstaller.GetInstance(
                        manager.CurrentInstance,
                        Main.Instance.Manager.Cache,
                        Main.Instance.currentUser)
                                   .GetModuleContentsList(module)?.ToList();

                    // Update UI; must be in fg
                    if (contents != null)
                    {
                        foreach (string item in contents)
                        {
                            ContentsPreviewTree.Nodes[0].Nodes.Add(
                                item.Replace('/', Path.DirectorySeparatorChar));
                        }
                        ContentsPreviewTree.Nodes[0].ExpandAll();
                    }
                }
            }
        }
Example #3
0
        public void SetUp()
        {
            _testModule = TestData.DogeCoinFlag_101_module();

            _nullUser = new NullUser();

            _manager         = new KSPManager(_nullUser);
            _instance        = new DisposableKSP();
            _registryManager = CKAN.RegistryManager.Instance(_instance.KSP);
            _registry        = _registryManager.registry;
            _installer       = CKAN.ModuleInstaller.GetInstance(_instance.KSP, _manager.Cache, _nullUser);

            _gameDataDir = _instance.KSP.GameData();
            _registry.AddAvailable(_testModule);
            var testModFile = TestData.DogeCoinFlagZip();

            _manager.Cache.Store(_testModule, testModFile);
            _installer.InstallList(
                new List <string>()
            {
                _testModule.identifier
            },
                new RelationshipResolverOptions(),
                _registryManager
                );
        }
Example #4
0
        public void SetUp()
        {
            _testModule = TestData.DogeCoinFlag_101_module();

            _instance        = new DisposableKSP();
            _nullUser        = new NullUser();
            _config          = new FakeConfiguration(_instance.KSP, _instance.KSP.Name);
            _manager         = new GameInstanceManager(_nullUser, _config);
            _registryManager = CKAN.RegistryManager.Instance(_instance.KSP);
            _registry        = _registryManager.registry;
            _installer       = CKAN.ModuleInstaller.GetInstance(_instance.KSP, _manager.Cache, _nullUser);

            _gameDir     = _instance.KSP.GameDir();
            _gameDataDir = _instance.KSP.game.PrimaryModDirectory(_instance.KSP);
            _registry.AddAvailable(_testModule);
            var testModFile = TestData.DogeCoinFlagZip();

            _manager.Cache.Store(_testModule, testModFile);
            HashSet <string> possibleConfigOnlyDirs = null;

            _installer.InstallList(
                new List <string>()
            {
                _testModule.identifier
            },
                new RelationshipResolverOptions(),
                _registryManager,
                ref possibleConfigOnlyDirs
                );
        }
Example #5
0
        public void TestSimple()
        {
            var modules = _registry.available_modules
                          .Select((mod) => new GUIMod(mod.Value.Latest(), _registry, _instance.KSP.VersionCriteria()))
                          .ToList();

            // varargs method signature means we must call .ToArray()
            _listGui.Rows.AddRange(_modList.ConstructModList(modules).ToArray());
            // the header row adds one to the count
            Assert.AreEqual(modules.Count + 1, _listGui.Rows.Count);

            // sort by a text column, this is the fuse-lighting
            _listGui.Sort(_listGui.Columns[6], ListSortDirection.Descending);

            // mark the mod for install, after completion we will get an exception
            var otherModule = modules.First((mod) => mod.Identifier.Contains("kOS"));

            otherModule.IsInstallChecked = true;

            Assert.IsTrue(otherModule.IsInstallChecked);
            Assert.IsFalse(otherModule.IsInstalled);

            Assert.DoesNotThrow(() =>
            {
                // perform the install of the "other" module - now we need to sort
                ModuleInstaller.GetInstance(_instance.KSP, _manager.Cache, _manager.User).InstallList(
                    _modList.ComputeUserChangeSet(null).Select(change => change.Mod.ToCkanModule()).ToList(),
                    new RelationshipResolverOptions(),
                    new NetAsyncModulesDownloader(_manager.User, _manager.Cache)
                    );

                // trying to refresh the GUI state will throw a NullReferenceException
                _listGui.Refresh();
            });
        }
Example #6
0
        // Uninstalls a module, if it exists.
        static int Remove(RemoveOptions options)
        {
            ModuleInstaller installer = new ModuleInstaller();

            installer.Uninstall(options.Modname);

            return(EXIT_OK);
        }
Example #7
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;
            }
        }
Example #8
0
 private bool installable(ModuleInstaller installer, CkanModule module, IRegistryQuerier registry)
 {
     return(module.IsCompatibleKSP(Main.Instance.CurrentInstance.VersionCriteria()) &&
            installer.CanInstall(
                RelationshipResolver.DependsOnlyOpts(),
                new List <CkanModule>()
     {
         module
     },
                registry));
 }
Example #9
0
File: Repo.cs Project: starllv/CKAN
        /// <summary>
        /// Resolve differences between installed and available metadata for given ModuleInstaller
        /// </summary>
        /// <param name="metadataChanges">List of modules that changed</param>
        /// <param name="user">Object for user interaction callbacks</param>
        /// <param name="ksp">Game instance</param>
        private static void HandleModuleChanges(List <CkanModule> metadataChanges, IUser user, KSP ksp, NetModuleCache cache, RegistryManager registry_manager)
        {
            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < metadataChanges.Count; i++)
            {
                CkanModule module = metadataChanges[i];
                sb.AppendLine(string.Format("- {0} {1}", module.identifier, module.version));
            }

            if (user.RaiseYesNoDialog(string.Format(@"The following mods have had their metadata changed since last update:

{0}
You should reinstall them in order to preserve consistency with the repository.

Do you wish to reinstall now?", sb)))
            {
                ModuleInstaller installer = ModuleInstaller.GetInstance(ksp, cache, new NullUser());
                // New upstream metadata may break the consistency of already installed modules
                // e.g. if user installs modules A and B and then later up A is made to conflict with B
                // This is perfectly normal and shouldn't produce an error, therefore we skip enforcing
                // consistency. However, we will show the user any inconsistencies later on.

                // Use the identifiers so we use the overload that actually resolves relationships
                // Do each changed module one at a time so a failure of one doesn't cause all the others to fail
                foreach (string changedIdentifier in metadataChanges.Select(i => i.identifier))
                {
                    try
                    {
                        HashSet <string> possibleConfigOnlyDirs = null;
                        installer.Upgrade(
                            new[] { changedIdentifier },
                            new NetAsyncModulesDownloader(new NullUser(), cache),
                            ref possibleConfigOnlyDirs,
                            registry_manager,
                            enforceConsistency: false
                            );
                    }
                    // Thrown when a dependency couldn't be satisfied
                    catch (ModuleNotFoundKraken)
                    {
                        log.WarnFormat("Skipping installation of {0} due to relationship error.", changedIdentifier);
                        user.RaiseMessage("Skipping installation of {0} due to relationship error.", changedIdentifier);
                    }
                    // Thrown when a conflicts relationship is violated
                    catch (InconsistentKraken)
                    {
                        log.WarnFormat("Skipping installation of {0} due to relationship error.", changedIdentifier);
                        user.RaiseMessage("Skipping installation of {0} due to relationship error.", changedIdentifier);
                    }
                }
            }
        }
Example #10
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);
        }
Example #11
0
        private void _UpdateModContentsTree(bool force = false)
        {
            ContentsPreviewTree.BackColor = SystemColors.Window;
            ContentsPreviewTree.LineColor = SystemColors.WindowText;
            GUIMod guiMod = SelectedModule;

            if (!guiMod.IsCKAN)
            {
                return;
            }
            CkanModule module = guiMod.ToCkanModule();

            if (Equals(module, currentModContentsModule) && !force)
            {
                return;
            }
            else
            {
                currentModContentsModule = module;
            }
            if (!guiMod.IsCached)
            {
                NotCachedLabel.Text            = Properties.Resources.ModInfoNotCached;
                ContentsDownloadButton.Enabled = true;
                ContentsOpenButton.Enabled     = false;
                ContentsPreviewTree.Enabled    = false;
            }
            else
            {
                NotCachedLabel.Text            = Properties.Resources.ModInfoCached;
                ContentsDownloadButton.Enabled = false;
                ContentsOpenButton.Enabled     = true;
                ContentsPreviewTree.Enabled    = true;
            }

            ContentsPreviewTree.Nodes.Clear();
            ContentsPreviewTree.Nodes.Add(module.name);

            IEnumerable <string> contents = ModuleInstaller.GetInstance(manager.CurrentInstance, Main.Instance.Manager.Cache, Main.Instance.currentUser).GetModuleContentsList(module);

            if (contents == null)
            {
                return;
            }

            foreach (string item in contents)
            {
                ContentsPreviewTree.Nodes[0].Nodes.Add(item.Replace('/', Path.DirectorySeparatorChar));
            }

            ContentsPreviewTree.Nodes[0].ExpandAll();
        }
Example #12
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);
        }
Example #13
0
        private async Task UpdateChangeSetAndConflicts(IRegistryQuerier registry)
        {
            IEnumerable <ModChange>     full_change_set = null;
            Dictionary <GUIMod, string> new_conflicts   = null;

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

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

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

            if (too_many_provides_thrown)
            {
                await UpdateChangeSetAndConflicts(registry);

                new_conflicts   = Conflicts;
                full_change_set = ChangeSet;
            }

            last_mod_to_have_install_toggled.Clear();
            Conflicts = new_conflicts;
            ChangeSet = full_change_set;
        }
Example #14
0
        private void _UpdateModContentsTree(bool force = false)
        {
            GUIMod guiMod = SelectedModule;

            if (!guiMod.IsCKAN)
            {
                return;
            }
            CkanModule module = guiMod.ToCkanModule();

            if (Equals(module, current_mod_contents_module) && !force)
            {
                return;
            }
            else
            {
                current_mod_contents_module = module;
            }
            if (!guiMod.IsCached)
            {
                NotCachedLabel.Text            = Properties.Resources.MainModInfoNotCached;
                ContentsDownloadButton.Enabled = true;
                ContentsOpenButton.Enabled     = false;
                ContentsPreviewTree.Enabled    = false;
            }
            else
            {
                NotCachedLabel.Text            = Properties.Resources.MainModInfoCached;
                ContentsDownloadButton.Enabled = false;
                ContentsOpenButton.Enabled     = true;
                ContentsPreviewTree.Enabled    = true;
            }

            ContentsPreviewTree.Nodes.Clear();
            ContentsPreviewTree.Nodes.Add(module.name);

            IEnumerable <string> contents = ModuleInstaller.GetInstance(manager.CurrentInstance, Main.Instance.Manager.Cache, GUI.user).GetModuleContentsList(module);

            if (contents == null)
            {
                return;
            }

            foreach (string item in contents)
            {
                ContentsPreviewTree.Nodes[0].Nodes.Add(item);
            }

            ContentsPreviewTree.Nodes[0].ExpandAll();
        }
Example #15
0
        /// <summary>
        /// Initiate the GUI installer flow for one specific module
        /// </summary>
        /// <param name="registry">Reference to the registry</param>
        /// <param name="module">Module to install</param>
        public async void InstallModuleDriver(IRegistryQuerier registry, CkanModule module)
        {
            RelationshipResolverOptions install_ops = RelationshipResolver.DefaultOpts();

            install_ops.with_recommends = false;

            try
            {
                // Resolve the provides relationships in the dependencies
                List <ModChange> fullChangeSet = new List <ModChange>(
                    await mainModList.ComputeChangeSetFromModList(
                        registry,
                        new HashSet <ModChange>()
                {
                    new ModChange(
                        new GUIMod(
                            module,
                            registry,
                            CurrentInstance.VersionCriteria()
                            ),
                        GUIModChangeType.Install,
                        null
                        )
                },
                        ModuleInstaller.GetInstance(CurrentInstance, 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;
            }
        }
Example #16
0
        /// <summary>
        /// Gets the ModuleInstaller instance associated with the passed KSP instance. Creates a new ModuleInstaller instance if none exists.
        /// </summary>
        /// <returns>The ModuleInstaller instance.</returns>
        /// <param name="ksp_instance">Current KSP instance.</param>
        /// <param name="user">IUser implementation.</param>
        public static ModuleInstaller GetInstance(KSP ksp_instance, IUser user)
        {
            ModuleInstaller instance;

            // Check in the list of instances if we have already created a ModuleInstaller instance for this KSP instance.
            if (!instances.TryGetValue(ksp_instance.GameDir().ToLower(), out instance))
            {
                // Create a new instance and insert it in the static list.
                instance = new ModuleInstaller(ksp_instance, user);

                instances.Add(ksp_instance.GameDir().ToLower(), instance);
            }

            return instance;
        }
Example #17
0
        private bool allowInstall(CkanModule module)
        {
            GameInstance     currentInstance = Main.Instance.Manager.CurrentInstance;
            IRegistryQuerier registry        = RegistryManager.Instance(currentInstance).registry;
            var installer = new ModuleInstaller(
                currentInstance,
                Main.Instance.Manager.Cache,
                Main.Instance.currentUser);

            return(installable(installer, module, registry) ||
                   Main.Instance.YesNoDialog(
                       string.Format(Properties.Resources.AllModVersionsInstallPrompt, module.ToString()),
                       Properties.Resources.AllModVersionsInstallYes,
                       Properties.Resources.AllModVersionsInstallNo));
        }
Example #18
0
        /// <summary>
        /// Gets the ModuleInstaller instance associated with the passed KSP instance. Creates a new ModuleInstaller instance if none exists.
        /// </summary>
        /// <returns>The ModuleInstaller instance.</returns>
        /// <param name="ksp_instance">Current KSP instance.</param>
        /// <param name="user">IUser implementation.</param>
        public static ModuleInstaller GetInstance(KSP ksp_instance, IUser user)
        {
            ModuleInstaller instance;

            // Check in the list of instances if we have already created a ModuleInstaller instance for this KSP instance.
            if (!instances.TryGetValue(ksp_instance.GameDir().ToLower(), out instance))
            {
                // Create a new instance and insert it in the static list.
                instance = new ModuleInstaller(ksp_instance, user);

                instances.Add(ksp_instance.GameDir().ToLower(), instance);
            }

            return(instance);
        }
Example #19
0
        public void Up()
        {
            _instance        = new DisposableKSP();
            _registryManager = RegistryManager.Instance(_instance.KSP);
            _registry        = Registry.Empty();
            _config          = new FakeConfiguration(_instance.KSP, _instance.KSP.Name);
            _manager         = new GameInstanceManager(
                new NullUser(),
                _config
                );

            // this module contains a ksp_version of "any" which repros our issue
            _anyVersionModule = TestData.DogeCoinFlag_101_module();

            // install it and set it as pre-installed
            _manager.Cache.Store(TestData.DogeCoinFlag_101_module(), TestData.DogeCoinFlagZip());
            _registry.RegisterModule(_anyVersionModule, new string[] { }, _instance.KSP, false);
            _registry.AddAvailable(_anyVersionModule);

            HashSet <string> possibleConfigOnlyDirs = null;

            ModuleInstaller.GetInstance(_instance.KSP, _manager.Cache, _manager.User).InstallList(
                new List <CkanModule> {
                { _anyVersionModule }
            },
                new RelationshipResolverOptions(),
                _registryManager,
                ref possibleConfigOnlyDirs,
                new NetAsyncModulesDownloader(_manager.User, _manager.Cache)
                );

            // this module is not for "any" version, to provide another to sort against
            _registry.AddAvailable(TestData.kOS_014_module());

            // test object
            _modList = new ModList(null);
            _listGui = new DataGridView();

            // todo: refactor the column header code to allow mocking of the GUI without creating columns
            _listGui.Columns.Add(new DataGridViewCheckBoxColumn());
            _listGui.Columns.Add(new DataGridViewCheckBoxColumn());
            _listGui.Columns.Add(new DataGridViewCheckBoxColumn());
            _listGui.Columns.Add(new DataGridViewCheckBoxColumn());
            for (int i = 0; i < 10; i++)
            {
                _listGui.Columns.Add(i.ToString(), "Column" + i);
            }
        }
Example #20
0
        private void _UpdateModContentsTree(bool force = false)
        {
            GUIMod guiMod = GetSelectedModule();

            if (!guiMod.IsCKAN)
            {
                return;
            }
            CfanModule module = guiMod.ToCkanModule();

            if (Equals(module, current_mod_contents_module) && !force)
            {
                return;
            }
            else
            {
                current_mod_contents_module = module;
            }
            if (!guiMod.IsCached)
            {
                NotCachedLabel.Text            = "This mod is not in the cache, click 'Download' to preview contents";
                ContentsDownloadButton.Enabled = true;
                ContentsPreviewTree.Enabled    = false;
            }
            else
            {
                NotCachedLabel.Text            = "Module is cached, preview available";
                ContentsDownloadButton.Enabled = false;
                ContentsPreviewTree.Enabled    = true;
            }

            ContentsPreviewTree.Nodes.Clear();
            ContentsPreviewTree.Nodes.Add(module.title);

            IEnumerable <string> contents = ModuleInstaller.GetInstance(manager.CurrentInstance, GUI.user).GetModuleContentsList(module);

            if (contents == null)
            {
                return;
            }

            foreach (string item in contents)
            {
                ContentsPreviewTree.Nodes[0].Nodes.Add(item);
            }

            ContentsPreviewTree.Nodes[0].ExpandAll();
        }
Example #21
0
        private void ContentsDownloadButton_Click(object sender, EventArgs e)
        {
            var module = GetSelectedModule();

            if (module == null)
            {
                return;
            }
            ResetProgress();
            ShowWaitDialog(false);
            ModuleInstaller.GetInstance(CurrentInstance, GUI.user).CachedOrDownload(module);
            HideWaitDialog(true);

            UpdateModContentsTree(module);
            RecreateDialogs();
        }
Example #22
0
        public async Task TooManyProvidesCallsHandlers()
        {
            using (var tidy = new DisposableKSP())
            {
                var manager       = new KSPManager(new NullUser());
                var registry      = Registry.Empty();
                var generator     = new RandomModuleGenerator(new Random(0451));
                var provide_ident = "provide";
                var ksp_version   = tidy.KSP.Version();
                var mod           = generator.GeneratorRandomModule(depends: new List <RelationshipDescriptor>
                {
                    new ModuleRelationshipDescriptor {
                        name = provide_ident
                    }
                }, ksp_version: ksp_version);
                var moda = generator.GeneratorRandomModule(provides: new List <string> {
                    provide_ident
                }
                                                           , ksp_version: ksp_version);
                var modb = generator.GeneratorRandomModule(provides: new List <string> {
                    provide_ident
                }
                                                           , ksp_version: ksp_version);
                var choice_of_provide = modb;
                registry.AddAvailable(mod);
                registry.AddAvailable(moda);
                registry.AddAvailable(modb);
                var installer     = ModuleInstaller.GetInstance(tidy.KSP, manager.Cache, null);
                var main_mod_list = new MainModList(null, async kraken => await Task.FromResult(choice_of_provide));
                var a             = new HashSet <ModChange>
                {
                    new ModChange(new GUIMod(mod, registry, new KspVersionCriteria(ksp_version)), GUIModChangeType.Install, null)
                };

                var mod_list = await main_mod_list.ComputeChangeSetFromModList(registry, a, installer, new KspVersionCriteria (ksp_version));

                CollectionAssert.AreEquivalent(
                    new[] {
                    new ModChange(new GUIMod(mod, registry, new KspVersionCriteria(ksp_version)), GUIModChangeType.Install, null),
                    new ModChange(new GUIMod(modb, registry, new KspVersionCriteria(ksp_version)), GUIModChangeType.Install, null)
                }, mod_list);

                manager.Dispose();
            }
        }
Example #23
0
        private void _UpdateModContentsTree()
        {
            var module = (CkanModule)ModInfoTabControl.Tag;

            if (module == current_mod_contents_module)
            {
                return;
            }
            else
            {
                current_mod_contents_module = module;
            }
            if (!manager.CurrentInstance.Cache.IsCachedZip(module.download))
            {
                NotCachedLabel.Text            = "This mod is not in the cache, click 'Download' to preview contents";
                ContentsDownloadButton.Enabled = true;
                ContentsPreviewTree.Enabled    = false;
            }
            else
            {
                NotCachedLabel.Text            = "Module is cached, preview available";
                ContentsDownloadButton.Enabled = false;
                ContentsPreviewTree.Enabled    = true;
            }

            ContentsPreviewTree.Nodes.Clear();
            ContentsPreviewTree.Nodes.Add(module.name);

            IEnumerable <string> contents = ModuleInstaller.GetInstance(manager.CurrentInstance, GUI.user).GetModuleContentsList(module);

            if (contents == null)
            {
                return;
            }

            foreach (string item in contents)
            {
                ContentsPreviewTree.Nodes[0].Nodes.Add(item);
            }

            ContentsPreviewTree.Nodes[0].ExpandAll();
        }
Example #24
0
        private void ImportModules()
        {
            // Prompt the user to select one or more ZIP files
            OpenFileDialog dlg = new OpenFileDialog()
            {
                Title            = "Import Mods",
                AddExtension     = true,
                CheckFileExists  = true,
                CheckPathExists  = true,
                InitialDirectory = FindDownloadsPath(CurrentInstance),
                DefaultExt       = "zip",
                Filter           = "Mods (*.zip)|*.zip",
                Multiselect      = true
            };

            if (dlg.ShowDialog() == DialogResult.OK &&
                dlg.FileNames.Length > 0)
            {
                // Set up GUI to respond to IUser calls...
                GUIUser.DisplayYesNo old_YesNoDialog = currentUser.displayYesNo;
                currentUser.displayYesNo = YesNoDialog;
                tabController.RenameTab("WaitTabPage", "Status log");
                tabController.ShowTab("WaitTabPage");
                tabController.SetTabLock(true);

                try
                {
                    ModuleInstaller.GetInstance(CurrentInstance, Manager.Cache, currentUser).ImportFiles(
                        GetFiles(dlg.FileNames),
                        currentUser,
                        (CkanModule mod) => MarkModForInstall(mod.identifier, false)
                        );
                }
                finally
                {
                    // Put GUI back the way we found it
                    currentUser.displayYesNo = old_YesNoDialog;
                    tabController.SetTabLock(false);
                    tabController.HideTab("WaitTabPage");
                }
            }
        }
Example #25
0
        static int Install(InstallOptions options)
        {
            // If we have a zipfile, use it.

            if (options.ZipFile != null)
            {
                // Aha! We've been called as ckan -f somefile.zip somefile.ckan

                if (options.Files.Count > 1)
                {
                    Console.WriteLine("Only a single CKAN file can be provided when installing from zip");
                    return(EXIT_BADOPT);
                }

                // TODO: Support installing from CKAN file embedded in zip.

                string zipFilename  = options.ZipFile;
                string ckanFilename = options.Files[0];

                Console.WriteLine("Installing " + ckanFilename + " from " + zipFilename);

                CkanModule      module    = CkanModule.from_file(ckanFilename);
                ModuleInstaller installer = new ModuleInstaller();

                installer.Install(module, zipFilename);
                return(EXIT_OK);
            }

            // Regular invocation, walk through all CKAN files on the cmdline

            foreach (string filename in options.Files)
            {
                CkanModule      module    = CkanModule.from_file(filename);
                ModuleInstaller installer = new ModuleInstaller();
                installer.Install(module);
            }

            Console.WriteLine("\nDone!\n");

            return(EXIT_OK);
        }
Example #26
0
        private void ImportModules()
        {
            // Prompt the user to select one or more ZIP files
            OpenFileDialog dlg = new OpenFileDialog()
            {
                Title            = Properties.Resources.MainImportTitle,
                AddExtension     = true,
                CheckFileExists  = true,
                CheckPathExists  = true,
                InitialDirectory = FindDownloadsPath(CurrentInstance),
                DefaultExt       = "zip",
                Filter           = Properties.Resources.MainImportFilter,
                Multiselect      = true
            };

            if (dlg.ShowDialog() == DialogResult.OK &&
                dlg.FileNames.Length > 0)
            {
                // Show WaitTabPage (status page) and lock it.
                tabController.RenameTab("WaitTabPage", Properties.Resources.MainImportWaitTitle);
                tabController.ShowTab("WaitTabPage");
                tabController.SetTabLock(true);

                try
                {
                    ModuleInstaller.GetInstance(CurrentInstance, Manager.Cache, currentUser).ImportFiles(
                        GetFiles(dlg.FileNames),
                        currentUser,
                        (CkanModule mod) => ManageMods.MarkModForInstall(mod.identifier, false),
                        RegistryManager.Instance(CurrentInstance).registry
                        );
                }
                finally
                {
                    // Put GUI back the way we found it
                    tabController.SetTabLock(false);
                    tabController.HideTab("WaitTabPage");
                }
            }
        }
Example #27
0
        private async Task UpdateChangeSetAndConflicts(IRegistryQuerier registry)
        {
            IEnumerable <ModChange>     full_change_set = null;
            Dictionary <GUIMod, string> new_conflicts   = null;

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

            try
            {
                var module_installer = ModuleInstaller.GetInstance(CurrentInstance, GUI.user);
                full_change_set =
                    await mainModList.ComputeChangeSetFromModList(registry, user_change_set, module_installer,
                                                                  CurrentInstance.VersionCriteria());
            }
            catch (InconsistentKraken)
            {
                //Need to be recomputed due to ComputeChangeSetFromModList possibly changing it with too many provides handling.
                user_change_set = mainModList.ComputeUserChangeSet();
                new_conflicts   = MainModList.ComputeConflictsFromModList(registry, user_change_set, CurrentInstance.VersionCriteria());
                full_change_set = null;
            }
            catch (TooManyModsProvideKraken)
            {
                //Can be thrown by ComputeChangeSetFromModList if the user cancels out of it.
                //We can just rerun it as the ModInfoTabControl has been removed.
                too_many_provides_thrown = true;
            }
            if (too_many_provides_thrown)
            {
                await UpdateChangeSetAndConflicts(registry);

                new_conflicts   = Conflicts;
                full_change_set = ChangeSet;
            }
            last_mod_to_have_install_toggled.Clear();
            Conflicts = new_conflicts;
            ChangeSet = full_change_set;
        }
Example #28
0
        private void AuditRecommendations(IRegistryQuerier registry, GameVersionCriteria versionCriteria)
        {
            var installer = ModuleInstaller.GetInstance(CurrentInstance, Manager.Cache, currentUser);

            if (installer.FindRecommendations(
                    registry.InstalledModules.Select(im => im.Module).ToHashSet(),
                    new HashSet <CkanModule>(),
                    registry as Registry,
                    out Dictionary <CkanModule, Tuple <bool, List <string> > > recommendations,
                    out Dictionary <CkanModule, List <string> > suggestions,
                    out Dictionary <CkanModule, HashSet <string> > supporters
                    ))
            {
                tabController.ShowTab("ChooseRecommendedModsTabPage", 3);
                ChooseRecommendedMods.LoadRecommendations(
                    registry, new HashSet <CkanModule>(), new HashSet <CkanModule>(),
                    versionCriteria, Manager.Cache,
                    recommendations, suggestions, supporters);
                var result = ChooseRecommendedMods.Wait();
                tabController.HideTab("ChooseRecommendedModsTabPage");
                if (result != null && result.Any())
                {
                    installWorker.RunWorkerAsync(
                        new KeyValuePair <List <ModChange>, RelationshipResolverOptions>(
                            result.Select(mod => new ModChange(
                                              mod,
                                              GUIModChangeType.Install,
                                              null
                                              )).ToList(),
                            RelationshipResolver.DependsOnlyOpts()
                            )
                        );
                }
            }
            else
            {
                currentUser.RaiseError(Properties.Resources.MainRecommendationsNoneFound);
            }
        }
Example #29
0
        public void InstallList_IdentifierEqualsVersionSyntax_InstallsModule()
        {
            using (DisposableKSP ksp = new DisposableKSP())
            {
                // Arrange
                var config = new FakeConfiguration(ksp.KSP, ksp.KSP.Name);

                GameInstanceManager manager = new GameInstanceManager(
                    new NullUser(),
                    config
                    )
                {
                    CurrentInstance = ksp.KSP
                };
                var registry = CKAN.RegistryManager.Instance(ksp.KSP).registry;
                var inst     = new CKAN.ModuleInstaller(ksp.KSP, manager.Cache, nullUser);

                const string mod_file_name = "DogeCoinFlag/Flags/dogecoin.png";
                string       mod_file_path = Path.Combine(ksp.KSP.game.PrimaryModDirectory(ksp.KSP), mod_file_name);
                CkanModule   mod           = TestData.DogeCoinFlag_101_module();
                registry.AddAvailable(mod);
                manager.Cache.Store(mod, TestData.DogeCoinFlagZip());
                List <string> modules = new List <string>()
                {
                    $"{mod.identifier}={mod.version}"
                };

                // Act
                HashSet <string> possibleConfigOnlyDirs = null;
                inst.InstallList(modules, new RelationshipResolverOptions(), CKAN.RegistryManager.Instance(manager.CurrentInstance), ref possibleConfigOnlyDirs);

                // Assert
                Assert.IsTrue(File.Exists(mod_file_path));

                manager.Dispose();
                config.Dispose();
            }
        }
Example #30
0
        private void UpdateChangeSetAndConflicts(Registry registry)
        {
            IEnumerable <KeyValuePair <CkanModule, GUIModChangeType> > full_change_set;
            Dictionary <Module, string> conflicts;

            var user_change_set = mainModList.ComputeUserChangeSet();

            try
            {
                var module_installer = ModuleInstaller.GetInstance(CurrentInstance, GUI.user);
                full_change_set = MainModList.ComputeChangeSetFromModList(registry, user_change_set, module_installer,
                                                                          CurrentInstance.Version());
                conflicts = null;
            }
            catch (InconsistentKraken)
            {
                conflicts       = MainModList.ComputeConflictsFromModList(registry, user_change_set, CurrentInstance.Version());
                full_change_set = null;
            }

            Conflicts = conflicts;
            ChangeSet = full_change_set;
        }
Example #31
0
        // this probably needs to be refactored
        private void InstallMods(object sender, DoWorkEventArgs e)
        {
            installCanceled = false;
            ClearLog();

            var opts = (KeyValuePair <ModChanges, RelationshipResolverOptions>)e.Argument;

            IRegistryQuerier registry  = RegistryManager.Instance(manager.CurrentInstance).registry;
            ModuleInstaller  installer = ModuleInstaller.GetInstance(CurrentInstance, Manager.Cache, GUI.user);

            // Avoid accumulating multiple event handlers
            installer.onReportModInstalled -= OnModInstalled;
            installer.onReportModInstalled += OnModInstalled;
            // setup progress callback

            // this will be the final list of mods we want to install
            HashSet <CkanModule> toInstall = new HashSet <CkanModule>();
            var toUninstall = new HashSet <string>();
            var toUpgrade   = new HashSet <string>();

            // First compose sets of what the user wants installed, upgraded, and removed.
            foreach (ModChange change in opts.Key)
            {
                switch (change.ChangeType)
                {
                case GUIModChangeType.Remove:
                    toUninstall.Add(change.Mod.Identifier);
                    break;

                case GUIModChangeType.Update:
                    toUpgrade.Add(change.Mod.Identifier);
                    break;

                case GUIModChangeType.Install:
                    toInstall.Add(change.Mod.ToModule());
                    break;

                case GUIModChangeType.Replace:
                    ModuleReplacement repl = registry.GetReplacement(change.Mod.ToModule(), CurrentInstance.VersionCriteria());
                    if (repl != null)
                    {
                        toUninstall.Add(repl.ToReplace.identifier);
                        toInstall.Add(repl.ReplaceWith);
                    }
                    break;
                }
            }

            // Prompt for recommendations and suggestions, if any
            var recRows = getRecSugRows(
                opts.Key.Where(ch => ch.ChangeType == GUIModChangeType.Install)
                .Select(ch => ch.Mod.ToModule()),
                registry, toInstall
                );

            if (recRows.Any())
            {
                ShowRecSugDialog(recRows, toInstall);
            }

            tabController.HideTab("ChooseRecommendedModsTabPage");

            if (installCanceled)
            {
                tabController.ShowTab("ManageModsTabPage");
                e.Result = new KeyValuePair <bool, ModChanges>(false, opts.Key);
                return;
            }

            // Now let's make all our changes.
            tabController.RenameTab("WaitTabPage", "Status log");
            ShowWaitDialog();
            tabController.SetTabLock(true);

            IDownloader downloader = new NetAsyncModulesDownloader(GUI.user);

            cancelCallback = () =>
            {
                downloader.CancelDownload();
                installCanceled = true;
            };

            // checks if all actions were successfull
            bool processSuccessful       = false;
            bool resolvedAllProvidedMods = false;

            // uninstall/installs/upgrades until every list is empty
            // if the queue is NOT empty, resolvedAllProvidedMods is set to false until the action is done
            while (!resolvedAllProvidedMods)
            {
                try
                {
                    e.Result = new KeyValuePair <bool, ModChanges>(false, opts.Key);
                    if (toUninstall.Count > 0)
                    {
                        processSuccessful = false;
                        if (!installCanceled)
                        {
                            installer.UninstallList(toUninstall, false, toInstall.Select(m => m.identifier));
                            processSuccessful = true;
                        }
                    }
                    if (toUpgrade.Count > 0)
                    {
                        processSuccessful = false;
                        if (!installCanceled)
                        {
                            installer.Upgrade(toUpgrade, downloader);
                            processSuccessful = true;
                        }
                    }
                    if (toInstall.Count > 0)
                    {
                        processSuccessful = false;
                        if (!installCanceled)
                        {
                            installer.InstallList(toInstall, opts.Value, downloader, false);
                            processSuccessful = true;
                        }
                    }
                    e.Result = new KeyValuePair <bool, ModChanges>(processSuccessful, opts.Key);
                    if (installCanceled)
                    {
                        return;
                    }
                    resolvedAllProvidedMods = true;
                }
                catch (TooManyModsProvideKraken k)
                {
                    // Prompt user to choose which mod to use
                    CkanModule chosen = TooManyModsProvideCore(k).Result;
                    // Close the selection prompt
                    Util.Invoke(this, () =>
                    {
                        tabController.ShowTab("WaitTabPage");
                        tabController.HideTab("ChooseProvidedModsTabPage");
                    });
                    if (chosen != null)
                    {
                        // User picked a mod, queue it up for installation
                        toInstall.Add(chosen);
                        // DON'T return so we can loop around and try the above InstallList call again
                    }
                    else
                    {
                        // User cancelled, get out
                        tabController.ShowTab("ManageModsTabPage");
                        e.Result = new KeyValuePair <bool, ModChanges>(false, opts.Key);
                        return;
                    }
                }
                catch (DependencyNotSatisfiedKraken ex)
                {
                    GUI.user.RaiseMessage(
                        "{0} requires {1} but it is not listed in the index, or not available for your version of KSP.",
                        ex.parent, ex.module);
                    return;
                }
                catch (ModuleNotFoundKraken ex)
                {
                    GUI.user.RaiseMessage(
                        "Module {0} required but it is not listed in the index, or not available for your version of KSP.",
                        ex.module);
                    return;
                }
                catch (BadMetadataKraken ex)
                {
                    GUI.user.RaiseMessage("Bad metadata detected for module {0}: {1}", ex.module, ex.Message);
                    return;
                }
                catch (FileExistsKraken ex)
                {
                    if (ex.owningModule != null)
                    {
                        GUI.user.RaiseMessage(
                            "\r\nOh no! We tried to overwrite a file owned by another mod!\r\n" +
                            "Please try a `ckan update` and try again.\r\n\r\n" +
                            "If this problem re-occurs, then it maybe a packaging bug.\r\n" +
                            "Please report it at:\r\n\r\n" +
                            "https://github.com/KSP-CKAN/NetKAN/issues/new\r\n\r\n" +
                            "Please including the following information in your report:\r\n\r\n" +
                            "File           : {0}\r\n" +
                            "Installing Mod : {1}\r\n" +
                            "Owning Mod     : {2}\r\n" +
                            "CKAN Version   : {3}\r\n",
                            ex.filename, ex.installingModule, ex.owningModule,
                            Meta.GetVersion()
                            );
                    }
                    else
                    {
                        GUI.user.RaiseMessage(
                            "\r\n\r\nOh no!\r\n\r\n" +
                            "It looks like you're trying to install a mod which is already installed,\r\n" +
                            "or which conflicts with another mod which is already installed.\r\n\r\n" +
                            "As a safety feature, the CKAN will *never* overwrite or alter a file\r\n" +
                            "that it did not install itself.\r\n\r\n" +
                            "If you wish to install {0} via the CKAN,\r\n" +
                            "then please manually uninstall the mod which owns:\r\n\r\n" +
                            "{1}\r\n\r\n" + "and try again.\r\n",
                            ex.installingModule, ex.filename
                            );
                    }

                    GUI.user.RaiseMessage("Your GameData has been returned to its original state.\r\n");
                    return;
                }
                catch (InconsistentKraken ex)
                {
                    // The prettiest Kraken formats itself for us.
                    GUI.user.RaiseMessage(ex.InconsistenciesPretty);
                    return;
                }
                catch (CancelledActionKraken)
                {
                    return;
                }
                catch (MissingCertificateKraken kraken)
                {
                    // Another very pretty kraken.
                    GUI.user.RaiseMessage(kraken.ToString());
                    return;
                }
                catch (DownloadThrottledKraken kraken)
                {
                    string msg = kraken.ToString();
                    GUI.user.RaiseMessage(msg);
                    if (YesNoDialog($"{msg}\r\n\r\nOpen settings now?", "Open Settings", "No"))
                    {
                        // Launch the URL describing this host's throttling practices, if any
                        if (kraken.infoUrl != null)
                        {
                            Process.Start(new ProcessStartInfo()
                            {
                                UseShellExecute = true,
                                FileName        = kraken.infoUrl.ToString()
                            });
                        }
                        // Now pretend they clicked the menu option for the settings
                        Enabled = false;
                        settingsDialog.ShowDialog();
                        Enabled = true;
                    }
                    return;
                }
                catch (ModuleDownloadErrorsKraken kraken)
                {
                    GUI.user.RaiseMessage(kraken.ToString());
                    GUI.user.RaiseError(kraken.ToString());
                    return;
                }
                catch (DirectoryNotFoundKraken kraken)
                {
                    GUI.user.RaiseMessage("\r\n{0}", kraken.Message);
                    return;
                }
                catch (DllNotFoundException)
                {
                    if (GUI.user.RaiseYesNoDialog("libcurl installation not found. Open wiki page for help?"))
                    {
                        Process.Start(new ProcessStartInfo()
                        {
                            UseShellExecute = true,
                            FileName        = "https://github.com/KSP-CKAN/CKAN/wiki/libcurl"
                        });
                    }
                    throw;
                }
            }
        }
Example #32
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;
        }