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 22, 2020
2 parents 5ae640d + 6d1494a commit 7ca5efb
Show file tree
Hide file tree
Showing 39 changed files with 1,115 additions and 538 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.3.2</Version>
<Version>3.4.0</Version>
<Product>SMAPI</Product>

<AssemblySearchPaths>$(AssemblySearchPaths);{GAC}</AssemblySearchPaths>
Expand Down
4 changes: 2 additions & 2 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ default | ✓ [fully translated](../src/SMAPI/i18n/default.json)
Chinese | ✓ [fully translated](../src/SMAPI/i18n/zh.json)
French | ✓ [fully translated](../src/SMAPI/i18n/fr.json)
German | ✓ [fully translated](../src/SMAPI/i18n/de.json)
Hungarian | ❑ not translated
Italian | ❑ not translated
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
Portuguese | ✓ [fully translated](../src/SMAPI/i18n/pt.json)
Expand Down
31 changes: 27 additions & 4 deletions docs/release-notes.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,29 @@
&larr; [README](README.md)

# Release notes
## 3.4
Released 22 March 2020 for Stardew Valley 1.4.1 or later.

* For players:
* Fixed semi-transparency issues on Linux/Mac in recent versions of Mono (e.g. pink shadows).
* Fixed `player_add` command error if you have broken XNB mods.
* Removed invalid-location check now handled by the game.
* Updated translations. Thanks to Annosz (added Hungarian)!

* For modders:
* Added support for flipped and rotated map tiles (in collaboration with Platonymous).
* Added support for `.tmx` maps using zlib compression (thanks to Platonymous!).
* Added `this.Monitor.LogOnce` method.
* Mods are no longer prevented from suppressing key presses in the chatbox.

* For the web UI:
* Added option to upload files using a file picker.
* Optimized log parser for very long multi-line log messages.
* Fixed log parser not detecting folder path in recent versions of SMAPI.

* For SMAPI developers:
* Added internal API to send custom input to the game/mods. This is mainly meant to support Virtual Keyboard on Android, but might be exposed as a public API in future versions.

## 3.3.2
Released 22 February 2020 for Stardew Valley 1.4.1 or later.

Expand All @@ -27,6 +50,10 @@ Released 22 February 2020 for Stardew Valley 1.4.1 or later.
* Fixed warning on MacOS when you have no saves yet.
* Reduced log messages.

* For the web UI:
* Updated the JSON validator and Content Patcher schema for `.tmx` support.
* The mod compatibility page now has a sticky table header.

* For modders:
* Added support for [message sending](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Integrations#Message_sending) to mods on the current computer (in addition to remote computers).
* Added `ExtendImage` method to content API when editing files to resize textures.
Expand All @@ -37,10 +64,6 @@ Released 22 February 2020 for Stardew Valley 1.4.1 or later.
* Updated dependencies (including Mono.Cecil 0.11.1 → 0.11.2).
* Fixed dialogue propagation clearing marriage dialogue.

* For the web UI:
* Updated the JSON validator and Content Patcher schema for `.tmx` support.
* The mod compatibility page now has a sticky table header.

* For SMAPI/tool developers:
* Improved support for four-part versions to support SMAPI on Android.
* The SMAPI log now prefixes the OS name with `Android` on Android.
Expand Down
28 changes: 23 additions & 5 deletions src/SMAPI.Mods.ConsoleCommands/Framework/ItemRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using StardewModdingAPI.Mods.ConsoleCommands.Framework.ItemData;
using StardewValley;
using StardewValley.Menus;
Expand Down Expand Up @@ -59,13 +60,13 @@ IEnumerable<SearchableItem> GetAllRaw()
yield return this.TryCreate(ItemType.Flooring, id, () => new Wallpaper(id, isFloor: true) { Category = SObject.furnitureCategory });

// equipment
foreach (int id in Game1.content.Load<Dictionary<int, string>>("Data\\Boots").Keys)
foreach (int id in this.TryLoad<int, string>("Data\\Boots").Keys)
yield return this.TryCreate(ItemType.Boots, id, () => new Boots(id));
foreach (int id in Game1.content.Load<Dictionary<int, string>>("Data\\hats").Keys)
foreach (int id in this.TryLoad<int, string>("Data\\hats").Keys)
yield return this.TryCreate(ItemType.Hat, id, () => new Hat(id));

// weapons
foreach (int id in Game1.content.Load<Dictionary<int, string>>("Data\\weapons").Keys)
foreach (int id in this.TryLoad<int, string>("Data\\weapons").Keys)
{
yield return this.TryCreate(ItemType.Weapon, id, () => (id >= 32 && id <= 34)
? (Item)new Slingshot(id)
Expand All @@ -74,7 +75,7 @@ IEnumerable<SearchableItem> GetAllRaw()
}

// furniture
foreach (int id in Game1.content.Load<Dictionary<int, string>>("Data\\Furniture").Keys)
foreach (int id in this.TryLoad<int, string>("Data\\Furniture").Keys)
{
if (id == 1466 || id == 1468)
yield return this.TryCreate(ItemType.Furniture, id, () => new TV(id, Vector2.Zero));
Expand All @@ -94,7 +95,7 @@ IEnumerable<SearchableItem> GetAllRaw()
// secret notes
if (id == 79)
{
foreach (int secretNoteId in Game1.content.Load<Dictionary<int, string>>("Data\\SecretNotes").Keys)
foreach (int secretNoteId in this.TryLoad<int, string>("Data\\SecretNotes").Keys)
{
yield return this.TryCreate(ItemType.Object, this.CustomIDOffset + secretNoteId, () =>
{
Expand Down Expand Up @@ -233,6 +234,23 @@ IEnumerable<SearchableItem> GetAllRaw()
/*********
** Private methods
*********/
/// <summary>Try to load a data file, and return empty data if it's invalid.</summary>
/// <typeparam name="TKey">The asset key type.</typeparam>
/// <typeparam name="TValue">The asset value type.</typeparam>
/// <param name="assetName">The data asset name.</param>
private Dictionary<TKey, TValue> TryLoad<TKey, TValue>(string assetName)
{
try
{
return Game1.content.Load<Dictionary<TKey, TValue>>(assetName);
}
catch (ContentLoadException)
{
// generally due to a player incorrectly replacing a data file with an XNB mod
return new Dictionary<TKey, TValue>();
}
}

/// <summary>Create a searchable item if valid.</summary>
/// <param name="type">The item type.</param>
/// <param name="id">The unique ID (if different from the item's parent sheet index).</param>
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.3.2",
"Version": "3.4.0",
"Description": "Adds SMAPI console commands that let you manipulate the game.",
"UniqueID": "SMAPI.ConsoleCommands",
"EntryDll": "ConsoleCommands.dll",
"MinimumApiVersion": "3.3.2"
"MinimumApiVersion": "3.4.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.3.2",
"Version": "3.4.0",
"Description": "Automatically backs up all your saves once per day into its folder.",
"UniqueID": "SMAPI.SaveBackup",
"EntryDll": "SaveBackup.dll",
"MinimumApiVersion": "3.3.2"
"MinimumApiVersion": "3.4.0"
}
2 changes: 1 addition & 1 deletion src/SMAPI.Toolkit/SMAPI.Toolkit.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="HtmlAgilityPack" Version="1.11.20" />
<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="System.Management" Version="4.5.0" Condition="'$(OS)' == 'Windows_NT'" />
Expand Down
89 changes: 89 additions & 0 deletions src/SMAPI.Web/Framework/LogParsing/LogMessageBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using System;
using System.Text;
using StardewModdingAPI.Web.Framework.LogParsing.Models;

namespace StardewModdingAPI.Web.Framework.LogParsing
{
/// <summary>Handles constructing log message instances with minimal memory allocation.</summary>
internal class LogMessageBuilder
{
/*********
** Fields
*********/
/// <summary>The local time when the next log was posted.</summary>
public string Time { get; set; }

/// <summary>The log level for the next log message.</summary>
public LogLevel Level { get; set; }

/// <summary>The mod name for the next log message.</summary>
public string Mod { get; set; }

/// <summary>The text for the next log message.</summary>
private readonly StringBuilder Text = new StringBuilder();


/*********
** Accessors
*********/
/// <summary>Whether the next log message has been started.</summary>
public bool Started { get; private set; }


/*********
** Public methods
*********/
/// <summary>Start accumulating values for a new log message.</summary>
/// <param name="time">The local time when the log was posted.</param>
/// <param name="level">The log level.</param>
/// <param name="mod">The mod name.</param>
/// <param name="text">The initial log text.</param>
/// <exception cref="InvalidOperationException">A log message is already started; call <see cref="Clear"/> before starting a new message.</exception>
public void Start(string time, LogLevel level, string mod, string text)
{
if (this.Started)
throw new InvalidOperationException("Can't start new message, previous log message isn't done yet.");

this.Started = true;

this.Time = time;
this.Level = level;
this.Mod = mod;
this.Text.Append(text);
}

/// <summary>Add a new line to the next log message being built.</summary>
/// <param name="text">The line to add.</param>
/// <exception cref="InvalidOperationException">A log message hasn't been started yet.</exception>
public void AddLine(string text)
{
if (!this.Started)
throw new InvalidOperationException("Can't add text, no log message started yet.");

this.Text.Append("\n");
this.Text.Append(text);
}

/// <summary>Get a log message for the accumulated values.</summary>
public LogMessage Build()
{
if (!this.Started)
return null;

return new LogMessage
{
Time = this.Time,
Level = this.Level,
Mod = this.Mod,
Text = this.Text.ToString()
};
}

/// <summary>Reset to start a new log message.</summary>
public void Clear()
{
this.Started = false;
this.Text.Clear();
}
}
}
66 changes: 35 additions & 31 deletions src/SMAPI.Web/Framework/LogParsing/LogParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ public ParsedLog Parse(string logText)
}

// mod path line
else if (message.Level == LogLevel.Debug && this.ModPathPattern.IsMatch(message.Text))
else if (message.Level == LogLevel.Info && this.ModPathPattern.IsMatch(message.Text))
{
Match match = this.ModPathPattern.Match(message.Text);
log.ModPath = match.Groups["path"].Value;
Expand Down Expand Up @@ -282,43 +282,47 @@ private IEnumerable<LogMessage> CollapseRepeats(IEnumerable<LogMessage> messages
/// <exception cref="LogParseException">The log text can't be parsed successfully.</exception>
private IEnumerable<LogMessage> GetMessages(string logText)
{
LogMessage message = new LogMessage();
using (StringReader reader = new StringReader(logText))
LogMessageBuilder builder = new LogMessageBuilder();
using StringReader reader = new StringReader(logText);
while (true)
{
while (true)
{
// read data
string line = reader.ReadLine();
if (line == null)
break;
Match header = this.MessageHeaderPattern.Match(line);

// validate
if (message.Text == null && !header.Success)
throw new LogParseException("Found a log message with no SMAPI metadata. Is this a SMAPI log file?");
// read line
string line = reader.ReadLine();
if (line == null)
break;

// start or continue message
if (header.Success)
{
if (message.Text != null)
yield return message;
// match header
Match header = this.MessageHeaderPattern.Match(line);
bool isNewMessage = header.Success;

message = new LogMessage
{
Time = header.Groups["time"].Value,
Level = Enum.Parse<LogLevel>(header.Groups["level"].Value, ignoreCase: true),
Mod = header.Groups["modName"].Value,
Text = line.Substring(header.Length)
};
// start/continue message
if (isNewMessage)
{
if (builder.Started)
{
yield return builder.Build();
builder.Clear();
}
else
message.Text += "\n" + line;

builder.Start(
time: header.Groups["time"].Value,
level: Enum.Parse<LogLevel>(header.Groups["level"].Value, ignoreCase: true),
mod: header.Groups["modName"].Value,
text: line.Substring(header.Length)
);
}
else
{
if (!builder.Started)
throw new LogParseException("Found a log message with no SMAPI metadata. Is this a SMAPI log file?");

// end last message
if (message.Text != null)
yield return message;
builder.AddLine(line);
}
}

// end last message
if (builder.Started)
yield return builder.Build();
}
}
}
2 changes: 2 additions & 0 deletions src/SMAPI.Web/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public static void Main(string[] args)
// configure web server
WebHost
.CreateDefaultBuilder(args)
.CaptureStartupErrors(true)
.UseSetting("detailedErrors", "true")
.UseStartup<Startup>()
.Build()
.Run();
Expand Down
12 changes: 6 additions & 6 deletions src/SMAPI.Web/SMAPI.Web.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,22 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Azure.Storage.Blobs" Version="12.3.0" />
<PackageReference Include="Azure.Storage.Blobs" Version="12.4.0" />
<PackageReference Include="Hangfire.AspNetCore" Version="1.7.9" />
<PackageReference Include="Hangfire.MemoryStorage" Version="1.6.3" />
<PackageReference Include="Hangfire.Mongo" Version="0.6.6" />
<PackageReference Include="HtmlAgilityPack" Version="1.11.20" />
<PackageReference Include="Hangfire.MemoryStorage" Version="1.7.0" />
<PackageReference Include="Hangfire.Mongo" Version="0.6.7" />
<PackageReference Include="HtmlAgilityPack" Version="1.11.23" />
<PackageReference Include="Humanizer.Core" Version="2.7.9" />
<PackageReference Include="JetBrains.Annotations" Version="2019.1.3" />
<PackageReference Include="Markdig" Version="0.18.1" />
<PackageReference Include="Markdig" Version="0.18.3" />
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Rewrite" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />
<PackageReference Include="Mongo2Go" Version="2.2.12" />
<PackageReference Include="MongoDB.Driver" Version="2.10.2" />
<PackageReference Include="Newtonsoft.Json.Schema" Version="3.0.13" />
<PackageReference Include="Pathoschild.FluentNexus" Version="0.8.0" />
<PackageReference Include="Pathoschild.FluentNexus" Version="1.0.0" />
<PackageReference Include="Pathoschild.Http.FluentClient" Version="3.3.1" />
</ItemGroup>
<ItemGroup>
Expand Down
3 changes: 1 addition & 2 deletions src/SMAPI.Web/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,7 @@ public void ConfigureServices(IServiceCollection services)
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// basic config
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
app.UseDeveloperExceptionPage();
app
.UseCors(policy => policy
.AllowAnyHeader()
Expand Down
Loading

0 comments on commit 7ca5efb

Please sign in to comment.