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 Apr 27, 2020
2 parents d0dad43 + f44151d commit df6e745
Show file tree
Hide file tree
Showing 50 changed files with 746 additions and 73 deletions.
2 changes: 1 addition & 1 deletion build/common.targets
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<!--set properties -->
<PropertyGroup>
<Version>3.4.1</Version>
<Version>3.5.0</Version>
<Product>SMAPI</Product>

<AssemblySearchPaths>$(AssemblySearchPaths);{GAC}</AssemblySearchPaths>
Expand Down
16 changes: 6 additions & 10 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
**SMAPI** is an open-source modding framework and API for [Stardew Valley](https://stardewvalley.net/)
that lets you play the game with mods. It's safely installed alongside the game's executable, and
doesn't change any of your game files. It serves eight main purposes:
doesn't change any of your game files. It serves seven main purposes:

1. **Load mods into the game.**
_SMAPI loads mods when the game is starting up so they can interact with it. (Code mods aren't
Expand All @@ -10,14 +10,10 @@ doesn't change any of your game files. It serves eight main purposes:
_SMAPI provides APIs and events which let mods interact with the game in ways they otherwise
couldn't._

3. **Rewrite mods for crossplatform compatibility.**
3. **Rewrite mods for compatibility.**
_SMAPI rewrites mods' compiled code before loading them so they work on Linux/Mac/Windows
without the mods needing to handle differences between the Linux/Mac and Windows versions of the
game._

4. **Rewrite mods to update them.**
_SMAPI detects when a mod accesses part of the game that changed in a game update which affects
many mods, and rewrites the mod so it's compatible._
game. In some cases it also rewrites code broken by a game update so the mod doesn't break._

5. **Intercept errors and automatically fix saves.**
_SMAPI intercepts errors, shows the error info in the SMAPI console, and in most cases
Expand All @@ -37,8 +33,8 @@ doesn't change any of your game files. It serves eight main purposes:
they cause problems._

8. **Back up your save files.**
_SMAPI automatically creates a daily backup of your saves and keeps ten backups, in case
something goes wrong. (Via the bundled SaveBackup mod.)_
_SMAPI automatically creates a daily backup of your saves and keeps ten backups (via the bundled
Save Backup mod), in case something goes wrong._

## Documentation
Have questions? Come [ask the community](https://smapi.io/community) to get help from SMAPI
Expand Down Expand Up @@ -69,7 +65,7 @@ German | ✓ [fully translated](../src/SMAPI/i18n/de.json)
Hungarian | ✓ [fully translated](../src/SMAPI/i18n/hu.json)
Italian | ✓ [fully translated](../src/SMAPI/i18n/it.json)
Japanese | ✓ [fully translated](../src/SMAPI/i18n/ja.json)
Korean | ❑ not translated
Korean | [fully translated](../src/SMAPI/i18n/ko.json)
Portuguese | ✓ [fully translated](../src/SMAPI/i18n/pt.json)
Russian | ✓ [fully translated](../src/SMAPI/i18n/ru.json)
Spanish | ✓ [fully translated](../src/SMAPI/i18n/es.json)
Expand Down
27 changes: 27 additions & 0 deletions docs/release-notes.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,33 @@
&larr; [README](README.md)

# Release notes
## 3.5
Released 27 April 2020 for Stardew Valley 1.4.1 or later.

* For players:
* SMAPI now prevents more game errors due to broken items, so you no longer need save editing to remove them.
* Added option to disable console colors.
* Updated compatibility list.
* Improved translations.¹

* For the Console Commands mod:
* Commands like `world_setday` now also affect the 'days played' stat, so in-game events/randomization match what you'd get if you played to that date normally (thanks to kdau!).

* For the web UI:
* Updated the JSON validator/schema for Content Patcher 1.13.
* Fixed rare intermittent "CGI application encountered an error" errors.

* For modders:
* Added map patching to the content API (via `asset.AsMap()`).
* Added support for using patch helpers with arbitrary data (via `helper.Content.GetPatchHelper`).
* Added `SDate` fields/methods: `SeasonIndex`, `FromDaysSinceStart`, `FromWorldDate`, `ToWorldDate`, and `ToLocaleString` (thanks to kdau!).
* Added `SDate` translations taken from the Lookup Anything mod.¹
* Fixed asset propagation for certain maps loaded through temporary content managers. This notably fixes unreliable patches to the farmhouse and town maps.
* Fixed asset propagation on Linux/Mac for monster sprites, NPC dialogue, and NPC schedules.
* Fixed asset propagation for NPC dialogue sometimes causing a spouse to skip marriage dialogue or not allow kisses.

¹ Date format translations were taken from the Lookup Anything mod; thanks to translators FixThisPlz (improved Russian), LeecanIt (added Italian), pomepome (added Japanese), S2SKY (added Korean), Sasara (added German), SteaNN (added Russian), ThomasGabrielDelavault (added Spanish), VincentRoth (added French), Yllelder (improved Spanish), and yuwenlan (added Chinese). Some translations for Korean, Hungarian, and Turkish were derived from the game translations.

## 3.4.1
Released 24 March 2020 for Stardew Valley 1.4.1 or later.

Expand Down
4 changes: 2 additions & 2 deletions src/SMAPI.Installer/InteractiveInstaller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ private IEnumerable<string> GetUninstallPaths(DirectoryInfo installDir, Director
yield return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley", "ErrorLogs"); // remove old log files
}

/// <summary>Handles writing color-coded text to the console.</summary>
private ColorfulConsoleWriter ConsoleWriter;
/// <summary>Handles writing text to the console.</summary>
private IConsoleWriter ConsoleWriter;


/*********
Expand Down
16 changes: 12 additions & 4 deletions src/SMAPI.Internal/ConsoleWriting/ColorfulConsoleWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

namespace StardewModdingAPI.Internal.ConsoleWriting
{
/// <summary>Provides a wrapper for writing color-coded text to the console.</summary>
internal class ColorfulConsoleWriter
/// <summary>Writes color-coded text to the console.</summary>
internal class ColorfulConsoleWriter : IConsoleWriter
{
/*********
** Fields
Expand All @@ -30,8 +30,16 @@ public ColorfulConsoleWriter(Platform platform)
/// <param name="colorConfig">The colors to use for text written to the SMAPI console.</param>
public ColorfulConsoleWriter(Platform platform, ColorSchemeConfig colorConfig)
{
this.SupportsColor = this.TestColorSupport();
this.Colors = this.GetConsoleColorScheme(platform, colorConfig);
if (colorConfig.UseScheme == MonitorColorScheme.None)
{
this.SupportsColor = false;
this.Colors = null;
}
else
{
this.SupportsColor = this.TestColorSupport();
this.Colors = this.GetConsoleColorScheme(platform, colorConfig);
}
}

/// <summary>Write a message line to the log.</summary>
Expand Down
11 changes: 11 additions & 0 deletions src/SMAPI.Internal/ConsoleWriting/IConsoleWriter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace StardewModdingAPI.Internal.ConsoleWriting
{
/// <summary>Writes text to the console.</summary>
internal interface IConsoleWriter
{
/// <summary>Write a message line to the log.</summary>
/// <param name="message">The message to log.</param>
/// <param name="level">The log level.</param>
void WriteLine(string message, ConsoleLogLevel level);
}
}
5 changes: 4 additions & 1 deletion src/SMAPI.Internal/ConsoleWriting/MonitorColorScheme.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ internal enum MonitorColorScheme
DarkBackground,

/// <summary>Use darker text colors that look better on a white or light background.</summary>
LightBackground
LightBackground,

/// <summary>Disable console color.</summary>
None
}
}
1 change: 1 addition & 0 deletions src/SMAPI.Internal/SMAPI.Internal.projitems
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<Compile Include="$(MSBuildThisFileDirectory)ConsoleWriting\ColorfulConsoleWriter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ConsoleWriting\ColorSchemeConfig.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ConsoleWriting\ConsoleLogLevel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ConsoleWriting\IConsoleWriter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ConsoleWriting\MonitorColorScheme.cs" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Linq;
using StardewModdingAPI.Utilities;
using StardewValley;

namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.World
Expand Down Expand Up @@ -32,6 +33,7 @@ public override void Handle(IMonitor monitor, string command, ArgumentParser arg

// handle
Game1.dayOfMonth = day;
Game1.stats.DaysPlayed = (uint)SDate.Now().DaysSinceStart;
monitor.Log($"OK, the date is now {Game1.currentSeason} {Game1.dayOfMonth}.", LogLevel.Info);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Linq;
using StardewModdingAPI.Utilities;
using StardewValley;

namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.World
Expand Down Expand Up @@ -40,6 +41,7 @@ public override void Handle(IMonitor monitor, string command, ArgumentParser arg
// handle
Game1.currentSeason = season.ToLower();
Game1.setGraphicsForSeason();
Game1.stats.DaysPlayed = (uint)SDate.Now().DaysSinceStart;
monitor.Log($"OK, the date is now {Game1.currentSeason} {Game1.dayOfMonth}.", LogLevel.Info);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Linq;
using StardewModdingAPI.Utilities;
using StardewValley;

namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.World
Expand Down Expand Up @@ -32,6 +33,7 @@ public override void Handle(IMonitor monitor, string command, ArgumentParser arg

// handle
Game1.year = year;
Game1.stats.DaysPlayed = (uint)SDate.Now().DaysSinceStart;
monitor.Log($"OK, the year is now {Game1.year}.", LogLevel.Info);
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/SMAPI.Mods.ConsoleCommands/manifest.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"Name": "Console Commands",
"Author": "SMAPI",
"Version": "3.4.1",
"Version": "3.5.0",
"Description": "Adds SMAPI console commands that let you manipulate the game.",
"UniqueID": "SMAPI.ConsoleCommands",
"EntryDll": "ConsoleCommands.dll",
"MinimumApiVersion": "3.4.1"
"MinimumApiVersion": "3.5.0"
}
4 changes: 2 additions & 2 deletions src/SMAPI.Mods.SaveBackup/manifest.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"Name": "Save Backup",
"Author": "SMAPI",
"Version": "3.4.1",
"Version": "3.5.0",
"Description": "Automatically backs up all your saves once per day into its folder.",
"UniqueID": "SMAPI.SaveBackup",
"EntryDll": "SaveBackup.dll",
"MinimumApiVersion": "3.4.1"
"MinimumApiVersion": "3.5.0"
}
2 changes: 1 addition & 1 deletion src/SMAPI.Tests/Core/ModResolverTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public void ReadBasicManifest_CanReadFile()
[nameof(IManifest.Description)] = Sample.String(),
[nameof(IManifest.UniqueID)] = $"{Sample.String()}.{Sample.String()}",
[nameof(IManifest.EntryDll)] = $"{Sample.String()}.dll",
[nameof(IManifest.MinimumApiVersion)] = $"{Sample.Int()}.{Sample.Int()}-{Sample.String()}",
[nameof(IManifest.MinimumApiVersion)] = $"{Sample.Int()}.{Sample.Int()}.{Sample.Int()}-{Sample.String()}",
[nameof(IManifest.Dependencies)] = new[] { originalDependency },
["ExtraString"] = Sample.String(),
["ExtraInt"] = Sample.Int()
Expand Down
91 changes: 91 additions & 0 deletions src/SMAPI.Tests/Utilities/SDateTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Text.RegularExpressions;
using NUnit.Framework;
using StardewModdingAPI.Utilities;
using StardewValley;

namespace SMAPI.Tests.Utilities
{
Expand Down Expand Up @@ -81,6 +82,62 @@ public void Constructor_RejectsInvalidValues(int day, string season, int year)
Assert.Throws<ArgumentException>(() => _ = new SDate(day, season, year), "Constructing the invalid date didn't throw the expected exception.");
}

/****
** FromDaysSinceStart
****/
[Test(Description = "Assert that FromDaysSinceStart returns the expected date.")]
[TestCase(1, ExpectedResult = "01 spring Y1")]
[TestCase(2, ExpectedResult = "02 spring Y1")]
[TestCase(28, ExpectedResult = "28 spring Y1")]
[TestCase(29, ExpectedResult = "01 summer Y1")]
[TestCase(141, ExpectedResult = "01 summer Y2")]
public string FromDaysSinceStart(int daysSinceStart)
{
// act
return SDate.FromDaysSinceStart(daysSinceStart).ToString();
}

[Test(Description = "Assert that FromDaysSinceStart throws an exception if the number of days is invalid.")]
[TestCase(-1)] // day < 0
[TestCase(0)] // day == 0
[SuppressMessage("ReSharper", "AssignmentIsFullyDiscarded", Justification = "Deliberate for unit test.")]
public void FromDaysSinceStart_RejectsInvalidValues(int daysSinceStart)
{
// act & assert
Assert.Throws<ArgumentException>(() => _ = SDate.FromDaysSinceStart(daysSinceStart), "Passing the invalid number of days didn't throw the expected exception.");
}

/****
** From
****/
[Test(Description = "Assert that SDate.From constructs the correct instance for a given date.")]
[TestCase(0, ExpectedResult = "01 spring Y1")]
[TestCase(1, ExpectedResult = "02 spring Y1")]
[TestCase(27, ExpectedResult = "28 spring Y1")]
[TestCase(28, ExpectedResult = "01 summer Y1")]
[TestCase(140, ExpectedResult = "01 summer Y2")]
public string From_WorldDate(int totalDays)
{
return SDate.From(new WorldDate { TotalDays = totalDays }).ToString();
}


/****
** SeasonIndex
****/
[Test(Description = "Assert the numeric index of the season.")]
[TestCase("01 spring Y1", ExpectedResult = 0)]
[TestCase("02 summer Y1", ExpectedResult = 1)]
[TestCase("28 fall Y1", ExpectedResult = 2)]
[TestCase("01 winter Y1", ExpectedResult = 3)]
[TestCase("01 winter Y2", ExpectedResult = 3)]
public int SeasonIndex(string dateStr)
{
// act
return this.GetDate(dateStr).SeasonIndex;
}


/****
** DayOfWeek
****/
Expand Down Expand Up @@ -119,6 +176,7 @@ public DayOfWeek DayOfWeek(string dateStr)
return this.GetDate(dateStr).DayOfWeek;
}


/****
** DaysSinceStart
****/
Expand All @@ -134,6 +192,7 @@ public int DaysSinceStart(string dateStr)
return this.GetDate(dateStr).DaysSinceStart;
}


/****
** ToString
****/
Expand All @@ -147,6 +206,7 @@ public string ToString(string dateStr)
return this.GetDate(dateStr).ToString();
}


/****
** AddDays
****/
Expand All @@ -166,6 +226,18 @@ public string AddDays(string dateStr, int addDays)
return this.GetDate(dateStr).AddDays(addDays).ToString();
}

[Test(Description = "Assert that AddDays throws an exception if the number of days is invalid.")]
[TestCase("01 spring Y1", -1)]
[TestCase("01 summer Y1", -29)]
[TestCase("01 spring Y2", -113)]
[SuppressMessage("ReSharper", "AssignmentIsFullyDiscarded", Justification = "Deliberate for unit test.")]
public void AddDays_RejectsInvalidValues(string dateStr, int addDays)
{
// act & assert
Assert.Throws<ArithmeticException>(() => _ = this.GetDate(dateStr).AddDays(addDays), "Passing the invalid number of days didn't throw the expected exception.");
}


/****
** GetHashCode
****/
Expand Down Expand Up @@ -194,6 +266,25 @@ public void GetHashCode_ReturnsUniqueOrderedValue()
}
}


/****
** ToWorldDate
****/
[Test(Description = "Assert that the WorldDate operator returns the corresponding WorldDate.")]
[TestCase("01 spring Y1", ExpectedResult = 0)]
[TestCase("02 spring Y1", ExpectedResult = 1)]
[TestCase("28 spring Y1", ExpectedResult = 27)]
[TestCase("01 summer Y1", ExpectedResult = 28)]
[TestCase("01 summer Y2", ExpectedResult = 140)]
public int ToWorldDate(string dateStr)
{
return this.GetDate(dateStr).ToWorldDate().TotalDays;
}


/****
** Operators
****/
[Test(Description = "Assert that the == operator returns the expected values. We only need a few test cases, since it's based on GetHashCode which is tested more thoroughly.")]
[TestCase(Dates.Now, null, ExpectedResult = false)]
[TestCase(Dates.Now, Dates.PrevDay, ExpectedResult = false)]
Expand Down
1 change: 1 addition & 0 deletions src/SMAPI.Web/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public static void Main(string[] args)
.CreateDefaultBuilder(args)
.CaptureStartupErrors(true)
.UseSetting("detailedErrors", "true")
.UseKestrel().UseIISIntegration() // must be used together; fixes intermittent errors on Azure: https://stackoverflow.com/a/38312175/262123
.UseStartup<Startup>()
.Build()
.Run();
Expand Down
2 changes: 1 addition & 1 deletion src/SMAPI.Web/wwwroot/SMAPI.metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@
*********/
"Auto Quality Patch": {
"ID": "SilentOak.AutoQualityPatch",
"~2.1.3-unofficial.7 | Status": "AssumeBroken" // runtime errors
"~2.1.3-unofficial.7-mizzion | Status": "AssumeBroken" // runtime errors
},

"Fix Dice": {
Expand Down
Loading

0 comments on commit df6e745

Please sign in to comment.