From 64193ff1b0cb3cc9770488512277695830cc5a5b Mon Sep 17 00:00:00 2001 From: Sinai <49360850+sinai-dev@users.noreply.github.com> Date: Mon, 21 Feb 2022 01:45:46 +1100 Subject: [PATCH] Use a patch instead of manual check on every property --- src/CacheObject/CacheProperty.cs | 2 -- src/Runtime/UnityCrashPrevention.cs | 31 +++++++++++++++++++++-------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/CacheObject/CacheProperty.cs b/src/CacheObject/CacheProperty.cs index d4ed940..fee7b9e 100644 --- a/src/CacheObject/CacheProperty.cs +++ b/src/CacheObject/CacheProperty.cs @@ -30,8 +30,6 @@ namespace UnityExplorer.CacheObject { try { - UnityCrashPrevention.CheckPropertyInfoEvaluation(this); - object ret; if (HasArguments) ret = PropertyInfo.GetValue(DeclaringInstance, this.Evaluator.TryParseArguments()); diff --git a/src/Runtime/UnityCrashPrevention.cs b/src/Runtime/UnityCrashPrevention.cs index 2ed142a..98f3032 100644 --- a/src/Runtime/UnityCrashPrevention.cs +++ b/src/Runtime/UnityCrashPrevention.cs @@ -1,4 +1,5 @@ -using System; +using HarmonyLib; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -7,17 +8,31 @@ using UnityExplorer.CacheObject; namespace UnityExplorer.Runtime { - public static class UnityCrashPrevention + internal static class UnityCrashPrevention { - public static void CheckPropertyInfoEvaluation(CacheProperty cacheProp) + internal static void Init() { - if (cacheProp.PropertyInfo.Name == "renderingDisplaySize" - && cacheProp.Owner.Target is Canvas canvas - && canvas.renderMode == RenderMode.WorldSpace - && !canvas.worldCamera) + try { - throw new Exception("Canvas is set to RenderMode.WorldSpace but has no worldCamera, cannot get value."); + ExplorerCore.Harmony.PatchAll(typeof(UnityCrashPrevention)); + ExplorerCore.Log("Initialized UnityCrashPrevention."); } + catch //(Exception ex) + { + //ExplorerCore.Log($"Exception setting up Canvas crash prevention patch: {ex}"); + } + } + + // In Unity 2020 they introduced "Canvas.renderingDisplaySize". + // If you try to get the value on a Canvas which has a renderMode value of WorldSpace and no worldCamera set, + // the game will Crash when Unity tries to read from a null ptr (I think). + [HarmonyPatch(typeof(Canvas), "renderingDisplaySize", MethodType.Getter)] + [HarmonyPrefix] + internal static void Prefix(Canvas __instance) + { + if (__instance.renderMode == RenderMode.WorldSpace && !__instance.worldCamera) + throw new InvalidOperationException( + "Canvas is set to RenderMode.WorldSpace but not worldCamera is set, cannot get renderingDisplaySize."); } } }