From e1aac57a51f1286e6bbe69db355541da0445767e Mon Sep 17 00:00:00 2001 From: Sinai <49360850+sinai-dev@users.noreply.github.com> Date: Tue, 12 Apr 2022 00:27:20 +1000 Subject: [PATCH] Refactor class for future expansion --- src/Runtime/UnityCrashPrevention.cs | 30 +++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/Runtime/UnityCrashPrevention.cs b/src/Runtime/UnityCrashPrevention.cs index 6b9b909..6f33ffb 100644 --- a/src/Runtime/UnityCrashPrevention.cs +++ b/src/Runtime/UnityCrashPrevention.cs @@ -1,7 +1,7 @@ -using HarmonyLib; -using System; +using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Text; using UnityEngine; using UnityExplorer.CacheObject; @@ -10,29 +10,39 @@ namespace UnityExplorer.Runtime { internal static class UnityCrashPrevention { + static readonly HarmonyLib.Harmony harmony = new ($"{ExplorerCore.GUID}.crashprevention"); + internal static void Init() + { + TryPatch("get_renderingDisplaySize", nameof(Canvas_renderingDisplaySize_Prefix)); + + IEnumerable patched = harmony.GetPatchedMethods(); + if (patched.Any()) + ExplorerCore.Log( + $"Initialized UnityCrashPrevention for: {string.Join(", ", patched.Select(it => $"{it.DeclaringType.Name}.{it.Name}").ToArray())}"); + } + + internal static void TryPatch(string orig, string prefix, Type[] argTypes = null) { try { - ExplorerCore.Harmony.PatchAll(typeof(UnityCrashPrevention)); - ExplorerCore.Log("Initialized UnityCrashPrevention."); + harmony.Patch( + HarmonyLib.AccessTools.Method(typeof(T), orig, argTypes), + new HarmonyLib.HarmonyMethod(HarmonyLib.AccessTools.Method(typeof(UnityCrashPrevention), prefix))); } catch //(Exception ex) { - //ExplorerCore.Log($"Exception setting up Canvas crash prevention patch: {ex}"); + //ExplorerCore.Log($"Exception patching {typeof(T).Name}.{orig}: {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 (I think from Unity trying to read from null ptr). - [HarmonyPatch(typeof(Canvas), "renderingDisplaySize", MethodType.Getter)] - [HarmonyPrefix] - internal static void Prefix_Canvas_renderingDisplaySize(Canvas __instance) + internal static void Canvas_renderingDisplaySize_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."); + throw new InvalidOperationException("Canvas is set to RenderMode.WorldSpace but not worldCamera is set."); } } }