diff --git a/docs/release-notes.md b/docs/release-notes.md index 06a133e8..8fa1c330 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -11,6 +11,7 @@ * For modders: * Expanded `PerScreen` API: you can now get/set the value for any screen, get all active values, or clear all values. * Expanded player info received from multiplayer API/events with new `IsSplitScreen` and `ScreenID` fields. + * Game errors shown in the chatbox are now logged. * Added an option to disable rewriting mods for compatibility (thanks to Bpendragon!). This may prevent older mods from loading, but bypasses a Visual Studio crash when debugging. * For the Error Handler mod: diff --git a/src/SMAPI/Framework/SChatBox.cs b/src/SMAPI/Framework/SChatBox.cs new file mode 100644 index 00000000..e000d1cd --- /dev/null +++ b/src/SMAPI/Framework/SChatBox.cs @@ -0,0 +1,49 @@ +using StardewValley; +using StardewValley.Menus; + +namespace StardewModdingAPI.Framework +{ + /// SMAPI's implementation of the chatbox which intercepts errors for logging. + internal class SChatBox : ChatBox + { + /********* + ** Fields + *********/ + /// Encapsulates monitoring and logging. + private readonly IMonitor Monitor; + + + /********* + ** Public methods + *********/ + /// Construct an instance. + /// Encapsulates monitoring and logging. + public SChatBox(IMonitor monitor) + { + this.Monitor = monitor; + } + + /// + protected override void runCommand(string command) + { + this.Monitor.Log($"> chat command: {command}"); + base.runCommand(command); + } + + /// + public override void receiveChatMessage(long sourceFarmer, int chatKind, LocalizedContentManager.LanguageCode language, string message) + { + if (chatKind == ChatBox.errorMessage) + { + // log error + this.Monitor.Log(message, LogLevel.Error); + + // add event details if applicable + if (Game1.CurrentEvent != null && message.StartsWith("Event script error:")) + this.Monitor.Log($"In event #{Game1.CurrentEvent.id} for location {Game1.currentLocation?.NameOrUniqueName}", LogLevel.Error); + } + + base.receiveChatMessage(sourceFarmer, chatKind, language, message); + } + } +} diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs index 06c88851..1b39065f 100644 --- a/src/SMAPI/Framework/SCore.cs +++ b/src/SMAPI/Framework/SCore.cs @@ -1054,6 +1054,13 @@ namespace StardewModdingAPI.Framework this.OnReturnedToTitle(); } + // override chatbox + if (newStage == LoadStage.Loaded) + { + Game1.onScreenMenus.Remove(Game1.chatBox); + Game1.onScreenMenus.Add(Game1.chatBox = new SChatBox(this.LogManager.MonitorForGame)); + } + // raise events this.EventManager.LoadStageChanged.Raise(new LoadStageChangedEventArgs(oldStage, newStage)); if (newStage == LoadStage.None)