Files

137 lines
5.0 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using BepInEx.Configuration;
using CodeStage.AntiCheat.ObscuredTypes;
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 RecNetUtil
{
public static ObscuredInt GetAccountId()
{
PropertyInfo selfAccountProp = AccessTools.Property("RecNet.Accounts:LocalAccount");
object acc = selfAccountProp.GetValue(null);
Type selfAccountType = acc.GetType();
PropertyInfo accountIdProp = AccessTools.Property(selfAccountType, "AccountId");
ObscuredInt val = (ObscuredInt)accountIdProp.GetValue(acc);
return val;
}
}
public class Util
{
private static readonly PatchTypesResult UnsuccessfulPatchResult = new()
{
Type = null,
Method = null,
Success = false
};
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;
}
}
}