Decompiled source of PatchDumper v1.0.0

patchers/PatchDumper/PatchDumperPatcher.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using MonoMod.RuntimeDetour.HookGen;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("MonoMod.RuntimeDetour")]
[assembly: AssemblyCompany("PatchDumperPatcher")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+e84cbf52fe999cf0bffaaf174136208d93cdfee5")]
[assembly: AssemblyProduct("PatchDumperPatcher")]
[assembly: AssemblyTitle("PatchDumperPatcher")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 PatchDumperPatcher
{
	public class BaseDetourInfo
	{
		public IDetour Detour { get; }

		public Assembly Owner { get; }

		public virtual MethodBase From { get; }

		public virtual MethodBase To { get; }

		public BaseDetourInfo(IDetour detour, MethodBase from, MethodBase to, Assembly owner)
		{
			Detour = detour ?? throw new ArgumentNullException("detour");
			Owner = owner;
			From = from;
			To = to;
		}
	}
	internal static class Log
	{
		private static readonly ManualLogSource _logSource = Logger.CreateLogSource("PatchDumperPatcher");

		private static string getLogPrefix(string callerPath, string callerMemberName, int callerLineNumber)
		{
			int num = callerPath.LastIndexOf("PatchDumperPatcher\\");
			if (num >= 0)
			{
				callerPath = callerPath.Substring(num + "PatchDumperPatcher\\".Length);
			}
			return $"{callerPath}:{callerLineNumber} ({callerMemberName}) ";
		}

		internal static void Debug(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogDebug((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		internal static void Debug_NoCallerPrefix(object data)
		{
			_logSource.LogDebug(data);
		}

		internal static void Error(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogError((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		internal static void Error_NoCallerPrefix(object data)
		{
			_logSource.LogError(data);
		}

		internal static void Fatal(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogFatal((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		internal static void Fatal_NoCallerPrefix(object data)
		{
			_logSource.LogFatal(data);
		}

		internal static void Info(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogInfo((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		internal static void Info_NoCallerPrefix(object data)
		{
			_logSource.LogInfo(data);
		}

		internal static void Message(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogMessage((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		internal static void Message_NoCallerPrefix(object data)
		{
			_logSource.LogMessage(data);
		}

		internal static void Warning(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogWarning((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		internal static void Warning_NoCallerPrefix(object data)
		{
			_logSource.LogWarning(data);
		}
	}
	internal class NativeDetourInfo : BaseDetourInfo
	{
		private readonly NativeDetour _nativeDetour;

		private readonly IntPtr _fromPtr;

		private MethodBase _from;

		private readonly IntPtr _toPtr;

		private MethodBase _to;

		public override MethodBase From
		{
			get
			{
				if (_from == null)
				{
					_from = findPinnedMethodFromPtr(_fromPtr);
				}
				return _from;
			}
		}

		public override MethodBase To
		{
			get
			{
				if (_to == null)
				{
					_to = findPinnedMethodFromPtr(_toPtr);
				}
				return _to;
			}
		}

		private MethodBase findPinnedMethodFromPtr(IntPtr ptr)
		{
			foreach (MethodBase item in _nativeDetour._Pinned)
			{
				IntPtr nativeStart = DetourHelper.GetNativeStart(DetourHelper.Pin<MethodBase>(item));
				if (nativeStart == ptr)
				{
					return item;
				}
			}
			return null;
		}

		internal NativeDetourInfo(NativeDetour detour, IntPtr from, IntPtr to, Assembly owner)
			: base((IDetour)(object)detour, null, null, owner)
		{
			_nativeDetour = detour;
			_fromPtr = from;
			_toPtr = to;
		}
	}
	public static class PatcherMain
	{
		private static readonly List<BaseDetourInfo> _activeDetours;

		public static readonly ReadOnlyCollection<BaseDetourInfo> ActiveDetours;

		private static bool _activeDetoursDirty;

		private static readonly Dictionary<MethodBase, List<BaseDetourInfo>> _activeDetoursMap;

		private static readonly ReadOnlyDictionary<MethodBase, List<BaseDetourInfo>> _readOnlyActiveDetoursMap;

		private static readonly string[] _hookTypes;

		private static readonly string[] _ignoreAssemblies;

		public static ReadOnlyDictionary<MethodBase, List<BaseDetourInfo>> ActiveDetoursMap
		{
			get
			{
				refreshActiveDetours();
				return _readOnlyActiveDetoursMap;
			}
		}

		public static IEnumerable<string> TargetDLLs { get; }

		private static void refreshActiveDetours()
		{
			if (!_activeDetoursDirty)
			{
				return;
			}
			_activeDetoursDirty = false;
			_activeDetoursMap.Clear();
			foreach (BaseDetourInfo activeDetour in _activeDetours)
			{
				if (!(activeDetour.From == null))
				{
					if (!_activeDetoursMap.TryGetValue(activeDetour.From, out var value))
					{
						value = new List<BaseDetourInfo>();
						_activeDetoursMap.Add(activeDetour.From, value);
					}
					value.Add(activeDetour);
				}
			}
		}

		static PatcherMain()
		{
			_activeDetours = new List<BaseDetourInfo>();
			ActiveDetours = _activeDetours.AsReadOnly();
			_activeDetoursDirty = false;
			_activeDetoursMap = new Dictionary<MethodBase, List<BaseDetourInfo>>();
			_readOnlyActiveDetoursMap = new ReadOnlyDictionary<MethodBase, List<BaseDetourInfo>>(_activeDetoursMap);
			_hookTypes = new string[4]
			{
				typeof(Hook).FullName,
				typeof(ILHook).FullName,
				typeof(Detour).FullName,
				typeof(NativeDetour).FullName
			};
			_ignoreAssemblies = new string[1] { typeof(HookEndpointManager).Assembly.GetName().Name };
			TargetDLLs = Array.Empty<string>();
			Array.Sort(_hookTypes, (IComparer<string>?)StringComparer.OrdinalIgnoreCase);
			Array.Sort(_ignoreAssemblies, (IComparer<string>?)StringComparer.OrdinalIgnoreCase);
		}

		public static void Patch(AssemblyDefinition assembly)
		{
		}

		public static void Initialize()
		{
			Util.AppendDelegate(ref Hook.OnDetour, registerHook);
			Util.AppendDelegate(ref Hook.OnUndo, unregisterDetour);
			Util.AppendDelegate(ref ILHook.OnDetour, registerILHook);
			Util.AppendDelegate(ref ILHook.OnUndo, unregisterDetour);
			Util.AppendDelegate(ref Detour.OnDetour, registerDetour);
			Util.AppendDelegate(ref Detour.OnUndo, unregisterDetour);
			Util.AppendDelegate(ref NativeDetour.OnDetour, registerNativeDetour);
			Util.AppendDelegate(ref NativeDetour.OnUndo, unregisterDetour);
		}

		private static void registerDetourInfo(BaseDetourInfo detourInfo)
		{
			_activeDetours.Add(detourInfo);
			_activeDetoursDirty = true;
		}

		private static bool unregisterDetour(IDetour detour)
		{
			if (_activeDetours.RemoveAll((BaseDetourInfo d) => d.Detour == detour) > 0)
			{
				_activeDetoursDirty = true;
			}
			return true;
		}

		private static bool registerHook(Hook hook, MethodBase from, MethodBase to, object target)
		{
			registerDetourInfo(new BaseDetourInfo((IDetour)(object)hook, from, to, findHookOwner()));
			return true;
		}

		private static bool registerILHook(ILHook hook, MethodBase method, Manipulator manipulator)
		{
			registerDetourInfo(new BaseDetourInfo((IDetour)(object)hook, method, ((Delegate)(object)manipulator).Method, findHookOwner()));
			return true;
		}

		private static bool registerDetour(Detour detour, MethodBase from, MethodBase to)
		{
			registerDetourInfo(new BaseDetourInfo((IDetour)(object)detour, from, to, findHookOwner()));
			return true;
		}

		private static bool registerNativeDetour(NativeDetour nativeDetour, MethodBase method, IntPtr from, IntPtr to)
		{
			registerDetourInfo(new NativeDetourInfo(nativeDetour, from, to, findHookOwner()));
			return true;
		}

		private static Assembly findHookOwner(StackTrace stackTrace = null)
		{
			if (stackTrace == null)
			{
				stackTrace = new StackTrace();
			}
			StackFrame[] frames = stackTrace.GetFrames();
			Assembly assembly = null;
			for (int num = frames.Length - 1; num >= 0; num--)
			{
				Type type = frames[num].GetMethod()?.DeclaringType;
				if (!(type == null) && Array.BinarySearch<string>(_hookTypes, type.FullName, (IComparer<string>?)StringComparer.OrdinalIgnoreCase) >= 0)
				{
					for (num++; num < frames.Length; num++)
					{
						Assembly assembly2 = frames[num].GetMethod()?.DeclaringType?.Assembly;
						if (!(assembly2 == null))
						{
							string name = assembly2.GetName().Name;
							if (Array.BinarySearch(_ignoreAssemblies, name, (IComparer<string>?)StringComparer.OrdinalIgnoreCase) < 0 && !name.StartsWith("MMHOOK_", StringComparison.OrdinalIgnoreCase))
							{
								assembly = assembly2;
								break;
							}
						}
					}
					break;
				}
			}
			if (!(assembly != null))
			{
				Log.Warning($"Failed to find owner assembly for stack trace {stackTrace}", "D:\\Git\\RoR2\\PatchDumper\\PatchDumperPatcher\\PatcherMain.cs", "findHookOwner", 175);
			}
			return assembly;
		}
	}
	internal static class Util
	{
		public static void AppendDelegate<TDelegate>(ref TDelegate del, TDelegate add) where TDelegate : Delegate
		{
			del = (TDelegate)Delegate.Combine(del, add);
		}

		public static void RemoveDelegate<TDelegate>(ref TDelegate del, TDelegate remove, bool all) where TDelegate : Delegate
		{
			del = (TDelegate)(all ? Delegate.RemoveAll(del, remove) : Delegate.Remove(del, remove));
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		internal IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}

plugins/PatchDumper/PatchDumper.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HG.Reflection;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Rocks;
using Mono.Collections.Generic;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using MonoMod.Utils;
using PatchDumperPatcher;
using RoR2;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: OptIn]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("MonoMod.RuntimeDetour")]
[assembly: AssemblyCompany("PatchDumper")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+e84cbf52fe999cf0bffaaf174136208d93cdfee5")]
[assembly: AssemblyProduct("PatchDumper")]
[assembly: AssemblyTitle("PatchDumper")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 PatchDumper
{
	public static class HookExtensions
	{
		public static bool TryGetUnderlyingDetour(this IDetour detour, out Detour underlying)
		{
			Hook val = (Hook)(object)((detour is Hook) ? detour : null);
			if (val == null)
			{
				ILHook val2 = (ILHook)(object)((detour is ILHook) ? detour : null);
				if (val2 != null)
				{
					underlying = val2._Ctx.Detour;
				}
				else
				{
					underlying = null;
				}
			}
			else
			{
				underlying = val.Detour;
			}
			return underlying != null;
		}
	}
	internal static class Log
	{
		internal static ManualLogSource _logSource;

		internal static void Init(ManualLogSource logSource)
		{
			_logSource = logSource;
		}

		private static string getLogPrefix(string callerPath, string callerMemberName, int callerLineNumber)
		{
			int num = callerPath.LastIndexOf("PatchDumper\\");
			if (num >= 0)
			{
				callerPath = callerPath.Substring(num + "PatchDumper\\".Length);
			}
			return $"{callerPath}:{callerLineNumber} ({callerMemberName}) ";
		}

		[Conditional("DEBUG")]
		internal static void Debug(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogDebug((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		[Conditional("DEBUG")]
		internal static void Debug_NoCallerPrefix(object data)
		{
			_logSource.LogDebug(data);
		}

		internal static void Error(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogError((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		internal static void Error_NoCallerPrefix(object data)
		{
			_logSource.LogError(data);
		}

		internal static void Fatal(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogFatal((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		internal static void Fatal_NoCallerPrefix(object data)
		{
			_logSource.LogFatal(data);
		}

		internal static void Info(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogInfo((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		internal static void Info_NoCallerPrefix(object data)
		{
			_logSource.LogInfo(data);
		}

		internal static void Message(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogMessage((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		internal static void Message_NoCallerPrefix(object data)
		{
			_logSource.LogMessage(data);
		}

		internal static void Warning(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogWarning((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		internal static void Warning_NoCallerPrefix(object data)
		{
			_logSource.LogWarning(data);
		}
	}
	[BepInPlugin("Gorakh.PatchDumper", "PatchDumper", "1.0.0")]
	public class PatchDumperPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "Gorakh.PatchDumper";

		public const string PluginAuthor = "Gorakh";

		public const string PluginName = "PatchDumper";

		public const string PluginVersion = "1.0.0";

		internal static PatchDumperPlugin Instance { get; private set; }

		private void Awake()
		{
			Stopwatch stopwatch = Stopwatch.StartNew();
			Log.Init(((BaseUnityPlugin)this).Logger);
			Instance = SingletonHelper.Assign<PatchDumperPlugin>(Instance, this);
			stopwatch.Stop();
			Log.Info_NoCallerPrefix($"Initialized in {stopwatch.Elapsed.TotalSeconds:F2} seconds");
		}

		private void OnDestroy()
		{
			Instance = SingletonHelper.Unassign<PatchDumperPlugin>(Instance, this);
		}

		[ConCommand(commandName = "dump_hooks")]
		private static void CCDumpHooks(ConCommandArgs args)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_002b: Expected O, but got Unknown
			AssemblyDefinition val = AssemblyDefinition.CreateAssembly(new AssemblyNameDefinition("Hooks", new Version(0, 0, 0, 0)), "Hooks.dll", new ModuleParameters
			{
				Kind = (ModuleKind)0
			});
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				val.MainModule.AssemblyReferences.Add(AssemblyNameReference.Parse(assembly.FullName));
			}
			PatchDumperProcessor patchDumperProcessor = new PatchDumperProcessor(val);
			foreach (var (method, detours) in PatcherMain.ActiveDetoursMap)
			{
				patchDumperProcessor.AddDetours(method, detours);
			}
			patchDumperProcessor.Validate();
			patchDumperProcessor.OutputAssembly.Write(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)Instance).Info.Location), "Hooks.dll"));
		}
	}
	internal class PatchDumperProcessor
	{
		private static readonly Assembly _harmonyAssembly = typeof(Harmony).Assembly;

		public readonly AssemblyDefinition OutputAssembly;

		private readonly TypeReference _attributeTypeRef;

		private readonly TypeReference _voidTypeRef;

		private readonly TypeReference _stringTypeRef;

		private readonly MethodDefinition _patchInfoAttributeConstructor;

		private readonly Dictionary<Type, TypeDefinition> _cachedContainerTypes = new Dictionary<Type, TypeDefinition>();

		public PatchDumperProcessor(AssemblyDefinition outputAssembly)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Expected O, but got Unknown
			OutputAssembly = outputAssembly;
			ModuleDefinition mainModule = OutputAssembly.MainModule;
			_attributeTypeRef = mainModule.ImportReference(typeof(Attribute));
			_voidTypeRef = mainModule.ImportReference(typeof(void));
			_stringTypeRef = mainModule.ImportReference(typeof(string));
			TypeDefinition val = new TypeDefinition("", "PatchInfoAttribute", (TypeAttributes)1048832, _attributeTypeRef);
			_patchInfoAttributeConstructor = new MethodDefinition(".ctor", (MethodAttributes)6278, _voidTypeRef);
			((MethodReference)_patchInfoAttributeConstructor).Parameters.Add(new ParameterDefinition("type", (ParameterAttributes)0, _stringTypeRef));
			((MethodReference)_patchInfoAttributeConstructor).Parameters.Add(new ParameterDefinition("owner", (ParameterAttributes)0, _stringTypeRef));
			val.Methods.Add(_patchInfoAttributeConstructor);
			OutputAssembly.MainModule.Types.Add(val);
		}

		private TypeDefinition getOrCreateContainerType(Type type)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Expected O, but got Unknown
			if (type.IsGenericType)
			{
				type = type.GetGenericTypeDefinition();
			}
			if (_cachedContainerTypes.TryGetValue(type, out var value))
			{
				return value;
			}
			string text = type.Name;
			int num = text.IndexOf('`');
			if (num >= 0)
			{
				text = text.Remove(num);
			}
			Type declaringType = type.DeclaringType;
			TypeDefinition val;
			if (declaringType != null)
			{
				TypeDefinition orCreateContainerType = getOrCreateContainerType(declaringType);
				val = new TypeDefinition("", text, (TypeAttributes)385);
				orCreateContainerType.NestedTypes.Add(val);
			}
			else
			{
				string @namespace = type.Namespace;
				@namespace = ((!string.IsNullOrEmpty(@namespace)) ? ("Hook." + @namespace) : "Hook");
				val = new TypeDefinition(@namespace, text, (TypeAttributes)385);
				OutputAssembly.MainModule.Types.Add(val);
			}
			_cachedContainerTypes.Add(type, val);
			return val;
		}

		public void AddDetours(MethodBase method, List<BaseDetourInfo> detours)
		{
			if (method == null || detours == null)
			{
				return;
			}
			int count = detours.Count;
			if (count <= 0)
			{
				return;
			}
			List<BaseDetourInfo> list = new List<BaseDetourInfo>(count);
			List<BaseDetourInfo> list2 = new List<BaseDetourInfo>(count);
			List<BaseDetourInfo> list3 = new List<BaseDetourInfo>(count);
			List<BaseDetourInfo> list4 = new List<BaseDetourInfo>(count);
			foreach (BaseDetourInfo detour2 in detours)
			{
				IDetour detour = detour2.Detour;
				IDetour val = detour;
				if (!(val is Hook))
				{
					if (!(val is ILHook))
					{
						if (!(val is NativeDetour))
						{
							if (val is Detour)
							{
								list4.Add(detour2);
							}
						}
						else
						{
							list3.Add(detour2);
						}
					}
					else
					{
						list2.Add(detour2);
					}
				}
				else
				{
					list.Add(detour2);
				}
			}
			foreach (BaseDetourInfo detour3 in detours)
			{
				if (detour3.Detour.TryGetUnderlyingDetour(out var underlyingDetour))
				{
					list4.RemoveAll((BaseDetourInfo d) => d.Detour == underlyingDetour);
				}
			}
			sortDetours<ILHook>(list2);
			sortDetours<Detour>(list4);
			addILHookMethods(method, list2);
			Log.Info_NoCallerPrefix(GeneralExtensions.FullDescription(method) + " detours:");
			foreach (BaseDetourInfo detour4 in detours)
			{
				string name = ((object)detour4.Detour).GetType().Name;
				MethodBase to = detour4.To;
				Log.Info_NoCallerPrefix("    " + name + ": " + (((object)to != null) ? GeneralExtensions.FullDescription(to) : null));
			}
		}

		private void addILHookMethods(MethodBase method, List<BaseDetourInfo> ilHookDetourInfos)
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Expected O, but got Unknown
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Expected O, but got Unknown
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			if (!MethodBaseExtensions.HasMethodBody(method))
			{
				Log.Error("Method has no body, cannot dump il hooks: " + GeneralExtensions.FullDescription(method), "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "addILHookMethods", 161);
			}
			else
			{
				if (ilHookDetourInfos.Count <= 0)
				{
					return;
				}
				Log.Info("Dumping IL hooks for " + GeneralExtensions.FullDescription(method) + ":", "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "addILHookMethods", 168);
				TypeDefinition orCreateContainerType = getOrCreateContainerType(method.DeclaringType);
				DynamicMethodDefinition val = new DynamicMethodDefinition(method);
				try
				{
					MethodDefinition definition = val.Definition;
					((MemberReference)definition).Name = method.Name;
					definition.DeclaringType = orCreateContainerType;
					definition.CustomAttributes.Clear();
					IILReferenceBag referenceBag = (IILReferenceBag)new RuntimeILReferenceBag();
					foreach (BaseDetourInfo ilHookDetourInfo in ilHookDetourInfos)
					{
						ILHook val2 = (ILHook)ilHookDetourInfo.Detour;
						Log.Info("    - Applying manipulator " + GeneralExtensions.FullDescription((MethodBase)((Delegate)(object)val2.Manipulator).Method), "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "addILHookMethods", 184);
						ILContext val3 = new ILContext(definition);
						try
						{
							val3.ReferenceBag = referenceBag;
							try
							{
								val3.Invoke(val2.Manipulator);
							}
							catch (Exception arg)
							{
								Log.Error_NoCallerPrefix($"Exception invoking hook ILManipulator {GeneralExtensions.FullDescription((MethodBase)((Delegate)(object)val2.Manipulator).Method)}: {arg}");
							}
						}
						finally
						{
							((IDisposable)val3)?.Dispose();
						}
					}
					addPatchInfoAttributes(definition, ilHookDetourInfos);
					importMethodReferences(definition);
					orCreateContainerType.Methods.Add(definition);
				}
				finally
				{
					((IDisposable)val)?.Dispose();
				}
			}
		}

		private void addPatchInfoAttributes(MethodDefinition method, List<BaseDetourInfo> detourInfos)
		{
			foreach (BaseDetourInfo detourInfo in detourInfos)
			{
				addPatchInfoAttribute(method, detourInfo);
			}
		}

		private void addPatchInfoAttribute(MethodDefinition method, BaseDetourInfo detourInfo)
		{
			if (detourInfo.Owner == _harmonyAssembly)
			{
				Patches patchInfo = Harmony.GetPatchInfo(detourInfo.From);
				if (patchInfo != null)
				{
					bool flag = false;
					foreach (Patch prefix in patchInfo.Prefixes)
					{
						addPatchAttribute("HarmonyPrefix", prefix);
						flag = true;
					}
					foreach (Patch postfix in patchInfo.Postfixes)
					{
						addPatchAttribute("HarmonyPostfix", postfix);
						flag = true;
					}
					foreach (Patch transpiler in patchInfo.Transpilers)
					{
						addPatchAttribute("HarmonyTranspiler", transpiler);
						flag = true;
					}
					foreach (Patch finalizer in patchInfo.Finalizers)
					{
						addPatchAttribute("HarmonyFinalizer", finalizer);
						flag = true;
					}
					foreach (Patch iLManipulator in patchInfo.ILManipulators)
					{
						addPatchAttribute("HarmonyManipulator", iLManipulator);
						flag = true;
					}
					if (flag)
					{
						return;
					}
				}
			}
			addAttribute(((object)detourInfo.Detour).GetType().Name, detourInfo.Owner?.FullName);
			void addAttribute(string type, string owner)
			{
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Expected O, but got Unknown
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0054: Unknown result type (might be due to invalid IL or missing references)
				if (string.IsNullOrEmpty(type))
				{
					type = string.Empty;
				}
				if (string.IsNullOrEmpty(owner))
				{
					owner = string.Empty;
				}
				CustomAttribute val = new CustomAttribute((MethodReference)(object)_patchInfoAttributeConstructor);
				val.ConstructorArguments.Add(new CustomAttributeArgument(_stringTypeRef, (object)type));
				val.ConstructorArguments.Add(new CustomAttributeArgument(_stringTypeRef, (object)owner));
				method.CustomAttributes.Add(val);
			}
			void addPatchAttribute(string type, Patch patch)
			{
				addAttribute(type, patch.PatchMethod?.DeclaringType?.Assembly?.FullName);
			}
		}

		private void importMethodReferences(MethodDefinition method)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			((MethodReference)method).ReturnType = OutputAssembly.MainModule.ImportReference(((MethodReference)method).ReturnType);
			Enumerator<ParameterDefinition> enumerator = ((MethodReference)method).Parameters.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					ParameterDefinition current = enumerator.Current;
					((ParameterReference)current).ParameterType = OutputAssembly.MainModule.ImportReference(((ParameterReference)current).ParameterType);
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			Enumerator<CustomAttribute> enumerator2 = method.CustomAttributes.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					CustomAttribute current2 = enumerator2.Current;
					current2.Constructor = OutputAssembly.MainModule.ImportReference(current2.Constructor);
				}
			}
			finally
			{
				((IDisposable)enumerator2).Dispose();
			}
			Enumerator<VariableDefinition> enumerator3 = method.Body.Variables.GetEnumerator();
			try
			{
				while (enumerator3.MoveNext())
				{
					VariableDefinition current3 = enumerator3.Current;
					((VariableReference)current3).VariableType = OutputAssembly.MainModule.ImportReference(((VariableReference)current3).VariableType);
				}
			}
			finally
			{
				((IDisposable)enumerator3).Dispose();
			}
			Enumerator<ExceptionHandler> enumerator4 = method.Body.ExceptionHandlers.GetEnumerator();
			try
			{
				while (enumerator4.MoveNext())
				{
					ExceptionHandler current4 = enumerator4.Current;
					if (current4.CatchType != null)
					{
						current4.CatchType = OutputAssembly.MainModule.ImportReference(current4.CatchType);
					}
				}
			}
			finally
			{
				((IDisposable)enumerator4).Dispose();
			}
			Enumerator<Instruction> enumerator5 = method.Body.Instructions.GetEnumerator();
			try
			{
				while (enumerator5.MoveNext())
				{
					Instruction current5 = enumerator5.Current;
					object operand = current5.Operand;
					object obj = operand;
					IMetadataTokenProvider val = (IMetadataTokenProvider)((obj is IMetadataTokenProvider) ? obj : null);
					if (val == null)
					{
						if (obj is MethodBase methodBase && methodBase.DeclaringType != null)
						{
							current5.Operand = OutputAssembly.MainModule.ImportReference(methodBase);
						}
					}
					else
					{
						current5.Operand = Extensions.ImportReference(OutputAssembly.MainModule, val);
					}
				}
			}
			finally
			{
				((IDisposable)enumerator5).Dispose();
			}
		}

		private static void sortDetours<TDetour>(List<BaseDetourInfo> detourInfos) where TDetour : ISortableDetour
		{
			if (detourInfos == null || detourInfos.Count <= 1)
			{
				return;
			}
			List<TDetour> list = new List<TDetour>(detourInfos.Count);
			foreach (BaseDetourInfo detourInfo in detourInfos)
			{
				list.Add((TDetour)(object)detourInfo.Detour);
			}
			DetourSorter<TDetour>.Sort(list);
			for (int i = 0; i < list.Count; i++)
			{
				TDetour detour = list[i];
				int num = detourInfos.FindIndex(i, (BaseDetourInfo d) => d.Detour == (object)detour);
				if (num == -1)
				{
					throw new InvalidOperationException("Failed to find detour in list, collection was modified");
				}
				if (num != i)
				{
					int index = i;
					int index2 = num;
					BaseDetourInfo value = detourInfos[num];
					BaseDetourInfo value2 = detourInfos[i];
					detourInfos[index] = value;
					detourInfos[index2] = value2;
				}
			}
		}

		public void Validate()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Invalid comparison between Unknown and I4
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Invalid comparison between Unknown and I4
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Invalid comparison between Unknown and I4
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Invalid comparison between Unknown and I4
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<ModuleDefinition> enumerator = OutputAssembly.Modules.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					ModuleDefinition current = enumerator.Current;
					List<TypeDefinition> list = new List<TypeDefinition>();
					foreach (TypeDefinition allType in ModuleDefinitionRocks.GetAllTypes(current))
					{
						List<MethodDefinition> list2 = new List<MethodDefinition>();
						Enumerator<MethodDefinition> enumerator3 = allType.Methods.GetEnumerator();
						try
						{
							while (enumerator3.MoveNext())
							{
								MethodDefinition current3 = enumerator3.Current;
								bool flag = false;
								Enumerator<Instruction> enumerator4 = current3.Body.Instructions.GetEnumerator();
								try
								{
									while (enumerator4.MoveNext())
									{
										Instruction current4 = enumerator4.Current;
										OpCode opCode = current4.OpCode;
										if ((int)((OpCode)(ref opCode)).FlowControl == 2)
										{
											if (current4.Operand is MethodBase methodBase)
											{
												try
												{
													current4.Operand = current.ImportReference(methodBase);
													Log.Info($"Converted invalid call operand {GeneralExtensions.FullDescription(methodBase)} to {current4.Operand} at {current4.Offset:X4} in {((MemberReference)current3).FullName}", "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "Validate", 375);
												}
												catch (Exception ex)
												{
													Log.Error($"Failed to convert invalid call operand {GeneralExtensions.FullDescription(methodBase)} at {current4.Offset:X4} in {((MemberReference)current3).FullName}: {ex}", "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "Validate", 379);
												}
											}
											if (!(current4.Operand is IMethodSignature))
											{
												Log.Error(string.Format("Invalid call operand {0} ({1}) at {2:X4} in {3}", current4.Operand, current4.Operand?.GetType()?.FullName ?? "null", current4.Offset, ((MemberReference)current3).FullName), "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "Validate", 385);
												flag = true;
											}
										}
										opCode = current4.OpCode;
										OperandType operandType = ((OpCode)(ref opCode)).OperandType;
										OperandType val = operandType;
										if ((int)val == 1 || (int)val == 4 || val - 11 <= 1)
										{
											if (current4.Operand is FieldInfo fieldInfo)
											{
												try
												{
													current4.Operand = current.ImportReference(fieldInfo);
													Log.Info($"Converted invalid inline field operand {fieldInfo.DeclaringType.FullName}.{fieldInfo.Name} to {current4.Operand} at {current4.Offset:X4} in {((MemberReference)current3).FullName}", "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "Validate", 402);
												}
												catch (Exception ex2)
												{
													Log.Error($"Failed to convert invalid inline field operand {fieldInfo.DeclaringType.FullName}.{fieldInfo.Name} at {current4.Offset:X4} in {((MemberReference)current3).FullName}: {ex2}", "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "Validate", 406);
												}
											}
											else if (current4.Operand is MethodBase methodBase2)
											{
												try
												{
													current4.Operand = current.ImportReference(methodBase2);
													Log.Info($"Converted invalid inline method operand {GeneralExtensions.FullDescription(methodBase2)} to {current4.Operand} at {current4.Offset:X4} in {((MemberReference)current3).FullName}", "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "Validate", 414);
												}
												catch (Exception ex3)
												{
													Log.Error($"Failed to convert invalid inline method operand {GeneralExtensions.FullDescription(methodBase2)} at {current4.Offset:X4} in {((MemberReference)current3).FullName}: {ex3}", "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "Validate", 418);
												}
											}
											else if (current4.Operand is Type type)
											{
												try
												{
													current4.Operand = current.ImportReference(type);
													Log.Info($"Converted invalid inline type operand {GeneralExtensions.FullDescription(type)} to {current4.Operand} at {current4.Offset:X4} in {((MemberReference)current3).FullName}", "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "Validate", 426);
												}
												catch (Exception ex4)
												{
													Log.Error($"Failed to convert invalid inline type operand {GeneralExtensions.FullDescription(type)} at {current4.Offset:X4} in {((MemberReference)current3).FullName}: {ex4}", "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "Validate", 430);
												}
											}
											else if (!(current4.Operand is IMetadataTokenProvider))
											{
												Log.Warning($"Unknown inline operand {current4.Operand} ({current4.Operand?.GetType()?.FullName}) at {current4.Offset:X4} in {((MemberReference)current3).FullName}", "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "Validate", 435);
											}
											if (!(current4.Operand is IMetadataTokenProvider))
											{
												object[] array = new object[6];
												opCode = current4.OpCode;
												array[0] = ((OpCode)(ref opCode)).OperandType;
												opCode = current4.OpCode;
												array[1] = ((OpCode)(ref opCode)).Name;
												array[2] = current4.Operand;
												array[3] = current4.Operand?.GetType()?.FullName ?? "null";
												array[4] = current4.Offset;
												array[5] = ((MemberReference)current3).FullName;
												Log.Error(string.Format("Invalid {0} ({1}) operand {2} ({3}) at {4:X4} in {5}", array), "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "Validate", 440);
												flag = true;
											}
										}
										object operand = current4.Operand;
										IMemberDefinition val2 = (IMemberDefinition)((operand is IMemberDefinition) ? operand : null);
										if (val2 != null && val2.DeclaringType == null)
										{
											Log.Error($"Invalid member reference in method {((MemberReference)current3).FullName} at {current4.Offset:X4} ({val2})", "D:\\Git\\RoR2\\PatchDumper\\PatchDumper\\PatchDumperProcessor.cs", "Validate", 451);
											flag = true;
										}
									}
								}
								finally
								{
									((IDisposable)enumerator4).Dispose();
								}
								if (flag)
								{
									list2.Add(current3);
								}
							}
						}
						finally
						{
							((IDisposable)enumerator3).Dispose();
						}
						foreach (MethodDefinition item in list2)
						{
							allType.Methods.Remove(item);
						}
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		internal IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}