Decompiled source of SilksongPrepatcher v1.0.2

patchers/SilksongPrepatcher.dll

Decompiled 6 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Rocks;
using Mono.Collections.Generic;
using MonoMod.Cil;
using MonoMod.Utils;
using SilksongPrepatcher.Patchers;
using SilksongPrepatcher.Patchers.PlayerDataPatcher;
using SilksongPrepatcher.Utils;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("SilksongPrepatcher")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2+a22d0b9cfde457406fae294d2fcf0c7a234d839d")]
[assembly: AssemblyProduct("SilksongPrepatcher")]
[assembly: AssemblyTitle("SilksongPrepatcher")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.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 SilksongPrepatcher
{
	public static class AssemblyNames
	{
		public const string Assembly_CSharp = "Assembly-CSharp.dll";

		public const string PlayMaker = "PlayMaker.dll";

		public const string TeamCherry_NestedFadeGroup = "TeamCherry.NestedFadeGroup.dll";

		public const string TeamCherry_SharedUtils = "TeamCherry.SharedUtils.dll";

		public const string Newtonsoft_Json_UnityConverters = "Newtonsoft.Json.UnityConverters.dll";
	}
	public abstract class BasePrepatcher
	{
		protected ManualLogSource Log { get; private set; }

		public string Name { get; private set; }

		public BasePrepatcher()
			: this(null)
		{
		}

		public BasePrepatcher(string? name)
		{
			if (name == null)
			{
				name = GetType().Name;
			}
			Name = name;
			Log = Logger.CreateLogSource(name);
		}

		public abstract void PatchAssembly(AssemblyDefinition asm);
	}
	public static class SilksongPrepatcher
	{
		private static readonly List<(string assemblyName, BasePrepatcher patcher)> patcherData = GetPatcherData();

		private static ManualLogSource Log { get; } = Logger.CreateLogSource("SilksongPrepatcher");


		internal static string PatchCacheDir
		{
			get
			{
				string text = Path.Combine(Paths.CachePath, "SilksongPrepatcher");
				Directory.CreateDirectory(text);
				return text;
			}
		}

		public static IEnumerable<string> TargetDLLs => patcherData.Select<(string, BasePrepatcher), string>(((string assemblyName, BasePrepatcher patcher) pair) => pair.assemblyName).Distinct();

		private static List<(string assemblyName, BasePrepatcher patcher)> GetPatcherData()
		{
			BasePrepatcher item = new MethodReplacer((MethodReference mr) => ((MemberReference)((MemberReference)mr).DeclaringType).Name == "Assembly" && ((MemberReference)mr).Name == "GetTypes", typeof(AssemblyExtensions).GetMethod("GetTypesSafelyIgnoreMMHook", new Type[1] { typeof(Assembly) }));
			BasePrepatcher item2 = new MethodReplacer((MethodReference mr) => ((MemberReference)((MemberReference)mr).DeclaringType).Name == "Type" && ((MemberReference)mr).Name == "IsAssignableFrom", typeof(AssemblyExtensions).GetMethod("TypeAssignableFromSafe", new Type[2]
			{
				typeof(Type),
				typeof(Type)
			}));
			return new List<(string, BasePrepatcher)>
			{
				("TeamCherry.NestedFadeGroup.dll", item),
				("PlayMaker.dll", item),
				("PlayMaker.dll", new ReflectionUtilsPatcher()),
				("Assembly-CSharp.dll", new PlayerDataPatcher()),
				("TeamCherry.SharedUtils.dll", new VariableExtensionsPatcher()),
				("Newtonsoft.Json.UnityConverters.dll", item2)
			};
		}

		public static void Patch(AssemblyDefinition assembly)
		{
			string assemblyName = ((AssemblyNameReference)assembly.Name).Name + ".dll";
			List<BasePrepatcher> list = (from pair in patcherData
				where pair.assemblyName == assemblyName
				select pair.patcher).ToList();
			Log.LogInfo((object)("Patching " + assemblyName + ": " + string.Join(", ", list.Select((BasePrepatcher x) => x.Name))));
			foreach (BasePrepatcher item in list)
			{
				item.PatchAssembly(assembly);
			}
		}
	}
}
namespace SilksongPrepatcher.Utils
{
	public static class AssemblyExtensions
	{
		public static Type[] GetTypesSafely(this Assembly asm)
		{
			try
			{
				return asm.GetTypes();
			}
			catch (ReflectionTypeLoadException ex)
			{
				return ex.Types.Where((Type x) => (object)x != null).ToArray();
			}
		}

		public static Type[] GetTypesSafelyIgnoreMMHook(Assembly asm)
		{
			if (asm.GetName().Name.StartsWith("MMHOOK"))
			{
				return Array.Empty<Type>();
			}
			return asm.GetTypesSafely();
		}

		public static bool TypeAssignableFromSafe(Type self, Type other)
		{
			try
			{
				return self.IsAssignableFrom(other);
			}
			catch
			{
				return false;
			}
		}
	}
	public static class CecilUtils
	{
		[CompilerGenerated]
		private sealed class <GetMethodDefinitions>d__2 : IEnumerable<MethodDefinition>, IEnumerable, IEnumerator<MethodDefinition>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private MethodDefinition <>2__current;

			private int <>l__initialThreadId;

			private ModuleDefinition mod;

			public ModuleDefinition <>3__mod;

			private IEnumerator<TypeDefinition> <>7__wrap1;

			private Enumerator<MethodDefinition> <>7__wrap2;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				if ((uint)(num - -4) <= 1u || num == 1)
				{
					try
					{
						if (num == -4 || num == 1)
						{
							try
							{
							}
							finally
							{
								<>m__Finally2();
							}
						}
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>7__wrap1 = null;
				<>7__wrap2 = default(Enumerator<MethodDefinition>);
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_004f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0054: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					int num = <>1__state;
					if (num != 0)
					{
						if (num != 1)
						{
							return false;
						}
						<>1__state = -4;
						goto IL_0089;
					}
					<>1__state = -1;
					<>7__wrap1 = GetTypeDefinitions(mod).GetEnumerator();
					<>1__state = -3;
					goto IL_00a8;
					IL_0089:
					if (<>7__wrap2.MoveNext())
					{
						MethodDefinition current = <>7__wrap2.Current;
						<>2__current = current;
						<>1__state = 1;
						return true;
					}
					<>m__Finally2();
					<>7__wrap2 = default(Enumerator<MethodDefinition>);
					goto IL_00a8;
					IL_00a8:
					if (<>7__wrap1.MoveNext())
					{
						TypeDefinition current2 = <>7__wrap1.Current;
						<>7__wrap2 = current2.Methods.GetEnumerator();
						<>1__state = -4;
						goto IL_0089;
					}
					<>m__Finally1();
					<>7__wrap1 = null;
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

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

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

			private void <>m__Finally2()
			{
				<>1__state = -3;
				((IDisposable)<>7__wrap2).Dispose();
			}

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

			[DebuggerHidden]
			IEnumerator<MethodDefinition> IEnumerable<MethodDefinition>.GetEnumerator()
			{
				<GetMethodDefinitions>d__2 <GetMethodDefinitions>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<GetMethodDefinitions>d__ = this;
				}
				else
				{
					<GetMethodDefinitions>d__ = new <GetMethodDefinitions>d__2(0);
				}
				<GetMethodDefinitions>d__.mod = <>3__mod;
				return <GetMethodDefinitions>d__;
			}

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

		[CompilerGenerated]
		private sealed class <GetTypeDefinitions>d__1 : IEnumerable<TypeDefinition>, IEnumerable, IEnumerator<TypeDefinition>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private TypeDefinition <>2__current;

			private int <>l__initialThreadId;

			private ModuleDefinition mod;

			public ModuleDefinition <>3__mod;

			private Enumerator<TypeDefinition> <>7__wrap1;

			private IEnumerator<TypeDefinition> <>7__wrap2;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				if ((uint)(num - -4) <= 1u || num == 1)
				{
					try
					{
						if (num == -4 || num == 1)
						{
							try
							{
							}
							finally
							{
								<>m__Finally2();
							}
						}
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>7__wrap1 = default(Enumerator<TypeDefinition>);
				<>7__wrap2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					int num = <>1__state;
					if (num != 0)
					{
						if (num != 1)
						{
							return false;
						}
						<>1__state = -4;
						goto IL_008a;
					}
					<>1__state = -1;
					<>7__wrap1 = mod.Types.GetEnumerator();
					<>1__state = -3;
					goto IL_00a4;
					IL_008a:
					if (<>7__wrap2.MoveNext())
					{
						TypeDefinition current = <>7__wrap2.Current;
						<>2__current = current;
						<>1__state = 1;
						return true;
					}
					<>m__Finally2();
					<>7__wrap2 = null;
					goto IL_00a4;
					IL_00a4:
					if (<>7__wrap1.MoveNext())
					{
						TypeDefinition current2 = <>7__wrap1.Current;
						<>7__wrap2 = GetTypesRecursive(current2).GetEnumerator();
						<>1__state = -4;
						goto IL_008a;
					}
					<>m__Finally1();
					<>7__wrap1 = default(Enumerator<TypeDefinition>);
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

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

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

			private void <>m__Finally2()
			{
				<>1__state = -3;
				if (<>7__wrap2 != null)
				{
					<>7__wrap2.Dispose();
				}
			}

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

			[DebuggerHidden]
			IEnumerator<TypeDefinition> IEnumerable<TypeDefinition>.GetEnumerator()
			{
				<GetTypeDefinitions>d__1 <GetTypeDefinitions>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<GetTypeDefinitions>d__ = this;
				}
				else
				{
					<GetTypeDefinitions>d__ = new <GetTypeDefinitions>d__1(0);
				}
				<GetTypeDefinitions>d__.mod = <>3__mod;
				return <GetTypeDefinitions>d__;
			}

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

		[CompilerGenerated]
		private sealed class <GetTypesRecursive>d__0 : IEnumerable<TypeDefinition>, IEnumerable, IEnumerator<TypeDefinition>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private TypeDefinition <>2__current;

			private int <>l__initialThreadId;

			private bool includeSelf;

			public bool <>3__includeSelf;

			private TypeDefinition type;

			public TypeDefinition <>3__type;

			private Enumerator<TypeDefinition> <>7__wrap1;

			private IEnumerator<TypeDefinition> <>7__wrap2;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				if ((uint)(num - -4) <= 1u || num == 2)
				{
					try
					{
						if (num == -4 || num == 2)
						{
							try
							{
							}
							finally
							{
								<>m__Finally2();
							}
						}
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>7__wrap1 = default(Enumerator<TypeDefinition>);
				<>7__wrap2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: 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)
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						if (includeSelf)
						{
							<>2__current = type;
							<>1__state = 1;
							return true;
						}
						goto IL_0050;
					case 1:
						<>1__state = -1;
						goto IL_0050;
					case 2:
						{
							<>1__state = -4;
							goto IL_00be;
						}
						IL_0050:
						<>7__wrap1 = type.NestedTypes.GetEnumerator();
						<>1__state = -3;
						goto IL_00d8;
						IL_00d8:
						if (<>7__wrap1.MoveNext())
						{
							TypeDefinition current = <>7__wrap1.Current;
							<>7__wrap2 = GetTypesRecursive(current).GetEnumerator();
							<>1__state = -4;
							goto IL_00be;
						}
						<>m__Finally1();
						<>7__wrap1 = default(Enumerator<TypeDefinition>);
						return false;
						IL_00be:
						if (<>7__wrap2.MoveNext())
						{
							TypeDefinition current2 = <>7__wrap2.Current;
							<>2__current = current2;
							<>1__state = 2;
							return true;
						}
						<>m__Finally2();
						<>7__wrap2 = null;
						goto IL_00d8;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

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

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

			private void <>m__Finally2()
			{
				<>1__state = -3;
				if (<>7__wrap2 != null)
				{
					<>7__wrap2.Dispose();
				}
			}

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

			[DebuggerHidden]
			IEnumerator<TypeDefinition> IEnumerable<TypeDefinition>.GetEnumerator()
			{
				<GetTypesRecursive>d__0 <GetTypesRecursive>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<GetTypesRecursive>d__ = this;
				}
				else
				{
					<GetTypesRecursive>d__ = new <GetTypesRecursive>d__0(0);
				}
				<GetTypesRecursive>d__.type = <>3__type;
				<GetTypesRecursive>d__.includeSelf = <>3__includeSelf;
				return <GetTypesRecursive>d__;
			}

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

		[IteratorStateMachine(typeof(<GetTypesRecursive>d__0))]
		public static IEnumerable<TypeDefinition> GetTypesRecursive(TypeDefinition type, bool includeSelf = true)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetTypesRecursive>d__0(-2)
			{
				<>3__type = type,
				<>3__includeSelf = includeSelf
			};
		}

		[IteratorStateMachine(typeof(<GetTypeDefinitions>d__1))]
		public static IEnumerable<TypeDefinition> GetTypeDefinitions(ModuleDefinition mod)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetTypeDefinitions>d__1(-2)
			{
				<>3__mod = mod
			};
		}

		[IteratorStateMachine(typeof(<GetMethodDefinitions>d__2))]
		public static IEnumerable<MethodDefinition> GetMethodDefinitions(ModuleDefinition mod)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetMethodDefinitions>d__2(-2)
			{
				<>3__mod = mod
			};
		}
	}
}
namespace SilksongPrepatcher.Patchers
{
	public class MethodReplacer : BasePrepatcher
	{
		[CompilerGenerated]
		private Func<MethodReference, bool> <predicate>P;

		[CompilerGenerated]
		private MethodInfo <newMethodInfo>P;

		public MethodReplacer(Func<MethodReference, bool> predicate, MethodInfo newMethodInfo)
		{
			<predicate>P = predicate;
			<newMethodInfo>P = newMethodInfo;
			base..ctor("MethodReplacer -> " + <newMethodInfo>P.Name);
		}

		public override void PatchAssembly(AssemblyDefinition asm)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			MethodReference operand = asm.MainModule.ImportReference((MethodBase)<newMethodInfo>P);
			foreach (TypeDefinition typeDefinition in CecilUtils.GetTypeDefinitions(asm.MainModule))
			{
				foreach (MethodDefinition item in ((IEnumerable<MethodDefinition>)typeDefinition.Methods).Where((MethodDefinition m) => m.HasBody))
				{
					ILContext val = new ILContext(item);
					try
					{
						ILCursor val2 = new ILCursor(val);
						while (val2.TryGotoNext(new Func<Instruction, bool>[1]
						{
							delegate(Instruction i)
							{
								//IL_0001: Unknown result type (might be due to invalid IL or missing references)
								//IL_0006: Unknown result type (might be due to invalid IL or missing references)
								//IL_0013: Unknown result type (might be due to invalid IL or missing references)
								//IL_0018: Unknown result type (might be due to invalid IL or missing references)
								if (i.OpCode == OpCodes.Call || i.OpCode == OpCodes.Callvirt)
								{
									object operand2 = i.Operand;
									MethodReference val3 = (MethodReference)((operand2 is MethodReference) ? operand2 : null);
									if (val3 != null)
									{
										return <predicate>P(val3);
									}
								}
								return false;
							}
						}))
						{
							base.Log.LogInfo((object)("Patching " + ((MemberReference)typeDefinition).FullName + " : " + ((MemberReference)item).FullName));
							val2.Next.OpCode = OpCodes.Call;
							val2.Next.Operand = operand;
						}
					}
					finally
					{
						((IDisposable)val)?.Dispose();
					}
				}
			}
		}
	}
	public class ReflectionUtilsPatcher : BasePrepatcher
	{
		public override void PatchAssembly(AssemblyDefinition assembly)
		{
			TypeDefinition val = ((IEnumerable<TypeDefinition>)assembly.MainModule.Types).FirstOrDefault((Func<TypeDefinition, bool>)((TypeDefinition t) => ((MemberReference)t).Name == "ReflectionUtils"));
			if (val == null)
			{
				base.Log.LogInfo((object)("Could not find type ReflectionUtils in " + ((AssemblyNameReference)assembly.Name).Name));
				return;
			}
			MethodDefinition val2 = ((IEnumerable<MethodDefinition>)val.Methods).FirstOrDefault((Func<MethodDefinition, bool>)((MethodDefinition m) => m.IsStatic && m.IsConstructor && m.IsSpecialName));
			if (val2 == null)
			{
				base.Log.LogInfo((object)"Could not find static constructor");
			}
			else
			{
				InjectTypeLookup(assembly.MainModule, val, val2);
			}
		}

		private void InjectTypeLookup(ModuleDefinition module, TypeDefinition typeDef, MethodDefinition cctor)
		{
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: 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_0128: 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_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			FieldDefinition val = ((IEnumerable<FieldDefinition>)typeDef.Fields).FirstOrDefault((Func<FieldDefinition, bool>)((FieldDefinition f) => ((MemberReference)f).Name == "typeLookup" && f.IsStatic));
			if (val == null)
			{
				return;
			}
			MethodReference val2 = module.ImportReference((MethodBase)typeof(Type).GetMethod("GetType", new Type[1] { typeof(string) }));
			MethodInfo method = typeof(Dictionary<, >).MakeGenericType(typeof(string), typeof(Type)).GetMethod("set_Item");
			MethodReference val3 = module.ImportReference((MethodBase)method);
			ILProcessor iLProcessor = cctor.Body.GetILProcessor();
			Instruction val4 = ((IEnumerable<Instruction>)cctor.Body.Instructions).Last();
			if (val4.OpCode != OpCodes.Ret)
			{
				val4 = ((IEnumerable<Instruction>)cctor.Body.Instructions).Reverse().FirstOrDefault((Func<Instruction, bool>)((Instruction i) => i.OpCode == OpCodes.Ret));
				if (val4 == null)
				{
					return;
				}
			}
			iLProcessor.InsertBefore(val4, iLProcessor.Create(OpCodes.Ldsfld, (FieldReference)(object)val));
			iLProcessor.InsertBefore(val4, iLProcessor.Create(OpCodes.Ldstr, "TMProOldOld.TextAlignmentOptions"));
			iLProcessor.InsertBefore(val4, iLProcessor.Create(OpCodes.Ldstr, "TMProOld.TextAlignmentOptions, Assembly-CSharp"));
			iLProcessor.InsertBefore(val4, iLProcessor.Create(OpCodes.Call, val2));
			iLProcessor.InsertBefore(val4, iLProcessor.Create(OpCodes.Callvirt, val3));
			MethodBodyRocks.OptimizeMacros(cctor.Body);
			base.Log.LogInfo((object)"Patch successfully applied");
		}
	}
}
namespace SilksongPrepatcher.Patchers.PlayerDataPatcher
{
	public class PatchedMethodCache
	{
		private static readonly ManualLogSource Log = Logger.CreateLogSource("PatchedMethodCache");

		public Dictionary<string, List<string>> PatchedMethods { get; set; } = new Dictionary<string, List<string>>();


		public void Add(string typeName, string methodName)
		{
			if (!PatchedMethods.TryGetValue(typeName, out List<string> value))
			{
				List<string> list2 = (PatchedMethods[typeName] = new List<string>());
				value = list2;
			}
			value.Add(methodName);
		}

		public static string GetMetadataString()
		{
			string arg = typeof(PatchedMethodCache).Assembly.GetName().Version.ToString();
			DateTime lastWriteTimeUtc = File.GetLastWriteTimeUtc(Path.Combine(Paths.ManagedPath, "Assembly-CSharp.dll"));
			return $"{arg} // {lastWriteTimeUtc}";
		}

		public void Serialize(string filePath)
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("X " + GetMetadataString());
			foreach (var (text2, list2) in PatchedMethods)
			{
				stringBuilder.AppendLine("T " + text2);
				foreach (string item in list2)
				{
					stringBuilder.AppendLine("M " + item);
				}
				stringBuilder.AppendLine("E ");
			}
			File.WriteAllText(filePath, stringBuilder.ToString());
		}

		public static PatchedMethodCache? Deserialize(string filePath)
		{
			if (!File.Exists(filePath))
			{
				Log.LogDebug((object)"Failed to deserialize: no method cache found in cache dir.");
				return null;
			}
			bool flag = false;
			PatchedMethodCache patchedMethodCache = new PatchedMethodCache();
			try
			{
				string[] array = File.ReadAllLines(filePath);
				string text = null;
				List<string> list = new List<string>();
				string[] array2 = array;
				foreach (string text2 in array2)
				{
					if (text2.StartsWith("X "))
					{
						if (!(text2.Substring(2) == GetMetadataString()))
						{
							Log.LogDebug((object)"Failed to deserialize: metadata mismatch.");
							return null;
						}
						flag = true;
					}
					else if (text2.StartsWith("T "))
					{
						text = text2.Substring(2);
					}
					else if (text2.StartsWith("M "))
					{
						list.Add(text2.Substring(2));
					}
					else if (text2.StartsWith("E "))
					{
						if (text == null)
						{
							throw new Exception("Key null on write");
						}
						patchedMethodCache.PatchedMethods[text] = list;
						text = null;
						list = new List<string>();
					}
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Failed to deserialize:\n" + ex));
				return null;
			}
			if (!flag)
			{
				Log.LogInfo((object)"Failed to deserialize: no metadata found.");
				return null;
			}
			return patchedMethodCache;
		}
	}
	internal class PatchingContext
	{
		public enum AccessMethodType
		{
			Default,
			Generic
		}

		public static readonly HashSet<string> DefaultAccessMethods = new HashSet<string> { "Bool", "String", "Float", "Int", "Vector3" };

		public ModuleDefinition MainModule { get; }

		public TypeDefinition PDType { get; }

		public MethodDefinition GenericGetMethod { get; }

		public MethodDefinition GenericSetMethod { get; }

		public Dictionary<TypeReference, MethodDefinition> DefaultGetMethods { get; }

		public Dictionary<TypeReference, MethodDefinition> DefaultSetMethods { get; }

		public PatchingContext(AssemblyDefinition asm)
		{
			MainModule = asm.MainModule;
			PDType = ((IEnumerable<TypeDefinition>)MainModule.Types).First((TypeDefinition t) => ((MemberReference)t).Name == "PlayerData");
			DefaultGetMethods = ((IEnumerable<MethodDefinition>)PDType.Methods).Where((MethodDefinition m) => ((MemberReference)m).Name.StartsWith("Get") && DefaultAccessMethods.Contains(((MemberReference)m).Name.Substring(3))).ToDictionary((MethodDefinition m) => ((MethodReference)m).ReturnType);
			DefaultSetMethods = ((IEnumerable<MethodDefinition>)PDType.Methods).Where((MethodDefinition m) => ((MemberReference)m).Name.StartsWith("Set") && DefaultAccessMethods.Contains(((MemberReference)m).Name.Substring(3)) && ((MethodReference)m).Parameters.Count == 2).ToDictionary((MethodDefinition m) => ((ParameterReference)((MethodReference)m).Parameters[1]).ParameterType);
			TypeDefinition type = AssemblyDefinition.ReadAssembly(Path.Combine(Paths.ManagedPath, "TeamCherry.SharedUtils.dll")).MainModule.GetType("TeamCherry.SharedUtils.VariableExtensions");
			GenericGetMethod = TypeDefinitionRocks.GetMethods(type).First((MethodDefinition x) => ((MemberReference)x).Name == "GetVariable" && ((MemberReference)x).ContainsGenericParameter && ((MethodReference)x).Parameters.Count == 2);
			GenericSetMethod = TypeDefinitionRocks.GetMethods(type).First((MethodDefinition x) => ((MemberReference)x).Name == "SetVariable" && ((MemberReference)x).ContainsGenericParameter && ((MethodReference)x).Parameters.Count == 3);
		}

		public MethodReference CreateGenericGetMethod(TypeReference fieldType)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			GenericInstanceMethod val = new GenericInstanceMethod(MainModule.ImportReference((MethodReference)(object)GenericGetMethod));
			val.GenericArguments.Add(fieldType);
			return (MethodReference)val;
		}

		public void GetGetMethod(TypeReference fieldType, out MethodReference accessMethod, out AccessMethodType accessType)
		{
			if (DefaultGetMethods.TryGetValue(fieldType, out MethodDefinition value))
			{
				accessMethod = MainModule.ImportReference((MethodReference)(object)value);
				accessType = AccessMethodType.Default;
			}
			else
			{
				accessMethod = CreateGenericGetMethod(fieldType);
				accessType = AccessMethodType.Generic;
			}
		}

		public MethodReference CreateGenericSetMethod(TypeReference fieldType)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			GenericInstanceMethod val = new GenericInstanceMethod(MainModule.ImportReference((MethodReference)(object)GenericSetMethod));
			val.GenericArguments.Add(fieldType);
			return (MethodReference)val;
		}

		public void GetSetMethod(TypeReference fieldType, out MethodReference accessMethod, out AccessMethodType accessType)
		{
			if (DefaultSetMethods.TryGetValue(fieldType, out MethodDefinition value))
			{
				accessMethod = MainModule.ImportReference((MethodReference)(object)value);
				accessType = AccessMethodType.Default;
			}
			else
			{
				accessMethod = CreateGenericSetMethod(fieldType);
				accessType = AccessMethodType.Generic;
			}
		}
	}
	public class PlayerDataPatcher : BasePrepatcher
	{
		private static string CacheFilePath => Path.Combine(SilksongPrepatcher.PatchCacheDir, "PlayerDataPatcher_cache.txt");

		public override void PatchAssembly(AssemblyDefinition asm)
		{
			PatchingContext ctx = new PatchingContext(asm);
			PatchedMethodCache patchedMethodCache = PatchedMethodCache.Deserialize(CacheFilePath);
			if (patchedMethodCache == null)
			{
				ReplaceFieldAccesses(ctx);
			}
			else
			{
				ReplaceFieldAccessesFromCache(ctx, patchedMethodCache);
			}
		}

		private void ReplaceFieldAccessesFromCache(PatchingContext ctx, PatchedMethodCache cache)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			int num2 = 0;
			Stopwatch stopwatch = new Stopwatch();
			stopwatch.Start();
			foreach (KeyValuePair<string, List<string>> patchedMethod in cache.PatchedMethods)
			{
				patchedMethod.Deconstruct(out var key, out var value);
				string text = key;
				List<string> list = value;
				TypeDefinition type = ctx.MainModule.GetType(text);
				new HashSet<string>(list);
				Enumerator<MethodDefinition> enumerator2 = type.Methods.GetEnumerator();
				try
				{
					while (enumerator2.MoveNext())
					{
						MethodDefinition current = enumerator2.Current;
						if (list.Contains(((MemberReference)current).FullName))
						{
							if (!PatchMethod(current, ctx, out var replaced, out var missed))
							{
								throw new Exception("Failed to patch " + text + " " + ((MemberReference)current).FullName);
							}
							num += replaced;
							num2 += missed;
						}
					}
				}
				finally
				{
					((IDisposable)enumerator2).Dispose();
				}
			}
			stopwatch.Stop();
			base.Log.LogInfo((object)$"Patched {num} accesses from cache in {stopwatch.ElapsedMilliseconds} ms");
		}

		private void ReplaceFieldAccesses(PatchingContext ctx)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			int num2 = 0;
			PatchedMethodCache patchedMethodCache = new PatchedMethodCache();
			Stopwatch stopwatch = new Stopwatch();
			stopwatch.Start();
			foreach (TypeDefinition typeDefinition in CecilUtils.GetTypeDefinitions(ctx.MainModule))
			{
				Enumerator<MethodDefinition> enumerator2 = typeDefinition.Methods.GetEnumerator();
				try
				{
					while (enumerator2.MoveNext())
					{
						MethodDefinition current2 = enumerator2.Current;
						if (current2.HasBody && (current2.DeclaringType != ctx.PDType || (!(((MemberReference)current2).Name == "SetupNewPlayerData") && !(((MemberReference)current2).Name == "SetupExistingPlayerData") && !((MemberReference)current2).Name.Contains(".ctor"))))
						{
							if (PatchMethod(current2, ctx, out var replaced, out var missed))
							{
								patchedMethodCache.Add(((MemberReference)typeDefinition).FullName, ((MemberReference)current2).FullName);
							}
							num += replaced;
							num2 += missed;
						}
					}
				}
				finally
				{
					((IDisposable)enumerator2).Dispose();
				}
			}
			stopwatch.Stop();
			base.Log.LogInfo((object)$"Patched {num} accesses in {stopwatch.ElapsedMilliseconds} ms");
			base.Log.LogInfo((object)$"Missed {num2} accesses");
			patchedMethodCache.Serialize(CacheFilePath);
		}

		private bool PatchMethod(MethodDefinition method, PatchingContext ctx, out int replaced, out int missed)
		{
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: 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_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			PatchingContext ctx2 = ctx;
			MethodDefinition method2 = method;
			Dictionary<TypeReference, VariableReference> addedVariables = new Dictionary<TypeReference, VariableReference>();
			replaced = 0;
			missed = 0;
			MethodBodyRocks.SimplifyMacros(method2.Body);
			ILProcessor iLProcessor = method2.Body.GetILProcessor();
			for (int num = iLProcessor.Body.Instructions.Count - 1; num >= 0; num--)
			{
				Instruction val = iLProcessor.Body.Instructions[num];
				object operand = val.Operand;
				FieldReference val2 = (FieldReference)((operand is FieldReference) ? operand : null);
				if (val2 != null && !(((MemberReference)((MemberReference)val2).DeclaringType).FullName != ((MemberReference)ctx2.PDType).FullName) && !val2.Resolve().IsPrivate && !((IEnumerable<CustomAttribute>)val2.Resolve().CustomAttributes).Any((CustomAttribute ca) => ((MemberReference)ca.AttributeType).FullName == "System.NonSerializedAttribute"))
				{
					if (val.OpCode == OpCodes.Ldfld)
					{
						ctx2.GetGetMethod(val2.FieldType, out MethodReference accessMethod, out PatchingContext.AccessMethodType accessType);
						OpCode val3 = ((accessType == PatchingContext.AccessMethodType.Default) ? OpCodes.Callvirt : OpCodes.Call);
						Instruction[] array = (Instruction[])(object)new Instruction[2]
						{
							iLProcessor.Create(OpCodes.Ldstr, ((MemberReference)val2).Name),
							iLProcessor.Create(val3, accessMethod)
						};
						val.OpCode = array[0].OpCode;
						val.Operand = array[0].Operand;
						iLProcessor.InsertAfter(val, array[1]);
						replaced++;
					}
					else if (val.OpCode == OpCodes.Stfld)
					{
						ctx2.GetSetMethod(val2.FieldType, out MethodReference accessMethod2, out PatchingContext.AccessMethodType accessType2);
						OpCode val4 = ((accessType2 == PatchingContext.AccessMethodType.Default) ? OpCodes.Callvirt : OpCodes.Call);
						VariableReference val5 = GetOrAddLocal(val2.FieldType);
						Instruction[] array2 = (Instruction[])(object)new Instruction[4]
						{
							Extensions.Create(iLProcessor, OpCodes.Stloc, (object)val5),
							iLProcessor.Create(OpCodes.Ldstr, ((MemberReference)val2).Name),
							Extensions.Create(iLProcessor, OpCodes.Ldloc, (object)val5),
							iLProcessor.Create(val4, accessMethod2)
						};
						val.OpCode = array2[0].OpCode;
						val.Operand = array2[0].Operand;
						iLProcessor.InsertAfter(val, array2[1]);
						iLProcessor.InsertAfter(array2[1], array2[2]);
						iLProcessor.InsertAfter(array2[2], array2[3]);
						replaced++;
					}
					else if (val.OpCode == OpCodes.Ldflda)
					{
						if (TryPatchRefAccess(iLProcessor, val, method2, ctx2, GetOrAddLocal))
						{
							replaced++;
						}
						else
						{
							missed++;
						}
					}
				}
			}
			MethodBodyRocks.OptimizeMacros(method2.Body);
			return replaced > 0;
			VariableReference GetOrAddLocal(TypeReference td)
			{
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				TypeReference val6 = ctx2.MainModule.ImportReference(td);
				if (!addedVariables.ContainsKey(val6))
				{
					VariableDefinition val7 = new VariableDefinition(val6);
					method2.Body.Variables.Add(val7);
					addedVariables.Add(val6, (VariableReference)(object)val7);
				}
				return addedVariables[val6];
			}
		}

		private bool TryPatchRefAccess(ILProcessor il, Instruction instr, MethodDefinition method, PatchingContext ctx, Func<TypeReference, VariableReference> getOrAddLocal)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: 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_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: 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_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			Instruction next = instr.Next;
			if (next.OpCode == OpCodes.Call)
			{
				object operand = next.Operand;
				MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null);
				if (val != null && ((MemberReference)val.ReturnType).FullName == "System.Void" && val.Parameters.Count == 1)
				{
					object operand2 = instr.Operand;
					FieldReference val2 = (FieldReference)((operand2 is FieldReference) ? operand2 : null);
					if (val2 != null)
					{
						VariableReference val3 = getOrAddLocal(val2.FieldType);
						ctx.GetGetMethod(val2.FieldType, out MethodReference accessMethod, out PatchingContext.AccessMethodType accessType);
						OpCode val4 = ((accessType == PatchingContext.AccessMethodType.Default) ? OpCodes.Callvirt : OpCodes.Call);
						ctx.GetSetMethod(val2.FieldType, out MethodReference accessMethod2, out PatchingContext.AccessMethodType accessType2);
						OpCode val5 = ((accessType2 == PatchingContext.AccessMethodType.Default) ? OpCodes.Callvirt : OpCodes.Call);
						Instruction[] array = (Instruction[])(object)new Instruction[9]
						{
							il.Create(OpCodes.Dup),
							il.Create(OpCodes.Ldstr, ((MemberReference)val2).Name),
							il.Create(val4, accessMethod),
							Extensions.Create(il, OpCodes.Stloc, (object)val3),
							Extensions.Create(il, OpCodes.Ldloca, (object)val3),
							next,
							il.Create(OpCodes.Ldstr, ((MemberReference)val2).Name),
							Extensions.Create(il, OpCodes.Ldloc, (object)val3),
							il.Create(val5, accessMethod2)
						};
						il.InsertBefore(instr, array[0]);
						instr.OpCode = array[1].OpCode;
						instr.Operand = array[1].Operand;
						il.InsertAfter(instr, array[2]);
						il.InsertAfter(array[2], array[3]);
						il.InsertAfter(array[3], array[4]);
						il.InsertAfter(next, array[6]);
						il.InsertAfter(array[6], array[7]);
						il.InsertAfter(array[7], array[8]);
						return true;
					}
				}
			}
			return false;
		}
	}
	public class VariableExtensionsPatcher : BasePrepatcher
	{
		public override void PatchAssembly(AssemblyDefinition asm)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
			ModuleDefinition mainModule = asm.MainModule;
			string text = "TeamCherry.SharedUtils.VariableExtensions";
			TypeDefinition type = mainModule.GetType(text);
			MethodDefinition val = null;
			Enumerator<MethodDefinition> enumerator = type.Methods.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					MethodDefinition current = enumerator.Current;
					if (!(((MemberReference)current).Name != "GetVariables"))
					{
						TypeReference parameterType = ((ParameterReference)((MethodReference)current).Parameters[1]).ParameterType;
						GenericInstanceType val2 = (GenericInstanceType)(object)((parameterType is GenericInstanceType) ? parameterType : null);
						if (val2 != null && !(((MemberReference)val2).Name != "Func`2") && !(((MemberReference)((TypeReference)val2).Resolve()).FullName != "System.Func`2"))
						{
							val = current;
							break;
						}
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			MethodDefinition val3 = null;
			enumerator = type.Methods.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					MethodDefinition current2 = enumerator.Current;
					if (!(((MemberReference)current2).Name != "GetVariable") && ((MethodReference)current2).Parameters.Count == 2 && ((MemberReference)current2).ContainsGenericParameter)
					{
						val3 = current2;
						break;
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			if (val != null && val3 != null)
			{
				PatchGetVariablesMethod(val, val3, mainModule);
			}
		}

		private void PatchGetVariablesMethod(MethodDefinition method, MethodDefinition getVariableMethod, ModuleDefinition mod)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			base.Log.LogInfo((object)("Found method " + ((MemberReference)method).FullName));
			GenericParameter val = ((MethodReference)method).GenericParameters[0];
			GenericInstanceMethod val2 = new GenericInstanceMethod((MethodReference)(object)getVariableMethod);
			val2.GenericArguments.Add((TypeReference)(object)val);
			MethodBodyRocks.SimplifyMacros(method.Body);
			method.Body.GetILProcessor();
			Instruction val3 = null;
			Enumerator<Instruction> enumerator = method.Body.Instructions.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					Instruction current = enumerator.Current;
					if (current.OpCode == OpCodes.Callvirt)
					{
						object operand = current.Operand;
						MethodReference val4 = (MethodReference)((operand is MethodReference) ? operand : null);
						if (val4 != null && ((MemberReference)val4).Name == "GetValue" && ((MemberReference)((MemberReference)val4).DeclaringType).FullName == "System.Reflection.FieldInfo")
						{
							val3 = current;
							break;
						}
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			if (val3 == null)
			{
				throw new Exception("Could not find call to FieldInfo::GetValue.");
			}
			Instruction[] array = (Instruction[])(object)new Instruction[4]
			{
				val3.Previous.Previous,
				val3.Previous,
				val3,
				val3.Next
			};
			OpCode opCode = array[0].OpCode;
			if (!((OpCode)(ref opCode)).Name.ToLower().StartsWith("ldloc"))
			{
				throw new Exception("First instruction not Ldloc");
			}
			opCode = array[1].OpCode;
			if (!((OpCode)(ref opCode)).Name.ToLower().StartsWith("ldarg"))
			{
				throw new Exception("Second instruction not Ldarg");
			}
			opCode = array[3].OpCode;
			if (!((OpCode)(ref opCode)).Name.ToLower().StartsWith("unbox"))
			{
				throw new Exception("Fourth instruction not unbox");
			}
			OpCode opCode2 = array[1].OpCode;
			object operand2 = array[1].Operand;
			array[1].OpCode = array[0].OpCode;
			array[1].Operand = array[0].Operand;
			array[0].OpCode = opCode2;
			array[0].Operand = operand2;
			MethodInfo getMethod = typeof(FieldInfo).GetProperty("Name").GetGetMethod();
			MethodReference operand3 = mod.ImportReference((MethodBase)getMethod);
			array[2].OpCode = OpCodes.Callvirt;
			array[2].Operand = operand3;
			array[3].OpCode = OpCodes.Call;
			array[3].Operand = val2;
			MethodBodyRocks.OptimizeMacros(method.Body);
		}
	}
}

plugins/PrepatcherPlugin.dll

Decompiled 6 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using MonoMod.RuntimeDetour;
using TeamCherry.SharedUtils;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PrepatcherPlugin")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2+a22d0b9cfde457406fae294d2fcf0c7a234d839d")]
[assembly: AssemblyProduct("PrepatcherPlugin")]
[assembly: AssemblyTitle("PrepatcherPlugin")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/silksong-modding/Silksong.Prepatcher")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace PrepatcherPlugin
{
	internal static class Extensions
	{
		public static MethodInfo GetMethodOrThrow(this Type type, string name)
		{
			MethodInfo? method = type.GetMethod(name);
			if (method == null)
			{
				throw new MissingMemberException(type.FullName, name);
			}
			return method;
		}
	}
	internal static class Hooks
	{
		private static List<Hook>? hooks = null;

		private static readonly Dictionary<Type, Func<PlayerData, string, object, object>> GenericGetMethodCache = new Dictionary<Type, Func<PlayerData, string, object, object>>();

		private static readonly Dictionary<Type, Func<PlayerData, string, object, object>> GenericSetMethodCache = new Dictionary<Type, Func<PlayerData, string, object, object>>();

		internal static void EnsureHooked()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Expected O, but got Unknown
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Expected O, but got Unknown
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Expected O, but got Unknown
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Expected O, but got Unknown
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Expected O, but got Unknown
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Expected O, but got Unknown
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Expected O, but got Unknown
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Expected O, but got Unknown
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Expected O, but got Unknown
			if (hooks == null)
			{
				hooks = new List<Hook>(12)
				{
					new Hook((MethodBase)typeof(PlayerData).GetMethodOrThrow("GetBool"), (Delegate)new Func<Func<PlayerData, string, bool>, PlayerData, string, bool>(ModifyGetBool)),
					new Hook((MethodBase)typeof(PlayerData).GetMethodOrThrow("SetBool"), (Delegate)new Action<Action<PlayerData, string, bool>, PlayerData, string, bool>(ModifySetBool)),
					new Hook((MethodBase)typeof(PlayerData).GetMethodOrThrow("GetInt"), (Delegate)new Func<Func<PlayerData, string, int>, PlayerData, string, int>(ModifyGetInt)),
					new Hook((MethodBase)typeof(PlayerData).GetMethodOrThrow("SetInt"), (Delegate)new Action<Action<PlayerData, string, int>, PlayerData, string, int>(ModifySetInt)),
					new Hook((MethodBase)typeof(PlayerData).GetMethodOrThrow("GetString"), (Delegate)new Func<Func<PlayerData, string, string>, PlayerData, string, string>(ModifyGetString)),
					new Hook((MethodBase)typeof(PlayerData).GetMethodOrThrow("SetString"), (Delegate)new Action<Action<PlayerData, string, string>, PlayerData, string, string>(ModifySetString)),
					new Hook((MethodBase)typeof(PlayerData).GetMethodOrThrow("GetFloat"), (Delegate)new Func<Func<PlayerData, string, float>, PlayerData, string, float>(ModifyGetFloat)),
					new Hook((MethodBase)typeof(PlayerData).GetMethodOrThrow("SetFloat"), (Delegate)new Action<Action<PlayerData, string, float>, PlayerData, string, float>(ModifySetFloat)),
					new Hook((MethodBase)typeof(PlayerData).GetMethodOrThrow("GetVector3"), (Delegate)new Func<Func<PlayerData, string, Vector3>, PlayerData, string, Vector3>(ModifyGetVector3)),
					new Hook((MethodBase)typeof(PlayerData).GetMethodOrThrow("SetVector3"), (Delegate)new Action<Action<PlayerData, string, Vector3>, PlayerData, string, Vector3>(ModifySetVector3)),
					new Hook((MethodBase)typeof(VariableExtensions).GetMethods().First((MethodInfo m) => m.Name == "GetVariable" && !m.IsGenericMethod), (Delegate)new Func<Func<IIncludeVariableExtensions, string, Type, object>, IIncludeVariableExtensions, string, Type, object>(ModifyGetVariable)),
					new Hook((MethodBase)typeof(VariableExtensions).GetMethods().First((MethodInfo m) => m.Name == "SetVariable" && !m.IsGenericMethod), (Delegate)new Action<Action<IIncludeVariableExtensions, string, object, Type>, IIncludeVariableExtensions, string, object, Type>(ModifySetVariable))
				};
			}
		}

		private static bool ModifyGetBool(Func<PlayerData, string, bool> orig, PlayerData self, string boolName)
		{
			bool current = orig(self, boolName);
			return PlayerDataVariableEvents<bool>.ModifyGetVariable(self, boolName, current);
		}

		private static void ModifySetBool(Action<PlayerData, string, bool> orig, PlayerData self, string boolName, bool value)
		{
			bool arg = PlayerDataVariableEvents<bool>.ModifySetVariable(self, boolName, value);
			orig(self, boolName, arg);
		}

		private static int ModifyGetInt(Func<PlayerData, string, int> orig, PlayerData self, string intName)
		{
			int current = orig(self, intName);
			return PlayerDataVariableEvents<int>.ModifyGetVariable(self, intName, current);
		}

		private static void ModifySetInt(Action<PlayerData, string, int> orig, PlayerData self, string intName, int value)
		{
			int arg = PlayerDataVariableEvents<int>.ModifySetVariable(self, intName, value);
			orig(self, intName, arg);
		}

		private static string ModifyGetString(Func<PlayerData, string, string> orig, PlayerData self, string stringName)
		{
			string current = orig(self, stringName);
			return PlayerDataVariableEvents<string>.ModifyGetVariable(self, stringName, current);
		}

		private static void ModifySetString(Action<PlayerData, string, string> orig, PlayerData self, string stringName, string value)
		{
			string arg = PlayerDataVariableEvents<string>.ModifySetVariable(self, stringName, value);
			orig(self, stringName, arg);
		}

		private static float ModifyGetFloat(Func<PlayerData, string, float> orig, PlayerData self, string floatName)
		{
			float current = orig(self, floatName);
			return PlayerDataVariableEvents<float>.ModifyGetVariable(self, floatName, current);
		}

		private static void ModifySetFloat(Action<PlayerData, string, float> orig, PlayerData self, string floatName, float value)
		{
			float arg = PlayerDataVariableEvents<float>.ModifySetVariable(self, floatName, value);
			orig(self, floatName, arg);
		}

		private static Vector3 ModifyGetVector3(Func<PlayerData, string, Vector3> orig, PlayerData self, string vector3Name)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			Vector3 current = orig(self, vector3Name);
			return PlayerDataVariableEvents<Vector3>.ModifyGetVariable(self, vector3Name, current);
		}

		private static void ModifySetVector3(Action<PlayerData, string, Vector3> orig, PlayerData self, string vector3Name, Vector3 value)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			Vector3 arg = PlayerDataVariableEvents<Vector3>.ModifySetVariable(self, vector3Name, value);
			orig(self, vector3Name, arg);
		}

		private static object ModifyGetVariable(Func<IIncludeVariableExtensions, string, Type, object> orig, IIncludeVariableExtensions obj, string fieldName, Type type)
		{
			object obj2 = orig(obj, fieldName, type);
			PlayerData val = (PlayerData)(object)((obj is PlayerData) ? obj : null);
			if (val == null)
			{
				return obj2;
			}
			if (!GenericGetMethodCache.TryGetValue(type, out Func<PlayerData, string, object, object> value))
			{
				MethodInfo method = typeof(PlayerDataVariableEvents<>).MakeGenericType(type).GetMethod("ModifyGetVariableNonGeneric", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				value = (Func<PlayerData, string, object, object>)Delegate.CreateDelegate(typeof(Func<PlayerData, string, object, object>), method);
				GenericGetMethodCache[type] = value;
			}
			return value(val, fieldName, obj2);
		}

		private static void ModifySetVariable(Action<IIncludeVariableExtensions, string, object, Type> orig, IIncludeVariableExtensions obj, string fieldName, object value, Type type)
		{
			PlayerData val = (PlayerData)(object)((obj is PlayerData) ? obj : null);
			if (val == null)
			{
				orig(obj, fieldName, value, type);
				return;
			}
			if (!GenericSetMethodCache.TryGetValue(type, out Func<PlayerData, string, object, object> value2))
			{
				MethodInfo method = typeof(PlayerDataVariableEvents<>).MakeGenericType(type).GetMethod("ModifySetVariableNonGeneric", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				value2 = (Func<PlayerData, string, object, object>)Delegate.CreateDelegate(typeof(Func<PlayerData, string, object, object>), method);
				GenericSetMethodCache[type] = value2;
			}
			object arg = value2(val, fieldName, value);
			orig(obj, fieldName, arg, type);
		}
	}
	public static class PlayerDataVariableEvents<T>
	{
		public delegate T PlayerDataVariableHandler(PlayerData pd, string fieldName, T current);

		private static readonly ManualLogSource Log = Logger.CreateLogSource("PlayerDataVariableEvents");

		private static PlayerDataVariableHandler? _onGetVariable;

		private static PlayerDataVariableHandler? _onSetVariable;

		public static event PlayerDataVariableHandler? OnGetVariable
		{
			add
			{
				Hooks.EnsureHooked();
				_onGetVariable = (PlayerDataVariableHandler)Delegate.Combine(_onGetVariable, value);
			}
			remove
			{
				_onGetVariable = (PlayerDataVariableHandler)Delegate.Remove(_onGetVariable, value);
			}
		}

		public static event PlayerDataVariableHandler? OnSetVariable
		{
			add
			{
				Hooks.EnsureHooked();
				_onSetVariable = (PlayerDataVariableHandler)Delegate.Combine(_onSetVariable, value);
			}
			remove
			{
				_onSetVariable = (PlayerDataVariableHandler)Delegate.Remove(_onSetVariable, value);
			}
		}

		internal static T ModifyGetVariable(PlayerData pd, string fieldName, T current)
		{
			if (_onGetVariable == null)
			{
				return current;
			}
			foreach (PlayerDataVariableHandler item in _onGetVariable.GetInvocationList().Cast<PlayerDataVariableHandler>())
			{
				try
				{
					current = item(pd, fieldName, current);
				}
				catch (Exception ex)
				{
					Log.LogError((object)("Error invoking ModifyGetVariable, " + typeof(T).Name + "\n" + ex));
				}
			}
			return current;
		}

		internal static object? ModifyGetVariableNonGeneric(PlayerData pd, string fieldName, object current)
		{
			T current2;
			try
			{
				current2 = (T)current;
			}
			catch (Exception)
			{
				Log.LogWarning((object)string.Format("Failed to cast fieldname {0}, object {1} to type {2} in {3}", fieldName, current, typeof(T), "ModifySetVariableNonGeneric"));
				current2 = default(T);
			}
			return ModifyGetVariable(pd, fieldName, current2);
		}

		internal static T ModifySetVariable(PlayerData pd, string fieldName, T current)
		{
			if (_onSetVariable == null)
			{
				return current;
			}
			Delegate[] invocationList = _onSetVariable.GetInvocationList();
			for (int i = 0; i < invocationList.Length; i++)
			{
				PlayerDataVariableHandler playerDataVariableHandler = (PlayerDataVariableHandler)invocationList[i];
				try
				{
					current = playerDataVariableHandler(pd, fieldName, current);
				}
				catch (Exception ex)
				{
					Log.LogError((object)("Error invoking ModifyGetVariable, " + typeof(T).Name + "\n" + ex));
				}
			}
			return current;
		}

		internal static object? ModifySetVariableNonGeneric(PlayerData pd, string fieldName, object current)
		{
			T current2;
			try
			{
				current2 = (T)current;
			}
			catch (Exception)
			{
				Log.LogWarning((object)string.Format("Failed to cast fieldname {0}, object {1} to type {2} in {3}", fieldName, current, typeof(T), "ModifySetVariableNonGeneric"));
				return current;
			}
			return ModifySetVariable(pd, fieldName, current2);
		}
	}
	public static class PlayerDataVariableEvents
	{
		public static event PlayerDataVariableEvents<bool>.PlayerDataVariableHandler? OnGetBool
		{
			add
			{
				PlayerDataVariableEvents<bool>.OnGetVariable += value;
			}
			remove
			{
				PlayerDataVariableEvents<bool>.OnGetVariable -= value;
			}
		}

		public static event PlayerDataVariableEvents<bool>.PlayerDataVariableHandler? OnSetBool
		{
			add
			{
				PlayerDataVariableEvents<bool>.OnSetVariable += value;
			}
			remove
			{
				PlayerDataVariableEvents<bool>.OnSetVariable -= value;
			}
		}

		public static event PlayerDataVariableEvents<int>.PlayerDataVariableHandler? OnGetInt
		{
			add
			{
				PlayerDataVariableEvents<int>.OnGetVariable += value;
			}
			remove
			{
				PlayerDataVariableEvents<int>.OnGetVariable -= value;
			}
		}

		public static event PlayerDataVariableEvents<int>.PlayerDataVariableHandler? OnSetInt
		{
			add
			{
				PlayerDataVariableEvents<int>.OnSetVariable += value;
			}
			remove
			{
				PlayerDataVariableEvents<int>.OnSetVariable -= value;
			}
		}

		public static event PlayerDataVariableEvents<string>.PlayerDataVariableHandler? OnGetString
		{
			add
			{
				PlayerDataVariableEvents<string>.OnGetVariable += value;
			}
			remove
			{
				PlayerDataVariableEvents<string>.OnGetVariable -= value;
			}
		}

		public static event PlayerDataVariableEvents<string>.PlayerDataVariableHandler? OnSetString
		{
			add
			{
				PlayerDataVariableEvents<string>.OnSetVariable += value;
			}
			remove
			{
				PlayerDataVariableEvents<string>.OnSetVariable -= value;
			}
		}

		public static event PlayerDataVariableEvents<float>.PlayerDataVariableHandler? OnGetFloat
		{
			add
			{
				PlayerDataVariableEvents<float>.OnGetVariable += value;
			}
			remove
			{
				PlayerDataVariableEvents<float>.OnGetVariable -= value;
			}
		}

		public static event PlayerDataVariableEvents<float>.PlayerDataVariableHandler? OnSetFloat
		{
			add
			{
				PlayerDataVariableEvents<float>.OnSetVariable += value;
			}
			remove
			{
				PlayerDataVariableEvents<float>.OnSetVariable -= value;
			}
		}

		public static event PlayerDataVariableEvents<Vector3>.PlayerDataVariableHandler? OnGetVector3
		{
			add
			{
				PlayerDataVariableEvents<Vector3>.OnGetVariable += value;
			}
			remove
			{
				PlayerDataVariableEvents<Vector3>.OnGetVariable -= value;
			}
		}

		public static event PlayerDataVariableEvents<Vector3>.PlayerDataVariableHandler? OnSetVector3
		{
			add
			{
				PlayerDataVariableEvents<Vector3>.OnSetVariable += value;
			}
			remove
			{
				PlayerDataVariableEvents<Vector3>.OnSetVariable -= value;
			}
		}
	}
	[BepInPlugin("org.silksong-modding.prepatcher", "PrepatcherPlugin", "1.0.2")]
	public class PrepatcherPlugin : BaseUnityPlugin
	{
		public const string Id = "org.silksong-modding.prepatcher";

		public static string Name => "PrepatcherPlugin";

		public static string Version => "1.0.2";

		private void Awake()
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Plugin " + Name + " (org.silksong-modding.prepatcher) has loaded!"));
		}
	}
}