Decompiled source of MonkeyInjectionLibrary v1.0.1

BepInEx/patchers/MonkeyInjectionLibrary.dll

Decompiled 10 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using InjectionLibrary.Attributes;
using InjectionLibrary.Exceptions;
using InjectionLibrary.Patches;
using InjectionLibrary.Utils;
using Microsoft.CodeAnalysis;
using Mono;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
using MonoMod.Utils;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("BepInEx")]
[assembly: IgnoresAccessChecksTo("Mono.Cecil")]
[assembly: IgnoresAccessChecksTo("Mono.Cecil.Mdb")]
[assembly: IgnoresAccessChecksTo("Mono.Cecil.Pdb")]
[assembly: IgnoresAccessChecksTo("Mono.Cecil.Rocks")]
[assembly: AssemblyCompany("mattymatty")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1")]
[assembly: AssemblyInformationalVersion("1.0.1+0983314c868ad9483e0f0051ea5dcb906907aa8b")]
[assembly: AssemblyProduct("MonkeyInjectionLibrary")]
[assembly: AssemblyTitle("MonkeyInjectionLibrary")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.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 InjectionLibrary
{
	public enum ErrorHandlingStrategy
	{
		Terminate,
		Ignore,
		LogWarning,
		LogError
	}
	public enum ErrorLevel
	{
		None,
		Soft,
		Hard
	}
	internal static class Preloader
	{
		private static class DevelopConfig
		{
			internal static ConfigEntry<bool> Enabled;

			internal static ConfigEntry<string> OutputPath;

			internal static ConfigEntry<string> OutputExtension;

			public static void Init()
			{
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				ConfigFile val = new ConfigFile(Utility.CombinePaths(new string[2] { MainDir, "MonkeyInjectionLibrary.Development.cfg" }), true, Plugin);
				Enabled = val.Bind<bool>("DevelOptions", "Enabled", false, "Enable development dll output");
				OutputPath = val.Bind<string>("DevelOptions", "OutputPath", MainDir, "Folder where to write the modified dlls");
				OutputExtension = val.Bind<string>("DevelOptions", "OutputExtension", ".pdll", "Extension to use for the modified dlls\n( Do not use .dll if outputting inside the BepInEx folders )");
				PropertyInfo property = ((object)val).GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic);
				Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)property.GetValue(val, null);
				dictionary.Clear();
				val.Save();
			}
		}

		private static class ModConfig
		{
			internal static ConfigEntry<bool> EnhancedCompatibility;

			public static void Init()
			{
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				ConfigFile val = new ConfigFile(Utility.CombinePaths(new string[2]
				{
					Paths.ConfigPath,
					"MonkeyInjectionLibrary.cfg"
				}), true, Plugin);
				EnhancedCompatibility = val.Bind<bool>("LoadOptions", "enhanced_compatibility", false, "Try to load missing assemblies from BepInEx folders");
				PropertyInfo property = ((object)val).GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic);
				Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)property.GetValue(val, null);
				dictionary.Clear();
				val.Save();
			}
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static AssemblyResolveEventHandler <>9__23_0;

			public static ResolveEventHandler <>9__23_1;

			public static Func<CustomAttribute, bool> <>9__25_0;

			public static Func<CustomAttribute, bool> <>9__25_1;

			public static Func<CustomAttribute, bool> <>9__25_2;

			internal AssemblyDefinition <Initialize>b__23_0(object _, AssemblyNameReference reference)
			{
				AssemblyName assemblyName = default(AssemblyName);
				if (!Utility.TryParseAssemblyName(reference.FullName, ref assemblyName))
				{
					Log.LogWarning((object)("Could not parse assembly name: " + reference.FullName));
					return null;
				}
				AssemblyDefinition result = default(AssemblyDefinition);
				foreach (string item in new string[3]
				{
					Paths.BepInExAssemblyDirectory,
					Paths.PluginPath,
					Paths.PatcherPluginPath
				}.Concat(Paths.DllSearchPaths))
				{
					if (Utility.TryResolveDllAssembly(assemblyName, item, _readerParameters, ref result))
					{
						return result;
					}
				}
				Log.LogWarning((object)$"Could not find assembly: {assemblyName}");
				return null;
			}

			internal Assembly <Initialize>b__23_1(object _, ResolveEventArgs args)
			{
				AssemblyName assemblyName = new AssemblyName(args.Name);
				Assembly result = default(Assembly);
				foreach (string item in new string[3]
				{
					Paths.BepInExAssemblyDirectory,
					Paths.PluginPath,
					Paths.PatcherPluginPath
				}.Concat(Paths.DllSearchPaths))
				{
					if (Utility.TryResolveDllAssembly(assemblyName, item, ref result))
					{
						return result;
					}
				}
				return null;
			}

			internal bool <EnumerateTargetDlLs>b__25_0(CustomAttribute x)
			{
				return ((MemberReference)x.AttributeType).FullName == RequiresInjectionAttributeName;
			}

			internal bool <EnumerateTargetDlLs>b__25_1(CustomAttribute at)
			{
				return ((MemberReference)at.AttributeType).FullName == HandleErrorsAttributeName;
			}

			internal bool <EnumerateTargetDlLs>b__25_2(CustomAttribute at)
			{
				return ((MemberReference)at.AttributeType).FullName == InjectInterfaceAttributeName;
			}
		}

		[CompilerGenerated]
		private sealed class <EnumerateTargetDlLs>d__25 : IEnumerable<string>, IEnumerable, IEnumerator<string>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private string <>2__current;

			private int <>l__initialThreadId;

			private Dictionary<string, Dictionary<string, List<(TypeDefinition @interface, ErrorHandlingStrategy strategy)>>>.KeyCollection.Enumerator <>7__wrap1;

			string IEnumerator<string>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <EnumerateTargetDlLs>d__25(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>7__wrap1 = default(Dictionary<string, Dictionary<string, List<(TypeDefinition, ErrorHandlingStrategy)>>>.KeyCollection.Enumerator);
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
				//IL_0183: Unknown result type (might be due to invalid IL or missing references)
				//IL_0188: Unknown result type (might be due to invalid IL or missing references)
				//IL_0239: Unknown result type (might be due to invalid IL or missing references)
				//IL_023e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0247: Unknown result type (might be due to invalid IL or missing references)
				//IL_024e: Expected O, but got Unknown
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
					{
						<>1__state = -1;
						string[] files = Directory.GetFiles(Path.GetFullPath(Paths.PluginPath), "*.dll", SearchOption.AllDirectories);
						string[] array = files;
						foreach (string text in array)
						{
							try
							{
								AssemblyDefinition val = AssemblyDefinition.ReadAssembly(text, _readerParameters);
								if (!val.HasCustomAttributes)
								{
									val.Dispose();
									continue;
								}
								CustomAttribute val2 = ((IEnumerable<CustomAttribute>)val.CustomAttributes).FirstOrDefault((Func<CustomAttribute, bool>)((CustomAttribute x) => ((MemberReference)x.AttributeType).FullName == RequiresInjectionAttributeName));
								if (val2 == null)
								{
									val.Dispose();
									continue;
								}
								Log.LogDebug((object)("Assembly " + ((AssemblyNameReference)val.Name).Name + " Wants to inject something"));
								if (((AssemblyNameReference)val.Name).Name != Path.GetFileNameWithoutExtension(text))
								{
									Log.LogFatal((object)("\r\n⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f\r\nFound assembly \"" + Path.GetRelativePath(Paths.BepInExRootPath, text) + "\"\r\nwith AssemblyName of \"" + ((AssemblyNameReference)val.Name).Name + "\".\r\nThe file name has to be the same as the AssemblyName!\r\n⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f⚠\ufe0f"));
									inError = ErrorLevel.Soft;
									break;
								}
								LoadedAssemblies.AddLast(val);
								ErrorHandlingStrategy item = ErrorHandlingStrategy.Terminate;
								CustomAttribute val3 = ((IEnumerable<CustomAttribute>)val.CustomAttributes).FirstOrDefault((Func<CustomAttribute, bool>)((CustomAttribute at) => ((MemberReference)at.AttributeType).FullName == HandleErrorsAttributeName));
								CustomAttributeArgument val4;
								if (val3 != null)
								{
									val4 = val3.ConstructorArguments[0];
									item = (ErrorHandlingStrategy)((CustomAttributeArgument)(ref val4)).Value;
								}
								Enumerator<TypeDefinition> enumerator = val.MainModule.Types.GetEnumerator();
								try
								{
									while (enumerator.MoveNext())
									{
										TypeDefinition current = enumerator.Current;
										if (!current.HasCustomAttributes)
										{
											continue;
										}
										CustomAttribute[] array2 = ((IEnumerable<CustomAttribute>)current.CustomAttributes).Where((CustomAttribute at) => ((MemberReference)at.AttributeType).FullName == InjectInterfaceAttributeName).ToArray();
										if (!array2.Any())
										{
											continue;
										}
										Log.LogDebug((object)("Found " + ((MemberReference)current).FullName));
										CustomAttribute[] array3 = array2;
										foreach (CustomAttribute val5 in array3)
										{
											val4 = val5.ConstructorArguments[0];
											TypeReference val6 = (TypeReference)((CustomAttributeArgument)(ref val4)).Value;
											TargetTypes.Add(val6.GetAssemblyQualifiedName());
											string key = val6.Scope.Name + ".dll";
											string fullName = ((MemberReference)val6).FullName;
											if (!Interfaces.TryGetValue(key, out Dictionary<string, List<(TypeDefinition, ErrorHandlingStrategy)>> value))
											{
												value = new Dictionary<string, List<(TypeDefinition, ErrorHandlingStrategy)>>();
												Interfaces[key] = value;
											}
											if (!value.TryGetValue(fullName, out var value2))
											{
												value2 = (value[fullName] = new List<(TypeDefinition, ErrorHandlingStrategy)>());
											}
											value2.Add((current, item));
										}
									}
								}
								finally
								{
									((IDisposable)enumerator).Dispose();
								}
							}
							catch (BadImageFormatException ex)
							{
								Log.LogWarning((object)("Skipping " + Path.GetRelativePath(Paths.BepInExRootPath, text) + " because it's not a valid .NET assembly. Full error: " + ex.Message));
							}
							catch (Exception arg)
							{
								inError = ErrorLevel.Hard;
								Log.LogFatal((object)$"Exception parsing {Path.GetRelativePath(Paths.BepInExRootPath, text)}:\n{arg}");
								break;
							}
						}
						Log.LogInfo((object)$"Found {LoadedAssemblies.Count} assemblies that require Injections");
						<>7__wrap1 = Interfaces.Keys.GetEnumerator();
						<>1__state = -3;
						break;
					}
					case 1:
						<>1__state = -3;
						break;
					}
					if (<>7__wrap1.MoveNext())
					{
						string current2 = <>7__wrap1.Current;
						if (inError <= ErrorLevel.Soft)
						{
							_targetAssembly = current2;
							<>2__current = current2;
							<>1__state = 1;
							return true;
						}
					}
					<>m__Finally1();
					<>7__wrap1 = default(Dictionary<string, Dictionary<string, List<(TypeDefinition, ErrorHandlingStrategy)>>>.KeyCollection.Enumerator);
					_targetAssembly = null;
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				((IDisposable)<>7__wrap1).Dispose();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<string> IEnumerable<string>.GetEnumerator()
			{
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					return this;
				}
				return new <EnumerateTargetDlLs>d__25(0);
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<string>)this).GetEnumerator();
			}
		}

		public const string GUID = "mattymatty.MonkeyInjectionLibrary";

		public const string NAME = "MonkeyInjectionLibrary";

		public const string VERSION = "1.0.1";

		internal static readonly BepInPlugin Plugin = new BepInPlugin("mattymatty.MonkeyInjectionLibrary", "MonkeyInjectionLibrary", "1.0.1");

		private static ReaderParameters _readerParameters;

		private static readonly string RequiresInjectionAttributeName = typeof(RequiresInjectionsAttribute).FullName;

		private static readonly string InjectInterfaceAttributeName = typeof(InjectInterfaceAttribute).FullName;

		private static readonly string HandleErrorsAttributeName = typeof(HandleErrorsAttribute).FullName;

		private static readonly string MainDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

		private static readonly Dictionary<string, Dictionary<string, List<(TypeDefinition @interface, ErrorHandlingStrategy strategy)>>> Interfaces = new Dictionary<string, Dictionary<string, List<(TypeDefinition, ErrorHandlingStrategy)>>>();

		private static readonly LinkedList<AssemblyDefinition> LoadedAssemblies = new LinkedList<AssemblyDefinition>();

		private static readonly HashSet<string> TargetTypes = new HashSet<string>();

		private static ErrorLevel _inError;

		private static string _targetAssembly;

		internal static ManualLogSource Log { get; } = Logger.CreateLogSource("InjectionLibrary");


		internal static ErrorLevel inError
		{
			get
			{
				return _inError;
			}
			set
			{
				if (value > _inError)
				{
					_inError = value;
				}
			}
		}

		public static IEnumerable<string> TargetDLLs => EnumerateTargetDlLs();

		public static void Patch(ref AssemblyDefinition assembly)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			if (inError > ErrorLevel.Soft)
			{
				return;
			}
			try
			{
				if (Interfaces.TryGetValue(_targetAssembly, out Dictionary<string, List<(TypeDefinition, ErrorHandlingStrategy)>> value))
				{
					Log.LogInfo((object)("Patching " + _targetAssembly));
					Enumerator<ModuleDefinition> enumerator = assembly.Modules.GetEnumerator();
					try
					{
						while (enumerator.MoveNext())
						{
							ModuleDefinition current = enumerator.Current;
							current.assembly_resolver = Disposable.NotOwned<IAssemblyResolver>((IAssemblyResolver)(object)TypeLoader.Resolver);
							current.metadata_resolver = (IMetadataResolver)new MetadataResolver((IAssemblyResolver)(object)TypeLoader.Resolver);
							Enumerator<TypeDefinition> enumerator2 = current.Types.GetEnumerator();
							try
							{
								while (enumerator2.MoveNext())
								{
									TypeDefinition current2 = enumerator2.Current;
									if (!value.TryGetValue(((MemberReference)current2).FullName, out var value2))
									{
										continue;
									}
									TargetTypes.Remove(((TypeReference)(object)current2).GetAssemblyQualifiedName());
									foreach (var (@interface, errorHandlingStrategy) in value2)
									{
										current2.ImplementInterface((TypeReference)(object)@interface, errorHandlingStrategy);
									}
								}
							}
							finally
							{
								((IDisposable)enumerator2).Dispose();
							}
						}
					}
					finally
					{
						((IDisposable)enumerator).Dispose();
					}
				}
			}
			catch (Exception ex)
			{
				inError = ErrorLevel.Hard;
				if (!(ex is TerminationException))
				{
					Log.LogFatal((object)$"Exception while patching {((AssemblyNameReference)assembly.Name).Name}:\n{ex}");
				}
			}
			if (DevelopConfig.Enabled.Value)
			{
				string text = DevelopConfig.OutputPath.Value + "/" + ((AssemblyNameReference)assembly.Name).Name + DevelopConfig.OutputExtension.Value;
				Log.LogWarning((object)("Saving modified Assembly to " + text));
				assembly.Write(text);
			}
		}

		public static void Initialize()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			Log.LogInfo((object)"Preloader Started");
			ModConfig.Init();
			DevelopConfig.Init();
			DefaultAssemblyResolver val = new DefaultAssemblyResolver();
			_readerParameters = new ReaderParameters
			{
				ReadWrite = false,
				ReadSymbols = false,
				ReadingMode = (ReadingMode)2,
				AssemblyResolver = (IAssemblyResolver)(object)val
			};
			object obj = <>c.<>9__23_0;
			if (obj == null)
			{
				AssemblyResolveEventHandler val2 = delegate(object _, AssemblyNameReference reference)
				{
					AssemblyName assemblyName2 = default(AssemblyName);
					if (!Utility.TryParseAssemblyName(reference.FullName, ref assemblyName2))
					{
						Log.LogWarning((object)("Could not parse assembly name: " + reference.FullName));
						return null;
					}
					AssemblyDefinition result2 = default(AssemblyDefinition);
					foreach (string item in new string[3]
					{
						Paths.BepInExAssemblyDirectory,
						Paths.PluginPath,
						Paths.PatcherPluginPath
					}.Concat(Paths.DllSearchPaths))
					{
						if (Utility.TryResolveDllAssembly(assemblyName2, item, _readerParameters, ref result2))
						{
							return result2;
						}
					}
					Log.LogWarning((object)$"Could not find assembly: {assemblyName2}");
					return null;
				};
				<>c.<>9__23_0 = val2;
				obj = (object)val2;
			}
			((BaseAssemblyResolver)val).ResolveFailure += (AssemblyResolveEventHandler)obj;
			if (!ModConfig.EnhancedCompatibility.Value)
			{
				return;
			}
			AppDomain.CurrentDomain.AssemblyResolve += delegate(object _, ResolveEventArgs args)
			{
				AssemblyName assemblyName = new AssemblyName(args.Name);
				Assembly result = default(Assembly);
				foreach (string item2 in new string[3]
				{
					Paths.BepInExAssemblyDirectory,
					Paths.PluginPath,
					Paths.PatcherPluginPath
				}.Concat(Paths.DllSearchPaths))
				{
					if (Utility.TryResolveDllAssembly(assemblyName, item2, ref result))
					{
						return result;
					}
				}
				return null;
			};
		}

		public static void Finish()
		{
			foreach (AssemblyDefinition loadedAssembly in LoadedAssemblies)
			{
				try
				{
					loadedAssembly.Dispose();
				}
				catch (Exception)
				{
				}
			}
			LoadedAssemblies.Clear();
			if (TargetTypes.Count > 0 && inError < ErrorLevel.Hard)
			{
				inError = ErrorLevel.Soft;
				Log.LogFatal((object)("Some Injection types have not been found:\n |- " + string.Join("\n |- ", TargetTypes)));
			}
			if (inError > ErrorLevel.None)
			{
				Log.LogWarning((object)"\r\n//////////////////////////////////////////////////////////////////\r\n\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\r\nAn Error Occurred while injecting code, \r\nthe game is most likely in a broken state and will probably crash!\r\n//////////////////////////////////////////////////////////////////\r\n\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\");
				if (ConsoleManager.ConsoleActive)
				{
					Log.LogWarning((object)"Pausing for 10s to let the user read the logs");
					Thread.Sleep(TimeSpan.FromSeconds(10.0));
				}
				if (inError >= ErrorLevel.Hard)
				{
					Harmony.CreateAndPatchAll(typeof(TerminationPatch), "mattymatty.MonkeyInjectionLibrary");
				}
			}
			Log.LogInfo((object)"Preloader Finished");
		}

		[IteratorStateMachine(typeof(<EnumerateTargetDlLs>d__25))]
		private static IEnumerable<string> EnumerateTargetDlLs()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <EnumerateTargetDlLs>d__25(-2);
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "mattymatty.MonkeyInjectionLibrary";

		public const string PLUGIN_NAME = "MonkeyInjectionLibrary";

		public const string PLUGIN_VERSION = "1.0.1";
	}
}
namespace InjectionLibrary.Utils
{
	internal static class InjectionHelper
	{
		private static class Interfaces
		{
			internal static void ImplementProperties(in TypeDefinition type, TypeDefinition @interface, in HashSet<IMemberDefinition> blacklist, ErrorHandlingStrategy errorHandlingStrategy)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				Enumerator<PropertyDefinition> enumerator = @interface.Properties.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						PropertyDefinition current = enumerator.Current;
						ImplementProperty(in type, current, in blacklist, errorHandlingStrategy);
					}
				}
				finally
				{
					((IDisposable)enumerator).Dispose();
				}
			}

			internal static void ImplementEvents(in TypeDefinition type, TypeDefinition @interface, in HashSet<IMemberDefinition> blacklist, ErrorHandlingStrategy errorHandlingStrategy)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				Enumerator<EventDefinition> enumerator = @interface.Events.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						EventDefinition current = enumerator.Current;
						ImplementEvent(in type, current, in blacklist, errorHandlingStrategy);
					}
				}
				finally
				{
					((IDisposable)enumerator).Dispose();
				}
			}

			internal static void ImplementMethods(in TypeDefinition type, TypeDefinition @interface, in HashSet<IMemberDefinition> blacklist, ErrorHandlingStrategy errorHandlingStrategy)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				Enumerator<MethodDefinition> enumerator = @interface.Methods.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						MethodDefinition current = enumerator.Current;
						ImplementMethod(in type, current, in blacklist, errorHandlingStrategy);
					}
				}
				finally
				{
					((IDisposable)enumerator).Dispose();
				}
			}

			private static void ImplementProperty(in TypeDefinition type, PropertyDefinition property, in HashSet<IMemberDefinition> blacklist, ErrorHandlingStrategy errorHandlingStrategy)
			{
				//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
				//IL_01fe: Expected O, but got Unknown
				//IL_021c: 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_023a: Unknown result type (might be due to invalid IL or missing references)
				//IL_039c: Unknown result type (might be due to invalid IL or missing references)
				//IL_03a3: Expected O, but got Unknown
				//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
				//IL_03ce: Expected O, but got Unknown
				//IL_03de: Unknown result type (might be due to invalid IL or missing references)
				//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
				//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
				//IL_0408: Unknown result type (might be due to invalid IL or missing references)
				PropertyDefinition propertyImpl2 = null;
				FieldDefinition backingField = null;
				bool hasImplementation = false;
				if (!blacklist.Add((IMemberDefinition)(object)property))
				{
					return;
				}
				Preloader.Log.LogDebug((object)("Adding Property  '" + ((MemberReference)property).Name + "' to " + ((MemberReference)type).FullName + "'"));
				CustomAttribute val = ((IEnumerable<CustomAttribute>)property.CustomAttributes).FirstOrDefault((Func<CustomAttribute, bool>)((CustomAttribute a) => ((MemberReference)a.AttributeType).FullName == ErrorStrategyAttributeName));
				if (val != null)
				{
					errorHandlingStrategy = val.GetAttributeInstance<HandleErrorsAttribute>().Strategy;
				}
				TypeReference typeRef = ((MemberReference)type).Module.ImportReference(((PropertyReference)property).PropertyType);
				MethodDefinition getMethod = property.GetMethod;
				if (getMethod != null && getMethod.IsAbstract && blacklist.Add((IMemberDefinition)(object)property.GetMethod))
				{
					Preloader.Log.LogDebug((object)("Adding getter of '" + ((MemberReference)property).Name + "' to " + ((MemberReference)type).FullName + "'"));
					MethodDefinition val2 = Extensions.FindMethod(type, "get_" + ((MemberReference)property).Name, true);
					if (val2 != null)
					{
						HandleError("Method 'get_" + ((MemberReference)property).Name + "' is already defined in '" + ((MemberReference)type).FullName + "'", errorHandlingStrategy);
						val2.Attributes = (MethodAttributes)2502;
					}
					else
					{
						Init(in type, out propertyImpl2);
						val2 = new MethodDefinition("get_" + ((MemberReference)property).Name, (MethodAttributes)2502, typeRef);
						val2.MarkAsInjected<MethodDefinition>(((MemberReference)type).Module);
						ILProcessor iLProcessor = val2.Body.GetILProcessor();
						iLProcessor.Emit(OpCodes.Ldarg_0);
						iLProcessor.Emit(OpCodes.Ldfld, (FieldReference)(object)backingField);
						iLProcessor.Emit(OpCodes.Ret);
						type.Methods.Add(val2);
						propertyImpl2.GetMethod = val2;
					}
					val2.CopyCustomAttributes<MethodDefinition>(property.GetMethod);
				}
				getMethod = property.SetMethod;
				if (getMethod != null && getMethod.IsAbstract && blacklist.Add((IMemberDefinition)(object)property.SetMethod))
				{
					Preloader.Log.LogDebug((object)("Adding setter of '" + ((MemberReference)property).Name + "' to " + ((MemberReference)type).FullName + "'"));
					MethodDefinition val3 = Extensions.FindMethod(type, "set_" + ((MemberReference)property).Name, true);
					if (val3 != null)
					{
						HandleError("Method 'set_" + ((MemberReference)property).Name + "' is already defined in '" + ((MemberReference)type).FullName + "'", errorHandlingStrategy);
						val3.Attributes = (MethodAttributes)2502;
					}
					else
					{
						if (!hasImplementation)
						{
							Init(in type, out propertyImpl2);
						}
						val3 = new MethodDefinition("set_" + ((MemberReference)property).Name, (MethodAttributes)2502, ((MemberReference)type).Module.TypeSystem.Void);
						val3.MarkAsInjected<MethodDefinition>(((MemberReference)type).Module);
						((MethodReference)val3).Parameters.Add(new ParameterDefinition("value", (ParameterAttributes)0, typeRef));
						ILProcessor iLProcessor2 = val3.Body.GetILProcessor();
						iLProcessor2.Emit(OpCodes.Ldarg_0);
						iLProcessor2.Emit(OpCodes.Ldarg_1);
						iLProcessor2.Emit(OpCodes.Stfld, (FieldReference)(object)backingField);
						iLProcessor2.Emit(OpCodes.Ret);
						type.Methods.Add(val3);
						propertyImpl2.SetMethod = val3;
					}
					val3.CopyCustomAttributes<MethodDefinition>(property.SetMethod);
				}
				if (!hasImplementation)
				{
					Preloader.Log.LogDebug((object)("Default Property '" + ((MemberReference)property).Name + "' to " + ((MemberReference)type).FullName + "'"));
				}
				else
				{
					type.Fields.TryAdd<FieldDefinition>(backingField);
					type.Properties.TryAdd<PropertyDefinition>(propertyImpl2);
				}
				void Init(in TypeDefinition type, out PropertyDefinition propertyImpl)
				{
					//IL_0054: Unknown result type (might be due to invalid IL or missing references)
					//IL_005e: Expected O, but got Unknown
					//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
					//IL_00cf: Expected O, but got Unknown
					propertyImpl = null;
					backingField = Extensions.FindField(type, "<" + ((MemberReference)property).Name + ">k__BackingField");
					if (backingField == null)
					{
						backingField = new FieldDefinition("<" + ((MemberReference)property).Name + ">k__BackingField", (FieldAttributes)1, typeRef);
						backingField.MarkAsInjected<FieldDefinition>(((MemberReference)type).Module);
					}
					else
					{
						HandleError("Field '<" + ((MemberReference)property).Name + ">k__BackingField' already exists in " + ((MemberReference)type).FullName, errorHandlingStrategy);
					}
					propertyImpl = Extensions.FindProperty(type, ((MemberReference)property).Name);
					if (propertyImpl == null)
					{
						propertyImpl = new PropertyDefinition(((MemberReference)property).Name, (PropertyAttributes)0, typeRef);
						propertyImpl.CopyCustomAttributes<PropertyDefinition>(property);
						propertyImpl.MarkAsInjected<PropertyDefinition>(((MemberReference)type).Module);
					}
					else
					{
						HandleError("Property '" + ((MemberReference)property).Name + "' already exists in " + ((MemberReference)type).FullName, errorHandlingStrategy);
					}
					hasImplementation = true;
				}
			}

			private static void ImplementEvent(in TypeDefinition type, EventDefinition @event, in HashSet<IMemberDefinition> blacklist, ErrorHandlingStrategy errorHandlingStrategy)
			{
				//IL_0202: Unknown result type (might be due to invalid IL or missing references)
				//IL_0209: Expected O, but got Unknown
				//IL_022a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0234: Expected O, but got Unknown
				//IL_0244: Unknown result type (might be due to invalid IL or missing references)
				//IL_0250: Unknown result type (might be due to invalid IL or missing references)
				//IL_025c: Unknown result type (might be due to invalid IL or missing references)
				//IL_026e: Unknown result type (might be due to invalid IL or missing references)
				//IL_027a: Unknown result type (might be due to invalid IL or missing references)
				//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
				//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
				//IL_0451: Unknown result type (might be due to invalid IL or missing references)
				//IL_0458: Expected O, but got Unknown
				//IL_0479: Unknown result type (might be due to invalid IL or missing references)
				//IL_0483: Expected O, but got Unknown
				//IL_0493: Unknown result type (might be due to invalid IL or missing references)
				//IL_049f: Unknown result type (might be due to invalid IL or missing references)
				//IL_04ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_04bd: Unknown result type (might be due to invalid IL or missing references)
				//IL_04c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_0515: Unknown result type (might be due to invalid IL or missing references)
				//IL_052c: Unknown result type (might be due to invalid IL or missing references)
				//IL_053e: Unknown result type (might be due to invalid IL or missing references)
				//IL_06a0: Unknown result type (might be due to invalid IL or missing references)
				//IL_06a7: Expected O, but got Unknown
				//IL_06c5: Unknown result type (might be due to invalid IL or missing references)
				//IL_06ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_06e7: Unknown result type (might be due to invalid IL or missing references)
				//IL_06ff: Unknown result type (might be due to invalid IL or missing references)
				//IL_0709: Expected O, but got Unknown
				//IL_0732: Unknown result type (might be due to invalid IL or missing references)
				//IL_073e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0755: Unknown result type (might be due to invalid IL or missing references)
				//IL_077b: Unknown result type (might be due to invalid IL or missing references)
				//IL_07cc: Unknown result type (might be due to invalid IL or missing references)
				EventDefinition eventImpl2 = null;
				FieldDefinition backingField = null;
				bool hasImplementation = false;
				if (!blacklist.Add((IMemberDefinition)(object)@event))
				{
					return;
				}
				Preloader.Log.LogDebug((object)("Adding Event     '" + ((MemberReference)@event).Name + "' to " + ((MemberReference)type).FullName + "'"));
				CustomAttribute val = ((IEnumerable<CustomAttribute>)@event.CustomAttributes).FirstOrDefault((Func<CustomAttribute, bool>)((CustomAttribute a) => ((MemberReference)a.AttributeType).FullName == ErrorStrategyAttributeName));
				if (val != null)
				{
					errorHandlingStrategy = val.GetAttributeInstance<HandleErrorsAttribute>().Strategy;
				}
				TypeReference typeRef = ((MemberReference)type).Module.ImportReference(((EventReference)@event).EventType);
				MethodDefinition addMethod = @event.AddMethod;
				if (addMethod != null && addMethod.IsAbstract && blacklist.Add((IMemberDefinition)(object)@event.AddMethod))
				{
					Preloader.Log.LogDebug((object)("Adding add of    '" + ((MemberReference)@event).Name + "' to " + ((MemberReference)type).FullName + "'"));
					MethodDefinition val2 = Extensions.FindMethod(type, "add_" + ((MemberReference)@event).Name, true);
					if (val2 != null)
					{
						HandleError("Method 'add_" + ((MemberReference)@event).Name + "' is already defined in '" + ((MemberReference)type).FullName + "'", errorHandlingStrategy);
						val2.Attributes = (MethodAttributes)2502;
					}
					else
					{
						Init(in type, out eventImpl2);
						val2 = new MethodDefinition("add_" + ((MemberReference)@event).Name, (MethodAttributes)2502, ((MemberReference)type).Module.TypeSystem.Void);
						val2.MarkAsInjected<MethodDefinition>(((MemberReference)type).Module);
						((MethodReference)val2).Parameters.Add(new ParameterDefinition("value", (ParameterAttributes)0, typeRef));
						ILProcessor iLProcessor = val2.Body.GetILProcessor();
						iLProcessor.Emit(OpCodes.Ldarg_0);
						iLProcessor.Emit(OpCodes.Ldarg_0);
						iLProcessor.Emit(OpCodes.Ldfld, (FieldReference)(object)backingField);
						iLProcessor.Emit(OpCodes.Ldarg_1);
						iLProcessor.Emit(OpCodes.Call, ((MemberReference)type).Module.ImportReference((MethodBase)typeof(Delegate).GetMethod("Combine", new Type[2]
						{
							typeof(Delegate),
							typeof(Delegate)
						})));
						iLProcessor.Emit(OpCodes.Castclass, ((EventReference)@event).EventType);
						iLProcessor.Emit(OpCodes.Stfld, (FieldReference)(object)backingField);
						iLProcessor.Emit(OpCodes.Ret);
						type.Methods.Add(val2);
						eventImpl2.AddMethod = val2;
					}
					val2.CopyCustomAttributes<MethodDefinition>(@event.AddMethod);
				}
				addMethod = @event.RemoveMethod;
				if (addMethod != null && addMethod.IsAbstract && blacklist.Add((IMemberDefinition)(object)@event.RemoveMethod))
				{
					if (!hasImplementation)
					{
						Init(in type, out eventImpl2);
					}
					Preloader.Log.LogDebug((object)("Adding remove of '" + ((MemberReference)@event).Name + "' to " + ((MemberReference)type).FullName + "'"));
					MethodDefinition val3 = Extensions.FindMethod(type, "remove_" + ((MemberReference)@event).Name, true);
					if (val3 != null)
					{
						HandleError("Method 'remove_" + ((MemberReference)@event).Name + "' is already defined in '" + ((MemberReference)type).FullName + "'", errorHandlingStrategy);
						val3.Attributes = (MethodAttributes)2502;
					}
					else
					{
						val3 = new MethodDefinition("remove_" + ((MemberReference)@event).Name, (MethodAttributes)2502, ((MemberReference)type).Module.TypeSystem.Void);
						val3.MarkAsInjected<MethodDefinition>(((MemberReference)type).Module);
						((MethodReference)val3).Parameters.Add(new ParameterDefinition("value", (ParameterAttributes)0, typeRef));
						ILProcessor iLProcessor2 = val3.Body.GetILProcessor();
						iLProcessor2.Emit(OpCodes.Ldarg_0);
						iLProcessor2.Emit(OpCodes.Ldarg_0);
						iLProcessor2.Emit(OpCodes.Ldfld, (FieldReference)(object)backingField);
						iLProcessor2.Emit(OpCodes.Ldarg_1);
						iLProcessor2.Emit(OpCodes.Call, ((MemberReference)type).Module.ImportReference((MethodBase)typeof(Delegate).GetMethod("Remove", new Type[2]
						{
							typeof(Delegate),
							typeof(Delegate)
						})));
						iLProcessor2.Emit(OpCodes.Castclass, ((EventReference)@event).EventType);
						iLProcessor2.Emit(OpCodes.Stfld, (FieldReference)(object)backingField);
						iLProcessor2.Emit(OpCodes.Ret);
						type.Methods.Add(val3);
						eventImpl2.RemoveMethod = val3;
					}
					val3.CopyCustomAttributes<MethodDefinition>(@event.RemoveMethod);
				}
				addMethod = @event.InvokeMethod;
				if (addMethod != null && addMethod.IsAbstract && blacklist.Add((IMemberDefinition)(object)@event.InvokeMethod))
				{
					Preloader.Log.LogDebug((object)("Adding raise of  '" + ((MemberReference)@event).Name + "' to " + ((MemberReference)type).FullName + "'"));
					MethodDefinition val4 = Extensions.FindMethod(type, "raise_" + ((MemberReference)@event).Name, true);
					if (val4 != null)
					{
						HandleError("Method 'raise_" + ((MemberReference)@event).Name + "' is already defined in '" + ((MemberReference)type).FullName + "'", errorHandlingStrategy);
						val4.Attributes = (MethodAttributes)2502;
					}
					else
					{
						if (!hasImplementation)
						{
							Init(in type, out eventImpl2);
						}
						val4 = new MethodDefinition("raise_" + ((MemberReference)@event).Name, (MethodAttributes)2502, ((MemberReference)type).Module.TypeSystem.Void);
						val4.MarkAsInjected<MethodDefinition>(((MemberReference)type).Module);
						Enumerator<ParameterDefinition> enumerator = ((MethodReference)@event.InvokeMethod).Parameters.GetEnumerator();
						try
						{
							while (enumerator.MoveNext())
							{
								ParameterDefinition current = enumerator.Current;
								((MethodReference)val4).Parameters.Add(new ParameterDefinition(((ParameterReference)current).Name, current.Attributes, ((MemberReference)type).Module.ImportReference(((ParameterReference)current).ParameterType)));
							}
						}
						finally
						{
							((IDisposable)enumerator).Dispose();
						}
						ILProcessor iLProcessor3 = val4.Body.GetILProcessor();
						iLProcessor3.Emit(OpCodes.Ldarg_0);
						iLProcessor3.Emit(OpCodes.Ldfld, (FieldReference)(object)backingField);
						for (int i = 0; i < ((MethodReference)val4).Parameters.Count; i++)
						{
							iLProcessor3.Emit(OpCodes.Ldarg, i + 1);
						}
						iLProcessor3.Emit(OpCodes.Callvirt, ((MemberReference)type).Module.ImportReference((MethodReference)(object)((IEnumerable<MethodDefinition>)((EventReference)@event).EventType.Resolve().Methods).First((MethodDefinition m) => ((MemberReference)m).Name == "Invoke")));
						iLProcessor3.Emit(OpCodes.Ret);
						type.Methods.Add(val4);
						eventImpl2.InvokeMethod = val4;
					}
					val4.CopyCustomAttributes<MethodDefinition>(@event.InvokeMethod);
				}
				if (hasImplementation)
				{
					type.Fields.TryAdd<FieldDefinition>(backingField);
					type.Events.TryAdd<EventDefinition>(eventImpl2);
				}
				void Init(in TypeDefinition type, out EventDefinition eventImpl)
				{
					//IL_0036: Unknown result type (might be due to invalid IL or missing references)
					//IL_0040: Expected O, but got Unknown
					//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
					//IL_00b1: Expected O, but got Unknown
					eventImpl = null;
					backingField = Extensions.FindField(type, ((MemberReference)@event).Name);
					if (backingField == null)
					{
						backingField = new FieldDefinition(((MemberReference)@event).Name, (FieldAttributes)1, typeRef);
						backingField.MarkAsInjected<FieldDefinition>(((MemberReference)type).Module);
					}
					else
					{
						HandleError("Field '" + ((MemberReference)@event).Name + "' already exists in " + ((MemberReference)type).FullName, errorHandlingStrategy);
					}
					eventImpl = Extensions.FindEvent(type, ((MemberReference)@event).Name);
					if (eventImpl == null)
					{
						eventImpl = new EventDefinition(((MemberReference)@event).Name, (EventAttributes)0, typeRef);
						eventImpl.CopyCustomAttributes<EventDefinition>(@event);
						eventImpl.MarkAsInjected<EventDefinition>(((MemberReference)type).Module);
					}
					else
					{
						HandleError("Event '" + ((MemberReference)@event).Name + "' already exists in " + ((MemberReference)type).FullName, errorHandlingStrategy);
					}
					hasImplementation = true;
				}
			}

			private static void ImplementMethod(in TypeDefinition type, MethodDefinition method, in HashSet<IMemberDefinition> blacklist, ErrorHandlingStrategy errorHandlingStrategy)
			{
				//IL_010a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0110: Expected O, but got Unknown
				//IL_0116: Unknown result type (might be due to invalid IL or missing references)
				//IL_011b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0136: Unknown result type (might be due to invalid IL or missing references)
				//IL_014e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0158: Expected O, but got Unknown
				//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
				if (!blacklist.Add((IMemberDefinition)(object)method))
				{
					return;
				}
				Preloader.Log.LogDebug((object)("Adding Method    '" + ((MemberReference)method).Name + "' to " + ((MemberReference)type).FullName + "'"));
				if (!method.IsAbstract)
				{
					return;
				}
				CustomAttribute val = ((IEnumerable<CustomAttribute>)method.CustomAttributes).FirstOrDefault((Func<CustomAttribute, bool>)((CustomAttribute a) => ((MemberReference)a.AttributeType).FullName == ErrorStrategyAttributeName));
				if (val != null)
				{
					errorHandlingStrategy = val.GetAttributeInstance<HandleErrorsAttribute>().Strategy;
				}
				MethodDefinition val2 = Extensions.FindMethod(type, ((MemberReference)method).Name, true);
				if (val2 != null)
				{
					HandleError("Method '" + ((MemberReference)method).Name + "' is already defined in '" + ((MemberReference)type).FullName + "'", errorHandlingStrategy);
					val2.Attributes = (MethodAttributes)326;
				}
				else
				{
					val2 = new MethodDefinition(((MemberReference)method).Name, (MethodAttributes)326, ((MemberReference)type).Module.ImportReference(((MethodReference)method).ReturnType));
					Enumerator<ParameterDefinition> enumerator = ((MethodReference)method).Parameters.GetEnumerator();
					try
					{
						while (enumerator.MoveNext())
						{
							ParameterDefinition current = enumerator.Current;
							((MethodReference)val2).Parameters.Add(new ParameterDefinition(((ParameterReference)current).Name, current.Attributes, ((MemberReference)type).Module.ImportReference(((ParameterReference)current).ParameterType)));
						}
					}
					finally
					{
						((IDisposable)enumerator).Dispose();
					}
					ILProcessor iLProcessor = val2.Body.GetILProcessor();
					if (((MemberReference)((MethodReference)method).ReturnType).FullName != "System.Void")
					{
						ConstructorInfo constructor = typeof(NotImplementedException).GetConstructor(new Type[1] { typeof(string) });
						MethodReference val3 = ((MemberReference)type).Module.ImportReference((MethodBase)constructor);
						iLProcessor.Emit(OpCodes.Ldstr, "This is a Stub");
						iLProcessor.Emit(OpCodes.Newobj, val3);
						iLProcessor.Emit(OpCodes.Throw);
					}
					else
					{
						iLProcessor.Emit(OpCodes.Ret);
					}
					val2.MarkAsInjected<MethodDefinition>(((MemberReference)type).Module);
				}
				val2.CopyCustomAttributes<MethodDefinition>(method);
				type.Methods.TryAdd<MethodDefinition>(val2);
			}
		}

		private static readonly string ErrorStrategyAttributeName = typeof(HandleErrorsAttribute).FullName;

		private const MethodAttributes InterfaceMethodAttributes = 326;

		private const MethodAttributes InterfaceSpecialMethodAttributes = 2502;

		private const PropertyAttributes InterfacePropertyAttributes = 0;

		private const EventAttributes InterfaceEventAttributes = 0;

		public static T GetAttributeInstance<T>(this CustomAttribute attribute) where T : Attribute
		{
			Type typeFromHandle = typeof(T);
			object[] args = ((IEnumerable<CustomAttributeArgument>)attribute.ConstructorArguments).Select((CustomAttributeArgument ca) => ((CustomAttributeArgument)(ref ca)).Value).ToArray();
			return (T)Activator.CreateInstance(typeFromHandle, args);
		}

		private static void HandleError(string message, ErrorHandlingStrategy strategy)
		{
			switch (strategy)
			{
			default:
				Preloader.inError = ErrorLevel.Hard;
				Preloader.Log.LogFatal((object)message);
				throw new TerminationException("Fatal Injection error!");
			case ErrorHandlingStrategy.LogWarning:
				Preloader.Log.LogWarning((object)message);
				break;
			case ErrorHandlingStrategy.LogError:
				Preloader.inError = ErrorLevel.Soft;
				Preloader.Log.LogError((object)message);
				break;
			case ErrorHandlingStrategy.Ignore:
				break;
			}
		}

		internal static void ImplementInterface(this TypeDefinition self, TypeReference @interface, ErrorHandlingStrategy errorHandlingStrategy)
		{
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Expected O, but got Unknown
			TypeDefinition val = @interface.Resolve();
			CustomAttribute val2 = ((IEnumerable<CustomAttribute>)val.CustomAttributes).FirstOrDefault((Func<CustomAttribute, bool>)((CustomAttribute a) => ((MemberReference)a.AttributeType).FullName == ErrorStrategyAttributeName));
			if (val2 != null)
			{
				errorHandlingStrategy = val2.GetAttributeInstance<HandleErrorsAttribute>().Strategy;
			}
			if (!val.IsInterface)
			{
				HandleError("Type '" + ((MemberReference)@interface).FullName + "' is not an interface!", errorHandlingStrategy);
			}
			if (((TypeReference)val).HasGenericParameters)
			{
				HandleError("Type '" + ((MemberReference)@interface).FullName + "' is a Generic type!", errorHandlingStrategy);
			}
			Preloader.Log.LogDebug((object)("Injecting '" + ((MemberReference)@interface).FullName + "' into " + ((MemberReference)self).FullName + "'"));
			if (((IEnumerable<InterfaceImplementation>)self.Interfaces).Any((InterfaceImplementation i) => i.InterfaceType == @interface))
			{
				Preloader.Log.LogWarning((object)("Interface '" + ((MemberReference)@interface).FullName + "' is already implemented, SKIPPING!"));
				return;
			}
			Enumerator<InterfaceImplementation> enumerator = val.Interfaces.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					InterfaceImplementation current = enumerator.Current;
					self.ImplementInterface(current.InterfaceType, errorHandlingStrategy);
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			TypeReference val3 = ((MemberReference)self).Module.ImportReference(@interface);
			HashSet<IMemberDefinition> blacklist = new HashSet<IMemberDefinition>();
			Interfaces.ImplementProperties(in self, val, in blacklist, errorHandlingStrategy);
			Interfaces.ImplementEvents(in self, val, in blacklist, errorHandlingStrategy);
			Interfaces.ImplementMethods(in self, val, in blacklist, errorHandlingStrategy);
			self.Interfaces.Add(new InterfaceImplementation(val3));
		}

		private static void MarkAsInjected<T>(this T target, ModuleDefinition module) where T : MemberReference, ICustomAttributeProvider
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			module.ImportReference(typeof(InjectedMemberAttribute));
			MethodReference val = module.ImportReference((MethodBase)typeof(InjectedMemberAttribute).GetConstructor(AccessTools.all, null, Array.Empty<Type>(), Array.Empty<ParameterModifier>()));
			CustomAttribute val2 = new CustomAttribute(val);
			((ICustomAttributeProvider)target).CustomAttributes.Add(val2);
		}

		private static void CopyCustomAttributes<T>(this T target, T source) where T : MemberReference, ICustomAttributeProvider
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			ModuleDefinition module = ((MemberReference)target).Module;
			Enumerator<CustomAttribute> enumerator = ((ICustomAttributeProvider)source).CustomAttributes.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					CustomAttribute current = enumerator.Current;
					if (((MemberReference)current.AttributeType).FullName == ErrorStrategyAttributeName)
					{
						continue;
					}
					MethodReference val = module.ImportReference(current.Constructor);
					CustomAttribute val2 = new CustomAttribute(val);
					Enumerator<CustomAttributeArgument> enumerator2 = current.ConstructorArguments.GetEnumerator();
					try
					{
						while (enumerator2.MoveNext())
						{
							CustomAttributeArgument current2 = enumerator2.Current;
							val2.ConstructorArguments.Add(module.ImportCustomAttributeArgument(current2));
						}
					}
					finally
					{
						((IDisposable)enumerator2).Dispose();
					}
					Enumerator<CustomAttributeNamedArgument> enumerator3 = current.Properties.GetEnumerator();
					try
					{
						while (enumerator3.MoveNext())
						{
							CustomAttributeNamedArgument current3 = enumerator3.Current;
							val2.Properties.Add(new CustomAttributeNamedArgument(((CustomAttributeNamedArgument)(ref current3)).Name, module.ImportCustomAttributeArgument(((CustomAttributeNamedArgument)(ref current3)).Argument)));
						}
					}
					finally
					{
						((IDisposable)enumerator3).Dispose();
					}
					Enumerator<CustomAttributeNamedArgument> enumerator4 = current.Fields.GetEnumerator();
					try
					{
						while (enumerator4.MoveNext())
						{
							CustomAttributeNamedArgument current4 = enumerator4.Current;
							val2.Fields.Add(new CustomAttributeNamedArgument(((CustomAttributeNamedArgument)(ref current4)).Name, module.ImportCustomAttributeArgument(((CustomAttributeNamedArgument)(ref current4)).Argument)));
						}
					}
					finally
					{
						((IDisposable)enumerator4).Dispose();
					}
					((ICustomAttributeProvider)target).CustomAttributes.Add(val2);
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
		}

		private static CustomAttributeArgument ImportCustomAttributeArgument(this ModuleDefinition targetModule, CustomAttributeArgument arg)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			TypeReference val = targetModule.ImportReference(((CustomAttributeArgument)(ref arg)).Type);
			object value = ((CustomAttributeArgument)(ref arg)).Value;
			TypeReference val2 = (TypeReference)((value is TypeReference) ? value : null);
			if (val2 == null)
			{
				if (value is CustomAttributeArgument[] array)
				{
					CustomAttributeArgument[] array2 = (CustomAttributeArgument[])(object)new CustomAttributeArgument[array.Length];
					for (int i = 0; i < array.Length; i++)
					{
						array2[i] = targetModule.ImportCustomAttributeArgument(array[i]);
					}
					return new CustomAttributeArgument(val, (object)array2);
				}
				return new CustomAttributeArgument(val, ((CustomAttributeArgument)(ref arg)).Value);
			}
			return new CustomAttributeArgument(val, (object)targetModule.ImportReference(val2));
		}

		private static void TryAdd<T>(this Collection<T> collection, T newMember) where T : IMemberDefinition
		{
			if (!((IEnumerable<T>)collection).Any((T member) => ((IMemberDefinition)member).Name == ((IMemberDefinition)newMember).Name))
			{
				collection.Add(newMember);
			}
		}

		internal static string GetAssemblyQualifiedName(this TypeReference type)
		{
			IMetadataScope scope = type.Scope;
			AssemblyNameReference val = (AssemblyNameReference)(object)((scope is AssemblyNameReference) ? scope : null);
			string text;
			if (val == null)
			{
				ModuleDefinition val2 = (ModuleDefinition)(object)((scope is ModuleDefinition) ? scope : null);
				if (val2 != null)
				{
					AssemblyDefinition assembly = val2.Assembly;
					object obj;
					if (assembly == null)
					{
						obj = null;
					}
					else
					{
						AssemblyNameDefinition name = assembly.Name;
						obj = ((name != null) ? ((AssemblyNameReference)name).FullName : null);
					}
					text = (string)obj;
				}
				else
				{
					text = null;
				}
			}
			else
			{
				text = val.FullName;
			}
			string text2 = text;
			if (text2 == null)
			{
				return ((MemberReference)type).FullName;
			}
			return ((MemberReference)type).FullName + ", " + text2;
		}
	}
}
namespace InjectionLibrary.Patches
{
	[HarmonyPatch(typeof(Chainloader))]
	internal static class TerminationPatch
	{
		[HarmonyPatch("ReplayPreloaderLogs")]
		[HarmonyFinalizer]
		internal static void TerminateAfterLogging()
		{
			Preloader.Log.LogFatal((object)"An unrecoverable error occurred. Shutting down the process.");
			Environment.Exit(999);
		}
	}
}
namespace InjectionLibrary.Exceptions
{
	public class TerminationException : Exception
	{
		public TerminationException(string message)
			: base(message)
		{
		}
	}
}
namespace InjectionLibrary.Attributes
{
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Interface)]
	public class HandleErrorsAttribute : Attribute
	{
		public ErrorHandlingStrategy Strategy { get; }

		public HandleErrorsAttribute(ErrorHandlingStrategy strategy)
		{
			Strategy = strategy;
		}

		public HandleErrorsAttribute(int strategy)
		{
			Strategy = (ErrorHandlingStrategy)strategy;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event, AllowMultiple = true)]
	public class InjectedMemberAttribute : Attribute
	{
		internal InjectedMemberAttribute()
		{
		}
	}
	[AttributeUsage(AttributeTargets.Interface, AllowMultiple = true)]
	public sealed class InjectInterfaceAttribute : Attribute
	{
		[CompilerGenerated]
		private Type <targetType>P;

		public string AssemblyName => <targetType>P.Assembly.GetName().Name;

		public string TypeName => <targetType>P.FullName;

		public InjectInterfaceAttribute(Type targetType)
		{
			<targetType>P = targetType;
			base..ctor();
		}
	}
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	public sealed class RequiresInjectionsAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}