Decompiled source of MonoDetour v0.7.7

core/com.github.MonoDetour.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
using MonoDetour;
using MonoDetour.Bindings.Reorg;
using MonoDetour.Bindings.Reorg.MonoModUtils;
using MonoDetour.Bindings.Reorg.RuntimeDetour;
using MonoDetour.Cil;
using MonoDetour.Cil.Analysis;
using MonoDetour.DetourTypes;
using MonoDetour.DetourTypes.Manipulation;
using MonoDetour.Interop.Cecil;
using MonoDetour.Interop.MonoModUtils;
using MonoDetour.Interop.RuntimeDetour;
using MonoDetour.Logging;
using MonoDetour.Reflection.Unspeakable;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using MonoMod.SourceGen.Internal;
using MonoMod.Utils;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("com.github.MonoDetour.Interop.HarmonyX")]
[assembly: InternalsVisibleTo("MonoDetour.UnitTests")]
[assembly: InternalsVisibleTo("0.com.github.MonoDetour.BepInEx.5")]
[assembly: InternalsVisibleTo("0.com.github.MonoDetour.BepInEx.6")]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("Hamunii")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Easy and convenient .NET detouring library, powered by MonoMod.RuntimeDetour.")]
[assembly: AssemblyFileVersion("0.7.7.0")]
[assembly: AssemblyInformationalVersion("0.7.7+d7c5fcdc39fb24ad6b0d68e7f1ff487bf6cbc1e7")]
[assembly: AssemblyProduct("MonoDetour")]
[assembly: AssemblyTitle("MonoDetour")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/MonoDetour/MonoDetour")]
[assembly: AssemblyVersion("0.7.7.0")]
[module: RefSafetyRules(11)]
internal class <Module>
{
	static <Module>()
	{
		<ModuleInitialization>F34D4C8E80BA55CF2DF46033D6935630EF80CDE4B828E451B074E18291EB971BE__ModuleInitialization.InitializeModule();
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class ExtensionMarkerAttribute : Attribute
	{
		public ExtensionMarkerAttribute(string name)
		{
		}
	}
}
namespace System
{
	[ExcludeFromCodeCoverage]
	internal readonly struct Index : IEquatable<Index>
	{
		private static class ThrowHelper
		{
			[DoesNotReturn]
			public static void ThrowValueArgumentOutOfRange_NeedNonNegNumException()
			{
				throw new ArgumentOutOfRangeException("value", "Non-negative number required.");
			}
		}

		private readonly int _value;

		public static Index Start => new Index(0);

		public static Index End => new Index(-1);

		public int Value
		{
			get
			{
				if (_value < 0)
				{
					return ~_value;
				}
				return _value;
			}
		}

		public bool IsFromEnd => _value < 0;

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Index(int value, bool fromEnd = false)
		{
			if (value < 0)
			{
				ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException();
			}
			if (fromEnd)
			{
				_value = ~value;
			}
			else
			{
				_value = value;
			}
		}

		private Index(int value)
		{
			_value = value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Index FromStart(int value)
		{
			if (value < 0)
			{
				ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException();
			}
			return new Index(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Index FromEnd(int value)
		{
			if (value < 0)
			{
				ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException();
			}
			return new Index(~value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public int GetOffset(int length)
		{
			int num = _value;
			if (IsFromEnd)
			{
				num += length + 1;
			}
			return num;
		}

		public override bool Equals([NotNullWhen(true)] object? value)
		{
			if (value is Index)
			{
				return _value == ((Index)value)._value;
			}
			return false;
		}

		public bool Equals(Index other)
		{
			return _value == other._value;
		}

		public override int GetHashCode()
		{
			return _value;
		}

		public static implicit operator Index(int value)
		{
			return FromStart(value);
		}

		public override string ToString()
		{
			if (IsFromEnd)
			{
				return ToStringFromEnd();
			}
			return ((uint)Value).ToString();
		}

		private string ToStringFromEnd()
		{
			return "^" + Value;
		}
	}
	[ExcludeFromCodeCoverage]
	internal readonly struct Range : IEquatable<Range>
	{
		private static class HashHelpers
		{
			public static int Combine(int h1, int h2)
			{
				uint num = (uint)(h1 << 5) | ((uint)h1 >> 27);
				return ((int)num + h1) ^ h2;
			}
		}

		private static class ThrowHelper
		{
			[DoesNotReturn]
			public static void ThrowArgumentOutOfRangeException()
			{
				throw new ArgumentOutOfRangeException("length");
			}
		}

		public Index Start { get; }

		public Index End { get; }

		public static Range All => Index.Start..Index.End;

		public Range(Index start, Index end)
		{
			Start = start;
			End = end;
		}

		public override bool Equals([NotNullWhen(true)] object? value)
		{
			if (value is Range range && range.Start.Equals(Start))
			{
				return range.End.Equals(End);
			}
			return false;
		}

		public bool Equals(Range other)
		{
			if (other.Start.Equals(Start))
			{
				return other.End.Equals(End);
			}
			return false;
		}

		public override int GetHashCode()
		{
			return HashHelpers.Combine(Start.GetHashCode(), End.GetHashCode());
		}

		public override string ToString()
		{
			return Start.ToString() + ".." + End;
		}

		public static Range StartAt(Index start)
		{
			return start..Index.End;
		}

		public static Range EndAt(Index end)
		{
			return Index.Start..end;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public (int Offset, int Length) GetOffsetAndLength(int length)
		{
			Index start = Start;
			int num = ((!start.IsFromEnd) ? start.Value : (length - start.Value));
			Index end = End;
			int num2 = ((!end.IsFromEnd) ? end.Value : (length - end.Value));
			if ((uint)num2 > (uint)length || (uint)num > (uint)num2)
			{
				ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			return (num, num2 - num);
		}
	}
}
namespace System.Runtime.Versioning
{
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiresPreviewFeaturesAttribute : Attribute
	{
		public string? Message { get; }

		public string? Url { get; set; }

		public RequiresPreviewFeaturesAttribute()
		{
		}

		public RequiresPreviewFeaturesAttribute(string? message)
		{
			Message = message;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false, AllowMultiple = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class AsyncMethodBuilderAttribute : Attribute
	{
		public Type BuilderType { get; }

		public AsyncMethodBuilderAttribute(Type builderType)
		{
			BuilderType = builderType;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CallerArgumentExpressionAttribute : Attribute
	{
		public string ParameterName { get; }

		public CallerArgumentExpressionAttribute(string parameterName)
		{
			ParameterName = parameterName;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CollectionBuilderAttribute : Attribute
	{
		public Type BuilderType { get; }

		public string MethodName { get; }

		public CollectionBuilderAttribute(Type builderType, string methodName)
		{
			BuilderType = builderType;
			MethodName = methodName;
		}
	}
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CompilerFeatureRequiredAttribute : Attribute
	{
		public const string RefStructs = "RefStructs";

		public const string RequiredMembers = "RequiredMembers";

		public string FeatureName { get; }

		public bool IsOptional { get; set; }

		public CompilerFeatureRequiredAttribute(string featureName)
		{
			FeatureName = featureName;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute
	{
		public string[] Arguments { get; }

		public InterpolatedStringHandlerArgumentAttribute(string argument)
		{
			Arguments = new string[1] { argument };
		}

		public InterpolatedStringHandlerArgumentAttribute(params string[] arguments)
		{
			Arguments = arguments;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class InterpolatedStringHandlerAttribute : Attribute
	{
	}
	[EditorBrowsable(EditorBrowsableState.Never)]
	[ExcludeFromCodeCoverage]
	internal static class IsExternalInit
	{
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ModuleInitializerAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class OverloadResolutionPriorityAttribute : Attribute
	{
		public int Priority { get; }

		public OverloadResolutionPriorityAttribute(int priority)
		{
			Priority = priority;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ParamCollectionAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiredMemberAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[EditorBrowsable(EditorBrowsableState.Never)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiresLocationAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class SkipLocalsInitAttribute : Attribute
	{
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class AllowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ConstantExpectedAttribute : Attribute
	{
		public object? Min { get; set; }

		public object? Max { get; set; }
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class DisallowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class DoesNotReturnAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class DoesNotReturnIfAttribute : Attribute
	{
		public bool ParameterValue { get; }

		public DoesNotReturnIfAttribute(bool parameterValue)
		{
			ParameterValue = parameterValue;
		}
	}
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ExperimentalAttribute : Attribute
	{
		public string DiagnosticId { get; }

		public string? UrlFormat { get; set; }

		public ExperimentalAttribute(string diagnosticId)
		{
			DiagnosticId = diagnosticId;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class MaybeNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class MaybeNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public MaybeNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	internal sealed class MemberNotNullAttribute : Attribute
	{
		public string[] Members { get; }

		public MemberNotNullAttribute(string member)
		{
			Members = new string[1] { member };
		}

		public MemberNotNullAttribute(params string[] members)
		{
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	internal sealed class MemberNotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public string[] Members { get; }

		public MemberNotNullWhenAttribute(bool returnValue, string member)
		{
			ReturnValue = returnValue;
			Members = new string[1] { member };
		}

		public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
		{
			ReturnValue = returnValue;
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class NotNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class NotNullIfNotNullAttribute : Attribute
	{
		public string ParameterName { get; }

		public NotNullIfNotNullAttribute(string parameterName)
		{
			ParameterName = parameterName;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class NotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public NotNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class SetsRequiredMembersAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class StringSyntaxAttribute : Attribute
	{
		public const string CompositeFormat = "CompositeFormat";

		public const string DateOnlyFormat = "DateOnlyFormat";

		public const string DateTimeFormat = "DateTimeFormat";

		public const string EnumFormat = "EnumFormat";

		public const string GuidFormat = "GuidFormat";

		public const string Json = "Json";

		public const string NumericFormat = "NumericFormat";

		public const string Regex = "Regex";

		public const string TimeOnlyFormat = "TimeOnlyFormat";

		public const string TimeSpanFormat = "TimeSpanFormat";

		public const string Uri = "Uri";

		public const string Xml = "Xml";

		public string Syntax { get; }

		public object?[] Arguments { get; }

		public StringSyntaxAttribute(string syntax)
		{
			Syntax = syntax;
			Arguments = new object[0];
		}

		public StringSyntaxAttribute(string syntax, params object?[] arguments)
		{
			Syntax = syntax;
			Arguments = arguments;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class UnscopedRefAttribute : Attribute
	{
	}
}
namespace MonoMod.SourceGen.Internal
{
	internal sealed class CodeBuilder
	{
		private readonly StringBuilder sb;

		private readonly char indentChar = ' ';

		private readonly int indentAmount;

		private int indentLevel;

		private bool didWriteIndent;

		public CodeBuilder(StringBuilder sb, int indentAmount = 4)
		{
			this.sb = sb;
			this.indentAmount = indentAmount;
		}

		public CodeBuilder WriteHeader()
		{
			WriteLine("// <auto-generated />");
			WriteLine("#pragma warning disable");
			WriteLine("#nullable enable");
			WriteLine("using PrefixDetour = global::MonoDetour.DetourTypes.PrefixDetour;");
			WriteLine("using PostfixDetour = global::MonoDetour.DetourTypes.PostfixDetour;");
			WriteLine("using ILHookDetour = global::MonoDetour.DetourTypes.ILHookDetour;");
			return this;
		}

		public CodeBuilder OpenBlock()
		{
			return WriteLine('{').IncreaseIndent();
		}

		public CodeBuilder CloseBlock()
		{
			return DecreaseIndent().WriteLine('}');
		}

		public CodeBuilder IncreaseIndent()
		{
			indentLevel++;
			return this;
		}

		public CodeBuilder DecreaseIndent()
		{
			indentLevel--;
			return this;
		}

		public CodeBuilder RemoveIndent()
		{
			indentLevel = 0;
			return this;
		}

		private void WriteIndentIfNeeded()
		{
			if (!didWriteIndent)
			{
				if (indentLevel > 0)
				{
					sb.Append(indentChar, indentLevel * indentAmount);
				}
				didWriteIndent = true;
			}
		}

		public CodeBuilder Write(int i)
		{
			return Write(i.ToString(CultureInfo.InvariantCulture));
		}

		public CodeBuilder Write(string? s)
		{
			WriteIndentIfNeeded();
			sb.Append(s);
			return this;
		}

		public CodeBuilder Write(char c)
		{
			WriteIndentIfNeeded();
			sb.Append(c);
			return this;
		}

		public CodeBuilder WriteLine(int i)
		{
			return WriteLine(i.ToString(CultureInfo.InvariantCulture));
		}

		public CodeBuilder WriteLine(string s)
		{
			WriteIndentIfNeeded();
			sb.AppendLine(s);
			didWriteIndent = false;
			return this;
		}

		public CodeBuilder WriteLine(char c)
		{
			WriteIndentIfNeeded();
			sb.Append(c).AppendLine();
			didWriteIndent = false;
			return this;
		}

		public CodeBuilder WriteLine()
		{
			sb.AppendLine();
			didWriteIndent = false;
			return this;
		}

		public override string ToString()
		{
			return sb.ToString();
		}
	}
}
namespace MonoDetour
{
	internal static class Helpers
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static T ThrowIfNull<T>([NotNull] T? argument, [CallerArgumentExpression("argument")] string name = "")
		{
			if (argument == null)
			{
				ThrowArgumentNull(name);
			}
			return argument;
		}

		[DoesNotReturn]
		private static void ThrowArgumentNull(string argName)
		{
			throw new ArgumentNullException(argName);
		}
	}
	public interface IMonoDetourHook : IReadOnlyMonoDetourHook, IDisposable
	{
		void Apply();

		void Undo();
	}
	public interface IReadOnlyMonoDetourHook
	{
		MethodBase Target { get; }

		MethodBase Manipulator { get; }

		Delegate? ManipulatorDelegate { get; }

		MonoDetourManager Owner { get; }

		MonoDetourConfig? Config { get; }

		bool IsValid { get; }

		bool IsApplied { get; }
	}
	internal static class <ModuleInitialization>F34D4C8E80BA55CF2DF46033D6935630EF80CDE4B828E451B074E18291EB971BE__ModuleInitialization
	{
		[ModuleInitializer]
		internal static void InitializeModule()
		{
			ILHookInstructionILLabelCastFixes.InitHook();
			ILHookDMDManipulation.InitHook();
		}
	}
	public class MonoDetourConfig : IMonoDetourConfig
	{
		public string? OverrideId { get; }

		public int Priority { get; }

		public IEnumerable<string> Before { get; }

		public IEnumerable<string> After { get; }

		public MonoDetourConfig(int priority = 0, IEnumerable<string>? before = null, IEnumerable<string>? after = null, string? overrideId = null)
		{
			Priority = priority;
			Before = AsFixedSize(before ?? Array.Empty<string>());
			After = AsFixedSize(after ?? Array.Empty<string>());
			OverrideId = overrideId;
		}

		private static IEnumerable<string> AsFixedSize(IEnumerable<string> enumerable)
		{
			if (enumerable == Enumerable.Empty<string>())
			{
				return enumerable;
			}
			if (enumerable is ICollection<string>)
			{
				return enumerable;
			}
			return enumerable.ToArray();
		}

		public MonoDetourConfig WithPriority(int priority)
		{
			return new MonoDetourConfig(priority, Before, After, OverrideId);
		}

		public MonoDetourConfig WithBefore(IEnumerable<string> before)
		{
			return new MonoDetourConfig(Priority, before, After, OverrideId);
		}

		public MonoDetourConfig WithBefore(params string[] before)
		{
			return WithBefore(before.AsEnumerable());
		}

		public MonoDetourConfig WithAfter(IEnumerable<string> after)
		{
			return new MonoDetourConfig(Priority, Before, after, OverrideId);
		}

		public MonoDetourConfig WithAfter(params string[] after)
		{
			return WithAfter(after.AsEnumerable());
		}

		public MonoDetourConfig AddBefore(IEnumerable<string> before)
		{
			return WithBefore(Before.Concat(before));
		}

		public MonoDetourConfig AddBefore(params string[] before)
		{
			return AddBefore(before.AsEnumerable());
		}

		public MonoDetourConfig AddAfter(IEnumerable<string> after)
		{
			return WithAfter(After.Concat(after));
		}

		public MonoDetourConfig AddAfter(params string[] after)
		{
			return AddAfter(after.AsEnumerable());
		}
	}
	public class MonoDetourHook : IMonoDetourHook, IReadOnlyMonoDetourHook, IDisposable
	{
		private static readonly ConditionalWeakTable<Manipulator, MonoDetourHook> s_ManipulatorToHook = new ConditionalWeakTable<Manipulator, MonoDetourHook>();

		private static readonly object tableLock = new object();

		private bool isDisposed;

		public MethodBase Target { get; }

		public MethodBase Manipulator { get; }

		public Delegate? ManipulatorDelegate { get; }

		public MonoDetourManager Owner { get; }

		public MonoDetourConfig? Config { get; }

		public ILHook Applier { get; }

		public Type ApplierType { get; }

		public bool IsValid => Applier.IsValid;

		public bool IsApplied => Applier.IsApplied;

		private MonoDetourHook(MethodBase target, MethodBase manipulator, Delegate? manipulatorDelegate, Type applierType, MonoDetourManager owner, MonoDetourConfig? config = null, bool applyByDefault = true)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			Target = Helpers.ThrowIfNull(target, "target");
			Manipulator = Helpers.ThrowIfNull(manipulator, "manipulator");
			Owner = Helpers.ThrowIfNull(owner, "owner");
			ManipulatorDelegate = manipulatorDelegate;
			ApplierType = applierType;
			Config = config;
			IMonoDetourHookApplier monoDetourHookApplier = (IMonoDetourHookApplier)Activator.CreateInstance(applierType);
			monoDetourHookApplier.Hook = this;
			owner.Hooks.Add(this);
			Manipulator val = new Manipulator(monoDetourHookApplier.ApplierManipulator);
			Applier = ProxyILHookConstructor.ConstructILHook(target, val, (IMonoDetourConfig?)(object)config, owner.Id);
			lock (tableLock)
			{
				s_ManipulatorToHook.Add(val, this);
			}
			if (applyByDefault)
			{
				Applier.Apply();
			}
		}

		public static MonoDetourHook Create<TApplier>(MethodBase target, Delegate manipulator, MonoDetourManager owner, MonoDetourConfig? config = null, bool applyByDefault = true) where TApplier : class, IMonoDetourHookApplier
		{
			return new MonoDetourHook(target, Helpers.ThrowIfNull(manipulator, "manipulator").Method, manipulator, typeof(TApplier), owner, config, applyByDefault);
		}

		public static MonoDetourHook Create<TApplier>(MethodBase target, MethodBase manipulator, MonoDetourManager owner, MonoDetourConfig? config = null, bool applyByDefault = true) where TApplier : class, IMonoDetourHookApplier
		{
			return new MonoDetourHook(target, manipulator, null, typeof(TApplier), owner, config, applyByDefault);
		}

		public static bool TryGetFrom(Manipulator key, [NotNullWhen(true)] out MonoDetourHook? monoDetourHook)
		{
			return s_ManipulatorToHook.TryGetValue(key, out monoDetourHook);
		}

		public void Apply()
		{
			Applier.Apply();
		}

		public void Undo()
		{
			Applier.Undo();
		}

		public void Dispose()
		{
			if (!isDisposed)
			{
				Applier.Dispose();
				GC.SuppressFinalize(this);
				isDisposed = true;
			}
		}
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false)]
	public class MonoDetourHookInitializeAttribute : Attribute
	{
	}
	public class MonoDetourManager : IDisposable, IMonoDetourLogSource
	{
		private bool isDisposed;

		public string Id { get; } = Helpers.ThrowIfNull(id, "id");


		public MonoDetourLogger.LogChannel LogFilter { get; set; } = MonoDetourLogger.LogChannel.Warning | MonoDetourLogger.LogChannel.Error;


		public List<IMonoDetourHook> Hooks { get; } = new List<IMonoDetourHook>();


		public event Action<IReadOnlyMonoDetourHook>? OnHookThrew;

		public MonoDetourManager(string id)
		{
		}

		private void ThrowIfDisposed()
		{
			if (!isDisposed)
			{
				return;
			}
			throw new ObjectDisposedException(ToString());
		}

		internal bool CallOnHookThrew(IReadOnlyMonoDetourHook hook)
		{
			if (this.OnHookThrew == null)
			{
				return false;
			}
			this.OnHookThrew(hook);
			return true;
		}

		public static void InvokeHookInitializers(Assembly assembly, bool reportUnloadableTypes = true)
		{
			Type[] typesFromAssembly = ReflectionUtils.GetTypesFromAssembly(assembly, reportUnloadableTypes);
			foreach (Type type in typesFromAssembly)
			{
				if (ReflectionUtils.HasCustomAttribute<IMonoDetourTargets>(type, reportUnloadableTypes))
				{
					InvokeHookInitializers(type, reportUnloadableTypes);
				}
			}
		}

		public static void InvokeHookInitializers(Assembly assembly)
		{
			InvokeHookInitializers(assembly, reportUnloadableTypes: true);
		}

		public static void InvokeHookInitializers(Type type, bool reportUnloadableTypes = true)
		{
			MethodInfo[] methods = type.GetMethods((BindingFlags)(-1));
			MethodInfo[] array = methods;
			foreach (MethodInfo methodInfo in array)
			{
				if (ReflectionUtils.HasCustomAttribute<MonoDetourHookInitializeAttribute>(methodInfo, reportUnloadableTypes))
				{
					methodInfo.Invoke(null, null);
				}
			}
		}

		public static void InvokeHookInitializers(Type type)
		{
			InvokeHookInitializers(type, reportUnloadableTypes: true);
		}

		public void ApplyHooks()
		{
			Hooks.ForEach(delegate(IMonoDetourHook x)
			{
				x.Apply();
			});
		}

		public void UndoHooks()
		{
			Hooks.ForEach(delegate(IMonoDetourHook x)
			{
				x.Undo();
			});
		}

		public void DisposeHooks()
		{
			Hooks.ForEach(delegate(IMonoDetourHook x)
			{
				x.Dispose();
			});
			Hooks.Clear();
		}

		public MonoDetourHook ILHook(Delegate target, ILManipulationInfo.Manipulator manipulator, MonoDetourConfig? config = null, bool applyByDefault = true)
		{
			return ILHook(target.Method, manipulator, config, applyByDefault);
		}

		public MonoDetourHook ILHook(MethodBase target, ILManipulationInfo.Manipulator manipulator, MonoDetourConfig? config = null, bool applyByDefault = true)
		{
			return Hook<ILHookDetour>(target, manipulator, config, applyByDefault);
		}

		public MonoDetourHook Hook<TApplier>(Delegate target, Delegate manipulator, MonoDetourConfig? config = null, bool applyByDefault = true) where TApplier : class, IMonoDetourHookApplier
		{
			return Hook<TApplier>(target.Method, manipulator, config, applyByDefault);
		}

		public MonoDetourHook Hook<TApplier>(MethodBase target, Delegate manipulator, MonoDetourConfig? config = null, bool applyByDefault = true) where TApplier : class, IMonoDetourHookApplier
		{
			ThrowIfDisposed();
			return MonoDetourHook.Create<TApplier>(target, manipulator, this, config, applyByDefault);
		}

		public MonoDetourHook Hook<TApplier>(MethodBase target, MethodBase manipulator, MonoDetourConfig? config = null, bool applyByDefault = true) where TApplier : class, IMonoDetourHookApplier
		{
			ThrowIfDisposed();
			return MonoDetourHook.Create<TApplier>(target, manipulator, this, config, applyByDefault);
		}

		public void Dispose()
		{
			if (!isDisposed)
			{
				DisposeHooks();
				GC.SuppressFinalize(this);
				isDisposed = true;
			}
		}
	}
	public interface IMonoDetourTargets
	{
	}
	internal static class ReflectionUtils
	{
		public static bool HasCustomAttribute<T>(MemberInfo member, bool reportUnloadableTypes)
		{
			IEnumerable<Attribute> customAttributes;
			try
			{
				customAttributes = member.GetCustomAttributes();
			}
			catch (TypeLoadException)
			{
				if (!reportUnloadableTypes)
				{
					return false;
				}
				bool flag = false;
				foreach (CustomAttributeData customAttribute in member.CustomAttributes)
				{
					try
					{
						if (typeof(T).IsAssignableFrom(customAttribute.AttributeType))
						{
							flag = true;
							break;
						}
					}
					catch (TypeLoadException)
					{
					}
				}
				if (flag)
				{
					MonoDetourLogger.Log(MonoDetourLogger.LogChannel.Warning, "[InvokeHookInitializers]" + $" Skipping '{member}' ({member.Module.Assembly.GetName().Name}) due to unloadable type." + " Use 'reportUnloadableTypes: false' to hide this message.");
				}
				return false;
			}
			foreach (Attribute item in customAttributes)
			{
				if (item is T)
				{
					return true;
				}
			}
			return false;
		}

		public static Type[] GetTypesFromAssembly(Assembly assembly, bool reportUnloadableTypes)
		{
			try
			{
				Type[] types = assembly.GetTypes();
				for (int i = 0; i < types.Length; i++)
				{
					if (types[i] == null)
					{
						ReportUnloadableAssemblyTypes(assembly, reportUnloadableTypes);
						return types.Where((Type type) => (object)type != null).ToArray();
					}
				}
				return types;
			}
			catch (ReflectionTypeLoadException ex)
			{
				ReportUnloadableAssemblyTypes(assembly, reportUnloadableTypes);
				return ex.Types.Where((Type type) => (object)type != null).ToArray();
			}
		}

		private static void ReportUnloadableAssemblyTypes(Assembly assembly, bool reportUnloadableTypes)
		{
			if (reportUnloadableTypes)
			{
				MonoDetourLogger.Log(MonoDetourLogger.LogChannel.Warning, "[InvokeHookInitializers] Unloadable type(s) found in '" + assembly.GetName().Name + "'. If such a type has hook initializers, they will be skipped. Use 'reportUnloadableTypes: false' to hide this message.");
			}
		}
	}
}
namespace MonoDetour.Logging
{
	internal interface IMonoDetourLogSource
	{
		MonoDetourLogger.LogChannel LogFilter { get; set; }
	}
	public static class MonoDetourLogger
	{
		internal delegate void LogReceiver(LogChannel channel, string message);

		[Flags]
		public enum LogChannel
		{
			None = 0,
			IL = 4,
			Warning = 8,
			Error = 0x10
		}

		private static LogChannel GlobalFilter { get; set; } = LogChannel.Warning | LogChannel.Error;


		internal static event LogReceiver? OnLog;

		private static string LogChannelToString(LogChannel channel)
		{
			return channel switch
			{
				LogChannel.None => "None   ", 
				LogChannel.IL => "IL     ", 
				LogChannel.Warning => "Warning", 
				LogChannel.Error => "Error  ", 
				_ => throw new NotSupportedException(), 
			};
		}

		internal static bool IsEnabledFor(LogChannel caller, LogChannel channel)
		{
			return (caller & channel) != 0;
		}

		internal static void Log(this IMonoDetourLogSource caller, LogChannel channel, Func<string> message)
		{
			if (IsEnabledFor(caller.LogFilter, channel))
			{
				if (MonoDetourLogger.OnLog == null)
				{
					DefaultLog(channel, message());
				}
				else
				{
					MonoDetourLogger.OnLog?.Invoke(channel, message());
				}
			}
		}

		internal static void Log(LogChannel channel, Func<string> message)
		{
			if (IsEnabledFor(GlobalFilter, channel))
			{
				if (MonoDetourLogger.OnLog == null)
				{
					DefaultLog(channel, message());
				}
				else
				{
					MonoDetourLogger.OnLog?.Invoke(channel, message());
				}
			}
		}

		internal static void Log(this IMonoDetourLogSource caller, LogChannel channel, string message)
		{
			if (IsEnabledFor(caller.LogFilter, channel))
			{
				if (MonoDetourLogger.OnLog == null)
				{
					DefaultLog(channel, message);
				}
				else
				{
					MonoDetourLogger.OnLog?.Invoke(channel, message);
				}
			}
		}

		internal static void Log(LogChannel channel, string message)
		{
			if (IsEnabledFor(GlobalFilter, channel))
			{
				if (MonoDetourLogger.OnLog == null)
				{
					DefaultLog(channel, message);
				}
				else
				{
					MonoDetourLogger.OnLog?.Invoke(channel, message);
				}
			}
		}

		private static void DefaultLog(LogChannel channel, string message)
		{
			ConsoleColor color = channel switch
			{
				LogChannel.Warning => ConsoleColor.Yellow, 
				LogChannel.Error => ConsoleColor.Red, 
				_ => Console.ForegroundColor, 
			};
			LogWithColor("[" + LogChannelToString(channel) + ": MonoDetour] " + message, color);
		}

		private static void LogWithColor(string message, ConsoleColor color)
		{
			ConsoleColor foregroundColor = Console.ForegroundColor;
			Console.ForegroundColor = color;
			Console.Error.WriteLine(message);
			Console.ForegroundColor = foregroundColor;
		}
	}
}
namespace MonoDetour.Interop.RuntimeDetour
{
	internal static class ILHookDMDManipulation
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Manipulator <0>__GetDMDBeforeManipulation;

			public static ILManipulationInfo.Manipulator <1>__TryCatchAnalyzeCompilationReorg;

			public static ILManipulationInfo.Manipulator <2>__TryCatchAnalyzeCompilationLegacy;

			public static Func<DynamicMethodDefinition, DynamicMethodDefinition> <3>__BorrowDMD;

			public static Action<InvalidProgramException, DynamicMethodDefinition> <4>__AnalyzeMethod;

			public static Func<DynamicMethodDefinition, MethodBody> <5>__GetMethodBody;

			public static Action<InvalidProgramException, MethodBody> <6>__AnalyzeMethodBody;
		}

		internal static readonly ConditionalWeakTable<MethodDefinition, ReadOnlyCollection<Instruction>> s_MethodDefinitionToOriginalInstructions = new ConditionalWeakTable<MethodDefinition, ReadOnlyCollection<Instruction>>();

		internal static readonly ConditionalWeakTable<MethodDefinition, MethodBase> s_MethodDefinitionToOriginalMethod = new ConditionalWeakTable<MethodDefinition, MethodBase>();

		private static ConstructorInfo dmdConstructor = null;

		private static ILHook getDmdBeforeManipulationHook = null;

		private static readonly MonoDetourManager m = new MonoDetourManager(typeof(ILHookDMDManipulation).Assembly.GetName().Name);

		private static bool initialized;

		internal static void InitHook()
		{
			if (initialized)
			{
				return;
			}
			initialized = true;
			try
			{
				if (MonoModVersion.IsReorg)
				{
					InitHookReorg();
				}
				else
				{
					InitHookLegacy();
				}
			}
			catch (Exception innerException)
			{
				throw new NotSupportedException("MonoDetour doesn't seem to support this MonoMod version, please report this issue: https://github.com/MonoDetour/MonoDetour: " + $"'{typeof(Hook).Assembly}'", innerException);
			}
		}

		private static void InitHookReorg()
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			dmdConstructor = typeof(DynamicMethodDefinition).GetConstructor(new Type[1] { typeof(DynamicMethodDefinition) }) ?? throw new NullReferenceException("DMD constructor not found.");
			Type type = Type.GetType("MonoMod.RuntimeDetour.DetourManager+ManagedDetourState, MonoMod.RuntimeDetour") ?? throw new NullReferenceException("Type 'MonoMod.RuntimeDetour.DetourManager+ManagedDetourState, MonoMod.RuntimeDetour' not found.");
			MethodInfo methodInfo = type.GetMethod("UpdateEndOfChain", BindingFlags.Instance | BindingFlags.NonPublic) ?? throw new NullReferenceException("Method 'UpdateEndOfChain' not found.");
			object obj = <>O.<0>__GetDMDBeforeManipulation;
			if (obj == null)
			{
				Manipulator val = GetDMDBeforeManipulation;
				<>O.<0>__GetDMDBeforeManipulation = val;
				obj = (object)val;
			}
			getDmdBeforeManipulationHook = new ILHook((MethodBase)methodInfo, (Manipulator)obj);
			m.ILHook(methodInfo, TryCatchAnalyzeCompilationReorg);
		}

		private static void InitHookLegacy()
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			dmdConstructor = typeof(DynamicMethodDefinition).GetConstructor(new Type[1] { typeof(MethodBase) }) ?? throw new NullReferenceException("DMD constructor not found.");
			Type type = Type.GetType("MonoMod.RuntimeDetour.ILHook+Context, MonoMod.RuntimeDetour") ?? throw new NullReferenceException("Type 'MonoMod.RuntimeDetour.ILHook+Context, MonoMod.RuntimeDetour' not found.");
			MethodInfo methodInfo = type.GetMethod("Refresh") ?? throw new NullReferenceException("Method 'Refresh' not found.");
			object obj = <>O.<0>__GetDMDBeforeManipulation;
			if (obj == null)
			{
				Manipulator val = GetDMDBeforeManipulation;
				<>O.<0>__GetDMDBeforeManipulation = val;
				obj = (object)val;
			}
			getDmdBeforeManipulationHook = new ILHook((MethodBase)methodInfo, (Manipulator)obj);
			m.ILHook(methodInfo, TryCatchAnalyzeCompilationLegacy);
		}

		private static void GetDMDBeforeManipulation(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			ILCursor val = new ILCursor(il);
			if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchNewobj(x, (MethodBase)dmdConstructor)
			}))
			{
				Console.WriteLine(il);
				throw new NullReferenceException("DMD construction not found.");
			}
			val.EmitDelegate<Func<DynamicMethodDefinition, DynamicMethodDefinition>>((Func<DynamicMethodDefinition, DynamicMethodDefinition>)BorrowDMD);
		}

		private static DynamicMethodDefinition BorrowDMD(DynamicMethodDefinition dmd)
		{
			MethodDefinition definition = dmd.Definition;
			ReadOnlyCollection<Instruction> value = ((IEnumerable<Instruction>)definition.Body.Instructions).ToList().AsReadOnly();
			s_MethodDefinitionToOriginalInstructions.Add(definition, value);
			s_MethodDefinitionToOriginalMethod.Add(definition, dmd.OriginalMethod);
			return dmd;
		}

		private static void TryCatchAnalyzeCompilationReorg(ILManipulationInfo info)
		{
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			ILWeaver w = new ILWeaver(info);
			int localIndexDmd = 0;
			Instruction tryStart = null;
			MethodReference val3 = default(MethodReference);
			int num2 = default(int);
			MethodReference val2 = default(MethodReference);
			int num = default(int);
			MethodReference val = default(MethodReference);
			w.MatchRelaxed((Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref localIndexDmd), (Instruction x) => ILPatternMatchingExt.MatchCallvirt(x, ref val3), (Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref num2), (Instruction x) => ILPatternMatchingExt.MatchCall(x, ref val2) && w.SetInstructionTo(ref tryStart, x), (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref num), (Instruction x) => ILPatternMatchingExt.MatchCallvirt(x, ref val) && w.SetCurrentTo(x)).Extract(out ILWeaverResult result);
			if (!result.IsValid)
			{
				MonoDetourLogger.Log(MonoDetourLogger.LogChannel.Error, "MonoDetour's invalid IL analysis failed to be applied. Please report this issue: https://github.com/MonoDetour/MonoDetour: " + $"'{typeof(Hook).Assembly}'");
				MonoDetourLogger.Log(MonoDetourLogger.LogChannel.Error, result.FailureMessage);
				return;
			}
			w.HandlerCreateCatch(typeof(InvalidProgramException), out WeaverExceptionCatchHandler handler);
			w.HandlerSetTryStart(tryStart, handler);
			w.HandlerSetTryEnd(w.Current, handler);
			w.InsertAfterCurrent(new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[2]
			{
				w.Create(OpCodes.Ldloc, localIndexDmd),
				w.CreateCall(new Action<InvalidProgramException, DynamicMethodDefinition>(AnalyzeMethod))
			}));
			w.HandlerSetHandlerEnd(w.Current, handler);
			w.HandlerApply(handler);
		}

		private static void TryCatchAnalyzeCompilationLegacy(ILManipulationInfo info)
		{
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			ILWeaver w = new ILWeaver(info);
			int localIndexDmd = 0;
			int num4 = default(int);
			w.MatchRelaxed((Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref localIndexDmd) && w.SetCurrentTo(x), (Instruction x) => ILPatternMatchingExt.MatchCallvirt<DynamicMethodDefinition>(x, "Generate"), (Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref num4)).Extract(out ILWeaverResult result);
			if (!result.IsValid)
			{
				MonoDetourLogger.Log(MonoDetourLogger.LogChannel.Error, "MonoDetour's invalid IL analysis failed to be applied. Please report this issue: https://github.com/MonoDetour/MonoDetour: " + $"'{typeof(Hook).Assembly}'");
				MonoDetourLogger.Log(MonoDetourLogger.LogChannel.Error, result.FailureMessage);
				return;
			}
			VariableDefinition variable = w.DeclareVariable(typeof(MethodBody));
			w.InsertAfterCurrent(new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[3]
			{
				w.Create(OpCodes.Dup),
				w.CreateCall(new Func<DynamicMethodDefinition, MethodBody>(GetMethodBody)),
				w.Create(OpCodes.Stloc, variable)
			}));
			Instruction tryStart = null;
			int num3 = default(int);
			int num2 = default(int);
			FieldReference val4 = default(FieldReference);
			int num = default(int);
			FieldReference val3 = default(FieldReference);
			MethodReference val2 = default(MethodReference);
			FieldReference val = default(FieldReference);
			w.MatchRelaxed((Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num3) && w.SetInstructionTo(ref tryStart, x), (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num2), (Instruction x) => ILPatternMatchingExt.MatchLdfld(x, ref val4), (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref num), (Instruction x) => ILPatternMatchingExt.MatchLdsflda(x, ref val3), (Instruction x) => ILPatternMatchingExt.MatchNewobj(x, ref val2), (Instruction x) => ILPatternMatchingExt.MatchStfld(x, ref val) && w.SetCurrentTo(x)).Extract(out result);
			if (!result.IsValid)
			{
				MonoDetourLogger.Log(MonoDetourLogger.LogChannel.Error, "MonoDetour's invalid IL analysis failed to be applied. Please report this issue: https://github.com/MonoDetour/MonoDetour: " + $"'{typeof(Hook).Assembly}'");
				MonoDetourLogger.Log(MonoDetourLogger.LogChannel.Error, result.FailureMessage);
				return;
			}
			w.HandlerCreateCatch(typeof(InvalidProgramException), out WeaverExceptionCatchHandler handler);
			w.HandlerSetTryStart(tryStart, handler);
			w.HandlerSetTryEnd(w.Current, handler);
			w.InsertAfterCurrent(new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[2]
			{
				w.Create(OpCodes.Ldloc, variable),
				w.CreateCall(new Action<InvalidProgramException, MethodBody>(AnalyzeMethodBody))
			}));
			w.HandlerSetHandlerEnd(w.Current, handler);
			w.HandlerApply(handler);
		}

		private static MethodBody GetMethodBody(DynamicMethodDefinition dmd)
		{
			return dmd.Definition.Body;
		}

		private static void AnalyzeMethod(InvalidProgramException ex, DynamicMethodDefinition dmd)
		{
			AnalyzeMethodBody(ex, dmd.Definition.Body);
		}

		private static void AnalyzeMethodBody(InvalidProgramException ex, MethodBody body)
		{
			IInformationalMethodBody informationalBody;
			try
			{
				informationalBody = body.CreateInformationalSnapshotJIT().AnnotateErrors();
			}
			catch
			{
				throw new Exception("MonoDetour failed to analyze invalid program.", ex);
			}
			throw new InvalidProgramException(informationalBody.ToErrorMessageString(), ex);
		}
	}
	internal static class ProxyILHookConstructor
	{
		private static Dictionary<IMonoDetourConfig, ILHookConfig>? interfaceToConfig;

		private static readonly ILHook detourContextHook;

		static ProxyILHookConstructor()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			if (!MonoModVersion.IsReorg)
			{
				detourContextHook = new ILHook((MethodBase)new Func<DetourContext>(DetourContextGetCurrent).Method, new Manipulator(ILHook_DetourContextGetCurrent));
			}
		}

		private static void ILHook_DetourContextGetCurrent(ILContext il)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0044: 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)
			MethodInfo methodInfo = typeof(DetourContext).GetProperty("Current", BindingFlags.Static | BindingFlags.NonPublic).GetGetMethod(nonPublic: true) ?? throw new NullReferenceException("Couldn't find 'DetourContext.get_Current'.");
			ILCursor val = new ILCursor(il);
			val.Body.Instructions.Clear();
			val.Emit(OpCodes.Call, (MethodBase)methodInfo);
			val.Emit(OpCodes.Ret);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static DetourContext DetourContextGetCurrent()
		{
			throw new NotImplementedException("DetourContextGetCurrent wasn't initialized.");
		}

		internal static ILHook ConstructILHook(MethodBase target, Manipulator manipulator, IMonoDetourConfig? config, string id)
		{
			if (MonoModVersion.IsReorg)
			{
				return ReorgILHook.ConstructILHook(target, manipulator, config, id);
			}
			return ConstructLegacyILHook(target, manipulator, config, id);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static ILHook ConstructLegacyILHook(MethodBase target, Manipulator manipulator, IMonoDetourConfig? config, string id)
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			//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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_003f: Expected O, but got Unknown
			//IL_00cf: 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_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_0050: 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_0057: Expected O, but got Unknown
			if (interfaceToConfig == null)
			{
				interfaceToConfig = new Dictionary<IMonoDetourConfig, ILHookConfig>();
			}
			if (config == null)
			{
				DetourContext val = DetourContextGetCurrent();
				if (val != null)
				{
					ILHookConfig iLHookConfig = val.ILHookConfig;
					if (!iLHookConfig.ManualApply)
					{
						ILHookConfig val2 = iLHookConfig;
						val2.ManualApply = true;
						ILHookConfig val3 = val2;
						return new ILHook(target, manipulator, val3);
					}
					return new ILHook(target, manipulator, iLHookConfig);
				}
				return new ILHook(target, manipulator, new ILHookConfig
				{
					ID = id,
					ManualApply = true
				});
			}
			if (!interfaceToConfig.TryGetValue(config, out var value))
			{
				ILHookConfig val2 = default(ILHookConfig);
				val2.ID = config.OverrideId ?? id;
				val2.Priority = config.Priority;
				val2.Before = config.Before;
				val2.After = config.After;
				val2.ManualApply = true;
				value = val2;
				interfaceToConfig.Add(config, value);
				return new ILHook(target, manipulator, value);
			}
			return new ILHook(target, manipulator, value);
		}
	}
}
namespace MonoDetour.Interop.MonoModUtils
{
	internal static class InteropFastDelegateInvokers
	{
		private static MethodInfo? getDelegateInvoker;

		internal static (MethodInfo Invoker, Type Delegate)? GetDelegateInvoker(ILContext il, Type delegateType)
		{
			if (!MonoModVersion.IsReorg)
			{
				return LegacyGetDelegateInvoker(il, delegateType);
			}
			return ReorgFastDelegateInvokers.GetDelegateInvoker(delegateType);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static (MethodInfo Invoker, Type Delegate)? LegacyGetDelegateInvoker(ILContext il, Type delegateType)
		{
			IILReferenceBag referenceBag = il.ReferenceBag;
			RuntimeILReferenceBag val = (RuntimeILReferenceBag)(object)((referenceBag is RuntimeILReferenceBag) ? referenceBag : null);
			if (val == null)
			{
				throw new Exception("ReferenceBag is not RuntimeILReferenceBag! If you are not in an ILHook managed by MonoMod, do not use this method.");
			}
			if ((object)getDelegateInvoker == null)
			{
				Type typeFromHandle = typeof(RuntimeILReferenceBag);
				MethodInfo method = typeFromHandle.GetMethod("GetDelegateInvoker");
				getDelegateInvoker = method;
			}
			MethodInfo methodInfo = getDelegateInvoker.MakeGenericMethod(delegateType);
			MethodInfo methodInfo2 = (MethodInfo)methodInfo.Invoke(val, Array.Empty<object>());
			if ((object)methodInfo2 == null)
			{
				return null;
			}
			return (methodInfo2, delegateType);
		}
	}
	internal static class InteropILContext
	{
		[CompilerGenerated]
		private sealed class <LegacyGetReference>d__4 : IEnumerable<Instruction>, IEnumerable, IEnumerator<Instruction>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private Instruction <>2__current;

			private int <>l__initialThreadId;

			private ILContext context;

			public ILContext <>3__context;

			private Type t;

			public Type <>3__t;

			private ILWeaver w;

			public ILWeaver <>3__w;

			private int id;

			public int <>3__id;

			private MethodInfo <delegateInvoker>5__2;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<delegateInvoker>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
				//IL_009f: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					IILReferenceBag referenceBag = context.ReferenceBag;
					RuntimeILReferenceBag val = (RuntimeILReferenceBag)(object)((referenceBag is RuntimeILReferenceBag) ? referenceBag : null);
					if (val == null)
					{
						throw new Exception("ReferenceBag is not RuntimeILReferenceBag! If you are not in an ILHook managed by MonoMod, do not use this method.");
					}
					if ((object)getGetter == null)
					{
						Type typeFromHandle = typeof(RuntimeILReferenceBag);
						MethodInfo method = typeFromHandle.GetMethod("GetGetter");
						getGetter = method;
					}
					MethodInfo methodInfo = getGetter.MakeGenericMethod(t);
					<delegateInvoker>5__2 = (MethodInfo)methodInfo.Invoke(val, Array.Empty<object>());
					<>2__current = w.Create(OpCodes.Ldc_I4, id);
					<>1__state = 1;
					return true;
				}
				case 1:
					<>1__state = -1;
					<>2__current = w.Create(OpCodes.Call, (MethodBase)<delegateInvoker>5__2);
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					return false;
				}
			}

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

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

			[DebuggerHidden]
			IEnumerator<Instruction> IEnumerable<Instruction>.GetEnumerator()
			{
				<LegacyGetReference>d__4 <LegacyGetReference>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<LegacyGetReference>d__ = this;
				}
				else
				{
					<LegacyGetReference>d__ = new <LegacyGetReference>d__4(0);
				}
				<LegacyGetReference>d__.t = <>3__t;
				<LegacyGetReference>d__.context = <>3__context;
				<LegacyGetReference>d__.w = <>3__w;
				<LegacyGetReference>d__.id = <>3__id;
				return <LegacyGetReference>d__;
			}

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

		private static MethodInfo? getGetter;

		internal static int InteropAddReference<T>(this ILContext context, in T? t)
		{
			if (!MonoModVersion.IsReorg)
			{
				return LegacyAddReference(context, t);
			}
			return ReorgILContext.AddReference<T>(context, ref t);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static int LegacyAddReference<T>(ILContext context, T? t)
		{
			return context.AddReference<T>(t);
		}

		internal static IEnumerable<Instruction> InteropGetReference(this ILContext context, ILWeaver weaver, int id, Delegate @delegate)
		{
			if (!MonoModVersion.IsReorg)
			{
				return LegacyGetReference(@delegate.GetType(), context, weaver, id);
			}
			return ReorgILContext.GetReference(@delegate.GetType(), context, id);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		[IteratorStateMachine(typeof(<LegacyGetReference>d__4))]
		private static IEnumerable<Instruction> LegacyGetReference(Type t, ILContext context, ILWeaver w, int id)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LegacyGetReference>d__4(-2)
			{
				<>3__t = t,
				<>3__context = context,
				<>3__w = w,
				<>3__id = id
			};
		}
	}
	internal static class InteropILCursor
	{
		internal static int InteropEmitReference<T>(this ILCursor cursor, in T? t)
		{
			if (!MonoModVersion.IsReorg)
			{
				return LegacyEmitReference(cursor, t);
			}
			return ReorgILCursor.EmitReference<T>(cursor, ref t);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static int LegacyEmitReference<T>(ILCursor cursor, T? t)
		{
			return cursor.EmitReference<T>(t);
		}

		internal static int InteropEmitReferenceBefore<T>(this ILContext context, Instruction target, in T? t)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return new ILCursor(context).Goto(target, (MoveType)0, false).InteropEmitReference(in t);
		}

		internal static void EmitGetReferenceBefore<T>(ILContext context, Instruction target, int id) where T : Delegate
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			new ILCursor(context).Goto(target, (MoveType)0, false).EmitGetReference<T>(id);
		}

		internal static int EmitDelegateBefore<T>(ILContext context, Instruction target, in T cb) where T : Delegate
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return new ILCursor(context).Goto(target, (MoveType)0, false).EmitDelegate<T>(cb);
		}
	}
	internal static class InteropILLabel
	{
		internal static Instruction? InteropGetTarget(this ILLabel label)
		{
			if (!MonoModVersion.IsReorg)
			{
				return LegacyGetTarget(label);
			}
			return ReorgILLabel.GetTarget(label);
		}

		internal static void InteropSetTarget(this ILLabel label, Instruction value)
		{
			if (MonoModVersion.IsReorg)
			{
				ReorgILLabel.SetTarget(label, value);
			}
			else
			{
				LegacySetTarget(label, value);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Instruction? LegacyGetTarget(ILLabel label)
		{
			return label.Target;
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Instruction? LegacySetTarget(ILLabel label, Instruction value)
		{
			return label.Target = value;
		}
	}
}
namespace MonoDetour.Interop.Cecil
{
	internal static class ILHookInstructionILLabelCastFixes
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Manipulator <0>__ILHook_Instruction_ToString;

			public static Manipulator <1>__ILHook_Instruction_GetSize;

			public static Func<object, object> <2>__IfILLabelThenReturnTargetInstruction;

			public static Func<object, object> <3>__IfILLabelArrayThenReturnTargetInstruction;
		}

		private static ILHook castILLabelToInstructionToStringILHook;

		private static ILHook castILLabelToInstructionGetSizeILHook;

		private static bool initialized;

		internal static void InitHook()
		{
			if (initialized)
			{
				return;
			}
			initialized = true;
			try
			{
				InitHookToString();
				InitHookGetSize();
			}
			catch (Exception innerException)
			{
				throw new NotSupportedException("MonoDetour doesn't seem to support this Mono.Cecil version, please report this issue: https://github.com/MonoDetour/MonoDetour: " + $"'{typeof(Instruction).Assembly}'", innerException);
			}
		}

		private static void InitHookToString()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			MethodInfo? method = typeof(Instruction).GetMethod("ToString", Array.Empty<Type>());
			object obj = <>O.<0>__ILHook_Instruction_ToString;
			if (obj == null)
			{
				Manipulator val = ILHook_Instruction_ToString;
				<>O.<0>__ILHook_Instruction_ToString = val;
				obj = (object)val;
			}
			castILLabelToInstructionToStringILHook = new ILHook((MethodBase)method, (Manipulator)obj);
		}

		private static void InitHookGetSize()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			MethodInfo? method = typeof(Instruction).GetMethod("GetSize", Array.Empty<Type>());
			object obj = <>O.<1>__ILHook_Instruction_GetSize;
			if (obj == null)
			{
				Manipulator val = ILHook_Instruction_GetSize;
				<>O.<1>__ILHook_Instruction_GetSize = val;
				obj = (object)val;
			}
			castILLabelToInstructionGetSizeILHook = new ILHook((MethodBase)method, (Manipulator)obj);
		}

		private static void ILHook_Instruction_ToString(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			ILCursor val = new ILCursor(il);
			if (!val.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCastclass<Instruction>(x)
			}))
			{
				MonoDetourLogger.Log(MonoDetourLogger.LogChannel.Error, "ILHook_Instruction_ToString] Could not find 'castclass Mono.Cecil.Cil.Instruction'!");
				return;
			}
			val.EmitDelegate<Func<object, object>>((Func<object, object>)IfILLabelThenReturnTargetInstruction);
			if (!val.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCastclass<Instruction[]>(x)
			}))
			{
				MonoDetourLogger.Log(MonoDetourLogger.LogChannel.Error, "ILHook_Instruction_ToString] Could not find 'castclass class Mono.Cecil.Cil.Instruction[]'!");
			}
			else
			{
				val.EmitDelegate<Func<object, object>>((Func<object, object>)IfILLabelArrayThenReturnTargetInstruction);
			}
		}

		private static void ILHook_Instruction_GetSize(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			ILCursor val = new ILCursor(il);
			if (!val.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCastclass<Instruction[]>(x)
			}))
			{
				MonoDetourLogger.Log(MonoDetourLogger.LogChannel.Error, "[ILHook_Instruction_GetSize] Could not find 'castclass class Mono.Cecil.Cil.Instruction[]'!");
			}
			else
			{
				val.EmitDelegate<Func<object, object>>((Func<object, object>)IfILLabelArrayThenReturnTargetInstruction);
			}
		}

		private static object? IfILLabelThenReturnTargetInstruction(object operand)
		{
			ILLabel val = (ILLabel)((operand is ILLabel) ? operand : null);
			if (val != null)
			{
				return val.InteropGetTarget() ?? throw new NullReferenceException("ILLabel.Target must not not be null!");
			}
			return operand;
		}

		private static object IfILLabelArrayThenReturnTargetInstruction(object operand)
		{
			if (operand is ILLabel[] source)
			{
				return source.Select((ILLabel l) => l.InteropGetTarget()).ToArray();
			}
			return operand;
		}
	}
}
namespace MonoDetour.DetourTypes
{
	public class ILHookDetour : IMonoDetourHookApplier
	{
		private IReadOnlyMonoDetourHook _hook;

		private ILManipulationInfo.Manipulator invoker;

		public IReadOnlyMonoDetourHook Hook
		{
			get
			{
				return _hook;
			}
			set
			{
				_hook = value;
				invoker = ((ILManipulationInfo.Manipulator)_hook.ManipulatorDelegate) ?? ((ILManipulationInfo.Manipulator)Delegate.CreateDelegate(typeof(ILManipulationInfo.Manipulator), (Hook.Manipulator as MethodInfo) ?? throw new InvalidCastException("Hook Manipulator method is not MethodInfo!")));
			}
		}

		public void ApplierManipulator(ILContext il)
		{
			ILContext il2 = il;
			ReadOnlyCollection<Instruction> originalInstructions = HookTargetRecords.GetOriginalInstructions(il2.Method);
			ILManipulationInfo info = new ILManipulationInfo(il2, Hook.Target, originalInstructions);
			invoker(info);
			Hook.Owner.Log(MonoDetourLogger.LogChannel.IL, delegate
			{
				IInformationalMethodBody arg = il2.Body.CreateInformationalSnapshotJIT().AnnotateErrors();
				return $"Manipulated by ILHook: {Hook.Manipulator.Name} ({Hook.Owner.Id}):\n{arg}";
			});
		}
	}
	public interface IMonoDetourHookApplier
	{
		IReadOnlyMonoDetourHook Hook { get; set; }

		void ApplierManipulator(ILContext il);
	}
	public class PostfixDetour : IMonoDetourHookApplier
	{
		private IReadOnlyMonoDetourHook hook;

		private static readonly List<Delegate> postfixDelegates = new List<Delegate>();

		private static readonly List<IReadOnlyMonoDetourHook> postfixHooks = new List<IReadOnlyMonoDetourHook>();

		private int delegateId = -1;

		private int hookId = -1;

		public IReadOnlyMonoDetourHook Hook
		{
			get
			{
				return hook;
			}
			set
			{
				hook = value;
				hookId = postfixHooks.Count;
				postfixHooks.Add(hook);
				Delegate manipulatorDelegate = value.ManipulatorDelegate;
				if ((object)manipulatorDelegate != null)
				{
					delegateId = postfixDelegates.Count;
					postfixDelegates.Add(manipulatorDelegate);
				}
			}
		}

		private static Delegate GetDelegate(int id)
		{
			return postfixDelegates[id];
		}

		private static IReadOnlyMonoDetourHook GetHook(int id)
		{
			return postfixHooks[id];
		}

		public void ApplierManipulator(ILContext il)
		{
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			if (Hook.ModifiesControlFlow())
			{
				throw new NotSupportedException("A PostfixDetour may not modify control flow.");
			}
			HookTargetRecords.HookTargetInfo hookTargetInfo = HookTargetRecords.GetHookTargetInfo(il);
			ReadOnlyCollection<Instruction> originalInstructions = HookTargetRecords.GetOriginalInstructions(il.Method);
			ILWeaver w = new ILWeaver(new ILManipulationInfo(il, Hook.Target, originalInstructions));
			w.CurrentTo(w.Last);
			List<Instruction> firstPostfixInstructions = hookTargetInfo.PostfixInfo.FirstPostfixInstructions;
			ILLabel label = RedirectEarlyReturnsToLabel(w, hookTargetInfo);
			IEnumerable<ILLabel> incomingLabelsFor = w.GetIncomingLabelsFor(label.InteropGetTarget());
			w.MarkLabelToFutureNextInsert(label);
			w.HandlerCreateCatch(null, out WeaverExceptionCatchHandler handler);
			w.DefineLabel(out ILLabel label2);
			w.HandlerSetTryStart(label2, handler);
			Instruction callMaybeInsertGetDelegate;
			if (hookTargetInfo.ReturnValue != null)
			{
				w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Stloc, hookTargetInfo.ReturnValue)));
				w.MarkLabelToFutureNextInsert(label2);
				callMaybeInsertGetDelegate = Utils.GetCallMaybeInsertGetDelegate(w, Hook, delegateId, GetDelegate);
				w.EmitParamsAndReturnValueBeforeCurrent(hookTargetInfo.ReturnValue, Hook);
			}
			else
			{
				w.MarkLabelToFutureNextInsert(label2);
				callMaybeInsertGetDelegate = Utils.GetCallMaybeInsertGetDelegate(w, Hook, delegateId, GetDelegate);
				w.EmitParamsBeforeCurrent(Hook);
			}
			w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(callMaybeInsertGetDelegate));
			w.HandlerSetTryEnd(w.Previous, handler);
			w.InsertBeforeCurrent(new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[3]
			{
				w.Create(OpCodes.Ldc_I4, hookId),
				w.CreateCall(new Func<int, IReadOnlyMonoDetourHook>(GetHook)),
				w.CreateCall(new Action<Exception, IReadOnlyMonoDetourHook>(Utils.DisposeBadHooks))
			}));
			w.HandlerSetHandlerEnd(w.Previous, handler);
			if (hookTargetInfo.ReturnValue != null)
			{
				w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Ldloc, hookTargetInfo.ReturnValue)));
			}
			else
			{
				w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Nop)));
			}
			w.RetargetLabels(incomingLabelsFor, label.InteropGetTarget());
			firstPostfixInstructions.Add(label.InteropGetTarget());
			Enumerator<ExceptionHandler> enumerator = il.Body.ExceptionHandlers.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					ExceptionHandler current = enumerator.Current;
					if (current.HandlerEnd == w.Last)
					{
						current.HandlerEnd = label.InteropGetTarget();
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			w.HandlerApply(handler);
			Hook.Owner.Log(MonoDetourLogger.LogChannel.IL, delegate
			{
				IInformationalMethodBody arg = w.Body.CreateInformationalSnapshotJIT().AnnotateErrors();
				return $"Manipulated by Postfix: {Hook.Manipulator.Name} ({Hook.Owner.Id}):\n{arg}";
			});
		}

		private static ILLabel RedirectEarlyReturnsToLabel(ILWeaver w, HookTargetRecords.HookTargetInfo info)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: 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_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			List<Instruction> firstPostfixInstructions = info.PostfixInfo.FirstPostfixInstructions;
			VariableDefinition? returnValue = info.ReturnValue;
			int? num = ((returnValue != null) ? new int?(((VariableReference)returnValue).Index) : null);
			if (w.Body.Instructions.Count == 0)
			{
				w.Body.Instructions.Add(w.Create(OpCodes.Nop));
			}
			Collection<Instruction> instructions = w.Body.Instructions;
			Instruction last = w.Last;
			w.DefineAndMarkLabelTo(last, out ILLabel markedLabel);
			bool flag = false;
			foreach (Instruction item in ((IEnumerable<Instruction>)w.Body.Instructions).Where((Instruction ins) => ILPatternMatchingExt.MatchRet(ins)))
			{
				flag = true;
				Instruction next = item.Next;
				if (next == null)
				{
					continue;
				}
				if (num.HasValue)
				{
					int valueOrDefault = num.GetValueOrDefault();
					Instruction next2 = next.Next;
					if (((next2 != null) ? next2.Next : null) != null)
					{
						Instruction previous = item.Previous;
						if (((previous != null) ? new bool?(ILPatternMatchingExt.MatchLdloc(previous, valueOrDefault)) : null) ?? false)
						{
							if (next.Next.OpCode == OpCodes.Ret && ILPatternMatchingExt.MatchLdloc(next, valueOrDefault))
							{
								continue;
							}
							Instruction previous2 = item.Previous.Previous;
							OpCode? val = ((previous2 != null) ? new OpCode?(previous2.OpCode) : null);
							OpCode ret = OpCodes.Ret;
							if (val.HasValue && val.GetValueOrDefault() == ret)
							{
								Instruction previous3 = item.Previous.Previous.Previous;
								if (((previous3 != null) ? new bool?(ILPatternMatchingExt.MatchLdloc(previous3, valueOrDefault)) : null) ?? false)
								{
									continue;
								}
							}
						}
					}
				}
				else if (next.Next != null)
				{
					if (next.OpCode == OpCodes.Ret)
					{
						continue;
					}
					Instruction previous4 = item.Previous;
					OpCode? val = ((previous4 != null) ? new OpCode?(previous4.OpCode) : null);
					OpCode ret = OpCodes.Ret;
					if (val.HasValue && val.GetValueOrDefault() == ret)
					{
						continue;
					}
				}
				bool flag2 = false;
				foreach (Instruction item2 in firstPostfixInstructions)
				{
					if (item2 != null && instructions.IndexOf(item) < instructions.IndexOf(item2))
					{
						item.OpCode = OpCodes.Br;
						item.Operand = item2;
						flag2 = true;
						break;
					}
				}
				if (!flag2)
				{
					item.OpCode = OpCodes.Br;
					item.Operand = markedLabel;
				}
			}
			last.OpCode = (flag ? OpCodes.Ret : OpCodes.Nop);
			last.Operand = null;
			return markedLabel;
		}
	}
	public class PrefixDetour : IMonoDetourHookApplier
	{
		private IReadOnlyMonoDetourHook hook;

		private static readonly List<Delegate> prefixDelegates = new List<Delegate>();

		private static readonly List<IReadOnlyMonoDetourHook> prefixHooks = new List<IReadOnlyMonoDetourHook>();

		private int delegateId = -1;

		private int hookId = -1;

		public IReadOnlyMonoDetourHook Hook
		{
			get
			{
				return hook;
			}
			set
			{
				hook = value;
				hookId = prefixHooks.Count;
				prefixHooks.Add(hook);
				Delegate manipulatorDelegate = value.ManipulatorDelegate;
				if ((object)manipulatorDelegate != null)
				{
					delegateId = prefixDelegates.Count;
					prefixDelegates.Add(manipulatorDelegate);
				}
			}
		}

		private static Delegate GetDelegate(int id)
		{
			return prefixDelegates[id];
		}

		private static IReadOnlyMonoDetourHook GetHook(int id)
		{
			return prefixHooks[id];
		}

		public void ApplierManipulator(ILContext il)
		{
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_037a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0398: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_045c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0516: Unknown result type (might be due to invalid IL or missing references)
			HookTargetRecords.HookTargetInfo hookTargetInfo = HookTargetRecords.GetHookTargetInfo(il);
			ReadOnlyCollection<Instruction> originalInstructions = HookTargetRecords.GetOriginalInstructions(il.Method);
			ILWeaver w = new ILWeaver(new ILManipulationInfo(il, Hook.Target, originalInstructions));
			bool flag = Hook.ModifiesControlFlow() && hookTargetInfo.ReturnValue != null;
			w.HandlerCreateCatch(null, out WeaverExceptionCatchHandler handler);
			w.DefineAndMarkLabelToFutureNextInsert(out ILLabel futureMarkedLabel);
			w.HandlerSetTryStart(futureMarkedLabel, handler);
			Instruction callMaybeInsertGetDelegate = Utils.GetCallMaybeInsertGetDelegate(w, Hook, delegateId, GetDelegate);
			if (flag)
			{
				w.EmitParamsAndReturnValueBeforeCurrent(hookTargetInfo.ReturnValue, Hook);
			}
			else
			{
				w.EmitParamsBeforeCurrent(Hook);
			}
			w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(callMaybeInsertGetDelegate));
			if (Hook.ModifiesControlFlow())
			{
				w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Stloc, hookTargetInfo.PrefixInfo.TemporaryControlFlow)));
			}
			w.HandlerSetTryEnd(w.Previous, handler);
			w.InsertBeforeCurrent(new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[3]
			{
				w.Create(OpCodes.Ldc_I4, hookId),
				w.CreateCall(new Func<int, IReadOnlyMonoDetourHook>(GetHook)),
				w.CreateCall(new Action<Exception, IReadOnlyMonoDetourHook>(Utils.DisposeBadHooks))
			}));
			w.HandlerSetHandlerEnd(w.Previous, handler);
			if (Hook.ModifiesControlFlow())
			{
				Instruction val = w.Create(OpCodes.Switch, new object());
				w.InsertBeforeCurrent(new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[2]
				{
					w.Create(OpCodes.Ldloc, hookTargetInfo.PrefixInfo.TemporaryControlFlow),
					val
				}));
				w.DefineAndMarkLabelToFutureNextInsert(out ILLabel futureMarkedLabel2);
				for (int i = 0; i < 2; i++)
				{
					if (hookTargetInfo.ReturnValue != null)
					{
						w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Ldloc, hookTargetInfo.ReturnValue)));
					}
					w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(hookTargetInfo.MarkPersistentInstruction(w.Create(OpCodes.Ret))));
				}
				w.DefineAndMarkLabelToFutureNextInsert(out ILLabel futureMarkedLabel3);
				w.InsertBeforeCurrent(new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[2]
				{
					w.Create(OpCodes.Ldc_I4_1),
					w.Create(OpCodes.Stloc, hookTargetInfo.PrefixInfo.ControlFlow)
				}));
				w.DefineAndMarkLabelToCurrentOrFutureNextInsert(out ILLabel futureMarkedLabel4);
				val.Operand = new ILLabel[3] { futureMarkedLabel4, futureMarkedLabel3, futureMarkedLabel2 };
			}
			if (!hookTargetInfo.PrefixInfo.ControlFlowImplemented)
			{
				hookTargetInfo.PrefixInfo.SetControlFlowImplemented();
				w.DefineAndMarkLabelToCurrent(out ILLabel markedLabel);
				w.InsertBeforeCurrent(new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[2]
				{
					w.Create(OpCodes.Ldloc, hookTargetInfo.PrefixInfo.ControlFlow),
					w.Create(OpCodes.Brfalse, (object)markedLabel)
				}));
				if (hookTargetInfo.ReturnValue != null)
				{
					w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Ldloc, hookTargetInfo.ReturnValue)));
				}
				if (hookTargetInfo.PostfixInfo.FirstPostfixInstructions.FirstOrDefault() == null)
				{
					w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Ret)));
				}
				else
				{
					bool flag2 = false;
					foreach (Instruction firstPostfixInstruction in hookTargetInfo.PostfixInfo.FirstPostfixInstructions)
					{
						if (w.Body.Instructions.Contains(firstPostfixInstruction))
						{
							w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Br, firstPostfixInstruction)));
							flag2 = true;
							break;
						}
					}
					if (!flag2)
					{
						Hook.Owner.Log(MonoDetourLogger.LogChannel.Warning, "While applying Prefix: " + Hook.Manipulator.Name + " (" + Hook.Owner.Id + "): No postfix labels found despite postfixes being applied on the method. " + $"Postfixes might not run on method '{Hook.Target}'. ");
						w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Ret)));
					}
				}
			}
			w.HandlerApply(handler);
			Hook.Owner.Log(MonoDetourLogger.LogChannel.IL, delegate
			{
				IInformationalMethodBody arg = w.Body.CreateInformationalSnapshotJIT().AnnotateErrors();
				return $"Manipulated by Prefix: {Hook.Manipulator.Name} ({Hook.Owner.Id}):\n{arg}";
			});
		}
	}
	public enum ReturnFlow
	{
		None,
		SkipOriginal,
		HardReturn
	}
}
namespace MonoDetour.DetourTypes.Manipulation
{
	public static class HookTargetRecords
	{
		public class HookTargetInfo
		{
			public TargetPrefixInfo PrefixInfo { get; }

			public TargetPostfixInfo PostfixInfo { get; } = new TargetPostfixInfo();


			public VariableDefinition? ReturnValue { get; }

			internal HashSet<Instruction> PersistentInstructions { get; } = new HashSet<Instruction>();


			internal HookTargetInfo(MethodDefinition method, VariableDefinition? returnValue)
			{
				PrefixInfo = new TargetPrefixInfo(method);
				ReturnValue = returnValue;
			}

			internal Instruction MarkPersistentInstruction(Instruction instruction)
			{
				PersistentInstructions.Add(instruction);
				return instruction;
			}

			internal bool IsPersistentInstruction(Instruction instruction)
			{
				return PersistentInstructions.Contains(instruction);
			}
		}

		public class TargetPrefixInfo
		{
			public VariableDefinition ControlFlow { get; }

			public VariableDefinition TemporaryControlFlow { get; }

			public bool ControlFlowImplemented { get; private set; }

			internal TargetPrefixInfo(MethodDefinition method)
			{
				ControlFlow = method.DeclareVariable(typeof(int));
				TemporaryControlFlow = method.DeclareVariable(typeof(int));
			}

			public void SetControlFlowImplemented()
			{
				ControlFlowImplemented = true;
			}
		}

		public class TargetPostfixInfo
		{
			public List<Instruction> FirstPostfixInstructions { get; } = new List<Instruction>();


			internal TargetPostfixInfo()
			{
			}
		}

		private static readonly ConditionalWeakTable<MethodDefinition, HookTargetInfo> s_MethodToInfo = new ConditionalWeakTable<MethodDefinition, HookTargetInfo>();

		internal static ReadOnlyCollection<Instruction> GetOriginalInstructions(MethodDefinition method)
		{
			ConditionalWeakTable<MethodDefinition, ReadOnlyCollection<Instruction>> s_MethodDefinitionToOriginalInstructions = ILHookDMDManipulation.s_MethodDefinitionToOriginalInstructions;
			if (s_MethodDefinitionToOriginalInstructions.TryGetValue(method, out var value))
			{
				return value;
			}
			throw new Exception("Tried to get original instructions for a method which MonoDetour does not know about.");
		}

		internal static void SwapOriginalInstructionsCollection(MethodDefinition method, ReadOnlyCollection<Instruction> replacement)
		{
			ILHookDMDManipulation.s_MethodDefinitionToOriginalInstructions.Remove(method);
			ILHookDMDManipulation.s_MethodDefinitionToOriginalInstructions.Add(method, replacement);
		}

		public static HookTargetInfo GetHookTargetInfo(ILContext il)
		{
			return GetHookTargetInfo(il.Method);
		}

		public static HookTargetInfo GetHookTargetInfo(MethodDefinition method)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			if (s_MethodToInfo.TryGetValue(method, out HookTargetInfo value))
			{
				return value;
			}
			VariableDefinition val = null;
			if ((int)((MethodReference)method).ReturnType.MetadataType != 1)
			{
				val = new VariableDefinition(((MethodReference)method).ReturnType);
				method.Body.Variables.Add(val);
			}
			value = new HookTargetInfo(method, val);
			s_MethodToInfo.Add(method, value);
			return value;
		}

		private static VariableDefinition DeclareVariable(this MethodDefinition method, Type type)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			VariableDefinition val = new VariableDefinition(((MemberReference)method).Module.ImportReference(type));
			method.Body.Variables.Add(val);
			return val;
		}
	}
	internal static class Utils
	{
		private static void WriteSpeakableEnumerator(ILWeaver w, Type speakableEnumeratorType, Type enumeratorType)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			MethodInfo method = speakableEnumeratorType.GetMethod("PreBuildFieldReferenceGetters");
			method.Invoke(null, new object[1] { enumeratorType });
			MethodInfo method2 = speakableEnumeratorType.GetMethod("GetOrCreate");
			w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Call, (MethodBase)method2)));
		}

		public static bool ModifiesControlFlow(this IReadOnlyMonoDetourHook hook)
		{
			if (hook.Manipulator is MethodInfo methodInfo)
			{
				return methodInfo.ReturnType == typeof(ReturnFlow);
			}
			return false;
		}

		public static void EmitParamsAndReturnValueBeforeCurrent(this ILWeaver w, VariableDefinition returnValue, IReadOnlyMonoDetourHook hook)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			Helpers.ThrowIfNull<VariableDefinition>(returnValue, "returnValue");
			w.EmitParamsBeforeCurrent(hook);
			w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Ldloca, returnValue)));
		}

		public static void EmitParamsBeforeCurrent(this ILWeaver w, IReadOnlyMonoDetourHook hook)
		{
			//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_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			bool isStatic = hook.Target.IsStatic;
			Enumerator<ParameterDefinition> enumerator = ((MethodReference)w.Method).Parameters.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					ParameterDefinition current = enumerator.Current;
					if (!isStatic && ((ParameterReference)current).Index == 0)
					{
						Type parameterType = hook.Manipulator.GetParameters().First().ParameterType;
						if (typeof(ISpeakableEnumerator).IsAssignableFrom(parameterType))
						{
							Type enumeratorType = hook.Target.DeclaringType ?? throw new NullReferenceException("Declaring type of target method is null!");
							w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Ldarg, ((ParameterReference)current).Index)));
							WriteSpeakableEnumerator(w, parameterType, enumeratorType);
						}
						else
						{
							w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Ldarg, ((ParameterReference)current).Index)));
						}
					}
					else if (((ParameterReference)current).ParameterType.IsByReference)
					{
						w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Ldarg, ((ParameterReference)current).Index)));
					}
					else
					{
						w.InsertBeforeCurrent(new <>z__ReadOnlySingleElementList<Instruction>(w.Create(OpCodes.Ldarga, ((ParameterReference)current).Index)));
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
		}

		internal static void DisposeBadHooks(Exception ex, IReadOnlyMonoDetourHook hook)
		{
			IReadOnlyMonoDetourHook hook2 = hook;
			Exception ex2 = ex;
			MethodBase manipulator = hook2.Manipulator;
			MethodBase target = hook2.Target;
			string text = target.DeclaringType?.FullName;
			int hooksCount = hook2.Owner.Hooks.Count;
			hook2.Owner.Log(MonoDetourLogger.LogChannel.Error, () => "Exception caught in a hook belonging to MonoDetourManager '" + hook2.Owner.Id + "'" + $" (disposing all {hooksCount} of its hooks in an attempt to minimize potential damage):\n" + ex2);
			try
			{
				if (!hook2.Owner.CallOnHookThrew(hook2))
				{
					hook2.Owner.Log(MonoDetourLogger.LogChannel.Warning, () => "No disposal event handler for the MonoDetourManager was registered. You can subscribe to the MonoDetourManager.OnHookThrew event to clean up the rest of your resources.");
				}
			}
			catch (Exception ex3)
			{
				Exception ex4 = ex3;
				Exception disposalEx = ex4;
				hook2.Owner.Log(MonoDetourLogger.LogChannel.Error, () => $"Disposal event handler threw an exception:\n{disposalEx}");
			}
			finally
			{
				hook2.Owner.DisposeHooks();
			}
		}

		internal static void ThrowIfHookManipulatorDelegateIsNull(IReadOnlyMonoDetourHook hook, out Delegate manipulatorDelegate)
		{
			Delegate manipulatorDelegate2 = hook.ManipulatorDelegate;
			if ((object)manipulatorDelegate2 != null)
			{
				manipulatorDelegate = manipulatorDelegate2;
				return;
			}
			throw new NullReferenceException("IReadOnlyMonoDetourHook.Manipulator is not static, and IReadOnlyMonoDetourHook.ManipulatorDelegate is null. Please use a constructor which takes a Delegate instead of a MethodBase for Manipulator.");
		}

		internal static Instruction GetCallMaybeInsertGetDelegate(ILWeaver w, IReadOnlyMonoDetourHook hook, int id, Func<int, Delegate> getDelegate)
		{
			//IL_0031: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			if (hook.Manipulator.IsStatic)
			{
				return w.Create(OpCodes.Call, hook.Manipulator);
			}
			ThrowIfHookManipulatorDelegateIsNull(hook, out Delegate manipulatorDelegate);
			w.InsertBeforeCurrent(new <>z__ReadOnlyArray<Instruction>((Instruction[])(object)new Instruction[2]
			{
				w.Create(OpCodes.Ldc_I4, id),
				w.CreateCall(getDelegate)
			}));
			MethodInfo method = manipulatorDelegate.GetType().GetMethod("Invoke");
			return w.Create(OpCodes.Callvirt, (MethodBase)method);
		}

		[Conditional("DEBUG")]
		internal static void DebugValidateCILValidatorNoErrors(IReadOnlyMonoDetourHook hook, MethodBody body)
		{
			IInformationalMethodBody informationalMethodBody = body.CreateInformationalSnapshotJIT().AnnotateErrors();
			if (informationalMethodBody.HasErrors())
			{
				hook.Owner.Log(MonoDetourLogger.LogChannel.Error, "Hook CIL validation failed! " + hook.Manipulator.Name + "\n" + informationalMethodBody.ToErrorMessageString());
			}
		}
	}
}
namespace MonoDetour.Cil
{
	public static class ILContextExtensions
	{
		public static string ToAnalyzedString(this ILContext context)
		{
			return context.Body.CreateInformationalSnapshotJIT().AnnotateErrors().ToStringWithAnnotations();
		}
	}
	public class ILManipulationInfo
	{
		public delegate void Manipulator(ILManipulationInfo info);

		private static readonly ReadOnlyCollection<Instruction> emptyCollection = new ReadOnlyCollection<Instruction>(new List<Instruction>());

		private ILContext? _original;

		public MethodBase? Original { get; }

		public ILContext Context { get; }

		public ReadOnlyCollection<Instruction> OriginalInstructions { get; }

		public ILContext UnmanipulatedContext
		{
			get
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Expected O, but got Unknown
				//IL_0027: Expected O, but got Unknown
				ILContext obj = _original;
				if (obj == null)
				{
					ILContext val = new ILContext(new DynamicMethodDefinition(Original).Definition);
					ILContext val2 = val;
					_original = val;
					obj = val2;
				}
				return obj;
			}
		}

		public ILManipulationInfo(ILContext il, MethodBase? original = null, ReadOnlyCollection<Instruction>? originalInstructions = null)
		{
			Original = original;
			Context = il;
			OriginalInstructions = originalInstructions ?? emptyCollection;
			base..ctor();
		}

		public override string ToString()
		{
			return Context.ToAnalyzedString();
		}
	}
	public class ILWeaver : IMonoDetourLogSource
	{
		private enum InsertType
		{
			BeforeAndStealLabels,
			Before,
			After
		}

		private enum MatchPassType
		{
			StrictNoOriginalPass,
			RelaxedAllowOriginalPass,
			IsOriginalPass
		}

		private const string obsoleteMessageRemoveAt = "Removing a range by count is prone to causing invalid IL if the target method's instructions have changed. Use ILWeaver.InsertBranchOver instead as it doesn't have this design flaw. Note that these two methods behave slightly differently; please read the method's remarks in detail.";

		private Instruction current;

		private readonly List<ILLabel> pendingFutureNextInsertLabels = new List<ILLabel>();

		private const string gotoMatchingDocsLink = "<documentation link will be here once it exists>";

		public ILManipulationInfo ManipulationInfo { get; }

		public ILContext Context { get; }

		public ILProcessor IL => Context.IL;

		public MethodBody Body => Context.Body;

		public MethodDefinition Method => Context.Method;

		public Collection<Instruction> Instructions => Context.Instrs;

		public Instruction Current
		{
			get
			{
				return current;
			}
			set
			{
				CurrentTo(value);
			}
		}

		public Instruction Previous => Current.Previous;

		public Instruction Next => Current.Next;

		public Instruction First => Instructions[0];

		public Instruction Last
		{
			get
			{
				Collection<Instruction> instructions = Instructions;
				return instructions[instructions.Count - 1];
			}
		}

		public int Index
		{
			get
			{
				return Instructions.IndexOf(Current);
			}
			[Obsolete("Offsetting the index is error-prone; see https://github.com/MonoDetour/MonoDetour/issues/10\nIf you know what you are doing, use ILWeaver.CurrentTo(int) directly.", true)]
			set
			{
				CurrentTo(value);
			}
		}

		public MonoDetourLogger.LogChannel LogFilter { get; set; } = MonoDetourLogger.LogChannel.Warning | MonoDetourLogger.LogChannel.Error;


		public ILWeaver(ILManipulationInfo il)
		{
			ManipulationInfo = Helpers.ThrowIfNull(il, "il");
			Context = il.Context;
			current = Context.Instrs[0];
		}

		public ILWeaver(ILWeaver weaver, bool copyState = true)
			: this(weaver.ManipulationInfo)
		{
			if (copyState)
			{
				Current = weaver.Current;
			}
		}

		public ILWeaver New()
		{
			return new ILWeaver(this, copyState: false);
		}

		public ILWeaver Clone()
		{
			return new ILWeaver(this);
		}

		public IEnumerable<ILLabel> GetIncomingLabelsForCurrent()
		{
			return Context.GetIncomingLabels(Current);
		}

		public IEnumerable<ILLabel> GetIncomingLabelsFor(Instruction target)
		{
			return Context.GetIncomingLabels(target);
		}

		public ILWeaver RetargetLabels(IEnumerable<ILLabel> labels, Instruction target)
		{
			foreach (ILLabel label in labels)
			{
				label.InteropSetTarget(target);
			}
			return this;
		}

		public ILWeaver RetargetLabels(ILLabel? label, Instruction target)
		{
			label?.InteropSetTarget(target);
			return this;
		}

		public ILLabel DefineLabel()
		{
			return Context.DefineLabel();
		}

		public ILWeaver DefineLabel(out ILLabel label)
		{
			label = Context.DefineLabel();
			return this;
		}

		public ILWeaver MarkLabelTo(Instruction target, ILLabel label)
		{
			Helpers.ThrowIfNull<Instruction>(target, "target");
			label.InteropSetTarget(target);
			return this;
		}

		public ILWeaver DefineAndMarkLabelTo(Instruction target, out ILLabel markedLabel)
		{
			Helpers.ThrowIfNull<Instruction>(target, "target");
			markedLabel = Context.DefineLabel(target);
			return this;
		}

		public ILLabel DefineAndMarkLabelTo(Instruction target)
		{
			DefineAndMarkLabelTo(target, out ILLabel markedLabel);
			return markedLabel;
		}

		public ILWeaver MarkLabelToFutureNextInsert(ILLabel label)
		{
			Helpers.ThrowIfNull<ILLabel>(label, "label");
			pendingFutureNextInsertLabels.Add(label);
			return this;
		}

		public ILWeaver DefineAndMarkLabelToFutureNextInsert(out ILLabel futureMarkedLabel)
		{
			futureMarkedLabel = Context.DefineLabel();
			pendingFutureNextInsertLabels.Add(futureMarkedLabel);
			return this;
		}

		public ILLabel DefineAndMarkLabelToFutureNextInsert()
		{
			DefineAndMarkLabelToFutureNextInsert(out ILLabel futureMarkedLabel);
			return futureMarkedLabel;
		}

		public ILWeaver MarkLabelToCurrentOrFutureNextInsert(ILLabel label)
		{
			Helpers.ThrowIfNull<ILLabel>(label, "label");
			label.InteropSetTarget(Current);
			pendingFutureNextInsertLabels.Add(label);
			return this;
		}

		public ILWeaver DefineAndMarkLabelToCurrentOrFutureNextInsert(out ILLabel futureMarkedLabel)
		{
			futureMarkedLabel = Context.DefineLabel(Current);
			pendingFutureNextInsertLabels.Add(futureMarkedLabel);
			return this;
		}

		public ILLabel DefineAndMarkLabelToCurrentOrFutureNextInsert()
		{
			DefineAndMarkLabelToCurrentOrFutureNextInsert(out ILLabel futureMarkedLabel);
			return futureMarkedLabel;
		}

		public ILWeaver MarkLabelToCurrent(ILLabel label)
		{
			Helpers.ThrowIfNull<ILLabel>(label, "label");
			label.InteropSetTarget(Current);
			return this;
		}

		public ILWeaver DefineAndMarkLabelToCurrent(out ILLabel markedLabel)
		{
			markedLabel = Context.DefineLabel(Current);
			return this;
		}

		public ILLabel DefineAndMarkLabelToCurrent()
		{
			DefineAndMarkLabelToCurrent(out ILLabel markedLabel);
			return markedLabel;
		}

		public ILWeaver MarkLabelToCurrentPrevious(ILLabel label)
		{
			Helpers.ThrowIfNull<ILLabel>(label, "label");
			label.InteropSetTarget(Current.Previous);
			return this;
		}

		public ILWeaver DefineAndMarkLabelToCurrentPrevious(out ILLabel markedLabel)
		{
			markedLabel = Context.DefineLabel(Current.Previous);
			return this;
		}

		public ILLabel DefineAndMarkLabelToCurrentPrevious()
		{
			DefineAndMarkLabelToCurrentPrevious(out ILLabel markedLabel);
			return markedLabel;
		}

		public ILWeaver MarkLabelToCurrentNext(ILLabel label)
		{
			Helpers.ThrowIfNull<ILLabel>(label, "label");
			label.InteropSetTarget(Current.Next);
			return this;
		}

		public ILWeaver DefineAndMarkLabelToCurrentNext(out ILLabel markedLabel)
		{
			markedLabel = Context.DefineLabel(Current.Next);
			return this;
		}

		public ILLabel DefineAndMarkLabelToCurrentNext()
		{
			DefineAndMarkLabelToCurrentNext(out ILLabel markedLabel);
			return markedLabel;
		}

		public VariableDefinition DeclareVariable(Type type)
		{
			DeclareVariable(type, out VariableDefinition variableDefinition);
			return variableDefinition;
		}

		public ILWeaver DeclareVariable(Type type, out VariableDefinition variableDefinition)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			variableDefinition = new VariableDefinition(Context.Import(type));
			Body.Variables.Add(variableDefinition);
			return this;
		}

		public ILWeaver Replace(Instruction target, Instruction replacement)
		{
			InsertAfter(target, new <>z__ReadOnlySingleElementList<Instruction>(replacement));
			Remove(target, out ILLabel orphanedLabel);
			RetargetLabels(orphanedLabel, replacement);
			return this;
		}

		public ILWeaver ReplaceCurrent(Instruction replacement)
		{
			Replace(Current, replacement);
			return this;
		}

		[Obsolete("Removing a range by count is prone to causing invalid IL if the target method's instructions have changed. Use ILWeaver.InsertBranchOver instead as it doesn't have this design flaw. Note that these two methods behave slightly differently; please read the method's remarks in detail.")]
		public ILWeaver RemoveAt(int index, int instructions, out IEnumerable<ILLabel> orphanedLabels)
		{
			int num = index + instructions - 1;
			int index2 = Index;
			if (instructions < 0)
			{
				throw new IndexOutOfRangeException("Can not remove a negative amount of instructions.");
			}
			if (num > Instructions.Count)
			{
				throw new 

core/com.github.MonoDetour.Reflection.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Utils;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("Hamunii")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.7.7.0")]
[assembly: AssemblyInformationalVersion("0.7.7+d7c5fcdc39fb24ad6b0d68e7f1ff487bf6cbc1e7")]
[assembly: AssemblyProduct("MonoDetour.Reflection")]
[assembly: AssemblyTitle("MonoDetour.Reflection")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/MonoDetour/MonoDetour")]
[assembly: AssemblyVersion("0.7.7.0")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 MonoDetour.Reflection.Unspeakable
{
	public delegate ref T EnumeratorFieldReferenceGetter<T>(IEnumerator instance);
	internal static class <EnumeratorReflection>F195F66C6DA9E115B6F6704672598F4179F4F7206901F87F23A1D221B9EE964B6__EnumeratorExtensionsCache<T>
	{
		internal static readonly ConcurrentDictionary<(Type, int), EnumeratorFieldReferenceGetter<T>> s_FieldToRef = new ConcurrentDictionary<(Type, int), EnumeratorFieldReferenceGetter<T>>();

		internal static readonly ConcurrentDictionary<(Type, string), EnumeratorFieldReferenceGetter<T>> s_3ToRef = new ConcurrentDictionary<(Type, string), EnumeratorFieldReferenceGetter<T>>();
	}
	public static class EnumeratorReflection
	{
		private const string DeclaringTypeNull = "Declaring type of method is null!";

		public static void EnumeratorFastFieldReferenceThis<T>(this MethodInfo methodInfo, ref EnumeratorFieldReferenceGetter<T> enumeratorFieldReference)
		{
			enumeratorFieldReference = methodInfo.EnumeratorFastFieldReferenceThis<T>();
		}

		public static EnumeratorFieldReferenceGetter<T> EnumeratorFastFieldReferenceThis<T>(this MethodInfo methodInfo)
		{
			return methodInfo.DeclaringType?.EnumeratorFastFieldReferenceThis<T>() ?? throw new NullReferenceException("Declaring type of method is null!");
		}

		public static void EnumeratorFastFieldReferenceThis<T>(this Type enumeratorType, ref EnumeratorFieldReferenceGetter<T> enumeratorFieldReference)
		{
			enumeratorFieldReference = enumeratorType.EnumeratorFastFieldReferenceThis<T>();
		}

		public static EnumeratorFieldReferenceGetter<T> EnumeratorFastFieldReferenceThis<T>(this Type enumeratorType)
		{
			return enumeratorType.EnumeratorFastFieldReference<T>(4);
		}

		public static void EnumeratorFastFieldReferenceCurrent<T>(this MethodInfo methodInfo, ref EnumeratorFieldReferenceGetter<T> enumeratorFieldReference)
		{
			enumeratorFieldReference = methodInfo.EnumeratorFastFieldReferenceCurrent<T>();
		}

		public static EnumeratorFieldReferenceGetter<T> EnumeratorFastFieldReferenceCurrent<T>(this MethodInfo methodInfo)
		{
			return methodInfo.DeclaringType?.EnumeratorFastFieldReferenceCurrent<T>() ?? throw new NullReferenceException("Declaring type of method is null!");
		}

		public static void EnumeratorFastFieldReferenceCurrent<T>(this Type enumeratorType, ref EnumeratorFieldReferenceGetter<T> enumeratorFieldReference)
		{
			enumeratorFieldReference = enumeratorType.EnumeratorFastFieldReferenceCurrent<T>();
		}

		public static EnumeratorFieldReferenceGetter<T> EnumeratorFastFieldReferenceCurrent<T>(this Type enumeratorType)
		{
			return enumeratorType.EnumeratorFastFieldReference<T>(2);
		}

		public static void EnumeratorFastFieldReferenceState(this MethodInfo methodInfo, ref EnumeratorFieldReferenceGetter<int> enumeratorFieldReference)
		{
			enumeratorFieldReference = methodInfo.EnumeratorFastFieldReferenceState();
		}

		public static EnumeratorFieldReferenceGetter<int> EnumeratorFastFieldReferenceState(this MethodInfo methodInfo)
		{
			return methodInfo.DeclaringType?.EnumeratorFastFieldReferenceState() ?? throw new NullReferenceException("Declaring type of method is null!");
		}

		public static void EnumeratorFastFieldReferenceState(this Type enumeratorType, ref EnumeratorFieldReferenceGetter<int> enumeratorFieldReference)
		{
			enumeratorFieldReference = enumeratorType.EnumeratorFastFieldReferenceState();
		}

		public static EnumeratorFieldReferenceGetter<int> EnumeratorFastFieldReferenceState(this Type enumeratorType)
		{
			return enumeratorType.EnumeratorFastFieldReference<int>(1);
		}

		public static void EnumeratorFastFieldReference<T>(this MethodInfo methodInfo, string fieldName, ref EnumeratorFieldReferenceGetter<T> enumeratorFieldReference)
		{
			enumeratorFieldReference = methodInfo.EnumeratorFastFieldReference<T>(fieldName);
		}

		public static EnumeratorFieldReferenceGetter<T> EnumeratorFastFieldReference<T>(this MethodInfo methodInfo, string fieldName)
		{
			return methodInfo.DeclaringType?.EnumeratorFastFieldReference<T>(fieldName) ?? throw new NullReferenceException("Declaring type of method is null!");
		}

		public static void EnumeratorFastFieldReference<T>(this Type enumeratorType, string fieldName, ref EnumeratorFieldReferenceGetter<T> enumeratorFieldReference)
		{
			enumeratorFieldReference = enumeratorType.EnumeratorFastFieldReference<T>(fieldName);
		}

		private static EnumeratorFieldReferenceGetter<T> EnumeratorFastFieldReference<T>(this Type enumeratorType, int fieldId)
		{
			if (<EnumeratorReflection>F195F66C6DA9E115B6F6704672598F4179F4F7206901F87F23A1D221B9EE964B6__EnumeratorExtensionsCache<T>.s_FieldToRef.TryGetValue((enumeratorType, fieldId), out EnumeratorFieldReferenceGetter<T> value))
			{
				return value;
			}
			string text = fieldId switch
			{
				1 => "<>1__state", 
				2 => "<>2__current", 
				3 => throw new ArgumentException("field id 3 is not constant."), 
				4 => "<>4__this", 
				_ => throw new ArgumentOutOfRangeException("fieldId", $"Valid values are 1, 2, and 4. The value provided was: {fieldId}"), 
			};
			FieldInfo fieldInfo = enumeratorType.GetField(text, (BindingFlags)(-1)) ?? throw new NullReferenceException($"'{text}' field not found on type {enumeratorType}.");
			if (!typeof(T).IsAssignableFrom(fieldInfo.FieldType))
			{
				throw new InvalidCastException($"{typeof(T)} is not assignable from '{text}' field type {fieldInfo.FieldType}");
			}
			value = CreateFastFieldReference<T>(fieldInfo);
			<EnumeratorReflection>F195F66C6DA9E115B6F6704672598F4179F4F7206901F87F23A1D221B9EE964B6__EnumeratorExtensionsCache<T>.s_FieldToRef.TryAdd((enumeratorType, fieldId), value);
			return value;
		}

		public static EnumeratorFieldReferenceGetter<T> EnumeratorFastFieldReference<T>(this Type enumeratorType, string fieldName)
		{
			if (<EnumeratorReflection>F195F66C6DA9E115B6F6704672598F4179F4F7206901F87F23A1D221B9EE964B6__EnumeratorExtensionsCache<T>.s_3ToRef.TryGetValue((enumeratorType, fieldName), out EnumeratorFieldReferenceGetter<T> value))
			{
				return value;
			}
			FieldInfo fieldInfo = enumeratorType.GetField(fieldName, (BindingFlags)(-1)) ?? throw new NullReferenceException($"'{fieldName}' field not found on type {enumeratorType}.");
			if (!typeof(T).IsAssignableFrom(fieldInfo.FieldType))
			{
				throw new InvalidCastException($"{typeof(T)} is not assignable from '{fieldName}' field type {fieldInfo.FieldType}");
			}
			value = CreateFastFieldReference<T>(fieldInfo);
			<EnumeratorReflection>F195F66C6DA9E115B6F6704672598F4179F4F7206901F87F23A1D221B9EE964B6__EnumeratorExtensionsCache<T>.s_3ToRef.TryAdd((enumeratorType, fieldName), value);
			return value;
		}

		private static EnumeratorFieldReferenceGetter<T> CreateFastFieldReference<T>(FieldInfo fieldInfo)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			DynamicMethodDefinition val = new DynamicMethodDefinition("FastFieldReference", typeof(T).MakeByRefType(), new Type[1] { typeof(object) });
			ILProcessor iLProcessor = val.GetILProcessor();
			iLProcessor.Emit(OpCodes.Ldarg_0);
			Extensions.Emit(iLProcessor, OpCodes.Ldflda, fieldInfo);
			iLProcessor.Emit(OpCodes.Ret);
			return Extensions.CreateDelegate<EnumeratorFieldReferenceGetter<T>>((MethodBase)val.Generate());
		}
	}
	public interface ISpeakableEnumerator
	{
	}
	public sealed class SpeakableEnumerator<TCurrent, TThis> : ISpeakableEnumerator
	{
		private readonly EnumeratorFieldReferenceGetter<TThis> getThisRef;

		private readonly EnumeratorFieldReferenceGetter<TCurrent> getCurrentRef;

		private readonly EnumeratorFieldReferenceGetter<int> getStateRef;

		private readonly IEnumerator<TCurrent> instance;

		private static readonly ConditionalWeakTable<IEnumerator<TCurrent>, SpeakableEnumerator<TCurrent, TThis>> s_EnumeratorToSpeakable = new ConditionalWeakTable<IEnumerator<TCurrent>, SpeakableEnumerator<TCurrent, TThis>>();

		public TThis This => getThisRef(instance);

		public IEnumerator<TCurrent> Enumerator => instance;

		public TCurrent Current
		{
			get
			{
				return getCurrentRef(instance);
			}
			set
			{
				getCurrentRef(instance) = value;
			}
		}

		public int State
		{
			get
			{
				return getStateRef(instance);
			}
			set
			{
				getStateRef(instance) = value;
			}
		}

		public SpeakableEnumerator(IEnumerator<TCurrent> instance)
		{
			Type type = instance.GetType();
			this.instance = instance;
			getCurrentRef = type.EnumeratorFastFieldReferenceCurrent<TCurrent>();
			getStateRef = type.EnumeratorFastFieldReferenceState();
			getThisRef = type.EnumeratorFastFieldReferenceThis<TThis>();
		}

		public static void PreBuildFieldReferenceGetters(Type type)
		{
			SpeakableEnumerator<TCurrent>.PreBuildFieldReferenceGetters(type);
			type.EnumeratorFastFieldReferenceThis<TThis>();
		}

		public static SpeakableEnumerator<TCurrent, TThis> GetOrCreate(IEnumerator<TCurrent> instance)
		{
			if (s_EnumeratorToSpeakable.TryGetValue(instance, out SpeakableEnumerator<TCurrent, TThis> value))
			{
				return value;
			}
			value = new SpeakableEnumerator<TCurrent, TThis>(instance);
			s_EnumeratorToSpeakable.Add(instance, value);
			return value;
		}
	}
	public sealed class SpeakableEnumerator<TCurrent> : ISpeakableEnumerator
	{
		private readonly EnumeratorFieldReferenceGetter<TCurrent> getCurrentRef;

		private readonly EnumeratorFieldReferenceGetter<int> getStateRef;

		private readonly IEnumerator<TCurrent> instance;

		private static readonly ConditionalWeakTable<IEnumerator<TCurrent>, SpeakableEnumerator<TCurrent>> s_EnumeratorToSpeakable = new ConditionalWeakTable<IEnumerator<TCurrent>, SpeakableEnumerator<TCurrent>>();

		public IEnumerator<TCurrent> Enumerator => instance;

		public TCurrent Current
		{
			get
			{
				return getCurrentRef(instance);
			}
			set
			{
				getCurrentRef(instance) = value;
			}
		}

		public int State
		{
			get
			{
				return getStateRef(instance);
			}
			set
			{
				getStateRef(instance) = value;
			}
		}

		public SpeakableEnumerator(IEnumerator<TCurrent> instance)
		{
			Type type = instance.GetType();
			this.instance = instance;
			getCurrentRef = type.EnumeratorFastFieldReferenceCurrent<TCurrent>();
			getStateRef = type.EnumeratorFastFieldReferenceState();
		}

		public static void PreBuildFieldReferenceGetters(Type type)
		{
			type.EnumeratorFastFieldReferenceCurrent<TCurrent>();
			type.EnumeratorFastFieldReferenceState();
		}

		public static SpeakableEnumerator<TCurrent> GetOrCreate(IEnumerator<TCurrent> instance)
		{
			if (s_EnumeratorToSpeakable.TryGetValue(instance, out SpeakableEnumerator<TCurrent> value))
			{
				return value;
			}
			value = new SpeakableEnumerator<TCurrent>(instance);
			s_EnumeratorToSpeakable.Add(instance, value);
			return value;
		}
	}
}

core/com.github.MonoDetour.Bindings.Reorg.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using MonoDetour.Bindings.Reorg.MonoModUtils;
using MonoDetour.Bindings.Reorg.RuntimeDetour;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using MonoMod.Utils;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("com.github.MonoDetour")]
[assembly: InternalsVisibleTo("com.github.MonoDetour.ILWeaver")]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("Hamunii")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.7.7.0")]
[assembly: AssemblyInformationalVersion("0.7.7+d7c5fcdc39fb24ad6b0d68e7f1ff487bf6cbc1e7")]
[assembly: AssemblyProduct("MonoDetour.Bindings.Reorg")]
[assembly: AssemblyTitle("MonoDetour.Bindings.Reorg")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/MonoDetour/MonoDetour")]
[assembly: AssemblyVersion("0.7.7.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 MonoDetour.Bindings.Reorg
{
	internal static class MonoModVersion
	{
		internal static bool IsReorg { get; }

		static MonoModVersion()
		{
			Type type = Type.GetType("MonoMod.Utils.ArchitectureKind, MonoMod.Utils");
			if ((object)type != null)
			{
				IsReorg = true;
				InitAll();
			}
			else
			{
				IsReorg = false;
			}
		}

		private static void InitAll()
		{
			ReorgILHook.Init();
			ReorgILLabel.Init();
			ReorgILCursor.Init();
			ReorgILContext.Init();
			ReorgFastDelegateInvokers.Init();
		}
	}
}
namespace MonoDetour.Bindings.Reorg.RuntimeDetour
{
	internal interface IMonoDetourConfig
	{
		string? OverrideId { get; }

		int Priority { get; }

		IEnumerable<string> Before { get; }

		IEnumerable<string> After { get; }
	}
	internal static class ReorgILHook
	{
		private delegate ILHook ILHookConstructor(MethodBase source, Manipulator manip, object? config, bool applyByDefault);

		private delegate object DetourConfigConstructor(string id, int? priority = null, IEnumerable<string>? before = null, IEnumerable<string>? after = null);

		private static Func<object> detourContext_GetDefaultConfig = null;

		private static ILHookConstructor newILHook = null;

		private static DetourConfigConstructor newDetourConfig = null;

		private static Func<object, int?> detourConfigPriority = null;

		private static MethodInfo detourConfig_WithPriority = null;

		private static readonly ConcurrentDictionary<IMonoDetourConfig, object> interfaceToConfig = new ConcurrentDictionary<IMonoDetourConfig, object>();

		private static readonly ConcurrentDictionary<object, object> configToConfig = new ConcurrentDictionary<object, object>();

		private static readonly ConcurrentDictionary<string, object> idToConfig = new ConcurrentDictionary<string, object>();

		internal static void Init()
		{
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Expected O, but got Unknown
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Expected O, but got Unknown
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			detourContext_GetDefaultConfig = Extensions.CreateDelegate<Func<object>>((MethodBase)typeof(DetourContext).GetMethod("GetDefaultConfig", BindingFlags.Static | BindingFlags.Public));
			Type type = Type.GetType("MonoMod.RuntimeDetour.DetourConfig, MonoMod.RuntimeDetour");
			detourConfig_WithPriority = type.GetMethod("WithPriority", new Type[1] { typeof(int?) });
			ConstructorInfo constructor = typeof(ILHook).GetConstructor(new Type[4]
			{
				typeof(MethodBase),
				typeof(Manipulator),
				type,
				typeof(bool)
			});
			DynamicMethodDefinition val = new DynamicMethodDefinition("newILHook", typeof(ILHook), new Type[4]
			{
				typeof(MethodBase),
				typeof(Manipulator),
				typeof(object),
				typeof(bool)
			});
			try
			{
				ILProcessor iLProcessor = val.GetILProcessor();
				iLProcessor.Emit(OpCodes.Ldarg_0);
				iLProcessor.Emit(OpCodes.Ldarg_1);
				iLProcessor.Emit(OpCodes.Ldarg_2);
				iLProcessor.Emit(OpCodes.Ldarg_3);
				Extensions.Emit(iLProcessor, OpCodes.Newobj, (MethodBase)constructor);
				iLProcessor.Emit(OpCodes.Ret);
				newILHook = Extensions.CreateDelegate<ILHookConstructor>((MethodBase)val.Generate());
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
			ConstructorInfo constructor2 = type.GetConstructor(new Type[4]
			{
				typeof(string),
				typeof(int?),
				typeof(IEnumerable<string>),
				typeof(IEnumerable<string>)
			});
			DynamicMethodDefinition val2 = new DynamicMethodDefinition("iLHookConstructor", typeof(object), new Type[4]
			{
				typeof(string),
				typeof(int?),
				typeof(IEnumerable<string>),
				typeof(IEnumerable<string>)
			});
			try
			{
				ILProcessor iLProcessor2 = val2.GetILProcessor();
				iLProcessor2.Emit(OpCodes.Ldarg_0);
				iLProcessor2.Emit(OpCodes.Ldarg_1);
				iLProcessor2.Emit(OpCodes.Ldarg_2);
				iLProcessor2.Emit(OpCodes.Ldarg_3);
				Extensions.Emit(iLProcessor2, OpCodes.Newobj, (MethodBase)constructor2);
				iLProcessor2.Emit(OpCodes.Ret);
				newDetourConfig = Extensions.CreateDelegate<DetourConfigConstructor>((MethodBase)val2.Generate());
			}
			finally
			{
				((IDisposable)val2)?.Dispose();
			}
			MethodInfo getMethod = type.GetProperty("Priority").GetGetMethod();
			DynamicMethodDefinition val3 = new DynamicMethodDefinition("get_Priority", typeof(int?), new Type[1] { typeof(object) });
			try
			{
				ILProcessor iLProcessor3 = val3.GetILProcessor();
				iLProcessor3.Emit(OpCodes.Ldarg_0);
				Extensions.Emit(iLProcessor3, OpCodes.Callvirt, (MethodBase)getMethod);
				iLProcessor3.Emit(OpCodes.Ret);
				detourConfigPriority = Extensions.CreateDelegate<Func<object, int?>>((MethodBase)val3.Generate());
			}
			finally
			{
				((IDisposable)val3)?.Dispose();
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static ILHook ConstructILHook(MethodBase target, Manipulator manipulator, IMonoDetourConfig? config, string id)
		{
			if (config == null)
			{
				object obj = detourContext_GetDefaultConfig();
				if (obj == null)
				{
					if (!idToConfig.TryGetValue(id, out object value))
					{
						value = newDetourConfig(id, 0);
						idToConfig.TryAdd(id, value);
					}
					return newILHook(target, manipulator, value, applyByDefault: false);
				}
				if (detourConfigPriority(obj).HasValue)
				{
					return newILHook(target, manipulator, obj, applyByDefault: false);
				}
				if (!configToConfig.TryGetValue(obj, out object value2))
				{
					value2 = detourConfig_WithPriority.Invoke(obj, new object[1] { 0 });
					configToConfig.TryAdd(obj, value2);
				}
				return newILHook(target, manipulator, value2, applyByDefault: false);
			}
			if (!interfaceToConfig.TryGetValue(config, out object value3))
			{
				value3 = newDetourConfig(config.OverrideId ?? id, config.Priority, config.Before, config.After);
				interfaceToConfig.TryAdd(config, value3);
			}
			return newILHook(target, manipulator, value3, applyByDefault: false);
		}
	}
}
namespace MonoDetour.Bindings.Reorg.MonoModUtils
{
	internal static class ReorgFastDelegateInvokers
	{
		private static Func<Type, (MethodInfo Invoker, Type Delegate)?> getDelegateInvoker;

		internal static void Init()
		{
			Type type = Type.GetType("MonoMod.Cil.FastDelegateInvokers, MonoMod.Utils");
			getDelegateInvoker = Extensions.CreateDelegate<Func<Type, (MethodInfo, Type)?>>((MethodBase)type.GetMethod("GetDelegateInvoker", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(Type) }, null));
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static (MethodInfo Invoker, Type Delegate)? GetDelegateInvoker(Type delegateType)
		{
			return getDelegateInvoker(delegateType);
		}
	}
	internal static class ReorgILContext
	{
		private delegate int Signature<T>(ILContext context, in T? value);

		private static class Container<T>
		{
			internal static Signature<T> AddReference => <AddReference>k__BackingField ?? (<AddReference>k__BackingField = Extensions.CreateDelegate<Signature<T>>((MethodBase)addReferenceMethod.MakeGenericMethod(typeof(T))));
		}

		[CompilerGenerated]
		private sealed class <GetReference>d__9 : IEnumerable<Instruction>, IEnumerable, IEnumerator<Instruction>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private Instruction <>2__current;

			private int <>l__initialThreadId;

			private ILContext context;

			public ILContext <>3__context;

			private int id;

			public int <>3__id;

			private Type type;

			public Type <>3__type;

			private object <cellRef>5__2;

			private ILProcessor <il>5__3;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<cellRef>5__2 = null;
				<il>5__3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00de: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<cellRef>5__2 = getReferenceCell.Invoke(context, new object[1] { id });
					<il>5__3 = context.IL;
					<>2__current = Extensions.Create(<il>5__3, OpCodes.Ldc_I4, cellRef_get_Index.Invoke(<cellRef>5__2, Array.Empty<object>()));
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = Extensions.Create(<il>5__3, OpCodes.Ldc_I4, cellRef_get_Hash.Invoke(<cellRef>5__2, Array.Empty<object>()));
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					<>2__current = <il>5__3.Create(OpCodes.Call, ((MemberReference)<il>5__3.Body.Method).Module.ImportReference((MethodBase)Self_GetValueT_ii.MakeGenericMethod(type)));
					<>1__state = 3;
					return true;
				case 3:
					<>1__state = -1;
					return false;
				}
			}

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

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

			[DebuggerHidden]
			IEnumerator<Instruction> IEnumerable<Instruction>.GetEnumerator()
			{
				<GetReference>d__9 <GetReference>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<GetReference>d__ = this;
				}
				else
				{
					<GetReference>d__ = new <GetReference>d__9(0);
				}
				<GetReference>d__.type = <>3__type;
				<GetReference>d__.context = <>3__context;
				<GetReference>d__.id = <>3__id;
				return <GetReference>d__;
			}

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

		private static MethodInfo Self_GetValueT_ii;

		private static MethodInfo addReferenceMethod;

		private static MethodInfo cellRef_get_Index;

		private static MethodInfo cellRef_get_Hash;

		private static MethodInfo getReferenceCell;

		internal static void Init()
		{
			addReferenceMethod = typeof(ILContext).GetMethod("AddReference") ?? throw new NullReferenceException();
			Type type = Type.GetType("MonoMod.Utils.DynamicReferenceManager, MonoMod.Utils");
			Self_GetValueT_ii = type.GetMethod("GetValueT", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[2]
			{
				typeof(int),
				typeof(int)
			}, null) ?? throw new InvalidOperationException("GetValueT doesn't exist?!?!?!?");
			Type type2 = Type.GetType("MonoMod.Utils.DynamicReferenceCell, MonoMod.Utils");
			getReferenceCell = typeof(ILContext).GetMethod("GetReferenceCell");
			cellRef_get_Index = type2.GetProperty("Index").GetGetMethod();
			cellRef_get_Hash = type2.GetProperty("Hash").GetGetMethod();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static int AddReference<T>(ILContext context, in T value)
		{
			return Container<T>.AddReference(context, in value);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		[IteratorStateMachine(typeof(<GetReference>d__9))]
		internal static IEnumerable<Instruction> GetReference(Type type, ILContext context, int id)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetReference>d__9(-2)
			{
				<>3__type = type,
				<>3__context = context,
				<>3__id = id
			};
		}
	}
	internal static class ReorgILCursor
	{
		private delegate int Signature<T>(ILCursor cursor, in T? t);

		private static class Container<T>
		{
			internal static Signature<T> EmitReference => <EmitReference>k__BackingField ?? (<EmitReference>k__BackingField = Extensions.CreateDelegate<Signature<T>>((MethodBase)emitReferenceMethod.MakeGenericMethod(typeof(T))));
		}

		private static MethodInfo emitReferenceMethod;

		internal static void Init()
		{
			emitReferenceMethod = typeof(ILCursor).GetMethod("EmitReference") ?? throw new NullReferenceException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static int EmitReference<T>(ILCursor cursor, in T? t)
		{
			return Container<T>.EmitReference(cursor, in t);
		}
	}
	internal static class ReorgILLabel
	{
		private static Func<ILLabel, Instruction> get_Target;

		private static Action<ILLabel, Instruction> set_Target;

		internal static void Init()
		{
			PropertyInfo property = typeof(ILLabel).GetProperty("Target");
			set_Target = Extensions.CreateDelegate<Action<ILLabel, Instruction>>((MethodBase)property.GetSetMethod());
			get_Target = Extensions.CreateDelegate<Func<ILLabel, Instruction>>((MethodBase)property.GetGetMethod());
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static Instruction? GetTarget(ILLabel label)
		{
			return get_Target(label);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static void SetTarget(ILLabel label, Instruction value)
		{
			set_Target(label, value);
		}
	}
}