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 ); }
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 ); }
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(); } }
// 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; } } }
// this probably needs to be refactored private void InstallMods(object sender, DoWorkEventArgs e) { installCanceled = false; Wait.ClearLog(); var opts = (KeyValuePair <ModChanges, RelationshipResolverOptions>)e.Argument; RegistryManager registry_manager = RegistryManager.Instance(manager.CurrentInstance); Registry registry = registry_manager.registry; ModuleInstaller installer = ModuleInstaller.GetInstance(CurrentInstance, Manager.Cache, currentUser); // 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); break; case GUIModChangeType.Replace: ModuleReplacement repl = registry.GetReplacement(change.Mod, CurrentInstance.VersionCriteria()); if (repl != null) { toUninstall.Add(repl.ToReplace.identifier); toInstall.Add(repl.ReplaceWith); } break; } } // Prompt for recommendations and suggestions, if any if (installer.FindRecommendations( opts.Key.Where(ch => ch.ChangeType == GUIModChangeType.Install) .Select(ch => ch.Mod) .ToHashSet(), toInstall, 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, CurrentInstance.VersionCriteria(), Manager.Cache, recommendations, suggestions, supporters); tabController.SetTabLock(true); var result = ChooseRecommendedMods.Wait(); if (result == null) { installCanceled = true; } else { toInstall.UnionWith(result); } tabController.SetTabLock(false); 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. Util.Invoke(this, () => { // Need to be on the GUI thread to get the translated string tabController.RenameTab("WaitTabPage", Properties.Resources.MainInstallWaitTitle); }); ShowWaitDialog(); tabController.SetTabLock(true); IDownloader downloader = new NetAsyncModulesDownloader(currentUser, Manager.Cache); downloader.Progress += Wait.SetModuleProgress; downloader.AllComplete += Wait.DownloadsComplete; cancelCallback = () => { downloader.CancelDownload(); installCanceled = true; }; HashSet <string> possibleConfigOnlyDirs = null; // 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, ref possibleConfigOnlyDirs, registry_manager, false, toInstall); processSuccessful = true; } } if (toUpgrade.Count > 0) { processSuccessful = false; if (!installCanceled) { installer.Upgrade(toUpgrade, downloader, ref possibleConfigOnlyDirs, registry_manager); processSuccessful = true; } } if (toInstall.Count > 0) { processSuccessful = false; if (!installCanceled) { installer.InstallList(toInstall, opts.Value, registry_manager, ref possibleConfigOnlyDirs, downloader, false); processSuccessful = true; } } HandlePossibleConfigOnlyDirs(registry, possibleConfigOnlyDirs); 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 tabController.ShowTab("ChooseProvidedModsTabPage", 3); ChooseProvidedMods.LoadProviders(k.requested, k.modules, Manager.Cache); tabController.SetTabLock(true); CkanModule chosen = ChooseProvidedMods.Wait(); // Close the selection prompt tabController.SetTabLock(false); 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 tabController.ShowTab("WaitTabPage"); } else { // User cancelled, get out tabController.ShowTab("ManageModsTabPage"); e.Result = new KeyValuePair <bool, ModChanges>(false, opts.Key); return; } } } }
// 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", Properties.Resources.MainInstallWaitTitle); ShowWaitDialog(); tabController.SetTabLock(true); IDownloader downloader = new NetAsyncModulesDownloader(GUI.user, Manager.Cache); 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(Properties.Resources.MainInstallDepNotSatisfied, ex.parent, ex.module); return; } catch (ModuleNotFoundKraken ex) { GUI.user.RaiseMessage(Properties.Resources.MainInstallNotFound, ex.module); return; } catch (BadMetadataKraken ex) { GUI.user.RaiseMessage(Properties.Resources.MainInstallBadMetadata, ex.module, ex.Message); return; } catch (FileExistsKraken ex) { if (ex.owningModule != null) { GUI.user.RaiseMessage( Properties.Resources.MainInstallFileExists, ex.filename, ex.installingModule, ex.owningModule, Meta.GetVersion() ); } else { GUI.user.RaiseMessage( Properties.Resources.MainInstallUnownedFileExists, ex.installingModule, ex.filename ); } GUI.user.RaiseMessage(Properties.Resources.MainInstallGameDataReverted); 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(string.Format(Properties.Resources.MainInstallOpenSettingsPrompt, msg), Properties.Resources.MainInstallOpenSettings, Properties.Resources.MainInstallNo)) { // 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(Properties.Resources.MainInstallLibCurlMissing)) { Process.Start(new ProcessStartInfo() { UseShellExecute = true, FileName = "https://github.com/KSP-CKAN/CKAN/wiki/libcurl" }); } throw; } } }
private void InstallMods(object sender, DoWorkEventArgs e) // this probably needs to be refactored { ShowWaitDialog(); installCanceled = false; ClearLog(); var opts = (KeyValuePair <ModChanges, RelationshipResolverOptions>)e.Argument; IRegistryQuerier registry = RegistryManager.Instance(manager.CurrentInstance).registry; ModuleInstaller installer = ModuleInstaller.GetInstance(CurrentInstance, GUI.user); // Avoid accumulating multiple event handlers installer.onReportModInstalled -= OnModInstalled; installer.onReportModInstalled += OnModInstalled; // setup progress callback 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; } } // Now work on satisifying dependencies. var recommended = new Dictionary <CkanModule, List <string> >(); var suggested = new Dictionary <CkanModule, List <string> >(); foreach (var change in opts.Key) { if (change.ChangeType == GUIModChangeType.Install) { AddMod(change.Mod.ToModule().recommends, recommended, change.Mod.Identifier, registry); AddMod(change.Mod.ToModule().suggests, suggested, change.Mod.Identifier, registry); } } ShowSelection(recommended); ShowSelection(suggested, true); tabController.HideTab("ChooseRecommendedModsTabPage"); if (installCanceled) { tabController.HideTab("WaitTabPage"); 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"); tabController.ShowTab("WaitTabPage"); tabController.SetTabLock(true); IDownloader downloader = new NetAsyncModulesDownloader(GUI.user); cancelCallback = () => { downloader.CancelDownload(); installCanceled = true; }; bool resolvedAllProvidedMods = false; while (!resolvedAllProvidedMods) { try { e.Result = new KeyValuePair <bool, ModChanges>(false, opts.Key); if (!installCanceled && toUninstall.Count > 0) { installer.UninstallList(toUninstall); } if (!installCanceled && toUpgrade.Count > 0) { installer.Upgrade(toUpgrade, downloader); } if (!installCanceled && toInstall.Count > 0) { installer.InstallList(toInstall, opts.Value, downloader); } e.Result = new KeyValuePair <bool, ModChanges>(!installCanceled, opts.Key); if (installCanceled) { return; } resolvedAllProvidedMods = true; } 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?")) { // 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; } } }
public void InstallAndSortByCompat_WithAnyCompat_NoCrash() { /* * // An exception would be thrown at the bottom of this. * var main = new Main(null, new GUIUser(), false); * main.Manager = _manager; * // First sort by name * main.configuration.SortByColumnIndex = 2; * // Now sort by version * main.configuration.SortByColumnIndex = 6; * main.MarkModForInstall("kOS"); * * // Make sure we have one requested change * var changeList = main.mainModList.ComputeUserChangeSet() * .Select((change) => change.Mod.ToCkanModule()).ToList(); * * // Do the install * new ModuleInstaller(_instance.KSP, main.currentUser).InstallList( * changeList, * new RelationshipResolverOptions(), * new NetAsyncModulesDownloader(main.currentUser) * ); */ // Arrange DisposableKSP instance = new DisposableKSP(); RegistryManager registryManager = RegistryManager.Instance(instance.KSP); Registry registry = Registry.Empty(); FakeConfiguration config = new FakeConfiguration(instance.KSP, instance.KSP.Name); GameInstanceManager manager = new GameInstanceManager(new NullUser(), config); // A module with a ksp_version of "any" to repro our issue CkanModule anyVersionModule = TestData.DogeCoinFlag_101_module(); ModList modList = new ModList(null); DataGridView listGui = new DataGridView(); CKAN.ModuleInstaller installer = new CKAN.ModuleInstaller(instance.KSP, manager.Cache, manager.User); NetAsyncModulesDownloader downloader = new NetAsyncModulesDownloader(manager.User, manager.Cache); // Act // Install module 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; installer.InstallList( new List <CkanModule> { anyVersionModule }, new RelationshipResolverOptions(), registryManager, ref possibleConfigOnlyDirs, downloader ); // This module is not for "any" version, // to provide another to sort against registry.AddAvailable(TestData.kOS_014_module()); // TODO: Refactor the column header code to allow mocking of the GUI without creating columns const int numCheckboxCols = 4; const int numTextCols = 10; listGui.Columns.AddRange( Enumerable.Range(1, numCheckboxCols) .Select(i => (DataGridViewColumn) new DataGridViewCheckBoxColumn()) .Concat(Enumerable.Range(1, numTextCols) .Select(i => new DataGridViewTextBoxColumn())) .ToArray()); // Assert (and Act a bit more) Assert.IsNotNull(instance.KSP); Assert.IsNotNull(manager); Assert.IsNotNull(modList); var modules = registry.available_modules .Select(mod => new GUIMod(mod.Value.Latest(), registry, instance.KSP.VersionCriteria())) .ToList(); listGui.Rows.AddRange(modList.ConstructModList(modules, null).ToArray()); // The header row adds one to the count Assert.AreEqual(modules.Count + 1, listGui.Rows.Count); // Sort by game compatibility, this is the fuse-lighting listGui.Sort(listGui.Columns[8], 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(() => { // Install the "other" module installer.InstallList( modList.ComputeUserChangeSet(null).Select(change => change.Mod).ToList(), new RelationshipResolverOptions(), registryManager, ref possibleConfigOnlyDirs, downloader ); // Now we need to sort // Make sure refreshing the GUI state does not throw a NullReferenceException listGui.Refresh(); }); instance.Dispose(); manager.Dispose(); config.Dispose(); }