Decompiled source of GameApiCompatShim v1.0.0

patchers\GameApiCompatShim.dll

Decompiled 5 hours ago
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<string> 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<MethodDefinition>)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<MethodDefinition>)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);
			}
		}
	}
}