From 9732ddb2759774e6b22c9414e3f5341865257270 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 14 Apr 2019 21:55:11 -0400 Subject: [PATCH] avoid possible invalid state if checkEventPrecondition is called asynchronously (#636) --- .../CheckEventPreconditionErrorPatch.cs | 47 +++++++++---------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/src/SMAPI/Patches/CheckEventPreconditionErrorPatch.cs b/src/SMAPI/Patches/CheckEventPreconditionErrorPatch.cs index 673fae1c..74cfbfb0 100644 --- a/src/SMAPI/Patches/CheckEventPreconditionErrorPatch.cs +++ b/src/SMAPI/Patches/CheckEventPreconditionErrorPatch.cs @@ -15,11 +15,8 @@ namespace StardewModdingAPI.Patches /// Writes messages to the console and log file on behalf of the game. private static IMonitor MonitorForGame; - /// The method being wrapped. - private static MethodInfo OriginalMethod; - /// Whether the method is currently being intercepted. - private static bool IsArbitrated; + private static bool IsIntercepted; /********* @@ -43,8 +40,10 @@ namespace StardewModdingAPI.Patches /// The Harmony instance. public void Apply(HarmonyInstance harmony) { - CheckEventPreconditionErrorPatch.OriginalMethod = AccessTools.Method(typeof(GameLocation), "checkEventPrecondition"); - harmony.Patch(CheckEventPreconditionErrorPatch.OriginalMethod, new HarmonyMethod(AccessTools.Method(this.GetType(), nameof(CheckEventPreconditionErrorPatch.Prefix)))); + harmony.Patch( + original: AccessTools.Method(typeof(GameLocation), "checkEventPrecondition"), + prefix: new HarmonyMethod(AccessTools.Method(this.GetType(), nameof(CheckEventPreconditionErrorPatch.Prefix))) + ); } @@ -55,30 +54,30 @@ namespace StardewModdingAPI.Patches /// The instance being patched. /// The return value of the original method. /// The precondition to be parsed. + /// The method being wrapped. /// 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, ref int __result, string precondition) + private static bool Prefix(GameLocation __instance, ref int __result, string precondition, MethodInfo __originalMethod) { - if (CheckEventPreconditionErrorPatch.IsArbitrated) - { - CheckEventPreconditionErrorPatch.IsArbitrated = false; + if (CheckEventPreconditionErrorPatch.IsIntercepted) return true; - } - else + + try { - CheckEventPreconditionErrorPatch.IsArbitrated = true; - try - { - __result = (int)CheckEventPreconditionErrorPatch.OriginalMethod.Invoke(__instance, new object[] { precondition }); - return false; - } - catch (TargetInvocationException ex) - { - __result = -1; - CheckEventPreconditionErrorPatch.MonitorForGame.Log($"Failed parsing event precondition ({precondition}):\n{ex.InnerException}", LogLevel.Error); - return false; - } + CheckEventPreconditionErrorPatch.IsIntercepted = true; + __result = (int)__originalMethod.Invoke(__instance, new object[] { precondition }); + return false; + } + catch (TargetInvocationException ex) + { + __result = -1; + CheckEventPreconditionErrorPatch.MonitorForGame.Log($"Failed parsing event precondition ({precondition}):\n{ex.InnerException}", LogLevel.Error); + return false; + } + finally + { + CheckEventPreconditionErrorPatch.IsIntercepted = false; } } }