private int MarkAuto(MarkAutoOptions opts, bool value, string verb, string descrip) { if (opts.modules.Count < 1) { user.RaiseMessage("Usage: ckan mark {0} Mod [Mod2 ...]", verb); return(Exit.BADOPT); } int exitCode = opts.Handle(manager, user); if (exitCode != Exit.OK) { return(exitCode); } var ksp = MainClass.GetGameInstance(manager); var regMgr = RegistryManager.Instance(ksp); bool needSave = false; Search.AdjustModulesCase(ksp, opts.modules); foreach (string id in opts.modules) { InstalledModule im = regMgr.registry.InstalledModule(id); if (im == null) { user.RaiseError("{0} is not installed.", id); } else if (im.AutoInstalled == value) { user.RaiseError("{0} is already marked as {1}.", id, descrip); } else { user.RaiseMessage("Marking {0} as {1}...", id, descrip); try { im.AutoInstalled = value; needSave = true; } catch (ModuleIsDLCKraken kraken) { user.RaiseMessage($"Can't mark expansion '{kraken.module.name}' as auto-installed."); return(Exit.BADOPT); } } } if (needSave) { regMgr.Save(false); user.RaiseMessage("Changes made!"); } return(Exit.OK); }
/// <summary> /// Uninstalls a module, if it exists. /// </summary> /// <param name="ksp">Game instance from which to remove</param> /// <param name="raw_options">Command line options object</param> /// <returns> /// Exit code for shell environment /// </returns> public int RunCommand(CKAN.GameInstance ksp, object raw_options) { RemoveOptions options = (RemoveOptions)raw_options; RegistryManager regMgr = RegistryManager.Instance(ksp); // Use one (or more!) regex to select the modules to remove if (options.regex) { log.Debug("Attempting Regex"); // Parse every "module" as a grumpy regex var justins = options.modules.Select(s => new Regex(s)); // Modules that have been selected by one regex List <string> selectedModules = new List <string>(); // Get the list of installed modules // Try every regex on every installed module: // if it matches, select for removal foreach (string mod in regMgr.registry.InstalledModules.Select(mod => mod.identifier)) { if (justins.Any(re => re.IsMatch(mod))) { selectedModules.Add(mod); } } // Replace the regular expressions with the selected modules // and continue removal as usual options.modules = selectedModules; } if (options.rmall) { log.Debug("Removing all mods"); // Add the list of installed modules to the list that should be uninstalled options.modules.AddRange( regMgr.registry.InstalledModules .Where(mod => !mod.Module.IsDLC) .Select(mod => mod.identifier) ); } if (options.modules != null && options.modules.Count > 0) { try { HashSet <string> possibleConfigOnlyDirs = null; var installer = ModuleInstaller.GetInstance(ksp, manager.Cache, user); Search.AdjustModulesCase(ksp, options.modules); installer.UninstallList(options.modules, ref possibleConfigOnlyDirs, regMgr); user.RaiseMessage(""); } catch (ModNotInstalledKraken kraken) { user.RaiseMessage("I can't do that, {0} isn't installed.", kraken.mod); user.RaiseMessage("Try `ckan list` for a list of installed mods."); return(Exit.BADOPT); } catch (ModuleIsDLCKraken kraken) { user.RaiseMessage($"CKAN can't remove expansion '{kraken.module.name}' for you."); var res = kraken?.module?.resources; var storePagesMsg = new Uri[] { res?.store, res?.steamstore } .Where(u => u != null) .Aggregate("", (a, b) => $"{a}\r\n- {b}"); if (!string.IsNullOrEmpty(storePagesMsg)) { user.RaiseMessage($"To remove this expansion, follow the instructions for the store page from which you purchased it:\r\n{storePagesMsg}"); } return(Exit.BADOPT); } catch (CancelledActionKraken k) { user.RaiseMessage("Remove aborted: {0}", k.Message); return(Exit.ERROR); } } else { user.RaiseMessage("No mod selected, nothing to do"); return(Exit.BADOPT); } return(Exit.OK); }
/// <summary> /// Uninstalls a module, if it exists. /// </summary> /// <param name="ksp">Game instance from which to remove</param> /// <param name="raw_options">Command line options object</param> /// <returns> /// Exit code for shell environment /// </returns> public int RunCommand(CKAN.KSP ksp, object raw_options) { RemoveOptions options = (RemoveOptions)raw_options; // Use one (or more!) regex to select the modules to remove if (options.regex) { log.Debug("Attempting Regex"); // Parse every "module" as a grumpy regex var justins = options.modules.Select(s => new Regex(s)); // Modules that have been selected by one regex List <string> selectedModules = new List <string>(); // Get the list of installed modules IRegistryQuerier registry = RegistryManager.Instance(ksp).registry; // Try every regex on every installed module: // if it matches, select for removal foreach (string mod in registry.InstalledModules.Select(mod => mod.identifier)) { if (justins.Any(re => re.IsMatch(mod))) { selectedModules.Add(mod); } } // Replace the regular expressions with the selected modules // and continue removal as usual options.modules = selectedModules; } if (options.rmall) { log.Debug("Removing all mods"); // Add the list of installed modules to the list that should be uninstalled IRegistryQuerier registry = RegistryManager.Instance(ksp).registry; options.modules.AddRange( registry.InstalledModules.Select(mod => mod.identifier) ); } if (options.modules != null && options.modules.Count > 0) { try { var installer = ModuleInstaller.GetInstance(ksp, manager.Cache, user); Search.AdjustModulesCase(ksp, options.modules); installer.UninstallList(options.modules); } catch (ModNotInstalledKraken kraken) { user.RaiseMessage("I can't do that, {0} isn't installed.", kraken.mod); user.RaiseMessage("Try `ckan list` for a list of installed mods."); return(Exit.BADOPT); } } else { user.RaiseMessage("No mod selected, nothing to do"); return(Exit.BADOPT); } return(Exit.OK); }
public int RunCommand(CKAN.KSP ksp, object raw_options) { InstallOptions options = (InstallOptions)raw_options; if (options.ckan_files != null) { // Oooh! We're installing from a CKAN file. foreach (string ckan_file in options.ckan_files) { Uri ckan_uri; // Check if the argument if a wellformatted Uri. if (!Uri.IsWellFormedUriString(ckan_file, UriKind.Absolute)) { // Assume it is a local file, check if the file exists. if (File.Exists(ckan_file)) { // Get the full path of the file. ckan_uri = new Uri(Path.GetFullPath(ckan_file)); } else { // We have no further ideas as what we can do with this Uri, tell the user. user.RaiseError("Can not find file \"{0}\".", ckan_file); user.RaiseError("Exiting."); return(Exit.ERROR); } } else { ckan_uri = new Uri(ckan_file); } string filename = String.Empty; // If it is a local file, we already know the filename. If it is remote, create a temporary file and download the remote resource. if (ckan_uri.IsFile) { filename = ckan_uri.LocalPath; log.InfoFormat("Installing from local CKAN file \"{0}\"", filename); } else { log.InfoFormat("Installing from remote CKAN file \"{0}\"", ckan_uri); filename = Net.Download(ckan_uri, null, user); log.DebugFormat("Temporary file for \"{0}\" is at \"{1}\".", ckan_uri, filename); } // Parse the JSON file. try { CkanModule m = LoadCkanFromFile(ksp, filename); options.modules.Add($"{m.identifier}={m.version}"); } catch (Kraken kraken) { user.RaiseError(kraken.InnerException == null ? kraken.Message : $"{kraken.Message}: {kraken.InnerException.Message}"); } } // At times RunCommand() calls itself recursively - in this case we do // not want to be doing this again, so "consume" the option options.ckan_files = null; } else { Search.AdjustModulesCase(ksp, options.modules); } if (options.modules.Count == 0) { // What? No files specified? user.RaiseMessage( "Usage: ckan install [--with-suggests] [--with-all-suggests] [--no-recommends] [--headless] Mod [Mod2, ...]"); return(Exit.BADOPT); } // Prepare options. Can these all be done in the new() somehow? var install_ops = new RelationshipResolverOptions { with_all_suggests = options.with_all_suggests, with_suggests = options.with_suggests, with_recommends = !options.no_recommends, allow_incompatible = options.allow_incompatible }; if (user.Headless) { install_ops.without_toomanyprovides_kraken = true; install_ops.without_enforce_consistency = true; } // Install everything requested. :) try { var installer = ModuleInstaller.GetInstance(ksp, user); installer.InstallList(options.modules, install_ops); } catch (DependencyNotSatisfiedKraken ex) { if (ex.version == null) { 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); } else { user.RaiseMessage("{0} requires {1} {2} but it is not listed in the index, or not available for your version of KSP.", ex.parent, ex.module, ex.version); } user.RaiseMessage("If you're lucky, you can do a `ckan update` and try again."); user.RaiseMessage("Try `ckan install --no-recommends` to skip installation of recommended modules."); user.RaiseMessage("Or `ckan install --allow-incompatible` to ignore module compatibility."); return(Exit.ERROR); } catch (ModuleNotFoundKraken ex) { if (ex.version == null) { user.RaiseMessage("Module {0} required but it is not listed in the index, or not available for your version of KSP.", ex.module); } else { user.RaiseMessage("Module {0} {1} required but it is not listed in the index, or not available for your version of KSP.", ex.module, ex.version); } user.RaiseMessage("If you're lucky, you can do a `ckan update` and try again."); user.RaiseMessage("Try `ckan install --no-recommends` to skip installation of recommended modules."); user.RaiseMessage("Or `ckan install --allow-incompatible` to ignore module compatibility."); return(Exit.ERROR); } catch (BadMetadataKraken ex) { user.RaiseMessage("Bad metadata detected for module {0}.", ex.module); user.RaiseMessage(ex.Message); return(Exit.ERROR); } catch (TooManyModsProvideKraken ex) { // Request the user selects one of the mods. string[] mods = new string[ex.modules.Count]; for (int i = 0; i < ex.modules.Count; i++) { mods[i] = String.Format("{0} ({1})", ex.modules[i].identifier, ex.modules[i].name); } string message = String.Format("Too many mods provide {0}. Please pick from the following:\r\n", ex.requested); int result; try { result = user.RaiseSelectionDialog(message, mods); } catch (Kraken e) { user.RaiseMessage(e.Message); return(Exit.ERROR); } if (result < 0) { user.RaiseMessage(String.Empty); // Looks tidier. return(Exit.ERROR); } // Add the module to the list. options.modules.Add(ex.modules[result].identifier); return(new Install(user).RunCommand(ksp, options)); } catch (FileExistsKraken ex) { if (ex.owningModule != null) { 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(VersionFormat.Full) ); } else { 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 ); } user.RaiseMessage("Your GameData has been returned to its original state.\r\n"); return(Exit.ERROR); } catch (InconsistentKraken ex) { // The prettiest Kraken formats itself for us. user.RaiseMessage(ex.InconsistenciesPretty); user.RaiseMessage("Install canceled. Your files have been returned to their initial state."); return(Exit.ERROR); } catch (CancelledActionKraken) { user.RaiseMessage("Installation canceled at user request."); return(Exit.ERROR); } catch (MissingCertificateKraken kraken) { // Another very pretty kraken. user.RaiseMessage(kraken.ToString()); return(Exit.ERROR); } catch (DownloadThrottledKraken kraken) { user.RaiseMessage(kraken.ToString()); user.RaiseMessage($"Try the authtoken command. See {kraken.infoUrl} for details."); return(Exit.ERROR); } catch (DownloadErrorsKraken) { user.RaiseMessage("One or more files failed to download, stopped."); return(Exit.ERROR); } catch (ModuleDownloadErrorsKraken kraken) { user.RaiseMessage(kraken.ToString()); return(Exit.ERROR); } catch (DirectoryNotFoundKraken kraken) { user.RaiseMessage("\r\n{0}", kraken.Message); return(Exit.ERROR); } return(Exit.OK); }
public int RunCommand(CKAN.KSP ksp, object raw_options) { UpgradeOptions options = (UpgradeOptions)raw_options; if (options.ckan_file != null) { options.modules.Add(LoadCkanFromFile(ksp, options.ckan_file).identifier); } if (options.modules.Count == 0 && !options.upgrade_all) { // What? No files specified? User.RaiseMessage("Usage: ckan upgrade Mod [Mod2, ...]"); User.RaiseMessage(" or ckan upgrade --all"); if (AutoUpdate.CanUpdate) { User.RaiseMessage(" or ckan upgrade ckan"); } return(Exit.BADOPT); } if (!options.upgrade_all && options.modules[0] == "ckan" && AutoUpdate.CanUpdate) { User.RaiseMessage("Querying the latest CKAN version"); AutoUpdate.Instance.FetchLatestReleaseInfo(); var latestVersion = AutoUpdate.Instance.LatestVersion; var currentVersion = new ModuleVersion(Meta.GetVersion(VersionFormat.Short)); if (latestVersion.IsGreaterThan(currentVersion)) { User.RaiseMessage("New CKAN version available - " + latestVersion); var releaseNotes = AutoUpdate.Instance.ReleaseNotes; User.RaiseMessage(releaseNotes); User.RaiseMessage("\r\n"); if (User.RaiseYesNoDialog("Proceed with install?")) { User.RaiseMessage("Upgrading CKAN, please wait.."); AutoUpdate.Instance.StartUpdateProcess(false); } } else { User.RaiseMessage("You already have the latest version."); } return(Exit.OK); } User.RaiseMessage("\r\nUpgrading modules...\r\n"); try { if (options.upgrade_all) { var registry = RegistryManager.Instance(ksp).registry; var installed = new Dictionary <string, ModuleVersion>(registry.Installed()); var to_upgrade = new List <CkanModule>(); foreach (KeyValuePair <string, ModuleVersion> mod in installed) { ModuleVersion current_version = mod.Value; if ((current_version is ProvidesModuleVersion) || (current_version is UnmanagedModuleVersion)) { continue; } else { try { // Check if upgrades are available var latest = registry.LatestAvailable(mod.Key, ksp.VersionCriteria()); // This may be an unindexed mod. If so, // skip rather than crash. See KSP-CKAN/CKAN#841. if (latest == null) { continue; } if (latest.version.IsGreaterThan(mod.Value)) { // Upgradable log.InfoFormat("New version {0} found for {1}", latest.version, latest.identifier); to_upgrade.Add(latest); } } catch (ModuleNotFoundKraken) { log.InfoFormat("{0} is installed, but no longer in the registry", mod.Key); } } } ModuleInstaller.GetInstance(ksp, User).Upgrade(to_upgrade, new NetAsyncModulesDownloader(User)); } else { // TODO: These instances all need to go. Search.AdjustModulesCase(ksp, options.modules); ModuleInstaller.GetInstance(ksp, User).Upgrade(options.modules, new NetAsyncModulesDownloader(User)); } } catch (ModuleNotFoundKraken kraken) { User.RaiseMessage("Module {0} not found", kraken.module); return(Exit.ERROR); } catch (InconsistentKraken kraken) { User.RaiseMessage(kraken.ToString()); return(Exit.ERROR); } User.RaiseMessage("\r\nDone!\r\n"); return(Exit.OK); }
/// <summary> /// Upgrade an installed module /// </summary> /// <param name="ksp">Game instance from which to remove</param> /// <param name="raw_options">Command line options object</param> /// <returns> /// Exit code for shell environment /// </returns> public int RunCommand(CKAN.GameInstance ksp, object raw_options) { UpgradeOptions options = (UpgradeOptions)raw_options; if (options.ckan_file != null) { options.modules.Add(MainClass.LoadCkanFromFile(ksp, options.ckan_file).identifier); } if (options.modules.Count == 0 && !options.upgrade_all) { // What? No files specified? User.RaiseMessage("Usage: ckan upgrade Mod [Mod2, ...]"); User.RaiseMessage(" or ckan upgrade --all"); if (AutoUpdate.CanUpdate) { User.RaiseMessage(" or ckan upgrade ckan"); } return(Exit.BADOPT); } if (!options.upgrade_all && options.modules[0] == "ckan" && AutoUpdate.CanUpdate) { User.RaiseMessage("Querying the latest CKAN version"); AutoUpdate.Instance.FetchLatestReleaseInfo(); var latestVersion = AutoUpdate.Instance.latestUpdate.Version; var currentVersion = new ModuleVersion(Meta.GetVersion(VersionFormat.Short)); if (latestVersion.IsGreaterThan(currentVersion)) { User.RaiseMessage("New CKAN version available - " + latestVersion); var releaseNotes = AutoUpdate.Instance.latestUpdate.ReleaseNotes; User.RaiseMessage(releaseNotes); User.RaiseMessage("\r\n"); if (User.RaiseYesNoDialog("Proceed with install?")) { User.RaiseMessage("Upgrading CKAN, please wait.."); AutoUpdate.Instance.StartUpdateProcess(false); } } else { User.RaiseMessage("You already have the latest version."); } return(Exit.OK); } try { var regMgr = RegistryManager.Instance(ksp); var registry = regMgr.registry; if (options.upgrade_all) { var to_upgrade = new List <CkanModule>(); foreach (KeyValuePair <string, ModuleVersion> mod in registry.Installed(false)) { try { // Check if upgrades are available var latest = registry.LatestAvailable(mod.Key, ksp.VersionCriteria()); // This may be an unindexed mod. If so, // skip rather than crash. See KSP-CKAN/CKAN#841. if (latest == null || latest.IsDLC) { continue; } if (latest.version.IsGreaterThan(mod.Value)) { // Upgradable log.InfoFormat("New version {0} found for {1}", latest.version, latest.identifier); to_upgrade.Add(latest); } } catch (ModuleNotFoundKraken) { log.InfoFormat("{0} is installed, but no longer in the registry", mod.Key); } } UpgradeModules(manager, User, ksp, true, to_upgrade); } else { Search.AdjustModulesCase(ksp, options.modules); UpgradeModules(manager, User, ksp, options.modules); } User.RaiseMessage(""); } catch (CancelledActionKraken k) { User.RaiseMessage("Upgrade aborted: {0}", k.Message); return(Exit.ERROR); } catch (ModuleNotFoundKraken kraken) { User.RaiseMessage("Module {0} not found", kraken.module); return(Exit.ERROR); } catch (InconsistentKraken kraken) { User.RaiseMessage(kraken.ToString()); return(Exit.ERROR); } catch (ModuleIsDLCKraken kraken) { User.RaiseMessage($"CKAN can't upgrade expansion '{kraken.module.name}' for you."); var res = kraken?.module?.resources; var storePagesMsg = new Uri[] { res?.store, res?.steamstore } .Where(u => u != null) .Aggregate("", (a, b) => $"{a}\r\n- {b}"); if (!string.IsNullOrEmpty(storePagesMsg)) { User.RaiseMessage($"To upgrade this expansion, download any updates from the store page from which you purchased it:\r\n{storePagesMsg}"); } return(Exit.ERROR); } return(Exit.OK); }