fix errors reading empty JSON files

This commit is contained in:
Jesse Plamondon-Willard 2022-05-06 18:06:47 -04:00
parent 87d5288287
commit b834ed7ef5
No known key found for this signature in database
GPG Key ID: CF8B1456B3E29F49
3 changed files with 27 additions and 8 deletions

View File

@ -8,6 +8,7 @@
* Removed experimental 'aggressive memory optimizations' option.
_This was disabled by default and is no longer needed in most cases. Memory usage will be better reduced by reworked asset propagation in the upcoming SMAPI 4.0.0._
* Fixed 'content file was not found' error when the game tries to load unlocalized text from a localizable mod data asset.
* Fixed error reading empty JSON files. These are now treated as if they didn't exist like before 3.14.0.
* Updated compatibility list.
## 3.14.0

View File

@ -108,12 +108,11 @@ namespace StardewModdingAPI.Toolkit.Serialization
/// <summary>Deserialize JSON text if possible.</summary>
/// <typeparam name="TModel">The model type.</typeparam>
/// <param name="json">The raw JSON text.</param>
public TModel Deserialize<TModel>(string json)
public TModel? Deserialize<TModel>(string json)
{
try
{
return JsonConvert.DeserializeObject<TModel>(json, this.JsonSettings)
?? throw new InvalidOperationException($"Couldn't deserialize model type '{typeof(TModel)}' from empty or null JSON.");
return JsonConvert.DeserializeObject<TModel>(json, this.JsonSettings);
}
catch (JsonReaderException)
{

View File

@ -9,6 +9,7 @@ using StardewModdingAPI.Events;
using StardewModdingAPI.Framework.Events;
using StardewModdingAPI.Framework.Networking;
using StardewModdingAPI.Framework.Reflection;
using StardewModdingAPI.Internal;
using StardewModdingAPI.Toolkit.Serialization;
using StardewModdingAPI.Utilities;
using StardewValley;
@ -489,8 +490,8 @@ namespace StardewModdingAPI.Framework
private RemoteContextModel? ReadContext(BinaryReader reader)
{
string data = reader.ReadString();
RemoteContextModel model = this.JsonHelper.Deserialize<RemoteContextModel>(data);
return model.ApiVersion != null
RemoteContextModel? model = this.JsonHelper.Deserialize<RemoteContextModel>(data);
return model?.ApiVersion != null
? model
: null; // no data available for vanilla players
}
@ -499,13 +500,31 @@ namespace StardewModdingAPI.Framework
/// <param name="message">The raw message to parse.</param>
private void ReceiveModMessage(IncomingMessage message)
{
// parse message
// read message JSON
string json = message.Reader.ReadString();
ModMessageModel model = this.JsonHelper.Deserialize<ModMessageModel>(json);
HashSet<long> playerIDs = new HashSet<long>(model.ToPlayerIDs ?? this.GetKnownPlayerIDs());
if (this.LogNetworkTraffic)
this.Monitor.Log($"Received message: {json}.");
// deserialize model
ModMessageModel? model;
try
{
model = this.JsonHelper.Deserialize<ModMessageModel>(json);
if (model is null)
{
this.Monitor.Log($"Received invalid mod message from {message.FarmerID}.\nRaw message data: {json}");
return;
}
}
catch (Exception ex)
{
this.Monitor.Log($"Received invalid mod message from {message.FarmerID}.\nRaw message data: {json}\nError details: {ex.GetLogSummary()}");
return;
}
// get player IDs
HashSet<long> playerIDs = new HashSet<long>(model.ToPlayerIDs ?? this.GetKnownPlayerIDs());
// notify local mods
if (playerIDs.Contains(Game1.player.UniqueMultiplayerID))
this.OnModMessageReceived(model);