コード例 #1
0
ファイル: GUIMod.cs プロジェクト: pjf/CKAN
        public GUIMod(CkanModule mod, Registry registry, KSPVersion ksp_version)
        {
            //Currently anything which could alter these causes a full reload of the modlist
            // If this is ever changed these could be moved into the properties
            Mod              = mod;
            IsInstalled      = registry.IsInstalled(mod.identifier);
            IsInstallChecked = IsInstalled;
            HasUpdate        = registry.HasUpdate(mod.identifier);
            IsIncompatible   = !mod.IsCompatibleKSP(ksp_version);
            IsAutodetected   = registry.IsAutodetected(mod.identifier);
            Authors          = mod.author == null ? "N/A" : String.Join(",", mod.author);

            var installedVersion = registry.InstalledVersion(mod.identifier);
            var latestVersion    = mod.version;
            var kspVersion       = mod.ksp_version;

            InstalledVersion = installedVersion != null?installedVersion.ToString() : "-";

            LatestVersion = latestVersion != null?latestVersion.ToString() : "-";

            KSPversion = kspVersion != null?kspVersion.ToString() : "-";

            Abstract = mod.@abstract;
            Homepage = mod.resources != null && mod.resources.homepage != null
                ? (object)mod.resources.homepage
                : "N/A";

            Identifier = mod.identifier;
        }
コード例 #2
0
        private int CountModsByFilter(GUIModFilter filter)
        {
            Registry          registry = RegistryManager.Instance(KSPManager.CurrentInstance).registry;
            List <CkanModule> modules  = registry.Available();

            int count = modules.Count();

            // filter by left menu selection
            switch (filter)
            {
            case GUIModFilter.All:
                break;

            case GUIModFilter.Installed:
                count -= modules.Count(m => !registry.IsInstalled(m.identifier));
                break;

            case GUIModFilter.InstalledUpdateAvailable:
                count -= modules.Count
                         (
                    m => !(registry.IsInstalled(m.identifier) &&
                           m.version.IsGreaterThan(
                               registry.InstalledVersion(m.identifier)))
                         );
                break;

            case GUIModFilter.NewInRepository:
                break;

            case GUIModFilter.NotInstalled:
                count -= modules.RemoveAll(m => registry.IsInstalled(m.identifier));
                break;

            case GUIModFilter.Incompatible:
                count = registry.Incompatible().Count;
                break;
            }

            return(count);
        }
コード例 #3
0
        /// <summary>
        /// Updates the supplied registry from the URL given.
        /// This does not *save* the registry. For that, you probably want Repo.Update
        /// </summary>
        internal static void UpdateRegistry(Uri repo, Registry registry, KSP ksp, IUser user, Boolean clear = true)
        {
            log.InfoFormat("Downloading {0}", repo);

            string repo_file = String.Empty;

            try
            {
                repo_file = Net.Download(repo);
            }
            catch (System.Net.WebException)
            {
                user.RaiseMessage("Connection to {0} could not be established.", repo);
                return;
            }

            // Clear our list of known modules.
            var old_available = registry.available_modules;

            if (clear)
            {
                registry.ClearAvailable();
            }

            // Check the filetype.
            FileType type = FileIdentifier.IdentifyFile(repo_file);

            switch (type)
            {
            case FileType.TarGz:
                UpdateRegistryFromTarGz(repo_file, registry);
                break;

            case FileType.Zip:
                UpdateRegistryFromZip(repo_file, registry);
                break;

            default:
                break;
            }

            List <CkanModule> metadataChanges = new List <CkanModule>();

            foreach (var identifierModulePair in old_available)
            {
                var identifier = identifierModulePair.Key;

                if (registry.IsInstalled(identifier))
                {
                    var installedVersion = registry.InstalledVersion(identifier);
                    if (!(registry.available_modules.ContainsKey(identifier)))
                    {
                        log.InfoFormat("UpdateRegistry, module {0}, version {1} not in repository ({2})", identifier, installedVersion, repo);
                        continue;
                    }

                    if (!registry.available_modules[identifier].module_version.ContainsKey(installedVersion))
                    {
                        continue;
                    }

                    // if the mod is installed and the metadata is different we have to reinstall it
                    var metadata = registry.available_modules[identifier].module_version[installedVersion];

                    if (!old_available.ContainsKey(identifier) ||
                        !old_available[identifier].module_version.ContainsKey(installedVersion))
                    {
                        continue;
                    }

                    var oldMetadata = old_available[identifier].module_version[installedVersion];

                    bool same = true;
                    if ((metadata.install == null) != (oldMetadata.install == null) ||
                        (metadata.install != null && metadata.install.Length != oldMetadata.install.Length))
                    {
                        same = false;
                    }
                    else
                    {
                        if (metadata.install != null)
                        {
                            for (int i = 0; i < metadata.install.Length; i++)
                            {
                                if (metadata.install[i].file != oldMetadata.install[i].file)
                                {
                                    same = false;
                                    break;
                                }

                                if (metadata.install[i].install_to != oldMetadata.install[i].install_to)
                                {
                                    same = false;
                                    break;
                                }

                                if ((metadata.install[i].filter == null) != (oldMetadata.install[i].filter == null))
                                {
                                    same = false;
                                    break;
                                }

                                if (metadata.install[i].filter != null)
                                {
                                    if (!metadata.install[i].filter.SequenceEqual(oldMetadata.install[i].filter))
                                    {
                                        same = false;
                                        break;
                                    }
                                }

                                if ((metadata.install[i].filter_regexp == null) != (oldMetadata.install[i].filter_regexp == null))
                                {
                                    same = false;
                                    break;
                                }

                                if (metadata.install[i].filter_regexp != null)
                                {
                                    if (!metadata.install[i].filter_regexp.SequenceEqual(oldMetadata.install[i].filter_regexp))
                                    {
                                        same = false;
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    if (!same)
                    {
                        metadataChanges.Add(registry.available_modules[identifier].module_version[installedVersion]);
                    }
                }
            }

            if (metadataChanges.Any())
            {
                string mods = "";
                for (int i = 0; i < metadataChanges.Count; i++)
                {
                    mods += metadataChanges[i].identifier + " "
                            + metadataChanges[i].version.ToString() + ((i < metadataChanges.Count - 1) ? ", " : "");
                }

                if (user.RaiseYesNoDialog(String.Format(
                                              @"The following mods have had their metadata changed since last update - {0}.
It is advisable that you reinstall them in order to preserve consistency with the repository. Do you wish to reinstall now?", mods)))
                {
                    ModuleInstaller installer = ModuleInstaller.GetInstance(ksp, new NullUser());
                    installer.Upgrade(metadataChanges, new NetAsyncDownloader(new NullUser()));
                }
            }

            // Remove our downloaded meta-data now we've processed it.
            // Seems weird to do this as part of a transaction, but Net.Download uses them, so let's be consistent.
            file_transaction.Delete(repo_file);
        }
コード例 #4
0
ファイル: Repo.cs プロジェクト: Rusk85/CKAN
        /// <summary>
        /// Updates the supplied registry from the URL given.
        /// This does not *save* the registry. For that, you probably want Repo.Update
        /// </summary>
        internal static void UpdateRegistry(Uri repo, Registry registry, KSP ksp, IUser user, Boolean clear = true)
        {
            log.InfoFormat("Downloading {0}", repo);

            string repo_file = Net.Download(repo);

            // Clear our list of known modules.
            var old_available = registry.available_modules;
            if (clear)
            {
                registry.ClearAvailable();
            }

            // Check the filetype.
            FileType type = FileIdentifier.IdentifyFile(repo_file);

            switch (type)
            {
            case FileType.TarGz:
                UpdateRegistryFromTarGz (repo_file, registry);
                break;
            case FileType.Zip:
                UpdateRegistryFromZip (repo_file, registry);
                break;
            default:
                break;
            }

            List<CkanModule> metadataChanges = new List<CkanModule>();

            foreach (var identifierModulePair in old_available)
            {
                var identifier = identifierModulePair.Key;

                if (registry.IsInstalled(identifier))
                {
                    var installedVersion = registry.InstalledVersion(identifier);
                    if (!(registry.available_modules.ContainsKey(identifier)))
                    {
                        log.InfoFormat("UpdateRegistry, module {0}, version {1} not in repository ({2})", identifier, installedVersion, repo);
                        continue;
                    }

                    if (!registry.available_modules[identifier].module_version.ContainsKey(installedVersion))
                    {
                        continue;
                    }

                    // if the mod is installed and the metadata is different we have to reinstall it
                    var metadata = registry.available_modules[identifier].module_version[installedVersion];

                    if (!old_available.ContainsKey(identifier) ||
                        !old_available[identifier].module_version.ContainsKey(installedVersion))
                    {
                        continue;
                    }

                    var oldMetadata = old_available[identifier].module_version[installedVersion];

                    bool same = true;
                    if ((metadata.install == null) != (oldMetadata.install == null) ||
                        (metadata.install != null && metadata.install.Length != oldMetadata.install.Length))
                    {
                        same = false;
                    }
                    else
                    {
                        if(metadata.install != null)
                        for (int i = 0; i < metadata.install.Length; i++)
                        {
                            if (metadata.install[i].file != oldMetadata.install[i].file)
                            {
                                same = false;
                                break;
                            }

                            if (metadata.install[i].install_to != oldMetadata.install[i].install_to)
                            {
                                same = false;
                                break;
                            }

                            if ((metadata.install[i].filter == null) != (oldMetadata.install[i].filter == null))
                            {
                                same = false;
                                break;
                            }

                            if(metadata.install[i].filter != null)
                            if (!metadata.install[i].filter.SequenceEqual(oldMetadata.install[i].filter))
                            {
                                same = false;
                                break;
                            }

                            if ((metadata.install[i].filter_regexp == null) != (oldMetadata.install[i].filter_regexp == null))
                            {
                                same = false;
                                break;
                            }

                            if(metadata.install[i].filter_regexp != null)
                            if (!metadata.install[i].filter_regexp.SequenceEqual(oldMetadata.install[i].filter_regexp))
                            {
                                same = false;
                                break;
                            }
                        }
                    }

                    if (!same)
                    {
                        metadataChanges.Add(registry.available_modules[identifier].module_version[installedVersion]);
                    }
                }
            }

            if (metadataChanges.Any())
            {
                string mods = "";
                for (int i = 0; i < metadataChanges.Count; i++)
                {
                    mods += metadataChanges[i].identifier + " "
                        + metadataChanges[i].version.ToString() + ((i < metadataChanges.Count-1) ? ", " : "");
                }

                if(user.RaiseYesNoDialog(String.Format(
                    @"The following mods have had their metadata changed since last update - {0}.
            It is advisable that you reinstall them in order to preserve consistency with the repository. Do you wish to reinstall now?", mods)))
                {
                    ModuleInstaller installer = ModuleInstaller.GetInstance(ksp, new NullUser());
                    installer.Upgrade(metadataChanges, new NetAsyncDownloader(new NullUser()));
                }
            }

            // Remove our downloaded meta-data now we've processed it.
            // Seems weird to do this as part of a transaction, but Net.Download uses them, so let's be consistent.
            file_transaction.Delete(repo_file);
        }
コード例 #5
0
        private void _UpdateModsList(bool markUpdates)
        {
            Registry registry = RegistryManager.Instance(KSPManager.CurrentInstance).registry;

            ModList.Rows.Clear();

            List <CkanModule> modules = GetModsByFilter(m_ModFilter);

            // filter by left menu selection
            switch (m_ModFilter)
            {
            case GUIModFilter.All:
                break;

            case GUIModFilter.Installed:
                modules.RemoveAll(m => !registry.IsInstalled(m.identifier));
                break;

            case GUIModFilter.InstalledUpdateAvailable:
                modules.RemoveAll
                (
                    m => !(registry.IsInstalled(m.identifier) &&
                           m.version.IsGreaterThan(
                               registry.InstalledVersion(m.identifier)))
                );
                break;

            case GUIModFilter.NewInRepository:
                break;

            case GUIModFilter.NotInstalled:
                modules.RemoveAll(m => registry.IsInstalled(m.identifier));
                break;

            case GUIModFilter.Incompatible:
                break;
            }

            // filter by name
            modules.RemoveAll(m => !m.name.ToLowerInvariant().Contains(m_ModNameFilter.ToLowerInvariant()));

            foreach (CkanModule mod in modules)
            {
                var item = new DataGridViewRow();
                item.Tag = mod;

                bool isInstalled = registry.IsInstalled(mod.identifier);

                // installed
                if (m_ModFilter != GUIModFilter.Incompatible)
                {
                    var installedCell = new DataGridViewCheckBoxCell();
                    installedCell.Value = isInstalled;
                    item.Cells.Add(installedCell);
                }
                else
                {
                    var installedCell = new DataGridViewTextBoxCell();
                    installedCell.Value = "-";
                    item.Cells.Add(installedCell);
                }

                // want update
                if (!isInstalled)
                {
                    var updateCell = new DataGridViewTextBoxCell();
                    item.Cells.Add(updateCell);
                    updateCell.ReadOnly = true;
                    updateCell.Value    = "-";
                }
                else
                {
                    bool isUpToDate =
                        !registry.InstalledVersion(mod.identifier).IsLessThan(mod.version);
                    if (!isUpToDate)
                    {
                        var updateCell = new DataGridViewCheckBoxCell();
                        item.Cells.Add(updateCell);
                        updateCell.ReadOnly = false;
                    }
                    else
                    {
                        var updateCell = new DataGridViewTextBoxCell();
                        item.Cells.Add(updateCell);
                        updateCell.ReadOnly = true;
                        updateCell.Value    = "-";
                    }
                }

                // name
                var nameCell = new DataGridViewTextBoxCell();
                nameCell.Value = mod.name;
                item.Cells.Add(nameCell);

                // author
                var authorCell = new DataGridViewTextBoxCell();
                if (mod.author != null)
                {
                    string authors = "";
                    for (int i = 0; i < mod.author.Count(); i++)
                    {
                        authors += mod.author[i];
                        if (i != mod.author.Count() - 1)
                        {
                            authors += ", ";
                        }
                    }

                    authorCell.Value = authors;
                }
                else
                {
                    authorCell.Value = "N/A";
                }

                item.Cells.Add(authorCell);

                // installed version
                Version installedVersion     = registry.InstalledVersion(mod.identifier);
                var     installedVersionCell = new DataGridViewTextBoxCell();

                if (installedVersion != null)
                {
                    installedVersionCell.Value = installedVersion.ToString();
                }
                else
                {
                    installedVersionCell.Value = "-";
                }

                item.Cells.Add(installedVersionCell);

                // latest version
                Version latestVersion     = mod.version;
                var     latestVersionCell = new DataGridViewTextBoxCell();

                if (latestVersion != null)
                {
                    latestVersionCell.Value = latestVersion.ToString();
                }
                else
                {
                    latestVersionCell.Value = "-";
                }

                item.Cells.Add(latestVersionCell);

                // KSP version
                KSPVersion kspVersion     = mod.ksp_version;
                var        kspVersionCell = new DataGridViewTextBoxCell();

                if (kspVersion != null)
                {
                    kspVersionCell.Value = kspVersion.ToString();
                }
                else
                {
                    kspVersionCell.Value = "-";
                }

                item.Cells.Add(kspVersionCell);

                // description
                var descriptionCell = new DataGridViewTextBoxCell();
                descriptionCell.Value = mod.@abstract;
                item.Cells.Add(descriptionCell);

                // homepage
                var homepageCell = new DataGridViewLinkCell();

                if (mod.resources != null && mod.resources.homepage != null)
                {
                    homepageCell.Value = mod.resources.homepage;
                }
                else
                {
                    homepageCell.Value = "N/A";
                }

                item.Cells.Add(homepageCell);

                ModList.Rows.Add(item);

                // sort by name
                ModList.Sort(ModList.Columns[2], ListSortDirection.Ascending);
                ModList.Refresh();
            }
        }
コード例 #6
0
        // this functions computes a changeset from the user's choices in the GUI
        private List <KeyValuePair <CkanModule, GUIModChangeType> > ComputeChangeSetFromModList()
        // this probably needs to be refactored
        {
            var changeset = new HashSet <KeyValuePair <CkanModule, GUIModChangeType> >();

            // these are the lists
            var modulesToInstall = new HashSet <string>();
            var modulesToRemove  = new HashSet <string>();

            Registry registry = RegistryManager.Instance(KSPManager.CurrentInstance).registry;

            foreach (DataGridViewRow row in ModList.Rows)
            {
                var mod = (CkanModule)row.Tag;
                if (mod == null)
                {
                    continue;
                }

                bool isInstalled        = registry.IsInstalled(mod.identifier);
                var  isInstalledCell    = row.Cells[0] as DataGridViewCheckBoxCell;
                var  isInstalledChecked = (bool)isInstalledCell.Value;

                if (!isInstalled && isInstalledChecked)
                {
                    modulesToInstall.Add(mod.identifier);
                }
                else if (isInstalled && !isInstalledChecked)
                {
                    modulesToRemove.Add(mod.identifier);
                }
            }

            RelationshipResolverOptions options = RelationshipResolver.DefaultOpts();

            options.with_recommends = false;
            options.without_toomanyprovides_kraken = true;
            options.without_enforce_consistency    = true;

            RelationshipResolver resolver = null;

            try
            {
                resolver = new RelationshipResolver(modulesToInstall.ToList(), options, registry);
            }
            catch (Exception e)
            {
                return(null);
            }

            foreach (CkanModule mod in resolver.ModList())
            {
                changeset.Add(new KeyValuePair <CkanModule, GUIModChangeType>(mod, GUIModChangeType.Install));
            }

            ModuleInstaller installer = ModuleInstaller.Instance;

            foreach (string moduleName in modulesToRemove)
            {
                var reverseDependencies = installer.FindReverseDependencies(moduleName);
                foreach (string reverseDependency in reverseDependencies)
                {
                    CkanModule mod = registry.LatestAvailable(reverseDependency);
                    changeset.Add(new KeyValuePair <CkanModule, GUIModChangeType>(mod, GUIModChangeType.Remove));
                }
            }

            foreach (DataGridViewRow row in ModList.Rows)
            {
                var mod = (CkanModule)row.Tag;
                if (mod == null)
                {
                    continue;
                }

                bool             isInstalled         = registry.IsInstalled(mod.identifier);
                var              isInstalledCell     = row.Cells[0] as DataGridViewCheckBoxCell;
                var              isInstalledChecked  = (bool)isInstalledCell.Value;
                DataGridViewCell shouldBeUpdatedCell = row.Cells[1];
                bool             shouldBeUpdated     = false;
                if (shouldBeUpdatedCell is DataGridViewCheckBoxCell && shouldBeUpdatedCell.Value != null)
                {
                    shouldBeUpdated = (bool)shouldBeUpdatedCell.Value;
                }

                if (isInstalled && !isInstalledChecked)
                {
                    changeset.Add(new KeyValuePair <CkanModule, GUIModChangeType>(mod, GUIModChangeType.Remove));
                }
                else if (isInstalled && isInstalledChecked &&
                         mod.version.IsGreaterThan(registry.InstalledVersion(mod.identifier)) && shouldBeUpdated)
                {
                    changeset.Add(new KeyValuePair <CkanModule, GUIModChangeType>(mod, GUIModChangeType.Update));
                }
            }

            return(changeset.ToList());
        }
コード例 #7
0
        /// <summary>
        /// Resolve a relationship stanza (a list of relationships).
        /// This will add modules to be installed, if required.
        /// May recurse back to Resolve for those new modules.
        ///
        /// If `soft_resolve` is true, we warn rather than throw exceptions on mods we cannot find.
        /// If `soft_resolve` is false (default), we throw a ModuleNotFoundKraken if we can't find a dependency.
        ///
        /// Throws a TooManyModsProvideKraken if we have too many choices.
        /// </summary>
        private void ResolveStanza(IEnumerable <RelationshipDescriptor> stanza, RelationshipResolverOptions options, bool soft_resolve = false)
        {
            if (stanza == null)
            {
                return;
            }

            foreach (string dep_name in stanza.Select(dep => dep.name))
            {
                log.DebugFormat("Considering {0}", dep_name);

                // If we already have this dependency covered, skip.
                // If it's already installed, skip.
                if (modlist.ContainsKey(dep_name) || registry.IsInstalled(dep_name))
                {
                    continue;
                }

                List <CkanModule> candidates = registry.LatestAvailableWithProvides(dep_name, kspversion);

                if (candidates.Count == 0)
                {
                    if (!soft_resolve)
                    {
                        log.ErrorFormat("Dependency on {0} found, but nothing provides it.", dep_name);
                        throw new ModuleNotFoundKraken(dep_name);
                    }
                    log.InfoFormat("{0} is recommended/suggested, but nothing provides it.", dep_name);
                    continue;
                }
                if (candidates.Count > 1)
                {
                    // Oh no, too many to pick from!
                    // TODO: It would be great if instead we picked the one with the
                    // most recommendations.
                    if (options.without_toomanyprovides_kraken)
                    {
                        continue;
                    }

                    throw new TooManyModsProvideKraken(dep_name, candidates);
                }

                CkanModule candidate = candidates[0];

                // Finally, check our candidate against everything which might object
                // to it being installed; that's all the mods which are fixed in our
                // list thus far, as well as everything on the system.

                var fixed_mods =
                    new HashSet <Module>(modlist.Values);

                fixed_mods.UnionWith(registry.InstalledModules.Select(x => x.Module));

                foreach (Module mod in fixed_mods)
                {
                    if (mod.ConflictsWith(candidate))
                    {
                        if (soft_resolve)
                        {
                            log.InfoFormat("{0} would cause conflicts, excluding it from consideration", candidate);

                            // I want labeled loops please, so I don't have to set this to null,
                            // break, and then look at it at the end. o_O
                            candidate = null;
                            break;
                        }
                        var this_is_why_we_cant_have_nice_things = new List <string> {
                            string.Format(
                                "{0} and {1} conflict with each other, yet we require them both!",
                                candidate, mod)
                        };

                        throw new InconsistentKraken(this_is_why_we_cant_have_nice_things);
                    }
                }

                // Our candidate may have been set to null if it was vetoed by our
                // sanity check above.
                if (candidate != null)
                {
                    // Okay, looks like we want this one. Adding.
                    Add(candidate);
                    Resolve(candidate, options);
                }
            }
        }
コード例 #8
0
        /// <summary>
        /// Resolve a relationship stanza (a list of relationships).
        /// This will add modules to be installed, if required.
        /// May recurse back to Resolve for those new modules.
        ///
        /// If `soft_resolve` is true, we warn rather than throw exceptions on mods we cannot find.
        /// If `soft_resolve` is false (default), we throw a ModuleNotFoundKraken if we can't find a dependency.
        ///
        /// Throws a TooManyModsProvideKraken if we have too many choices and
        /// options.without_toomanyprovides_kraken is not set.
        ///
        /// See RelationshipResolverOptions for further adjustments that can be made.
        ///
        /// </summary>

        private void ResolveStanza(IEnumerable <RelationshipDescriptor> stanza, Relationship reason,
                                   RelationshipResolverOptions options, bool soft_resolve = false)
        {
            if (stanza == null)
            {
                return;
            }

            foreach (string dep_name in stanza.Select(dep => dep.name))
            {
                log.DebugFormat("Considering {0}", dep_name);

                // If we already have this dependency covered, skip.
                // If it's already installed, skip.
                if (modlist.ContainsKey(dep_name) || registry.IsInstalled(dep_name))
                {
                    continue;
                }

                List <CkanModule> candidates = registry.LatestAvailableWithProvides(dep_name, kspversion);

                if (candidates.Count == 0)
                {
                    if (!soft_resolve)
                    {
                        log.ErrorFormat("Dependency on {0} found, but nothing provides it.", dep_name);
                        throw new ModuleNotFoundKraken(dep_name);
                    }
                    log.InfoFormat("{0} is recommended/suggested, but nothing provides it.", dep_name);
                    continue;
                }
                if (candidates.Count > 1)
                {
                    // Oh no, too many to pick from!
                    // TODO: It would be great if instead we picked the one with the
                    // most recommendations.
                    if (options.without_toomanyprovides_kraken)
                    {
                        continue;
                    }

                    throw new TooManyModsProvideKraken(dep_name, candidates);
                }

                CkanModule candidate = candidates[0];

                // Finally, check our candidate against everything which might object
                // to it being installed; that's all the mods which are fixed in our
                // list thus far, as well as everything on the system.

                var fixed_mods = new HashSet <Module>(modlist.Values);
                fixed_mods.UnionWith(registry.InstalledModules.Select(x => x.Module));

                var conflicting_mod = fixed_mods.FirstOrDefault(mod => mod.ConflictsWith(candidate));
                if (conflicting_mod == null)
                {
                    // Okay, looks like we want this one. Adding.
                    Add(candidate, reason);
                    Resolve(candidate, options);
                }
                else if (soft_resolve)
                {
                    log.InfoFormat("{0} would cause conflicts, excluding it from consideration", candidate);
                }
                else
                {
                    if (options.procede_with_inconsistencies)
                    {
                        Add(candidate, reason);
                        conflicts.Add(new KeyValuePair <Module, Module>(conflicting_mod, candidate));
                        conflicts.Add(new KeyValuePair <Module, Module>(candidate, conflicting_mod));
                    }
                    else
                    {
                        throw new InconsistentKraken(string.Format("{0} conflicts with {1}, can't install both.", conflicting_mod,
                                                                   candidate));
                    }
                }
            }
        }
コード例 #9
0
        /// <summary>
        /// Updates the supplied registry from the URL given.
        /// This does not *save* the registry. For that, you probably want Repo.Update
        /// </summary>
        internal static void UpdateRegistry(Uri repo, Registry registry, KSP ksp, IUser user, Boolean clear = true)
        {
            log.InfoFormat("Downloading {0}", repo);

            string repo_file = String.Empty;

            try
            {
                repo_file = Net.Download(repo);
            }
            catch (System.Net.WebException e)
            {
                user.RaiseError($"Couldn't download {repo}.", e);
                return;
            }

            // Clear our list of known modules.
            var old_available = registry.available_modules;

            if (clear)
            {
                registry.ClearAvailable();
            }

            // Check the filetype.
            FileType type = FileIdentifier.IdentifyFile(repo_file);

            switch (type)
            {
            case FileType.TarGz:
                UpdateRegistryFromTarGz(repo_file, registry);
                break;

            case FileType.Zip:
                UpdateRegistryFromZip(repo_file, registry);
                break;

            default:
                break;
            }

            List <CfanModule> metadataChanges = new List <CfanModule>();

            foreach (var identifierModulePair in old_available)
            {
                var identifier = identifierModulePair.Key;

                if (registry.IsInstalled(identifier))
                {
                    AbstractVersion abstractVersion  = registry.InstalledVersion(identifier);
                    var             installedVersion = new ModVersion(abstractVersion.ToString());

                    if (!(registry.available_modules.ContainsKey(identifier)))
                    {
                        log.InfoFormat("UpdateRegistry, module {0}, version {1} not in repository ({2})", identifier, installedVersion, repo);
                        continue;
                    }

                    if (!registry.available_modules[identifier].module_version.ContainsKey(installedVersion))
                    {
                        continue;
                    }

                    // if the mod is installed and the metadata is different we have to reinstall it
                    CfanModule metadata = new CfanModule(registry.available_modules[identifier].module_version[installedVersion]);

                    if (!old_available.ContainsKey(identifier) ||
                        !old_available[identifier].module_version.ContainsKey(installedVersion))
                    {
                        continue;
                    }

                    CfanModule oldMetadata = new CfanModule(old_available[identifier].module_version[installedVersion]);

                    bool same = metadata.kind == oldMetadata.kind;

                    if (!same)
                    {
                        metadataChanges.Add(new CfanModule(registry.available_modules[identifier].module_version[installedVersion]));
                    }
                }
            }

            if (metadataChanges.Any())
            {
                string mods = "";
                for (int i = 0; i < metadataChanges.Count; i++)
                {
                    mods += metadataChanges[i].identifier + " "
                            + metadataChanges[i].modVersion.ToString() + ((i < metadataChanges.Count - 1) ? ", " : "");
                }

                if (user.RaiseYesNoDialog(String.Format(
                                              @"The following mods have had their metadata changed since last update - {0}.
It is advisable that you reinstall them in order to preserve consistency with the repository. Do you wish to reinstall now?", mods)))
                {
                    ModuleInstaller installer = ModuleInstaller.GetInstance(ksp, new NullUser());
                    installer.Upgrade(metadataChanges, new NetAsyncModulesDownloader(new NullUser(), ksp.tryGetFactorioAuthData()));
                }
            }

            // Remove our downloaded meta-data now we've processed it.
            // Seems weird to do this as part of a transaction, but Net.Download uses them, so let's be consistent.
            file_transaction.Delete(repo_file);
        }