From 929dccb75a1405737975d76648e015a3e7c00177 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 7 Oct 2017 23:07:10 -0400 Subject: reorganise repo structure --- .../Framework/ConfigModels/ModUpdateCheckConfig.cs | 74 +++++++++++++++++ .../Framework/InternalControllerFeatureProvider.cs | 27 ++++++ .../Framework/ModRepositories/BaseRepository.cs | 51 ++++++++++++ .../ModRepositories/ChucklefishRepository.cs | 92 ++++++++++++++++++++ .../Framework/ModRepositories/GitHubRepository.cs | 97 ++++++++++++++++++++++ .../Framework/ModRepositories/IModRepository.cs | 24 ++++++ .../Framework/ModRepositories/NexusRepository.cs | 89 ++++++++++++++++++++ src/SMAPI.Web/Framework/RewriteSubdomainRule.cs | 30 +++++++ src/SMAPI.Web/Framework/VersionConstraint.cs | 15 ++++ 9 files changed, 499 insertions(+) create mode 100644 src/SMAPI.Web/Framework/ConfigModels/ModUpdateCheckConfig.cs create mode 100644 src/SMAPI.Web/Framework/InternalControllerFeatureProvider.cs create mode 100644 src/SMAPI.Web/Framework/ModRepositories/BaseRepository.cs create mode 100644 src/SMAPI.Web/Framework/ModRepositories/ChucklefishRepository.cs create mode 100644 src/SMAPI.Web/Framework/ModRepositories/GitHubRepository.cs create mode 100644 src/SMAPI.Web/Framework/ModRepositories/IModRepository.cs create mode 100644 src/SMAPI.Web/Framework/ModRepositories/NexusRepository.cs create mode 100644 src/SMAPI.Web/Framework/RewriteSubdomainRule.cs create mode 100644 src/SMAPI.Web/Framework/VersionConstraint.cs (limited to 'src/SMAPI.Web/Framework') diff --git a/src/SMAPI.Web/Framework/ConfigModels/ModUpdateCheckConfig.cs b/src/SMAPI.Web/Framework/ConfigModels/ModUpdateCheckConfig.cs new file mode 100644 index 00000000..03de639e --- /dev/null +++ b/src/SMAPI.Web/Framework/ConfigModels/ModUpdateCheckConfig.cs @@ -0,0 +1,74 @@ +namespace StardewModdingAPI.Web.Framework.ConfigModels +{ + /// The config settings for mod update checks. + public class ModUpdateCheckConfig + { + /********* + ** Accessors + *********/ + /**** + ** General + ****/ + /// The number of minutes update checks should be cached before refetching them. + public int CacheMinutes { get; set; } + + /// A regex which matches SMAPI-style semantic version. + /// Derived from SMAPI's SemanticVersion implementation. + public string SemanticVersionRegex { get; set; } + + /**** + ** Chucklefish mod site + ****/ + /// The repository key for the Chucklefish mod site. + public string ChucklefishKey { get; set; } + + /// The user agent for the Chucklefish API client, where {0} is the SMAPI version. + public string ChucklefishUserAgent { get; set; } + + /// The base URL for the Chucklefish mod site. + public string ChucklefishBaseUrl { get; set; } + + /// The URL for a mod page on the Chucklefish mod site excluding the , where {0} is the mod ID. + public string ChucklefishModPageUrlFormat { get; set; } + + + /**** + ** GitHub + ****/ + /// The repository key for Nexus Mods. + public string GitHubKey { get; set; } + + /// The user agent for the GitHub API client, where {0} is the SMAPI version. + public string GitHubUserAgent { get; set; } + + /// The base URL for the GitHub API. + public string GitHubBaseUrl { get; set; } + + /// The URL for a GitHub API latest-release query excluding the , where {0} is the organisation and project name. + public string GitHubReleaseUrlFormat { get; set; } + + /// The Accept header value expected by the GitHub API. + public string GitHubAcceptHeader { get; set; } + + /// The username with which to authenticate to the GitHub API (if any). + public string GitHubUsername { get; set; } + + /// The password with which to authenticate to the GitHub API (if any). + public string GitHubPassword { get; set; } + + /**** + ** Nexus Mods + ****/ + /// The repository key for Nexus Mods. + public string NexusKey { get; set; } + + /// The user agent for the Nexus Mods API client. + public string NexusUserAgent { get; set; } + + /// The base URL for the Nexus Mods API. + public string NexusBaseUrl { get; set; } + + /// The URL for a Nexus Mods API query excluding the , where {0} is the mod ID. + public string NexusModUrlFormat { get; set; } + } +} diff --git a/src/SMAPI.Web/Framework/InternalControllerFeatureProvider.cs b/src/SMAPI.Web/Framework/InternalControllerFeatureProvider.cs new file mode 100644 index 00000000..2c24c610 --- /dev/null +++ b/src/SMAPI.Web/Framework/InternalControllerFeatureProvider.cs @@ -0,0 +1,27 @@ +using System; +using System.Reflection; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Controllers; + +namespace StardewModdingAPI.Web.Framework +{ + /// Discovers controllers with support for non-public controllers. + internal class InternalControllerFeatureProvider : ControllerFeatureProvider + { + /********* + ** Public methods + *********/ + /// Determines if a given type is a controller. + /// The candidate. + /// true if the type is a controller; otherwise false. + protected override bool IsController(TypeInfo type) + { + return + type.IsClass + && !type.IsAbstract + && (/*type.IsPublic &&*/ !type.ContainsGenericParameters) + && (!type.IsDefined(typeof(NonControllerAttribute)) + && (type.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase) || type.IsDefined(typeof(ControllerAttribute)))); + } + } +} diff --git a/src/SMAPI.Web/Framework/ModRepositories/BaseRepository.cs b/src/SMAPI.Web/Framework/ModRepositories/BaseRepository.cs new file mode 100644 index 00000000..d98acd89 --- /dev/null +++ b/src/SMAPI.Web/Framework/ModRepositories/BaseRepository.cs @@ -0,0 +1,51 @@ +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using StardewModdingAPI.Models; + +namespace StardewModdingAPI.Web.Framework.ModRepositories +{ + internal abstract class RepositoryBase : IModRepository + { + /********* + ** Accessors + *********/ + /// The unique key for this vendor. + public string VendorKey { get; } + + + /********* + ** Public methods + *********/ + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + public abstract void Dispose(); + + /// Get metadata about a mod in the repository. + /// The mod ID in this repository. + public abstract Task GetModInfoAsync(string id); + + + /********* + ** Protected methods + *********/ + /// Construct an instance. + /// The unique key for this vendor. + protected RepositoryBase(string vendorKey) + { + this.VendorKey = vendorKey; + } + + /// Normalise a version string. + /// The version to normalise. + protected string NormaliseVersion(string version) + { + if (string.IsNullOrWhiteSpace(version)) + return null; + + version = version.Trim(); + if (Regex.IsMatch(version, @"^v\d", RegexOptions.CultureInvariant | RegexOptions.IgnoreCase)) // common version prefix + version = version.Substring(1); + + return version; + } + } +} diff --git a/src/SMAPI.Web/Framework/ModRepositories/ChucklefishRepository.cs b/src/SMAPI.Web/Framework/ModRepositories/ChucklefishRepository.cs new file mode 100644 index 00000000..ed7bd60b --- /dev/null +++ b/src/SMAPI.Web/Framework/ModRepositories/ChucklefishRepository.cs @@ -0,0 +1,92 @@ +using System; +using System.Net; +using System.Threading.Tasks; +using HtmlAgilityPack; +using Pathoschild.Http.Client; +using StardewModdingAPI.Models; + +namespace StardewModdingAPI.Web.Framework.ModRepositories +{ + /// An HTTP client for fetching mod metadata from the Chucklefish mod site. + internal class ChucklefishRepository : RepositoryBase + { + /********* + ** Properties + *********/ + /// The base URL for the Chucklefish mod site. + private readonly string BaseUrl; + + /// The URL for a mod page excluding the base URL, where {0} is the mod ID. + private readonly string ModPageUrlFormat; + + /// The underlying HTTP client. + private readonly IClient Client; + + + /********* + ** Public methods + *********/ + /// Construct an instance. + /// The unique key for this vendor. + /// The user agent for the API client. + /// The base URL for the Chucklefish mod site. + /// The URL for a mod page excluding the , where {0} is the mod ID. + public ChucklefishRepository(string vendorKey, string userAgent, string baseUrl, string modPageUrlFormat) + : base(vendorKey) + { + this.BaseUrl = baseUrl; + this.ModPageUrlFormat = modPageUrlFormat; + this.Client = new FluentClient(baseUrl).SetUserAgent(userAgent); + } + + /// Get metadata about a mod in the repository. + /// The mod ID in this repository. + public override async Task GetModInfoAsync(string id) + { + // validate ID format + if (!uint.TryParse(id, out uint _)) + return new ModInfoModel($"The value '{id}' isn't a valid Chucklefish mod ID, must be an integer ID."); + + // fetch info + try + { + // fetch HTML + string html; + try + { + html = await this.Client + .GetAsync(string.Format(this.ModPageUrlFormat, id)) + .AsString(); + } + catch (ApiException ex) when (ex.Status == HttpStatusCode.NotFound) + { + return new ModInfoModel("Found no mod with this ID."); + } + + // parse HTML + var doc = new HtmlDocument(); + doc.LoadHtml(html); + + // extract mod info + string url = new UriBuilder(new Uri(this.BaseUrl)) { Path = string.Format(this.ModPageUrlFormat, id) }.Uri.ToString(); + string name = doc.DocumentNode.SelectSingleNode("//meta[@name='twitter:title']").Attributes["content"].Value; + if (name.StartsWith("[SMAPI] ")) + name = name.Substring("[SMAPI] ".Length); + string version = doc.DocumentNode.SelectSingleNode("//h1/span").InnerText; + + // create model + return new ModInfoModel(name, this.NormaliseVersion(version), url); + } + catch (Exception ex) + { + return new ModInfoModel(ex.ToString()); + } + } + + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + public override void Dispose() + { + this.Client.Dispose(); + } + } +} diff --git a/src/SMAPI.Web/Framework/ModRepositories/GitHubRepository.cs b/src/SMAPI.Web/Framework/ModRepositories/GitHubRepository.cs new file mode 100644 index 00000000..174fb79a --- /dev/null +++ b/src/SMAPI.Web/Framework/ModRepositories/GitHubRepository.cs @@ -0,0 +1,97 @@ +using System; +using System.Net; +using System.Threading.Tasks; +using Newtonsoft.Json; +using Pathoschild.Http.Client; +using StardewModdingAPI.Models; + +namespace StardewModdingAPI.Web.Framework.ModRepositories +{ + /// An HTTP client for fetching mod metadata from GitHub project releases. + internal class GitHubRepository : RepositoryBase + { + /********* + ** Properties + *********/ + /// The URL for a Nexus Mods API query excluding the base URL, where {0} is the mod ID. + private readonly string ReleaseUrlFormat; + + /// The underlying HTTP client. + private readonly IClient Client; + + + /********* + ** Public methods + *********/ + /// Construct an instance. + /// The unique key for this vendor. + /// The base URL for the Nexus Mods API. + /// The URL for a Nexus Mods API query excluding the , where {0} is the mod ID. + /// The user agent for the API client. + /// The Accept header value expected by the GitHub API. + /// The username with which to authenticate to the GitHub API. + /// The password with which to authenticate to the GitHub API. + public GitHubRepository(string vendorKey, string baseUrl, string releaseUrlFormat, string userAgent, string acceptHeader, string username, string password) + : base(vendorKey) + { + this.ReleaseUrlFormat = releaseUrlFormat; + + this.Client = new FluentClient(baseUrl) + .SetUserAgent(userAgent) + .AddDefault(req => req.WithHeader("Accept", acceptHeader)); + if (!string.IsNullOrWhiteSpace(username)) + this.Client = this.Client.SetBasicAuthentication(username, password); + } + + /// Get metadata about a mod in the repository. + /// The mod ID in this repository. + public override async Task GetModInfoAsync(string id) + { + // validate ID format + if (!id.Contains("/") || id.IndexOf("/", StringComparison.InvariantCultureIgnoreCase) != id.LastIndexOf("/", StringComparison.InvariantCultureIgnoreCase)) + return new ModInfoModel($"The value '{id}' isn't a valid GitHub mod ID, must be a username and project name like 'Pathoschild/LookupAnything'."); + + // fetch info + try + { + GitRelease release = await this.Client + .GetAsync(string.Format(this.ReleaseUrlFormat, id)) + .As(); + return new ModInfoModel(id, this.NormaliseVersion(release.Tag), $"https://github.com/{id}/releases"); + } + catch (ApiException ex) when (ex.Status == HttpStatusCode.NotFound) + { + return new ModInfoModel("Found no mod with this ID."); + } + catch (Exception ex) + { + return new ModInfoModel(ex.ToString()); + } + } + + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + public override void Dispose() + { + this.Client.Dispose(); + } + + + /********* + ** Private models + *********/ + /// Metadata about a GitHub release tag. + private class GitRelease + { + /********* + ** Accessors + *********/ + /// The display name. + [JsonProperty("name")] + public string Name { get; set; } + + /// The semantic version string. + [JsonProperty("tag_name")] + public string Tag { get; set; } + } + } +} diff --git a/src/SMAPI.Web/Framework/ModRepositories/IModRepository.cs b/src/SMAPI.Web/Framework/ModRepositories/IModRepository.cs new file mode 100644 index 00000000..98e4c957 --- /dev/null +++ b/src/SMAPI.Web/Framework/ModRepositories/IModRepository.cs @@ -0,0 +1,24 @@ +using System; +using System.Threading.Tasks; +using StardewModdingAPI.Models; + +namespace StardewModdingAPI.Web.Framework.ModRepositories +{ + /// A repository which provides mod metadata. + internal interface IModRepository : IDisposable + { + /********* + ** Accessors + *********/ + /// The unique key for this vendor. + string VendorKey { get; } + + + /********* + ** Public methods + *********/ + /// Get metadata about a mod in the repository. + /// The mod ID in this repository. + Task GetModInfoAsync(string id); + } +} diff --git a/src/SMAPI.Web/Framework/ModRepositories/NexusRepository.cs b/src/SMAPI.Web/Framework/ModRepositories/NexusRepository.cs new file mode 100644 index 00000000..71970bec --- /dev/null +++ b/src/SMAPI.Web/Framework/ModRepositories/NexusRepository.cs @@ -0,0 +1,89 @@ +using System; +using System.Threading.Tasks; +using Newtonsoft.Json; +using Pathoschild.Http.Client; +using StardewModdingAPI.Models; + +namespace StardewModdingAPI.Web.Framework.ModRepositories +{ + /// An HTTP client for fetching mod metadata from Nexus Mods. + internal class NexusRepository : RepositoryBase + { + /********* + ** Properties + *********/ + /// The URL for a Nexus Mods API query excluding the base URL, where {0} is the mod ID. + private readonly string ModUrlFormat; + + /// The underlying HTTP client. + private readonly IClient Client; + + + /********* + ** Public methods + *********/ + /// Construct an instance. + /// The unique key for this vendor. + /// The user agent for the Nexus Mods API client. + /// The base URL for the Nexus Mods API. + /// The URL for a Nexus Mods API query excluding the , where {0} is the mod ID. + public NexusRepository(string vendorKey, string userAgent, string baseUrl, string modUrlFormat) + : base(vendorKey) + { + this.ModUrlFormat = modUrlFormat; + this.Client = new FluentClient(baseUrl).SetUserAgent(userAgent); + } + + /// Get metadata about a mod in the repository. + /// The mod ID in this repository. + public override async Task GetModInfoAsync(string id) + { + // validate ID format + if (!uint.TryParse(id, out uint _)) + return new ModInfoModel($"The value '{id}' isn't a valid Nexus mod ID, must be an integer ID."); + + // fetch info + try + { + NexusResponseModel response = await this.Client + .GetAsync(string.Format(this.ModUrlFormat, id)) + .As(); + + return response != null + ? new ModInfoModel(response.Name, this.NormaliseVersion(response.Version), response.Url) + : new ModInfoModel("Found no mod with this ID."); + } + catch (Exception ex) + { + return new ModInfoModel(ex.ToString()); + } + } + + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + public override void Dispose() + { + this.Client.Dispose(); + } + + + /********* + ** Private models + *********/ + /// A mod metadata response from Nexus Mods. + private class NexusResponseModel + { + /********* + ** Accessors + *********/ + /// The mod name. + public string Name { get; set; } + + /// The mod's semantic version number. + public string Version { get; set; } + + /// The mod's web URL. + [JsonProperty("mod_page_uri")] + public string Url { get; set; } + } + } +} diff --git a/src/SMAPI.Web/Framework/RewriteSubdomainRule.cs b/src/SMAPI.Web/Framework/RewriteSubdomainRule.cs new file mode 100644 index 00000000..5a56844f --- /dev/null +++ b/src/SMAPI.Web/Framework/RewriteSubdomainRule.cs @@ -0,0 +1,30 @@ +using System; +using Microsoft.AspNetCore.Rewrite; + +namespace StardewModdingAPI.Web.Framework +{ + /// Rewrite requests to prepend the subdomain portion (if any) to the path. + /// Derived from . + internal class RewriteSubdomainRule : IRule + { + /// Applies the rule. Implementations of ApplyRule should set the value for (defaults to RuleResult.ContinueRules). + /// The rewrite context. + public void ApplyRule(RewriteContext context) + { + context.Result = RuleResult.ContinueRules; + + // get host parts + string host = context.HttpContext.Request.Host.Host; + string[] parts = host.Split('.'); + + // validate + if (parts.Length < 2) + return; + if (parts.Length < 3 && !"localhost".Equals(parts[1], StringComparison.InvariantCultureIgnoreCase)) + return; + + // prepend to path + context.HttpContext.Request.Path = $"/{parts[0]}{context.HttpContext.Request.Path}"; + } + } +} diff --git a/src/SMAPI.Web/Framework/VersionConstraint.cs b/src/SMAPI.Web/Framework/VersionConstraint.cs new file mode 100644 index 00000000..be9c0918 --- /dev/null +++ b/src/SMAPI.Web/Framework/VersionConstraint.cs @@ -0,0 +1,15 @@ +using Microsoft.AspNetCore.Routing.Constraints; + +namespace StardewModdingAPI.Web.Framework +{ + /// Constrains a route value to a valid semantic version. + internal class VersionConstraint : RegexRouteConstraint + { + /********* + ** Public methods + *********/ + /// Construct an instance. + public VersionConstraint() + : base(@"^v(?>(?0|[1-9]\d*))\.(?>(?0|[1-9]\d*))(?>(?:\.(?0|[1-9]\d*))?)(?:-(?(?>[a-z0-9]+[\-\.]?)+))?$") { } + } +} -- cgit From b7fb188513a844afed66b9b292ecfddb58528a42 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 7 Oct 2017 23:57:47 -0400 Subject: rename shared project for broader use --- src/SMAPI.Common/Models/ModInfoModel.cs | 48 ++++++++++++++++++++++ src/SMAPI.Common/Models/ModSeachModel.cs | 30 ++++++++++++++ .../StardewModdingAPI.Common.projitems | 18 ++++++++ src/SMAPI.Common/StardewModdingAPI.Common.shproj | 13 ++++++ src/SMAPI.Models/ModInfoModel.cs | 48 ---------------------- src/SMAPI.Models/ModSeachModel.cs | 30 -------------- .../StardewModdingAPI.Models.projitems | 15 ------- src/SMAPI.Models/StardewModdingAPI.Models.shproj | 13 ------ src/SMAPI.Web/Controllers/ModsController.cs | 2 +- .../Framework/ModRepositories/BaseRepository.cs | 2 +- .../ModRepositories/ChucklefishRepository.cs | 2 +- .../Framework/ModRepositories/GitHubRepository.cs | 2 +- .../Framework/ModRepositories/IModRepository.cs | 2 +- .../Framework/ModRepositories/NexusRepository.cs | 2 +- src/SMAPI.Web/StardewModdingAPI.Web.csproj | 2 +- src/SMAPI.sln | 6 +-- src/SMAPI/Framework/WebApiClient.cs | 2 +- src/SMAPI/Program.cs | 2 +- src/SMAPI/StardewModdingAPI.csproj | 2 +- 19 files changed, 122 insertions(+), 119 deletions(-) create mode 100644 src/SMAPI.Common/Models/ModInfoModel.cs create mode 100644 src/SMAPI.Common/Models/ModSeachModel.cs create mode 100644 src/SMAPI.Common/StardewModdingAPI.Common.projitems create mode 100644 src/SMAPI.Common/StardewModdingAPI.Common.shproj delete mode 100644 src/SMAPI.Models/ModInfoModel.cs delete mode 100644 src/SMAPI.Models/ModSeachModel.cs delete mode 100644 src/SMAPI.Models/StardewModdingAPI.Models.projitems delete mode 100644 src/SMAPI.Models/StardewModdingAPI.Models.shproj (limited to 'src/SMAPI.Web/Framework') diff --git a/src/SMAPI.Common/Models/ModInfoModel.cs b/src/SMAPI.Common/Models/ModInfoModel.cs new file mode 100644 index 00000000..e071c0bb --- /dev/null +++ b/src/SMAPI.Common/Models/ModInfoModel.cs @@ -0,0 +1,48 @@ +using Newtonsoft.Json; + +namespace StardewModdingAPI.Common.Models +{ + /// Generic metadata about a mod. + internal class ModInfoModel + { + /********* + ** Accessors + *********/ + /// The mod name. + public string Name { get; } + + /// The mod's semantic version number. + public string Version { get; } + + /// The mod's web URL. + public string Url { get; } + + /// The error message indicating why the mod is invalid (if applicable). + public string Error { get; } + + + /********* + ** Public methods + *********/ + /// Construct a valid instance. + /// The mod name. + /// The mod's semantic version number. + /// The mod's web URL. + /// The error message indicating why the mod is invalid (if applicable). + [JsonConstructor] + public ModInfoModel(string name, string version, string url, string error = null) + { + this.Name = name; + this.Version = version; + this.Url = url; + this.Error = error; // mainly initialised here for the JSON deserialiser + } + + /// Construct an valid instance. + /// The error message indicating why the mod is invalid. + public ModInfoModel(string error) + { + this.Error = error; + } + } +} diff --git a/src/SMAPI.Common/Models/ModSeachModel.cs b/src/SMAPI.Common/Models/ModSeachModel.cs new file mode 100644 index 00000000..3f69f0ae --- /dev/null +++ b/src/SMAPI.Common/Models/ModSeachModel.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; +using System.Linq; + +namespace StardewModdingAPI.Common.Models +{ + /// Specifies mods whose update-check info to fetch. + internal class ModSearchModel + { + /********* + ** Accessors + *********/ + /// The namespaced mod keys to search. + public string[] ModKeys { get; set; } + + + /********* + ** Public methods + *********/ + /// Construct an empty instance. + /// This constructed is needed for JSON deserialisation. + public ModSearchModel() { } + + /// Construct an valid instance. + /// The namespaced mod keys to search. + public ModSearchModel(IEnumerable modKeys) + { + this.ModKeys = modKeys.ToArray(); + } + } +} diff --git a/src/SMAPI.Common/StardewModdingAPI.Common.projitems b/src/SMAPI.Common/StardewModdingAPI.Common.projitems new file mode 100644 index 00000000..b3296570 --- /dev/null +++ b/src/SMAPI.Common/StardewModdingAPI.Common.projitems @@ -0,0 +1,18 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + true + 2aa02fb6-ff03-41cf-a215-2ee60ab4f5dc + + + StardewModdingAPI.Common + + + + + + + + + \ No newline at end of file diff --git a/src/SMAPI.Common/StardewModdingAPI.Common.shproj b/src/SMAPI.Common/StardewModdingAPI.Common.shproj new file mode 100644 index 00000000..0ef29144 --- /dev/null +++ b/src/SMAPI.Common/StardewModdingAPI.Common.shproj @@ -0,0 +1,13 @@ + + + + 2aa02fb6-ff03-41cf-a215-2ee60ab4f5dc + 14.0 + + + + + + + + diff --git a/src/SMAPI.Models/ModInfoModel.cs b/src/SMAPI.Models/ModInfoModel.cs deleted file mode 100644 index 44071230..00000000 --- a/src/SMAPI.Models/ModInfoModel.cs +++ /dev/null @@ -1,48 +0,0 @@ -using Newtonsoft.Json; - -namespace StardewModdingAPI.Models -{ - /// Generic metadata about a mod. - internal class ModInfoModel - { - /********* - ** Accessors - *********/ - /// The mod name. - public string Name { get; } - - /// The mod's semantic version number. - public string Version { get; } - - /// The mod's web URL. - public string Url { get; } - - /// The error message indicating why the mod is invalid (if applicable). - public string Error { get; } - - - /********* - ** Public methods - *********/ - /// Construct a valid instance. - /// The mod name. - /// The mod's semantic version number. - /// The mod's web URL. - /// The error message indicating why the mod is invalid (if applicable). - [JsonConstructor] - public ModInfoModel(string name, string version, string url, string error = null) - { - this.Name = name; - this.Version = version; - this.Url = url; - this.Error = error; // mainly initialised here for the JSON deserialiser - } - - /// Construct an valid instance. - /// The error message indicating why the mod is invalid. - public ModInfoModel(string error) - { - this.Error = error; - } - } -} diff --git a/src/SMAPI.Models/ModSeachModel.cs b/src/SMAPI.Models/ModSeachModel.cs deleted file mode 100644 index 526fbaf3..00000000 --- a/src/SMAPI.Models/ModSeachModel.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Collections.Generic; -using System.Linq; - -namespace StardewModdingAPI.Models -{ - /// Specifies mods whose update-check info to fetch. - internal class ModSearchModel - { - /********* - ** Accessors - *********/ - /// The namespaced mod keys to search. - public string[] ModKeys { get; set; } - - - /********* - ** Public methods - *********/ - /// Construct an empty instance. - /// This constructed is needed for JSON deserialisation. - public ModSearchModel() { } - - /// Construct an valid instance. - /// The namespaced mod keys to search. - public ModSearchModel(IEnumerable modKeys) - { - this.ModKeys = modKeys.ToArray(); - } - } -} diff --git a/src/SMAPI.Models/StardewModdingAPI.Models.projitems b/src/SMAPI.Models/StardewModdingAPI.Models.projitems deleted file mode 100644 index e2cb29e1..00000000 --- a/src/SMAPI.Models/StardewModdingAPI.Models.projitems +++ /dev/null @@ -1,15 +0,0 @@ - - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - true - 2aa02fb6-ff03-41cf-a215-2ee60ab4f5dc - - - StardewModdingAPI.Models - - - - - - \ No newline at end of file diff --git a/src/SMAPI.Models/StardewModdingAPI.Models.shproj b/src/SMAPI.Models/StardewModdingAPI.Models.shproj deleted file mode 100644 index c80517af..00000000 --- a/src/SMAPI.Models/StardewModdingAPI.Models.shproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - 2aa02fb6-ff03-41cf-a215-2ee60ab4f5dc - 14.0 - - - - - - - - diff --git a/src/SMAPI.Web/Controllers/ModsController.cs b/src/SMAPI.Web/Controllers/ModsController.cs index 7dcfcf13..a671ddca 100644 --- a/src/SMAPI.Web/Controllers/ModsController.cs +++ b/src/SMAPI.Web/Controllers/ModsController.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Options; -using StardewModdingAPI.Models; +using StardewModdingAPI.Common.Models; using StardewModdingAPI.Web.Framework.ConfigModels; using StardewModdingAPI.Web.Framework.ModRepositories; diff --git a/src/SMAPI.Web/Framework/ModRepositories/BaseRepository.cs b/src/SMAPI.Web/Framework/ModRepositories/BaseRepository.cs index d98acd89..edb00454 100644 --- a/src/SMAPI.Web/Framework/ModRepositories/BaseRepository.cs +++ b/src/SMAPI.Web/Framework/ModRepositories/BaseRepository.cs @@ -1,6 +1,6 @@ using System.Text.RegularExpressions; using System.Threading.Tasks; -using StardewModdingAPI.Models; +using StardewModdingAPI.Common.Models; namespace StardewModdingAPI.Web.Framework.ModRepositories { diff --git a/src/SMAPI.Web/Framework/ModRepositories/ChucklefishRepository.cs b/src/SMAPI.Web/Framework/ModRepositories/ChucklefishRepository.cs index ed7bd60b..06ec58ed 100644 --- a/src/SMAPI.Web/Framework/ModRepositories/ChucklefishRepository.cs +++ b/src/SMAPI.Web/Framework/ModRepositories/ChucklefishRepository.cs @@ -3,7 +3,7 @@ using System.Net; using System.Threading.Tasks; using HtmlAgilityPack; using Pathoschild.Http.Client; -using StardewModdingAPI.Models; +using StardewModdingAPI.Common.Models; namespace StardewModdingAPI.Web.Framework.ModRepositories { diff --git a/src/SMAPI.Web/Framework/ModRepositories/GitHubRepository.cs b/src/SMAPI.Web/Framework/ModRepositories/GitHubRepository.cs index 174fb79a..9d43adf0 100644 --- a/src/SMAPI.Web/Framework/ModRepositories/GitHubRepository.cs +++ b/src/SMAPI.Web/Framework/ModRepositories/GitHubRepository.cs @@ -3,7 +3,7 @@ using System.Net; using System.Threading.Tasks; using Newtonsoft.Json; using Pathoschild.Http.Client; -using StardewModdingAPI.Models; +using StardewModdingAPI.Common.Models; namespace StardewModdingAPI.Web.Framework.ModRepositories { diff --git a/src/SMAPI.Web/Framework/ModRepositories/IModRepository.cs b/src/SMAPI.Web/Framework/ModRepositories/IModRepository.cs index 98e4c957..4496400c 100644 --- a/src/SMAPI.Web/Framework/ModRepositories/IModRepository.cs +++ b/src/SMAPI.Web/Framework/ModRepositories/IModRepository.cs @@ -1,6 +1,6 @@ using System; using System.Threading.Tasks; -using StardewModdingAPI.Models; +using StardewModdingAPI.Common.Models; namespace StardewModdingAPI.Web.Framework.ModRepositories { diff --git a/src/SMAPI.Web/Framework/ModRepositories/NexusRepository.cs b/src/SMAPI.Web/Framework/ModRepositories/NexusRepository.cs index 71970bec..8a4bb0d8 100644 --- a/src/SMAPI.Web/Framework/ModRepositories/NexusRepository.cs +++ b/src/SMAPI.Web/Framework/ModRepositories/NexusRepository.cs @@ -2,7 +2,7 @@ using System; using System.Threading.Tasks; using Newtonsoft.Json; using Pathoschild.Http.Client; -using StardewModdingAPI.Models; +using StardewModdingAPI.Common.Models; namespace StardewModdingAPI.Web.Framework.ModRepositories { diff --git a/src/SMAPI.Web/StardewModdingAPI.Web.csproj b/src/SMAPI.Web/StardewModdingAPI.Web.csproj index 6b1d0687..ec1311f4 100644 --- a/src/SMAPI.Web/StardewModdingAPI.Web.csproj +++ b/src/SMAPI.Web/StardewModdingAPI.Web.csproj @@ -21,6 +21,6 @@ - + diff --git a/src/SMAPI.sln b/src/SMAPI.sln index fcb805a7..7941394d 100644 --- a/src/SMAPI.sln +++ b/src/SMAPI.sln @@ -29,7 +29,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StardewModdingAPI.Web", "SM EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Internal", "Internal", "{82D22ED7-A0A7-4D64-8E92-4B6A5E74ED11}" EndProject -Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "StardewModdingAPI.Models", "SMAPI.Models\StardewModdingAPI.Models.shproj", "{2AA02FB6-FF03-41CF-A215-2EE60AB4F5DC}" +Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "StardewModdingAPI.Common", "SMAPI.Common\StardewModdingAPI.Common.shproj", "{2AA02FB6-FF03-41CF-A215-2EE60AB4F5DC}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{EB35A917-67B9-4EFA-8DFC-4FB49B3949BB}" ProjectSection(SolutionItems) = preProject @@ -47,8 +47,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{09CF91E5 EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution - SMAPI.Models\StardewModdingAPI.Models.projitems*{2aa02fb6-ff03-41cf-a215-2ee60ab4f5dc}*SharedItemsImports = 13 - SMAPI.Models\StardewModdingAPI.Models.projitems*{f1a573b0-f436-472c-ae29-0b91ea6b9f8f}*SharedItemsImports = 4 + SMAPI.Common\StardewModdingAPI.Common.projitems*{2aa02fb6-ff03-41cf-a215-2ee60ab4f5dc}*SharedItemsImports = 13 + SMAPI.Common\StardewModdingAPI.Common.projitems*{f1a573b0-f436-472c-ae29-0b91ea6b9f8f}*SharedItemsImports = 4 EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/src/SMAPI/Framework/WebApiClient.cs b/src/SMAPI/Framework/WebApiClient.cs index f3c7de28..e78ac14b 100644 --- a/src/SMAPI/Framework/WebApiClient.cs +++ b/src/SMAPI/Framework/WebApiClient.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; using System.Net; using Newtonsoft.Json; -using StardewModdingAPI.Models; +using StardewModdingAPI.Common.Models; namespace StardewModdingAPI.Framework { diff --git a/src/SMAPI/Program.cs b/src/SMAPI/Program.cs index 7dfdc745..293c9da7 100644 --- a/src/SMAPI/Program.cs +++ b/src/SMAPI/Program.cs @@ -12,6 +12,7 @@ using System.Management; using System.Windows.Forms; #endif using Newtonsoft.Json; +using StardewModdingAPI.Common.Models; using StardewModdingAPI.Events; using StardewModdingAPI.Framework; using StardewModdingAPI.Framework.Exceptions; @@ -21,7 +22,6 @@ using StardewModdingAPI.Framework.ModHelpers; using StardewModdingAPI.Framework.ModLoading; using StardewModdingAPI.Framework.Reflection; using StardewModdingAPI.Framework.Serialisation; -using StardewModdingAPI.Models; using StardewValley; using Monitor = StardewModdingAPI.Framework.Monitor; using SObject = StardewValley.Object; diff --git a/src/SMAPI/StardewModdingAPI.csproj b/src/SMAPI/StardewModdingAPI.csproj index c6ff75d1..35a784cd 100644 --- a/src/SMAPI/StardewModdingAPI.csproj +++ b/src/SMAPI/StardewModdingAPI.csproj @@ -265,7 +265,7 @@ false - + {10db0676-9fc1-4771-a2c8-e2519f091e49} -- cgit From 24428d440592b388e8fcfdd87d953b2162eb1af5 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 8 Oct 2017 00:11:50 -0400 Subject: fix duplicate semver regex --- src/SMAPI.Common/SemanticVersionImpl.cs | 23 +++++++++-------------- src/SMAPI.Web/Framework/VersionConstraint.cs | 3 ++- 2 files changed, 11 insertions(+), 15 deletions(-) (limited to 'src/SMAPI.Web/Framework') diff --git a/src/SMAPI.Common/SemanticVersionImpl.cs b/src/SMAPI.Common/SemanticVersionImpl.cs index c257aaaf..e0f68a7e 100644 --- a/src/SMAPI.Common/SemanticVersionImpl.cs +++ b/src/SMAPI.Common/SemanticVersionImpl.cs @@ -8,20 +8,6 @@ namespace StardewModdingAPI.Common /// The implementation is defined by Semantic Version 2.0 (http://semver.org/). internal class SemanticVersionImpl { - /********* - ** Properties - *********/ - /// A regular expression matching a semantic version string. - /// - /// This pattern is derived from the BNF documentation in the semver repo, - /// with three important deviations intended to support Stardew Valley mod conventions: - /// - allows short-form "x.y" versions; - /// - allows hyphens in prerelease tags as synonyms for dots (like "-unofficial-update.3"); - /// - doesn't allow '+build' suffixes. - /// - private static readonly Regex Regex = new Regex(@"^(?>(?0|[1-9]\d*))\.(?>(?0|[1-9]\d*))(?>(?:\.(?0|[1-9]\d*))?)(?:-(?(?>[a-z0-9]+[\-\.]?)+))?$", RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.ExplicitCapture); - - /********* ** Accessors *********/ @@ -37,6 +23,15 @@ namespace StardewModdingAPI.Common /// An optional prerelease tag. public string Tag { get; } + /// A regular expression matching a semantic version string. + /// + /// This pattern is derived from the BNF documentation in the semver repo, + /// with three important deviations intended to support Stardew Valley mod conventions: + /// - allows short-form "x.y" versions; + /// - allows hyphens in prerelease tags as synonyms for dots (like "-unofficial-update.3"); + /// - doesn't allow '+build' suffixes. + /// + internal static readonly Regex Regex = new Regex(@"^(?>(?0|[1-9]\d*))\.(?>(?0|[1-9]\d*))(?>(?:\.(?0|[1-9]\d*))?)(?:-(?(?>[a-z0-9]+[\-\.]?)+))?$", RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.ExplicitCapture); /********* ** Public methods diff --git a/src/SMAPI.Web/Framework/VersionConstraint.cs b/src/SMAPI.Web/Framework/VersionConstraint.cs index be9c0918..cffb1092 100644 --- a/src/SMAPI.Web/Framework/VersionConstraint.cs +++ b/src/SMAPI.Web/Framework/VersionConstraint.cs @@ -1,4 +1,5 @@ using Microsoft.AspNetCore.Routing.Constraints; +using StardewModdingAPI.Common; namespace StardewModdingAPI.Web.Framework { @@ -10,6 +11,6 @@ namespace StardewModdingAPI.Web.Framework *********/ /// Construct an instance. public VersionConstraint() - : base(@"^v(?>(?0|[1-9]\d*))\.(?>(?0|[1-9]\d*))(?>(?:\.(?0|[1-9]\d*))?)(?:-(?(?>[a-z0-9]+[\-\.]?)+))?$") { } + : base(SemanticVersionImpl.Regex) { } } } -- cgit