From accaa6c0e03e99411d7b10f938dd17b142b8eedc Mon Sep 17 00:00:00 2001 From: berkay2578 Date: Sun, 14 Apr 2019 12:29:23 +0300 Subject: checkEventPrecondition crash fix --- .../Patches/CheckEventPreconditionErrorPatch.cs | 77 ++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 src/SMAPI/Patches/CheckEventPreconditionErrorPatch.cs (limited to 'src/SMAPI/Patches') diff --git a/src/SMAPI/Patches/CheckEventPreconditionErrorPatch.cs b/src/SMAPI/Patches/CheckEventPreconditionErrorPatch.cs new file mode 100644 index 00000000..63eca5d7 --- /dev/null +++ b/src/SMAPI/Patches/CheckEventPreconditionErrorPatch.cs @@ -0,0 +1,77 @@ +using System.Diagnostics.CodeAnalysis; +using System.Reflection; + +using Harmony; + +using StardewModdingAPI.Framework.Patching; +using StardewModdingAPI.Framework.Reflection; + +using StardewValley; + +namespace StardewModdingAPI.Patches { + /// A Harmony patch for the constructor which intercepts invalid dialogue lines and logs an error instead of crashing. + internal class CheckEventPreconditionErrorPatch : IHarmonyPatch { + /********* + ** Private methods + *********/ + /// Writes messages to the console and log file on behalf of the game. + private static IMonitor MonitorForGame; + + /// Local variable to store the patched method. + private static MethodInfo method; + /// Local variable to check if the method was already arbitrated. + private static bool isArbitrated; + + + /********* + ** Accessors + *********/ + /// A unique name for this patch. + public string Name => $"{nameof(CheckEventPreconditionErrorPatch)}"; + + + /********* + ** Public methods + *********/ + /// Construct an instance. + /// Writes messages to the console and log file on behalf of the game. + /// Simplifies access to private code. + public CheckEventPreconditionErrorPatch(IMonitor monitorForGame, Reflector reflector) { + CheckEventPreconditionErrorPatch.MonitorForGame = monitorForGame; + } + + + /// Apply the Harmony patch. + /// The Harmony instance. + public void Apply(HarmonyInstance harmony) { + method = AccessTools.Method(typeof(GameLocation), "checkEventPrecondition"); + MethodInfo transpiler = AccessTools.Method(this.GetType(), nameof(CheckEventPreconditionErrorPatch.Prefix)); + harmony.Patch(method, new HarmonyMethod(transpiler)); + } + + /********* + ** Private methods + *********/ + /// The method to call instead of the GameLocation.CheckEventPrecondition. + /// The instance being patched. + /// The precondition to be parsed. + /// Returns whether to execute the original method. + /// This method must be static for Harmony to work correctly. See the Harmony documentation before renaming arguments. + [SuppressMessage("ReSharper", "InconsistentNaming", Justification = "Argument names are defined by Harmony.")] + private static bool Prefix(GameLocation __instance, string precondition) { + if (isArbitrated) { + isArbitrated = false; + return true; + } else { + isArbitrated = true; + try { + method.Invoke(__instance, new object[] { precondition }); + } catch (System.Exception ex) { + CheckEventPreconditionErrorPatch.MonitorForGame.Log($"Failed parsing event info. Event precondition: {precondition}\n{ex}", LogLevel.Error); + } + + return false; + } + } + } +} -- cgit