fix crash when closing game window in multiplayer mode (#453)
This commit is contained in:
parent
6113482bef
commit
8e9b374173
|
@ -114,6 +114,9 @@ namespace StardewModdingAPI.Framework
|
|||
/// <summary>A callback to invoke after the game finishes initialising.</summary>
|
||||
private readonly Action OnGameInitialised;
|
||||
|
||||
/// <summary>A callback to invoke when the game exits.</summary>
|
||||
private readonly Action OnGameExiting;
|
||||
|
||||
/// <summary>Simplifies access to private game code.</summary>
|
||||
private readonly Reflector Reflection;
|
||||
|
||||
|
@ -136,7 +139,8 @@ namespace StardewModdingAPI.Framework
|
|||
/// <param name="reflection">Simplifies access to private game code.</param>
|
||||
/// <param name="eventManager">Manages SMAPI events for mods.</param>
|
||||
/// <param name="onGameInitialised">A callback to invoke after the game finishes initialising.</param>
|
||||
internal SGame(IMonitor monitor, Reflector reflection, EventManager eventManager, Action onGameInitialised)
|
||||
/// <param name="onGameExiting">A callback to invoke when the game exits.</param>
|
||||
internal SGame(IMonitor monitor, Reflector reflection, EventManager eventManager, Action onGameInitialised, Action onGameExiting)
|
||||
{
|
||||
// init XNA
|
||||
Game1.graphics.GraphicsProfile = GraphicsProfile.HiDef;
|
||||
|
@ -147,6 +151,7 @@ namespace StardewModdingAPI.Framework
|
|||
this.FirstUpdate = true;
|
||||
this.Reflection = reflection;
|
||||
this.OnGameInitialised = onGameInitialised;
|
||||
this.OnGameExiting = onGameExiting;
|
||||
if (this.ContentCore == null) // shouldn't happen since CreateContentManager is called first, but let's init here just in case
|
||||
this.ContentCore = new ContentCore(this.Content.ServiceProvider, this.Content.RootDirectory, Thread.CurrentThread.CurrentUICulture, this.Monitor, reflection);
|
||||
|
||||
|
@ -167,6 +172,16 @@ namespace StardewModdingAPI.Framework
|
|||
});
|
||||
}
|
||||
|
||||
/// <summary>Perform cleanup logic when the game exits.</summary>
|
||||
/// <param name="sender">The event sender.</param>
|
||||
/// <param name="args">The event args.</param>
|
||||
/// <remarks>This overrides the logic in <see cref="Game1.OnExiting"/> and <see cref="Game1.exitEvent"/> to let SMAPI clean up before exit.</remarks>
|
||||
protected override void OnExiting(object sender, EventArgs args)
|
||||
{
|
||||
Game1.multiplayer.Disconnect();
|
||||
this.OnGameExiting?.Invoke();
|
||||
}
|
||||
|
||||
/****
|
||||
** Intercepted methods & events
|
||||
****/
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
@ -30,6 +31,7 @@ using StardewModdingAPI.Framework.Utilities;
|
|||
using StardewValley;
|
||||
using Monitor = StardewModdingAPI.Framework.Monitor;
|
||||
using SObject = StardewValley.Object;
|
||||
using ThreadState = System.Threading.ThreadState;
|
||||
|
||||
namespace StardewModdingAPI
|
||||
{
|
||||
|
@ -197,7 +199,7 @@ namespace StardewModdingAPI
|
|||
// override game
|
||||
SGame.MonitorDuringInitialisation = this.Monitor;
|
||||
SGame.ReflectorDuringInitialisation = this.Reflection;
|
||||
this.GameInstance = new SGame(this.Monitor, this.Reflection, this.EventManager, this.InitialiseAfterGameStart);
|
||||
this.GameInstance = new SGame(this.Monitor, this.Reflection, this.EventManager, this.InitialiseAfterGameStart, this.Dispose);
|
||||
StardewValley.Program.gamePtr = this.GameInstance;
|
||||
|
||||
// add exit handler
|
||||
|
@ -221,10 +223,6 @@ namespace StardewModdingAPI
|
|||
}).Start();
|
||||
|
||||
// hook into game events
|
||||
#if SMAPI_FOR_WINDOWS
|
||||
((Form)Control.FromHandle(this.GameInstance.Window.Handle)).FormClosing += (sender, args) => this.Dispose();
|
||||
#endif
|
||||
this.GameInstance.Exiting += (sender, e) => this.Dispose();
|
||||
ContentEvents.AfterLocaleChanged += (sender, e) => this.OnLocaleChanged();
|
||||
|
||||
// set window titles
|
||||
|
@ -271,12 +269,11 @@ namespace StardewModdingAPI
|
|||
/// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
|
||||
public void Dispose()
|
||||
{
|
||||
this.Monitor.Log("Disposing...", LogLevel.Trace);
|
||||
|
||||
// skip if already disposed
|
||||
if (this.IsDisposed)
|
||||
return;
|
||||
this.IsDisposed = true;
|
||||
this.Monitor.Log("Disposing...", LogLevel.Trace);
|
||||
|
||||
// dispose mod data
|
||||
foreach (IModMetadata mod in this.ModRegistry.GetAll())
|
||||
|
@ -298,6 +295,9 @@ namespace StardewModdingAPI
|
|||
this.CancellationTokenSource?.Dispose();
|
||||
this.GameInstance?.Dispose();
|
||||
this.LogFile?.Dispose();
|
||||
|
||||
// end game (moved from Game1.OnExiting to let us clean up first)
|
||||
Process.GetCurrentProcess().Kill();
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue