avoid possible invalid state if checkEventPrecondition is called asynchronously (#636)

This commit is contained in:
Jesse Plamondon-Willard 2019-04-14 21:55:11 -04:00
parent bac92d6f26
commit 9732ddb275
No known key found for this signature in database
GPG Key ID: CF8B1456B3E29F49
1 changed files with 23 additions and 24 deletions

View File

@ -15,11 +15,8 @@ namespace StardewModdingAPI.Patches
/// <summary>Writes messages to the console and log file on behalf of the game.</summary>
private static IMonitor MonitorForGame;
/// <summary>The method being wrapped.</summary>
private static MethodInfo OriginalMethod;
/// <summary>Whether the method is currently being intercepted.</summary>
private static bool IsArbitrated;
private static bool IsIntercepted;
/*********
@ -43,8 +40,10 @@ namespace StardewModdingAPI.Patches
/// <param name="harmony">The Harmony instance.</param>
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
/// <param name="__instance">The instance being patched.</param>
/// <param name="__result">The return value of the original method.</param>
/// <param name="precondition">The precondition to be parsed.</param>
/// <param name="__originalMethod">The method being wrapped.</param>
/// <returns>Returns whether to execute the original method.</returns>
/// <remarks>This method must be static for Harmony to work correctly. See the Harmony documentation before renaming arguments.</remarks>
[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;
}
}
}