Refactor class for future expansion

This commit is contained in:
Sinai 2022-04-12 00:27:20 +10:00
parent 8f1f6cd0b2
commit e1aac57a51

View File

@ -1,7 +1,7 @@
using HarmonyLib; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Text; using System.Text;
using UnityEngine; using UnityEngine;
using UnityExplorer.CacheObject; using UnityExplorer.CacheObject;
@ -10,29 +10,39 @@ namespace UnityExplorer.Runtime
{ {
internal static class UnityCrashPrevention internal static class UnityCrashPrevention
{ {
static readonly HarmonyLib.Harmony harmony = new ($"{ExplorerCore.GUID}.crashprevention");
internal static void Init() internal static void Init()
{
TryPatch<Canvas>("get_renderingDisplaySize", nameof(Canvas_renderingDisplaySize_Prefix));
IEnumerable<MethodBase> 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<T>(string orig, string prefix, Type[] argTypes = null)
{ {
try try
{ {
ExplorerCore.Harmony.PatchAll(typeof(UnityCrashPrevention)); harmony.Patch(
ExplorerCore.Log("Initialized UnityCrashPrevention."); HarmonyLib.AccessTools.Method(typeof(T), orig, argTypes),
new HarmonyLib.HarmonyMethod(HarmonyLib.AccessTools.Method(typeof(UnityCrashPrevention), prefix)));
} }
catch //(Exception ex) 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". // 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, // 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). // the game will Crash (I think from Unity trying to read from null ptr).
[HarmonyPatch(typeof(Canvas), "renderingDisplaySize", MethodType.Getter)] internal static void Canvas_renderingDisplaySize_Prefix(Canvas __instance)
[HarmonyPrefix]
internal static void Prefix_Canvas_renderingDisplaySize(Canvas __instance)
{ {
if (__instance.renderMode == RenderMode.WorldSpace && !__instance.worldCamera) if (__instance.renderMode == RenderMode.WorldSpace && !__instance.worldCamera)
throw new InvalidOperationException( throw new InvalidOperationException("Canvas is set to RenderMode.WorldSpace but not worldCamera is set.");
"Canvas is set to RenderMode.WorldSpace but not worldCamera is set, cannot get renderingDisplaySize.");
} }
} }
} }