示例#1
0
文件: Registry.cs 项目: Yalchic/CKAN
        /// <summary>
        /// Get a dictionary of all mod versions indexed by their download URLs' hash.
        /// Useful for finding the mods for a group of URLs without repeatedly searching the entire registry.
        /// </summary>
        /// <returns>
        /// dictionary[urlHash] = {mod1, mod2, mod3};
        /// </returns>
        public Dictionary <string, List <CkanModule> > GetDownloadHashIndex()
        {
            var index = new Dictionary <string, List <CkanModule> >();

            foreach (var kvp in available_modules)
            {
                AvailableModule am = kvp.Value;
                foreach (var kvp2 in am.module_version)
                {
                    CkanModule mod = kvp2.Value;
                    if (mod.download != null)
                    {
                        string hash = NetFileCache.CreateURLHash(mod.download);
                        if (index.ContainsKey(hash))
                        {
                            index[hash].Add(mod);
                        }
                        else
                        {
                            index.Add(hash, new List <CkanModule>()
                            {
                                mod
                            });
                        }
                    }
                }
            }
            return(index);
        }
示例#2
0
文件: Registry.cs 项目: Yalchic/CKAN
        /// <summary>
        /// Get a dictionary of all mod versions indexed by their downloads' SHA-1 hash.
        /// Useful for finding the mods for a group of files without repeatedly searching the entire registry.
        /// </summary>
        /// <returns>
        /// dictionary[sha1] = {mod1, mod2, mod3};
        /// </returns>
        public Dictionary <string, List <CkanModule> > GetSha1Index()
        {
            var index = new Dictionary <string, List <CkanModule> >();

            foreach (var kvp in available_modules)
            {
                AvailableModule am = kvp.Value;
                foreach (var kvp2 in am.module_version)
                {
                    CkanModule mod = kvp2.Value;
                    if (mod.download_hash != null)
                    {
                        if (index.ContainsKey(mod.download_hash.sha1))
                        {
                            index[mod.download_hash.sha1].Add(mod);
                        }
                        else
                        {
                            index.Add(mod.download_hash.sha1, new List <CkanModule>()
                            {
                                mod
                            });
                        }
                    }
                }
            }
            return(index);
        }
示例#3
0
        /// <summary>
        /// Returns the specified CkanModule with the version specified,
        /// or null if it does not exist.
        /// <see cref = "IRegistryQuerier.GetModuleByVersion" />
        /// </summary>
        public CkanModule GetModuleByVersion(string ident, Version version)
        {
            log.DebugFormat("Trying to find {0} version {1}", ident, version);

            if (!available_modules.ContainsKey(ident))
            {
                return(null);
            }

            AvailableModule available = available_modules[ident];

            return(available.ByVersion(version));
        }
示例#4
0
        /// <summary>
        /// Mark a given module as available.
        /// </summary>
        public void AddAvailable(CkanModule module)
        {
            SealionTransaction();

            var identifier = module.identifier;

            // If we've never seen this module before, create an entry for it.
            if (!available_modules.ContainsKey(identifier))
            {
                log.DebugFormat("Adding new available module {0}", identifier);
                available_modules[identifier] = new AvailableModule(identifier);
            }

            // Now register the actual version that we have.
            // (It's okay to have multiple versions of the same mod.)

            log.DebugFormat("Available: {0} version {1}", identifier, module.version);
            available_modules[identifier].Add(module);
        }
示例#5
0
文件: Registry.cs 项目: Yalchic/CKAN
 /// <summary>
 /// Ensure one AvailableModule is present in the right spots in the providers index
 /// </summary>
 private void BuildProvidesIndexFor(AvailableModule am)
 {
     foreach (CkanModule m in am.AllAvailable())
     {
         foreach (string provided in m.ProvidesList)
         {
             if (providers.TryGetValue(provided, out HashSet <AvailableModule> provs))
             {
                 provs.Add(am);
             }
             else
             {
                 providers.Add(provided, new HashSet <AvailableModule>()
                 {
                     am
                 });
             }
         }
     }
 }
示例#6
0
        public void BuildTagIndexFor(AvailableModule am)
        {
            bool tagged = false;

            foreach (CkanModule m in am.AllAvailable())
            {
                if (m.Tags != null)
                {
                    tagged = true;
                    foreach (string tagName in m.Tags)
                    {
                        ModuleTag tag = null;
                        if (Tags.TryGetValue(tagName, out tag))
                        {
                            tag.Add(m.identifier);
                        }
                        else
                        {
                            Tags.Add(tagName, new ModuleTag()
                            {
                                Name              = tagName,
                                Visible           = !HiddenTags.Contains(tagName),
                                ModuleIdentifiers = new HashSet <string>()
                                {
                                    m.identifier
                                },
                            });
                        }
                    }
                }
            }
            if (!tagged)
            {
                Untagged.Add(am.AllAvailable().First().identifier);
            }
        }
示例#7
0
        /// <summary>
        /// Mark a given module as available.
        /// </summary>
        public void AddAvailable(CkanModule module)
        {
            SealionTransaction();

            var identifier = module.identifier;
            // If we've never seen this module before, create an entry for it.
            if (! available_modules.ContainsKey(identifier))
            {
                log.DebugFormat("Adding new available module {0}", identifier);
                available_modules[identifier] = new AvailableModule(identifier);
            }

            // Now register the actual version that we have.
            // (It's okay to have multiple versions of the same mod.)

            log.DebugFormat("Available: {0} version {1}", identifier, module.version);
            available_modules[identifier].Add(module);
        }
示例#8
0
        /// <summary>
        /// Move an indeterminate module to Compatible or Incompatible
        /// based on its dependencies.
        /// </summary>
        /// <param name="identifier">Identifier of the module to check</param>
        /// <param name="am">The module to check</param>
        /// <param name="providers">Mapping from identifiers to mods providing those identifiers</param>
        private void CheckDepends(string identifier, AvailableModule am, Dictionary <string, HashSet <AvailableModule> > providers)
        {
            Investigating.Push(identifier);
            foreach (CkanModule m in am.AllAvailable().Where(m => m.IsCompatibleKSP(CompatibleVersions)))
            {
                log.DebugFormat("What about {0}?", m.version);
                bool installable = true;
                if (m.depends != null)
                {
                    foreach (RelationshipDescriptor rel in m.depends)
                    {
                        bool foundCompat = false;
                        if (rel.MatchesAny(installed.Select(kvp => kvp.Value.Module), dlls, dlc))
                        {
                            // Matches a DLL or DLC, cool
                            foundCompat = true;
                        }
                        else
                        {
                            // Get the list of identifiers that would satisfy this dependency
                            // (mostly only one, except for any_of relationships).
                            // For each of those identifiers, if it is provided by at least one module, get all the modules
                            // that provide it (and make sure each is only once in the list)
                            var candidates = RelationshipIdentifiers(rel)
                                             .Where(ident => providers.ContainsKey(ident))
                                             .SelectMany(ident => providers[ident])
                                             .Distinct();

                            foreach (AvailableModule provider in candidates)
                            {
                                string ident = provider.AllAvailable().First().identifier;
                                log.DebugFormat("Checking depends: {0}", ident);
                                if (Investigating.Contains(ident))
                                {
                                    // Circular dependency, pretend it's fine for now
                                    foundCompat = true;
                                    break;
                                }
                                if (Indeterminate.ContainsKey(ident))
                                {
                                    CheckDepends(ident, provider, providers);
                                }
                                if (Compatible.ContainsKey(ident))
                                {
                                    // This one's OK, go to next relationship
                                    foundCompat = true;
                                    break;
                                }
                            }
                        }
                        if (!foundCompat)
                        {
                            // Not satisfiable!! Next CkanModule
                            installable = false;
                            break;
                        }
                    }
                }
                if (installable)
                {
                    // Apparently everything is OK, so we are compatible
                    log.DebugFormat("Complexly compatible: {0}", identifier);
                    Compatible.Add(identifier, am);
                    Indeterminate.Remove(identifier);
                    Investigating.Pop();
                    return;
                }
            }
            // None of the CkanModules can be installed!
            log.DebugFormat("Complexly incompatible: {0}", identifier);
            Incompatible.Add(identifier, am);
            Indeterminate.Remove(identifier);
            Investigating.Pop();
        }