Exemple #1
0
        /// <summary>Construct an instance.</summary>
        /// <param name="wiki">The mod metadata from the wiki (if available).</param>
        /// <param name="db">The mod metadata from SMAPI's internal DB (if available).</param>
        public ModExtendedMetadataModel(WikiCompatibilityEntry wiki, ModDataRecord db)
        {
            // wiki data
            if (wiki != null)
            {
                this.ID                   = wiki.ID;
                this.Name                 = wiki.Name;
                this.NexusID              = wiki.NexusID;
                this.ChucklefishID        = wiki.ChucklefishID;
                this.GitHubRepo           = wiki.GitHubRepo;
                this.CustomSourceUrl      = wiki.CustomSourceUrl;
                this.CustomUrl            = wiki.CustomUrl;
                this.CompatibilityStatus  = wiki.Status;
                this.CompatibilitySummary = wiki.Summary;
            }

            // internal DB data
            if (db != null)
            {
                this.ID   = this.ID.Union(db.FormerIDs).ToArray();
                this.Name = this.Name ?? db.DisplayName;
            }
        }
Exemple #2
0
        /*********
        ** Private methods
        *********/
        /// <summary>Get the metadata for a mod.</summary>
        /// <param name="search">The mod data to match.</param>
        /// <param name="wikiData">The wiki data.</param>
        /// <param name="includeExtendedMetadata">Whether to include extended metadata for each mod.</param>
        /// <returns>Returns the mod data if found, else <c>null</c>.</returns>
        private async Task <ModEntryModel> GetModData(ModSearchEntryModel search, WikiCompatibilityEntry[] wikiData, bool includeExtendedMetadata)
        {
            // resolve update keys
            var           updateKeys = new HashSet <string>(search.UpdateKeys ?? new string[0], StringComparer.InvariantCultureIgnoreCase);
            ModDataRecord record     = this.ModDatabase.Get(search.ID);

            if (record?.Fields != null)
            {
                string defaultUpdateKey = record.Fields.FirstOrDefault(p => p.Key == ModDataFieldKey.UpdateKey && p.IsDefault)?.Value;
                if (!string.IsNullOrWhiteSpace(defaultUpdateKey))
                {
                    updateKeys.Add(defaultUpdateKey);
                }
            }

            // get latest versions
            ModEntryModel result = new ModEntryModel {
                ID = search.ID
            };
            IList <string> errors = new List <string>();

            foreach (string updateKey in updateKeys)
            {
                // fetch data
                ModInfoModel data = await this.GetInfoForUpdateKeyAsync(updateKey);

                if (data.Error != null)
                {
                    errors.Add(data.Error);
                    continue;
                }

                // handle main version
                if (data.Version != null)
                {
                    if (!SemanticVersion.TryParse(data.Version, out ISemanticVersion version))
                    {
                        errors.Add($"The update key '{updateKey}' matches a mod with invalid semantic version '{data.Version}'.");
                        continue;
                    }

                    if (this.IsNewer(version, result.Main?.Version))
                    {
                        result.Main = new ModEntryVersionModel(version, data.Url);
                    }
                }

                // handle optional version
                if (data.PreviewVersion != null)
                {
                    if (!SemanticVersion.TryParse(data.PreviewVersion, out ISemanticVersion version))
                    {
                        errors.Add($"The update key '{updateKey}' matches a mod with invalid optional semantic version '{data.PreviewVersion}'.");
                        continue;
                    }

                    if (this.IsNewer(version, result.Optional?.Version))
                    {
                        result.Optional = new ModEntryVersionModel(version, data.Url);
                    }
                }
            }

            // get unofficial version
            WikiCompatibilityEntry wikiEntry = wikiData.FirstOrDefault(entry => entry.ID.Contains(result.ID.Trim(), StringComparer.InvariantCultureIgnoreCase));

            if (wikiEntry?.UnofficialVersion != null && this.IsNewer(wikiEntry.UnofficialVersion, result.Main?.Version) && this.IsNewer(wikiEntry.UnofficialVersion, result.Optional?.Version))
            {
                result.Unofficial = new ModEntryVersionModel(wikiEntry.UnofficialVersion, this.WikiCompatibilityPageUrl);
            }

            // fallback to preview if latest is invalid
            if (result.Main == null && result.Optional != null)
            {
                result.Main     = result.Optional;
                result.Optional = null;
            }

            // special cases
            if (result.ID == "Pathoschild.SMAPI")
            {
                if (result.Main != null)
                {
                    result.Main.Url = "https://smapi.io/";
                }
                if (result.Optional != null)
                {
                    result.Optional.Url = "https://smapi.io/";
                }
            }

            // add extended metadata
            if (includeExtendedMetadata && (wikiEntry != null || record != null))
            {
                result.Metadata = new ModExtendedMetadataModel(wikiEntry, record);
            }

            // add result
            result.Errors = errors.ToArray();
            return(result);
        }
Exemple #3
0
        /// <summary>Get update keys based on the available mod metadata, while maintaining the precedence order.</summary>
        /// <param name="specifiedKeys">The specified update keys.</param>
        /// <param name="record">The mod's entry in SMAPI's internal database.</param>
        /// <param name="entry">The mod's entry in the wiki list.</param>
        public IEnumerable <string> GetUpdateKeys(string[] specifiedKeys, ModDataRecord record, WikiCompatibilityEntry entry)
        {
            IEnumerable <string> GetRaw()
            {
                // specified update keys
                if (specifiedKeys != null)
                {
                    foreach (string key in specifiedKeys)
                    {
                        yield return(key?.Trim());
                    }
                }

                // default update key
                string defaultKey = record?.GetDefaultUpdateKey();

                if (defaultKey != null)
                {
                    yield return(defaultKey);
                }

                // wiki metadata
                if (entry != null)
                {
                    if (entry.NexusID.HasValue)
                    {
                        yield return($"Nexus:{entry.NexusID}");
                    }
                    if (entry.ChucklefishID.HasValue)
                    {
                        yield return($"Chucklefish:{entry.ChucklefishID}");
                    }
                }
            }

            HashSet <string> seen = new HashSet <string>(StringComparer.InvariantCulture);

            foreach (string key in GetRaw())
            {
                if (!string.IsNullOrWhiteSpace(key) && seen.Add(key))
                {
                    yield return(key);
                }
            }
        }