This repository has been archived on 2026-05-30. You can view files and clone it, but cannot push or open issues or pull requests.
Files
undead-universal-patch-il2cpp/Core/Util.cs
2025-08-12 22:54:54 -04:00

122 lines
4.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using BepInEx.Configuration;
using HarmonyLib;
using undead_universal_patch_il2cpp.Core.Config;
namespace undead_universal_patch_il2cpp.Core
{
public class PatchTypesResult
{
public string Description;
public Type Type;
public MethodInfo Method;
public bool Success;
}
public class Util
{
private static readonly PatchTypesResult UnsuccessfulPatchResult = new()
{
Type = null,
Method = null,
Success = false
};
public static string LocalInstanceGuid { set; get; }
public static void ConditionalDebug(string msg)
{
if (GenericConfig.PatchDebug.Value) UniversalPatchPlugin.Log.LogDebug(msg);
}
public static PatchTypesResult ConfigsPreparePatchTypes(ConfigEntry<bool>[] config, string description, string targetTypeName, string methodName)
{
if (config.All(conf => conf.Value)) return VerifyPatchTypes(description, targetTypeName, methodName);
else return UnsuccessfulPatchResult;
}
public static PatchTypesResult ConfigPreparePatchTypes(ConfigEntry<bool> config, string description, string targetTypeName, string methodName)
{
if (config.Value) return VerifyPatchTypes(description, targetTypeName, methodName);
else return UnsuccessfulPatchResult;
}
public static PatchTypesResult PreparePatchTypes(string description, string targetTypeName, string methodName)
{
return VerifyPatchTypes(description, targetTypeName, methodName);
}
public static PatchTypesResult PreparePatchSpecificTypes(string description, string targetTypeName, string methodName, string[] generics)
{
return VerifyPatchTypes(description, targetTypeName, methodName, [.. generics]);
}
private static PatchTypesResult VerifyPatchTypes(string description, string targetTypeName, string methodName, List<string> generics = null)
{
ConditionalDebug($"Loading patch '{description}'");
Type targetType = AccessTools.TypeByName(targetTypeName);
if (targetType == null)
{
UniversalPatchPlugin.Log.LogWarning($"Patch '{description}' disabled. The type for this patch was not found.");
return UnsuccessfulPatchResult;
}
List<Type> types = null;
if (generics != null)
{
types = generics.Select(AccessTools.TypeByName).ToList();
if (!types.All(type => type != null))
{
UniversalPatchPlugin.Log.LogWarning($"Patch '{description}' disabled. One or more generics for this patch were not found.");
return UnsuccessfulPatchResult;
}
}
MethodInfo method;
if (generics != null && types != null)
{
ConditionalDebug($"Fetching method type: Type '{targetType.Name}', Method '{methodName}', Generics: {types.Count}");
method = AccessTools.Method(targetType, methodName, [.. types]);
}
else
{
ConditionalDebug($"Fetching method type: Type '{targetType.Name}', Method '{methodName}'");
method = AccessTools.Method(targetType, methodName);
}
if (method == null)
{
UniversalPatchPlugin.Log.LogWarning($"Patch '{description}' disabled. The method for this patch was not found.");
return UnsuccessfulPatchResult;
}
UniversalPatchPlugin.Log.LogInfo($"Patch '{description}' succeeded validation.");
return new PatchTypesResult
{
Description = description,
Type = targetType,
Method = method,
Success = true
};
}
public static PatchTypesResult PostRequireTypes(PatchTypesResult result, object[] objects)
{
if (result.Success)
{
if (!objects.All(obj => obj != null))
{
UniversalPatchPlugin.Log.LogError($"'{result.Description}' failed: A postrequire type was not found.");
return UnsuccessfulPatchResult;
}
else return result;
}
else return UnsuccessfulPatchResult;
}
}
}