private void PostInstallMods(object sender, RunWorkerCompletedEventArgs e) { okCallback = () => { ManageMods.UpdateModsList(null); okCallback = null; }; if (e.Error != null) { switch (e.Error) { case DependencyNotSatisfiedKraken exc: currentUser.RaiseMessage(Properties.Resources.MainInstallDepNotSatisfied, exc.parent, exc.module); break; case ModuleNotFoundKraken exc: currentUser.RaiseMessage(Properties.Resources.MainInstallNotFound, exc.module); break; case BadMetadataKraken exc: currentUser.RaiseMessage(Properties.Resources.MainInstallBadMetadata, exc.module, exc.Message); break; case FileExistsKraken exc: if (exc.owningModule != null) { currentUser.RaiseMessage( Properties.Resources.MainInstallFileExists, exc.filename, exc.installingModule, exc.owningModule, Meta.GetVersion() ); } else { currentUser.RaiseMessage( Properties.Resources.MainInstallUnownedFileExists, exc.installingModule, exc.filename ); } currentUser.RaiseMessage(Properties.Resources.MainInstallGameDataReverted); break; case InconsistentKraken exc: currentUser.RaiseMessage(exc.InconsistenciesPretty); break; case CancelledActionKraken exc: currentUser.RaiseMessage(exc.Message); installCanceled = true; break; case MissingCertificateKraken exc: currentUser.RaiseMessage(exc.ToString()); break; case DownloadThrottledKraken exc: string msg = exc.ToString(); currentUser.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 (exc.infoUrl != null) { Utilities.ProcessStartURL(exc.infoUrl.ToString()); } // Now pretend they clicked the menu option for the settings Enabled = false; new SettingsDialog(currentUser).ShowDialog(); Enabled = true; } break; case ModuleDownloadErrorsKraken exc: currentUser.RaiseMessage(exc.ToString()); currentUser.RaiseError(exc.ToString()); break; case DirectoryNotFoundKraken exc: currentUser.RaiseMessage("\r\n{0}", exc.Message); break; case ModuleIsDLCKraken exc: string dlcMsg = string.Format(Properties.Resources.MainInstallCantInstallDLC, exc.module.name); currentUser.RaiseMessage(dlcMsg); currentUser.RaiseError(dlcMsg); break; case TransactionalKraken exc: // Want to see the stack trace for this one currentUser.RaiseMessage(exc.ToString()); currentUser.RaiseError(exc.ToString()); break; default: currentUser.RaiseMessage(e.Error.Message); break; } FailWaitDialog( Properties.Resources.MainInstallErrorInstalling, Properties.Resources.MainInstallKnownError, Properties.Resources.MainInstallFailed, false ); } else { // The Result property throws if InstallMods threw (!!!) KeyValuePair <bool, ModChanges> result = (KeyValuePair <bool, ModChanges>)e.Result; if (!installCanceled) { // Rebuilds the list of GUIMods ManageMods.UpdateModsList(null); if (modChangedCallback != null) { foreach (var mod in result.Value) { modChangedCallback(mod.Mod, mod.ChangeType); } } Util.Invoke(this, () => Enabled = true); Util.Invoke(menuStrip1, () => menuStrip1.Enabled = true); tabController.SetTabLock(false); AddStatusMessage(Properties.Resources.MainInstallSuccess); HideWaitDialog(true); } else { // User cancelled the installation if (result.Key) { FailWaitDialog( Properties.Resources.MainInstallCancelTooLate, Properties.Resources.MainInstallCancelAfterInstall, Properties.Resources.MainInstallProcessComplete, true ); } else { FailWaitDialog( Properties.Resources.MainInstallProcessCanceled, Properties.Resources.MainInstallCanceledManually, Properties.Resources.MainInstallInstallCanceled, false ); } } } }
protected override void OnLoad(EventArgs e) { SetStartPosition(); Size = configuration.WindowSize; WindowState = configuration.IsWindowMaximised ? FormWindowState.Maximized : FormWindowState.Normal; if (!configuration.CheckForUpdatesOnLaunchNoNag && AutoUpdate.CanUpdate) { log.Debug("Asking user if they wish for auto-updates"); if (new AskUserForAutoUpdatesDialog().ShowDialog() == DialogResult.OK) { configuration.CheckForUpdatesOnLaunch = true; } configuration.CheckForUpdatesOnLaunchNoNag = true; configuration.Save(); } bool autoUpdating = false; if (configuration.CheckForUpdatesOnLaunch && AutoUpdate.CanUpdate) { try { log.Info("Making auto-update call"); AutoUpdate.Instance.FetchLatestReleaseInfo(); var latest_version = AutoUpdate.Instance.latestUpdate.Version; var current_version = new ModuleVersion(Meta.GetVersion()); if (AutoUpdate.Instance.IsFetched() && latest_version.IsGreaterThan(current_version)) { log.Debug("Found higher ckan version"); var release_notes = AutoUpdate.Instance.latestUpdate.ReleaseNotes; var dialog = new NewUpdateDialog(latest_version.ToString(), release_notes); if (dialog.ShowDialog() == DialogResult.OK) { UpdateCKAN(); autoUpdating = true; } } } catch (Exception exception) { currentUser.RaiseError(Properties.Resources.MainAutoUpdateFailed, exception.Message); log.Error("Error in auto-update", exception); } } CheckTrayState(); InitRefreshTimer(); m_UpdateRepoWorker = new BackgroundWorker { WorkerReportsProgress = false, WorkerSupportsCancellation = true }; m_UpdateRepoWorker.RunWorkerCompleted += PostUpdateRepo; m_UpdateRepoWorker.DoWork += UpdateRepo; installWorker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true }; installWorker.RunWorkerCompleted += PostInstallMods; installWorker.DoWork += InstallMods; URLHandlers.RegisterURLHandler(configuration, currentUser); CurrentInstanceUpdated(!autoUpdating); if (commandLineArgs.Length >= 2) { var identifier = commandLineArgs[1]; if (identifier.StartsWith("//")) { identifier = identifier.Substring(2); } else if (identifier.StartsWith("ckan://")) { identifier = identifier.Substring(7); } if (identifier.EndsWith("/")) { identifier = identifier.Substring(0, identifier.Length - 1); } log.Debug("Attempting to select mod from startup parameters"); ManageMods.FocusMod(identifier, true, true); ManageMods.ModGrid.Refresh(); log.Debug("Failed to select mod from startup parameters"); } var pluginsPath = Path.Combine(CurrentInstance.CkanDir(), "Plugins"); if (!Directory.Exists(pluginsPath)) { Directory.CreateDirectory(pluginsPath); } pluginController = new PluginController(pluginsPath); CurrentInstance.RebuildKSPSubDir(); log.Info("GUI started"); base.OnLoad(e); }
/// <summary> /// React to switching to a new game instance /// </summary> /// <param name="allowRepoUpdate">true if a repo update is allowed if needed (e.g. on initial load), false otherwise</param> private void CurrentInstanceUpdated(bool allowRepoUpdate) { Util.Invoke(this, () => { Text = $"CKAN {Meta.GetVersion()} - KSP {CurrentInstance.Version()} -- {CurrentInstance.GameDir().Replace('/', Path.DirectorySeparatorChar)}"; StatusInstanceLabel.Text = string.Format( Properties.Resources.StatusInstanceLabelText, CurrentInstance.Name, CurrentInstance.Version()?.ToString() ); }); configuration = GUIConfiguration.LoadOrCreateConfiguration( Path.Combine(CurrentInstance.CkanDir(), "GUIConfig.xml") ); if (CurrentInstance.CompatibleVersionsAreFromDifferentKsp) { new CompatibleKspVersionsDialog(CurrentInstance, !actuallyVisible) .ShowDialog(); } (RegistryManager.Instance(CurrentInstance).registry as Registry) ?.BuildTagIndex(ManageMods.mainModList.ModuleTags); bool repoUpdateNeeded = configuration.RefreshOnStartup || !RegistryManager.Instance(CurrentInstance).registry.HasAnyAvailable(); if (allowRepoUpdate && repoUpdateNeeded) { // Update the filters after UpdateRepo() completed. // Since this happens with a backgroundworker, Filter() is added as callback for RunWorkerCompleted. // Remove it again after it ran, else it stays there and is added again and again. void filterUpdate(object sender, RunWorkerCompletedEventArgs e) { ManageMods.Filter( (GUIModFilter)configuration.ActiveFilter, ManageMods.mainModList.ModuleTags.Tags.GetOrDefault(configuration.TagFilter), ManageMods.mainModList.ModuleLabels.LabelsFor(CurrentInstance.Name) .FirstOrDefault(l => l.Name == configuration.CustomLabelFilter) ); m_UpdateRepoWorker.RunWorkerCompleted -= filterUpdate; } m_UpdateRepoWorker.RunWorkerCompleted += filterUpdate; ManageMods.ModGrid.Rows.Clear(); UpdateRepo(); } else { ManageMods.UpdateModsList(); ManageMods.Filter( (GUIModFilter)configuration.ActiveFilter, ManageMods.mainModList.ModuleTags.Tags.GetOrDefault(configuration.TagFilter), ManageMods.mainModList.ModuleLabels.LabelsFor(CurrentInstance.Name) .FirstOrDefault(l => l.Name == configuration.CustomLabelFilter) ); } ManageMods.InstanceUpdated(CurrentInstance); }
protected override void OnLoad(EventArgs e) { if (configuration.WindowLoc.X == -1 && configuration.WindowLoc.Y == -1) { // Center on screen for first launch StartPosition = FormStartPosition.CenterScreen; } else if (Platform.IsMac) { // Make sure there's room at the top for the MacOSX menu bar Location = Util.ClampedLocationWithMargins( configuration.WindowLoc, configuration.WindowSize, new Size(0, 30), new Size(0, 0) ); } else { // Just make sure it's fully on screen Location = Util.ClampedLocation(configuration.WindowLoc, configuration.WindowSize); } Size = configuration.WindowSize; WindowState = configuration.IsWindowMaximised ? FormWindowState.Maximized : FormWindowState.Normal; #if (!ONI) if (!configuration.CheckForUpdatesOnLaunchNoNag && AutoUpdate.CanUpdate) { log.Debug("Asking user if they wish for auto-updates"); if (new AskUserForAutoUpdatesDialog().ShowDialog() == DialogResult.OK) { configuration.CheckForUpdatesOnLaunch = true; } configuration.CheckForUpdatesOnLaunchNoNag = true; configuration.Save(); } #else configuration.CheckForUpdatesOnLaunch = false; configuration.CheckForUpdatesOnLaunchNoNag = false; configuration.Save(); #endif bool autoUpdating = false; if (configuration.CheckForUpdatesOnLaunch && AutoUpdate.CanUpdate) { try { log.Info("Making auto-update call"); AutoUpdate.Instance.FetchLatestReleaseInfo(); var latest_version = AutoUpdate.Instance.latestUpdate.Version; var current_version = new ModuleVersion(Meta.GetVersion()); if (AutoUpdate.Instance.IsFetched() && latest_version.IsGreaterThan(current_version)) { log.Debug("Found higher ckan version"); var release_notes = AutoUpdate.Instance.latestUpdate.ReleaseNotes; var dialog = new NewUpdateDialog(latest_version.ToString(), release_notes); if (dialog.ShowDialog() == DialogResult.OK) { UpdateCKAN(); autoUpdating = true; } } } catch (Exception exception) { currentUser.RaiseError($"Error in auto-update:\n\t{exception.Message}"); log.Error("Error in auto-update", exception); } } CheckTrayState(); InitRefreshTimer(); m_UpdateRepoWorker = new BackgroundWorker { WorkerReportsProgress = false, WorkerSupportsCancellation = true }; m_UpdateRepoWorker.RunWorkerCompleted += PostUpdateRepo; m_UpdateRepoWorker.DoWork += UpdateRepo; installWorker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true }; installWorker.RunWorkerCompleted += PostInstallMods; installWorker.DoWork += InstallMods; #if (!ONI) URLHandlers.RegisterURLHandler(configuration, currentUser); #endif ApplyToolButton.Enabled = false; CurrentInstanceUpdated(); // We would like to refresh if we're configured to refresh on startup, // or if we have no currently available modules. bool repoUpdateNeeded = configuration.RefreshOnStartup || !RegistryManager.Instance(CurrentInstance).registry.HasAnyAvailable(); // If we're auto-updating the client then we shouldn't interfere with the progress tab if (!autoUpdating && repoUpdateNeeded) { UpdateRepo(); } Text = $"CKAN {Meta.GetVersion()} - {GameConfig.Constants.GameNameShort} {CurrentInstance.Version()} -- {CurrentInstance.GameDir()}"; if (commandLineArgs.Length >= 2) { var identifier = commandLineArgs[1]; if (identifier.StartsWith("//")) { identifier = identifier.Substring(2); } else if (identifier.StartsWith("ckan://")) { identifier = identifier.Substring(7); } if (identifier.EndsWith("/")) { identifier = identifier.Substring(0, identifier.Length - 1); } log.Debug("Attempting to select mod from startup parameters"); FocusMod(identifier, true, true); ModList.Refresh(); log.Debug("Failed to select mod from startup parameters"); } var pluginsPath = Path.Combine(CurrentInstance.CkanDir(), "Plugins"); if (!Directory.Exists(pluginsPath)) { Directory.CreateDirectory(pluginsPath); } pluginController = new PluginController(pluginsPath); CurrentInstance.RebuildKSPSubDir(); // Initialize navigation. This should be called as late as // possible, once the UI is "settled" from its initial load. NavInit(); log.Info("GUI started"); base.OnLoad(e); }
protected override void OnLoad(EventArgs e) { Location = configuration.WindowLoc; Size = configuration.WindowSize; WindowState = configuration.IsWindowMaximised ? FormWindowState.Maximized : FormWindowState.Normal; try { splitContainer1.SplitterDistance = configuration.PanelPosition; } catch { // SplitContainer is mis-designed to throw exceptions // if the min/max limits are exceeded rather than simply obeying them. } ModInfoTabControl.ModMetaSplitPosition = configuration.ModInfoPosition; if (!configuration.CheckForUpdatesOnLaunchNoNag && AutoUpdate.CanUpdate) { log.Debug("Asking user if they wish for auto-updates"); if (new AskUserForAutoUpdatesDialog().ShowDialog() == DialogResult.OK) { configuration.CheckForUpdatesOnLaunch = true; } configuration.CheckForUpdatesOnLaunchNoNag = true; configuration.Save(); } bool autoUpdating = false; if (configuration.CheckForUpdatesOnLaunch && AutoUpdate.CanUpdate) { try { log.Info("Making auto-update call"); AutoUpdate.Instance.FetchLatestReleaseInfo(); var latest_version = AutoUpdate.Instance.latestUpdate.Version; var current_version = new ModuleVersion(Meta.GetVersion()); if (AutoUpdate.Instance.IsFetched() && latest_version.IsGreaterThan(current_version)) { log.Debug("Found higher ckan version"); var release_notes = AutoUpdate.Instance.latestUpdate.ReleaseNotes; var dialog = new NewUpdateDialog(latest_version.ToString(), release_notes); if (dialog.ShowDialog() == DialogResult.OK) { UpdateCKAN(); autoUpdating = true; } } } catch (Exception exception) { currentUser.RaiseError($"Error in auto-update:\n\t{exception.Message}"); log.Error("Error in auto-update", exception); } } CheckTrayState(); InitRefreshTimer(); m_UpdateRepoWorker = new BackgroundWorker { WorkerReportsProgress = false, WorkerSupportsCancellation = true }; m_UpdateRepoWorker.RunWorkerCompleted += PostUpdateRepo; m_UpdateRepoWorker.DoWork += UpdateRepo; installWorker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true }; installWorker.RunWorkerCompleted += PostInstallMods; installWorker.DoWork += InstallMods; var old_YesNoDialog = currentUser.displayYesNo; currentUser.displayYesNo = YesNoDialog; URLHandlers.RegisterURLHandler(configuration, currentUser); currentUser.displayYesNo = old_YesNoDialog; ApplyToolButton.Enabled = false; CurrentInstanceUpdated(); // We would like to refresh if we're configured to refresh on startup, // or if we have no currently available modules. bool repoUpdateNeeded = configuration.RefreshOnStartup || !RegistryManager.Instance(CurrentInstance).registry.HasAnyAvailable(); // If we're auto-updating the client then we shouldn't interfere with the progress tab if (!autoUpdating && repoUpdateNeeded) { UpdateRepo(); } Text = $"CKAN {Meta.GetVersion()} - KSP {CurrentInstance.Version()} -- {CurrentInstance.GameDir()}"; if (commandLineArgs.Length >= 2) { var identifier = commandLineArgs[1]; if (identifier.StartsWith("//")) { identifier = identifier.Substring(2); } else if (identifier.StartsWith("ckan://")) { identifier = identifier.Substring(7); } if (identifier.EndsWith("/")) { identifier = identifier.Substring(0, identifier.Length - 1); } log.Debug("Attempting to select mod from startup parameters"); FocusMod(identifier, true, true); ModList.Refresh(); log.Debug("Failed to select mod from startup parameters"); } var pluginsPath = Path.Combine(CurrentInstance.CkanDir(), "Plugins"); if (!Directory.Exists(pluginsPath)) { Directory.CreateDirectory(pluginsPath); } pluginController = new PluginController(pluginsPath); CurrentInstance.RebuildKSPSubDir(); // Initialize navigation. This should be called as late as // possible, once the UI is "settled" from its initial load. NavInit(); log.Info("GUI started"); base.OnLoad(e); }
protected override void OnLoad(EventArgs e) { Location = m_Configuration.WindowLoc; Size = m_Configuration.WindowSize; if (!m_Configuration.CheckForUpdatesOnLaunchNoNag) { log.Debug("Asking user if they wish for autoupdates"); if (new AskUserForAutoUpdatesDialog().ShowDialog() == DialogResult.OK) { m_Configuration.CheckForUpdatesOnLaunch = true; } m_Configuration.CheckForUpdatesOnLaunchNoNag = true; m_Configuration.Save(); } if (m_Configuration.CheckForUpdatesOnLaunch) { try { log.Info("Making autoupdate call"); var latest_version = AutoUpdate.FetchLatestCkanVersion(); var current_version = new Version(Meta.Version()); if (latest_version.IsGreaterThan(current_version)) { log.Debug("Found higher ckan version"); var release_notes = AutoUpdate.FetchLatestCkanVersionReleaseNotes(); var dialog = new NewUpdateDialog(latest_version.ToString(), release_notes); if (dialog.ShowDialog() == DialogResult.OK) { log.Info("Start ckan update"); AutoUpdate.StartUpdateProcess(true); } } } catch (Exception exception) { m_User.RaiseError("Error in autoupdate: \n\t" + exception.Message + ""); log.Error("Error in autoupdate", exception); } } m_UpdateRepoWorker = new BackgroundWorker { WorkerReportsProgress = false, WorkerSupportsCancellation = true }; m_UpdateRepoWorker.RunWorkerCompleted += PostUpdateRepo; m_UpdateRepoWorker.DoWork += UpdateRepo; m_InstallWorker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true }; m_InstallWorker.RunWorkerCompleted += PostInstallMods; m_InstallWorker.DoWork += InstallMods; UpdateModsList(); m_User.displayYesNo = YesNoDialog; URLHandlers.RegisterURLHandler(m_Configuration, m_User); m_User.displayYesNo = null; ApplyToolButton.Enabled = false; CurrentInstanceUpdated(); ModList.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells); if (m_CommandLineArgs.Length >= 2) { var identifier = m_CommandLineArgs[1]; if (identifier.StartsWith("//")) { identifier = identifier.Substring(2); } else if (identifier.StartsWith("ckan://")) { identifier = identifier.Substring(7); } if (identifier.EndsWith("/")) { identifier = identifier.Substring(0, identifier.Length - 1); } int i = 0; log.Debug("Attempting to select mod from startup parameters"); foreach (DataGridViewRow row in ModList.Rows) { var module = ((GUIMod)row.Tag).ToCkanModule(); if (identifier == module.identifier) { ModList.FirstDisplayedScrollingRowIndex = i; row.Selected = true; break; } i++; } log.Debug("Failed to select mod from startup parameters"); } var pluginsPath = Path.Combine(CurrentInstance.CkanDir(), "Plugins"); if (!Directory.Exists(pluginsPath)) { Directory.CreateDirectory(pluginsPath); } m_PluginController = new PluginController(pluginsPath, true); log.Info("GUI started"); base.OnLoad(e); }
/// <summary> /// Helper function to wrap around calls to ModuleInstaller. /// Handles some of the possible krakens and displays user friendly messages for them. /// </summary> private static bool WasSuccessful(Action action) { try { action(); } 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(false); } catch (BadMetadataKraken ex) { GUI.user.RaiseMessage("Bad metadata detected for module {0}: {1}", ex.module, ex.Message); return(false); } 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.Version() ); } 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(false); } catch (InconsistentKraken ex) { // The prettiest Kraken formats itself for us. GUI.user.RaiseMessage(ex.InconsistenciesPretty); return(false); } catch (CancelledActionKraken) { return(false); } catch (MissingCertificateKraken kraken) { // Another very pretty kraken. GUI.user.RaiseMessage(kraken.ToString()); return(false); } catch (DownloadErrorsKraken) { // User notified in InstallList return(false); } catch (DirectoryNotFoundKraken kraken) { GUI.user.RaiseMessage("\r\n{0}", kraken.Message); return(false); } return(true); }
private void InstallMods(object sender, DoWorkEventArgs e) // this probably needs to be refactored { 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 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.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; }; 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; } 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; } } }
protected override void OnLoad(EventArgs e) { Location = m_Configuration.WindowLoc; Size = m_Configuration.WindowSize; if (!m_Configuration.CheckForUpdatesOnLaunchNoNag) { log.Debug("Asking user if they wish for autoupdates"); if (new AskUserForAutoUpdatesDialog().ShowDialog() == DialogResult.OK) { m_Configuration.CheckForUpdatesOnLaunch = true; } m_Configuration.CheckForUpdatesOnLaunchNoNag = true; m_Configuration.Save(); } if (m_Configuration.CheckForUpdatesOnLaunch) { try { log.Info("Making autoupdate call"); AutoUpdate.Instance.FetchLatestReleaseInfo(); var latest_version = AutoUpdate.Instance.LatestVersion; var current_version = new Version(Meta.Version()); if (AutoUpdate.Instance.IsFetched() && latest_version.IsGreaterThan(current_version)) { log.Debug("Found higher ckan version"); var release_notes = AutoUpdate.Instance.ReleaseNotes; var dialog = new NewUpdateDialog(latest_version.ToString(), release_notes); if (dialog.ShowDialog() == DialogResult.OK) { log.Info("Start ckan update"); AutoUpdate.Instance.StartUpdateProcess(true); } } } catch (Exception exception) { m_User.RaiseError("Error in autoupdate: \n\t" + exception.Message + ""); log.Error("Error in autoupdate", exception); } } m_UpdateRepoWorker = new BackgroundWorker { WorkerReportsProgress = false, WorkerSupportsCancellation = true }; m_UpdateRepoWorker.RunWorkerCompleted += PostUpdateRepo; m_UpdateRepoWorker.DoWork += UpdateRepo; m_InstallWorker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true }; m_InstallWorker.RunWorkerCompleted += PostInstallMods; m_InstallWorker.DoWork += InstallMods; m_CacheWorker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true }; m_CacheWorker.RunWorkerCompleted += PostModCaching; m_CacheWorker.DoWork += CacheMod; m_User.displayYesNo = YesNoDialog; URLHandlers.RegisterURLHandler(m_Configuration, m_User); m_User.displayYesNo = null; ApplyToolButton.Enabled = false; CurrentInstanceUpdated(); if (m_Configuration.RefreshOnStartup) { UpdateRepo(); } Text = String.Format("CKAN {0} - KSP {1} -- {2}", Meta.Version(), CurrentInstance.Version(), CurrentInstance.GameDir()); KSPVersionLabel.Text = String.Format("Kerbal Space Program {0}", CurrentInstance.Version()); if (m_CommandLineArgs.Length >= 2) { var identifier = m_CommandLineArgs[1]; if (identifier.StartsWith("//")) { identifier = identifier.Substring(2); } else if (identifier.StartsWith("ckan://")) { identifier = identifier.Substring(7); } if (identifier.EndsWith("/")) { identifier = identifier.Substring(0, identifier.Length - 1); } int i = 0; log.Debug("Attempting to select mod from startup parameters"); FocusMod(identifier, true, true); ModList.Refresh(); log.Debug("Failed to select mod from startup parameters"); } var pluginsPath = Path.Combine(CurrentInstance.CkanDir(), "Plugins"); if (!Directory.Exists(pluginsPath)) { Directory.CreateDirectory(pluginsPath); } m_PluginController = new PluginController(pluginsPath, true); CurrentInstance.RebuildKSPSubDir(); log.Info("GUI started"); ModList.Select(); base.OnLoad(e); }
// 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); 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 var recRows = getRecSugRows( opts.Key.Where(ch => ch.ChangeType == GUIModChangeType.Install) .Select(ch => ch.Mod), 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 bool InstallList(HashSet <string> toInstall, RelationshipResolverOptions options, NetAsyncDownloader downloader) { if (toInstall.Any()) { // actual magic happens here, we run the installer with our mod list ModuleInstaller.GetInstance(manager.CurrentInstance, GUI.user).onReportModInstalled = OnModInstalled; cancelCallback = downloader.CancelDownload; try { ModuleInstaller.GetInstance(manager.CurrentInstance, GUI.user) .InstallList(toInstall.ToList(), options, downloader); } catch (ModuleNotFoundKraken ex) { GUI.user.RaiseMessage("Module {0} required, but not listed in index, or not available for your version of KSP", ex.module); return(false); } catch (BadMetadataKraken ex) { GUI.user.RaiseMessage("Bad metadata detected for module {0}: {1}", ex.module, ex.Message); return(false); } catch (FileExistsKraken ex) { if (ex.owning_module != null) { GUI.user.RaiseMessage( "\nOh no! We tried to overwrite a file owned by another mod!\n" + "Please try a `ckan update` and try again.\n\n" + "If this problem re-occurs, then it maybe a packaging bug.\n" + "Please report it at:\n\n" + "https://github.com/KSP-CKAN/CKAN-meta/issues/new\n\n" + "Please including the following information in your report:\n\n" + "File : {0}\n" + "Installing Mod : {1}\n" + "Owning Mod : {2}\n" + "CKAN Version : {3}\n", ex.filename, ex.installing_module, ex.owning_module, Meta.Version() ); } else { GUI.user.RaiseMessage( "\n\nOh no!\n\n" + "It looks like you're trying to install a mod which is already installed,\n" + "or which conflicts with another mod which is already installed.\n\n" + "As a safety feature, the CKAN will *never* overwrite or alter a file\n" + "that it did not install itself.\n\n" + "If you wish to install {0} via the CKAN,\n" + "then please manually uninstall the mod which owns:\n\n" + "{1}\n\n" + "and try again.\n", ex.installing_module, ex.filename ); } GUI.user.RaiseMessage("Your GameData has been returned to its original state.\n"); return(false); } catch (InconsistentKraken ex) { // The prettiest Kraken formats itself for us. GUI.user.RaiseMessage(ex.InconsistenciesPretty); return(false); } catch (CancelledActionKraken) { return(false); } catch (MissingCertificateKraken kraken) { // Another very pretty kraken. GUI.user.RaiseMessage(kraken.ToString()); return(false); } catch (DownloadErrorsKraken) { // User notified in InstallList return(false); } } return(true); }
protected override void OnLoad(EventArgs e) { Location = configuration.WindowLoc; Size = configuration.WindowSize; if (!configuration.CheckForUpdatesOnLaunchNoNag) { log.Debug("Asking user if they wish for autoupdates"); if (new AskUserForAutoUpdatesDialog().ShowDialog() == DialogResult.OK) { configuration.CheckForUpdatesOnLaunch = true; } configuration.CheckForUpdatesOnLaunchNoNag = true; configuration.Save(); } bool autoUpdating = false; if (configuration.CheckForUpdatesOnLaunch) { try { log.Info("Making autoupdate call"); AutoUpdate.Instance.FetchLatestReleaseInfo(); var latest_version = AutoUpdate.Instance.LatestVersion; var current_version = new Version(Meta.Version()); if (AutoUpdate.Instance.IsFetched() && latest_version.IsGreaterThan(current_version)) { log.Debug("Found higher ckan version"); var release_notes = AutoUpdate.Instance.ReleaseNotes; var dialog = new NewUpdateDialog(latest_version.ToString(), release_notes); if (dialog.ShowDialog() == DialogResult.OK) { UpdateCKAN(); autoUpdating = true; } } } catch (Exception exception) { currentUser.RaiseError("Error in autoupdate: \n\t" + exception.Message + ""); log.Error("Error in autoupdate", exception); } } m_UpdateRepoWorker = new BackgroundWorker { WorkerReportsProgress = false, WorkerSupportsCancellation = true }; m_UpdateRepoWorker.RunWorkerCompleted += PostUpdateRepo; m_UpdateRepoWorker.DoWork += UpdateRepo; installWorker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true }; installWorker.RunWorkerCompleted += PostInstallMods; installWorker.DoWork += InstallMods; m_CacheWorker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true }; m_CacheWorker.RunWorkerCompleted += PostModCaching; m_CacheWorker.DoWork += CacheMod; var old_YesNoDialog = currentUser.displayYesNo; currentUser.displayYesNo = YesNoDialog; URLHandlers.RegisterURLHandler(configuration, currentUser); currentUser.displayYesNo = old_YesNoDialog; ApplyToolButton.Enabled = false; CurrentInstanceUpdated(); // if we're autoUpdating then we shouldn't interfere progress tab if (configuration.RefreshOnStartup && !autoUpdating) { UpdateRepo(); } Text = String.Format("CKAN {0} - KSP {1} -- {2}", Meta.Version(), CurrentInstance.Version(), CurrentInstance.GameDir()); if (commandLineArgs.Length >= 2) { var identifier = commandLineArgs[1]; if (identifier.StartsWith("//")) { identifier = identifier.Substring(2); } else if (identifier.StartsWith("ckan://")) { identifier = identifier.Substring(7); } if (identifier.EndsWith("/")) { identifier = identifier.Substring(0, identifier.Length - 1); } log.Debug("Attempting to select mod from startup parameters"); FocusMod(identifier, true, true); ModList.Refresh(); log.Debug("Failed to select mod from startup parameters"); } var pluginsPath = Path.Combine(CurrentInstance.CkanDir(), "Plugins"); if (!Directory.Exists(pluginsPath)) { Directory.CreateDirectory(pluginsPath); } pluginController = new PluginController(pluginsPath, true); CurrentInstance.RebuildKSPSubDir(); NavInit(); // initialize navigation. this should be called as late // as possible, once the UI is "settled" from its initial // load. log.Info("GUI started"); base.OnLoad(e); }