fix error on Linux/Mac when a mod tries to load content immediately after save is loaded
This commit is contained in:
parent
e84028f22b
commit
588b42742d
|
@ -18,6 +18,7 @@ For players:
|
|||
* SMAPI now remembers if your game crashed and offers help next time you relaunch.
|
||||
* Fixed installer finding redundant game paths on Linux.
|
||||
* Fixed save events not being raised after the first day on Linux/Mac.
|
||||
* Fixed error on Linux/Mac when a mod tries to load content immediately after the save is loaded.
|
||||
|
||||
For mod developers:
|
||||
* Added log entries for basic context changes (e.g. loaded save) to simplify troubleshooting. More detailed logging can be enabled by setting `VerboseLogging: true` in `StardewModdingAPI.config.json`.
|
||||
|
|
|
@ -264,7 +264,7 @@ namespace StardewModdingAPI.Framework
|
|||
base.Update(gameTime);
|
||||
return;
|
||||
}
|
||||
if(this.IsBetweenSaveEvents)
|
||||
if (this.IsBetweenSaveEvents)
|
||||
{
|
||||
// raise after-save
|
||||
this.IsBetweenSaveEvents = false;
|
||||
|
@ -579,6 +579,53 @@ namespace StardewModdingAPI.Framework
|
|||
|
||||
/// <summary>The method called to draw everything to the screen.</summary>
|
||||
/// <param name="gameTime">A snapshot of the game timing state.</param>
|
||||
protected override void Draw(GameTime gameTime)
|
||||
{
|
||||
Context.IsInDrawLoop = true;
|
||||
try
|
||||
{
|
||||
this.DrawImpl(gameTime);
|
||||
this.FailedDraws = 0;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// log error
|
||||
this.Monitor.Log($"An error occured in the overridden draw loop: {ex.GetLogSummary()}", LogLevel.Error);
|
||||
|
||||
// exit if irrecoverable
|
||||
if (this.FailedDraws >= this.MaxFailedDraws)
|
||||
{
|
||||
this.Monitor.ExitGameImmediately("the game crashed when drawing, and SMAPI was unable to recover the game.");
|
||||
return;
|
||||
}
|
||||
this.FailedDraws++;
|
||||
|
||||
// abort in known unrecoverable cases
|
||||
if (Game1.toolSpriteSheet?.IsDisposed == true)
|
||||
{
|
||||
this.Monitor.ExitGameImmediately("the game unexpectedly disposed the tool spritesheet, so it crashed trying to draw a tool. This is a known bug in Stardew Valley 1.2.29, and there's no way to recover from it.");
|
||||
return;
|
||||
}
|
||||
|
||||
// recover sprite batch
|
||||
try
|
||||
{
|
||||
if (Game1.spriteBatch.IsOpen(SGame.Reflection))
|
||||
{
|
||||
this.Monitor.Log("Recovering sprite batch from error...", LogLevel.Trace);
|
||||
Game1.spriteBatch.End();
|
||||
}
|
||||
}
|
||||
catch (Exception innerEx)
|
||||
{
|
||||
this.Monitor.Log($"Could not recover sprite batch state: {innerEx.GetLogSummary()}", LogLevel.Error);
|
||||
}
|
||||
}
|
||||
Context.IsInDrawLoop = false;
|
||||
}
|
||||
|
||||
/// <summary>Replicate the game's draw logic with some changes for SMAPI.</summary>
|
||||
/// <param name="gameTime">A snapshot of the game timing state.</param>
|
||||
/// <remarks>This implementation is identical to <see cref="Game1.Draw"/>, except for try..catch around menu draw code, private field references replaced by wrappers, and added events.</remarks>
|
||||
[SuppressMessage("ReSharper", "CompareOfFloatsByEqualityOperator", Justification = "copied from game code as-is")]
|
||||
[SuppressMessage("ReSharper", "LocalVariableHidesMember", Justification = "copied from game code as-is")]
|
||||
|
@ -587,10 +634,7 @@ namespace StardewModdingAPI.Framework
|
|||
[SuppressMessage("ReSharper", "RedundantCast", Justification = "copied from game code as-is")]
|
||||
[SuppressMessage("ReSharper", "RedundantExplicitNullableCreation", Justification = "copied from game code as-is")]
|
||||
[SuppressMessage("ReSharper", "RedundantTypeArgumentsOfMethod", Justification = "copied from game code as-is")]
|
||||
protected override void Draw(GameTime gameTime)
|
||||
{
|
||||
Context.IsInDrawLoop = true;
|
||||
try
|
||||
private void DrawImpl(GameTime gameTime)
|
||||
{
|
||||
if (Game1.debugMode)
|
||||
{
|
||||
|
@ -1236,45 +1280,6 @@ namespace StardewModdingAPI.Framework
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// reset failed draw count
|
||||
this.FailedDraws = 0;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// log error
|
||||
this.Monitor.Log($"An error occured in the overridden draw loop: {ex.GetLogSummary()}", LogLevel.Error);
|
||||
|
||||
// exit if irrecoverable
|
||||
if (this.FailedDraws >= this.MaxFailedDraws)
|
||||
{
|
||||
this.Monitor.ExitGameImmediately("the game crashed when drawing, and SMAPI was unable to recover the game.");
|
||||
return;
|
||||
}
|
||||
this.FailedDraws++;
|
||||
|
||||
// abort in known unrecoverable cases
|
||||
if (Game1.toolSpriteSheet?.IsDisposed == true)
|
||||
{
|
||||
this.Monitor.ExitGameImmediately("the game unexpectedly disposed the tool spritesheet, so it crashed trying to draw a tool. This is a known bug in Stardew Valley 1.2.29, and there's no way to recover from it.");
|
||||
return;
|
||||
}
|
||||
|
||||
// recover sprite batch
|
||||
try
|
||||
{
|
||||
if (Game1.spriteBatch.IsOpen(SGame.Reflection))
|
||||
{
|
||||
this.Monitor.Log("Recovering sprite batch from error...", LogLevel.Trace);
|
||||
Game1.spriteBatch.End();
|
||||
}
|
||||
}
|
||||
catch (Exception innerEx)
|
||||
{
|
||||
this.Monitor.Log($"Could not recover sprite batch state: {innerEx.GetLogSummary()}", LogLevel.Error);
|
||||
}
|
||||
}
|
||||
Context.IsInDrawLoop = false;
|
||||
}
|
||||
|
||||
/****
|
||||
|
|
Loading…
Reference in New Issue