Example #1
0
        /// <summary>Get update check info about a mod.</summary>
        /// <param name="id">The mod ID.</param>
        public async Task <IModPage> GetModData(string id)
        {
            IModPage page = new GenericModPage(this.SiteKey, id);

            // get ID
            if (!uint.TryParse(id, out uint parsedId))
            {
                return(page.SetError(RemoteModStatus.DoesNotExist, $"The value '{id}' isn't a valid CurseForge mod ID, must be an integer ID."));
            }

            // get raw data
            ModModel mod = await this.Client
                           .GetAsync($"addon/{parsedId}")
                           .As <ModModel>();

            if (mod == null)
            {
                return(page.SetError(RemoteModStatus.DoesNotExist, "Found no CurseForge mod with this ID."));
            }

            // get downloads
            List <IModDownload> downloads = new List <IModDownload>();

            foreach (ModFileModel file in mod.LatestFiles)
            {
                downloads.Add(
                    new GenericModDownload(name: file.DisplayName ?? file.FileName, description: null, version: this.GetRawVersion(file))
                    );
            }

            // return info
            return(page.SetInfo(name: mod.Name, version: null, url: mod.WebsiteUrl, downloads: downloads));
        }
Example #2
0
        /// <summary>Get update check info about a mod.</summary>
        /// <param name="id">The mod ID.</param>
        public async Task <IModPage> GetModData(string id)
        {
            IModPage page = new GenericModPage(this.SiteKey, id);

            if (!uint.TryParse(id, out uint parsedId))
            {
                return(page.SetError(RemoteModStatus.DoesNotExist, $"The value '{id}' isn't a valid Nexus mod ID, must be an integer ID."));
            }

            // Fetch from the Nexus website when possible, since it has no rate limits. Mods with
            // adult content are hidden for anonymous users, so fall back to the API in that case.
            // Note that the API has very restrictive rate limits which means we can't just use it
            // for all cases.
            NexusMod mod = await this.GetModFromWebsiteAsync(parsedId);

            if (mod?.Status == NexusModStatus.AdultContentForbidden)
            {
                mod = await this.GetModFromApiAsync(parsedId);
            }

            // page doesn't exist
            if (mod == null || mod.Status == NexusModStatus.Hidden || mod.Status == NexusModStatus.NotPublished)
            {
                return(page.SetError(RemoteModStatus.DoesNotExist, "Found no Nexus mod with this ID."));
            }

            // return info
            page.SetInfo(name: mod.Name, url: mod.Url, version: mod.Version, downloads: mod.Downloads);
            if (mod.Status != NexusModStatus.Ok)
            {
                page.SetError(RemoteModStatus.TemporaryError, mod.Error);
            }
            return(page);
        }
Example #3
0
        /// <summary>Get update check info about a mod.</summary>
        /// <param name="id">The mod ID.</param>
        public async Task <IModPage> GetModData(string id)
        {
            IModPage page = new GenericModPage(this.SiteKey, id);

            if (!id.Contains("/") || id.IndexOf("/", StringComparison.OrdinalIgnoreCase) != id.LastIndexOf("/", StringComparison.OrdinalIgnoreCase))
            {
                return(page.SetError(RemoteModStatus.DoesNotExist, $"The value '{id}' isn't a valid GitHub mod ID, must be a username and project name like 'Pathoschild/SMAPI'."));
            }

            // fetch repo info
            GitRepo repository = await this.GetRepositoryAsync(id);

            if (repository == null)
            {
                return(page.SetError(RemoteModStatus.DoesNotExist, "Found no GitHub repository for this ID."));
            }
            string name = repository.FullName;
            string url  = $"{repository.WebUrl}/releases";

            // get releases
            GitRelease latest;
            GitRelease preview;

            {
                // get latest release (whether preview or stable)
                latest = await this.GetLatestReleaseAsync(id, includePrerelease : true);

                if (latest == null)
                {
                    return(page.SetError(RemoteModStatus.DoesNotExist, "Found no GitHub release for this ID."));
                }

                // get stable version if different
                preview = null;
                if (latest.IsPrerelease)
                {
                    GitRelease release = await this.GetLatestReleaseAsync(id, includePrerelease : false);

                    if (release != null)
                    {
                        preview = latest;
                        latest  = release;
                    }
                }
            }

            // get downloads
            IModDownload[] downloads = new[] { latest, preview }
            .Where(release => release != null)
            .Select(release => (IModDownload) new GenericModDownload(release.Name, release.Body, release.Tag))
            .ToArray();

            // return info
            return(page.SetInfo(name: name, url: url, version: null, downloads: downloads));
        }
Example #4
0
        /// <summary>Get update check info about a mod.</summary>
        /// <param name="id">The mod ID.</param>
        public async Task <IModPage> GetModData(string id)
        {
            var page = new GenericModPage(this.SiteKey, id);

            if (!long.TryParse(id, out long parsedId))
            {
                return(page.SetError(RemoteModStatus.DoesNotExist, $"The value '{id}' isn't a valid ModDrop mod ID, must be an integer ID."));
            }

            // get raw data
            ModListModel response = await this.Client
                                    .PostAsync("")
                                    .WithBody(new
            {
                ModIDs = new[] { parsedId },
                Files  = true,
                Mods   = true
            })
                                    .As <ModListModel>();

            ModModel mod = response.Mods[parsedId];

            if (mod.Mod?.Title == null || mod.Mod.ErrorCode.HasValue)
            {
                return(null);
            }

            // get files
            var downloads = new List <IModDownload>();

            foreach (FileDataModel file in mod.Files)
            {
                if (file.IsOld || file.IsDeleted || file.IsHidden)
                {
                    continue;
                }

                downloads.Add(
                    new GenericModDownload(file.Name, file.Description, file.Version)
                    );
            }

            // return info
            string name = mod.Mod?.Title;
            string url  = string.Format(this.ModUrlFormat, id);

            return(page.SetInfo(name: name, version: null, url: url, downloads: downloads));
        }
Example #5
0
        /// <summary>Get update check info about a mod.</summary>
        /// <param name="id">The mod ID.</param>
        public async Task <IModPage> GetModData(string id)
        {
            IModPage page = new GenericModPage(this.SiteKey, id);

            // get mod ID
            if (!uint.TryParse(id, out uint parsedId))
            {
                return(page.SetError(RemoteModStatus.DoesNotExist, $"The value '{id}' isn't a valid Chucklefish mod ID, must be an integer ID."));
            }

            // fetch HTML
            string html;

            try
            {
                html = await this.Client
                       .GetAsync(string.Format(this.ModPageUrlFormat, parsedId))
                       .AsString();
            }
            catch (ApiException ex) when(ex.Status == HttpStatusCode.NotFound || ex.Status == HttpStatusCode.Forbidden)
            {
                return(page.SetError(RemoteModStatus.DoesNotExist, "Found no Chucklefish mod with this ID."));
            }
            var doc = new HtmlDocument();

            doc.LoadHtml(html);

            // extract mod info
            string url     = this.GetModUrl(parsedId);
            string version = doc.DocumentNode.SelectSingleNode("//h1/span")?.InnerText;
            string name    = doc.DocumentNode.SelectSingleNode("//h1").ChildNodes[0].InnerText.Trim();

            if (name.StartsWith("[SMAPI]"))
            {
                name = name.Substring("[SMAPI]".Length).TrimStart();
            }

            // return info
            return(page.SetInfo(name: name, version: version, url: url, downloads: Array.Empty <IModDownload>()));
        }
Example #6
0
        /// <summary>Get the mod info for an update key.</summary>
        /// <param name="updateKey">The namespaced update key.</param>
        public async Task <IModPage> GetModPageAsync(UpdateKey updateKey)
        {
            // get site
            if (!this.ModSites.TryGetValue(updateKey.Site, out IModSiteClient client))
            {
                return(new GenericModPage(updateKey.Site, updateKey.ID).SetError(RemoteModStatus.DoesNotExist, $"There's no mod site with key '{updateKey.Site}'. Expected one of [{string.Join(", ", this.ModSites.Keys)}]."));
            }

            // fetch mod
            IModPage mod;

            try
            {
                mod = await client.GetModData(updateKey.ID);
            }
            catch (Exception ex)
            {
                mod = new GenericModPage(updateKey.Site, updateKey.ID).SetError(RemoteModStatus.TemporaryError, ex.ToString());
            }

            // handle errors
            return(mod ?? new GenericModPage(updateKey.Site, updateKey.ID).SetError(RemoteModStatus.DoesNotExist, $"Found no {updateKey.Site} mod with ID '{updateKey.ID}'."));
        }