summaryrefslogtreecommitdiff
path: root/src/SMAPI.Web/ViewModels/ModModel.cs
blob: 929bf682e1a2b9e0be8d87baa8773d16310331a2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using StardewModdingAPI.Toolkit.Framework.Clients.Wiki;

namespace StardewModdingAPI.Web.ViewModels
{
    /// <summary>Metadata about a mod.</summary>
    public class ModModel
    {
        /*********
        ** Accessors
        *********/
        /// <summary>The mod name.</summary>
        public string? Name { get; }

        /// <summary>The mod's alternative names, if any.</summary>
        public string AlternateNames { get; }

        /// <summary>The mod author's name.</summary>
        public string? Author { get; }

        /// <summary>The mod author's alternative names, if any.</summary>
        public string AlternateAuthors { get; }

        /// <summary>The GitHub repo, if any.</summary>
        public string? GitHubRepo { get; }

        /// <summary>The URL to the mod's source code, if any.</summary>
        public string? SourceUrl { get; }

        /// <summary>The compatibility status for the stable version of the game.</summary>
        public ModCompatibilityModel Compatibility { get; }

        /// <summary>The compatibility status for the beta version of the game.</summary>
        public ModCompatibilityModel? BetaCompatibility { get; }

        /// <summary>Links to the available mod pages.</summary>
        public ModLinkModel[] ModPages { get; }

        /// <summary>The human-readable warnings for players about this mod.</summary>
        public string[] Warnings { get; }

        /// <summary>The URL of the pull request which submits changes for an unofficial update to the author, if any.</summary>
        public string? PullRequestUrl { get; }

        /// <summary>Special notes intended for developers who maintain unofficial updates or submit pull requests.</summary>
        public string? DevNote { get; }

        /// <summary>A unique identifier for the mod that can be used in an anchor URL.</summary>
        public string? Slug { get; }

        /// <summary>The sites where the mod can be downloaded.</summary>
        public string[] ModPageSites => this.ModPages.Select(p => p.Text).ToArray();


        /*********
        ** Public methods
        *********/
        /// <summary>Construct an instance.</summary>
        /// <param name="name">The mod name.</param>
        /// <param name="alternateNames">The mod's alternative names, if any.</param>
        /// <param name="author">The mod author's name.</param>
        /// <param name="alternateAuthors">The mod author's alternative names, if any.</param>
        /// <param name="gitHubRepo">The GitHub repo, if any.</param>
        /// <param name="sourceUrl">The URL to the mod's source code, if any.</param>
        /// <param name="compatibility">The compatibility status for the stable version of the game.</param>
        /// <param name="betaCompatibility">The compatibility status for the beta version of the game.</param>
        /// <param name="modPages">Links to the available mod pages.</param>
        /// <param name="warnings">The human-readable warnings for players about this mod.</param>
        /// <param name="pullRequestUrl">The URL of the pull request which submits changes for an unofficial update to the author, if any.</param>
        /// <param name="devNote">Special notes intended for developers who maintain unofficial updates or submit pull requests.</param>
        /// <param name="slug">A unique identifier for the mod that can be used in an anchor URL.</param>
        [JsonConstructor]
        public ModModel(string? name, string alternateNames, string author, string alternateAuthors, string gitHubRepo, string sourceUrl, ModCompatibilityModel compatibility, ModCompatibilityModel betaCompatibility, ModLinkModel[] modPages, string[] warnings, string pullRequestUrl, string devNote, string slug)
        {
            this.Name = name;
            this.AlternateNames = alternateNames;
            this.Author = author;
            this.AlternateAuthors = alternateAuthors;
            this.GitHubRepo = gitHubRepo;
            this.SourceUrl = sourceUrl;
            this.Compatibility = compatibility;
            this.BetaCompatibility = betaCompatibility;
            this.ModPages = modPages;
            this.Warnings = warnings;
            this.PullRequestUrl = pullRequestUrl;
            this.DevNote = devNote;
            this.Slug = slug;
        }

        /// <summary>Construct an instance.</summary>
        /// <param name="entry">The mod metadata.</param>
        public ModModel(WikiModEntry entry)
        {
            // basic info
            this.Name = entry.Name.FirstOrDefault();
            this.AlternateNames = string.Join(", ", entry.Name.Skip(1).ToArray());
            this.Author = entry.Author.FirstOrDefault();
            this.AlternateAuthors = string.Join(", ", entry.Author.Skip(1).ToArray());
            this.GitHubRepo = entry.GitHubRepo;
            this.SourceUrl = this.GetSourceUrl(entry);
            this.Compatibility = new ModCompatibilityModel(entry.Compatibility);
            this.BetaCompatibility = entry.BetaCompatibility != null ? new ModCompatibilityModel(entry.BetaCompatibility) : null;
            this.ModPages = this.GetModPageUrls(entry).ToArray();
            this.Warnings = entry.Warnings;
            this.PullRequestUrl = entry.PullRequestUrl;
            this.DevNote = entry.DevNote;
            this.Slug = entry.Anchor;
        }


        /*********
        ** Private methods
        *********/
        /// <summary>Get the web URL for the mod's source code repository, if any.</summary>
        /// <param name="entry">The mod metadata.</param>
        private string? GetSourceUrl(WikiModEntry entry)
        {
            if (!string.IsNullOrWhiteSpace(entry.GitHubRepo))
                return $"https://github.com/{entry.GitHubRepo}";
            if (!string.IsNullOrWhiteSpace(entry.CustomSourceUrl))
                return entry.CustomSourceUrl;
            return null;
        }

        /// <summary>Get the web URLs for the mod pages, if any.</summary>
        /// <param name="entry">The mod metadata.</param>
        private IEnumerable<ModLinkModel> GetModPageUrls(WikiModEntry entry)
        {
            bool anyFound = false;

            // normal mod pages
            if (entry.NexusID.HasValue)
            {
                anyFound = true;
                yield return new ModLinkModel($"https://www.nexusmods.com/stardewvalley/mods/{entry.NexusID}", "Nexus");
            }
            if (entry.ModDropID.HasValue)
            {
                anyFound = true;
                yield return new ModLinkModel($"https://www.moddrop.com/stardew-valley/mod/{entry.ModDropID}", "ModDrop");
            }
            if (!string.IsNullOrWhiteSpace(entry.CurseForgeKey))
            {
                anyFound = true;
                yield return new ModLinkModel($"https://www.curseforge.com/stardewvalley/mods/{entry.CurseForgeKey}", "CurseForge");
            }
            if (entry.ChucklefishID.HasValue)
            {
                anyFound = true;
                yield return new ModLinkModel($"https://community.playstarbound.com/resources/{entry.ChucklefishID}", "Chucklefish");
            }

            // fallback
            if (!anyFound && !string.IsNullOrWhiteSpace(entry.CustomUrl))
            {
                anyFound = true;
                yield return new ModLinkModel(entry.CustomUrl, "custom");
            }
            if (!anyFound && !string.IsNullOrWhiteSpace(entry.GitHubRepo))
                yield return new ModLinkModel($"https://github.com/{entry.GitHubRepo}/releases", "GitHub");
        }
    }
}