diff options
72 files changed, 917 insertions, 647 deletions
diff --git a/docs/release-notes.md b/docs/release-notes.md index de4684ec..e133a45c 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -2,6 +2,14 @@ # Release notes ## Upcoming released +* For players: + * Mod warnings are now listed alphabetically. + +* For the web UI: + * Updated web framework to improve site performance and reliability. + * Added GitHub licenses to mod compatibility list. + * Internal changes to improve performance and reliability. + * For modders: * Added `Multiplayer.PeerConnected` event. * Migrated to Harmony 2.0 (see [_migrate to Harmony 2.0_](https://stardewvalleywiki.com/Modding:Migrate_to_Harmony_2.0) for more info). @@ -9,8 +17,13 @@ * Improved mod rewriting for compatibility: * Fixed rewriting types in custom attributes. * Fixed rewriting generic types to method references. + * Simplified paranoid warnings in the log and reduced their log level. * Fixed asset propagation for Gil's portraits. +* For SMAPI developers: + * When deploying web services to a single-instance app, the MongoDB server can now be replaced with in-memory storage. + * Merged the separate legacy redirects app on AWS into the main app on Azure. + ## 3.5 Released 27 April 2020 for Stardew Valley 1.4.1 or later. diff --git a/docs/technical/web.md b/docs/technical/web.md index 67e86c8b..ef591aee 100644 --- a/docs/technical/web.md +++ b/docs/technical/web.md @@ -340,9 +340,20 @@ short url | → | target page A local environment lets you run a complete copy of the web project (including cache database) on your machine, with no external dependencies aside from the actual mod sites. -1. Enter the Nexus credentials in `appsettings.Development.json` . You can leave the other - credentials empty to default to fetching data anonymously, and storing data in-memory and - on disk. +1. Edit `appsettings.Development.json` and set these options: + + property name | description + ------------- | ----------- + `NexusApiKey` | [Your Nexus API key](https://www.nexusmods.com/users/myaccount?tab=api#personal_key). + + Optional settings: + + property name | description + --------------------------- | ----------- + `AzureBlobConnectionString` | The connection string for the Azure Blob storage account. Defaults to using the system's temporary file folder if not specified. + `GitHubUsername`<br />`GitHubPassword` | The GitHub credentials with which to query GitHub release info. Defaults to anonymous requests if not specified. + `Storage` | How to storage cached wiki/mod data. `InMemory` is recommended in most cases, or `MongoInMemory` to test the MongoDB storage code. See [production environment](#production-environment) for more info on `Mongo`. + 2. Launch `SMAPI.Web` from Visual Studio to run a local version of the site. ### Production environment @@ -355,19 +366,15 @@ accordingly. Initial setup: -1. Launch an empty MongoDB server (e.g. using [MongoDB Atlas](https://www.mongodb.com/cloud/atlas)) - for mod data. -2. Create an Azure Blob storage account for uploaded files. -3. Create an Azure App Services environment running the latest .NET Core on Linux or Windows. -4. Add these application settings in the new App Services environment: +1. Create an Azure Blob storage account for uploaded files. +2. Create an Azure App Services environment running the latest .NET Core on Linux or Windows. +3. Add these application settings in the new App Services environment: property name | description ------------------------------- | ----------------- `ApiClients.AzureBlobConnectionString` | The connection string for the Azure Blob storage account created in step 2. `ApiClients.GitHubUsername`<br />`ApiClients.GitHubPassword` | The login credentials for the GitHub account with which to fetch release info. If these are omitted, GitHub will impose much stricter rate limits. `ApiClients:NexusApiKey` | The [Nexus API authentication key](https://github.com/Pathoschild/FluentNexus#init-a-client). - `MongoDB:ConnectionString` | The connection string for the MongoDB instance. - `MongoDB:Database` | The MongoDB database name (e.g. `smapi` in production or `smapi-edge` in testing environments). Optional settings: @@ -378,6 +385,23 @@ Initial setup: `Site:BetaBlurb` | If `Site:BetaEnabled` is true and there's a beta version of SMAPI in its GitHub releases, this is shown on the beta download button as explanatory subtext. `Site:SupporterList` | A list of Patreon supports to credit on the download page. +To enable distributed servers: + +1. Launch an empty MongoDB server (e.g. using [MongoDB Atlas](https://www.mongodb.com/cloud/atlas)) + for mod data. +2. Add these application settings in the App Services environment: + + property name | description + ------------------------------- | ----------------- + `Storage:Mode` | Set to `Mongo`. + `Storage:ConnectionString` | Set to the connection string for the MongoDB instance. + + Optional settings: + + property name | description + ------------------------------- | ----------------- + `Storage:Database` | Set to the MongoDB database name (defaults to `smapi`). + To deploy updates: 1. [Deploy the web project from Visual Studio](https://docs.microsoft.com/en-us/visualstudio/deployment/quickstart-deploy-to-azure). 2. If the MongoDB schema changed, delete the MongoDB database. (It'll be recreated automatically.) diff --git a/src/SMAPI.ModBuildConfig.Analyzer.Tests/SMAPI.ModBuildConfig.Analyzer.Tests.csproj b/src/SMAPI.ModBuildConfig.Analyzer.Tests/SMAPI.ModBuildConfig.Analyzer.Tests.csproj index e2be66d9..5ae6574d 100644 --- a/src/SMAPI.ModBuildConfig.Analyzer.Tests/SMAPI.ModBuildConfig.Analyzer.Tests.csproj +++ b/src/SMAPI.ModBuildConfig.Analyzer.Tests/SMAPI.ModBuildConfig.Analyzer.Tests.csproj @@ -7,7 +7,7 @@ <ItemGroup> <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="2.10.0" /> - <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" /> + <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" /> <PackageReference Include="NUnit" Version="3.12.0" /> <PackageReference Include="NUnit3TestAdapter" Version="3.16.1"> <PrivateAssets>all</PrivateAssets> diff --git a/src/SMAPI.ModBuildConfig/DeployModTask.cs b/src/SMAPI.ModBuildConfig/DeployModTask.cs index 96d95e06..ced05a28 100644 --- a/src/SMAPI.ModBuildConfig/DeployModTask.cs +++ b/src/SMAPI.ModBuildConfig/DeployModTask.cs @@ -153,23 +153,22 @@ namespace StardewModdingAPI.ModBuildConfig // create zip file Directory.CreateDirectory(outputFolderPath); - using (Stream zipStream = new FileStream(zipPath, FileMode.Create, FileAccess.Write)) - using (ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Create)) + using Stream zipStream = new FileStream(zipPath, FileMode.Create, FileAccess.Write); + using ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Create); + + foreach (var fileEntry in files) { - foreach (var fileEntry in files) - { - string relativePath = fileEntry.Key; - FileInfo file = fileEntry.Value; + string relativePath = fileEntry.Key; + FileInfo file = fileEntry.Value; - // get file info - string filePath = file.FullName; - string entryName = folderName + '/' + relativePath.Replace(Path.DirectorySeparatorChar, '/'); + // get file info + string filePath = file.FullName; + string entryName = folderName + '/' + relativePath.Replace(Path.DirectorySeparatorChar, '/'); - // add to zip - using (Stream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read)) - using (Stream fileStreamInZip = archive.CreateEntry(entryName).Open()) - fileStream.CopyTo(fileStreamInZip); - } + // add to zip + using Stream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read); + using Stream fileStreamInZip = archive.CreateEntry(entryName).Open(); + fileStream.CopyTo(fileStreamInZip); } } diff --git a/src/SMAPI.Tests/SMAPI.Tests.csproj b/src/SMAPI.Tests/SMAPI.Tests.csproj index 639c22a4..b1548e3a 100644 --- a/src/SMAPI.Tests/SMAPI.Tests.csproj +++ b/src/SMAPI.Tests/SMAPI.Tests.csproj @@ -16,7 +16,7 @@ </ItemGroup> <ItemGroup> - <PackageReference Include="Moq" Version="4.13.1" /> + <PackageReference Include="Moq" Version="4.14.1" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.3" /> <PackageReference Include="NUnit" Version="3.12.0" /> </ItemGroup> diff --git a/src/SMAPI.Toolkit/Framework/Clients/WebApi/WebApiClient.cs b/src/SMAPI.Toolkit/Framework/Clients/WebApi/WebApiClient.cs index f0a7c82a..2fb6ed20 100644 --- a/src/SMAPI.Toolkit/Framework/Clients/WebApi/WebApiClient.cs +++ b/src/SMAPI.Toolkit/Framework/Clients/WebApi/WebApiClient.cs @@ -62,16 +62,15 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.WebApi private TResult Post<TBody, TResult>(string url, TBody content) { // note: avoid HttpClient for Mac compatibility - using (WebClient client = new WebClient()) - { - Uri fullUrl = new Uri(this.BaseUrl, url); - string data = JsonConvert.SerializeObject(content); + using WebClient client = new WebClient(); - client.Headers["Content-Type"] = "application/json"; - client.Headers["User-Agent"] = $"SMAPI/{this.Version}"; - string response = client.UploadString(fullUrl, data); - return JsonConvert.DeserializeObject<TResult>(response, this.JsonSettings); - } + Uri fullUrl = new Uri(this.BaseUrl, url); + string data = JsonConvert.SerializeObject(content); + + client.Headers["Content-Type"] = "application/json"; + client.Headers["User-Agent"] = $"SMAPI/{this.Version}"; + string response = client.UploadString(fullUrl, data); + return JsonConvert.DeserializeObject<TResult>(response, this.JsonSettings); } } } diff --git a/src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityStatus.cs b/src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityStatus.cs index a1d2dfae..5cdf489f 100644 --- a/src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityStatus.cs +++ b/src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityStatus.cs @@ -3,25 +3,28 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki /// <summary>The compatibility status for a mod.</summary> public enum WikiCompatibilityStatus { + /// <summary>The status is unknown.</summary> + Unknown, + /// <summary>The mod is compatible.</summary> - Ok = 0, + Ok, /// <summary>The mod is compatible if you use an optional official download.</summary> - Optional = 1, + Optional, /// <summary>The mod is compatible if you use an unofficial update.</summary> - Unofficial = 2, + Unofficial, /// <summary>The mod isn't compatible, but the player can fix it or there's a good alternative.</summary> - Workaround = 3, + Workaround, /// <summary>The mod isn't compatible.</summary> - Broken = 4, + Broken, /// <summary>The mod is no longer maintained by the author, and an unofficial update or continuation is unlikely.</summary> - Abandoned = 5, + Abandoned, /// <summary>The mod is no longer needed and should be removed.</summary> - Obsolete = 6 + Obsolete } } diff --git a/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs b/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs index 212c70ef..4eec3424 100644 --- a/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs +++ b/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs @@ -124,8 +124,8 @@ namespace StardewModdingAPI.Toolkit.Framework.GameScanning XElement root; try { - using (FileStream stream = file.OpenRead()) - root = XElement.Load(stream); + using FileStream stream = file.OpenRead(); + root = XElement.Load(stream); } catch { diff --git a/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj b/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj index edb1d612..4e6918ad 100644 --- a/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj +++ b/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj @@ -14,7 +14,7 @@ <ItemGroup> <PackageReference Include="HtmlAgilityPack" Version="1.11.23" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.3" /> - <PackageReference Include="Pathoschild.Http.FluentClient" Version="3.3.1" /> + <PackageReference Include="Pathoschild.Http.FluentClient" Version="4.0.0" /> <PackageReference Include="System.Management" Version="4.5.0" Condition="'$(OS)' == 'Windows_NT'" /> <PackageReference Include="Microsoft.Win32.Registry" Version="4.5.0" Condition="'$(OS)' == 'Windows_NT' AND '$(TargetFramework)' == 'netstandard2.0'" /> </ItemGroup> diff --git a/src/SMAPI.Toolkit/Utilities/EnvironmentUtility.cs b/src/SMAPI.Toolkit/Utilities/EnvironmentUtility.cs index c45448f3..1e490448 100644 --- a/src/SMAPI.Toolkit/Utilities/EnvironmentUtility.cs +++ b/src/SMAPI.Toolkit/Utilities/EnvironmentUtility.cs @@ -30,10 +30,7 @@ namespace StardewModdingAPI.Toolkit.Utilities /// <summary>Detect the current OS.</summary> public static Platform DetectPlatform() { - if (EnvironmentUtility.CachedPlatform == null) - EnvironmentUtility.CachedPlatform = EnvironmentUtility.DetectPlatformImpl(); - - return EnvironmentUtility.CachedPlatform.Value; + return EnvironmentUtility.CachedPlatform ??= EnvironmentUtility.DetectPlatformImpl(); } diff --git a/src/SMAPI.Web.LegacyRedirects/Controllers/ModsApiController.cs b/src/SMAPI.Web.LegacyRedirects/Controllers/ModsApiController.cs deleted file mode 100644 index 44ed0b6b..00000000 --- a/src/SMAPI.Web.LegacyRedirects/Controllers/ModsApiController.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; -using Pathoschild.Http.Client; -using StardewMod |
