Skip to content

Commit

Permalink
Merge branch 'develop' into stable
Browse files Browse the repository at this point in the history
  • Loading branch information
Pathoschild committed Mar 26, 2018
2 parents afb3c49 + 4d68ef3 commit 46141a7
Show file tree
Hide file tree
Showing 34 changed files with 999 additions and 339 deletions.
4 changes: 2 additions & 2 deletions build/GlobalAssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System.Reflection;

[assembly: AssemblyProduct("SMAPI")]
[assembly: AssemblyVersion("2.5.3")]
[assembly: AssemblyFileVersion("2.5.3")]
[assembly: AssemblyVersion("2.5.4")]
[assembly: AssemblyFileVersion("2.5.4")]
23 changes: 23 additions & 0 deletions docs/mod-build-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,36 @@ or you have multiple installs, you can specify the path yourself. There's two wa
The configuration will check your custom path first, then fall back to the default paths (so it'll
still compile on a different computer).

### Unit test projects
**(upcoming in 2.0.3)**

You can use the package in unit test projects too. Its optional unit test mode...

1. disables deploying the project as a mod;
2. disables creating a release zip;
2. and copies the referenced DLLs into the build output for unit test frameworks.

To enable it, add this above the first `</PropertyGroup>` in your `.csproj`:
```xml
<ModUnitTests>True</ModUnitTests>
```

## Troubleshoot
### "Failed to find the game install path"
That error means the package couldn't find your game. You can specify the game path yourself; see
_[Game path](#game-path)_ above.

## Release notes
### 2.0.3 alpha
* Added support for Stardew Valley 1.3.
* Added support for unit test projects.

### 2.0.2
* Fixed compatibility issue on Linux.

### 2.0.1
* Fixed mod deploy failing to create subfolders if they don't already exist.

### 2.0
* Added: mods are now copied into the `Mods` folder automatically (configurable).
* Added: release zips are now created automatically in your build output folder (configurable).
Expand Down
29 changes: 27 additions & 2 deletions docs/release-notes.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,43 @@
# Release notes
<!--
## 2.6 alpha
* For players:
* Updated for Stardew Valley 1.3 (multiplayer update); no longer compatible with earlier versions.
* Added support for Stardew Valley 1.3+; no longer compatible with earlier versions.
* Fixed SMAPI update alerts linking to the GitHub repository instead of [smapi.io](https://smapi.io).
* Fixed SMAPI update checks not showing newer beta versions when using a beta version.
* For modders:
* Dropped support for some deprecated APIs.
* Dropped some deprecated APIs.
* Fixed some assets not being editable.
* For SMAPI developers:
* Added prerelease versions to the mod update-check API response where available (GitHub only).
* Added support for beta releases on the home page.
-->

## 2.5.4
* For players:
* Fixed some textures not updated when a mod changes them.
* Fixed visual bug on Linux/Mac when mods overlay textures.
* Fixed error when mods remove an asset editor/loader.
* Fixed minimum game version incorrectly increased in SMAPI 2.5.3.

* For the [log parser][]:
* Fixed error when log text contains certain tokens.

* For modders:
* Updated to Json.NET 11.0.2.

* For SMAPI developers:
* Added support for beta update track to support upcoming Stardew Valley 1.3 beta.

## 2.5.3
* For players:
* Simplified and improved skipped-mod messages.
* Fixed rare crash with some combinations of manifest fields and internal mod data.
* Fixed update checks failing for Nexus Mods due to a change in their API.
* Fixed update checks failing for some older mods with non-standard versions.
* Fixed failed update checks being cached for an hour (now cached 5 minutes).
* Fixed error when a content pack needs a mod that couldn't be loaded.
* Fixed Linux ["magic number is wrong" errors](https://github.com/mono/mono/issues/6752) by changing default terminal order.
* Updated compatibility list and added update checks for more mods.
Expand Down
12 changes: 8 additions & 4 deletions src/SMAPI.Common/Models/ModInfoModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ internal class ModInfoModel
/// <summary>The mod name.</summary>
public string Name { get; set; }

/// <summary>The mod's semantic version number.</summary>
/// <summary>The semantic version for the mod's latest release.</summary>
public string Version { get; set; }

/// <summary>The semantic version for the mod's latest preview release, if available and different from <see cref="Version"/>.</summary>
public string PreviewVersion { get; set; }

/// <summary>The mod's web URL.</summary>
public string Url { get; set; }

Expand All @@ -28,16 +31,17 @@ public ModInfoModel()
// needed for JSON deserialising
}


/// <summary>Construct an instance.</summary>
/// <param name="name">The mod name.</param>
/// <param name="version">The mod's semantic version number.</param>
/// <param name="version">The semantic version for the mod's latest release.</param>
/// <param name="previewVersion">The semantic version for the mod's latest preview release, if available and different from <see cref="Version"/>.</param>
/// <param name="url">The mod's web URL.</param>
/// <param name="error">The error message indicating why the mod is invalid (if applicable).</param>
public ModInfoModel(string name, string version, string url, string error = null)
public ModInfoModel(string name, string version, string url, string previewVersion = null, string error = null)
{
this.Name = name;
this.Version = version;
this.PreviewVersion = previewVersion;
this.Url = url;
this.Error = error; // mainly initialised here for the JSON deserialiser
}
Expand Down
17 changes: 17 additions & 0 deletions src/SMAPI.ModBuildConfig/build/smapi.targets
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,14 @@

<!-- set default settings -->
<ModFolderName Condition="'$(ModFolderName)' == ''">$(MSBuildProjectName)</ModFolderName>
<ModUnitTests Condition="'$(ModUnitTests)' == ''">False</ModUnitTests>
<ModZipPath Condition="'$(ModZipPath)' == ''">$(TargetDir)</ModZipPath>
<EnableModDeploy Condition="'$(EnableModDeploy)' == ''">True</EnableModDeploy>
<EnableModZip Condition="'$(EnableModZip)' == ''">True</EnableModZip>

<!-- disable mod deploy in unit test project -->
<EnableModDeploy Condition="'$(ModUnitTests)' == true">False</EnableModDeploy>
<EnableModZip Condition="'$(ModUnitTests)' == true">False</EnableModZip>
</PropertyGroup>

<!-- find platform + game path -->
Expand Down Expand Up @@ -57,32 +62,40 @@
<ItemGroup>
<Reference Include="Microsoft.Xna.Framework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
<Private>false</Private>
<Private Condition="$(ModUnitTests)">true</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Game, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
<Private>false</Private>
<Private Condition="$(ModUnitTests)">true</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Graphics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
<Private>false</Private>
<Private Condition="$(ModUnitTests)">true</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Xact, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
<Private>false</Private>
<Private Condition="$(ModUnitTests)">true</Private>
</Reference>
<Reference Include="Netcode" Condition="Exists('$(GamePath)\Netcode.dll')">
<HintPath>$(GamePath)\Netcode.dll</HintPath>
<Private>False</Private>
<Private Condition="$(ModUnitTests)">true</Private>
</Reference>
<Reference Include="Stardew Valley">
<HintPath>$(GamePath)\Stardew Valley.exe</HintPath>
<Private>false</Private>
<Private Condition="$(ModUnitTests)">true</Private>
</Reference>
<Reference Include="StardewModdingAPI">
<HintPath>$(GamePath)\StardewModdingAPI.exe</HintPath>
<Private>false</Private>
<Private Condition="$(ModUnitTests)">true</Private>
</Reference>
<Reference Include="xTile, Version=2.0.4.0, Culture=neutral, processorArchitecture=x86">
<HintPath>$(GamePath)\xTile.dll</HintPath>
<Private>false</Private>
<SpecificVersion>False</SpecificVersion>
<Private Condition="$(ModUnitTests)">true</Private>
</Reference>
</ItemGroup>

Expand All @@ -100,18 +113,22 @@
<HintPath>$(GamePath)\MonoGame.Framework.dll</HintPath>
<Private>false</Private>
<SpecificVersion>False</SpecificVersion>
<Private Condition="$(ModUnitTests)">true</Private>
</Reference>
<Reference Include="StardewValley">
<HintPath>$(GamePath)\StardewValley.exe</HintPath>
<Private>false</Private>
<Private Condition="$(ModUnitTests)">true</Private>
</Reference>
<Reference Include="StardewModdingAPI">
<HintPath>$(GamePath)\StardewModdingAPI.exe</HintPath>
<Private>false</Private>
<Private Condition="$(ModUnitTests)">true</Private>
</Reference>
<Reference Include="xTile">
<HintPath>$(GamePath)\xTile.dll</HintPath>
<Private>false</Private>
<Private Condition="$(ModUnitTests)">true</Private>
</Reference>
</ItemGroup>
</Otherwise>
Expand Down
3 changes: 2 additions & 1 deletion src/SMAPI.ModBuildConfig/package.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
<metadata>
<id>Pathoschild.Stardew.ModBuildConfig</id>
<version>2.0.3-alpha20180307</version>
<version>2.0.3-alpha20180325</version>
<title>Build package for SMAPI mods</title>
<authors>Pathoschild</authors>
<owners>Pathoschild</owners>
Expand All @@ -29,6 +29,7 @@

2.0.3:
- Added support for Stardew Valley 1.3.
- Added support for unit test projects.
</releaseNotes>
</metadata>
<files>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.11.0.1-beta3\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>False</Private>
<HintPath>..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Xml" />
Expand Down
2 changes: 1 addition & 1 deletion src/SMAPI.Mods.ConsoleCommands/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"Name": "Console Commands",
"Author": "SMAPI",
"Version": "2.5.3",
"Version": "2.5.4",
"Description": "Adds SMAPI console commands that let you manipulate the game.",
"UniqueID": "SMAPI.ConsoleCommands",
"EntryDll": "ConsoleCommands.dll"
Expand Down
2 changes: 1 addition & 1 deletion src/SMAPI.Mods.ConsoleCommands/packages.config
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="11.0.1-beta3" targetFramework="net45" />
<package id="Newtonsoft.Json" version="11.0.2" targetFramework="net45" />
</packages>
53 changes: 46 additions & 7 deletions src/SMAPI.Web/Controllers/IndexController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using StardewModdingAPI.Common;
using StardewModdingAPI.Web.Framework.Clients.GitHub;
using StardewModdingAPI.Web.ViewModels;

Expand All @@ -23,7 +24,10 @@ internal class IndexController : Controller
private readonly IGitHubClient GitHub;

/// <summary>The cache time for release info.</summary>
private readonly TimeSpan CacheTime = TimeSpan.FromMinutes(5);
private readonly TimeSpan CacheTime = TimeSpan.FromSeconds(1);

/// <summary>The GitHub repository name to check for update.</summary>
private readonly string RepositoryName = "Pathoschild/SMAPI";


/*********
Expand All @@ -42,17 +46,24 @@ public IndexController(IMemoryCache cache, IGitHubClient github)
[HttpGet]
public async Task<ViewResult> Index()
{
// fetch latest SMAPI release
GitRelease release = await this.Cache.GetOrCreateAsync("latest-smapi-release", async entry =>
// fetch SMAPI releases
IndexVersionModel stableVersion = await this.Cache.GetOrCreateAsync("stable-version", async entry =>
{
entry.AbsoluteExpiration = DateTimeOffset.UtcNow.Add(this.CacheTime);
GitRelease release = await this.GitHub.GetLatestReleaseAsync(this.RepositoryName, includePrerelease: false);
return new IndexVersionModel(release.Name, release.Body, this.GetMainDownloadUrl(release), this.GetDevDownloadUrl(release));
});
IndexVersionModel betaVersion = await this.Cache.GetOrCreateAsync("beta-version", async entry =>
{
entry.AbsoluteExpiration = DateTimeOffset.UtcNow.Add(this.CacheTime);
return await this.GitHub.GetLatestReleaseAsync("Pathoschild/SMAPI");
GitRelease release = await this.GitHub.GetLatestReleaseAsync(this.RepositoryName, includePrerelease: true);
return release.IsPrerelease
? this.GetBetaDownload(release)
: null;
});
string downloadUrl = this.GetMainDownloadUrl(release);
string devDownloadUrl = this.GetDevDownloadUrl(release);

// render view
var model = new IndexModel(release.Name, release.Body, downloadUrl, devDownloadUrl);
var model = new IndexModel(stableVersion, betaVersion);
return this.View(model);
}

Expand Down Expand Up @@ -89,5 +100,33 @@ private string GetDevDownloadUrl(GitRelease release)
// fallback just in case
return "https://github.com/pathoschild/SMAPI/releases";
}

/// <summary>Get the latest beta download for a SMAPI release.</summary>
/// <param name="release">The SMAPI release.</param>
private IndexVersionModel GetBetaDownload(GitRelease release)
{
// get download with the latest version
SemanticVersionImpl latestVersion = null;
string latestUrl = null;
foreach (GitAsset asset in release.Assets ?? new GitAsset[0])
{
// parse version
Match versionMatch = Regex.Match(asset.FileName, @"SMAPI-([\d\.]+(?:-.+)?)-installer.zip");
if (!versionMatch.Success || !SemanticVersionImpl.TryParse(versionMatch.Groups[1].Value, out SemanticVersionImpl version))
continue;

// save latest version
if (latestVersion == null || latestVersion.CompareTo(version) < 0)
{
latestVersion = version;
latestUrl = asset.DownloadUrl;
}
}

// return if prerelease
return latestVersion?.Tag != null
? new IndexVersionModel(latestVersion.ToString(), release.Body, latestUrl, null)
: null;
}
}
}
16 changes: 10 additions & 6 deletions src/SMAPI.Web/Controllers/ModsApiController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@ internal class ModsApiController : Controller
/// <summary>The cache in which to store mod metadata.</summary>
private readonly IMemoryCache Cache;

/// <summary>The number of minutes update checks should be cached before refetching them.</summary>
private readonly int CacheMinutes;
/// <summary>The number of minutes successful update checks should be cached before refetching them.</summary>
private readonly int SuccessCacheMinutes;

/// <summary>The number of minutes failed update checks should be cached before refetching them.</summary>
private readonly int ErrorCacheMinutes;

/// <summary>A regex which matches SMAPI-style semantic version.</summary>
private readonly string VersionRegex;
Expand All @@ -50,7 +53,8 @@ public ModsApiController(IMemoryCache cache, IOptions<ModUpdateCheckConfig> conf
ModUpdateCheckConfig config = configProvider.Value;

this.Cache = cache;
this.CacheMinutes = config.CacheMinutes;
this.SuccessCacheMinutes = config.SuccessCacheMinutes;
this.ErrorCacheMinutes = config.ErrorCacheMinutes;
this.VersionRegex = config.SemanticVersionRegex;
this.Repositories =
new IModRepository[]
Expand Down Expand Up @@ -115,13 +119,13 @@ public async Task<IDictionary<string, ModInfoModel>> PostAsync([FromBody] ModSea
if (info.Error == null)
{
if (info.Version == null)
info = new ModInfoModel(info.Name, info.Version, info.Url, "Mod has no version number.");
info = new ModInfoModel(name: info.Name, version: info.Version, url: info.Url, error: "Mod has no version number.");
if (!allowInvalidVersions && !Regex.IsMatch(info.Version, this.VersionRegex, RegexOptions.CultureInvariant | RegexOptions.IgnoreCase))
info = new ModInfoModel(info.Name, info.Version, info.Url, $"Mod has invalid semantic version '{info.Version}'.");
info = new ModInfoModel(name: info.Name, version: info.Version, url: info.Url, error: $"Mod has invalid semantic version '{info.Version}'.");
}

// cache & return
entry.AbsoluteExpiration = DateTimeOffset.UtcNow.AddMinutes(this.CacheMinutes);
entry.AbsoluteExpiration = DateTimeOffset.UtcNow.AddMinutes(info.Error == null ? this.SuccessCacheMinutes : this.ErrorCacheMinutes);
return info;
});
}
Expand Down
Loading

0 comments on commit 46141a7

Please sign in to comment.