Example #1
0
        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);
        }
Example #2
0
        /// <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);
        }
Example #3
0
        /// <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);
        }
Example #4
0
        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);
        }
Example #5
0
        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);
        }
Example #6
0
        /// <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);
        }