Exemple #1
0
        /// <summary>Get the mod info for an update key.</summary>
        /// <param name="updateKey">The namespaced update key.</param>
        private async Task <ModInfoModel> GetInfoForUpdateKeyAsync(string updateKey)
        {
            // parse update key
            UpdateKey parsed = UpdateKey.Parse(updateKey);

            if (!parsed.LooksValid)
            {
                return(new ModInfoModel($"The update key '{updateKey}' isn't in a valid format. It should contain the site key and mod ID like 'Nexus:541'."));
            }

            // get matching repository
            if (!this.Repositories.TryGetValue(parsed.Repository, out IModRepository repository))
            {
                return(new ModInfoModel($"There's no mod site with key '{parsed.Repository}'. Expected one of [{string.Join(", ", this.Repositories.Keys)}]."));
            }

            // fetch mod info
            return(await this.Cache.GetOrCreateAsync($"{repository.VendorKey}:{parsed.ID}".ToLower(), async entry =>
            {
                ModInfoModel result = await repository.GetModInfoAsync(parsed.ID);
                if (result.Error == null)
                {
                    if (result.Version == null)
                    {
                        result.Error = $"The update key '{updateKey}' matches a mod with no version number.";
                    }
                    else if (!Regex.IsMatch(result.Version, this.VersionRegex, RegexOptions.CultureInvariant | RegexOptions.IgnoreCase))
                    {
                        result.Error = $"The update key '{updateKey}' matches a mod with invalid semantic version '{result.Version}'.";
                    }
                }
                entry.AbsoluteExpiration = DateTimeOffset.UtcNow.AddMinutes(result.Error == null ? this.SuccessCacheMinutes : this.ErrorCacheMinutes);
                return result;
            }));
        }
        /// <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>
        private IEnumerable <UpdateKey> GetUpdateKeys(string[] specifiedKeys, ModDataRecord record, WikiModEntry 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($"{ModRepositoryKey.Nexus}:{entry.NexusID}");
                    }
                    if (entry.ModDropID.HasValue)
                    {
                        yield return($"{ModRepositoryKey.ModDrop}:{entry.ModDropID}");
                    }
                    if (entry.CurseForgeID.HasValue)
                    {
                        yield return($"{ModRepositoryKey.CurseForge}:{entry.CurseForgeID}");
                    }
                    if (entry.ChucklefishID.HasValue)
                    {
                        yield return($"{ModRepositoryKey.Chucklefish}:{entry.ChucklefishID}");
                    }
                }
            }

            HashSet <UpdateKey> seen = new HashSet <UpdateKey>();

            foreach (string rawKey in GetRaw())
            {
                if (string.IsNullOrWhiteSpace(rawKey))
                {
                    continue;
                }

                UpdateKey key = UpdateKey.Parse(rawKey);
                if (seen.Add(key))
                {
                    yield return(key);
                }
            }
        }
Exemple #3
0
 /// <inheritdoc />
 public IEnumerable <UpdateKey> GetUpdateKeys(bool validOnly = false)
 {
     foreach (string rawKey in this.Manifest?.UpdateKeys ?? new string[0])
     {
         UpdateKey updateKey = UpdateKey.Parse(rawKey);
         if (updateKey.LooksValid || !validOnly)
         {
             yield return(updateKey);
         }
     }
 }
Exemple #4
0
        /// <inheritdoc />
        public IEnumerable <UpdateKey> GetUpdateKeys(bool validOnly = false)
        {
            if (!this.HasManifest())
            {
                yield break;
            }

            foreach (string rawKey in this.Manifest.UpdateKeys)
            {
                UpdateKey updateKey = UpdateKey.Parse(rawKey);
                if (updateKey.LooksValid || !validOnly)
                {
                    yield return(updateKey);
                }
            }
        }
Exemple #5
0
        /// <summary>Get an update URL for an update key (if valid).</summary>
        /// <param name="updateKey">The update key.</param>
        public string GetUpdateUrl(string updateKey)
        {
            UpdateKey parsed = UpdateKey.Parse(updateKey);

            if (!parsed.LooksValid)
            {
                return(null);
            }

            if (this.VendorModUrls.TryGetValue(parsed.Site, out string urlTemplate))
            {
                return(string.Format(urlTemplate, parsed.ID));
            }

            return(null);
        }
Exemple #6
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>
        private IEnumerable <UpdateKey> GetUpdateKeys(string[] specifiedKeys, ModDataRecord record, WikiModEntry entry)
        {
            // get unique update keys
            List <UpdateKey> updateKeys = this.GetUnfilteredUpdateKeys(specifiedKeys, record, entry)
                                          .Select(UpdateKey.Parse)
                                          .Distinct()
                                          .ToList();

            // apply remove overrides from wiki
            {
                var removeKeys = new HashSet <UpdateKey>(
                    from key in entry?.ChangeUpdateKeys ?? new string[0]
                    where key.StartsWith('-')
                    select UpdateKey.Parse(key.Substring(1))
                    );
                if (removeKeys.Any())
                {
                    updateKeys.RemoveAll(removeKeys.Contains);
                }
            }

            // if the list has both an update key (like "Nexus:2400") and subkey (like "Nexus:2400@subkey") for the same page, the subkey takes priority
            {
                var removeKeys = new HashSet <UpdateKey>();
                foreach (var key in updateKeys)
                {
                    if (key.Subkey != null)
                    {
                        removeKeys.Add(new UpdateKey(key.Site, key.ID, null));
                    }
                }
                if (removeKeys.Any())
                {
                    updateKeys.RemoveAll(removeKeys.Contains);
                }
            }

            return(updateKeys);
        }