using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx.Logging; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("GameApiCompatShim")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("GameApiCompatShim")] [assembly: AssemblyTitle("GameApiCompatShim")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace GameApiCompatShim { public static class Patcher { internal static readonly ManualLogSource Log = Logger.CreateLogSource("GameApiCompatShim"); public static IEnumerable TargetDLLs { get; } = new string[1] { "Assembly-CSharp.dll" }; public static void Patch(AssemblyDefinition assembly) { ModuleDefinition mainModule = assembly.MainModule; AddOverload(mainModule, "PlayerHealth", "HurtOther", 4, false); AddOverload(mainModule, "EnemyNavMeshAgent", "Warp", 1, false); AddOverload(mainModule, "Sound", "PlayLoop", 4, 1f); } private static void AddOverload(ModuleDefinition module, string typeName, string methodName, int oldArgCount, object extraDefault) { //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Expected O, but got Unknown //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Expected O, but got Unknown //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) try { TypeDefinition type = module.GetType(typeName); if (type == null) { Log.LogWarning((object)(typeName + " not found; skipping " + methodName + " shim.")); return; } MethodDefinition val = (from x in (IEnumerable)type.Methods where ((MemberReference)x).Name == methodName && !x.IsStatic && ((MethodReference)x).Parameters.Count > oldArgCount orderby ((MethodReference)x).Parameters.Count select x).FirstOrDefault(); if (val == null) { Log.LogWarning((object)("No longer " + typeName + "." + methodName + " overload to forward to; skipping.")); return; } if (((IEnumerable)type.Methods).Any((MethodDefinition x) => ((MemberReference)x).Name == methodName && !x.IsStatic && ((MethodReference)x).Parameters.Count == oldArgCount)) { Log.LogInfo((object)$"{typeName}.{methodName}({oldArgCount} args) already present; skipping."); return; } MethodDefinition val2 = new MethodDefinition(methodName, (MethodAttributes)134, module.TypeSystem.Void); for (int num = 0; num < oldArgCount; num++) { ((MethodReference)val2).Parameters.Add(new ParameterDefinition(((ParameterReference)((MethodReference)val).Parameters[num]).ParameterType)); } val2.Body.MaxStackSize = oldArgCount + 3; ILProcessor iLProcessor = val2.Body.GetILProcessor(); iLProcessor.Emit(OpCodes.Ldarg_0); for (int num2 = 0; num2 < oldArgCount; num2++) { iLProcessor.Emit(OpCodes.Ldarg, ((MethodReference)val2).Parameters[num2]); } EmitConstant(iLProcessor, extraDefault); iLProcessor.Emit(OpCodes.Call, (MethodReference)(object)val); if (((MemberReference)((MethodReference)val).ReturnType).FullName != "System.Void") { iLProcessor.Emit(OpCodes.Pop); } iLProcessor.Emit(OpCodes.Ret); type.Methods.Add(val2); Log.LogInfo((object)$"Added compat overload {typeName}.{methodName}({oldArgCount} args) -> {((MethodReference)val).Parameters.Count}-arg current."); } catch (Exception arg) { Log.LogError((object)$"Failed to add {typeName}.{methodName} shim: {arg}"); } } private static void EmitConstant(ILProcessor il, object v) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) if (v is bool flag) { il.Emit(flag ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0); } else if (v is int num) { il.Emit(OpCodes.Ldc_I4, num); } else if (v is float num2) { il.Emit(OpCodes.Ldc_R4, num2); } else { il.Emit(OpCodes.Ldnull); } } } }